blob: 443ce58631215f9ca7bc2a84ebae39fdaaaaa818 [file] [log] [blame]
package org.robolectric.internal;
import android.app.Application;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import org.robolectric.AndroidManifest;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.TestLifecycle;
import org.robolectric.res.ResourceLoader;
import org.robolectric.res.builder.RobolectricPackageManager;
import org.robolectric.shadows.ShadowActivityThread;
import org.robolectric.shadows.ShadowContext;
import org.robolectric.shadows.ShadowContextImpl;
import org.robolectric.shadows.ShadowResources;
import org.robolectric.util.DatabaseConfig;
import java.io.File;
import java.lang.reflect.Method;
import static org.fest.reflect.core.Reflection.*;
import static org.robolectric.Robolectric.shadowOf;
public class ParallelUniverse implements ParallelUniverseInterface {
private Class<?> contextImplClass;
public void resetStaticState() {
Robolectric.reset();
}
@Override public void setDatabaseMap(DatabaseConfig.DatabaseMap databaseMap) {
DatabaseConfig.setDatabaseMap(databaseMap);
}
@Override public void setUpApplicationState(Method method, TestLifecycle testLifecycle, boolean strictI18n, ResourceLoader systemResourceLoader, AndroidManifest appManifest) {
Robolectric.application = null;
Robolectric.packageManager = new RobolectricPackageManager();
if (appManifest != null) {
Robolectric.packageManager.addManifest(appManifest);
}
ShadowResources.setSystemResources(systemResourceLoader);
String qualifiers = RobolectricTestRunner.determineResourceQualifiers(method);
Resources systemResources = Resources.getSystem();
Configuration configuration = systemResources.getConfiguration();
shadowOf(configuration).overrideQualifiers(qualifiers);
systemResources.updateConfiguration(configuration, systemResources.getDisplayMetrics());
contextImplClass = type(ShadowContextImpl.CLASS_NAME)
.withClassLoader(getClass().getClassLoader())
.load();
Class<?> activityThreadClass = type(ShadowActivityThread.CLASS_NAME)
.withClassLoader(getClass().getClassLoader())
.load();
Object activityThread = constructor()
.in(activityThreadClass)
.newInstance();
ResourceLoader resourceLoader;
if (appManifest != null) {
resourceLoader = RobolectricTestRunner.getAppResourceLoader(systemResourceLoader, appManifest);
} else {
resourceLoader = systemResourceLoader;
}
Context systemContextImpl = (Context) method("createSystemContext")
.withReturnType(contextImplClass)
.withParameterTypes(activityThreadClass)
.in(contextImplClass)
.invoke(activityThread);
final Application application = (Application) testLifecycle.createApplication(method, appManifest);
if (application != null) {
ApplicationInfo applicationInfo;
if (appManifest == null) {
applicationInfo = new ApplicationInfo();
applicationInfo.packageName = "some.package.name";
applicationInfo.sourceDir = new File(".").getAbsolutePath();
// todo: this should be deleted after each test... 2.0-cleanup
applicationInfo.dataDir = ShadowContext.FILES_DIR.getAbsolutePath();
} else {
try {
applicationInfo = Robolectric.packageManager.getApplicationInfo(appManifest.getPackageName(), 0);
} catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException(e);
}
}
Class<?> compatibilityInfoClass = type("android.content.res.CompatibilityInfo").load();
Object loadedApk = method("getPackageInfo")
.withParameterTypes(ApplicationInfo.class, compatibilityInfoClass, ClassLoader.class, boolean.class, boolean.class)
.in(activityThread)
.invoke(applicationInfo, null, getClass().getClassLoader(), false, true);
shadowOf(application).bind(appManifest, resourceLoader);
Resources appResources = application.getResources();
field("mResources").ofType(Resources.class).in(loadedApk).set(appResources);
Context contextImpl = method("createPackageContext")
.withReturnType(Context.class)
.withParameterTypes(String.class, int.class) // packageName, flags
.in(systemContextImpl)
.invoke(applicationInfo.packageName, Context.CONTEXT_INCLUDE_CODE);
method("attach")
.withParameterTypes(Context.class)
.in(application)
.invoke(contextImpl);
appResources.updateConfiguration(configuration, appResources.getDisplayMetrics());
shadowOf(application).setStrictI18n(strictI18n);
Robolectric.application = application;
application.onCreate();
}
}
@Override public void tearDownApplication() {
if (Robolectric.application != null) {
Robolectric.application.onTerminate();
}
}
@Override public Object getCurrentApplication() {
return Robolectric.application;
}
}