aboutsummaryrefslogtreecommitdiff
path: root/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWindowManagerGlobal.java
diff options
context:
space:
mode:
Diffstat (limited to 'shadows/framework/src/main/java/org/robolectric/shadows/ShadowWindowManagerGlobal.java')
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowWindowManagerGlobal.java292
1 files changed, 48 insertions, 244 deletions
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWindowManagerGlobal.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWindowManagerGlobal.java
index 80b484cdc..75b0371eb 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWindowManagerGlobal.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWindowManagerGlobal.java
@@ -2,40 +2,25 @@ package org.robolectric.shadows;
import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR2;
-import static android.os.Build.VERSION_CODES.LOLLIPOP_MR1;
-import static android.os.Build.VERSION_CODES.M;
import static android.os.Build.VERSION_CODES.P;
-import static android.os.Build.VERSION_CODES.Q;
import static android.os.Build.VERSION_CODES.R;
-import static android.os.Build.VERSION_CODES.S;
-import static android.os.Build.VERSION_CODES.S_V2;
import static org.robolectric.shadows.ShadowView.useRealGraphics;
import static org.robolectric.util.reflector.Reflector.reflector;
import android.app.Instrumentation;
import android.content.ClipData;
import android.content.Context;
-import android.graphics.Rect;
import android.os.Binder;
-import android.os.Build.VERSION;
import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteException;
import android.os.ServiceManager;
-import android.view.DisplayCutout;
-import android.view.IWindow;
import android.view.IWindowManager;
import android.view.IWindowSession;
-import android.view.InputChannel;
-import android.view.InsetsSourceControl;
-import android.view.InsetsState;
-import android.view.InsetsVisibilities;
-import android.view.Surface;
-import android.view.SurfaceControl;
import android.view.View;
-import android.view.WindowManager;
import android.view.WindowManagerGlobal;
import androidx.annotation.Nullable;
+import java.lang.reflect.Proxy;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
@@ -53,44 +38,18 @@ import org.robolectric.util.reflector.Static;
minSdk = JELLY_BEAN_MR1,
looseSignatures = true)
public class ShadowWindowManagerGlobal {
- private static WindowSessionDelegate windowSessionDelegate;
+ private static WindowSessionDelegate windowSessionDelegate = new WindowSessionDelegate();
private static IWindowSession windowSession;
@Resetter
public static void reset() {
reflector(WindowManagerGlobalReflector.class).setDefaultWindowManager(null);
- windowSessionDelegate = null;
+ windowSessionDelegate = new WindowSessionDelegate();
windowSession = null;
}
- private static synchronized WindowSessionDelegate getWindowSessionDelegate() {
- if (windowSessionDelegate == null) {
- int apiLevel = RuntimeEnvironment.getApiLevel();
- if (apiLevel >= S_V2) {
- windowSessionDelegate = new WindowSessionDelegateSV2();
- } else if (apiLevel >= S) {
- windowSessionDelegate = new WindowSessionDelegateS();
- } else if (apiLevel >= R) {
- windowSessionDelegate = new WindowSessionDelegateR();
- } else if (apiLevel >= Q) {
- windowSessionDelegate = new WindowSessionDelegateQ();
- } else if (apiLevel >= P) {
- windowSessionDelegate = new WindowSessionDelegateP();
- } else if (apiLevel >= M) {
- windowSessionDelegate = new WindowSessionDelegateM();
- } else if (apiLevel >= LOLLIPOP_MR1) {
- windowSessionDelegate = new WindowSessionDelegateLMR1();
- } else if (apiLevel >= JELLY_BEAN_MR1) {
- windowSessionDelegate = new WindowSessionDelegateJBMR1();
- } else {
- windowSessionDelegate = new WindowSessionDelegateJB();
- }
- }
- return windowSessionDelegate;
- }
-
public static boolean getInTouchMode() {
- return getWindowSessionDelegate().getInTouchMode();
+ return windowSessionDelegate.getInTouchMode();
}
/**
@@ -98,7 +57,7 @@ public class ShadowWindowManagerGlobal {
* Instrumentation#setInTouchMode(boolean)} to modify this from a test.
*/
static void setInTouchMode(boolean inTouchMode) {
- getWindowSessionDelegate().setInTouchMode(inTouchMode);
+ windowSessionDelegate.setInTouchMode(inTouchMode);
}
/**
@@ -107,21 +66,46 @@ public class ShadowWindowManagerGlobal {
*/
@Nullable
public static ClipData getLastDragClipData() {
- return windowSessionDelegate != null ? windowSessionDelegate.lastDragClipData : null;
+ return windowSessionDelegate.lastDragClipData;
}
/** Clears the data returned by {@link #getLastDragClipData()}. */
public static void clearLastDragClipData() {
- if (windowSessionDelegate != null) {
- windowSessionDelegate.lastDragClipData = null;
- }
+ windowSessionDelegate.lastDragClipData = null;
}
@Implementation(minSdk = JELLY_BEAN_MR2)
protected static synchronized IWindowSession getWindowSession() {
if (windowSession == null) {
+ // Use Proxy.newProxyInstance instead of ReflectionHelpers.createDelegatingProxy as there are
+ // too many variants of 'add', 'addToDisplay', and 'addToDisplayAsUser', some of which have
+ // arg types that don't exist any more.
windowSession =
- ReflectionHelpers.createDelegatingProxy(IWindowSession.class, getWindowSessionDelegate());
+ (IWindowSession)
+ Proxy.newProxyInstance(
+ IWindowSession.class.getClassLoader(),
+ new Class<?>[] {IWindowSession.class},
+ (proxy, method, args) -> {
+ String methodName = method.getName();
+ switch (methodName) {
+ case "add": // SDK 16
+ case "addToDisplay": // SDK 17-29
+ case "addToDisplayAsUser": // SDK 30+
+ return windowSessionDelegate.getAddFlags();
+ case "getInTouchMode":
+ return windowSessionDelegate.getInTouchMode();
+ case "performDrag":
+ return windowSessionDelegate.performDrag(args);
+ case "prepareDrag":
+ return windowSessionDelegate.prepareDrag();
+ case "setInTouchMode":
+ windowSessionDelegate.setInTouchMode((boolean) args[0]);
+ return null;
+ default:
+ return ReflectionHelpers.defaultValueForType(
+ method.getReturnType().getName());
+ }
+ });
}
return windowSession;
}
@@ -143,7 +127,7 @@ public class ShadowWindowManagerGlobal {
if (service == null) {
service = IWindowManager.Stub.asInterface(ServiceManager.getService(Context.WINDOW_SERVICE));
reflector(WindowManagerGlobalReflector.class).setWindowManagerService(service);
- if (VERSION.SDK_INT >= 30) {
+ if (RuntimeEnvironment.getApiLevel() >= R) {
reflector(WindowManagerGlobalReflector.class).setUseBlastAdapter(service.useBLAST());
}
}
@@ -169,7 +153,7 @@ public class ShadowWindowManagerGlobal {
void setUseBlastAdapter(boolean useBlastAdapter);
}
- private abstract static class WindowSessionDelegate {
+ private static class WindowSessionDelegate {
// From WindowManagerGlobal (was WindowManagerImpl in JB).
static final int ADD_FLAG_IN_TOUCH_MODE = 0x1;
static final int ADD_FLAG_APP_VISIBLE = 0x2;
@@ -202,200 +186,20 @@ public class ShadowWindowManagerGlobal {
this.inTouchMode = inTouchMode;
}
- // @Implementation(maxSdk = O_MR1)
- public IBinder prepareDrag(
- IWindow window, int flags, int thumbnailWidth, int thumbnailHeight, Surface outSurface) {
- return new Binder();
- }
-
- // @Implementation(maxSdk = M)
- public boolean performDrag(
- IWindow window,
- IBinder dragToken,
- float touchX,
- float touchY,
- float thumbCenterX,
- float thumbCenterY,
- ClipData data) {
- lastDragClipData = data;
- return true;
- }
-
- // @Implementation(minSdk = N, maxSdk = O_MR1)
- public boolean performDrag(
- IWindow window,
- IBinder dragToken,
- int touchSource,
- float touchX,
- float touchY,
- float thumbCenterX,
- float thumbCenterY,
- ClipData data) {
- lastDragClipData = data;
- return true;
- }
- }
-
- private static class WindowSessionDelegateJB extends WindowSessionDelegate {
- // @Implementation(maxSdk = JELLY_BEAN)
- public int add(
- IWindow window,
- int seq,
- WindowManager.LayoutParams attrs,
- int viewVisibility,
- int layerStackId,
- Rect outContentInsets,
- InputChannel outInputChannel) {
- return getAddFlags();
- }
- }
-
- private static class WindowSessionDelegateJBMR1 extends WindowSessionDelegateJB {
- // @Implementation(minSdk = JELLY_BEAN_MR1, maxSdk = LOLLIPOP)
- public int addToDisplay(
- IWindow window,
- int seq,
- WindowManager.LayoutParams attrs,
- int viewVisibility,
- int layerStackId,
- Rect outContentInsets,
- InputChannel outInputChannel) {
- return getAddFlags();
- }
- }
-
- private static class WindowSessionDelegateLMR1 extends WindowSessionDelegateJBMR1 {
- // @Implementation(sdk = LOLLIPOP_MR1)
- public int addToDisplay(
- IWindow window,
- int seq,
- WindowManager.LayoutParams attrs,
- int viewVisibility,
- int layerStackId,
- Rect outContentInsets,
- Rect outStableInsets,
- InputChannel outInputChannel) {
- return getAddFlags();
- }
- }
-
- private static class WindowSessionDelegateM extends WindowSessionDelegateLMR1 {
- // @Implementation(minSdk = M, maxSdk = O_MR1)
- public int addToDisplay(
- IWindow window,
- int seq,
- WindowManager.LayoutParams attrs,
- int viewVisibility,
- int layerStackId,
- Rect outContentInsets,
- Rect outStableInsets,
- Rect outInsets,
- InputChannel outInputChannel) {
- return getAddFlags();
- }
- }
-
- private static class WindowSessionDelegateP extends WindowSessionDelegateM {
- // @Implementation(sdk = P)
- public int addToDisplay(
- IWindow window,
- int seq,
- WindowManager.LayoutParams attrs,
- int viewVisibility,
- int layerStackId,
- Rect outFrame,
- Rect outContentInsets,
- Rect outStableInsets,
- Rect outOutsets,
- DisplayCutout.ParcelableWrapper displayCutout,
- InputChannel outInputChannel) {
- return getAddFlags();
- }
-
- // @Implementation(minSdk = P)
- public IBinder performDrag(
- IWindow window,
- int flags,
- SurfaceControl surface,
- int touchSource,
- float touchX,
- float touchY,
- float thumbCenterX,
- float thumbCenterY,
- ClipData data) {
- lastDragClipData = data;
+ public IBinder prepareDrag() {
return new Binder();
}
- }
- private static class WindowSessionDelegateQ extends WindowSessionDelegateP {
- // @Implementation(sdk = Q)
- public int addToDisplay(
- IWindow window,
- int seq,
- WindowManager.LayoutParams attrs,
- int viewVisibility,
- int layerStackId,
- Rect outFrame,
- Rect outContentInsets,
- Rect outStableInsets,
- Rect outOutsets,
- DisplayCutout.ParcelableWrapper displayCutout,
- InputChannel outInputChannel,
- InsetsState insetsState) {
- return getAddFlags();
- }
- }
-
- private static class WindowSessionDelegateR extends WindowSessionDelegateQ {
- // @Implementation(sdk = R)
- public int addToDisplayAsUser(
- IWindow window,
- int seq,
- WindowManager.LayoutParams attrs,
- int viewVisibility,
- int layerStackId,
- int userId,
- Rect outFrame,
- Rect outContentInsets,
- Rect outStableInsets,
- DisplayCutout.ParcelableWrapper displayCutout,
- InputChannel outInputChannel,
- InsetsState insetsState,
- InsetsSourceControl[] activeControls) {
- return getAddFlags();
- }
- }
-
- private static class WindowSessionDelegateS extends WindowSessionDelegateR {
- // @Implementation(sdk = S)
- public int addToDisplayAsUser(
- IWindow window,
- WindowManager.LayoutParams attrs,
- int viewVisibility,
- int layerStackId,
- int userId,
- InsetsState requestedVisibility,
- InputChannel outInputChannel,
- InsetsState insetsState,
- InsetsSourceControl[] activeControls) {
- return getAddFlags();
- }
- }
-
- private static class WindowSessionDelegateSV2 extends WindowSessionDelegateS {
- // @Implementation(minSdk = S_V2)
- public int addToDisplayAsUser(
- IWindow window,
- WindowManager.LayoutParams attrs,
- int viewVisibility,
- int displayId,
- int userId,
- InsetsVisibilities requestedVisibilities,
- InputChannel outInputChannel,
- InsetsState outInsetsState,
- InsetsSourceControl[] outActiveControls) {
- return getAddFlags();
+ public Object performDrag(Object[] args) {
+ // extract the clipData param
+ for (int i = args.length - 1; i >= 0; i--) {
+ if (args[i] instanceof ClipData) {
+ lastDragClipData = (ClipData) args[i];
+ // In P (SDK 28), the return type changed from boolean to Binder.
+ return RuntimeEnvironment.getApiLevel() >= P ? new Binder() : true;
+ }
+ }
+ throw new AssertionError("Missing ClipData param");
}
}
}