Config.java revision bbdc3ce45195e6896254a2c7aa24370f2c55d57c
1cfb3d242306311ce27ec51bf511764377c173a7cKiran Ryali + Christian Williamspackage org.robolectric.annotation;
2dd40f718cf785a56e63c0685feeb73d266c13e3fWenhui Yao
39cc9bde8928b83e5de9cd1c521e157e1a584b2fdJonathan Gerrishimport android.app.Application;
4f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williamsimport org.jetbrains.annotations.NotNull;
5f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams
6f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williamsimport java.lang.annotation.Annotation;
7f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williamsimport java.lang.annotation.Documented;
8f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williamsimport java.lang.annotation.ElementType;
9f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williamsimport java.lang.annotation.Retention;
10f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williamsimport java.lang.annotation.RetentionPolicy;
11f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williamsimport java.lang.annotation.Target;
12f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williamsimport java.util.Arrays;
13c77f5791f081893a18f9db753bb5022269a7c5a6Simon Arlottimport java.util.HashSet;
1423a26cc3e5b33c0503a99847292ac99817f5af43Christian Williamsimport java.util.Properties;
15c77f5791f081893a18f9db753bb5022269a7c5a6Simon Arlottimport java.util.Set;
16f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams
17dd40f718cf785a56e63c0685feeb73d266c13e3fWenhui Yao/**
18c7482da584ddaa03f91afa7b785ed17fa084aa47Erich Douglass * Configuration settings that can be used on a per-class or per-test basis.
19dd40f718cf785a56e63c0685feeb73d266c13e3fWenhui Yao */
20f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams@Documented
21f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams@Retention(RetentionPolicy.RUNTIME)
22f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams@Target({ElementType.TYPE, ElementType.METHOD})
237be4d2ba0e45483ad70cbd994955ae1b70afafdcKiran Ryali + Christian Williamspublic @interface Config {
240bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass  String NONE = "--none";
250bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass  String DEFAULT = "--default";
260bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass  String DEFAULT_RES_FOLDER = "res";
270bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass  String DEFAULT_ASSET_FOLDER = "assets";
2829a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams
2929a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams  /**
30074a38a2ee8dd8cb1904853aebf2f30146d563a2Mike Grafton   * The Android SDK level to emulate. If not specified, Robolectric defaults to API 16.
3183bcaf5aa4b64a2223cfada134ef02e5c8ff660aErich Douglass   *
3283bcaf5aa4b64a2223cfada134ef02e5c8ff660aErich Douglass   * @return The Android SDK level to emulate.
3329a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams   */
34b2a2e594372228d4e4cae61730152d4e1047c8a7Erich Douglass  int emulateSdk() default -1;
3529a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams
3629a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams  /**
3729a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams   * The Android manifest file to load; Robolectric will look relative to the current directory.
3829a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams   * Resources and assets will be loaded relative to the manifest.
3929a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams   *
4029a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams   * If not specified, Robolectric defaults to {@code AndroidManifest.xml}.
4129a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams   *
4229a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams   * If your project has no manifest or resources, use {@link Config#NONE}.
4383bcaf5aa4b64a2223cfada134ef02e5c8ff660aErich Douglass   *
4483bcaf5aa4b64a2223cfada134ef02e5c8ff660aErich Douglass   * @return The Android manifest file to load.
4529a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams   */
4629a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams  String manifest() default DEFAULT;
4729a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams
4829a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams  /**
490bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass   * Reference to the BuildConfig class created by the Gradle build system.
500bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass   *
510bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass   * @return Reference to BuildConfig class.
520bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass   */
530bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass  Class<?> constants() default Void.class;
540bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass
550bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass  /**
569cc9bde8928b83e5de9cd1c521e157e1a584b2fdJonathan Gerrish   * The {@link android.app.Application} class to use in the test, this takes precedence over any application
579cc9bde8928b83e5de9cd1c521e157e1a584b2fdJonathan Gerrish   * specified in the AndroidManifest.xml.
5883bcaf5aa4b64a2223cfada134ef02e5c8ff660aErich Douglass   *
5983bcaf5aa4b64a2223cfada134ef02e5c8ff660aErich Douglass   * @return The {@link android.app.Application} class to use in the test.
609cc9bde8928b83e5de9cd1c521e157e1a584b2fdJonathan Gerrish   */
619cc9bde8928b83e5de9cd1c521e157e1a584b2fdJonathan Gerrish  Class<? extends Application> application() default Application.class;
629cc9bde8928b83e5de9cd1c521e157e1a584b2fdJonathan Gerrish
639cc9bde8928b83e5de9cd1c521e157e1a584b2fdJonathan Gerrish  /**
64bbdc3ce45195e6896254a2c7aa24370f2c55d57cErich Douglass   * Java package name where the "R.class" file is located. This only needs to be specified if you define
65bbdc3ce45195e6896254a2c7aa24370f2c55d57cErich Douglass   * an {@code applicationId} associated with {@code productFlavors} or specify {@code applicationIdSuffix}
66bbdc3ce45195e6896254a2c7aa24370f2c55d57cErich Douglass   * in your build.gradle.
67bbdc3ce45195e6896254a2c7aa24370f2c55d57cErich Douglass   *
68bbdc3ce45195e6896254a2c7aa24370f2c55d57cErich Douglass   * <p>If not specified, Robolectric defaults to the {@code applicationId}.</p>
69bbdc3ce45195e6896254a2c7aa24370f2c55d57cErich Douglass   *
70bbdc3ce45195e6896254a2c7aa24370f2c55d57cErich Douglass   * @return The java package name for R.class.
71bbdc3ce45195e6896254a2c7aa24370f2c55d57cErich Douglass   */
72bbdc3ce45195e6896254a2c7aa24370f2c55d57cErich Douglass  String packageName() default "";
73bbdc3ce45195e6896254a2c7aa24370f2c55d57cErich Douglass
74bbdc3ce45195e6896254a2c7aa24370f2c55d57cErich Douglass  /**
7529a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams   * Qualifiers for the resource resolution, such as "fr-normal-port-hdpi".
7629a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams   *
7783bcaf5aa4b64a2223cfada134ef02e5c8ff660aErich Douglass   * @return Qualifiers used for resource resolution.
7829a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams   */
7929a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams  String qualifiers() default "";
8029a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams
8129a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams  /**
826b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass   * The directory from which to load resources.  This should be relative to the directory containing AndroidManifest.xml.
8383bcaf5aa4b64a2223cfada134ef02e5c8ff660aErich Douglass   *
84bbdc3ce45195e6896254a2c7aa24370f2c55d57cErich Douglass   * <p>If not specified, Robolectric defaults to {@code res}.</p>
8583bcaf5aa4b64a2223cfada134ef02e5c8ff660aErich Douglass   *
8683bcaf5aa4b64a2223cfada134ef02e5c8ff660aErich Douglass   * @return Android resource directory.
875277f871bca2be31c657ace35ae305285b2e0c55Ryan Spore and Trevor John   */
886b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass  String resourceDir() default DEFAULT_RES_FOLDER;
896b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass
906b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass  /**
916b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass   * The directory from which to load assets. This should be relative to the directory containing AndroidManifest.xml.
9283bcaf5aa4b64a2223cfada134ef02e5c8ff660aErich Douglass   *
93bbdc3ce45195e6896254a2c7aa24370f2c55d57cErich Douglass   * <p>If not specified, Robolectric defaults to {@code assets}.</p>
9483bcaf5aa4b64a2223cfada134ef02e5c8ff660aErich Douglass   *
9583bcaf5aa4b64a2223cfada134ef02e5c8ff660aErich Douglass   * @return Android asset directory.
966b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass   */
976b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass  String assetDir() default DEFAULT_ASSET_FOLDER;
985277f871bca2be31c657ace35ae305285b2e0c55Ryan Spore and Trevor John
995277f871bca2be31c657ace35ae305285b2e0c55Ryan Spore and Trevor John  /**
10029a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams   * The Android SDK level to report in Build.VERSION.SDK_INT.
10129a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams   *
10283bcaf5aa4b64a2223cfada134ef02e5c8ff660aErich Douglass   * @return The Android SDK level to report.
10329a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams   */
10429a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams  int reportSdk() default -1;
10529a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams
10629a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams  /**
10729a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams   * A list of shadow classes to enable, in addition to those that are already present.
10883bcaf5aa4b64a2223cfada134ef02e5c8ff660aErich Douglass   *
10983bcaf5aa4b64a2223cfada134ef02e5c8ff660aErich Douglass   * @return A list of additional shadow classes to enable.
11029a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams   */
11129a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams  Class<?>[] shadows() default {};
11229a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams
113ed898f2b5b7312af4779636638d081aa6ebd9e13Andrew Richardson  /**
114ed898f2b5b7312af4779636638d081aa6ebd9e13Andrew Richardson   * A list of folders containing Android Libraries on which this project depends.
11583bcaf5aa4b64a2223cfada134ef02e5c8ff660aErich Douglass   *
11683bcaf5aa4b64a2223cfada134ef02e5c8ff660aErich Douglass   * @return A list of Android Libraries.
117ed898f2b5b7312af4779636638d081aa6ebd9e13Andrew Richardson   */
118ed898f2b5b7312af4779636638d081aa6ebd9e13Andrew Richardson  String[] libraries() default {};
119ed898f2b5b7312af4779636638d081aa6ebd9e13Andrew Richardson
1200bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass  class Implementation implements Config {
1210bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass    private final int reportSdk;
12229a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams    private final int emulateSdk;
12329a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams    private final String manifest;
12429a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams    private final String qualifiers;
1255277f871bca2be31c657ace35ae305285b2e0c55Ryan Spore and Trevor John    private final String resourceDir;
1266b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass    private final String assetDir;
127bbdc3ce45195e6896254a2c7aa24370f2c55d57cErich Douglass    private final String packageName;
1280bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass    private final Class<?> constants;
12929a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams    private final Class<?>[] shadows;
1309cc9bde8928b83e5de9cd1c521e157e1a584b2fdJonathan Gerrish    private final Class<? extends Application> application;
131ed898f2b5b7312af4779636638d081aa6ebd9e13Andrew Richardson    private final String[] libraries;
13229a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams
1330bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass    public static Config fromProperties(Properties properties) {
1340bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass      if (properties == null || properties.size() == 0) return null;
13529a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      return new Implementation(
1360bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass          Integer.parseInt(properties.getProperty("emulateSdk", "-1")),
1370bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass          properties.getProperty("manifest", DEFAULT),
1380bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass          properties.getProperty("qualifiers", ""),
139bbdc3ce45195e6896254a2c7aa24370f2c55d57cErich Douglass          properties.getProperty("packageName", ""),
1400bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass          properties.getProperty("resourceDir", Config.DEFAULT_RES_FOLDER),
1410bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass          properties.getProperty("assetDir", Config.DEFAULT_ASSET_FOLDER),
1420bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass          Integer.parseInt(properties.getProperty("reportSdk", "-1")),
1430bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass          parseClasses(properties.getProperty("shadows", "")),
1440bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass          parseApplication(properties.getProperty("application", "android.app.Application")),
1450bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass          parsePaths(properties.getProperty("libraries", "")),
1460bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass          parseClass(properties.getProperty("constants", ""))
14729a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      );
14829a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams    }
14923a26cc3e5b33c0503a99847292ac99817f5af43Christian Williams
1500bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass    private static Class<?> parseClass(String className) {
1510bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass      if (className.isEmpty()) return null;
1520bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass      try {
1530bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass        return Implementation.class.getClassLoader().loadClass(className);
1540bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass      } catch (ClassNotFoundException e) {
1550bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass        throw new RuntimeException("Could not load class: " + className);
1560bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass      }
1570bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass    }
1580bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass
1590bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass    private static Class<?>[] parseClasses(String input) {
1600bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass      if (input.isEmpty()) return new Class[0];
1610bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass      final String[] classNames = input.split("[, ]+");
1620bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass      final Class[] classes = new Class[classNames.length];
16329a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      for (int i = 0; i < classNames.length; i++) {
1640bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass        classes[i] = parseClass(classNames[i]);
16529a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      }
16629a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      return classes;
16729a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams    }
16823a26cc3e5b33c0503a99847292ac99817f5af43Christian Williams
1690bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass    @SuppressWarnings("unchecked")
1709cc9bde8928b83e5de9cd1c521e157e1a584b2fdJonathan Gerrish    private static <T extends Application> Class<T> parseApplication(String className) {
1710bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass      return (Class<T>) parseClass(className);
1729cc9bde8928b83e5de9cd1c521e157e1a584b2fdJonathan Gerrish    }
1739cc9bde8928b83e5de9cd1c521e157e1a584b2fdJonathan Gerrish
174ed898f2b5b7312af4779636638d081aa6ebd9e13Andrew Richardson    private static String[] parsePaths(String pathList) {
1750bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass      if (pathList.isEmpty()) return new String[0];
176ed898f2b5b7312af4779636638d081aa6ebd9e13Andrew Richardson      return pathList.split("[, ]+");
177ed898f2b5b7312af4779636638d081aa6ebd9e13Andrew Richardson    }
178ed898f2b5b7312af4779636638d081aa6ebd9e13Andrew Richardson
179bbdc3ce45195e6896254a2c7aa24370f2c55d57cErich Douglass    public Implementation(int emulateSdk, String manifest, String qualifiers, String packageName, String resourceDir, String assetDir, int reportSdk, Class<?>[] shadows, Class<? extends Application> application, String[] libraries, Class<?> constants) {
18029a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      this.emulateSdk = emulateSdk;
18129a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      this.manifest = manifest;
18229a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      this.qualifiers = qualifiers;
183bbdc3ce45195e6896254a2c7aa24370f2c55d57cErich Douglass      this.packageName = packageName;
1845277f871bca2be31c657ace35ae305285b2e0c55Ryan Spore and Trevor John      this.resourceDir = resourceDir;
1856b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass      this.assetDir = assetDir;
18629a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      this.reportSdk = reportSdk;
18729a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      this.shadows = shadows;
1889cc9bde8928b83e5de9cd1c521e157e1a584b2fdJonathan Gerrish      this.application = application;
189ed898f2b5b7312af4779636638d081aa6ebd9e13Andrew Richardson      this.libraries = libraries;
1900bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass      this.constants = constants;
19129a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams    }
192f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams
19328950f540f7c7bf50fbfb8d9bc8cbf7c2d14e1faAlexander Blom    public Implementation(Config other) {
19428950f540f7c7bf50fbfb8d9bc8cbf7c2d14e1faAlexander Blom      this.reportSdk = other.reportSdk();
19528950f540f7c7bf50fbfb8d9bc8cbf7c2d14e1faAlexander Blom      this.emulateSdk = other.emulateSdk();
19628950f540f7c7bf50fbfb8d9bc8cbf7c2d14e1faAlexander Blom      this.manifest = other.manifest();
19728950f540f7c7bf50fbfb8d9bc8cbf7c2d14e1faAlexander Blom      this.qualifiers = other.qualifiers();
198bbdc3ce45195e6896254a2c7aa24370f2c55d57cErich Douglass      this.packageName = other.packageName();
19928950f540f7c7bf50fbfb8d9bc8cbf7c2d14e1faAlexander Blom      this.resourceDir = other.resourceDir();
20028950f540f7c7bf50fbfb8d9bc8cbf7c2d14e1faAlexander Blom      this.assetDir = other.assetDir();
20128950f540f7c7bf50fbfb8d9bc8cbf7c2d14e1faAlexander Blom      this.constants = other.constants();
20228950f540f7c7bf50fbfb8d9bc8cbf7c2d14e1faAlexander Blom      this.shadows = other.shadows();
20328950f540f7c7bf50fbfb8d9bc8cbf7c2d14e1faAlexander Blom      this.application = other.application();
20428950f540f7c7bf50fbfb8d9bc8cbf7c2d14e1faAlexander Blom      this.libraries = other.libraries();
20528950f540f7c7bf50fbfb8d9bc8cbf7c2d14e1faAlexander Blom    }
20628950f540f7c7bf50fbfb8d9bc8cbf7c2d14e1faAlexander Blom
20729a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams    public Implementation(Config baseConfig, Config overlayConfig) {
208b2a2e594372228d4e4cae61730152d4e1047c8a7Erich Douglass      this.emulateSdk = pick(baseConfig.emulateSdk(), overlayConfig.emulateSdk(), -1);
20929a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      this.manifest = pick(baseConfig.manifest(), overlayConfig.manifest(), DEFAULT);
21029a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      this.qualifiers = pick(baseConfig.qualifiers(), overlayConfig.qualifiers(), "");
211bbdc3ce45195e6896254a2c7aa24370f2c55d57cErich Douglass      this.packageName = pick(baseConfig.packageName(), overlayConfig.packageName(), "");
2126b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass      this.resourceDir = pick(baseConfig.resourceDir(), overlayConfig.resourceDir(), Config.DEFAULT_RES_FOLDER);
2136b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass      this.assetDir = pick(baseConfig.assetDir(), overlayConfig.assetDir(), Config.DEFAULT_ASSET_FOLDER);
21429a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      this.reportSdk = pick(baseConfig.reportSdk(), overlayConfig.reportSdk(), -1);
215b3c13990ef697c1f25635529ff485760cb5cf644Jen Mendez      this.constants = pick(baseConfig.constants(), overlayConfig.constants(), Void.class);
216ed898f2b5b7312af4779636638d081aa6ebd9e13Andrew Richardson
2170bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass      Set<Class<?>> shadows = new HashSet<>();
21829a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      shadows.addAll(Arrays.asList(baseConfig.shadows()));
21929a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      shadows.addAll(Arrays.asList(overlayConfig.shadows()));
22029a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      this.shadows = shadows.toArray(new Class[shadows.size()]);
221ed898f2b5b7312af4779636638d081aa6ebd9e13Andrew Richardson
2229cc9bde8928b83e5de9cd1c521e157e1a584b2fdJonathan Gerrish      this.application = pick(baseConfig.application(), overlayConfig.application(), null);
223ed898f2b5b7312af4779636638d081aa6ebd9e13Andrew Richardson
2240bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass      Set<String> libraries = new HashSet<>();
225ed898f2b5b7312af4779636638d081aa6ebd9e13Andrew Richardson      libraries.addAll(Arrays.asList(baseConfig.libraries()));
226ed898f2b5b7312af4779636638d081aa6ebd9e13Andrew Richardson      libraries.addAll(Arrays.asList(overlayConfig.libraries()));
227ed898f2b5b7312af4779636638d081aa6ebd9e13Andrew Richardson      this.libraries = libraries.toArray(new String[libraries.size()]);
22829a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams    }
229f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams
23029a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams    private <T> T pick(T baseValue, T overlayValue, T nullValue) {
2310bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass      return overlayValue != null ? (overlayValue.equals(nullValue) ? baseValue : overlayValue) : null;
23229a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams    }
233f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams
2346b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass    @Override
2356b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass    public int emulateSdk() {
23629a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      return emulateSdk;
23729a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams    }
238f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams
2396b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass    @Override
2406b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass    public String manifest() {
24129a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      return manifest;
24229a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams    }
24348f95f3e0955035946f7c416dec56219a9b19886Christian Williams
2449cc9bde8928b83e5de9cd1c521e157e1a584b2fdJonathan Gerrish    @Override
2450bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass    public Class<?> constants() {
2460bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass      return constants;
2470bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass    }
2480bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass
2490bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass    @Override
2509cc9bde8928b83e5de9cd1c521e157e1a584b2fdJonathan Gerrish    public Class<? extends Application> application() {
2519cc9bde8928b83e5de9cd1c521e157e1a584b2fdJonathan Gerrish      return application;
2529cc9bde8928b83e5de9cd1c521e157e1a584b2fdJonathan Gerrish    }
2539cc9bde8928b83e5de9cd1c521e157e1a584b2fdJonathan Gerrish
2546b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass    @Override
2556b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass    public String qualifiers() {
25629a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      return qualifiers;
25729a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams    }
258f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams
2595277f871bca2be31c657ace35ae305285b2e0c55Ryan Spore and Trevor John    @Override
260bbdc3ce45195e6896254a2c7aa24370f2c55d57cErich Douglass    public String packageName() {
261bbdc3ce45195e6896254a2c7aa24370f2c55d57cErich Douglass      return packageName;
262bbdc3ce45195e6896254a2c7aa24370f2c55d57cErich Douglass    }
263bbdc3ce45195e6896254a2c7aa24370f2c55d57cErich Douglass
264bbdc3ce45195e6896254a2c7aa24370f2c55d57cErich Douglass    @Override
2655277f871bca2be31c657ace35ae305285b2e0c55Ryan Spore and Trevor John    public String resourceDir() {
2665277f871bca2be31c657ace35ae305285b2e0c55Ryan Spore and Trevor John      return resourceDir;
2675277f871bca2be31c657ace35ae305285b2e0c55Ryan Spore and Trevor John    }
2685277f871bca2be31c657ace35ae305285b2e0c55Ryan Spore and Trevor John
2696b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass    @Override
2706b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass    public String assetDir() {
2716b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass      return assetDir;
2726b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass    }
2736b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass
2746b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass    @Override
2756b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass    public int reportSdk() {
27629a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      return reportSdk;
27729a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams    }
278f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams
2796b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass    @Override
2806b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass    public Class<?>[] shadows() {
28129a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      return shadows;
28229a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams    }
283f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams
2846b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass    @Override
2856b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass    public String[] libraries() {
286ed898f2b5b7312af4779636638d081aa6ebd9e13Andrew Richardson      return libraries;
287ed898f2b5b7312af4779636638d081aa6ebd9e13Andrew Richardson    }
288ed898f2b5b7312af4779636638d081aa6ebd9e13Andrew Richardson
2896b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass    @NotNull @Override
2906b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass    public Class<? extends Annotation> annotationType() {
29129a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      return Config.class;
29229a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams    }
293f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams
29429a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams    @Override
29529a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams    public boolean equals(Object o) {
29629a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      if (this == o) return true;
29729a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      if (o == null || getClass() != o.getClass()) return false;
298f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams
29929a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      Implementation other = (Implementation) o;
300f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams
30129a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      if (emulateSdk != other.emulateSdk) return false;
30229a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      if (reportSdk != other.reportSdk) return false;
30329a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      if (!qualifiers.equals(other.qualifiers)) return false;
30429a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      if (!Arrays.equals(shadows, other.shadows)) return false;
3059cc9bde8928b83e5de9cd1c521e157e1a584b2fdJonathan Gerrish      if (application != other.application) return false;
306f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams
30729a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      return true;
30829a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams    }
309f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams
31029a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams    @Override
31129a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams    public int hashCode() {
31229a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      int result = emulateSdk;
31329a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      result = 31 * result + qualifiers.hashCode();
31429a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      result = 31 * result + reportSdk;
31529a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      result = 31 * result + Arrays.hashCode(shadows);
3169cc9bde8928b83e5de9cd1c521e157e1a584b2fdJonathan Gerrish      result = 31 * result + application.hashCode();
31729a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      return result;
318f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams    }
31929a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams  }
320dd40f718cf785a56e63c0685feeb73d266c13e3fWenhui Yao}
321