Merge "WM: implicitly exclude all edges for pre-Q immersive sticky apps" into qt-dev
am: 8ef731c232
Change-Id: Ie23184e62d410cff170232d15720b22d53f7e6df
diff --git a/api/test-current.txt b/api/test-current.txt
index d2dbacb..fa018a3 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -2313,6 +2313,7 @@
}
public static interface DeviceConfig.WindowManager {
+ field public static final String KEY_SYSTEM_GESTURES_EXCLUDED_BY_PRE_Q_STICKY_IMMERSIVE = "system_gestures_excluded_by_pre_q_sticky_immersive";
field public static final String KEY_SYSTEM_GESTURE_EXCLUSION_LIMIT_DP = "system_gesture_exclusion_limit_dp";
}
diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java
index 920eb4b..e30ba38 100644
--- a/core/java/android/provider/DeviceConfig.java
+++ b/core/java/android/provider/DeviceConfig.java
@@ -325,6 +325,17 @@
*/
@TestApi
String KEY_SYSTEM_GESTURE_EXCLUSION_LIMIT_DP = "system_gesture_exclusion_limit_dp";
+
+ /**
+ * Key for controlling whether system gestures are implicitly excluded by windows requesting
+ * sticky immersive mode from apps that are targeting an SDK prior to Q.
+ *
+ * @see android.provider.DeviceConfig#NAMESPACE_WINDOW_MANAGER
+ * @hide
+ */
+ @TestApi
+ String KEY_SYSTEM_GESTURES_EXCLUDED_BY_PRE_Q_STICKY_IMMERSIVE =
+ "system_gestures_excluded_by_pre_q_sticky_immersive";
}
private static final Object sLock = new Object();
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 1659131..c069b2e 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -5158,15 +5158,19 @@
w.getTouchableRegion(touchableRegion);
touchableRegion.op(unhandled, Op.INTERSECT);
- rectListToRegion(w.getSystemGestureExclusion(), local);
+ if (w.isImplicitlyExcludingAllSystemGestures()) {
+ local.set(touchableRegion);
+ } else {
+ rectListToRegion(w.getSystemGestureExclusion(), local);
- // Transform to display coordinates
- local.scale(w.mGlobalScale);
- final Rect frame = w.getWindowFrames().mFrame;
- local.translate(frame.left, frame.top);
+ // Transform to display coordinates
+ local.scale(w.mGlobalScale);
+ final Rect frame = w.getWindowFrames().mFrame;
+ local.translate(frame.left, frame.top);
- // A window can only exclude system gestures where it is actually touchable
- local.op(touchableRegion, Op.INTERSECT);
+ // A window can only exclude system gestures where it is actually touchable
+ local.op(touchableRegion, Op.INTERSECT);
+ }
// Apply restriction if necessary.
if (needsGestureExclusionRestrictions(w, mLastDispatchedSystemUiVisibility)) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 2db0131..fb57d73 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -32,6 +32,7 @@
import static android.os.Process.SYSTEM_UID;
import static android.os.Process.myPid;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
+import static android.provider.DeviceConfig.WindowManager.KEY_SYSTEM_GESTURES_EXCLUDED_BY_PRE_Q_STICKY_IMMERSIVE;
import static android.provider.DeviceConfig.WindowManager.KEY_SYSTEM_GESTURE_EXCLUSION_LIMIT_DP;
import static android.provider.Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS;
import static android.view.Display.DEFAULT_DISPLAY;
@@ -844,6 +845,7 @@
boolean mWindowsChanged = false;
int mSystemGestureExclusionLimitDp;
+ boolean mSystemGestureExcludedByPreQStickyImmersive;
public interface WindowChangeListener {
public void windowsChanged();
@@ -1142,13 +1144,21 @@
mSystemGestureExclusionLimitDp = Math.max(MIN_GESTURE_EXCLUSION_LIMIT_DP,
DeviceConfig.getInt(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
KEY_SYSTEM_GESTURE_EXCLUSION_LIMIT_DP, 0));
+ mSystemGestureExcludedByPreQStickyImmersive =
+ DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
+ KEY_SYSTEM_GESTURES_EXCLUDED_BY_PRE_Q_STICKY_IMMERSIVE, false);
DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
new HandlerExecutor(mH), properties -> {
synchronized (mGlobalLock) {
final int exclusionLimitDp = Math.max(MIN_GESTURE_EXCLUSION_LIMIT_DP,
properties.getInt(KEY_SYSTEM_GESTURE_EXCLUSION_LIMIT_DP, 0));
- if (mSystemGestureExclusionLimitDp != exclusionLimitDp) {
+ final boolean excludedByPreQSticky = DeviceConfig.getBoolean(
+ DeviceConfig.NAMESPACE_WINDOW_MANAGER,
+ KEY_SYSTEM_GESTURES_EXCLUDED_BY_PRE_Q_STICKY_IMMERSIVE, false);
+ if (mSystemGestureExcludedByPreQStickyImmersive != excludedByPreQSticky
+ || mSystemGestureExclusionLimitDp != exclusionLimitDp) {
mSystemGestureExclusionLimitDp = exclusionLimitDp;
+ mSystemGestureExcludedByPreQStickyImmersive = excludedByPreQSticky;
mRoot.forAllDisplays(DisplayContent::updateSystemGestureExclusionLimit);
}
}
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index c6c9e1b..b5586bf 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -24,6 +24,8 @@
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.SurfaceControl.Transaction;
+import static android.view.View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
+import static android.view.View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT;
import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION;
@@ -155,6 +157,7 @@
import android.graphics.Rect;
import android.graphics.Region;
import android.os.Binder;
+import android.os.Build;
import android.os.Debug;
import android.os.IBinder;
import android.os.PowerManager;
@@ -657,6 +660,15 @@
return true;
}
+ boolean isImplicitlyExcludingAllSystemGestures() {
+ final int immersiveStickyFlags =
+ SYSTEM_UI_FLAG_HIDE_NAVIGATION | SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
+ final boolean immersiveSticky =
+ (mSystemUiVisibility & immersiveStickyFlags) == immersiveStickyFlags;
+ return immersiveSticky && mWmService.mSystemGestureExcludedByPreQStickyImmersive
+ && mAppToken != null && mAppToken.mTargetSdk < Build.VERSION_CODES.Q;
+ }
+
interface PowerManagerWrapper {
void wakeUp(long time, @WakeReason int reason, String details);
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index f49a575..f2e7dc6 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -26,8 +26,13 @@
import static android.view.DisplayCutout.BOUNDS_POSITION_LEFT;
import static android.view.DisplayCutout.BOUNDS_POSITION_TOP;
import static android.view.DisplayCutout.fromBoundingRect;
+import static android.view.View.SYSTEM_UI_FLAG_FULLSCREEN;
+import static android.view.View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
+import static android.view.View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
+import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
@@ -789,6 +794,34 @@
}
@Test
+ public void testCalculateSystemGestureExclusion_immersiveStickyLegacyWindow() throws Exception {
+ synchronized (mWm.mGlobalLock) {
+ mWm.mSystemGestureExcludedByPreQStickyImmersive = true;
+
+ final DisplayContent dc = createNewDisplay();
+ final WindowState win = createWindow(null, TYPE_BASE_APPLICATION, dc, "win");
+ win.getAttrs().flags |= FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR;
+ win.getAttrs().layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
+ win.getAttrs().privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION;
+ win.getAttrs().subtreeSystemUiVisibility = win.mSystemUiVisibility =
+ SYSTEM_UI_FLAG_FULLSCREEN | SYSTEM_UI_FLAG_HIDE_NAVIGATION
+ | SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
+ win.mAppToken.mTargetSdk = P;
+
+ dc.setLayoutNeeded();
+ dc.performLayout(true /* initial */, false /* updateImeWindows */);
+
+ win.setHasSurface(true);
+
+ final Region expected = Region.obtain();
+ expected.set(dc.getBounds());
+ assertEquals(expected, dc.calculateSystemGestureExclusion());
+
+ win.setHasSurface(false);
+ }
+ }
+
+ @Test
public void testOrientationChangeLogging() {
MetricsLogger mockLogger = mock(MetricsLogger.class);
Configuration oldConfig = new Configuration();
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
index c3561f4..d034f27 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -49,6 +49,7 @@
int mRotationToReport = 0;
boolean mKeyguardShowingAndNotOccluded = false;
+ boolean mOkToAnimate = true;
private Runnable mRunnableWhenAddingSplashScreen;
@@ -222,7 +223,7 @@
@Override
public boolean okToAnimate() {
- return true;
+ return mOkToAnimate;
}
@Override