Merge "Refine the provide insets parameters" into tm-qpr-dev am: 9607932ce9

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/17799734

Change-Id: I3b6bd2f97bef268a65f6471bf880a86c621aa92f
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Yunfan Chen
2022-06-13 11:59:22 +00:00
committed by Automerger Merge Worker
9 changed files with 373 additions and 216 deletions

View File

@@ -0,0 +1,205 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.view;
import android.graphics.Insets;
import android.os.Parcel;
import android.os.Parcelable;
import java.util.Objects;
/**
* Insets provided by a window.
*
* The insets frame will by default as the window frame size. If the providers are set, the
* calculation result based on the source size will be used as the insets frame.
* @hide
*/
public class InsetsFrameProvider implements Parcelable {
/**
* If specified in source field, the insets calculation will be based on the display frame.
*/
public static final int SOURCE_DISPLAY = 0;
/**
* If specified in source field, the insets calculation will be based on the window bounds. The
* container bounds can sometimes be different from the window frame. For example, when a task
* bar needs the entire screen to be prepared to showing the apps, the window container can take
* the entire display, or display area, but the window frame, as a result of the layout, will
* stay small until it actually taking the entire display to draw their view.
*/
public static final int SOURCE_CONTAINER_BOUNDS = 1;
/**
* If specified in source field, the insets calculation will be based on the window frame. This
* is also the default value of the source.
*/
public static final int SOURCE_FRAME = 2;
private static final int HAS_INSETS_SIZE = 1;
private static final int HAS_IME_INSETS_SIZE = 2;
/**
* The type of insets to provide.
*/
public @InsetsState.InternalInsetsType int type;
/**
* The source of frame. By default, all adjustment will be based on the window frame, it
* can be set to window bounds or display bounds instead.
*/
public int source = SOURCE_FRAME;
/**
* The provided insets size based on the source frame. The result will be used as the insets
* size to windows other than IME. Only one side should be set.
*
* For example, when the given source frame is (0, 0) - (100, 200), and the insetsSize is null,
* the source frame will be directly used as the final insets frame. If the insetsSize is set to
* (0, 0, 0, 50) instead, the insets frame will be a frame starting from the bottom side of the
* source frame with height of 50, i.e., (0, 150) - (100, 200).
*/
public Insets insetsSize = null;
/**
* The provided frame based on the source frame. The result will be used as the insets
* size to IME window. Only one side should be set.
*/
public Insets imeInsetsSize = null;
public InsetsFrameProvider(int type) {
this(type, SOURCE_FRAME, null, null);
}
public InsetsFrameProvider(int type, Insets insetsSize) {
this(type, SOURCE_FRAME, insetsSize, insetsSize);
}
public InsetsFrameProvider(int type, Insets insetsSize, Insets imeInsetsSize) {
this(type, SOURCE_FRAME, insetsSize, imeInsetsSize);
}
public InsetsFrameProvider(int type, int source, Insets insetsSize,
Insets imeInsetsSize) {
this.type = type;
this.source = source;
this.insetsSize = insetsSize;
this.imeInsetsSize = imeInsetsSize;
}
@Override
public int describeContents() {
return 0;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder(32);
sb.append("InsetsFrameProvider: {");
sb.append("type=").append(InsetsState.typeToString(type));
sb.append(", source=");
switch (source) {
case SOURCE_DISPLAY:
sb.append("SOURCE_DISPLAY");
break;
case SOURCE_CONTAINER_BOUNDS:
sb.append("SOURCE_CONTAINER_BOUNDS Bounds");
break;
case SOURCE_FRAME:
sb.append("SOURCE_FRAME");
break;
}
if (insetsSize != null) {
sb.append(", insetsSize=").append(insetsSize);
}
if (imeInsetsSize != null) {
sb.append(", imeInsetsSize=").append(imeInsetsSize);
}
sb.append("}");
return sb.toString();
}
public InsetsFrameProvider(Parcel in) {
int insetsSizeModified = in.readInt();
type = in.readInt();
source = in.readInt();
if ((insetsSizeModified & HAS_INSETS_SIZE) != 0) {
insetsSize = Insets.CREATOR.createFromParcel(in);
}
if ((insetsSizeModified & HAS_IME_INSETS_SIZE) != 0) {
imeInsetsSize = Insets.CREATOR.createFromParcel(in);
}
}
@Override
public void writeToParcel(Parcel out, int flags) {
int insetsSizeModified = 0;
if (insetsSize != null) {
insetsSizeModified |= HAS_INSETS_SIZE;
}
if (imeInsetsSize != null) {
insetsSizeModified |= HAS_IME_INSETS_SIZE;
}
out.writeInt(insetsSizeModified);
out.writeInt(type);
out.writeInt(source);
if (insetsSize != null) {
insetsSize.writeToParcel(out, flags);
}
if (imeInsetsSize != null) {
imeInsetsSize.writeToParcel(out, flags);
}
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
InsetsFrameProvider other = (InsetsFrameProvider) o;
return type == other.type && source == other.source
&& Objects.equals(insetsSize, other.insetsSize)
&& Objects.equals(imeInsetsSize, other.imeInsetsSize);
}
@Override
public int hashCode() {
int result = type;
result = 31 * result + source;
result = 31 * result + (insetsSize != null ? insetsSize.hashCode() : 0);
result = 31 * result + (imeInsetsSize != null ? imeInsetsSize.hashCode() : 0);
return result;
}
public static final @android.annotation.NonNull Parcelable.Creator<InsetsFrameProvider>
CREATOR = new Parcelable.Creator<InsetsFrameProvider>() {
@Override
public InsetsFrameProvider createFromParcel(Parcel in) {
return new InsetsFrameProvider(in);
}
@Override
public InsetsFrameProvider[] newArray(int size) {
return new InsetsFrameProvider[size];
}
};
}

