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);
}
}
}