package com.mirhoseini.marvel; import android.app.Application; import android.app.KeyguardManager; import android.content.Context; import android.content.pm.PackageManager; import android.os.Bundle; import android.os.IBinder; import android.os.PowerManager; import android.support.test.runner.AndroidJUnitRunner; import java.lang.reflect.Method; import timber.log.Timber; /** * Created by Mohsen on 21/10/2016. */ public class MarvelTestRunner extends AndroidJUnitRunner { @Override public Application newApplication(ClassLoader classLoader, String className, Context context) throws InstantiationException, IllegalAccessException, ClassNotFoundException { // replace Application class with mock one return super.newApplication(classLoader, MarvelTestApplication.class.getName(), context); } /* *Fix android emulator issues on CIs */ @Override public void onStart() { runOnMainSync(() -> { Context app = MarvelTestRunner.this.getTargetContext().getApplicationContext(); MarvelTestRunner.this.disableAnimations(app); String name = MarvelTestRunner.class.getSimpleName(); unlockScreen(app, name); keepScreenAwake(app, name); }); super.onStart(); } @Override public void finish(int resultCode, Bundle results) { super.finish(resultCode, results); enableAnimations(getContext()); } private void keepScreenAwake(Context app, String name) { PowerManager power = (PowerManager) app.getSystemService(Context.POWER_SERVICE); power.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.ON_AFTER_RELEASE, name) .acquire(); } private void unlockScreen(Context app, String name) { KeyguardManager keyguard = (KeyguardManager) app.getSystemService(Context.KEYGUARD_SERVICE); keyguard.newKeyguardLock(name).disableKeyguard(); } void disableAnimations(Context context) { int permStatus = context.checkCallingOrSelfPermission(android.Manifest.permission.SET_ANIMATION_SCALE); if (permStatus == PackageManager.PERMISSION_GRANTED) { setSystemAnimationsScale(0.0f); } } void enableAnimations(Context context) { int permStatus = context.checkCallingOrSelfPermission(android.Manifest.permission.SET_ANIMATION_SCALE); if (permStatus == PackageManager.PERMISSION_GRANTED) { setSystemAnimationsScale(1.0f); } } private void setSystemAnimationsScale(float animationScale) { try { Class<?> windowManagerStubClazz = Class.forName("android.view.IWindowManager$Stub"); Method asInterface = windowManagerStubClazz.getDeclaredMethod("asInterface", IBinder.class); Class<?> serviceManagerClazz = Class.forName("android.os.ServiceManager"); Method getService = serviceManagerClazz.getDeclaredMethod("getService", String.class); Class<?> windowManagerClazz = Class.forName("android.view.IWindowManager"); Method setAnimationScales = windowManagerClazz.getDeclaredMethod("setAnimationScales", float[].class); Method getAnimationScales = windowManagerClazz.getDeclaredMethod("getAnimationScales"); IBinder windowManagerBinder = (IBinder) getService.invoke(null, "window"); Object windowManagerObj = asInterface.invoke(null, windowManagerBinder); float[] currentScales = (float[]) getAnimationScales.invoke(windowManagerObj); for (int i = 0; i < currentScales.length; i++) { currentScales[i] = animationScale; } setAnimationScales.invoke(windowManagerObj, new Object[]{currentScales}); Timber.d("Changed permissions of animations"); } catch (Exception e) { Timber.e("Could not change animation scale to %s", animationScale); } } }