diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 55a6df28df728..ece805c129cb9 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -301,6 +301,7 @@ package android { field public static final String SET_POINTER_SPEED = "android.permission.SET_POINTER_SPEED"; field public static final String SET_SCREEN_COMPATIBILITY = "android.permission.SET_SCREEN_COMPATIBILITY"; field public static final String SET_SYSTEM_AUDIO_CAPTION = "android.permission.SET_SYSTEM_AUDIO_CAPTION"; + field public static final String SET_UNRESTRICTED_KEEP_CLEAR_AREAS = "android.permission.SET_UNRESTRICTED_KEEP_CLEAR_AREAS"; field public static final String SET_VOLUME_KEY_LONG_PRESS_LISTENER = "android.permission.SET_VOLUME_KEY_LONG_PRESS_LISTENER"; field public static final String SET_WALLPAPER_COMPONENT = "android.permission.SET_WALLPAPER_COMPONENT"; field public static final String SET_WALLPAPER_DIM_AMOUNT = "android.permission.SET_WALLPAPER_DIM_AMOUNT"; diff --git a/core/java/android/view/IDisplayWindowListener.aidl b/core/java/android/view/IDisplayWindowListener.aidl index 449e9b325904b..67ae7430e0b7f 100644 --- a/core/java/android/view/IDisplayWindowListener.aidl +++ b/core/java/android/view/IDisplayWindowListener.aidl @@ -63,5 +63,5 @@ oneway interface IDisplayWindowListener { /** * Called when the keep clear ares on a display have changed. */ - void onKeepClearAreasChanged(int displayId, in List keepClearAreas); + void onKeepClearAreasChanged(int displayId, in List restricted, in List unrestricted); } diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index c62d964cd5186..9c2c9826ef6da 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -6262,6 +6262,15 @@ + + + diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java index e2bc36028405d..9384e2b4dfdf9 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java @@ -245,7 +245,8 @@ public class DisplayController { } } - private void onKeepClearAreasChanged(int displayId, List keepClearAreas) { + private void onKeepClearAreasChanged(int displayId, List restricted, + List unrestricted) { synchronized (mDisplays) { if (mDisplays.get(displayId) == null || getDisplay(displayId) == null) { Slog.w(TAG, "Skipping onKeepClearAreasChanged on unknown" @@ -253,7 +254,8 @@ public class DisplayController { return; } for (int i = mDisplayChangedListeners.size() - 1; i >= 0; --i) { - mDisplayChangedListeners.get(i).onKeepClearAreasChanged(displayId, keepClearAreas); + mDisplayChangedListeners.get(i) + .onKeepClearAreasChanged(displayId, restricted, unrestricted); } } } @@ -318,9 +320,10 @@ public class DisplayController { } @Override - public void onKeepClearAreasChanged(int displayId, List keepClearAreas) { + public void onKeepClearAreasChanged(int displayId, List restricted, + List unrestricted) { mMainExecutor.execute(() -> { - DisplayController.this.onKeepClearAreasChanged(displayId, keepClearAreas); + DisplayController.this.onKeepClearAreasChanged(displayId, restricted, unrestricted); }); } } @@ -361,6 +364,7 @@ public class DisplayController { /** * Called when keep-clear areas on a display have changed. */ - default void onKeepClearAreasChanged(int displayId, List keepClearAreas) {} + default void onKeepClearAreasChanged(int displayId, List restricted, + List unrestricted) {} } } diff --git a/services/core/java/com/android/server/camera/CameraServiceProxy.java b/services/core/java/com/android/server/camera/CameraServiceProxy.java index 1e00ea9161a86..1b0341c1ce26c 100644 --- a/services/core/java/com/android/server/camera/CameraServiceProxy.java +++ b/services/core/java/com/android/server/camera/CameraServiceProxy.java @@ -308,7 +308,8 @@ public class CameraServiceProxy extends SystemService public void onFixedRotationFinished(int displayId) { } @Override - public void onKeepClearAreasChanged(int displayId, List keepClearArea) { } + public void onKeepClearAreasChanged(int displayId, List restricted, + List unrestricted) { } } diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index a1c823e18ccdd..bc917bfa9f225 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -170,7 +170,6 @@ import android.content.res.CompatibilityInfo; import android.content.res.Configuration; import android.graphics.Bitmap; import android.graphics.ColorSpace; -import android.graphics.Insets; import android.graphics.Matrix; import android.graphics.Point; import android.graphics.Rect; @@ -5490,26 +5489,46 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp } void updateKeepClearAreas() { + final List restrictedKeepClearAreas = new ArrayList(); + final List unrestrictedKeepClearAreas = new ArrayList(); + getKeepClearAreas(restrictedKeepClearAreas, unrestrictedKeepClearAreas); mWmService.mDisplayNotificationController.dispatchKeepClearAreasChanged( - this, getKeepClearAreas()); + this, restrictedKeepClearAreas, unrestrictedKeepClearAreas); } /** - * Returns all keep-clear areas from visible windows on this display. + * Fills {@param outRestricted} with all keep-clear areas from visible, relevant windows + * on this display, which set restricted keep-clear areas. + * Fills {@param outUnrestricted} with keep-clear areas from visible, relevant windows on this + * display, which set unrestricted keep-clear areas. + * + * For context on restricted vs unrestricted keep-clear areas, see + * {@link android.Manifest.permission.USE_UNRESTRICTED_KEEP_CLEAR_AREAS}. */ - ArrayList getKeepClearAreas() { - final ArrayList keepClearAreas = new ArrayList(); + void getKeepClearAreas(List outRestricted, List outUnrestricted) { final Matrix tmpMatrix = new Matrix(); final float[] tmpFloat9 = new float[9]; forAllWindows(w -> { if (w.isVisible() && !w.inPinnedWindowingMode()) { - keepClearAreas.addAll(w.getKeepClearAreas(tmpMatrix, tmpFloat9)); + if (w.mSession.mSetsUnrestrictedKeepClearAreas) { + outUnrestricted.addAll(w.getKeepClearAreas(tmpMatrix, tmpFloat9)); + } else { + outRestricted.addAll(w.getKeepClearAreas(tmpMatrix, tmpFloat9)); + } } // We stop traversing when we reach the base of a fullscreen app. return w.getWindowType() == TYPE_BASE_APPLICATION && w.getWindowingMode() == WINDOWING_MODE_FULLSCREEN; }, true); + } + + /** + * Returns all keep-clear areas from visible, relevant windows on this display. + */ + ArrayList getKeepClearAreas() { + final ArrayList keepClearAreas = new ArrayList(); + getKeepClearAreas(keepClearAreas, keepClearAreas); return keepClearAreas; } diff --git a/services/core/java/com/android/server/wm/DisplayWindowListenerController.java b/services/core/java/com/android/server/wm/DisplayWindowListenerController.java index 276dbe9c844aa..e18d5396831a2 100644 --- a/services/core/java/com/android/server/wm/DisplayWindowListenerController.java +++ b/services/core/java/com/android/server/wm/DisplayWindowListenerController.java @@ -120,12 +120,13 @@ class DisplayWindowListenerController { mDisplayListeners.finishBroadcast(); } - void dispatchKeepClearAreasChanged(DisplayContent display, List keepClearAreas) { + void dispatchKeepClearAreasChanged(DisplayContent display, List restricted, + List unrestricted) { int count = mDisplayListeners.beginBroadcast(); for (int i = 0; i < count; ++i) { try { mDisplayListeners.getBroadcastItem(i).onKeepClearAreasChanged( - display.mDisplayId, keepClearAreas); + display.mDisplayId, restricted, unrestricted); } catch (RemoteException e) { } } diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java index 9b94f44be714a..dd7818cbd426e 100644 --- a/services/core/java/com/android/server/wm/Session.java +++ b/services/core/java/com/android/server/wm/Session.java @@ -19,6 +19,7 @@ package com.android.server.wm; import static android.Manifest.permission.HIDE_NON_SYSTEM_OVERLAY_WINDOWS; import static android.Manifest.permission.HIDE_OVERLAY_WINDOWS; import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW; +import static android.Manifest.permission.SET_UNRESTRICTED_KEEP_CLEAR_AREAS; import static android.Manifest.permission.START_TASKS_FROM_RECENTS; import static android.Manifest.permission.SYSTEM_APPLICATION_OVERLAY; import static android.app.ActivityTaskManager.INVALID_TASK_ID; @@ -114,6 +115,7 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { private String mRelayoutTag; private final InsetsVisibilities mDummyRequestedVisibilities = new InsetsVisibilities(); private final InsetsSourceControl[] mDummyControls = new InsetsSourceControl[0]; + final boolean mSetsUnrestrictedKeepClearAreas; public Session(WindowManagerService service, IWindowSessionCallback callback) { mService = service; @@ -132,6 +134,9 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { == PERMISSION_GRANTED; mCanStartTasksFromRecents = service.mContext.checkCallingOrSelfPermission( START_TASKS_FROM_RECENTS) == PERMISSION_GRANTED; + mSetsUnrestrictedKeepClearAreas = + service.mContext.checkCallingOrSelfPermission(SET_UNRESTRICTED_KEEP_CLEAR_AREAS) + == PERMISSION_GRANTED; mShowingAlertWindowNotificationAllowed = mService.mShowAlertWindowNotifications; mDragDropController = mService.mDragDropController; StringBuilder sb = new StringBuilder(); diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java index 7c340ecac2c76..8ada97147dd3f 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java @@ -191,7 +191,8 @@ public class ActivityTaskManagerServiceTests extends WindowTestsBase { public void onFixedRotationFinished(int displayId) {} @Override - public void onKeepClearAreasChanged(int displayId, List keepClearAreas) {} + public void onKeepClearAreasChanged(int displayId, List restricted, + List unrestricted) {} }; int[] displayIds = mAtm.mWindowManager.registerDisplayWindowListener(listener); for (int i = 0; i < displayIds.length; i++) {