View File

@@ -98,7 +98,6 @@ import android.content.Context;
import android.content.pm.ActivityInfo; import android.content.pm.ActivityInfo;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.Insets;
import android.graphics.PixelFormat; import android.graphics.PixelFormat;
import android.graphics.Point; import android.graphics.Point;
import android.graphics.Rect; import android.graphics.Rect;
@@ -3603,34 +3602,17 @@ public interface WindowManager extends ViewManager {
private boolean mFitInsetsIgnoringVisibility = false; private boolean mFitInsetsIgnoringVisibility = false;
/** /**
* {@link InsetsState.InternalInsetsType}s to be applied to the window * If set, the specified insets types will be provided by the window and the insets frame
* If {@link #type} has the predefined insets (like {@link #TYPE_STATUS_BAR} or * will be calculated based on the provider's parameters. The insets types and the array
* {@link #TYPE_NAVIGATION_BAR}), this field will be ignored. * should not be modified after the window is added. If multiple layout parameters are
* * provided for different rotations in {@link LayoutParams#paramsForRotation}, the types in
* <p>Note: provide only one inset corresponding to the window type (like * the providedInsets array should be the same in all rotations, including the base one.
* {@link InsetsState.InternalInsetsType#ITYPE_STATUS_BAR} or * All other params can be adjusted at runtime.
* {@link InsetsState.InternalInsetsType#ITYPE_NAVIGATION_BAR})</p> * See {@link InsetsFrameProvider}.
* @hide
*/
public @InsetsState.InternalInsetsType int[] providesInsetsTypes;
/**
* If specified, the insets provided by this window will be our window frame minus the
* insets specified by providedInternalInsets for each type. This should not be used
* together with {@link WindowState#mGivenContentInsets}. If both of them are set, both will
* be applied.
* *
* @hide * @hide
*/ */
public Insets[] providedInternalInsets; public InsetsFrameProvider[] providedInsets;
/**
* If specified, the insets provided by this window for the IME will be our window frame
* minus the insets specified by providedInternalImeInsets.
*
* @hide
*/
public Insets[] providedInternalImeInsets;
/** /**
* If specified, the frame that used to calculate relative {@link RoundedCorner} will be * If specified, the frame that used to calculate relative {@link RoundedCorner} will be
@@ -4010,32 +3992,10 @@ public interface WindowManager extends ViewManager {
out.writeBoolean(mFitInsetsIgnoringVisibility); out.writeBoolean(mFitInsetsIgnoringVisibility);
out.writeBoolean(preferMinimalPostProcessing); out.writeBoolean(preferMinimalPostProcessing);
out.writeInt(mBlurBehindRadius); out.writeInt(mBlurBehindRadius);
if (providesInsetsTypes != null) {
out.writeInt(providesInsetsTypes.length);
out.writeIntArray(providesInsetsTypes);
} else {
out.writeInt(0);
}
if (providedInternalInsets != null) {
out.writeInt(providedInternalInsets.length);
out.writeTypedArray(providedInternalInsets, 0 /* parcelableFlags */);
} else {
out.writeInt(0);
}
if (providedInternalImeInsets != null) {
out.writeInt(providedInternalImeInsets.length);
out.writeTypedArray(providedInternalImeInsets, 0 /* parcelableFlags */);
} else {
out.writeInt(0);
}
out.writeBoolean(insetsRoundedCornerFrame); out.writeBoolean(insetsRoundedCornerFrame);
if (paramsForRotation != null) { out.writeTypedArray(providedInsets, 0 /* parcelableFlags */);
checkNonRecursiveParams(); checkNonRecursiveParams();
out.writeInt(paramsForRotation.length);
out.writeTypedArray(paramsForRotation, 0 /* parcelableFlags */); out.writeTypedArray(paramsForRotation, 0 /* parcelableFlags */);
} else {
out.writeInt(0);
}
} }
public static final @android.annotation.NonNull Parcelable.Creator<LayoutParams> CREATOR public static final @android.annotation.NonNull Parcelable.Creator<LayoutParams> CREATOR
@@ -4102,27 +4062,9 @@ public interface WindowManager extends ViewManager {
mFitInsetsIgnoringVisibility = in.readBoolean(); mFitInsetsIgnoringVisibility = in.readBoolean();
preferMinimalPostProcessing = in.readBoolean(); preferMinimalPostProcessing = in.readBoolean();
mBlurBehindRadius = in.readInt(); mBlurBehindRadius = in.readInt();
int insetsTypesLength = in.readInt();
if (insetsTypesLength > 0) {
providesInsetsTypes = new int[insetsTypesLength];
in.readIntArray(providesInsetsTypes);
}
int providedInternalInsetsLength = in.readInt();
if (providedInternalInsetsLength > 0) {
providedInternalInsets = new Insets[providedInternalInsetsLength];
in.readTypedArray(providedInternalInsets, Insets.CREATOR);
}
int providedInternalImeInsetsLength = in.readInt();
if (providedInternalImeInsetsLength > 0) {
providedInternalImeInsets = new Insets[providedInternalImeInsetsLength];
in.readTypedArray(providedInternalImeInsets, Insets.CREATOR);
}
insetsRoundedCornerFrame = in.readBoolean(); insetsRoundedCornerFrame = in.readBoolean();
int paramsForRotationLength = in.readInt(); providedInsets = in.createTypedArray(InsetsFrameProvider.CREATOR);
if (paramsForRotationLength > 0) { paramsForRotation = in.createTypedArray(LayoutParams.CREATOR);
paramsForRotation = new LayoutParams[paramsForRotationLength];
in.readTypedArray(paramsForRotation, LayoutParams.CREATOR);
}
} }
@SuppressWarnings({"PointlessBitwiseExpression"}) @SuppressWarnings({"PointlessBitwiseExpression"})
@@ -4414,18 +4356,8 @@ public interface WindowManager extends ViewManager {
changes |= LAYOUT_CHANGED; changes |= LAYOUT_CHANGED;
} }
if (!Arrays.equals(providesInsetsTypes, o.providesInsetsTypes)) { if (!Arrays.equals(providedInsets, o.providedInsets)) {
providesInsetsTypes = o.providesInsetsTypes; providedInsets = o.providedInsets;
changes |= LAYOUT_CHANGED;
}
if (!Arrays.equals(providedInternalInsets, o.providedInternalInsets)) {
providedInternalInsets = o.providedInternalInsets;
changes |= LAYOUT_CHANGED;
}
if (!Arrays.equals(providedInternalImeInsets, o.providedInternalImeInsets)) {
providedInternalImeInsets = o.providedInternalImeInsets;
changes |= LAYOUT_CHANGED; changes |= LAYOUT_CHANGED;
} }
@@ -4627,28 +4559,12 @@ public interface WindowManager extends ViewManager {
sb.append(System.lineSeparator()); sb.append(System.lineSeparator());
sb.append(prefix).append(" fitIgnoreVis"); sb.append(prefix).append(" fitIgnoreVis");
} }
if (providesInsetsTypes != null) { if (providedInsets != null) {
sb.append(System.lineSeparator()); sb.append(System.lineSeparator());
sb.append(prefix).append(" insetsTypes="); sb.append(" providedInsets=");
for (int i = 0; i < providesInsetsTypes.length; ++i) { for (int i = 0; i < providedInsets.length; ++i) {
if (i > 0) sb.append(' '); if (i > 0) sb.append(' ');
sb.append(InsetsState.typeToString(providesInsetsTypes[i])); sb.append((providedInsets[i]));
}
}
if (providedInternalInsets != null) {
sb.append(System.lineSeparator());
sb.append(" providedInternalInsets=");
for (int i = 0; i < providedInternalInsets.length; ++i) {
if (i > 0) sb.append(' ');
sb.append((providedInternalInsets[i]));
}
}
if (providedInternalImeInsets != null) {
sb.append(System.lineSeparator());
sb.append(" providedInternalImeInsets=");
for (int i = 0; i < providedInternalImeInsets.length; ++i) {
if (i > 0) sb.append(' ');
sb.append((providedInternalImeInsets[i]));
} }
} }
if (insetsRoundedCornerFrame) { if (insetsRoundedCornerFrame) {

View File

@@ -28,6 +28,7 @@ import android.os.Handler;
import android.os.RemoteException; import android.os.RemoteException;
import android.util.Log; import android.util.Log;
import android.view.InsetsController; import android.view.InsetsController;
import android.view.InsetsFrameProvider;
import android.view.InsetsState; import android.view.InsetsState;
import android.view.SurfaceControl; import android.view.SurfaceControl;
import android.view.WindowManager; import android.view.WindowManager;
@@ -105,7 +106,11 @@ public class WindowManagerWrapper {
*/ */
public void setProvidesInsetsTypes(WindowManager.LayoutParams params, public void setProvidesInsetsTypes(WindowManager.LayoutParams params,
int[] providesInsetsTypes) { int[] providesInsetsTypes) {
params.providesInsetsTypes = providesInsetsTypes; final int length = providesInsetsTypes.length;
params.providedInsets = new InsetsFrameProvider[length];
for (int i = 0; i < length; i++) {
params.providedInsets[i] = new InsetsFrameProvider(providesInsetsTypes[i]);
}
} }
/** /**

View File

@@ -80,7 +80,7 @@ import android.util.Log;
import android.view.Display; import android.view.Display;
import android.view.Gravity; import android.view.Gravity;
import android.view.HapticFeedbackConstants; import android.view.HapticFeedbackConstants;
import android.view.InsetsState; import android.view.InsetsFrameProvider;
import android.view.InsetsState.InternalInsetsType; import android.view.InsetsState.InternalInsetsType;
import android.view.InsetsVisibilities; import android.view.InsetsVisibilities;
import android.view.KeyEvent; import android.view.KeyEvent;
@@ -1631,12 +1631,14 @@ public class NavigationBar extends ViewController<NavigationBarView> implements
| WindowManager.LayoutParams.FLAG_SLIPPERY, | WindowManager.LayoutParams.FLAG_SLIPPERY,
PixelFormat.TRANSLUCENT); PixelFormat.TRANSLUCENT);
lp.gravity = gravity; lp.gravity = gravity;
lp.providedInternalInsets = new Insets[InsetsState.SIZE];
if (insetsHeight != -1) { if (insetsHeight != -1) {
lp.providedInternalInsets[ITYPE_NAVIGATION_BAR] = lp.providedInsets = new InsetsFrameProvider[] {
Insets.of(0, height - insetsHeight, 0, 0); new InsetsFrameProvider(ITYPE_NAVIGATION_BAR, Insets.of(0, 0, 0, insetsHeight))
};
} else { } else {
lp.providedInternalInsets[ITYPE_NAVIGATION_BAR] = null; lp.providedInsets = new InsetsFrameProvider[] {
new InsetsFrameProvider(ITYPE_NAVIGATION_BAR)
};
} }
lp.token = new Binder(); lp.token = new Binder();
lp.accessibilityTitle = userContext.getString(R.string.nav_bar); lp.accessibilityTitle = userContext.getString(R.string.nav_bar);

View File

@@ -120,6 +120,7 @@ import android.view.DisplayCutout;
import android.view.DisplayInfo; import android.view.DisplayInfo;
import android.view.Gravity; import android.view.Gravity;
import android.view.InsetsFlags; import android.view.InsetsFlags;
import android.view.InsetsFrameProvider;
import android.view.InsetsSource; import android.view.InsetsSource;
import android.view.InsetsState; import android.view.InsetsState;
import android.view.InsetsState.InternalInsetsType; import android.view.InsetsState.InternalInsetsType;
@@ -1079,17 +1080,18 @@ public class DisplayPolicy {
return WindowManagerGlobal.ADD_INVALID_TYPE; return WindowManagerGlobal.ADD_INVALID_TYPE;
} }
if (attrs.providesInsetsTypes != null) { if (attrs.providedInsets != null) {
// Recents component is allowed to add inset types. // Recents component is allowed to add inset types.
if (!mService.mAtmService.isCallerRecents(callingUid)) { if (!mService.mAtmService.isCallerRecents(callingUid)) {
mContext.enforcePermission( mContext.enforcePermission(
android.Manifest.permission.STATUS_BAR_SERVICE, callingPid, callingUid, android.Manifest.permission.STATUS_BAR_SERVICE, callingPid, callingUid,
"DisplayPolicy"); "DisplayPolicy");
} }
enforceSingleInsetsTypeCorrespondingToWindowType(attrs.providesInsetsTypes); enforceSingleInsetsTypeCorrespondingToWindowType(attrs.providedInsets);
for (@InternalInsetsType int insetType : attrs.providesInsetsTypes) { for (InsetsFrameProvider provider : attrs.providedInsets) {
switch (insetType) { @InternalInsetsType int insetsType = provider.type;
switch (insetsType) {
case ITYPE_STATUS_BAR: case ITYPE_STATUS_BAR:
if ((mStatusBar != null && mStatusBar.isAlive()) if ((mStatusBar != null && mStatusBar.isAlive())
|| (mStatusBarAlt != null && mStatusBarAlt.isAlive())) { || (mStatusBarAlt != null && mStatusBarAlt.isAlive())) {
@@ -1155,12 +1157,19 @@ public class DisplayPolicy {
mDisplayContent.setInsetProvider(ITYPE_NAVIGATION_BAR, win, mDisplayContent.setInsetProvider(ITYPE_NAVIGATION_BAR, win,
(displayFrames, windowContainer, inOutFrame) -> { (displayFrames, windowContainer, inOutFrame) -> {
if (!mNavButtonForcedVisible) { if (!mNavButtonForcedVisible) {
final Insets[] providedInternalInsets = win.getLayoutingAttrs( final LayoutParams lp =
displayFrames.mRotation).providedInternalInsets; win.getLayoutingAttrs(displayFrames.mRotation);
if (providedInternalInsets != null if (lp.providedInsets != null) {
&& providedInternalInsets.length > ITYPE_NAVIGATION_BAR for (InsetsFrameProvider provider :
&& providedInternalInsets[ITYPE_NAVIGATION_BAR] != null) { win.getLayoutingAttrs(displayFrames.mRotation)
inOutFrame.inset(providedInternalInsets[ITYPE_NAVIGATION_BAR]); .providedInsets) {
if (provider.type != ITYPE_NAVIGATION_BAR) {
continue;
}
calculateInsetsFrame(displayFrames, win, inOutFrame,
provider.source, provider.insetsSize
);
}
} }
inOutFrame.inset(win.mGivenContentInsets); inOutFrame.inset(win.mGivenContentInsets);
} }
@@ -1204,21 +1213,9 @@ public class DisplayPolicy {
if (DEBUG_LAYOUT) Slog.i(TAG, "NAVIGATION BAR: " + mNavigationBar); if (DEBUG_LAYOUT) Slog.i(TAG, "NAVIGATION BAR: " + mNavigationBar);
break; break;
default: default:
if (attrs.providesInsetsTypes != null) { if (attrs.providedInsets != null) {
for (@InternalInsetsType int insetsType : attrs.providesInsetsTypes) { for (InsetsFrameProvider provider : attrs.providedInsets) {
final TriConsumer<DisplayFrames, WindowContainer, Rect> imeFrameProvider = switch (provider.type) {
win.getAttrs().providedInternalImeInsets != null
? (displayFrames, windowContainer, inOutFrame) -> {
final Insets[] providedInternalImeInsets =
win.getLayoutingAttrs(displayFrames.mRotation)
.providedInternalImeInsets;
if (providedInternalImeInsets != null
&& providedInternalImeInsets.length > insetsType
&& providedInternalImeInsets[insetsType] != null) {
inOutFrame.inset(providedInternalImeInsets[insetsType]);
}
} : null;
switch (insetsType) {
case ITYPE_STATUS_BAR: case ITYPE_STATUS_BAR:
mStatusBarAlt = win; mStatusBarAlt = win;
mStatusBarAltPosition = getAltBarPosition(attrs); mStatusBarAltPosition = getAltBarPosition(attrs);
@@ -1236,41 +1233,24 @@ public class DisplayPolicy {
mExtraNavBarAltPosition = getAltBarPosition(attrs); mExtraNavBarAltPosition = getAltBarPosition(attrs);
break; break;
} }
mDisplayContent.setInsetProvider(insetsType, win, final TriConsumer<DisplayFrames, WindowContainer, Rect> frameProvider =
win.getAttrs().providedInternalInsets != null ? (displayFrames, provider.insetsSize != null
windowContainer, inOutFrame) -> { ? (displayFrames, windowContainer, inOutFrame) -> {
final Insets[] providedInternalInsets = win.getLayoutingAttrs(
displayFrames.mRotation).providedInternalInsets;
if (providedInternalInsets != null
&& providedInternalInsets.length > insetsType
&& providedInternalInsets[insetsType] != null) {
inOutFrame.inset(providedInternalInsets[insetsType]);
}
inOutFrame.inset(win.mGivenContentInsets); inOutFrame.inset(win.mGivenContentInsets);
} : null, imeFrameProvider); calculateInsetsFrame(displayFrames, windowContainer,
if (mNavigationBar == null && (insetsType == ITYPE_NAVIGATION_BAR inOutFrame, provider.source,
|| insetsType == ITYPE_EXTRA_NAVIGATION_BAR)) { provider.insetsSize);
mDisplayContent.setInsetProvider(ITYPE_LEFT_GESTURES, win, } : null;
(displayFrames, windowState, inOutFrame) -> { final TriConsumer<DisplayFrames, WindowContainer, Rect> imeFrameProvider =
final int leftSafeInset = provider.imeInsetsSize != null
Math.max(displayFrames.mDisplayCutoutSafe.left,0); ? (displayFrames, windowContainer, inOutFrame) -> {
inOutFrame.left = 0; inOutFrame.inset(win.mGivenContentInsets);
inOutFrame.top = 0; calculateInsetsFrame(displayFrames, windowContainer,
inOutFrame.bottom = displayFrames.mDisplayHeight; inOutFrame, provider.source,
inOutFrame.right = provider.imeInsetsSize);
leftSafeInset + mLeftGestureInset; } : null;
}); mDisplayContent.setInsetProvider(provider.type, win, frameProvider,
mDisplayContent.setInsetProvider(ITYPE_RIGHT_GESTURES, win, imeFrameProvider);
(displayFrames, windowState, inOutFrame) -> {
final int rightSafeInset =
Math.min(displayFrames.mDisplayCutoutSafe.right,
displayFrames.mUnrestricted.right);
inOutFrame.left = rightSafeInset - mRightGestureInset;
inOutFrame.top = 0;
inOutFrame.bottom = displayFrames.mDisplayHeight;
inOutFrame.right = displayFrames.mDisplayWidth;
});
}
mInsetsSourceWindowsExceptIme.add(win); mInsetsSourceWindowsExceptIme.add(win);
} }
} }
@@ -1278,6 +1258,29 @@ public class DisplayPolicy {
} }
} }
private void calculateInsetsFrame(DisplayFrames df, WindowContainer coutainer, Rect inOutFrame,
int source, Insets insetsSize) {
if (source == InsetsFrameProvider.SOURCE_DISPLAY) {
inOutFrame.set(df.mUnrestricted);
} else if (source == InsetsFrameProvider.SOURCE_CONTAINER_BOUNDS) {
inOutFrame.set(coutainer.getBounds());
}
if (insetsSize == null || insetsSize.equals(Insets.NONE)) {
return;
}
// Only one side of the provider shall be applied. Check in the order of left - top -
// right - bottom, only the first non-zero value will be applied.
if (insetsSize.left != 0) {
inOutFrame.right = inOutFrame.left + insetsSize.left;
} else if (insetsSize.top != 0) {
inOutFrame.bottom = inOutFrame.top + insetsSize.top;
} else if (insetsSize.right != 0) {
inOutFrame.left = inOutFrame.right - insetsSize.right;
} else if (insetsSize.bottom != 0) {
inOutFrame.top = inOutFrame.bottom - insetsSize.bottom;
}
}
@WindowManagerPolicy.AltBarPosition @WindowManagerPolicy.AltBarPosition
private int getAltBarPosition(WindowManager.LayoutParams params) { private int getAltBarPosition(WindowManager.LayoutParams params) {
switch (params.gravity) { switch (params.gravity) {
@@ -1316,10 +1319,11 @@ public class DisplayPolicy {
}; };
} }
private static void enforceSingleInsetsTypeCorrespondingToWindowType(int[] insetsTypes) { private static void enforceSingleInsetsTypeCorrespondingToWindowType(
InsetsFrameProvider[] providers) {
int count = 0; int count = 0;
for (int insetsType : insetsTypes) { for (InsetsFrameProvider provider : providers) {
switch (insetsType) { switch (provider.type) {
case ITYPE_NAVIGATION_BAR: case ITYPE_NAVIGATION_BAR:
case ITYPE_STATUS_BAR: case ITYPE_STATUS_BAR:
case ITYPE_CLIMATE_BAR: case ITYPE_CLIMATE_BAR:
@@ -1978,25 +1982,20 @@ public class DisplayPolicy {
&& lp.paramsForRotation[rotation] != null) { && lp.paramsForRotation[rotation] != null) {
lp = lp.paramsForRotation[rotation]; lp = lp.paramsForRotation[rotation];
} }
final Insets providedInternalInsets; Insets providedInsetsSize = null;
if (lp.providedInternalInsets != null if (lp.providedInsets != null) {
&& lp.providedInternalInsets.length > ITYPE_NAVIGATION_BAR for (InsetsFrameProvider provider : lp.providedInsets) {
&& lp.providedInternalInsets[ITYPE_NAVIGATION_BAR] != null) { if (provider.type != ITYPE_NAVIGATION_BAR) {
providedInternalInsets = lp.providedInternalInsets[ITYPE_NAVIGATION_BAR]; continue;
} else {
providedInternalInsets = Insets.NONE;
} }
providedInsetsSize = provider.insetsSize;
}
}
if (providedInsetsSize != null) {
if (position == NAV_BAR_LEFT) { if (position == NAV_BAR_LEFT) {
if (lp.width > providedInternalInsets.right) { return providedInsetsSize.left;
return lp.width - providedInternalInsets.right;
} else {
return 0;
}
} else if (position == NAV_BAR_RIGHT) { } else if (position == NAV_BAR_RIGHT) {
if (lp.width > providedInternalInsets.left) { return providedInsetsSize.right;
return lp.width - providedInternalInsets.left;
} else {
return 0;
} }
} }
return lp.width; return lp.width;
@@ -2043,18 +2042,20 @@ public class DisplayPolicy {
return 0; return 0;
} }
LayoutParams lp = mNavigationBar.getLayoutingAttrs(rotation); LayoutParams lp = mNavigationBar.getLayoutingAttrs(rotation);
final Insets providedInternalInsets; Insets providedInsetsSize = null;
if (lp.providedInternalInsets != null if (lp.providedInsets != null) {
&& lp.providedInternalInsets.length > ITYPE_NAVIGATION_BAR for (InsetsFrameProvider provider : lp.providedInsets) {
&& lp.providedInternalInsets[ITYPE_NAVIGATION_BAR] != null) { if (provider.type != ITYPE_NAVIGATION_BAR) {
providedInternalInsets = lp.providedInternalInsets[ITYPE_NAVIGATION_BAR]; continue;
} else {
providedInternalInsets = Insets.NONE;
} }
if (lp.height < providedInternalInsets.top) { providedInsetsSize = provider.insetsSize;
return 0; if (providedInsetsSize != null) {
return providedInsetsSize.bottom;
} }
return lp.height - providedInternalInsets.top; break;
}
}
return lp.height;
} }
/** /**

View File

@@ -55,6 +55,7 @@ import android.view.InsetsAnimationControlCallbacks;
import android.view.InsetsAnimationControlImpl; import android.view.InsetsAnimationControlImpl;
import android.view.InsetsAnimationControlRunner; import android.view.InsetsAnimationControlRunner;
import android.view.InsetsController; import android.view.InsetsController;
import android.view.InsetsFrameProvider;
import android.view.InsetsSource; import android.view.InsetsSource;
import android.view.InsetsSourceControl; import android.view.InsetsSourceControl;
import android.view.InsetsState; import android.view.InsetsState;
@@ -322,14 +323,14 @@ class InsetsPolicy {
} }
// If not one of the types above, check whether an internal inset mapping is specified. // If not one of the types above, check whether an internal inset mapping is specified.
if (attrs.providesInsetsTypes != null) { if (attrs.providedInsets != null) {
for (@InternalInsetsType int insetsType : attrs.providesInsetsTypes) { for (InsetsFrameProvider provider : attrs.providedInsets) {
switch (insetsType) { switch (provider.type) {
case ITYPE_STATUS_BAR: case ITYPE_STATUS_BAR:
case ITYPE_NAVIGATION_BAR: case ITYPE_NAVIGATION_BAR:
case ITYPE_CLIMATE_BAR: case ITYPE_CLIMATE_BAR:
case ITYPE_EXTRA_NAVIGATION_BAR: case ITYPE_EXTRA_NAVIGATION_BAR:
return insetsType; return provider.type;
} }
} }
} }

View File

@@ -42,6 +42,7 @@ import android.graphics.Insets;
import android.graphics.Point; import android.graphics.Point;
import android.graphics.Rect; import android.graphics.Rect;
import android.util.proto.ProtoOutputStream; import android.util.proto.ProtoOutputStream;
import android.view.InsetsFrameProvider;
import android.view.InsetsSource; import android.view.InsetsSource;
import android.view.InsetsSourceControl; import android.view.InsetsSourceControl;
import android.view.InsetsState; import android.view.InsetsState;
@@ -513,12 +514,13 @@ abstract class InsetsSourceProvider {
if (mWindowContainer.asWindowState() == null) { if (mWindowContainer.asWindowState() == null) {
return false; return false;
} }
final int[] provides = ((WindowState) mWindowContainer).mAttrs.providesInsetsTypes; final InsetsFrameProvider[] providers =
if (provides == null) { ((WindowState) mWindowContainer).mAttrs.providedInsets;
if (providers == null) {
return false; return false;
} }
for (int i = 0; i < provides.length; i++) { for (int i = 0; i < providers.length; i++) {
if (provides[i] == ITYPE_IME) { if (providers[i].type == ITYPE_IME) {
return true; return true;
} }
} }

View File

@@ -2254,9 +2254,21 @@ public class WindowManagerService extends IWindowManager.Stub
throw new IllegalArgumentException( throw new IllegalArgumentException(
"Window type can not be changed after the window is added."); "Window type can not be changed after the window is added.");
} }
if (!Arrays.equals(win.mAttrs.providesInsetsTypes, attrs.providesInsetsTypes)) { if (!(win.mAttrs.providedInsets == null && attrs.providedInsets == null)) {
if (win.mAttrs.providedInsets == null || attrs.providedInsets == null
|| (win.mAttrs.providedInsets.length != attrs.providedInsets.length)) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"Insets types can not be changed after the window is added."); "Insets types can not be changed after the window is added.");
} else {
final int insetsTypes = attrs.providedInsets.length;
for (int i = 0; i < insetsTypes; i++) {
if (win.mAttrs.providedInsets[i].type != attrs.providedInsets[i].type) {
throw new IllegalArgumentException(
"Insets types can not be changed after the window is "
+ "added.");
}
}
}
} }
flagChanges = win.mAttrs.flags ^ attrs.flags; flagChanges = win.mAttrs.flags ^ attrs.flags;

View File

@@ -43,6 +43,7 @@ import android.graphics.Rect;
import android.platform.test.annotations.Presubmit; import android.platform.test.annotations.Presubmit;
import android.util.Pair; import android.util.Pair;
import android.view.DisplayInfo; import android.view.DisplayInfo;
import android.view.InsetsFrameProvider;
import android.view.InsetsState; import android.view.InsetsState;
import android.view.PrivacyIndicatorBounds; import android.view.PrivacyIndicatorBounds;
import android.view.RoundedCorners; import android.view.RoundedCorners;
@@ -153,7 +154,10 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
mDisplayPolicy.removeWindowLw(mStatusBarWindow); // Removes the existing one. mDisplayPolicy.removeWindowLw(mStatusBarWindow); // Removes the existing one.
WindowState win = createWindow(null, TYPE_STATUS_BAR_SUB_PANEL, "StatusBarSubPanel"); WindowState win = createWindow(null, TYPE_STATUS_BAR_SUB_PANEL, "StatusBarSubPanel");
win.mAttrs.providesInsetsTypes = new int[]{ITYPE_STATUS_BAR, ITYPE_TOP_GESTURES}; win.mAttrs.providedInsets = new InsetsFrameProvider[] {
new InsetsFrameProvider(ITYPE_STATUS_BAR),
new InsetsFrameProvider(ITYPE_TOP_GESTURES)
};
win.getFrame().set(0, 0, 500, 100); win.getFrame().set(0, 0, 500, 100);
addWindow(win); addWindow(win);
@@ -182,7 +186,9 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
public void addingWindow_InWindowTypeWithPredefinedInsets() { public void addingWindow_InWindowTypeWithPredefinedInsets() {
mDisplayPolicy.removeWindowLw(mStatusBarWindow); // Removes the existing one. mDisplayPolicy.removeWindowLw(mStatusBarWindow); // Removes the existing one.
WindowState win = createWindow(null, TYPE_STATUS_BAR, "StatusBar"); WindowState win = createWindow(null, TYPE_STATUS_BAR, "StatusBar");
win.mAttrs.providesInsetsTypes = new int[]{ITYPE_STATUS_BAR}; win.mAttrs.providedInsets = new InsetsFrameProvider[] {
new InsetsFrameProvider(ITYPE_STATUS_BAR)
};
win.getFrame().set(0, 0, 500, 100); win.getFrame().set(0, 0, 500, 100);
addWindow(win); addWindow(win);
@@ -199,12 +205,19 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
@Test @Test
public void addingWindow_throwsException_WithMultipleInsetTypes() { public void addingWindow_throwsException_WithMultipleInsetTypes() {
WindowState win1 = createWindow(null, TYPE_STATUS_BAR_SUB_PANEL, "StatusBarSubPanel"); WindowState win1 = createWindow(null, TYPE_STATUS_BAR_SUB_PANEL, "StatusBarSubPanel");
win1.mAttrs.providesInsetsTypes = new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR}; win1.mAttrs.providedInsets = new InsetsFrameProvider[] {
new InsetsFrameProvider(ITYPE_STATUS_BAR),
new InsetsFrameProvider(ITYPE_NAVIGATION_BAR)
};
expectThrows(IllegalArgumentException.class, () -> addWindow(win1)); expectThrows(IllegalArgumentException.class, () -> addWindow(win1));
WindowState win2 = createWindow(null, TYPE_STATUS_BAR_SUB_PANEL, "StatusBarSubPanel"); WindowState win2 = createWindow(null, TYPE_STATUS_BAR_SUB_PANEL, "StatusBarSubPanel");
win2.mAttrs.providesInsetsTypes = new int[]{ITYPE_CLIMATE_BAR, ITYPE_EXTRA_NAVIGATION_BAR};
win2.mAttrs.providedInsets = new InsetsFrameProvider[] {
new InsetsFrameProvider(ITYPE_CLIMATE_BAR),
new InsetsFrameProvider(ITYPE_EXTRA_NAVIGATION_BAR)
};
expectThrows(IllegalArgumentException.class, () -> addWindow(win2)); expectThrows(IllegalArgumentException.class, () -> addWindow(win2));
} }