Merge "Send public types while showing or aborting transient bars"

This commit is contained in:
Tiger Huang
2023-02-06 06:20:21 +00:00
committed by Android (Google) Code Review
19 changed files with 295 additions and 328 deletions

View File

@@ -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");

View File

@@ -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.

View File

@@ -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<String, StatusBarIcon> 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,

View File

@@ -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);

View File

@@ -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<NavigationBarView> 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<NavigationBarView> 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();

View File

@@ -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();

View File

@@ -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);
}

View File

@@ -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();

View File

@@ -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,

View File

@@ -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));

View File

@@ -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,

View File

@@ -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<Integer> 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);
}
}

View File

@@ -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) {

View File

@@ -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<Integer, WindowContainerInsetsSourceProvider> 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<InsetsSourceControl> 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<InsetsSourceControl> 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,

View File

@@ -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);
}
}

View File

@@ -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<Integer, WindowContainerInsetsSourceProvider> mProviders =
new ArrayMap<>();
private final ArrayMap<InsetsControlTarget, ArrayList<Integer>> mControlTargetTypeMap =
new ArrayMap<>();
private final SparseArray<InsetsControlTarget> mTypeControlTargetMap = new SparseArray<>();
/** @see #onControlFakeTargetChanged */
private final SparseArray<InsetsControlTarget> mTypeFakeControlTargetMap = new SparseArray<>();
private final ArrayMap<InsetsControlTarget, ArrayList<InsetsSourceProvider>>
mControlTargetProvidersMap = new ArrayMap<>();
private final SparseArray<InsetsControlTarget> mIdControlTargetMap = new SparseArray<>();
private final SparseArray<InsetsControlTarget> mIdFakeControlTargetMap = new SparseArray<>();
private final ArraySet<InsetsControlTarget> mPendingControlChanged = new ArraySet<>();
@@ -108,14 +103,14 @@ class InsetsStateController {
}
@Nullable InsetsSourceControl[] getControlsForDispatch(InsetsControlTarget target) {
ArrayList<Integer> controlled = mControlTargetTypeMap.get(target);
final ArrayList<InsetsSourceProvider> 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<Integer> array = mControlTargetTypeMap.get(target);
InsetsSourceProvider provider, boolean fake) {
final ArrayList<InsetsSourceProvider> 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<Integer> array = mControlTargetTypeMap.computeIfAbsent(target,
key -> new ArrayList<>());
array.add(type);
InsetsSourceProvider provider, boolean fake) {
final ArrayList<InsetsSourceProvider> 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<InsetsSourceProvider> 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--) {

View File

@@ -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() {

View File

@@ -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()));
}

View File

@@ -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));
}