package jp.co.cyberagent.stf.compat;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import jp.co.cyberagent.stf.util.InternalApi;
public class WindowManagerWrapper {
private RotationInjector rotationInjector;
private Object windowManager;
private interface RotationInjector {
public void freezeRotation(int rotation);
public void thawRotation();
}
public static interface RotationWatcher {
public void onRotationChanged(int rotation);
}
public WindowManagerWrapper() {
windowManager = getWindowManager();
try {
rotationInjector = new FreezeThawRotationInjector();
}
catch (UnsupportedOperationException e) {
rotationInjector = new SetRotationRotationInjector();
}
}
public void freezeRotation(int rotation) {
rotationInjector.freezeRotation(rotation);
}
public void thawRotation() {
rotationInjector.thawRotation();
}
public void watchRotation(final RotationWatcher watcher) {
try {
Class<?> IRotationWatcher = Class.forName("android.view.IRotationWatcher");
Object windowManager = getWindowManager();
Object proxy = Proxy.newProxyInstance(IRotationWatcher.getClassLoader(), new Class[]{IRotationWatcher}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("Invoked " + method.getName());
if (method.getName().equals("onRotationChanged")) {
watcher.onRotationChanged((Integer) args[0]);
}
return null;
}
});
Method watchRotation = windowManager.getClass().getMethod("watchRotation", IRotationWatcher);
watchRotation.invoke(windowManager, proxy);
}
catch (ClassNotFoundException e) {
e.printStackTrace();
throw new UnsupportedOperationException("watchRotation is not supported: " + e.getMessage());
}
catch (NoSuchMethodException e) {
e.printStackTrace();
throw new UnsupportedOperationException("watchRotation is not supported: " + e.getMessage());
}
catch (IllegalAccessException e) {
e.printStackTrace();
throw new UnsupportedOperationException("watchRotation is not supported: " + e.getMessage());
}
catch (InvocationTargetException e) {
e.printStackTrace();
throw new UnsupportedOperationException("watchRotation is not supported: " + e.getMessage());
}
}
public static Object getWindowManager() {
return InternalApi.getServiceAsInterface("window", "android.view.IWindowManager$Stub");
}
/**
* EventInjector for SDK >10
*/
private class FreezeThawRotationInjector implements RotationInjector {
private Method freezeRotationInjector;
private Method thawRotationInjector;
public FreezeThawRotationInjector() {
try {
freezeRotationInjector = windowManager.getClass()
// public void freezeRotation(int rotation)
.getMethod("freezeRotation", int.class);
thawRotationInjector = windowManager.getClass()
// public void thawRotation()
.getMethod("thawRotation");
}
catch (NoSuchMethodException e) {
throw new UnsupportedOperationException("InputManagerEventInjector is not supported");
}
}
public void freezeRotation(int rotation) {
try {
freezeRotationInjector.invoke(windowManager, rotation);
}
catch (IllegalAccessException e) {
e.printStackTrace();
}
catch (InvocationTargetException e) {
e.printStackTrace();
}
}
public void thawRotation() {
try {
thawRotationInjector.invoke(windowManager);
}
catch (IllegalAccessException e) {
e.printStackTrace();
}
catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
/**
* EventInjector for SDK <=10
*/
private class SetRotationRotationInjector implements RotationInjector {
private Method setRotationInjector;
public SetRotationRotationInjector() {
try {
setRotationInjector = windowManager.getClass()
// void setRotation(int rotation, boolean alwaysSendConfiguration, int animFlags)
.getMethod("setRotation", int.class, boolean.class, int.class);
}
catch (NoSuchMethodException e) {
throw new UnsupportedOperationException("InputManagerEventInjector is not supported");
}
}
public void freezeRotation(int rotation) {
try {
setRotationInjector.invoke(windowManager, rotation, true, 0);
}
catch (IllegalAccessException e) {
e.printStackTrace();
}
catch (InvocationTargetException e) {
e.printStackTrace();
}
}
public void thawRotation() {
}
}
}