AndroidConfigurer.java revision 4d8a62b819387c47a952e2643399d77d1ee15b1c
1package org.robolectric.internal;
2
3import org.robolectric.RobolectricTestRunner;
4import org.robolectric.TestLifecycle;
5import org.robolectric.annotation.Config;
6import org.robolectric.annotation.Implements;
7import org.robolectric.internal.bytecode.InstrumentationConfiguration;
8import org.robolectric.internal.bytecode.Interceptors;
9import org.robolectric.internal.bytecode.MethodRef;
10import org.robolectric.android.fakes.RoboCharsets;
11import org.robolectric.android.fakes.RoboExtendedResponseCache;
12import org.robolectric.android.fakes.RoboResponseSource;
13import org.robolectric.manifest.AndroidManifest;
14import org.robolectric.res.ResourcePath;
15import org.robolectric.res.ResourceTable;
16import org.robolectric.res.builder.XmlBlock;
17
18import java.util.ServiceLoader;
19
20public class AndroidConfigurer {
21  public static void withConfig(InstrumentationConfiguration.Builder builder, Config config) {
22    for (Class<?> clazz : config.shadows()) {
23      Implements annotation = clazz.getAnnotation(Implements.class);
24      if (annotation == null) {
25        throw new IllegalArgumentException(clazz + " is not annotated with @Implements");
26      }
27
28      String className = annotation.className();
29      if (className.isEmpty()) {
30        className = annotation.value().getName();
31      }
32
33      if (!className.isEmpty()) {
34        builder.addInstrumentedClass(className);
35      }
36    }
37    for (String packageName : config.instrumentedPackages()) {
38      builder.addInstrumentedPackage(packageName);
39    }
40  }
41
42  public static void configure(InstrumentationConfiguration.Builder builder, Interceptors interceptors) {
43    for (MethodRef methodRef : interceptors.getAllMethodRefs()) {
44      builder.addInterceptedMethod(methodRef);
45    }
46
47    builder
48        .doNotAcquireClass(TestLifecycle.class)
49        .doNotAcquireClass(AndroidManifest.class)
50        .doNotAcquireClass(RobolectricTestRunner.class)
51        .doNotAcquireClass(RobolectricTestRunner.HelperTestRunner.class)
52        .doNotAcquireClass(ResourcePath.class)
53        .doNotAcquireClass(ResourceTable.class)
54        .doNotAcquireClass(XmlBlock.class);
55
56    builder
57      .doNotAcquirePackage("javax.")
58      .doNotAcquirePackage("org.robolectric.manifest.")
59      .doNotAcquirePackage("org.robolectric.res.")
60      .doNotAcquirePackage("sun.")
61      .doNotAcquirePackage("com.sun.")
62      .doNotAcquirePackage("org.w3c.")
63      .doNotAcquirePackage("org.xml.")
64      .doNotAcquirePackage("org.junit")
65      .doNotAcquirePackage("org.hamcrest")
66      .doNotAcquirePackage("org.specs2")  // allows for android projects with mixed scala\java tests to be
67      .doNotAcquirePackage("scala.")      //  run with Maven Surefire (see the RoboSpecs project on github)
68      .doNotAcquirePackage("kotlin.")
69      .doNotAcquirePackage("com.almworks.sqlite4java"); // Fix #958: SQLite native library must be loaded once.
70
71    builder.addClassNameTranslation("java.net.ExtendedResponseCache", RoboExtendedResponseCache.class.getName())
72       .addClassNameTranslation("java.net.ResponseSource", RoboResponseSource.class.getName())
73       .addClassNameTranslation("java.nio.charset.Charsets", RoboCharsets.class.getName());
74
75    // Instrumenting these classes causes a weird failure.
76    builder.doNotInstrumentClass("android.R")
77        .doNotInstrumentClass("android.R$styleable");
78
79    builder.addInstrumentedPackage("dalvik.")
80      .addInstrumentedPackage("libcore.")
81      .addInstrumentedPackage("android.")
82      .addInstrumentedPackage("com.android.internal.")
83      .addInstrumentedPackage("org.apache.http.")
84      .addInstrumentedPackage("org.kxml2.");
85
86
87    for (ShadowProvider provider : ServiceLoader.load(ShadowProvider.class)) {
88      for (String packagePrefix : provider.getProvidedPackageNames()) {
89        builder.addInstrumentedPackage(packagePrefix);
90      }
91    }
92  }
93}
94