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