package org.gnucash.android.test.ui.util;
import android.os.IBinder;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
import java.lang.reflect.Method;
import java.util.Arrays;
/**
* Created by Ngewi on 19.04.2016.
* Credit: https://product.reverb.com/2015/06/06/disabling-animations-in-espresso-for-android-testing/
*/
public class DisableAnimationsRule implements TestRule {
private Method mSetAnimationScalesMethod;
private Method mGetAnimationScalesMethod;
private Object mWindowManagerObject;
public DisableAnimationsRule() {
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");
mSetAnimationScalesMethod = windowManagerClazz.getDeclaredMethod("setAnimationScales", float[].class);
mGetAnimationScalesMethod = windowManagerClazz.getDeclaredMethod("getAnimationScales");
IBinder windowManagerBinder = (IBinder) getService.invoke(null, "window");
mWindowManagerObject = asInterface.invoke(null, windowManagerBinder);
}
catch (Exception e) {
throw new RuntimeException("Failed to access animation methods", e);
}
}
@Override
public Statement apply(final Statement statement, Description description) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
setAnimationScaleFactors(0.0f);
try { statement.evaluate(); }
finally { setAnimationScaleFactors(1.0f); }
}
};
}
private void setAnimationScaleFactors(float scaleFactor) throws Exception {
float[] scaleFactors = (float[]) mGetAnimationScalesMethod.invoke(mWindowManagerObject);
Arrays.fill(scaleFactors, scaleFactor);
mSetAnimationScalesMethod.invoke(mWindowManagerObject, scaleFactors);
}
}