Config.java revision b4d0e3b1d6313b7f37852f42a2b8b54cc57af17e
1cfb3d242306311ce27ec51bf511764377c173a7cKiran Ryali + Christian Williamspackage org.robolectric.annotation;
2dd40f718cf785a56e63c0685feeb73d266c13e3fWenhui Yao
39cc9bde8928b83e5de9cd1c521e157e1a584b2fdJonathan Gerrishimport android.app.Application;
4b4c08d70a2f549cf344c81bb20c824d3cc31c298Vijay Nayar
5f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williamsimport org.jetbrains.annotations.NotNull;
6f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams
7f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williamsimport java.lang.annotation.Annotation;
8f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williamsimport java.lang.annotation.Documented;
9f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williamsimport java.lang.annotation.ElementType;
10f6e6129091939d868f32182a3dbba7ca0188e515ChrisHennickAtGoogleimport java.lang.annotation.Inherited;
11f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williamsimport java.lang.annotation.Retention;
12f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williamsimport java.lang.annotation.RetentionPolicy;
13f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williamsimport java.lang.annotation.Target;
14f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williamsimport java.util.Arrays;
15c77f5791f081893a18f9db753bb5022269a7c5a6Simon Arlottimport java.util.HashSet;
1623a26cc3e5b33c0503a99847292ac99817f5af43Christian Williamsimport java.util.Properties;
17c77f5791f081893a18f9db753bb5022269a7c5a6Simon Arlottimport java.util.Set;
18f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams
19dd40f718cf785a56e63c0685feeb73d266c13e3fWenhui Yao/**
20c7482da584ddaa03f91afa7b785ed17fa084aa47Erich Douglass * Configuration settings that can be used on a per-class or per-test basis.
21dd40f718cf785a56e63c0685feeb73d266c13e3fWenhui Yao */
22f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams@Documented
23f6e6129091939d868f32182a3dbba7ca0188e515ChrisHennickAtGoogle@Inherited
24f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams@Retention(RetentionPolicy.RUNTIME)
25f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams@Target({ElementType.TYPE, ElementType.METHOD})
267be4d2ba0e45483ad70cbd994955ae1b70afafdcKiran Ryali + Christian Williamspublic @interface Config {
27b4c08d70a2f549cf344c81bb20c824d3cc31c298Vijay Nayar  /**
28b4c08d70a2f549cf344c81bb20c824d3cc31c298Vijay Nayar   * TODO(vnayar): Create named constants for default values instead of magic numbers.
29b4c08d70a2f549cf344c81bb20c824d3cc31c298Vijay Nayar   * Array named contants must be avoided in order to dodge a JDK 1.7 bug.
3084ec27668a169c2c23f5872da93eb532e7e4ae94Christian Williams   *   error: annotation Config is missing value for the attribute <clinit>
3184ec27668a169c2c23f5872da93eb532e7e4ae94Christian Williams   * See <a href="https://bugs.openjdk.java.net/browse/JDK-8013485">JDK-8013485</a>.
32b4c08d70a2f549cf344c81bb20c824d3cc31c298Vijay Nayar   */
330bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass  String NONE = "--none";
34b4d0e3b1d6313b7f37852f42a2b8b54cc57af17eChristian Williams  String DEFAULT_VALUE_STRING = "--default";
35b4d0e3b1d6313b7f37852f42a2b8b54cc57af17eChristian Williams  int DEFAULT_VALUE_INT = -1;
36b4d0e3b1d6313b7f37852f42a2b8b54cc57af17eChristian Williams
37b4d0e3b1d6313b7f37852f42a2b8b54cc57af17eChristian Williams  String DEFAULT_MANIFEST_NAME = "AndroidManifest.xml";
38b4c08d70a2f549cf344c81bb20c824d3cc31c298Vijay Nayar  String DEFAULT_PACKAGE_NAME = "";
39b4c08d70a2f549cf344c81bb20c824d3cc31c298Vijay Nayar  String DEFAULT_ABI_SPLIT = "";
40b4c08d70a2f549cf344c81bb20c824d3cc31c298Vijay Nayar  String DEFAULT_QUALIFIERS = "";
410bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass  String DEFAULT_RES_FOLDER = "res";
420bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass  String DEFAULT_ASSET_FOLDER = "assets";
43ed249b15fa2ff94708d5f079f94284356a96c2a4Sean Kenny  String DEFAULT_BUILD_FOLDER = "build";
4429a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams
4529a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams  /**
46bf73dde49765ed8f3556ef0b2ce63a0cb44703fbJonathan Gerrish   * The Android SDK level to emulate. This value will also be set as Build.VERSION.SDK_INT.
4729a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams   */
48b4c08d70a2f549cf344c81bb20c824d3cc31c298Vijay Nayar  int[] sdk() default {};  // DEFAULT_SDK
4929a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams
5029a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams  /**
51bf73dde49765ed8f3556ef0b2ce63a0cb44703fbJonathan Gerrish   * The minimum Android SDK level to emulate when running tests on multiple API versions.
52bf73dde49765ed8f3556ef0b2ce63a0cb44703fbJonathan Gerrish   */
53bf73dde49765ed8f3556ef0b2ce63a0cb44703fbJonathan Gerrish  int minSdk() default -1;
54bf73dde49765ed8f3556ef0b2ce63a0cb44703fbJonathan Gerrish
55bf73dde49765ed8f3556ef0b2ce63a0cb44703fbJonathan Gerrish  /**
56bf73dde49765ed8f3556ef0b2ce63a0cb44703fbJonathan Gerrish   * The minimum Android SDK level to emulate when running tests on multiple API versions.
57bf73dde49765ed8f3556ef0b2ce63a0cb44703fbJonathan Gerrish   */
58bf73dde49765ed8f3556ef0b2ce63a0cb44703fbJonathan Gerrish  int maxSdk() default -1;
59bf73dde49765ed8f3556ef0b2ce63a0cb44703fbJonathan Gerrish
60bf73dde49765ed8f3556ef0b2ce63a0cb44703fbJonathan Gerrish  /**
6129a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams   * The Android manifest file to load; Robolectric will look relative to the current directory.
6229a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams   * Resources and assets will be loaded relative to the manifest.
6329a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams   *
6429a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams   * If not specified, Robolectric defaults to {@code AndroidManifest.xml}.
6529a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams   *
6629a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams   * If your project has no manifest or resources, use {@link Config#NONE}.
6783bcaf5aa4b64a2223cfada134ef02e5c8ff660aErich Douglass   *
6883bcaf5aa4b64a2223cfada134ef02e5c8ff660aErich Douglass   * @return The Android manifest file to load.
6929a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams   */
70b4d0e3b1d6313b7f37852f42a2b8b54cc57af17eChristian Williams  String manifest() default DEFAULT_VALUE_STRING;
7129a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams
7229a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams  /**
730bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass   * Reference to the BuildConfig class created by the Gradle build system.
740bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass   *
750bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass   * @return Reference to BuildConfig class.
760bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass   */
77b4c08d70a2f549cf344c81bb20c824d3cc31c298Vijay Nayar  Class<?> constants() default Void.class;  // DEFAULT_CONSTANTS
780bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass
790bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass  /**
809cc9bde8928b83e5de9cd1c521e157e1a584b2fdJonathan Gerrish   * The {@link android.app.Application} class to use in the test, this takes precedence over any application
819cc9bde8928b83e5de9cd1c521e157e1a584b2fdJonathan Gerrish   * specified in the AndroidManifest.xml.
8283bcaf5aa4b64a2223cfada134ef02e5c8ff660aErich Douglass   *
8383bcaf5aa4b64a2223cfada134ef02e5c8ff660aErich Douglass   * @return The {@link android.app.Application} class to use in the test.
849cc9bde8928b83e5de9cd1c521e157e1a584b2fdJonathan Gerrish   */
85b4c08d70a2f549cf344c81bb20c824d3cc31c298Vijay Nayar  Class<? extends Application> application() default Application.class;  // DEFAULT_APPLICATION
869cc9bde8928b83e5de9cd1c521e157e1a584b2fdJonathan Gerrish
879cc9bde8928b83e5de9cd1c521e157e1a584b2fdJonathan Gerrish  /**
88bbdc3ce45195e6896254a2c7aa24370f2c55d57cErich Douglass   * Java package name where the "R.class" file is located. This only needs to be specified if you define
89bbdc3ce45195e6896254a2c7aa24370f2c55d57cErich Douglass   * an {@code applicationId} associated with {@code productFlavors} or specify {@code applicationIdSuffix}
90bbdc3ce45195e6896254a2c7aa24370f2c55d57cErich Douglass   * in your build.gradle.
91bbdc3ce45195e6896254a2c7aa24370f2c55d57cErich Douglass   *
92bbdc3ce45195e6896254a2c7aa24370f2c55d57cErich Douglass   * <p>If not specified, Robolectric defaults to the {@code applicationId}.</p>
93bbdc3ce45195e6896254a2c7aa24370f2c55d57cErich Douglass   *
94bbdc3ce45195e6896254a2c7aa24370f2c55d57cErich Douglass   * @return The java package name for R.class.
95bbdc3ce45195e6896254a2c7aa24370f2c55d57cErich Douglass   */
96b4c08d70a2f549cf344c81bb20c824d3cc31c298Vijay Nayar  String packageName() default DEFAULT_PACKAGE_NAME;
97bbdc3ce45195e6896254a2c7aa24370f2c55d57cErich Douglass
98bbdc3ce45195e6896254a2c7aa24370f2c55d57cErich Douglass  /**
993c6572b8953e3d636cdf4d8d26583873b2dd1f25Hilal Alsibai   * The ABI split to use when locating resources and AndroidManifest.xml
1003c6572b8953e3d636cdf4d8d26583873b2dd1f25Hilal Alsibai   *
1013c6572b8953e3d636cdf4d8d26583873b2dd1f25Hilal Alsibai   * <p>You do not typically have to set this, unless you are utilizing the ABI split feature</p>
1023c6572b8953e3d636cdf4d8d26583873b2dd1f25Hilal Alsibai   *
1033c6572b8953e3d636cdf4d8d26583873b2dd1f25Hilal Alsibai   * @return The ABI split to test with
1043c6572b8953e3d636cdf4d8d26583873b2dd1f25Hilal Alsibai   */
105b4c08d70a2f549cf344c81bb20c824d3cc31c298Vijay Nayar  String abiSplit() default DEFAULT_ABI_SPLIT;
1063c6572b8953e3d636cdf4d8d26583873b2dd1f25Hilal Alsibai
1073c6572b8953e3d636cdf4d8d26583873b2dd1f25Hilal Alsibai  /**
10829a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams   * Qualifiers for the resource resolution, such as "fr-normal-port-hdpi".
10929a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams   *
11083bcaf5aa4b64a2223cfada134ef02e5c8ff660aErich Douglass   * @return Qualifiers used for resource resolution.
11129a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams   */
112b4c08d70a2f549cf344c81bb20c824d3cc31c298Vijay Nayar  String qualifiers() default DEFAULT_QUALIFIERS;
11329a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams
11429a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams  /**
1156b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass   * The directory from which to load resources.  This should be relative to the directory containing AndroidManifest.xml.
11683bcaf5aa4b64a2223cfada134ef02e5c8ff660aErich Douglass   *
117bbdc3ce45195e6896254a2c7aa24370f2c55d57cErich Douglass   * <p>If not specified, Robolectric defaults to {@code res}.</p>
11883bcaf5aa4b64a2223cfada134ef02e5c8ff660aErich Douglass   *
11983bcaf5aa4b64a2223cfada134ef02e5c8ff660aErich Douglass   * @return Android resource directory.
1205277f871bca2be31c657ace35ae305285b2e0c55Ryan Spore and Trevor John   */
1216b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass  String resourceDir() default DEFAULT_RES_FOLDER;
1226b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass
1236b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass  /**
1246b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass   * The directory from which to load assets. This should be relative to the directory containing AndroidManifest.xml.
12583bcaf5aa4b64a2223cfada134ef02e5c8ff660aErich Douglass   *
126bbdc3ce45195e6896254a2c7aa24370f2c55d57cErich Douglass   * <p>If not specified, Robolectric defaults to {@code assets}.</p>
12783bcaf5aa4b64a2223cfada134ef02e5c8ff660aErich Douglass   *
12883bcaf5aa4b64a2223cfada134ef02e5c8ff660aErich Douglass   * @return Android asset directory.
1296b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass   */
1306b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass  String assetDir() default DEFAULT_ASSET_FOLDER;
1315277f871bca2be31c657ace35ae305285b2e0c55Ryan Spore and Trevor John
1325277f871bca2be31c657ace35ae305285b2e0c55Ryan Spore and Trevor John  /**
133ed249b15fa2ff94708d5f079f94284356a96c2a4Sean Kenny   * The directory where application files are created during the application build process.
134ed249b15fa2ff94708d5f079f94284356a96c2a4Sean Kenny   *
135ed249b15fa2ff94708d5f079f94284356a96c2a4Sean Kenny   * <p>If not specified, Robolectric defaults to {@code build}.</p>
136ed249b15fa2ff94708d5f079f94284356a96c2a4Sean Kenny   *
137ed249b15fa2ff94708d5f079f94284356a96c2a4Sean Kenny   * @return Android build directory.
138ed249b15fa2ff94708d5f079f94284356a96c2a4Sean Kenny   */
139ed249b15fa2ff94708d5f079f94284356a96c2a4Sean Kenny  String buildDir() default DEFAULT_BUILD_FOLDER;
140ed249b15fa2ff94708d5f079f94284356a96c2a4Sean Kenny
141ed249b15fa2ff94708d5f079f94284356a96c2a4Sean Kenny  /**
14229a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams   * A list of shadow classes to enable, in addition to those that are already present.
14383bcaf5aa4b64a2223cfada134ef02e5c8ff660aErich Douglass   *
14483bcaf5aa4b64a2223cfada134ef02e5c8ff660aErich Douglass   * @return A list of additional shadow classes to enable.
14529a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams   */
146b4c08d70a2f549cf344c81bb20c824d3cc31c298Vijay Nayar  Class<?>[] shadows() default {};  // DEFAULT_SHADOWS
147b4c08d70a2f549cf344c81bb20c824d3cc31c298Vijay Nayar
148d6cef1bcc644c7152d0716b8d33eb25054894836David Sun  /**
149d6cef1bcc644c7152d0716b8d33eb25054894836David Sun   * A list of instrumented packages, in addition to those that are already instrumented.
150b4c08d70a2f549cf344c81bb20c824d3cc31c298Vijay Nayar   *
151d6cef1bcc644c7152d0716b8d33eb25054894836David Sun   * @return A list of additional instrumented packages.
152d6cef1bcc644c7152d0716b8d33eb25054894836David Sun   */
153b4c08d70a2f549cf344c81bb20c824d3cc31c298Vijay Nayar  String[] instrumentedPackages() default {};  // DEFAULT_INSTRUMENTED_PACKAGES
15429a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams
155ed898f2b5b7312af4779636638d081aa6ebd9e13Andrew Richardson  /**
156ed898f2b5b7312af4779636638d081aa6ebd9e13Andrew Richardson   * A list of folders containing Android Libraries on which this project depends.
15783bcaf5aa4b64a2223cfada134ef02e5c8ff660aErich Douglass   *
15883bcaf5aa4b64a2223cfada134ef02e5c8ff660aErich Douglass   * @return A list of Android Libraries.
159ed898f2b5b7312af4779636638d081aa6ebd9e13Andrew Richardson   */
160b4c08d70a2f549cf344c81bb20c824d3cc31c298Vijay Nayar  String[] libraries() default {};  // DEFAULT_LIBRARIES;
161ed898f2b5b7312af4779636638d081aa6ebd9e13Andrew Richardson
1620bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass  class Implementation implements Config {
16381a928816f4cf068ff3fe636df2a25db269c73c8Jonathan Gerrish    private final int[] sdk;
164bf73dde49765ed8f3556ef0b2ce63a0cb44703fbJonathan Gerrish    private final int minSdk;
165bf73dde49765ed8f3556ef0b2ce63a0cb44703fbJonathan Gerrish    private final int maxSdk;
16629a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams    private final String manifest;
16729a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams    private final String qualifiers;
1685277f871bca2be31c657ace35ae305285b2e0c55Ryan Spore and Trevor John    private final String resourceDir;
1696b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass    private final String assetDir;
170ed249b15fa2ff94708d5f079f94284356a96c2a4Sean Kenny    private final String buildDir;
171bbdc3ce45195e6896254a2c7aa24370f2c55d57cErich Douglass    private final String packageName;
1723c6572b8953e3d636cdf4d8d26583873b2dd1f25Hilal Alsibai    private final String abiSplit;
1730bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass    private final Class<?> constants;
17429a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams    private final Class<?>[] shadows;
175d6cef1bcc644c7152d0716b8d33eb25054894836David Sun    private final String[] instrumentedPackages;
1769cc9bde8928b83e5de9cd1c521e157e1a584b2fdJonathan Gerrish    private final Class<? extends Application> application;
177ed898f2b5b7312af4779636638d081aa6ebd9e13Andrew Richardson    private final String[] libraries;
17829a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams
1790bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass    public static Config fromProperties(Properties properties) {
1800bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass      if (properties == null || properties.size() == 0) return null;
18129a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      return new Implementation(
18281a928816f4cf068ff3fe636df2a25db269c73c8Jonathan Gerrish          parseIntArrayProperty(properties.getProperty("sdk", "")),
1838a15973027ac5e93c3da04ed90b0d3d86a9f8dd0Jonathan Gerrish          Integer.parseInt(properties.getProperty("minSdk", "-1")),
1848a15973027ac5e93c3da04ed90b0d3d86a9f8dd0Jonathan Gerrish          Integer.parseInt(properties.getProperty("maxSdk", "-1")),
185b4d0e3b1d6313b7f37852f42a2b8b54cc57af17eChristian Williams          properties.getProperty("manifest", DEFAULT_VALUE_STRING),
186b4c08d70a2f549cf344c81bb20c824d3cc31c298Vijay Nayar          properties.getProperty("qualifiers", DEFAULT_QUALIFIERS),
187b4c08d70a2f549cf344c81bb20c824d3cc31c298Vijay Nayar          properties.getProperty("packageName", DEFAULT_PACKAGE_NAME),
188b4c08d70a2f549cf344c81bb20c824d3cc31c298Vijay Nayar          properties.getProperty("abiSplit", DEFAULT_ABI_SPLIT),
189b4c08d70a2f549cf344c81bb20c824d3cc31c298Vijay Nayar          properties.getProperty("resourceDir", DEFAULT_RES_FOLDER),
190b4c08d70a2f549cf344c81bb20c824d3cc31c298Vijay Nayar          properties.getProperty("assetDir", DEFAULT_ASSET_FOLDER),
191b4c08d70a2f549cf344c81bb20c824d3cc31c298Vijay Nayar          properties.getProperty("buildDir", DEFAULT_BUILD_FOLDER),
1920bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass          parseClasses(properties.getProperty("shadows", "")),
193d6cef1bcc644c7152d0716b8d33eb25054894836David Sun          parseStringArrayProperty(properties.getProperty("instrumentedPackages", "")),
1940bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass          parseApplication(properties.getProperty("application", "android.app.Application")),
19581a928816f4cf068ff3fe636df2a25db269c73c8Jonathan Gerrish          parseStringArrayProperty(properties.getProperty("libraries", "")),
1960bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass          parseClass(properties.getProperty("constants", ""))
19729a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      );
19829a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams    }
19923a26cc3e5b33c0503a99847292ac99817f5af43Christian Williams
2000bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass    private static Class<?> parseClass(String className) {
2010bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass      if (className.isEmpty()) return null;
2020bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass      try {
2030bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass        return Implementation.class.getClassLoader().loadClass(className);
2040bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass      } catch (ClassNotFoundException e) {
2050bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass        throw new RuntimeException("Could not load class: " + className);
2060bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass      }
2070bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass    }
2080bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass
2090bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass    private static Class<?>[] parseClasses(String input) {
2100bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass      if (input.isEmpty()) return new Class[0];
2110bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass      final String[] classNames = input.split("[, ]+");
2120bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass      final Class[] classes = new Class[classNames.length];
21329a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      for (int i = 0; i < classNames.length; i++) {
2140bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass        classes[i] = parseClass(classNames[i]);
21529a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      }
21629a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      return classes;
21729a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams    }
21823a26cc3e5b33c0503a99847292ac99817f5af43Christian Williams
2190bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass    @SuppressWarnings("unchecked")
2209cc9bde8928b83e5de9cd1c521e157e1a584b2fdJonathan Gerrish    private static <T extends Application> Class<T> parseApplication(String className) {
2210bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass      return (Class<T>) parseClass(className);
2229cc9bde8928b83e5de9cd1c521e157e1a584b2fdJonathan Gerrish    }
2239cc9bde8928b83e5de9cd1c521e157e1a584b2fdJonathan Gerrish
22481a928816f4cf068ff3fe636df2a25db269c73c8Jonathan Gerrish    private static String[] parseStringArrayProperty(String property) {
22581a928816f4cf068ff3fe636df2a25db269c73c8Jonathan Gerrish      if (property.isEmpty()) return new String[0];
22681a928816f4cf068ff3fe636df2a25db269c73c8Jonathan Gerrish      return property.split("[, ]+");
227ed898f2b5b7312af4779636638d081aa6ebd9e13Andrew Richardson    }
228ed898f2b5b7312af4779636638d081aa6ebd9e13Andrew Richardson
22981a928816f4cf068ff3fe636df2a25db269c73c8Jonathan Gerrish    private static int[] parseIntArrayProperty(String property) {
23081a928816f4cf068ff3fe636df2a25db269c73c8Jonathan Gerrish      String[] parts = parseStringArrayProperty(property);
23181a928816f4cf068ff3fe636df2a25db269c73c8Jonathan Gerrish      int[] result = new int[parts.length];
23281a928816f4cf068ff3fe636df2a25db269c73c8Jonathan Gerrish      for (int i = 0; i < parts.length; i++) {
23381a928816f4cf068ff3fe636df2a25db269c73c8Jonathan Gerrish        result[i] = Integer.parseInt(parts[i]);
23481a928816f4cf068ff3fe636df2a25db269c73c8Jonathan Gerrish      }
23581a928816f4cf068ff3fe636df2a25db269c73c8Jonathan Gerrish
23681a928816f4cf068ff3fe636df2a25db269c73c8Jonathan Gerrish      return result;
23781a928816f4cf068ff3fe636df2a25db269c73c8Jonathan Gerrish    }
23881a928816f4cf068ff3fe636df2a25db269c73c8Jonathan Gerrish
239bf73dde49765ed8f3556ef0b2ce63a0cb44703fbJonathan Gerrish    public Implementation(int[] sdk, int minSdk, int maxSdk, String manifest, String qualifiers, String packageName, String abiSplit, String resourceDir, String assetDir, String buildDir, Class<?>[] shadows, String[] instrumentedPackages, Class<? extends Application> application, String[] libraries, Class<?> constants) {
2408c45d4a57fa380436885166f8e89b3e20d20290cErich Douglass      this.sdk = sdk;
241bf73dde49765ed8f3556ef0b2ce63a0cb44703fbJonathan Gerrish      this.minSdk = minSdk;
242bf73dde49765ed8f3556ef0b2ce63a0cb44703fbJonathan Gerrish      this.maxSdk = maxSdk;
24329a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      this.manifest = manifest;
24429a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      this.qualifiers = qualifiers;
245bbdc3ce45195e6896254a2c7aa24370f2c55d57cErich Douglass      this.packageName = packageName;
2463c6572b8953e3d636cdf4d8d26583873b2dd1f25Hilal Alsibai      this.abiSplit = abiSplit;
2475277f871bca2be31c657ace35ae305285b2e0c55Ryan Spore and Trevor John      this.resourceDir = resourceDir;
2486b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass      this.assetDir = assetDir;
249ed249b15fa2ff94708d5f079f94284356a96c2a4Sean Kenny      this.buildDir = buildDir;
25029a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      this.shadows = shadows;
251d6cef1bcc644c7152d0716b8d33eb25054894836David Sun      this.instrumentedPackages = instrumentedPackages;
2529cc9bde8928b83e5de9cd1c521e157e1a584b2fdJonathan Gerrish      this.application = application;
253ed898f2b5b7312af4779636638d081aa6ebd9e13Andrew Richardson      this.libraries = libraries;
2540bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass      this.constants = constants;
25529a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams    }
256f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams
25728950f540f7c7bf50fbfb8d9bc8cbf7c2d14e1faAlexander Blom    public Implementation(Config other) {
2588c45d4a57fa380436885166f8e89b3e20d20290cErich Douglass      this.sdk = other.sdk();
259bf73dde49765ed8f3556ef0b2ce63a0cb44703fbJonathan Gerrish      this.minSdk = other.minSdk();
260bf73dde49765ed8f3556ef0b2ce63a0cb44703fbJonathan Gerrish      this.maxSdk = other.maxSdk();
26128950f540f7c7bf50fbfb8d9bc8cbf7c2d14e1faAlexander Blom      this.manifest = other.manifest();
26228950f540f7c7bf50fbfb8d9bc8cbf7c2d14e1faAlexander Blom      this.qualifiers = other.qualifiers();
263bbdc3ce45195e6896254a2c7aa24370f2c55d57cErich Douglass      this.packageName = other.packageName();
2643c6572b8953e3d636cdf4d8d26583873b2dd1f25Hilal Alsibai      this.abiSplit = other.abiSplit();
26528950f540f7c7bf50fbfb8d9bc8cbf7c2d14e1faAlexander Blom      this.resourceDir = other.resourceDir();
26628950f540f7c7bf50fbfb8d9bc8cbf7c2d14e1faAlexander Blom      this.assetDir = other.assetDir();
267ed249b15fa2ff94708d5f079f94284356a96c2a4Sean Kenny      this.buildDir = other.buildDir();
26828950f540f7c7bf50fbfb8d9bc8cbf7c2d14e1faAlexander Blom      this.constants = other.constants();
26928950f540f7c7bf50fbfb8d9bc8cbf7c2d14e1faAlexander Blom      this.shadows = other.shadows();
270d6cef1bcc644c7152d0716b8d33eb25054894836David Sun      this.instrumentedPackages = other.instrumentedPackages();
27128950f540f7c7bf50fbfb8d9bc8cbf7c2d14e1faAlexander Blom      this.application = other.application();
27228950f540f7c7bf50fbfb8d9bc8cbf7c2d14e1faAlexander Blom      this.libraries = other.libraries();
27328950f540f7c7bf50fbfb8d9bc8cbf7c2d14e1faAlexander Blom    }
27428950f540f7c7bf50fbfb8d9bc8cbf7c2d14e1faAlexander Blom
27529a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams    public Implementation(Config baseConfig, Config overlayConfig) {
27681a928816f4cf068ff3fe636df2a25db269c73c8Jonathan Gerrish      this.sdk = pickSdk(baseConfig.sdk(), overlayConfig.sdk(), new int[0]);
277b4d0e3b1d6313b7f37852f42a2b8b54cc57af17eChristian Williams      this.minSdk = pick(baseConfig.minSdk(), overlayConfig.minSdk(), DEFAULT_VALUE_INT);
278b4d0e3b1d6313b7f37852f42a2b8b54cc57af17eChristian Williams      this.maxSdk = pick(baseConfig.maxSdk(), overlayConfig.maxSdk(), DEFAULT_VALUE_INT);
279b4d0e3b1d6313b7f37852f42a2b8b54cc57af17eChristian Williams      this.manifest = pick(baseConfig.manifest(), overlayConfig.manifest(), DEFAULT_VALUE_STRING);
28029a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      this.qualifiers = pick(baseConfig.qualifiers(), overlayConfig.qualifiers(), "");
281bbdc3ce45195e6896254a2c7aa24370f2c55d57cErich Douglass      this.packageName = pick(baseConfig.packageName(), overlayConfig.packageName(), "");
2823c6572b8953e3d636cdf4d8d26583873b2dd1f25Hilal Alsibai      this.abiSplit = pick(baseConfig.abiSplit(), overlayConfig.abiSplit(), "");
2836b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass      this.resourceDir = pick(baseConfig.resourceDir(), overlayConfig.resourceDir(), Config.DEFAULT_RES_FOLDER);
2846b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass      this.assetDir = pick(baseConfig.assetDir(), overlayConfig.assetDir(), Config.DEFAULT_ASSET_FOLDER);
285ed249b15fa2ff94708d5f079f94284356a96c2a4Sean Kenny      this.buildDir = pick(baseConfig.buildDir(), overlayConfig.buildDir(), Config.DEFAULT_BUILD_FOLDER);
286b3c13990ef697c1f25635529ff485760cb5cf644Jen Mendez      this.constants = pick(baseConfig.constants(), overlayConfig.constants(), Void.class);
287ed898f2b5b7312af4779636638d081aa6ebd9e13Andrew Richardson
2880bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass      Set<Class<?>> shadows = new HashSet<>();
28929a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      shadows.addAll(Arrays.asList(baseConfig.shadows()));
29029a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      shadows.addAll(Arrays.asList(overlayConfig.shadows()));
29129a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      this.shadows = shadows.toArray(new Class[shadows.size()]);
292ed898f2b5b7312af4779636638d081aa6ebd9e13Andrew Richardson
293d6cef1bcc644c7152d0716b8d33eb25054894836David Sun      Set<String> instrumentedPackages = new HashSet<>();
294d6cef1bcc644c7152d0716b8d33eb25054894836David Sun      instrumentedPackages.addAll(Arrays.asList(baseConfig.instrumentedPackages()));
295d6cef1bcc644c7152d0716b8d33eb25054894836David Sun      instrumentedPackages.addAll(Arrays.asList(overlayConfig.instrumentedPackages()));
296d6cef1bcc644c7152d0716b8d33eb25054894836David Sun      this.instrumentedPackages = instrumentedPackages.toArray(new String[instrumentedPackages.size()]);
297b4c08d70a2f549cf344c81bb20c824d3cc31c298Vijay Nayar
2983af772e6f01a3da6c2eff85c100a30cc2ea33909Ibraheem Zaman      this.application = pick(baseConfig.application(), overlayConfig.application(), Application.class);
299ed898f2b5b7312af4779636638d081aa6ebd9e13Andrew Richardson
3000bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass      Set<String> libraries = new HashSet<>();
301ed898f2b5b7312af4779636638d081aa6ebd9e13Andrew Richardson      libraries.addAll(Arrays.asList(baseConfig.libraries()));
302ed898f2b5b7312af4779636638d081aa6ebd9e13Andrew Richardson      libraries.addAll(Arrays.asList(overlayConfig.libraries()));
303ed898f2b5b7312af4779636638d081aa6ebd9e13Andrew Richardson      this.libraries = libraries.toArray(new String[libraries.size()]);
30429a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams    }
305f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams
30629a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams    private <T> T pick(T baseValue, T overlayValue, T nullValue) {
3070bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass      return overlayValue != null ? (overlayValue.equals(nullValue) ? baseValue : overlayValue) : null;
30829a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams    }
309f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams
31081a928816f4cf068ff3fe636df2a25db269c73c8Jonathan Gerrish    private int[] pickSdk(int[] baseValue, int[] overlayValue, int[] nullValue) {
31181a928816f4cf068ff3fe636df2a25db269c73c8Jonathan Gerrish      return Arrays.equals(overlayValue, nullValue) ? baseValue : overlayValue;
31281a928816f4cf068ff3fe636df2a25db269c73c8Jonathan Gerrish    }
31381a928816f4cf068ff3fe636df2a25db269c73c8Jonathan Gerrish
3146b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass    @Override
31581a928816f4cf068ff3fe636df2a25db269c73c8Jonathan Gerrish    public int[] sdk() {
3168c45d4a57fa380436885166f8e89b3e20d20290cErich Douglass      return sdk;
31729a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams    }
318f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams
3196b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass    @Override
320bf73dde49765ed8f3556ef0b2ce63a0cb44703fbJonathan Gerrish    public int minSdk() {
321bf73dde49765ed8f3556ef0b2ce63a0cb44703fbJonathan Gerrish      return minSdk;
322bf73dde49765ed8f3556ef0b2ce63a0cb44703fbJonathan Gerrish    }
323bf73dde49765ed8f3556ef0b2ce63a0cb44703fbJonathan Gerrish
324bf73dde49765ed8f3556ef0b2ce63a0cb44703fbJonathan Gerrish    @Override
325bf73dde49765ed8f3556ef0b2ce63a0cb44703fbJonathan Gerrish    public int maxSdk() {
326bf73dde49765ed8f3556ef0b2ce63a0cb44703fbJonathan Gerrish      return maxSdk;
327bf73dde49765ed8f3556ef0b2ce63a0cb44703fbJonathan Gerrish    }
328bf73dde49765ed8f3556ef0b2ce63a0cb44703fbJonathan Gerrish
329bf73dde49765ed8f3556ef0b2ce63a0cb44703fbJonathan Gerrish    @Override
3306b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass    public String manifest() {
33129a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      return manifest;
33229a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams    }
33348f95f3e0955035946f7c416dec56219a9b19886Christian Williams
3349cc9bde8928b83e5de9cd1c521e157e1a584b2fdJonathan Gerrish    @Override
3350bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass    public Class<?> constants() {
3360bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass      return constants;
3370bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass    }
3380bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass
3390bbbacc2633146b2725cce97c24dc121ffa0e89bErich Douglass    @Override
3409cc9bde8928b83e5de9cd1c521e157e1a584b2fdJonathan Gerrish    public Class<? extends Application> application() {
3419cc9bde8928b83e5de9cd1c521e157e1a584b2fdJonathan Gerrish      return application;
3429cc9bde8928b83e5de9cd1c521e157e1a584b2fdJonathan Gerrish    }
3439cc9bde8928b83e5de9cd1c521e157e1a584b2fdJonathan Gerrish
3446b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass    @Override
3456b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass    public String qualifiers() {
34629a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      return qualifiers;
34729a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams    }
348f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams
3495277f871bca2be31c657ace35ae305285b2e0c55Ryan Spore and Trevor John    @Override
350bbdc3ce45195e6896254a2c7aa24370f2c55d57cErich Douglass    public String packageName() {
351bbdc3ce45195e6896254a2c7aa24370f2c55d57cErich Douglass      return packageName;
352bbdc3ce45195e6896254a2c7aa24370f2c55d57cErich Douglass    }
353bbdc3ce45195e6896254a2c7aa24370f2c55d57cErich Douglass
354bbdc3ce45195e6896254a2c7aa24370f2c55d57cErich Douglass    @Override
3553c6572b8953e3d636cdf4d8d26583873b2dd1f25Hilal Alsibai    public String abiSplit() {
3563c6572b8953e3d636cdf4d8d26583873b2dd1f25Hilal Alsibai      return abiSplit;
3573c6572b8953e3d636cdf4d8d26583873b2dd1f25Hilal Alsibai    }
3583c6572b8953e3d636cdf4d8d26583873b2dd1f25Hilal Alsibai
3593c6572b8953e3d636cdf4d8d26583873b2dd1f25Hilal Alsibai    @Override
3605277f871bca2be31c657ace35ae305285b2e0c55Ryan Spore and Trevor John    public String resourceDir() {
3615277f871bca2be31c657ace35ae305285b2e0c55Ryan Spore and Trevor John      return resourceDir;
3625277f871bca2be31c657ace35ae305285b2e0c55Ryan Spore and Trevor John    }
3635277f871bca2be31c657ace35ae305285b2e0c55Ryan Spore and Trevor John
3646b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass    @Override
3656b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass    public String assetDir() {
3666b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass      return assetDir;
3676b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass    }
3686b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass
3696b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass    @Override
370ed249b15fa2ff94708d5f079f94284356a96c2a4Sean Kenny    public String buildDir() {
371ed249b15fa2ff94708d5f079f94284356a96c2a4Sean Kenny      return buildDir;
372ed249b15fa2ff94708d5f079f94284356a96c2a4Sean Kenny    }
373ed249b15fa2ff94708d5f079f94284356a96c2a4Sean Kenny
374ed249b15fa2ff94708d5f079f94284356a96c2a4Sean Kenny    @Override
3756b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass    public Class<?>[] shadows() {
37629a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      return shadows;
37729a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams    }
378f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams
3796b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass    @Override
380d6cef1bcc644c7152d0716b8d33eb25054894836David Sun    public String[] instrumentedPackages() {
381d6cef1bcc644c7152d0716b8d33eb25054894836David Sun      return instrumentedPackages;
382d6cef1bcc644c7152d0716b8d33eb25054894836David Sun    }
383b4c08d70a2f549cf344c81bb20c824d3cc31c298Vijay Nayar
384d6cef1bcc644c7152d0716b8d33eb25054894836David Sun    @Override
3856b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass    public String[] libraries() {
386ed898f2b5b7312af4779636638d081aa6ebd9e13Andrew Richardson      return libraries;
387ed898f2b5b7312af4779636638d081aa6ebd9e13Andrew Richardson    }
388ed898f2b5b7312af4779636638d081aa6ebd9e13Andrew Richardson
3896b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass    @NotNull @Override
3906b00d4156e2e6bb2d262458a2650a109ddc76c76Erich Douglass    public Class<? extends Annotation> annotationType() {
39129a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams      return Config.class;
39229a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams    }
39329a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams  }
39455b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams
39555b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams  class Builder {
39655b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams    private int[] sdk = new int[0];
397bf73dde49765ed8f3556ef0b2ce63a0cb44703fbJonathan Gerrish    private int minSdk = -1;
398bf73dde49765ed8f3556ef0b2ce63a0cb44703fbJonathan Gerrish    private int maxSdk = -1;
399b4d0e3b1d6313b7f37852f42a2b8b54cc57af17eChristian Williams    private String manifest = Config.DEFAULT_VALUE_STRING;
40055b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams    private String qualifiers = Config.DEFAULT_QUALIFIERS;
40155b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams    private String packageName = Config.DEFAULT_PACKAGE_NAME;
40255b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams    private String abiSplit = Config.DEFAULT_ABI_SPLIT;
40355b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams    private String resourceDir = Config.DEFAULT_RES_FOLDER;
40455b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams    private String assetDir = Config.DEFAULT_ASSET_FOLDER;
40555b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams    private String buildDir = Config.DEFAULT_BUILD_FOLDER;
40655b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams    private Class<?>[] shadows = new Class[0];
40755b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams    private String[] instrumentedPackages = new String[0];
40855b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams    private Class<? extends Application> application = Application.class; // todo: make a private default dummy
40955b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams    private String[] libraries = new String[0];
41055b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams    private Class<?> constants = Void.class;
41155b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams
41255b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams    public Builder setSdk(int[] sdk) {
41355b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams      this.sdk = sdk;
41455b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams      return this;
41555b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams    }
41655b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams
417bf73dde49765ed8f3556ef0b2ce63a0cb44703fbJonathan Gerrish    public Builder setMinSdk(int minSdk) {
418bf73dde49765ed8f3556ef0b2ce63a0cb44703fbJonathan Gerrish      this.minSdk = minSdk;
419bf73dde49765ed8f3556ef0b2ce63a0cb44703fbJonathan Gerrish      return this;
420bf73dde49765ed8f3556ef0b2ce63a0cb44703fbJonathan Gerrish    }
421bf73dde49765ed8f3556ef0b2ce63a0cb44703fbJonathan Gerrish
422bf73dde49765ed8f3556ef0b2ce63a0cb44703fbJonathan Gerrish    public Builder setMaxSdk(int maxSdk) {
423bf73dde49765ed8f3556ef0b2ce63a0cb44703fbJonathan Gerrish      this.maxSdk = maxSdk;
424bf73dde49765ed8f3556ef0b2ce63a0cb44703fbJonathan Gerrish      return this;
425bf73dde49765ed8f3556ef0b2ce63a0cb44703fbJonathan Gerrish    }
426bf73dde49765ed8f3556ef0b2ce63a0cb44703fbJonathan Gerrish
42755b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams    public Builder setManifest(String manifest) {
42855b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams      this.manifest = manifest;
42955b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams      return this;
43055b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams    }
43155b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams
43255b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams    public Builder setQualifiers(String qualifiers) {
43355b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams      this.qualifiers = qualifiers;
43455b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams      return this;
43555b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams    }
43655b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams
43755b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams    public Builder setPackageName(String packageName) {
43855b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams      this.packageName = packageName;
43955b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams      return this;
44055b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams    }
44155b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams
44255b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams    public Builder setAbiSplit(String abiSplit) {
44355b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams      this.abiSplit = abiSplit;
44455b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams      return this;
44555b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams    }
44655b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams
44755b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams    public Builder setResourceDir(String resourceDir) {
44855b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams      this.resourceDir = resourceDir;
44955b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams      return this;
45055b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams    }
45155b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams
45255b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams    public Builder setAssetDir(String assetDir) {
45355b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams      this.assetDir = assetDir;
45455b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams      return this;
45555b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams    }
45655b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams
45755b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams    public Builder setBuildDir(String buildDir) {
45855b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams      this.buildDir = buildDir;
45955b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams      return this;
46055b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams    }
46155b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams
46255b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams    public Builder setShadows(Class<?>[] shadows) {
46355b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams      this.shadows = shadows;
46455b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams      return this;
46555b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams    }
46655b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams
46755b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams    public Builder setInstrumentedPackages(String[] instrumentedPackages) {
46855b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams      this.instrumentedPackages = instrumentedPackages;
46955b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams      return this;
47055b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams    }
47155b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams
47255b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams    public Builder setApplication(Class<? extends Application> application) {
47355b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams      this.application = application;
47455b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams      return this;
47555b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams    }
47655b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams
47755b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams    public Builder setLibraries(String[] libraries) {
47855b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams      this.libraries = libraries;
47955b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams      return this;
48055b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams    }
48155b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams
48255b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams    public Builder setConstants(Class<?> constants) {
48355b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams      this.constants = constants;
48455b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams      return this;
48555b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams    }
48655b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams
487b4d0e3b1d6313b7f37852f42a2b8b54cc57af17eChristian Williams    /**
488b4d0e3b1d6313b7f37852f42a2b8b54cc57af17eChristian Williams     * This returns actual default values where they exist, in the sense that we could use
489b4d0e3b1d6313b7f37852f42a2b8b54cc57af17eChristian Williams     * the values, rather than markers like <code>-1</code> or <code>--default</code>.
490b4d0e3b1d6313b7f37852f42a2b8b54cc57af17eChristian Williams     */
491b4d0e3b1d6313b7f37852f42a2b8b54cc57af17eChristian Williams    public static Builder defaults() {
492b4d0e3b1d6313b7f37852f42a2b8b54cc57af17eChristian Williams      return new Builder()
493b4d0e3b1d6313b7f37852f42a2b8b54cc57af17eChristian Williams          .setManifest(DEFAULT_MANIFEST_NAME)
494b4d0e3b1d6313b7f37852f42a2b8b54cc57af17eChristian Williams          .setResourceDir(DEFAULT_RES_FOLDER)
495b4d0e3b1d6313b7f37852f42a2b8b54cc57af17eChristian Williams          .setAssetDir(DEFAULT_ASSET_FOLDER);
496b4d0e3b1d6313b7f37852f42a2b8b54cc57af17eChristian Williams    }
497b4d0e3b1d6313b7f37852f42a2b8b54cc57af17eChristian Williams
49855b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams    public Implementation build() {
499bf73dde49765ed8f3556ef0b2ce63a0cb44703fbJonathan Gerrish      return new Implementation(sdk, minSdk, maxSdk, manifest, qualifiers, packageName, abiSplit, resourceDir, assetDir, buildDir, shadows, instrumentedPackages, application, libraries, constants);
50055b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams    }
50155b52578fdaca7097ea4b28b3daebac84094dab4Christian Williams  }
502dd40f718cf785a56e63c0685feeb73d266c13e3fWenhui Yao}
503