diff --git a/core/java/android/view/InsetsState.java b/core/java/android/view/InsetsState.java index 70a7739949269..ba7d823750a3f 100644 --- a/core/java/android/view/InsetsState.java +++ b/core/java/android/view/InsetsState.java @@ -781,19 +781,6 @@ public class InsetsState implements Parcelable { } } - public static boolean containsType(@InternalInsetsType int[] types, - @InternalInsetsType int type) { - if (types == null) { - return false; - } - for (int t : types) { - if (t == type) { - return true; - } - } - return false; - } - public void dump(String prefix, PrintWriter pw) { final String newPrefix = prefix + " "; pw.println(prefix + "InsetsState"); diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl index 1c85ca2bb2697..b529a10164641 100644 --- a/core/java/com/android/internal/statusbar/IStatusBar.aidl +++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl @@ -214,11 +214,11 @@ oneway interface IStatusBar * bar and navigation bar which are temporarily visible to the user. * * @param displayId the ID of the display to notify. - * @param types the internal insets types of the bars are about to show transiently. + * @param types the insets types of the bars are about to show transiently. * @param isGestureOnSystemBar whether the gesture to show the transient bar was a gesture on * one of the bars itself. */ - void showTransient(int displayId, in int[] types, boolean isGestureOnSystemBar); + void showTransient(int displayId, int types, boolean isGestureOnSystemBar); /** * Notifies System UI to abort the transient state of system bars, which prevents the bars being @@ -226,9 +226,9 @@ oneway interface IStatusBar * bars again. * * @param displayId the ID of the display to notify. - * @param types the internal insets types of the bars are about to abort the transient state. + * @param types the insets types of the bars are about to abort the transient state. */ - void abortTransient(int displayId, in int[] types); + void abortTransient(int displayId, int types); /** * Show a warning that the device is about to go to sleep due to user inactivity. diff --git a/core/java/com/android/internal/statusbar/RegisterStatusBarResult.java b/core/java/com/android/internal/statusbar/RegisterStatusBarResult.java index 54221ce92dc4a..4f827cda6afaf 100644 --- a/core/java/com/android/internal/statusbar/RegisterStatusBarResult.java +++ b/core/java/com/android/internal/statusbar/RegisterStatusBarResult.java @@ -16,7 +16,6 @@ package com.android.internal.statusbar; -import android.annotation.NonNull; import android.os.IBinder; import android.os.Parcel; import android.os.Parcelable; @@ -41,15 +40,14 @@ public final class RegisterStatusBarResult implements Parcelable { public final int mBehavior; public final int mRequestedVisibleTypes; public final String mPackageName; - public final int[] mTransientBarTypes; + public final int mTransientBarTypes; public final LetterboxDetails[] mLetterboxDetails; public RegisterStatusBarResult(ArrayMap icons, int disabledFlags1, int appearance, AppearanceRegion[] appearanceRegions, int imeWindowVis, int imeBackDisposition, boolean showImeSwitcher, int disabledFlags2, IBinder imeToken, boolean navbarColorManagedByIme, int behavior, int requestedVisibleTypes, - String packageName, @NonNull int[] transientBarTypes, - LetterboxDetails[] letterboxDetails) { + String packageName, int transientBarTypes, LetterboxDetails[] letterboxDetails) { mIcons = new ArrayMap<>(icons); mDisabledFlags1 = disabledFlags1; mAppearance = appearance; @@ -87,7 +85,7 @@ public final class RegisterStatusBarResult implements Parcelable { dest.writeInt(mBehavior); dest.writeInt(mRequestedVisibleTypes); dest.writeString(mPackageName); - dest.writeIntArray(mTransientBarTypes); + dest.writeInt(mTransientBarTypes); dest.writeParcelableArray(mLetterboxDetails, flags); } @@ -113,7 +111,7 @@ public final class RegisterStatusBarResult implements Parcelable { final int behavior = source.readInt(); final int requestedVisibleTypes = source.readInt(); final String packageName = source.readString(); - final int[] transientBarTypes = source.createIntArray(); + final int transientBarTypes = source.readInt(); final LetterboxDetails[] letterboxDetails = source.readParcelableArray(null, LetterboxDetails.class); return new RegisterStatusBarResult(icons, disabledFlags1, appearance, diff --git a/core/tests/coretests/src/com/android/internal/statusbar/RegisterStatusBarResultTest.java b/core/tests/coretests/src/com/android/internal/statusbar/RegisterStatusBarResultTest.java index 048c48bc45fae..f79ba28d946f5 100644 --- a/core/tests/coretests/src/com/android/internal/statusbar/RegisterStatusBarResultTest.java +++ b/core/tests/coretests/src/com/android/internal/statusbar/RegisterStatusBarResultTest.java @@ -67,7 +67,7 @@ public class RegisterStatusBarResultTest { BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE, WindowInsets.Type.defaultVisible(), "test" /* packageName */, - new int[0] /* transientBarTypes */, + 0 /* transientBarTypes */, new LetterboxDetails[] {letterboxDetails}); final RegisterStatusBarResult copy = clone(original); diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java index 79b4b3a4ab28b..f2c422986e5b1 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java @@ -30,7 +30,6 @@ import static android.view.InsetsState.ITYPE_BOTTOM_TAPPABLE_ELEMENT; import static android.view.InsetsState.ITYPE_LEFT_GESTURES; import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; import static android.view.InsetsState.ITYPE_RIGHT_GESTURES; -import static android.view.InsetsState.containsType; import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE; import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION; @@ -85,7 +84,6 @@ import android.view.DisplayCutout; import android.view.Gravity; import android.view.HapticFeedbackConstants; import android.view.InsetsFrameProvider; -import android.view.InsetsState.InternalInsetsType; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.Surface; @@ -97,6 +95,7 @@ import android.view.ViewRootImpl.SurfaceChangedCallback; import android.view.ViewTreeObserver; import android.view.ViewTreeObserver.InternalInsetsInfo; import android.view.ViewTreeObserver.OnComputeInternalInsetsListener; +import android.view.WindowInsets; import android.view.WindowInsets.Type.InsetsType; import android.view.WindowInsetsController.Appearance; import android.view.WindowInsetsController.Behavior; @@ -1150,12 +1149,11 @@ public class NavigationBar extends ViewController implements } @Override - public void showTransient(int displayId, @InternalInsetsType int[] types, - boolean isGestureOnSystemBar) { + public void showTransient(int displayId, @InsetsType int types, boolean isGestureOnSystemBar) { if (displayId != mDisplayId) { return; } - if (!containsType(types, ITYPE_NAVIGATION_BAR)) { + if ((types & WindowInsets.Type.navigationBars()) == 0) { return; } if (!mTransientShown) { @@ -1166,11 +1164,11 @@ public class NavigationBar extends ViewController implements } @Override - public void abortTransient(int displayId, @InternalInsetsType int[] types) { + public void abortTransient(int displayId, @InsetsType int types) { if (displayId != mDisplayId) { return; } - if (!containsType(types, ITYPE_NAVIGATION_BAR)) { + if ((types & WindowInsets.Type.navigationBars()) == 0) { return; } clearTransient(); diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java index f3712e66e330b..c3d736917b5df 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java @@ -20,8 +20,6 @@ import static android.app.ActivityManager.LOCK_TASK_MODE_PINNED; import static android.app.StatusBarManager.NAVIGATION_HINT_BACK_ALT; import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SWITCHER_SHOWN; import static android.app.StatusBarManager.WINDOW_STATE_SHOWING; -import static android.view.InsetsState.ITYPE_EXTRA_NAVIGATION_BAR; -import static android.view.InsetsState.containsType; import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; @@ -41,7 +39,6 @@ import static com.android.systemui.statusbar.phone.BarTransitions.TransitionMode import android.app.StatusBarManager; import android.app.StatusBarManager.WindowVisibleState; -import android.content.ComponentName; import android.content.Context; import android.content.res.Configuration; import android.graphics.Rect; @@ -52,6 +49,7 @@ import android.os.RemoteException; import android.util.Log; import android.view.Display; import android.view.View; +import android.view.WindowInsets; import android.view.WindowInsets.Type.InsetsType; import android.view.WindowInsetsController.Appearance; import android.view.WindowInsetsController.Behavior; @@ -68,7 +66,6 @@ import com.android.systemui.model.SysUiState; import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler; import com.android.systemui.recents.OverviewProxyService; import com.android.systemui.shared.recents.utilities.Utilities; -import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.QuickStepContract; import com.android.systemui.shared.system.TaskStackChangeListener; import com.android.systemui.shared.system.TaskStackChangeListeners; @@ -401,11 +398,11 @@ public class TaskbarDelegate implements CommandQueue.Callbacks, } @Override - public void showTransient(int displayId, int[] types, boolean isGestureOnSystemBar) { + public void showTransient(int displayId, @InsetsType int types, boolean isGestureOnSystemBar) { if (displayId != mDisplayId) { return; } - if (!containsType(types, ITYPE_EXTRA_NAVIGATION_BAR)) { + if ((types & WindowInsets.Type.navigationBars()) == 0) { return; } if (!mTaskbarTransientShowing) { @@ -415,11 +412,11 @@ public class TaskbarDelegate implements CommandQueue.Callbacks, } @Override - public void abortTransient(int displayId, int[] types) { + public void abortTransient(int displayId, @InsetsType int types) { if (displayId != mDisplayId) { return; } - if (!containsType(types, ITYPE_EXTRA_NAVIGATION_BAR)) { + if ((types & WindowInsets.Type.navigationBars()) == 0) { return; } clearTransient(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java index 3aaad87b8eab8..2cf1f53b4499b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java @@ -53,7 +53,6 @@ import android.os.Process; import android.os.RemoteException; import android.util.Pair; import android.util.SparseArray; -import android.view.InsetsState.InternalInsetsType; import android.view.WindowInsets.Type.InsetsType; import android.view.WindowInsetsController.Appearance; import android.view.WindowInsetsController.Behavior; @@ -371,22 +370,22 @@ public class CommandQueue extends IStatusBar.Stub implements String packageName, LetterboxDetails[] letterboxDetails) { } /** - * @see IStatusBar#showTransient(int, int[], boolean). + * @see IStatusBar#showTransient(int, int, boolean). */ - default void showTransient(int displayId, @InternalInsetsType int[] types) { } + default void showTransient(int displayId, @InsetsType int types) { } /** - * @see IStatusBar#showTransient(int, int[], boolean). + * @see IStatusBar#showTransient(int, int, boolean). */ - default void showTransient(int displayId, @InternalInsetsType int[] types, + default void showTransient(int displayId, @InsetsType int types, boolean isGestureOnSystemBar) { showTransient(displayId, types); } /** - * @see IStatusBar#abortTransient(int, int[]). + * @see IStatusBar#abortTransient(int, int). */ - default void abortTransient(int displayId, @InternalInsetsType int[] types) { } + default void abortTransient(int displayId, @InsetsType int types) { } /** * Called to notify System UI that a warning about the device going to sleep @@ -1131,17 +1130,23 @@ public class CommandQueue extends IStatusBar.Stub implements } @Override - public void showTransient(int displayId, int[] types, boolean isGestureOnSystemBar) { + public void showTransient(int displayId, int types, boolean isGestureOnSystemBar) { synchronized (mLock) { - mHandler.obtainMessage(MSG_SHOW_TRANSIENT, displayId, isGestureOnSystemBar ? 1 : 0, - types).sendToTarget(); + SomeArgs args = SomeArgs.obtain(); + args.argi1 = displayId; + args.argi2 = types; + args.argi3 = isGestureOnSystemBar ? 1 : 0; + mHandler.obtainMessage(MSG_SHOW_TRANSIENT, args).sendToTarget(); } } @Override - public void abortTransient(int displayId, int[] types) { + public void abortTransient(int displayId, int types) { synchronized (mLock) { - mHandler.obtainMessage(MSG_ABORT_TRANSIENT, displayId, 0, types).sendToTarget(); + SomeArgs args = SomeArgs.obtain(); + args.argi1 = displayId; + args.argi2 = types; + mHandler.obtainMessage(MSG_ABORT_TRANSIENT, args).sendToTarget(); } } @@ -1644,17 +1649,21 @@ public class CommandQueue extends IStatusBar.Stub implements args.recycle(); break; case MSG_SHOW_TRANSIENT: { - final int displayId = msg.arg1; - final int[] types = (int[]) msg.obj; - final boolean isGestureOnSystemBar = msg.arg2 != 0; + args = (SomeArgs) msg.obj; + final int displayId = args.argi1; + final int types = args.argi2; + final boolean isGestureOnSystemBar = args.argi3 != 0; + args.recycle(); for (int i = 0; i < mCallbacks.size(); i++) { mCallbacks.get(i).showTransient(displayId, types, isGestureOnSystemBar); } break; } case MSG_ABORT_TRANSIENT: { - final int displayId = msg.arg1; - final int[] types = (int[]) msg.obj; + args = (SomeArgs) msg.obj; + final int displayId = args.argi1; + final int types = args.argi2; + args.recycle(); for (int i = 0; i < mCallbacks.size(); i++) { mCallbacks.get(i).abortTransient(displayId, types); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java index 856d7dedb4eb0..fecaa3a0caf5a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java @@ -16,9 +16,6 @@ package com.android.systemui.statusbar.phone; -import static android.view.InsetsState.ITYPE_STATUS_BAR; -import static android.view.InsetsState.containsType; - import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_AWAKE; import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_WAKING; @@ -36,8 +33,8 @@ import android.os.VibrationEffect; import android.os.Vibrator; import android.util.Log; import android.util.Slog; -import android.view.InsetsState.InternalInsetsType; import android.view.KeyEvent; +import android.view.WindowInsets; import android.view.WindowInsets.Type.InsetsType; import android.view.WindowInsetsController.Appearance; import android.view.WindowInsetsController.Behavior; @@ -168,11 +165,11 @@ public class CentralSurfacesCommandQueueCallbacks implements CommandQueue.Callba } @Override - public void abortTransient(int displayId, @InternalInsetsType int[] types) { + public void abortTransient(int displayId, @InsetsType int types) { if (displayId != mDisplayId) { return; } - if (!containsType(types, ITYPE_STATUS_BAR)) { + if ((types & WindowInsets.Type.statusBars()) == 0) { return; } mCentralSurfaces.clearTransient(); @@ -489,12 +486,11 @@ public class CentralSurfacesCommandQueueCallbacks implements CommandQueue.Callba } @Override - public void showTransient(int displayId, @InternalInsetsType int[] types, - boolean isGestureOnSystemBar) { + public void showTransient(int displayId, @InsetsType int types, boolean isGestureOnSystemBar) { if (displayId != mDisplayId) { return; } - if (!containsType(types, ITYPE_STATUS_BAR)) { + if ((types & WindowInsets.Type.statusBars()) == 0) { return; } mCentralSurfaces.showTransientUnchecked(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java index e595ddf46a89b..1966a6657acbe 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java @@ -21,8 +21,6 @@ import static android.app.StatusBarManager.WINDOW_STATE_HIDDEN; import static android.app.StatusBarManager.WINDOW_STATE_SHOWING; import static android.app.StatusBarManager.WindowVisibleState; import static android.app.StatusBarManager.windowStateToString; -import static android.view.InsetsState.ITYPE_STATUS_BAR; -import static android.view.InsetsState.containsType; import static android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_BARS; import static android.view.WindowInsetsController.APPEARANCE_OPAQUE_STATUS_BARS; import static android.view.WindowInsetsController.APPEARANCE_SEMI_TRANSPARENT_STATUS_BARS; @@ -100,6 +98,7 @@ import android.view.ThreadedRenderer; import android.view.View; import android.view.ViewGroup; import android.view.ViewRootImpl; +import android.view.WindowInsets; import android.view.WindowInsetsController.Appearance; import android.view.WindowManager; import android.view.WindowManagerGlobal; @@ -943,7 +942,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { // Set up the initial notification state. This needs to happen before CommandQueue.disable() setUpPresenter(); - if (containsType(result.mTransientBarTypes, ITYPE_STATUS_BAR)) { + if ((result.mTransientBarTypes & WindowInsets.Type.statusBars()) != 0) { showTransientUnchecked(); } mCommandQueueCallbacks.onSystemBarAttributesChanged(mDisplayId, result.mAppearance, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java index b1ca1c02f6daf..f581154f66c02 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java @@ -18,8 +18,6 @@ import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE; import static android.inputmethodservice.InputMethodService.BACK_DISPOSITION_DEFAULT; import static android.inputmethodservice.InputMethodService.IME_INVISIBLE; import static android.view.Display.DEFAULT_DISPLAY; -import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; -import static android.view.InsetsState.ITYPE_STATUS_BAR; import static android.view.WindowInsetsController.BEHAVIOR_DEFAULT; import static org.mockito.ArgumentMatchers.anyInt; @@ -158,7 +156,7 @@ public class CommandQueueTest extends SysuiTestCase { @Test public void testShowTransient() { - int[] types = new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR}; + int types = WindowInsets.Type.statusBars() | WindowInsets.Type.navigationBars(); mCommandQueue.showTransient(DEFAULT_DISPLAY, types, true /* isGestureOnSystemBar */); waitForIdleSync(); verify(mCallbacks).showTransient(eq(DEFAULT_DISPLAY), eq(types), eq(true)); @@ -166,7 +164,7 @@ public class CommandQueueTest extends SysuiTestCase { @Test public void testShowTransientForSecondaryDisplay() { - int[] types = new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR}; + int types = WindowInsets.Type.statusBars() | WindowInsets.Type.navigationBars(); mCommandQueue.showTransient(SECONDARY_DISPLAY, types, true /* isGestureOnSystemBar */); waitForIdleSync(); verify(mCallbacks).showTransient(eq(SECONDARY_DISPLAY), eq(types), eq(true)); @@ -174,7 +172,7 @@ public class CommandQueueTest extends SysuiTestCase { @Test public void testAbortTransient() { - int[] types = new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR}; + int types = WindowInsets.Type.statusBars() | WindowInsets.Type.navigationBars(); mCommandQueue.abortTransient(DEFAULT_DISPLAY, types); waitForIdleSync(); verify(mCallbacks).abortTransient(eq(DEFAULT_DISPLAY), eq(types)); @@ -182,7 +180,7 @@ public class CommandQueueTest extends SysuiTestCase { @Test public void testAbortTransientForSecondaryDisplay() { - int[] types = new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR}; + int types = WindowInsets.Type.statusBars() | WindowInsets.Type.navigationBars(); mCommandQueue.abortTransient(SECONDARY_DISPLAY, types); waitForIdleSync(); verify(mCallbacks).abortTransient(eq(SECONDARY_DISPLAY), eq(types)); diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java index 5521384bb1693..ec052ecd20f29 100644 --- a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java +++ b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java @@ -21,7 +21,6 @@ import android.app.ITransientNotificationCallback; import android.hardware.fingerprint.IUdfpsRefreshRateRequestCallback; import android.os.Bundle; import android.os.IBinder; -import android.view.InsetsState.InternalInsetsType; import android.view.WindowInsets.Type.InsetsType; import android.view.WindowInsetsController.Appearance; import android.view.WindowInsetsController.Behavior; @@ -162,11 +161,10 @@ public interface StatusBarManagerInternal { LetterboxDetails[] letterboxDetails); /** @see com.android.internal.statusbar.IStatusBar#showTransient */ - void showTransient(int displayId, @InternalInsetsType int[] types, - boolean isGestureOnSystemBar); + void showTransient(int displayId, @InsetsType int types, boolean isGestureOnSystemBar); /** @see com.android.internal.statusbar.IStatusBar#abortTransient */ - void abortTransient(int displayId, @InternalInsetsType int[] types); + void abortTransient(int displayId, @InsetsType int types); /** * @see com.android.internal.statusbar.IStatusBar#showToast(String, IBinder, CharSequence, diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java index 83f4805aca58a..4489ba94235ce 100644 --- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java +++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java @@ -79,12 +79,10 @@ import android.service.notification.NotificationStats; import android.service.quicksettings.TileService; import android.text.TextUtils; import android.util.ArrayMap; -import android.util.ArraySet; import android.util.IndentingPrintWriter; import android.util.Pair; import android.util.Slog; import android.util.SparseArray; -import android.view.InsetsState.InternalInsetsType; import android.view.WindowInsets; import android.view.WindowInsets.Type.InsetsType; import android.view.WindowInsetsController.Appearance; @@ -645,7 +643,7 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D } @Override - public void showTransient(int displayId, @InternalInsetsType int[] types, + public void showTransient(int displayId, @InsetsType int types, boolean isGestureOnSystemBar) { getUiState(displayId).showTransient(types); if (mBar != null) { @@ -656,7 +654,7 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D } @Override - public void abortTransient(int displayId, @InternalInsetsType int[] types) { + public void abortTransient(int displayId, @InsetsType int types) { getUiState(displayId).clearTransient(types); if (mBar != null) { try { @@ -1258,7 +1256,7 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D private static class UiState { private @Appearance int mAppearance = 0; private AppearanceRegion[] mAppearanceRegions = new AppearanceRegion[0]; - private final ArraySet mTransientBarTypes = new ArraySet<>(); + private @InsetsType int mTransientBarTypes; private boolean mNavbarColorManagedByIme = false; private @Behavior int mBehavior; private @InsetsType int mRequestedVisibleTypes = WindowInsets.Type.defaultVisible(); @@ -1285,16 +1283,12 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D mLetterboxDetails = letterboxDetails; } - private void showTransient(@InternalInsetsType int[] types) { - for (int type : types) { - mTransientBarTypes.add(type); - } + private void showTransient(@InsetsType int types) { + mTransientBarTypes |= types; } - private void clearTransient(@InternalInsetsType int[] types) { - for (int type : types) { - mTransientBarTypes.remove(type); - } + private void clearTransient(@InsetsType int types) { + mTransientBarTypes &= ~types; } private int getDisabled1() { @@ -1410,16 +1404,12 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D // TODO(b/118592525): Currently, status bar only works on the default display. // Make it aware of multi-display if needed. final UiState state = mDisplayUiState.get(DEFAULT_DISPLAY); - final int[] transientBarTypes = new int[state.mTransientBarTypes.size()]; - for (int i = 0; i < transientBarTypes.length; i++) { - transientBarTypes[i] = state.mTransientBarTypes.valueAt(i); - } return new RegisterStatusBarResult(icons, gatherDisableActionsLocked(mCurrentUserId, 1), state.mAppearance, state.mAppearanceRegions, state.mImeWindowVis, state.mImeBackDisposition, state.mShowImeSwitcher, gatherDisableActionsLocked(mCurrentUserId, 2), state.mImeToken, state.mNavbarColorManagedByIme, state.mBehavior, state.mRequestedVisibleTypes, - state.mPackageName, transientBarTypes, state.mLetterboxDetails); + state.mPackageName, state.mTransientBarTypes, state.mLetterboxDetails); } } diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index e87680ac5a16f..7c12dbc7964b4 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -171,9 +171,8 @@ public class DisplayPolicy { /** Use the transit animation in style resource (see {@link #selectAnimation}). */ static final int ANIMATION_STYLEABLE = 0; - private static final int[] SHOW_TYPES_FOR_SWIPE = {ITYPE_NAVIGATION_BAR, ITYPE_STATUS_BAR, - ITYPE_CLIMATE_BAR, ITYPE_EXTRA_NAVIGATION_BAR}; - private static final int[] SHOW_TYPES_FOR_PANIC = {ITYPE_NAVIGATION_BAR}; + private static final int SHOW_TYPES_FOR_SWIPE = Type.statusBars() | Type.navigationBars(); + private static final int SHOW_TYPES_FOR_PANIC = Type.navigationBars(); private final WindowManagerService mService; private final Context mContext; @@ -251,7 +250,7 @@ public class DisplayPolicy { private boolean mIsFreeformWindowOverlappingWithNavBar; - private boolean mLastImmersiveMode; + private boolean mIsImmersiveMode; // The windows we were told about in focusChanged. private WindowState mFocusedWindow; @@ -2171,14 +2170,27 @@ public class DisplayPolicy { appearance = configureNavBarOpacity(appearance, multiWindowTaskVisible, freeformRootTaskVisible); + // Show immersive mode confirmation if needed. + final boolean wasImmersiveMode = mIsImmersiveMode; + final boolean isImmersiveMode = isImmersiveMode(win); + if (wasImmersiveMode != isImmersiveMode) { + mIsImmersiveMode = isImmersiveMode; + // The immersive confirmation window should be attached to the immersive window root. + final RootDisplayArea root = win.getRootDisplayArea(); + final int rootDisplayAreaId = root == null ? FEATURE_UNDEFINED : root.mFeatureId; + mImmersiveModeConfirmation.immersiveModeChangedLw(rootDisplayAreaId, isImmersiveMode, + mService.mPolicy.isUserSetupComplete(), + isNavBarEmpty(disableFlags)); + } + + // Show transient bars for panic if needed. final boolean requestHideNavBar = !win.isRequestedVisible(Type.navigationBars()); final long now = SystemClock.uptimeMillis(); final boolean pendingPanic = mPendingPanicGestureUptime != 0 && now - mPendingPanicGestureUptime <= PANIC_GESTURE_EXPIRATION; final DisplayPolicy defaultDisplayPolicy = mService.getDefaultDisplayContentLocked().getDisplayPolicy(); - if (pendingPanic && requestHideNavBar && win != mNotificationShade - && getInsetsPolicy().isHidden(ITYPE_NAVIGATION_BAR) + if (pendingPanic && requestHideNavBar && isImmersiveMode // TODO (b/111955725): Show keyguard presentation on all external displays && defaultDisplayPolicy.isKeyguardDrawComplete()) { // The user performed the panic gesture recently, we're about to hide the bars, @@ -2190,19 +2202,6 @@ public class DisplayPolicy { } } - // update navigation bar - boolean oldImmersiveMode = mLastImmersiveMode; - boolean newImmersiveMode = isImmersiveMode(win); - if (oldImmersiveMode != newImmersiveMode) { - mLastImmersiveMode = newImmersiveMode; - // The immersive confirmation window should be attached to the immersive window root. - final RootDisplayArea root = win.getRootDisplayArea(); - final int rootDisplayAreaId = root == null ? FEATURE_UNDEFINED : root.mFeatureId; - mImmersiveModeConfirmation.immersiveModeChangedLw(rootDisplayAreaId, newImmersiveMode, - mService.mPolicy.isUserSetupComplete(), - isNavBarEmpty(disableFlags)); - } - return appearance; } @@ -2324,18 +2323,10 @@ public class DisplayPolicy { if (win == null) { return false; } - return getNavigationBar() != null - && canHideNavigationBar() - && getInsetsPolicy().isHidden(ITYPE_NAVIGATION_BAR) - && win != getNotificationShade() - && !win.isActivityTypeDream(); - } - - /** - * @return whether the navigation bar can be hidden, e.g. the device has a navigation bar - */ - private boolean canHideNavigationBar() { - return hasNavigationBar(); + if (win == getNotificationShade() || win.isActivityTypeDream()) { + return false; + } + return getInsetsPolicy().hasHiddenSources(Type.navigationBars()); } private static boolean isNavBarEmpty(int systemUiFlags) { diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java index bd821134f9b73..f5d29ed54921f 100644 --- a/services/core/java/com/android/server/wm/InsetsPolicy.java +++ b/services/core/java/com/android/server/wm/InsetsPolicy.java @@ -26,8 +26,6 @@ import static android.view.InsetsController.ANIMATION_TYPE_SHOW; import static android.view.InsetsController.LAYOUT_INSETS_DURING_ANIMATION_HIDDEN; import static android.view.InsetsController.LAYOUT_INSETS_DURING_ANIMATION_SHOWN; import static android.view.InsetsSource.ID_IME; -import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; -import static android.view.InsetsState.ITYPE_STATUS_BAR; import static android.view.SyncRtSurfaceTransactionApplier.applyParams; import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR; @@ -42,7 +40,6 @@ import android.app.WindowConfiguration; import android.content.ComponentName; import android.content.res.Resources; import android.util.ArrayMap; -import android.util.IntArray; import android.util.SparseArray; import android.view.InsetsAnimationControlCallbacks; import android.view.InsetsAnimationControlImpl; @@ -52,7 +49,6 @@ import android.view.InsetsFrameProvider; import android.view.InsetsSource; import android.view.InsetsSourceControl; import android.view.InsetsState; -import android.view.InsetsState.InternalInsetsType; import android.view.InternalInsetsAnimationController; import android.view.SurfaceControl; import android.view.SyncRtSurfaceTransactionApplier; @@ -81,7 +77,6 @@ class InsetsPolicy { private final InsetsStateController mStateController; private final DisplayContent mDisplayContent; private final DisplayPolicy mPolicy; - private final IntArray mShowingTransientTypes = new IntArray(); /** For resetting visibilities of insets sources. */ private final InsetsControlTarget mDummyControlTarget = new InsetsControlTarget() { @@ -95,7 +90,7 @@ class InsetsPolicy { return; } for (InsetsSourceControl control : controls) { - if (mShowingTransientTypes.indexOf(control.getId()) != -1) { + if (isTransient(control.getType())) { // The visibilities of transient bars will be handled with animations. continue; } @@ -117,13 +112,16 @@ class InsetsPolicy { }; private WindowState mFocusedWin; - private BarWindow mStatusBar = new BarWindow(StatusBarManager.WINDOW_STATUS_BAR); - private BarWindow mNavBar = new BarWindow(StatusBarManager.WINDOW_NAVIGATION_BAR); + private final BarWindow mStatusBar = new BarWindow(StatusBarManager.WINDOW_STATUS_BAR); + private final BarWindow mNavBar = new BarWindow(StatusBarManager.WINDOW_NAVIGATION_BAR); + private @InsetsType int mShowingTransientTypes; private boolean mAnimatingShown; + /** * Let remote insets controller control system bars regardless of other settings. */ private boolean mRemoteInsetsControllerControlsSystemBars; + private final boolean mHideNavBarForKeyboard; private final float[] mTmpFloat9 = new float[9]; @@ -178,37 +176,46 @@ class InsetsPolicy { mNavBar.updateVisibility(navControlTarget, Type.navigationBars()); } - boolean isHidden(@InternalInsetsType int type) { - final WindowContainerInsetsSourceProvider provider = mStateController - .peekSourceProvider(type); - return provider != null && provider.hasWindowContainer() - && !provider.getSource().isVisible(); + boolean hasHiddenSources(@InsetsType int types) { + final InsetsState state = mStateController.getRawInsetsState(); + for (int i = state.sourceSize() - 1; i >= 0; i--) { + final InsetsSource source = state.sourceAt(i); + if ((source.getType() & types) == 0) { + continue; + } + if (!source.getFrame().isEmpty() && !source.isVisible()) { + return true; + } + } + return false; } - void showTransient(@InternalInsetsType int[] types, boolean isGestureOnSystemBar) { - boolean changed = false; - for (int i = types.length - 1; i >= 0; i--) { - final @InternalInsetsType int type = types[i]; - if (!isHidden(type)) { + void showTransient(@InsetsType int types, boolean isGestureOnSystemBar) { + @InsetsType int showingTransientTypes = mShowingTransientTypes; + final InsetsState rawState = mStateController.getRawInsetsState(); + for (int i = rawState.sourceSize() - 1; i >= 0; i--) { + final InsetsSource source = rawState.sourceAt(i); + if (source.isVisible()) { continue; } - if (mShowingTransientTypes.indexOf(type) != -1) { + final @InsetsType int type = source.getType(); + if ((source.getType() & types) == 0) { continue; } - mShowingTransientTypes.add(type); - changed = true; + showingTransientTypes |= type; } - if (changed) { + if (mShowingTransientTypes != showingTransientTypes) { + mShowingTransientTypes = showingTransientTypes; StatusBarManagerInternal statusBarManagerInternal = mPolicy.getStatusBarManagerInternal(); if (statusBarManagerInternal != null) { statusBarManagerInternal.showTransient(mDisplayContent.getDisplayId(), - mShowingTransientTypes.toArray(), isGestureOnSystemBar); + showingTransientTypes, isGestureOnSystemBar); } updateBarControlTarget(mFocusedWin); dispatchTransientSystemBarsVisibilityChanged( mFocusedWin, - isTransient(ITYPE_STATUS_BAR) || isTransient(ITYPE_NAVIGATION_BAR), + (showingTransientTypes & (Type.statusBars() | Type.navigationBars())) != 0, isGestureOnSystemBar); // The leashes can be created while updating bar control target. The surface transaction @@ -224,7 +231,7 @@ class InsetsPolicy { } void hideTransient() { - if (mShowingTransientTypes.size() == 0) { + if (mShowingTransientTypes == 0) { return; } @@ -235,20 +242,25 @@ class InsetsPolicy { startAnimation(false /* show */, () -> { synchronized (mDisplayContent.mWmService.mGlobalLock) { - for (int i = mShowingTransientTypes.size() - 1; i >= 0; i--) { + final ArrayMap providers = + mStateController.getSourceProviders(); + for (int i = providers.size() - 1; i >= 0; i--) { + final WindowContainerInsetsSourceProvider provider = providers.valueAt(i); + if (!isTransient(provider.getSource().getType())) { + continue; + } // We are about to clear mShowingTransientTypes, we don't want the transient bar // can cause insets on the client. Restore the client visibility. - final @InternalInsetsType int type = mShowingTransientTypes.get(i); - mStateController.getSourceProvider(type).setClientVisible(false); + provider.setClientVisible(false); } - mShowingTransientTypes.clear(); + mShowingTransientTypes = 0; updateBarControlTarget(mFocusedWin); } }); } - boolean isTransient(@InternalInsetsType int type) { - return mShowingTransientTypes.indexOf(type) != -1; + boolean isTransient(@InsetsType int type) { + return (mShowingTransientTypes & type) != 0; } /** @@ -280,9 +292,9 @@ class InsetsPolicy { ? token.getFixedRotationTransformInsetsState() : mStateController.getRawInsetsState(); outInsetsState.set(srcState, true /* copySources */); - for (int i = mShowingTransientTypes.size() - 1; i >= 0; i--) { - final InsetsSource source = outInsetsState.peekSource(mShowingTransientTypes.get(i)); - if (source != null) { + for (int i = outInsetsState.sourceSize() - 1; i >= 0; i--) { + final InsetsSource source = outInsetsState.sourceAt(i); + if (isTransient(source.getType())) { source.setVisible(false); } } @@ -365,18 +377,17 @@ class InsetsPolicy { private InsetsState adjustVisibilityForTransientTypes(InsetsState originalState) { InsetsState state = originalState; - for (int i = mShowingTransientTypes.size() - 1; i >= 0; i--) { - final @InternalInsetsType int type = mShowingTransientTypes.get(i); - final InsetsSource originalSource = state.peekSource(type); - if (originalSource != null && originalSource.isVisible()) { + for (int i = state.sourceSize() - 1; i >= 0; i--) { + final InsetsSource source = state.sourceAt(i); + if (isTransient(source.getType()) && source.isVisible()) { if (state == originalState) { // The source will be modified, create a non-deep copy to store the new one. state = new InsetsState(originalState); } // Replace the source with a copy in invisible state. - final InsetsSource source = new InsetsSource(originalSource); - source.setVisible(false); - state.addSource(source); + final InsetsSource outSource = new InsetsSource(source); + outSource.setVisible(false); + state.addSource(outSource); } } return state; @@ -385,18 +396,23 @@ class InsetsPolicy { private InsetsState adjustVisibilityForIme(WindowState w, InsetsState originalState, boolean copyState) { if (w.mIsImWindow) { + InsetsState state = originalState; // If navigation bar is not hidden by IME, IME should always receive visible // navigation bar insets. final boolean navVisible = !mHideNavBarForKeyboard; - final InsetsSource originalNavSource = originalState.peekSource(ITYPE_NAVIGATION_BAR); - if (originalNavSource != null && originalNavSource.isVisible() != navVisible) { - final InsetsState state = copyState ? new InsetsState(originalState) - : originalState; - final InsetsSource navSource = new InsetsSource(originalNavSource); + for (int i = originalState.sourceSize() - 1; i >= 0; i--) { + final InsetsSource source = originalState.sourceAt(i); + if (source.getType() != Type.navigationBars() || source.isVisible() == navVisible) { + continue; + } + if (state == originalState && copyState) { + state = new InsetsState(originalState); + } + final InsetsSource navSource = new InsetsSource(source); navSource.setVisible(navVisible); state.addSource(navSource); - return state; } + return state; } else if (w.mActivityRecord != null && w.mActivityRecord.mImeInsetsFrozenUntilStartInput) { // During switching tasks with gestural navigation, before the next IME input target // starts the input, we should adjust and freeze the last IME visibility of the window @@ -447,23 +463,22 @@ class InsetsPolicy { * @param caller who changed the insets state. */ private void checkAbortTransient(InsetsControlTarget caller) { - if (mShowingTransientTypes.size() != 0) { - final IntArray abortTypes = new IntArray(); - final boolean imeRequestedVisible = caller.isRequestedVisible(Type.ime()); - for (int i = mShowingTransientTypes.size() - 1; i >= 0; i--) { - final @InternalInsetsType int type = mShowingTransientTypes.get(i); - if ((mStateController.isFakeTarget(type, caller) - && caller.isRequestedVisible(InsetsState.toPublicType(type))) - || (type == ITYPE_NAVIGATION_BAR && imeRequestedVisible)) { - mShowingTransientTypes.remove(i); - abortTypes.add(type); - } - } - StatusBarManagerInternal statusBarManagerInternal = - mPolicy.getStatusBarManagerInternal(); - if (abortTypes.size() > 0 && statusBarManagerInternal != null) { - statusBarManagerInternal.abortTransient( - mDisplayContent.getDisplayId(), abortTypes.toArray()); + if (mShowingTransientTypes == 0) { + return; + } + final boolean isImeVisible = mStateController.getImeSourceProvider().isClientVisible(); + final @InsetsType int fakeControllingTypes = + mStateController.getFakeControllingTypes(caller); + final @InsetsType int abortTypes = + (fakeControllingTypes & caller.getRequestedVisibleTypes()) + | (isImeVisible ? Type.navigationBars() : 0); + mShowingTransientTypes &= ~abortTypes; + if (abortTypes != 0) { + mDisplayContent.setLayoutNeeded(); + mDisplayContent.mWmService.requestTraversal(); + final StatusBarManagerInternal statusBarManager = mPolicy.getStatusBarManagerInternal(); + if (statusBarManager != null) { + statusBarManager.abortTransient(mDisplayContent.getDisplayId(), abortTypes); } } } @@ -473,12 +488,16 @@ class InsetsPolicy { * updateBarControlTarget(mFocusedWin) after this invocation. */ private void abortTransient() { - StatusBarManagerInternal statusBarManagerInternal = mPolicy.getStatusBarManagerInternal(); - if (statusBarManagerInternal != null) { - statusBarManagerInternal.abortTransient( - mDisplayContent.getDisplayId(), mShowingTransientTypes.toArray()); + if (mShowingTransientTypes == 0) { + return; } - mShowingTransientTypes.clear(); + final StatusBarManagerInternal statusBarManager = mPolicy.getStatusBarManagerInternal(); + if (statusBarManager != null) { + statusBarManager.abortTransient(mDisplayContent.getDisplayId(), mShowingTransientTypes); + } + mShowingTransientTypes = 0; + mDisplayContent.setLayoutNeeded(); + mDisplayContent.mWmService.requestTraversal(); dispatchTransientSystemBarsVisibilityChanged( mFocusedWin, @@ -488,7 +507,7 @@ class InsetsPolicy { private @Nullable InsetsControlTarget getStatusControlTarget(@Nullable WindowState focusedWin, boolean fake) { - if (!fake && isShowingTransientTypes(Type.statusBars())) { + if (!fake && isTransient(Type.statusBars())) { return mDummyControlTarget; } final WindowState notificationShade = mPolicy.getNotificationShade(); @@ -541,7 +560,7 @@ class InsetsPolicy { // configured to be hidden by the IME. return null; } - if (!fake && isShowingTransientTypes(Type.navigationBars())) { + if (!fake && isTransient(Type.navigationBars())) { return mDummyControlTarget; } if (focusedWin == mPolicy.getNotificationShade()) { @@ -577,16 +596,6 @@ class InsetsPolicy { return focusedWin; } - private boolean isShowingTransientTypes(@InsetsType int types) { - final IntArray showingTransientTypes = mShowingTransientTypes; - for (int i = showingTransientTypes.size() - 1; i >= 0; i--) { - if ((InsetsState.toPublicType(showingTransientTypes.get(i)) & types) != 0) { - return true; - } - } - return false; - } - /** * Determines whether the remote insets controller should take control of system bars for all * windows. @@ -622,21 +631,17 @@ class InsetsPolicy { @VisibleForTesting void startAnimation(boolean show, Runnable callback) { - int typesReady = 0; - final SparseArray controls = new SparseArray<>(); - final IntArray showingTransientTypes = mShowingTransientTypes; - for (int i = showingTransientTypes.size() - 1; i >= 0; i--) { - final int sourceId = showingTransientTypes.get(i); - final WindowContainerInsetsSourceProvider provider = - mStateController.getSourceProvider(sourceId); - final InsetsSourceControl control = provider.getControl(mDummyControlTarget); - if (control == null || control.getLeash() == null) { - continue; + @InsetsType int typesReady = 0; + final SparseArray controlsReady = new SparseArray<>(); + final InsetsSourceControl[] controls = + mStateController.getControlsForDispatch(mDummyControlTarget); + for (InsetsSourceControl control : controls) { + if (isTransient(control.getType()) && control.getLeash() != null) { + typesReady |= control.getType(); + controlsReady.put(control.getId(), new InsetsSourceControl(control)); } - typesReady |= control.getType(); - controls.put(sourceId, new InsetsSourceControl(control)); } - controlAnimationUnchecked(typesReady, controls, show, callback); + controlAnimationUnchecked(typesReady, controlsReady, show, callback); } private void controlAnimationUnchecked(int typesReady, diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java index f5af2929c2bda..3ff37060ae925 100644 --- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java +++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java @@ -191,13 +191,6 @@ abstract class InsetsSourceProvider { } } - /** - * @return Whether there is a window container which backs this source. - */ - boolean hasWindowContainer() { - return mWindowContainer != null; - } - /** * The source frame can affect the layout of other windows, so this should be called once the * window container gets laid out. @@ -363,9 +356,9 @@ abstract class InsetsSourceProvider { } /** - * @see InsetsStateController#onControlFakeTargetChanged(int, InsetsControlTarget) + * @see InsetsStateController#onControlTargetChanged */ - void updateControlForFakeTarget(@Nullable InsetsControlTarget fakeTarget) { + void updateFakeControlTarget(@Nullable InsetsControlTarget fakeTarget) { if (fakeTarget == mFakeControlTarget) { return; } @@ -570,6 +563,10 @@ abstract class InsetsSourceProvider { return mControlTarget; } + InsetsControlTarget getFakeControlTarget() { + return mFakeControlTarget; + } + boolean isClientVisible() { return mClientVisible; } @@ -609,15 +606,15 @@ abstract class InsetsSourceProvider { } if (mControlTarget != null) { pw.print(prefix + "mControlTarget="); - pw.println(mControlTarget.getWindow()); + pw.println(mControlTarget); } if (mPendingControlTarget != null) { pw.print(prefix + "mPendingControlTarget="); - pw.println(mPendingControlTarget.getWindow()); + pw.println(mPendingControlTarget); } if (mFakeControlTarget != null) { pw.print(prefix + "mFakeControlTarget="); - pw.println(mFakeControlTarget.getWindow()); + pw.println(mFakeControlTarget); } } diff --git a/services/core/java/com/android/server/wm/InsetsStateController.java b/services/core/java/com/android/server/wm/InsetsStateController.java index a3f62b2c5693b..d377a3347d464 100644 --- a/services/core/java/com/android/server/wm/InsetsStateController.java +++ b/services/core/java/com/android/server/wm/InsetsStateController.java @@ -18,10 +18,6 @@ package com.android.server.wm; import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; import static android.view.InsetsSource.ID_IME; -import static android.view.InsetsState.ITYPE_CLIMATE_BAR; -import static android.view.InsetsState.ITYPE_EXTRA_NAVIGATION_BAR; -import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; -import static android.view.InsetsState.ITYPE_STATUS_BAR; import static android.view.WindowInsets.Type.displayCutout; import static android.view.WindowInsets.Type.ime; import static android.view.WindowInsets.Type.mandatorySystemGestures; @@ -42,6 +38,7 @@ import android.view.InsetsSourceControl; import android.view.InsetsState; import android.view.InsetsState.InternalInsetsType; import android.view.WindowInsets; +import android.view.WindowInsets.Type.InsetsType; import com.android.internal.protolog.common.ProtoLog; import com.android.server.inputmethod.InputMethodManagerInternal; @@ -62,12 +59,10 @@ class InsetsStateController { private final ArrayMap mProviders = new ArrayMap<>(); - private final ArrayMap> mControlTargetTypeMap = - new ArrayMap<>(); - private final SparseArray mTypeControlTargetMap = new SparseArray<>(); - - /** @see #onControlFakeTargetChanged */ - private final SparseArray mTypeFakeControlTargetMap = new SparseArray<>(); + private final ArrayMap> + mControlTargetProvidersMap = new ArrayMap<>(); + private final SparseArray mIdControlTargetMap = new SparseArray<>(); + private final SparseArray mIdFakeControlTargetMap = new SparseArray<>(); private final ArraySet mPendingControlChanged = new ArraySet<>(); @@ -108,14 +103,14 @@ class InsetsStateController { } @Nullable InsetsSourceControl[] getControlsForDispatch(InsetsControlTarget target) { - ArrayList controlled = mControlTargetTypeMap.get(target); + final ArrayList controlled = mControlTargetProvidersMap.get(target); if (controlled == null) { return null; } final int size = controlled.size(); final InsetsSourceControl[] result = new InsetsSourceControl[size]; for (int i = 0; i < size; i++) { - result[i] = mProviders.get(controlled.get(i)).getControl(target); + result[i] = controlled.get(i).getControl(target); } return result; } @@ -208,8 +203,16 @@ class InsetsStateController { } } - boolean isFakeTarget(@InternalInsetsType int type, InsetsControlTarget target) { - return mTypeFakeControlTargetMap.get(type) == target; + @InsetsType int getFakeControllingTypes(InsetsControlTarget target) { + @InsetsType int types = 0; + for (int i = mProviders.size() - 1; i >= 0; i--) { + final InsetsSourceProvider provider = mProviders.valueAt(i); + final InsetsControlTarget fakeControlTarget = provider.getFakeControlTarget(); + if (target == fakeControlTarget) { + types |= provider.getSource().getType(); + } + } + return types; } void onImeControlTargetChanged(@Nullable InsetsControlTarget imeTarget) { @@ -217,7 +220,7 @@ class InsetsStateController { // Make sure that we always have a control target for the IME, even if the IME target is // null. Otherwise there is no leash that will hide it and IME becomes "randomly" visible. InsetsControlTarget target = imeTarget != null ? imeTarget : mEmptyImeControlTarget; - onControlChanged(ID_IME, target); + onControlTargetChanged(getImeSourceProvider(), target, false /* fake */); ProtoLog.d(WM_DEBUG_IME, "onImeControlTargetChanged %s", target != null ? target.getWindow() : "null"); notifyPendingInsetsControlChanged(); @@ -235,101 +238,88 @@ class InsetsStateController { @Nullable InsetsControlTarget fakeStatusControlling, @Nullable InsetsControlTarget navControlling, @Nullable InsetsControlTarget fakeNavControlling) { - onControlChanged(ITYPE_STATUS_BAR, statusControlling); - onControlChanged(ITYPE_NAVIGATION_BAR, navControlling); - onControlChanged(ITYPE_CLIMATE_BAR, statusControlling); - onControlChanged(ITYPE_EXTRA_NAVIGATION_BAR, navControlling); - onControlFakeTargetChanged(ITYPE_STATUS_BAR, fakeStatusControlling); - onControlFakeTargetChanged(ITYPE_NAVIGATION_BAR, fakeNavControlling); - onControlFakeTargetChanged(ITYPE_CLIMATE_BAR, fakeStatusControlling); - onControlFakeTargetChanged(ITYPE_EXTRA_NAVIGATION_BAR, fakeNavControlling); + for (int i = mProviders.size() - 1; i >= 0; i--) { + final InsetsSourceProvider provider = mProviders.valueAt(i); + final @InsetsType int type = provider.getSource().getType(); + if (type == WindowInsets.Type.statusBars()) { + onControlTargetChanged(provider, statusControlling, false /* fake */); + onControlTargetChanged(provider, fakeStatusControlling, true /* fake */); + } else if (type == WindowInsets.Type.navigationBars()) { + onControlTargetChanged(provider, navControlling, false /* fake */); + onControlTargetChanged(provider, fakeNavControlling, true /* fake */); + } + } notifyPendingInsetsControlChanged(); } void notifyControlRevoked(@NonNull InsetsControlTarget previousControlTarget, InsetsSourceProvider provider) { - removeFromControlMaps(previousControlTarget, provider.getSource().getId(), - false /* fake */); + removeFromControlMaps(previousControlTarget, provider, false /* fake */); } - private void onControlChanged(@InternalInsetsType int type, - @Nullable InsetsControlTarget target) { - final InsetsControlTarget previous = mTypeControlTargetMap.get(type); - if (target == previous) { - return; - } - final WindowContainerInsetsSourceProvider provider = mProviders.get(type); - if (provider == null) { + private void onControlTargetChanged(InsetsSourceProvider provider, + @Nullable InsetsControlTarget target, boolean fake) { + final InsetsControlTarget lastTarget = fake + ? mIdFakeControlTargetMap.get(provider.getSource().getId()) + : mIdControlTargetMap.get(provider.getSource().getId()); + if (target == lastTarget) { return; } if (!provider.isControllable()) { return; } - provider.updateControlForTarget(target, false /* force */); - target = provider.getControlTarget(); - if (previous != null) { - removeFromControlMaps(previous, type, false /* fake */); - mPendingControlChanged.add(previous); + if (fake) { + // The fake target updated here will be used to pretend to the app that it's still under + // control of the bars while it's not really, but we still need to find out the apps + // intentions around showing/hiding. For example, when the transient bars are showing, + // and the fake target requests to show system bars, the transient state will be + // aborted. + provider.updateFakeControlTarget(target); + } else { + provider.updateControlForTarget(target, false /* force */); + + // Get control target again in case the provider didn't accept the one we passed to it. + target = provider.getControlTarget(); + if (target == lastTarget) { + return; + } + } + if (lastTarget != null) { + removeFromControlMaps(lastTarget, provider, fake); + mPendingControlChanged.add(lastTarget); } if (target != null) { - addToControlMaps(target, type, false /* fake */); + addToControlMaps(target, provider, fake); mPendingControlChanged.add(target); } } - /** - * The fake target saved here will be used to pretend to the app that it's still under control - * of the bars while it's not really, but we still need to find out the apps intentions around - * showing/hiding. For example, when the transient bars are showing, and the fake target - * requests to show system bars, the transient state will be aborted. - */ - void onControlFakeTargetChanged(@InternalInsetsType int type, - @Nullable InsetsControlTarget fakeTarget) { - final InsetsControlTarget previous = mTypeFakeControlTargetMap.get(type); - if (fakeTarget == previous) { - return; - } - final WindowContainerInsetsSourceProvider provider = mProviders.get(type); - if (provider == null) { - return; - } - provider.updateControlForFakeTarget(fakeTarget); - if (previous != null) { - removeFromControlMaps(previous, type, true /* fake */); - mPendingControlChanged.add(previous); - } - if (fakeTarget != null) { - addToControlMaps(fakeTarget, type, true /* fake */); - mPendingControlChanged.add(fakeTarget); - } - } - private void removeFromControlMaps(@NonNull InsetsControlTarget target, - @InternalInsetsType int type, boolean fake) { - final ArrayList array = mControlTargetTypeMap.get(target); + InsetsSourceProvider provider, boolean fake) { + final ArrayList array = mControlTargetProvidersMap.get(target); if (array == null) { return; } - array.remove((Integer) type); + array.remove(provider); if (array.isEmpty()) { - mControlTargetTypeMap.remove(target); + mControlTargetProvidersMap.remove(target); } if (fake) { - mTypeFakeControlTargetMap.remove(type); + mIdFakeControlTargetMap.remove(provider.getSource().getId()); } else { - mTypeControlTargetMap.remove(type); + mIdControlTargetMap.remove(provider.getSource().getId()); } } private void addToControlMaps(@NonNull InsetsControlTarget target, - @InternalInsetsType int type, boolean fake) { - final ArrayList array = mControlTargetTypeMap.computeIfAbsent(target, - key -> new ArrayList<>()); - array.add(type); + InsetsSourceProvider provider, boolean fake) { + final ArrayList array = mControlTargetProvidersMap.computeIfAbsent( + target, key -> new ArrayList<>()); + array.add(provider); if (fake) { - mTypeFakeControlTargetMap.put(type, target); + mIdFakeControlTargetMap.put(provider.getSource().getId(), target); } else { - mTypeControlTargetMap.put(type, target); + mIdControlTargetMap.put(provider.getSource().getId(), target); } } @@ -351,7 +341,7 @@ class InsetsStateController { for (int i = mPendingControlChanged.size() - 1; i >= 0; i--) { final InsetsControlTarget controlTarget = mPendingControlChanged.valueAt(i); controlTarget.notifyInsetsControlChanged(); - if (mControlTargetTypeMap.containsKey(controlTarget)) { + if (mControlTargetProvidersMap.containsKey(controlTarget)) { // We only collect targets who get controls, not lose controls. newControlTargets.add(controlTarget); } @@ -377,10 +367,25 @@ class InsetsStateController { prefix = prefix + " "; mState.dump(prefix, pw); pw.println(prefix + "Control map:"); - for (int i = mTypeControlTargetMap.size() - 1; i >= 0; i--) { + for (int i = mControlTargetProvidersMap.size() - 1; i >= 0; i--) { + final InsetsControlTarget controlTarget = mControlTargetProvidersMap.keyAt(i); pw.print(prefix + " "); - pw.println(InsetsState.typeToString(mTypeControlTargetMap.keyAt(i)) + " -> " - + mTypeControlTargetMap.valueAt(i)); + pw.print(controlTarget); + pw.println(":"); + final ArrayList providers = mControlTargetProvidersMap.valueAt(i); + for (int j = providers.size() - 1; j >= 0; j--) { + final InsetsSourceProvider provider = providers.get(j); + if (provider != null) { + pw.print(prefix + " "); + if (controlTarget == provider.getFakeControlTarget()) { + pw.print("(fake) "); + } + pw.println(provider.getControl(controlTarget)); + } + } + } + if (mControlTargetProvidersMap.isEmpty()) { + pw.print(prefix + " none"); } pw.println(prefix + "InsetsSourceProviders:"); for (int i = mProviders.size() - 1; i >= 0; i--) { diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java index dba299566f84d..1a126cfa5c2c4 100644 --- a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java @@ -280,8 +280,7 @@ public class InsetsPolicyTest extends WindowTestsBase { assertFalse(mDisplayContent.getInsetsStateController().getRawInsetsState() .isSourceOrDefaultVisible(ITYPE_NAVIGATION_BAR, navigationBars())); - policy.showTransient(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR}, - true /* isGestureOnSystemBar */); + policy.showTransient(navigationBars() | statusBars(), true /* isGestureOnSystemBar */); waitUntilWindowAnimatorIdle(); final InsetsSourceControl[] controls = mDisplayContent.getInsetsStateController().getControlsForDispatch(mAppWindow); @@ -308,11 +307,11 @@ public class InsetsPolicyTest extends WindowTestsBase { spyOn(policy); doNothing().when(policy).startAnimation(anyBoolean(), any()); policy.updateBarControlTarget(mAppWindow); - policy.showTransient(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR}, + policy.showTransient(navigationBars() | statusBars(), true /* isGestureOnSystemBar */); waitUntilWindowAnimatorIdle(); - assertTrue(policy.isTransient(ITYPE_STATUS_BAR)); - assertFalse(policy.isTransient(ITYPE_NAVIGATION_BAR)); + assertTrue(policy.isTransient(statusBars())); + assertFalse(policy.isTransient(navigationBars())); final InsetsSourceControl[] controls = mDisplayContent.getInsetsStateController().getControlsForDispatch(mAppWindow); @@ -344,7 +343,7 @@ public class InsetsPolicyTest extends WindowTestsBase { spyOn(policy); doNothing().when(policy).startAnimation(anyBoolean(), any()); policy.updateBarControlTarget(mAppWindow); - policy.showTransient(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR}, + policy.showTransient(navigationBars() | statusBars(), true /* isGestureOnSystemBar */); waitUntilWindowAnimatorIdle(); InsetsSourceControl[] controls = @@ -393,13 +392,13 @@ public class InsetsPolicyTest extends WindowTestsBase { spyOn(policy); doNothing().when(policy).startAnimation(anyBoolean(), any()); policy.updateBarControlTarget(app); - policy.showTransient(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR}, + policy.showTransient(navigationBars() | statusBars(), true /* isGestureOnSystemBar */); final InsetsSourceControl[] controls = mDisplayContent.getInsetsStateController().getControlsForDispatch(app); policy.updateBarControlTarget(app2); - assertFalse(policy.isTransient(ITYPE_STATUS_BAR)); - assertFalse(policy.isTransient(ITYPE_NAVIGATION_BAR)); + assertFalse(policy.isTransient(statusBars())); + assertFalse(policy.isTransient(navigationBars())); } private WindowState addNavigationBar() { diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java index 88ecd3fe2ceaf..5df8421d3aea4 100644 --- a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java @@ -351,10 +351,10 @@ public class InsetsStateControllerTest extends WindowTestsBase { assertTrue(rotatedState.isSourceOrDefaultVisible(ITYPE_STATUS_BAR, statusBars())); provider.getSource().setVisible(false); - mDisplayContent.getInsetsPolicy().showTransient(new int[] { ITYPE_STATUS_BAR }, + mDisplayContent.getInsetsPolicy().showTransient(statusBars(), true /* isGestureOnSystemBar */); - assertTrue(mDisplayContent.getInsetsPolicy().isTransient(ITYPE_STATUS_BAR)); + assertTrue(mDisplayContent.getInsetsPolicy().isTransient(statusBars())); assertFalse(app.getInsetsState().isSourceOrDefaultVisible(ITYPE_STATUS_BAR, statusBars())); } diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerInsetsSourceProviderTest.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerInsetsSourceProviderTest.java index 1e5ec4c4e48cc..7d13de84642ea 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerInsetsSourceProviderTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerInsetsSourceProviderTest.java @@ -170,10 +170,10 @@ public class WindowContainerInsetsSourceProviderTest extends WindowTestsBase { final WindowState target = createWindow(null, TYPE_APPLICATION, "target"); statusBar.getFrame().set(0, 0, 500, 100); mProvider.setWindowContainer(statusBar, null, null); - mProvider.updateControlForFakeTarget(target); + mProvider.updateFakeControlTarget(target); assertNotNull(mProvider.getControl(target)); assertNull(mProvider.getControl(target).getLeash()); - mProvider.updateControlForFakeTarget(null); + mProvider.updateFakeControlTarget(null); assertNull(mProvider.getControl(target)); }