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:
205
core/java/android/view/InsetsFrameProvider.java
Normal file
205
core/java/android/view/InsetsFrameProvider.java
Normal 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];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -98,7 +98,6 @@ import android.content.Context;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Insets;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
@@ -3603,34 +3602,17 @@ public interface WindowManager extends ViewManager {
|
||||
private boolean mFitInsetsIgnoringVisibility = false;
|
||||
|
||||
/**
|
||||
* {@link InsetsState.InternalInsetsType}s to be applied to the window
|
||||
* If {@link #type} has the predefined insets (like {@link #TYPE_STATUS_BAR} or
|
||||
* {@link #TYPE_NAVIGATION_BAR}), this field will be ignored.
|
||||
*
|
||||
* <p>Note: provide only one inset corresponding to the window type (like
|
||||
* {@link InsetsState.InternalInsetsType#ITYPE_STATUS_BAR} or
|
||||
* {@link InsetsState.InternalInsetsType#ITYPE_NAVIGATION_BAR})</p>
|
||||
* @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.
|
||||
* If set, the specified insets types will be provided by the window and the insets frame
|
||||
* will be calculated based on the provider's parameters. The insets types and the array
|
||||
* 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
|
||||
* the providedInsets array should be the same in all rotations, including the base one.
|
||||
* All other params can be adjusted at runtime.
|
||||
* See {@link InsetsFrameProvider}.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public Insets[] providedInternalInsets;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
public InsetsFrameProvider[] providedInsets;
|
||||
|
||||
/**
|
||||
* 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(preferMinimalPostProcessing);
|
||||
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);
|
||||
if (paramsForRotation != null) {
|
||||
checkNonRecursiveParams();
|
||||
out.writeInt(paramsForRotation.length);
|
||||
out.writeTypedArray(paramsForRotation, 0 /* parcelableFlags */);
|
||||
} else {
|
||||
out.writeInt(0);
|
||||
}
|
||||
out.writeTypedArray(providedInsets, 0 /* parcelableFlags */);
|
||||
checkNonRecursiveParams();
|
||||
out.writeTypedArray(paramsForRotation, 0 /* parcelableFlags */);
|
||||
}
|
||||
|
||||
public static final @android.annotation.NonNull Parcelable.Creator<LayoutParams> CREATOR
|
||||
@@ -4102,27 +4062,9 @@ public interface WindowManager extends ViewManager {
|
||||
mFitInsetsIgnoringVisibility = in.readBoolean();
|
||||
preferMinimalPostProcessing = in.readBoolean();
|
||||
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();
|
||||
int paramsForRotationLength = in.readInt();
|
||||
if (paramsForRotationLength > 0) {
|
||||
paramsForRotation = new LayoutParams[paramsForRotationLength];
|
||||
in.readTypedArray(paramsForRotation, LayoutParams.CREATOR);
|
||||
}
|
||||
providedInsets = in.createTypedArray(InsetsFrameProvider.CREATOR);
|
||||
paramsForRotation = in.createTypedArray(LayoutParams.CREATOR);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"PointlessBitwiseExpression"})
|
||||
@@ -4414,18 +4356,8 @@ public interface WindowManager extends ViewManager {
|
||||
changes |= LAYOUT_CHANGED;
|
||||
}
|
||||
|
||||
if (!Arrays.equals(providesInsetsTypes, o.providesInsetsTypes)) {
|
||||
providesInsetsTypes = o.providesInsetsTypes;
|
||||
changes |= LAYOUT_CHANGED;
|
||||
}
|
||||
|
||||
if (!Arrays.equals(providedInternalInsets, o.providedInternalInsets)) {
|
||||
providedInternalInsets = o.providedInternalInsets;
|
||||
changes |= LAYOUT_CHANGED;
|
||||
}
|
||||
|
||||
if (!Arrays.equals(providedInternalImeInsets, o.providedInternalImeInsets)) {
|
||||
providedInternalImeInsets = o.providedInternalImeInsets;
|
||||
if (!Arrays.equals(providedInsets, o.providedInsets)) {
|
||||
providedInsets = o.providedInsets;
|
||||
changes |= LAYOUT_CHANGED;
|
||||
}
|
||||
|
||||
@@ -4627,28 +4559,12 @@ public interface WindowManager extends ViewManager {
|
||||
sb.append(System.lineSeparator());
|
||||
sb.append(prefix).append(" fitIgnoreVis");
|
||||
}
|
||||
if (providesInsetsTypes != null) {
|
||||
if (providedInsets != null) {
|
||||
sb.append(System.lineSeparator());
|
||||
sb.append(prefix).append(" insetsTypes=");
|
||||
for (int i = 0; i < providesInsetsTypes.length; ++i) {
|
||||
sb.append(" providedInsets=");
|
||||
for (int i = 0; i < providedInsets.length; ++i) {
|
||||
if (i > 0) sb.append(' ');
|
||||
sb.append(InsetsState.typeToString(providesInsetsTypes[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]));
|
||||
sb.append((providedInsets[i]));
|
||||
}
|
||||
}
|
||||
if (insetsRoundedCornerFrame) {
|
||||
|
||||
@@ -28,6 +28,7 @@ import android.os.Handler;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
import android.view.InsetsController;
|
||||
import android.view.InsetsFrameProvider;
|
||||
import android.view.InsetsState;
|
||||
import android.view.SurfaceControl;
|
||||
import android.view.WindowManager;
|
||||
@@ -105,7 +106,11 @@ public class WindowManagerWrapper {
|
||||
*/
|
||||
public void setProvidesInsetsTypes(WindowManager.LayoutParams params,
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -80,7 +80,7 @@ import android.util.Log;
|
||||
import android.view.Display;
|
||||
import android.view.Gravity;
|
||||
import android.view.HapticFeedbackConstants;
|
||||
import android.view.InsetsState;
|
||||
import android.view.InsetsFrameProvider;
|
||||
import android.view.InsetsState.InternalInsetsType;
|
||||
import android.view.InsetsVisibilities;
|
||||
import android.view.KeyEvent;
|
||||
@@ -1631,12 +1631,14 @@ public class NavigationBar extends ViewController<NavigationBarView> implements
|
||||
| WindowManager.LayoutParams.FLAG_SLIPPERY,
|
||||
PixelFormat.TRANSLUCENT);
|
||||
lp.gravity = gravity;
|
||||
lp.providedInternalInsets = new Insets[InsetsState.SIZE];
|
||||
if (insetsHeight != -1) {
|
||||
lp.providedInternalInsets[ITYPE_NAVIGATION_BAR] =
|
||||
Insets.of(0, height - insetsHeight, 0, 0);
|
||||
lp.providedInsets = new InsetsFrameProvider[] {
|
||||
new InsetsFrameProvider(ITYPE_NAVIGATION_BAR, Insets.of(0, 0, 0, insetsHeight))
|
||||
};
|
||||
} else {
|
||||
lp.providedInternalInsets[ITYPE_NAVIGATION_BAR] = null;
|
||||
lp.providedInsets = new InsetsFrameProvider[] {
|
||||
new InsetsFrameProvider(ITYPE_NAVIGATION_BAR)
|
||||
};
|
||||
}
|
||||
lp.token = new Binder();
|
||||
lp.accessibilityTitle = userContext.getString(R.string.nav_bar);
|
||||
|
||||
@@ -120,6 +120,7 @@ import android.view.DisplayCutout;
|
||||
import android.view.DisplayInfo;
|
||||
import android.view.Gravity;
|
||||
import android.view.InsetsFlags;
|
||||
import android.view.InsetsFrameProvider;
|
||||
import android.view.InsetsSource;
|
||||
import android.view.InsetsState;
|
||||
import android.view.InsetsState.InternalInsetsType;
|
||||
@@ -1079,17 +1080,18 @@ public class DisplayPolicy {
|
||||
return WindowManagerGlobal.ADD_INVALID_TYPE;
|
||||
}
|
||||
|
||||
if (attrs.providesInsetsTypes != null) {
|
||||
if (attrs.providedInsets != null) {
|
||||
// Recents component is allowed to add inset types.
|
||||
if (!mService.mAtmService.isCallerRecents(callingUid)) {
|
||||
mContext.enforcePermission(
|
||||
android.Manifest.permission.STATUS_BAR_SERVICE, callingPid, callingUid,
|
||||
"DisplayPolicy");
|
||||
}
|
||||
enforceSingleInsetsTypeCorrespondingToWindowType(attrs.providesInsetsTypes);
|
||||
enforceSingleInsetsTypeCorrespondingToWindowType(attrs.providedInsets);
|
||||
|
||||
for (@InternalInsetsType int insetType : attrs.providesInsetsTypes) {
|
||||
switch (insetType) {
|
||||
for (InsetsFrameProvider provider : attrs.providedInsets) {
|
||||
@InternalInsetsType int insetsType = provider.type;
|
||||
switch (insetsType) {
|
||||
case ITYPE_STATUS_BAR:
|
||||
if ((mStatusBar != null && mStatusBar.isAlive())
|
||||
|| (mStatusBarAlt != null && mStatusBarAlt.isAlive())) {
|
||||
@@ -1155,12 +1157,19 @@ public class DisplayPolicy {
|
||||
mDisplayContent.setInsetProvider(ITYPE_NAVIGATION_BAR, win,
|
||||
(displayFrames, windowContainer, inOutFrame) -> {
|
||||
if (!mNavButtonForcedVisible) {
|
||||
final Insets[] providedInternalInsets = win.getLayoutingAttrs(
|
||||
displayFrames.mRotation).providedInternalInsets;
|
||||
if (providedInternalInsets != null
|
||||
&& providedInternalInsets.length > ITYPE_NAVIGATION_BAR
|
||||
&& providedInternalInsets[ITYPE_NAVIGATION_BAR] != null) {
|
||||
inOutFrame.inset(providedInternalInsets[ITYPE_NAVIGATION_BAR]);
|
||||
final LayoutParams lp =
|
||||
win.getLayoutingAttrs(displayFrames.mRotation);
|
||||
if (lp.providedInsets != null) {
|
||||
for (InsetsFrameProvider provider :
|
||||
win.getLayoutingAttrs(displayFrames.mRotation)
|
||||
.providedInsets) {
|
||||
if (provider.type != ITYPE_NAVIGATION_BAR) {
|
||||
continue;
|
||||
}
|
||||
calculateInsetsFrame(displayFrames, win, inOutFrame,
|
||||
provider.source, provider.insetsSize
|
||||
);
|
||||
}
|
||||
}
|
||||
inOutFrame.inset(win.mGivenContentInsets);
|
||||
}
|
||||
@@ -1204,21 +1213,9 @@ public class DisplayPolicy {
|
||||
if (DEBUG_LAYOUT) Slog.i(TAG, "NAVIGATION BAR: " + mNavigationBar);
|
||||
break;
|
||||
default:
|
||||
if (attrs.providesInsetsTypes != null) {
|
||||
for (@InternalInsetsType int insetsType : attrs.providesInsetsTypes) {
|
||||
final TriConsumer<DisplayFrames, WindowContainer, Rect> imeFrameProvider =
|
||||
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) {
|
||||
if (attrs.providedInsets != null) {
|
||||
for (InsetsFrameProvider provider : attrs.providedInsets) {
|
||||
switch (provider.type) {
|
||||
case ITYPE_STATUS_BAR:
|
||||
mStatusBarAlt = win;
|
||||
mStatusBarAltPosition = getAltBarPosition(attrs);
|
||||
@@ -1236,41 +1233,24 @@ public class DisplayPolicy {
|
||||
mExtraNavBarAltPosition = getAltBarPosition(attrs);
|
||||
break;
|
||||
}
|
||||
mDisplayContent.setInsetProvider(insetsType, win,
|
||||
win.getAttrs().providedInternalInsets != null ? (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);
|
||||
} : null, imeFrameProvider);
|
||||
if (mNavigationBar == null && (insetsType == ITYPE_NAVIGATION_BAR
|
||||
|| insetsType == ITYPE_EXTRA_NAVIGATION_BAR)) {
|
||||
mDisplayContent.setInsetProvider(ITYPE_LEFT_GESTURES, win,
|
||||
(displayFrames, windowState, inOutFrame) -> {
|
||||
final int leftSafeInset =
|
||||
Math.max(displayFrames.mDisplayCutoutSafe.left,0);
|
||||
inOutFrame.left = 0;
|
||||
inOutFrame.top = 0;
|
||||
inOutFrame.bottom = displayFrames.mDisplayHeight;
|
||||
inOutFrame.right =
|
||||
leftSafeInset + mLeftGestureInset;
|
||||
});
|
||||
mDisplayContent.setInsetProvider(ITYPE_RIGHT_GESTURES, win,
|
||||
(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;
|
||||
});
|
||||
}
|
||||
final TriConsumer<DisplayFrames, WindowContainer, Rect> frameProvider =
|
||||
provider.insetsSize != null
|
||||
? (displayFrames, windowContainer, inOutFrame) -> {
|
||||
inOutFrame.inset(win.mGivenContentInsets);
|
||||
calculateInsetsFrame(displayFrames, windowContainer,
|
||||
inOutFrame, provider.source,
|
||||
provider.insetsSize);
|
||||
} : null;
|
||||
final TriConsumer<DisplayFrames, WindowContainer, Rect> imeFrameProvider =
|
||||
provider.imeInsetsSize != null
|
||||
? (displayFrames, windowContainer, inOutFrame) -> {
|
||||
inOutFrame.inset(win.mGivenContentInsets);
|
||||
calculateInsetsFrame(displayFrames, windowContainer,
|
||||
inOutFrame, provider.source,
|
||||
provider.imeInsetsSize);
|
||||
} : null;
|
||||
mDisplayContent.setInsetProvider(provider.type, win, frameProvider,
|
||||
imeFrameProvider);
|
||||
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
|
||||
private int getAltBarPosition(WindowManager.LayoutParams params) {
|
||||
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;
|
||||
for (int insetsType : insetsTypes) {
|
||||
switch (insetsType) {
|
||||
for (InsetsFrameProvider provider : providers) {
|
||||
switch (provider.type) {
|
||||
case ITYPE_NAVIGATION_BAR:
|
||||
case ITYPE_STATUS_BAR:
|
||||
case ITYPE_CLIMATE_BAR:
|
||||
@@ -1978,25 +1982,20 @@ public class DisplayPolicy {
|
||||
&& lp.paramsForRotation[rotation] != null) {
|
||||
lp = lp.paramsForRotation[rotation];
|
||||
}
|
||||
final Insets providedInternalInsets;
|
||||
if (lp.providedInternalInsets != null
|
||||
&& lp.providedInternalInsets.length > ITYPE_NAVIGATION_BAR
|
||||
&& lp.providedInternalInsets[ITYPE_NAVIGATION_BAR] != null) {
|
||||
providedInternalInsets = lp.providedInternalInsets[ITYPE_NAVIGATION_BAR];
|
||||
} else {
|
||||
providedInternalInsets = Insets.NONE;
|
||||
}
|
||||
if (position == NAV_BAR_LEFT) {
|
||||
if (lp.width > providedInternalInsets.right) {
|
||||
return lp.width - providedInternalInsets.right;
|
||||
} else {
|
||||
return 0;
|
||||
Insets providedInsetsSize = null;
|
||||
if (lp.providedInsets != null) {
|
||||
for (InsetsFrameProvider provider : lp.providedInsets) {
|
||||
if (provider.type != ITYPE_NAVIGATION_BAR) {
|
||||
continue;
|
||||
}
|
||||
providedInsetsSize = provider.insetsSize;
|
||||
}
|
||||
} else if (position == NAV_BAR_RIGHT) {
|
||||
if (lp.width > providedInternalInsets.left) {
|
||||
return lp.width - providedInternalInsets.left;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
if (providedInsetsSize != null) {
|
||||
if (position == NAV_BAR_LEFT) {
|
||||
return providedInsetsSize.left;
|
||||
} else if (position == NAV_BAR_RIGHT) {
|
||||
return providedInsetsSize.right;
|
||||
}
|
||||
}
|
||||
return lp.width;
|
||||
@@ -2043,18 +2042,20 @@ public class DisplayPolicy {
|
||||
return 0;
|
||||
}
|
||||
LayoutParams lp = mNavigationBar.getLayoutingAttrs(rotation);
|
||||
final Insets providedInternalInsets;
|
||||
if (lp.providedInternalInsets != null
|
||||
&& lp.providedInternalInsets.length > ITYPE_NAVIGATION_BAR
|
||||
&& lp.providedInternalInsets[ITYPE_NAVIGATION_BAR] != null) {
|
||||
providedInternalInsets = lp.providedInternalInsets[ITYPE_NAVIGATION_BAR];
|
||||
} else {
|
||||
providedInternalInsets = Insets.NONE;
|
||||
Insets providedInsetsSize = null;
|
||||
if (lp.providedInsets != null) {
|
||||
for (InsetsFrameProvider provider : lp.providedInsets) {
|
||||
if (provider.type != ITYPE_NAVIGATION_BAR) {
|
||||
continue;
|
||||
}
|
||||
providedInsetsSize = provider.insetsSize;
|
||||
if (providedInsetsSize != null) {
|
||||
return providedInsetsSize.bottom;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (lp.height < providedInternalInsets.top) {
|
||||
return 0;
|
||||
}
|
||||
return lp.height - providedInternalInsets.top;
|
||||
return lp.height;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -55,6 +55,7 @@ import android.view.InsetsAnimationControlCallbacks;
|
||||
import android.view.InsetsAnimationControlImpl;
|
||||
import android.view.InsetsAnimationControlRunner;
|
||||
import android.view.InsetsController;
|
||||
import android.view.InsetsFrameProvider;
|
||||
import android.view.InsetsSource;
|
||||
import android.view.InsetsSourceControl;
|
||||
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 (attrs.providesInsetsTypes != null) {
|
||||
for (@InternalInsetsType int insetsType : attrs.providesInsetsTypes) {
|
||||
switch (insetsType) {
|
||||
if (attrs.providedInsets != null) {
|
||||
for (InsetsFrameProvider provider : attrs.providedInsets) {
|
||||
switch (provider.type) {
|
||||
case ITYPE_STATUS_BAR:
|
||||
case ITYPE_NAVIGATION_BAR:
|
||||
case ITYPE_CLIMATE_BAR:
|
||||
case ITYPE_EXTRA_NAVIGATION_BAR:
|
||||
return insetsType;
|
||||
return provider.type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ import android.graphics.Insets;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
import android.util.proto.ProtoOutputStream;
|
||||
import android.view.InsetsFrameProvider;
|
||||
import android.view.InsetsSource;
|
||||
import android.view.InsetsSourceControl;
|
||||
import android.view.InsetsState;
|
||||
@@ -513,12 +514,13 @@ abstract class InsetsSourceProvider {
|
||||
if (mWindowContainer.asWindowState() == null) {
|
||||
return false;
|
||||
}
|
||||
final int[] provides = ((WindowState) mWindowContainer).mAttrs.providesInsetsTypes;
|
||||
if (provides == null) {
|
||||
final InsetsFrameProvider[] providers =
|
||||
((WindowState) mWindowContainer).mAttrs.providedInsets;
|
||||
if (providers == null) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < provides.length; i++) {
|
||||
if (provides[i] == ITYPE_IME) {
|
||||
for (int i = 0; i < providers.length; i++) {
|
||||
if (providers[i].type == ITYPE_IME) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2254,9 +2254,21 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
throw new IllegalArgumentException(
|
||||
"Window type can not be changed after the window is added.");
|
||||
}
|
||||
if (!Arrays.equals(win.mAttrs.providesInsetsTypes, attrs.providesInsetsTypes)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Insets types can not be changed after the window is added.");
|
||||
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(
|
||||
"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;
|
||||
|
||||
@@ -43,6 +43,7 @@ import android.graphics.Rect;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
import android.util.Pair;
|
||||
import android.view.DisplayInfo;
|
||||
import android.view.InsetsFrameProvider;
|
||||
import android.view.InsetsState;
|
||||
import android.view.PrivacyIndicatorBounds;
|
||||
import android.view.RoundedCorners;
|
||||
@@ -153,7 +154,10 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
|
||||
mDisplayPolicy.removeWindowLw(mStatusBarWindow); // Removes the existing one.
|
||||
|
||||
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);
|
||||
|
||||
addWindow(win);
|
||||
@@ -182,7 +186,9 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
|
||||
public void addingWindow_InWindowTypeWithPredefinedInsets() {
|
||||
mDisplayPolicy.removeWindowLw(mStatusBarWindow); // Removes the existing one.
|
||||
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);
|
||||
|
||||
addWindow(win);
|
||||
@@ -199,12 +205,19 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
|
||||
@Test
|
||||
public void addingWindow_throwsException_WithMultipleInsetTypes() {
|
||||
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));
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user