/**
   * Initializes and acquires the scene, creating various Android objects such as context, inflater,
   * and parser.
   *
   * @param timeout the time to wait if another rendering is happening.
   * @return whether the scene was prepared
   * @see #acquire(long)
   * @see #release()
   */
  public Result init(long timeout) {
    // acquire the lock. if the result is null, lock was just acquired, otherwise, return
    // the result.
    Result result = acquireLock(timeout);
    if (result != null) {
      return result;
    }

    // setup the ParserFactory
    ParserFactory.setParserFactory(mParams.getLayoutlibCallback().getParserFactory());

    HardwareConfig hardwareConfig = mParams.getHardwareConfig();

    // setup the display Metrics.
    DisplayMetrics metrics = new DisplayMetrics();
    metrics.densityDpi = metrics.noncompatDensityDpi = hardwareConfig.getDensity().getDpiValue();

    metrics.density =
        metrics.noncompatDensity = metrics.densityDpi / (float) DisplayMetrics.DENSITY_DEFAULT;

    metrics.scaledDensity = metrics.noncompatScaledDensity = metrics.density;

    metrics.widthPixels = metrics.noncompatWidthPixels = hardwareConfig.getScreenWidth();
    metrics.heightPixels = metrics.noncompatHeightPixels = hardwareConfig.getScreenHeight();
    metrics.xdpi = metrics.noncompatXdpi = hardwareConfig.getXdpi();
    metrics.ydpi = metrics.noncompatYdpi = hardwareConfig.getYdpi();

    RenderResources resources = mParams.getResources();

    // build the context
    mContext =
        new BridgeContext(
            mParams.getProjectKey(),
            metrics,
            resources,
            mParams.getAssets(),
            mParams.getLayoutlibCallback(),
            getConfiguration(),
            mParams.getTargetSdkVersion(),
            mParams.isRtlSupported());

    setUp();

    return SUCCESS.createResult();
  }
  private Configuration getConfiguration() {
    Configuration config = new Configuration();

    HardwareConfig hardwareConfig = mParams.getHardwareConfig();

    ScreenSize screenSize = hardwareConfig.getScreenSize();
    if (screenSize != null) {
      switch (screenSize) {
        case SMALL:
          config.screenLayout |= Configuration.SCREENLAYOUT_SIZE_SMALL;
          break;
        case NORMAL:
          config.screenLayout |= Configuration.SCREENLAYOUT_SIZE_NORMAL;
          break;
        case LARGE:
          config.screenLayout |= Configuration.SCREENLAYOUT_SIZE_LARGE;
          break;
        case XLARGE:
          config.screenLayout |= Configuration.SCREENLAYOUT_SIZE_XLARGE;
          break;
      }
    }

    Density density = hardwareConfig.getDensity();
    if (density == null) {
      density = Density.MEDIUM;
    }

    config.screenWidthDp = hardwareConfig.getScreenWidth() / density.getDpiValue();
    config.screenHeightDp = hardwareConfig.getScreenHeight() / density.getDpiValue();
    if (config.screenHeightDp < config.screenWidthDp) {
      //noinspection SuspiciousNameCombination
      config.smallestScreenWidthDp = config.screenHeightDp;
    } else {
      config.smallestScreenWidthDp = config.screenWidthDp;
    }
    config.densityDpi = density.getDpiValue();

    // never run in compat mode:
    config.compatScreenWidthDp = config.screenWidthDp;
    config.compatScreenHeightDp = config.screenHeightDp;

    ScreenOrientation orientation = hardwareConfig.getOrientation();
    if (orientation != null) {
      switch (orientation) {
        case PORTRAIT:
          config.orientation = Configuration.ORIENTATION_PORTRAIT;
          break;
        case LANDSCAPE:
          config.orientation = Configuration.ORIENTATION_LANDSCAPE;
          break;
        case SQUARE:
          //noinspection deprecation
          config.orientation = Configuration.ORIENTATION_SQUARE;
          break;
      }
    } else {
      config.orientation = Configuration.ORIENTATION_UNDEFINED;
    }

    // TODO: fill in more config info.

    return config;
  }