summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/test-current.txt1
-rw-r--r--core/java/android/provider/DeviceConfig.java11
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java18
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java12
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java12
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java33
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java3
7 files changed, 81 insertions, 9 deletions
diff --git a/api/test-current.txt b/api/test-current.txt
index d2dbacb2fb81..fa018a316644 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -2313,6 +2313,7 @@ package android.provider {
}
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 920eb4b51775..e30ba38c127f 100644
--- a/core/java/android/provider/DeviceConfig.java
+++ b/core/java/android/provider/DeviceConfig.java
@@ -325,6 +325,17 @@ public final class DeviceConfig {
*/
@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 1659131d880d..c069b2e8da5c 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 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
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 2db0131a122f..fb57d73c9a21 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.content.pm.PackageManager.PERMISSION_GRANTED;
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 @@ public class WindowManagerService extends IWindowManager.Stub
boolean mWindowsChanged = false;
int mSystemGestureExclusionLimitDp;
+ boolean mSystemGestureExcludedByPreQStickyImmersive;
public interface WindowChangeListener {
public void windowsChanged();
@@ -1142,13 +1144,21 @@ public class WindowManagerService extends IWindowManager.Stub
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 c6c9e1b39db4..b5586bf28751 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.PowerManager.DRAW_WAKE_LOCK;
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.Point;
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 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
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 f49a57534938..f2e7dc6fecae 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.Display.DEFAULT_DISPLAY;
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 @@ public class DisplayContentTests extends WindowTestsBase {
}
@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 c3561f4bf6ab..d034f274f1e1 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 @@ class TestWindowManagerPolicy implements WindowManagerPolicy {
int mRotationToReport = 0;
boolean mKeyguardShowingAndNotOccluded = false;
+ boolean mOkToAnimate = true;
private Runnable mRunnableWhenAddingSplashScreen;
@@ -222,7 +223,7 @@ class TestWindowManagerPolicy implements WindowManagerPolicy {
@Override
public boolean okToAnimate() {
- return true;
+ return mOkToAnimate;
}
@Override