package io.github.hidroh.materialistic;
import android.content.Intent;
import android.view.View;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.TestLifecycleApplication;
import org.robolectric.res.builder.RobolectricPackageManager;
import org.robolectric.shadows.ShadowApplication;
import org.robolectric.shadows.ShadowResolveInfo;
import org.robolectric.util.ReflectionHelpers;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import dagger.ObjectGraph;
import io.github.hidroh.materialistic.test.shadow.ShadowSnackbar;
public class TestApplication extends Application implements TestLifecycleApplication {
public static ObjectGraph applicationGraph = ObjectGraph.create(new TestActivityModule());
public static void addResolver(Intent intent) {
RobolectricPackageManager packageManager = (RobolectricPackageManager)
RuntimeEnvironment.application.getPackageManager();
packageManager.addResolveInfoForIntent( intent,
ShadowResolveInfo.newResolveInfo("label", "com.android.chrome", "DefaultActivity"));
}
@Override
public ObjectGraph getApplicationGraph() {
return applicationGraph;
}
@Override
public void beforeTest(Method method) {
Preferences.sReleaseNotesSeen = true;
ShadowApplication.getInstance().declareActionUnbindable("com.google.android.gms.analytics.service.START");
}
@Override
public void prepareTest(Object o) {
}
@Override
public void afterTest(Method method) {
ShadowSnackbar.reset();
try {
resetWindowManager();
} catch (Exception e) {
System.err.println(e.toString());
}
}
// TODO https://github.com/robolectric/robolectric/issues/2068
private void resetWindowManager() {
Class clazz = ReflectionHelpers.loadClass(getClass().getClassLoader(), "android.view.WindowManagerGlobal");
Object instance = ReflectionHelpers.callStaticMethod(clazz, "getInstance");
// We essentially duplicate what's in {@link WindowManagerGlobal#closeAll} with what's below.
// The closeAll method has a bit of a bug where it's iterating through the "roots" but
// bases the number of objects to iterate through by the number of "views." This can result in
// an {@link java.lang.IndexOutOfBoundsException} being thrown.
Object lock = ReflectionHelpers.getField(instance, "mLock");
ArrayList<Object> roots = ReflectionHelpers.getField(instance, "mRoots");
//noinspection SynchronizationOnLocalVariableOrMethodParameter
synchronized (lock) {
for (int i = 0; i < roots.size(); i++) {
ReflectionHelpers.callInstanceMethod(instance, "removeViewLocked",
ReflectionHelpers.ClassParameter.from(int.class, i),
ReflectionHelpers.ClassParameter.from(boolean.class, false));
}
}
// Views will still be held by this array. We need to clear it out to ensure
// everything is released.
Collection<View> dyingViews = ReflectionHelpers.getField(instance, "mDyingViews");
dyingViews.clear();
}
}