Merge "Migrate Navigation Bar to InsetsFrameProvider"

This commit is contained in:
Yunfan Chen
2022-10-26 04:20:05 +00:00
committed by Android (Google) Code Review
7 changed files with 202 additions and 167 deletions

View File

@@ -273,6 +273,9 @@ public class InsetsFrameProvider implements Parcelable {
/**
* Class to describe the insets size to be provided to window with specific window type. If not
* used, same insets size will be sent as instructed in the insetsSize and source.
*
* If the insetsSize of given type is set to {@code null}, the insets source frame will be used
* directly for that window type.
*/
public static class InsetsSizeOverride implements Parcelable {
public final int windowType;
@@ -280,7 +283,7 @@ public class InsetsFrameProvider implements Parcelable {
protected InsetsSizeOverride(Parcel in) {
windowType = in.readInt();
insetsSize = in.readParcelable(null, android.graphics.Insets.class);
insetsSize = in.readParcelable(null, Insets.class);
}
public InsetsSizeOverride(int type, Insets size) {

View File

@@ -25,11 +25,16 @@ import static android.app.StatusBarManager.WindowVisibleState;
import static android.app.StatusBarManager.windowStateToString;
import static android.app.WindowConfiguration.ROTATION_UNDEFINED;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.InsetsState.ITYPE_BOTTOM_MANDATORY_GESTURES;
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;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
@@ -77,6 +82,7 @@ import android.telecom.TelecomManager;
import android.text.TextUtils;
import android.util.Log;
import android.view.Display;
import android.view.DisplayCutout;
import android.view.Gravity;
import android.view.HapticFeedbackConstants;
import android.view.InsetsFrameProvider;
@@ -240,6 +246,12 @@ public class NavigationBar extends ViewController<NavigationBarView> implements
private boolean mTransientShown;
private boolean mTransientShownFromGestureOnSystemBar;
/**
* This is to indicate whether the navigation bar button is forced visible. This is true
* when the setup wizard is on display. When that happens, the window frame should be provided
* as insets size directly.
*/
private boolean mIsButtonForceVisible;
private int mNavBarMode = NAV_BAR_MODE_3BUTTON;
private LightBarController mLightBarController;
private final LightBarController mMainLightBarController;
@@ -623,6 +635,10 @@ public class NavigationBar extends ViewController<NavigationBarView> implements
mView.setTouchHandler(mTouchHandler);
setNavBarMode(mNavBarMode);
mEdgeBackGestureHandler.setStateChangeCallback(mView::updateStates);
mEdgeBackGestureHandler.setButtonForceVisibleChangeCallback((forceVisible) -> {
mIsButtonForceVisible = forceVisible;
repositionNavigationBar(mCurrentRotation);
});
mNavigationBarTransitions.addListener(this::onBarTransition);
mView.updateRotationButton();
@@ -810,7 +826,6 @@ public class NavigationBar extends ViewController<NavigationBarView> implements
mLayoutDirection = ld;
refreshLayout(ld);
}
repositionNavigationBar(rotation);
if (canShowSecondaryHandle()) {
if (rotation != mCurrentRotation) {
@@ -1599,23 +1614,15 @@ public class NavigationBar extends ViewController<NavigationBarView> implements
width,
height,
WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
| WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
| WindowManager.LayoutParams.FLAG_SLIPPERY,
PixelFormat.TRANSLUCENT);
lp.gravity = gravity;
if (insetsHeight != -1) {
lp.providedInsets = new InsetsFrameProvider[] {
new InsetsFrameProvider(ITYPE_NAVIGATION_BAR, Insets.of(0, 0, 0, insetsHeight))
};
} else {
lp.providedInsets = new InsetsFrameProvider[] {
new InsetsFrameProvider(ITYPE_NAVIGATION_BAR)
};
}
lp.providedInsets = getInsetsFrameProvider(insetsHeight, userContext);
lp.token = new Binder();
lp.accessibilityTitle = userContext.getString(R.string.nav_bar);
lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC
@@ -1628,6 +1635,68 @@ public class NavigationBar extends ViewController<NavigationBarView> implements
return lp;
}
private InsetsFrameProvider[] getInsetsFrameProvider(int insetsHeight, Context userContext) {
final InsetsFrameProvider navBarProvider;
if (insetsHeight != -1 && !mIsButtonForceVisible) {
navBarProvider = new InsetsFrameProvider(
ITYPE_NAVIGATION_BAR, Insets.of(0, 0, 0, insetsHeight));
// Use window frame for IME.
navBarProvider.insetsSizeOverrides = new InsetsFrameProvider.InsetsSizeOverride[] {
new InsetsFrameProvider.InsetsSizeOverride(TYPE_INPUT_METHOD, null)
};
} else {
navBarProvider = new InsetsFrameProvider(ITYPE_NAVIGATION_BAR);
navBarProvider.insetsSizeOverrides = new InsetsFrameProvider.InsetsSizeOverride[]{
new InsetsFrameProvider.InsetsSizeOverride(TYPE_INPUT_METHOD, null)
};
}
final boolean navBarTapThrough = userContext.getResources().getBoolean(
com.android.internal.R.bool.config_navBarTapThrough);
final InsetsFrameProvider bottomTappableProvider;
if (navBarTapThrough) {
bottomTappableProvider = new InsetsFrameProvider(ITYPE_BOTTOM_TAPPABLE_ELEMENT,
Insets.of(0, 0, 0, 0));
} else {
bottomTappableProvider = new InsetsFrameProvider(ITYPE_BOTTOM_TAPPABLE_ELEMENT);
}
if (!mEdgeBackGestureHandler.isHandlingGestures()) {
// 2/3 button navigation is on. Do not provide any gesture insets here. But need to keep
// the provider to support runtime update.
return new InsetsFrameProvider[] {
navBarProvider,
new InsetsFrameProvider(
ITYPE_BOTTOM_MANDATORY_GESTURES, Insets.NONE),
new InsetsFrameProvider(ITYPE_LEFT_GESTURES, InsetsFrameProvider.SOURCE_DISPLAY,
Insets.NONE, null),
new InsetsFrameProvider(ITYPE_RIGHT_GESTURES,
InsetsFrameProvider.SOURCE_DISPLAY,
Insets.NONE, null),
bottomTappableProvider
};
} else {
// Gesture navigation
final int gestureHeight = userContext.getResources().getDimensionPixelSize(
com.android.internal.R.dimen.navigation_bar_gesture_height);
final DisplayCutout cutout = userContext.getDisplay().getCutout();
final int safeInsetsLeft = cutout != null ? cutout.getSafeInsetLeft() : 0;
final int safeInsetsRight = cutout != null ? cutout.getSafeInsetRight() : 0;
return new InsetsFrameProvider[] {
navBarProvider,
new InsetsFrameProvider(
ITYPE_BOTTOM_MANDATORY_GESTURES, Insets.of(0, 0, 0, gestureHeight)),
new InsetsFrameProvider(ITYPE_LEFT_GESTURES, InsetsFrameProvider.SOURCE_DISPLAY,
Insets.of(safeInsetsLeft
+ mEdgeBackGestureHandler.getEdgeWidthLeft(), 0, 0, 0), null),
new InsetsFrameProvider(ITYPE_RIGHT_GESTURES,
InsetsFrameProvider.SOURCE_DISPLAY,
Insets.of(0, 0, safeInsetsRight
+ mEdgeBackGestureHandler.getEdgeWidthRight(), 0), null),
bottomTappableProvider
};
}
}
private boolean canShowSecondaryHandle() {
return mNavBarMode == NAV_BAR_MODE_GESTURAL && mOrientationHandle != null;
}

View File

@@ -175,6 +175,7 @@ public class EdgeBackGestureHandler extends CurrentUserTracker
private final OverviewProxyService mOverviewProxyService;
private final SysUiState mSysUiState;
private Runnable mStateChangeCallback;
private Consumer<Boolean> mButtonForceVisibleCallback;
private final PluginManager mPluginManager;
private final ProtoTracer mProtoTracer;
@@ -240,6 +241,7 @@ public class EdgeBackGestureHandler extends CurrentUserTracker
private boolean mIsBackGestureAllowed;
private boolean mGestureBlockingActivityRunning;
private boolean mIsNewBackAffordanceEnabled;
private boolean mIsButtonForceVisible;
private InputMonitor mInputMonitor;
private InputChannelCompat.InputEventReceiver mInputEventReceiver;
@@ -402,12 +404,29 @@ public class EdgeBackGestureHandler extends CurrentUserTracker
mStateChangeCallback = callback;
}
public void setButtonForceVisibleChangeCallback(Consumer<Boolean> callback) {
mButtonForceVisibleCallback = callback;
}
public int getEdgeWidthLeft() {
return mEdgeWidthLeft;
}
public int getEdgeWidthRight() {
return mEdgeWidthRight;
}
public void updateCurrentUserResources() {
Resources res = mNavigationModeController.getCurrentUserContext().getResources();
mEdgeWidthLeft = mGestureNavigationSettingsObserver.getLeftSensitivity(res);
mEdgeWidthRight = mGestureNavigationSettingsObserver.getRightSensitivity(res);
mIsBackGestureAllowed =
!mGestureNavigationSettingsObserver.areNavigationButtonForcedVisible();
final boolean previousForceVisible = mIsButtonForceVisible;
mIsButtonForceVisible =
mGestureNavigationSettingsObserver.areNavigationButtonForcedVisible();
if (previousForceVisible != mIsButtonForceVisible && mButtonForceVisibleCallback != null) {
mButtonForceVisibleCallback.accept(mIsButtonForceVisible);
}
mIsBackGestureAllowed = !mIsButtonForceVisible;
final DisplayMetrics dm = res.getDisplayMetrics();
final float defaultGestureHeight = res.getDimension(

View File

@@ -19,14 +19,11 @@ package com.android.server.wm;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.view.Display.TYPE_INTERNAL;
import static android.view.InsetsState.ITYPE_BOTTOM_MANDATORY_GESTURES;
import static android.view.InsetsState.ITYPE_BOTTOM_TAPPABLE_ELEMENT;
import static android.view.InsetsFrameProvider.SOURCE_FRAME;
import static android.view.InsetsState.ITYPE_CAPTION_BAR;
import static android.view.InsetsState.ITYPE_CLIMATE_BAR;
import static android.view.InsetsState.ITYPE_EXTRA_NAVIGATION_BAR;
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.ITYPE_STATUS_BAR;
import static android.view.WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS;
import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
@@ -47,7 +44,6 @@ import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INTERCEPT_GLO
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_UNRESTRICTED_GESTURE_EXCLUSION;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
@@ -208,15 +204,12 @@ public class DisplayPolicy {
private final Object mServiceAcquireLock = new Object();
private StatusBarManagerInternal mStatusBarManagerInternal;
@Px
private int mBottomGestureAdditionalInset;
@Px
private int mLeftGestureInset;
@Px
private int mRightGestureInset;
private boolean mCanSystemBarsBeShownByUser;
private boolean mNavButtonForcedVisible;
StatusBarManagerInternal getStatusBarManagerInternal() {
synchronized (mServiceAcquireLock) {
@@ -240,7 +233,6 @@ public class DisplayPolicy {
private volatile boolean mHasNavigationBar;
// Can the navigation bar ever move to the side?
private volatile boolean mNavigationBarCanMove;
private volatile boolean mNavigationBarLetsThroughTaps;
private volatile boolean mNavigationBarAlwaysShowOnSideGesture;
// Written by vr manager thread, only read in this class.
@@ -360,8 +352,6 @@ public class DisplayPolicy {
private PointerLocationView mPointerLocationView;
private int mDisplayCutoutTouchableRegionSize;
private RefreshRatePolicy mRefreshRatePolicy;
/**
@@ -1150,71 +1140,9 @@ public class DisplayPolicy {
break;
case TYPE_NAVIGATION_BAR:
mNavigationBar = win;
final TriConsumer<DisplayFrames, WindowContainer, Rect> navFrameProvider =
(displayFrames, windowContainer, inOutFrame) -> {
if (!mNavButtonForcedVisible) {
final LayoutParams lp =
win.mAttrs.forRotation(displayFrames.mRotation);
if (lp.providedInsets != null) {
for (InsetsFrameProvider provider : lp.providedInsets) {
if (provider.type != ITYPE_NAVIGATION_BAR) {
continue;
}
InsetsFrameProvider.calculateInsetsFrame(
displayFrames.mUnrestricted,
win.getBounds(), displayFrames.mDisplayCutoutSafe,
inOutFrame, provider.source,
provider.insetsSize, lp.privateFlags,
provider.minimalInsetsSizeInDisplayCutoutSafe);
}
}
inOutFrame.inset(win.mGivenContentInsets);
}
};
final SparseArray<TriConsumer<DisplayFrames, WindowContainer, Rect>> imeOverride =
new SparseArray<>();
// For IME, we don't modify the frame.
imeOverride.put(TYPE_INPUT_METHOD, null);
mDisplayContent.setInsetProvider(ITYPE_NAVIGATION_BAR, win,
navFrameProvider, imeOverride);
mDisplayContent.setInsetProvider(ITYPE_BOTTOM_MANDATORY_GESTURES, win,
(displayFrames, windowContainer, inOutFrame) -> {
inOutFrame.top -= mBottomGestureAdditionalInset;
});
mDisplayContent.setInsetProvider(ITYPE_LEFT_GESTURES, win,
(displayFrames, windowContainer, inOutFrame) -> {
final int leftSafeInset =
Math.max(displayFrames.mDisplayCutoutSafe.left, 0);
inOutFrame.left = 0;
inOutFrame.top = 0;
inOutFrame.bottom = displayFrames.mHeight;
inOutFrame.right = leftSafeInset + mLeftGestureInset;
});
mDisplayContent.setInsetProvider(ITYPE_RIGHT_GESTURES, win,
(displayFrames, windowContainer, inOutFrame) -> {
final int rightSafeInset =
Math.min(displayFrames.mDisplayCutoutSafe.right,
displayFrames.mUnrestricted.right);
inOutFrame.left = rightSafeInset - mRightGestureInset;
inOutFrame.top = 0;
inOutFrame.bottom = displayFrames.mHeight;
inOutFrame.right = displayFrames.mWidth;
});
mDisplayContent.setInsetProvider(ITYPE_BOTTOM_TAPPABLE_ELEMENT, win,
(displayFrames, windowContainer, inOutFrame) -> {
if ((win.getAttrs().flags & FLAG_NOT_TOUCHABLE) != 0
|| mNavigationBarLetsThroughTaps) {
inOutFrame.setEmpty();
}
});
mInsetsSourceWindowsExceptIme.add(win);
if (DEBUG_LAYOUT) Slog.i(TAG, "NAVIGATION BAR: " + mNavigationBar);
break;
}
// TODO(b/239145252): Temporarily skip the navigation bar as it is still with the hard-coded
// logic.
if (attrs.providedInsets != null && attrs.type != TYPE_NAVIGATION_BAR) {
if (attrs.providedInsets != null) {
for (int i = attrs.providedInsets.length - 1; i >= 0; i--) {
final InsetsFrameProvider provider = attrs.providedInsets[i];
switch (provider.type) {
@@ -1242,24 +1170,8 @@ public class DisplayPolicy {
// The index of the provider and corresponding insets types cannot change at
// runtime as ensured in WMS. Make use of the index in the provider directly
// to access the latest provided size at runtime.
final int index = i;
final TriConsumer<DisplayFrames, WindowContainer, Rect> frameProvider =
provider.insetsSize != null
? (displayFrames, windowContainer, inOutFrame) -> {
inOutFrame.inset(win.mGivenContentInsets);
final LayoutParams lp =
win.mAttrs.forRotation(displayFrames.mRotation);
final InsetsFrameProvider ifp =
win.mAttrs.forRotation(displayFrames.mRotation)
.providedInsets[index];
InsetsFrameProvider.calculateInsetsFrame(
displayFrames.mUnrestricted,
windowContainer.getBounds(),
displayFrames.mDisplayCutoutSafe,
inOutFrame, ifp.source,
ifp.insetsSize, lp.privateFlags,
ifp.minimalInsetsSizeInDisplayCutoutSafe);
} : null;
getFrameProvider(win, provider, i);
final InsetsFrameProvider.InsetsSizeOverride[] overrides =
provider.insetsSizeOverrides;
final SparseArray<TriConsumer<DisplayFrames, WindowContainer, Rect>>
@@ -1267,27 +1179,10 @@ public class DisplayPolicy {
if (overrides != null) {
overrideProviders = new SparseArray<>();
for (int j = overrides.length - 1; j >= 0; j--) {
final int overrideIndex = j;
final TriConsumer<DisplayFrames, WindowContainer, Rect>
overrideFrameProvider =
(displayFrames, windowContainer, inOutFrame) -> {
final LayoutParams lp =
win.mAttrs.forRotation(
displayFrames.mRotation);
final InsetsFrameProvider ifp =
win.mAttrs.providedInsets[index];
InsetsFrameProvider.calculateInsetsFrame(
displayFrames.mUnrestricted,
windowContainer.getBounds(),
displayFrames.mDisplayCutoutSafe,
inOutFrame, ifp.source,
ifp.insetsSizeOverrides[
overrideIndex].insetsSize,
lp.privateFlags,
null);
};
overrideProviders.put(overrides[j].windowType,
overrideFrameProvider);
getOverrideFrameProvider(win, i, j);
overrideProviders.put(overrides[j].windowType, overrideFrameProvider);
}
} else {
overrideProviders = null;
@@ -1299,6 +1194,36 @@ public class DisplayPolicy {
}
}
@Nullable
private TriConsumer<DisplayFrames, WindowContainer, Rect> getFrameProvider(WindowState win,
InsetsFrameProvider provider, int index) {
if (provider.insetsSize == null && provider.source == SOURCE_FRAME) {
return null;
}
return (displayFrames, windowContainer, inOutFrame) -> {
inOutFrame.inset(win.mGivenContentInsets);
final LayoutParams lp = win.mAttrs.forRotation(displayFrames.mRotation);
final InsetsFrameProvider ifp = lp.providedInsets[index];
InsetsFrameProvider.calculateInsetsFrame(displayFrames.mUnrestricted,
windowContainer.getBounds(), displayFrames.mDisplayCutoutSafe, inOutFrame,
ifp.source, ifp.insetsSize, lp.privateFlags,
ifp.minimalInsetsSizeInDisplayCutoutSafe);
};
}
@NonNull
private TriConsumer<DisplayFrames, WindowContainer, Rect> getOverrideFrameProvider(
WindowState win, int index, int overrideIndex) {
return (displayFrames, windowContainer, inOutFrame) -> {
final LayoutParams lp = win.mAttrs.forRotation(displayFrames.mRotation);
final InsetsFrameProvider ifp = lp.providedInsets[index];
InsetsFrameProvider.calculateInsetsFrame(displayFrames.mUnrestricted,
windowContainer.getBounds(), displayFrames.mDisplayCutoutSafe, inOutFrame,
ifp.source, ifp.insetsSizeOverrides[overrideIndex].insetsSize, lp.privateFlags,
null);
};
}
@WindowManagerPolicy.AltBarPosition
private int getAltBarPosition(WindowManager.LayoutParams params) {
switch (params.gravity) {
@@ -1386,16 +1311,6 @@ public class DisplayPolicy {
mInsetsSourceWindowsExceptIme.remove(win);
}
private int getStatusBarHeight(DisplayFrames displayFrames) {
int statusBarHeight;
if (mStatusBar != null) {
statusBarHeight = mStatusBar.mAttrs.forRotation(displayFrames.mRotation).height;
} else {
statusBarHeight = 0;
}
return Math.max(statusBarHeight, displayFrames.mDisplayCutoutSafe.top);
}
WindowState getStatusBar() {
return mStatusBar != null ? mStatusBar : mStatusBarAlt;
}
@@ -1892,27 +1807,12 @@ public class DisplayPolicy {
final Resources res = getCurrentUserResources();
final int portraitRotation = displayRotation.getPortraitRotation();
if (hasStatusBar()) {
mDisplayCutoutTouchableRegionSize = res.getDimensionPixelSize(
R.dimen.display_cutout_touchable_region_size);
} else {
mDisplayCutoutTouchableRegionSize = 0;
}
mNavBarOpacityMode = res.getInteger(R.integer.config_navBarOpacityMode);
mLeftGestureInset = mGestureNavigationSettingsObserver.getLeftSensitivity(res);
mRightGestureInset = mGestureNavigationSettingsObserver.getRightSensitivity(res);
mNavButtonForcedVisible =
mGestureNavigationSettingsObserver.areNavigationButtonForcedVisible();
mNavigationBarLetsThroughTaps = res.getBoolean(R.bool.config_navBarTapThrough);
mNavigationBarAlwaysShowOnSideGesture =
res.getBoolean(R.bool.config_navBarAlwaysShowOnSideEdgeGesture);
// This should calculate how much above the frame we accept gestures.
mBottomGestureAdditionalInset =
res.getDimensionPixelSize(R.dimen.navigation_bar_gesture_height)
- getNavigationBarFrameHeight(portraitRotation);
updateConfigurationAndScreenSizeDependentBehaviors();
final boolean shouldAttach =

View File

@@ -266,6 +266,7 @@ import android.view.InputApplicationHandle;
import android.view.InputChannel;
import android.view.InputDevice;
import android.view.InputWindowHandle;
import android.view.InsetsFrameProvider;
import android.view.InsetsSourceControl;
import android.view.InsetsState;
import android.view.InsetsVisibilities;
@@ -2277,6 +2278,27 @@ public class WindowManagerService extends IWindowManager.Stub
"Insets types can not be changed after the window is "
+ "added.");
}
final InsetsFrameProvider.InsetsSizeOverride[] overrides =
win.mAttrs.providedInsets[i].insetsSizeOverrides;
final InsetsFrameProvider.InsetsSizeOverride[] newOverrides =
attrs.providedInsets[i].insetsSizeOverrides;
if (!(overrides == null && newOverrides == null)) {
if (overrides == null || newOverrides == null
|| (overrides.length != newOverrides.length)) {
throw new IllegalArgumentException(
"Insets override types can not be changed after the "
+ "window is added.");
} else {
final int overrideTypes = overrides.length;
for (int j = 0; j < overrideTypes; j++) {
if (overrides[j].windowType != newOverrides[j].windowType) {
throw new IllegalArgumentException(
"Insets override types can not be changed after"
+ " the window is added.");
}
}
}
}
}
}
}

View File

@@ -19,6 +19,8 @@ package com.android.server.wm;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.view.InsetsState.ITYPE_BOTTOM_MANDATORY_GESTURES;
import static android.view.InsetsState.ITYPE_BOTTOM_TAPPABLE_ELEMENT;
import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
import static android.view.InsetsState.ITYPE_STATUS_BAR;
import static android.view.InsetsState.ITYPE_TOP_MANDATORY_GESTURES;
@@ -74,7 +76,7 @@ public class InsetsPolicyTest extends WindowTestsBase {
@Test
public void testControlsForDispatch_regular() {
addStatusBar();
addWindow(TYPE_NAVIGATION_BAR, "navBar");
addNavigationBar();
final InsetsSourceControl[] controls = addAppWindowAndGetControlsForDispatch();
@@ -86,7 +88,7 @@ public class InsetsPolicyTest extends WindowTestsBase {
@Test
public void testControlsForDispatch_multiWindowTaskVisible() {
addStatusBar();
addWindow(TYPE_NAVIGATION_BAR, "navBar");
addNavigationBar();
final WindowState win = createWindow(null, WINDOWING_MODE_MULTI_WINDOW,
ACTIVITY_TYPE_STANDARD, TYPE_APPLICATION, mDisplayContent, "app");
@@ -99,7 +101,7 @@ public class InsetsPolicyTest extends WindowTestsBase {
@Test
public void testControlsForDispatch_freeformTaskVisible() {
addStatusBar();
addWindow(TYPE_NAVIGATION_BAR, "navBar");
addNavigationBar();
final WindowState win = createWindow(null, WINDOWING_MODE_FREEFORM,
ACTIVITY_TYPE_STANDARD, TYPE_APPLICATION, mDisplayContent, "app");
@@ -112,7 +114,7 @@ public class InsetsPolicyTest extends WindowTestsBase {
@Test
public void testControlsForDispatch_forceStatusBarVisible() {
addStatusBar().mAttrs.privateFlags |= PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR;
addWindow(TYPE_NAVIGATION_BAR, "navBar");
addNavigationBar();
final InsetsSourceControl[] controls = addAppWindowAndGetControlsForDispatch();
@@ -126,7 +128,7 @@ public class InsetsPolicyTest extends WindowTestsBase {
addWindow(TYPE_NOTIFICATION_SHADE, "notificationShade").mAttrs.privateFlags |=
PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION;
addStatusBar();
addWindow(TYPE_NAVIGATION_BAR, "navBar");
addNavigationBar();
final InsetsSourceControl[] controls = addAppWindowAndGetControlsForDispatch();
@@ -139,7 +141,7 @@ public class InsetsPolicyTest extends WindowTestsBase {
public void testControlsForDispatch_statusBarForceShowNavigation_butFocusedAnyways() {
WindowState notifShade = addWindow(TYPE_NOTIFICATION_SHADE, "notificationShade");
notifShade.mAttrs.privateFlags |= PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION;
addWindow(TYPE_NAVIGATION_BAR, "navBar");
addNavigationBar();
mDisplayContent.getInsetsPolicy().updateBarControlTarget(notifShade);
InsetsSourceControl[] controls
@@ -155,7 +157,7 @@ public class InsetsPolicyTest extends WindowTestsBase {
mDisplayContent.setRemoteInsetsController(createDisplayWindowInsetsController());
mDisplayContent.getInsetsPolicy().setRemoteInsetsControllerControlsSystemBars(true);
addStatusBar();
addWindow(TYPE_NAVIGATION_BAR, "navBar");
addNavigationBar();
final InsetsSourceControl[] controls = addAppWindowAndGetControlsForDispatch();
@@ -166,7 +168,7 @@ public class InsetsPolicyTest extends WindowTestsBase {
@Test
public void testControlsForDispatch_topAppHidesStatusBar() {
addStatusBar();
addWindow(TYPE_NAVIGATION_BAR, "navBar");
addNavigationBar();
// Add a fullscreen (MATCH_PARENT x MATCH_PARENT) app window which hides status bar.
final WindowState fullscreenApp = addWindow(TYPE_APPLICATION, "fullscreenApp");
@@ -261,7 +263,7 @@ public class InsetsPolicyTest extends WindowTestsBase {
final WindowState statusBar = addStatusBar();
statusBar.setHasSurface(true);
statusBar.getControllableInsetProvider().setServerVisible(true);
final WindowState navBar = addNonFocusableWindow(TYPE_NAVIGATION_BAR, "navBar");
final WindowState navBar = addNavigationBar();
navBar.setHasSurface(true);
navBar.getControllableInsetProvider().setServerVisible(true);
final InsetsPolicy policy = spy(mDisplayContent.getInsetsPolicy());
@@ -301,8 +303,7 @@ public class InsetsPolicyTest extends WindowTestsBase {
@Test
public void testShowTransientBars_statusBarCanBeTransient_appGetsStatusBarFakeControl() {
addStatusBar().getControllableInsetProvider().getSource().setVisible(false);
addNonFocusableWindow(TYPE_NAVIGATION_BAR, "navBar")
.getControllableInsetProvider().setServerVisible(true);
addNavigationBar().getControllableInsetProvider().setServerVisible(true);
final InsetsPolicy policy = spy(mDisplayContent.getInsetsPolicy());
doNothing().when(policy).startAnimation(anyBoolean(), any());
@@ -331,8 +332,8 @@ public class InsetsPolicyTest extends WindowTestsBase {
public void testAbortTransientBars_bothCanBeAborted_appGetsBothRealControls() {
final InsetsSource statusBarSource =
addStatusBar().getControllableInsetProvider().getSource();
final InsetsSource navBarSource = addNonFocusableWindow(TYPE_NAVIGATION_BAR, "navBar")
.getControllableInsetProvider().getSource();
final InsetsSource navBarSource =
addNavigationBar().getControllableInsetProvider().getSource();
statusBarSource.setVisible(false);
navBarSource.setVisible(false);
mAppWindow.mAboveInsetsState.addSource(navBarSource);
@@ -383,8 +384,7 @@ public class InsetsPolicyTest extends WindowTestsBase {
@Test
public void testShowTransientBars_abortsWhenControlTargetChanges() {
addStatusBar().getControllableInsetProvider().getSource().setVisible(false);
addNonFocusableWindow(TYPE_NAVIGATION_BAR, "navBar")
.getControllableInsetProvider().getSource().setVisible(false);
addNavigationBar().getControllableInsetProvider().getSource().setVisible(false);
final WindowState app = addWindow(TYPE_APPLICATION, "app");
final WindowState app2 = addWindow(TYPE_APPLICATION, "app");
@@ -400,9 +400,15 @@ public class InsetsPolicyTest extends WindowTestsBase {
assertFalse(policy.isTransient(ITYPE_NAVIGATION_BAR));
}
private WindowState addNonFocusableWindow(int type, String name) {
WindowState win = addWindow(type, name);
private WindowState addNavigationBar() {
final WindowState win = createWindow(null, TYPE_NAVIGATION_BAR, "navBar");
win.mAttrs.flags |= FLAG_NOT_FOCUSABLE;
win.mAttrs.providedInsets = new InsetsFrameProvider[] {
new InsetsFrameProvider(ITYPE_NAVIGATION_BAR),
new InsetsFrameProvider(ITYPE_BOTTOM_MANDATORY_GESTURES),
new InsetsFrameProvider(ITYPE_BOTTOM_TAPPABLE_ELEMENT)
};
mDisplayContent.getDisplayPolicy().addWindowLw(win, win.mAttrs);
return win;
}
@@ -429,6 +435,10 @@ public class InsetsPolicyTest extends WindowTestsBase {
}
private InsetsSourceControl[] addWindowAndGetControlsForDispatch(WindowState win) {
mDisplayContent.getDisplayPolicy().addWindowLw(win, win.mAttrs);
// Force update the focus in DisplayPolicy here. Otherwise, without server side focus
// update, the policy relying on windowing type will never get updated.
mDisplayContent.getDisplayPolicy().focusChangedLw(null, win);
mDisplayContent.getInsetsPolicy().updateBarControlTarget(win);
return mDisplayContent.getInsetsStateController().getControlsForDispatch(win);
}

View File

@@ -26,6 +26,8 @@ import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.os.Process.SYSTEM_UID;
import static android.view.InsetsState.ITYPE_BOTTOM_MANDATORY_GESTURES;
import static android.view.InsetsState.ITYPE_BOTTOM_TAPPABLE_ELEMENT;
import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
import static android.view.InsetsState.ITYPE_STATUS_BAR;
import static android.view.InsetsState.ITYPE_TOP_MANDATORY_GESTURES;
@@ -347,6 +349,11 @@ class WindowTestsBase extends SystemServiceTestsBase {
LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
mNavBarWindow.mAttrs.privateFlags |=
WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT;
mNavBarWindow.mAttrs.providedInsets = new InsetsFrameProvider[] {
new InsetsFrameProvider(ITYPE_NAVIGATION_BAR),
new InsetsFrameProvider(ITYPE_BOTTOM_MANDATORY_GESTURES),
new InsetsFrameProvider(ITYPE_BOTTOM_TAPPABLE_ELEMENT)
};
for (int rot = Surface.ROTATION_0; rot <= Surface.ROTATION_270; rot++) {
mNavBarWindow.mAttrs.paramsForRotation[rot] =
getNavBarLayoutParamsForRotation(rot);
@@ -400,6 +407,11 @@ class WindowTestsBase extends SystemServiceTestsBase {
lp.privateFlags |=
WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT;
lp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
lp.providedInsets = new InsetsFrameProvider[] {
new InsetsFrameProvider(ITYPE_NAVIGATION_BAR),
new InsetsFrameProvider(ITYPE_BOTTOM_MANDATORY_GESTURES),
new InsetsFrameProvider(ITYPE_BOTTOM_TAPPABLE_ELEMENT)
};
return lp;
}