Merge "Migrate Navigation Bar to InsetsFrameProvider"
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user