summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/InsetsFrameProvider.java139
-rw-r--r--core/java/android/view/WindowLayout.java4
-rw-r--r--core/proto/android/server/windowmanagerservice.proto2
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java17
-rw-r--r--services/core/java/com/android/server/wm/DisplayPolicy.java116
-rw-r--r--services/core/java/com/android/server/wm/InsetsPolicy.java32
-rw-r--r--services/core/java/com/android/server/wm/InsetsSourceProvider.java64
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java11
9 files changed, 247 insertions, 140 deletions
diff --git a/core/java/android/view/InsetsFrameProvider.java b/core/java/android/view/InsetsFrameProvider.java
index 9e66f54321cc..eb8687c47bed 100644
--- a/core/java/android/view/InsetsFrameProvider.java
+++ b/core/java/android/view/InsetsFrameProvider.java
@@ -16,10 +16,14 @@
package android.view;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT;
+
import android.graphics.Insets;
+import android.graphics.Rect;
import android.os.Parcel;
import android.os.Parcelable;
+import java.util.Arrays;
import java.util.Objects;
/**
@@ -52,7 +56,9 @@ public class InsetsFrameProvider implements Parcelable {
public static final int SOURCE_FRAME = 2;
private static final int HAS_INSETS_SIZE = 1;
- private static final int HAS_IME_INSETS_SIZE = 2;
+ private static final int HAS_INSETS_SIZE_OVERRIDE = 2;
+
+ private static Rect sTmpRect = new Rect();
/**
* The type of insets to provide.
@@ -77,29 +83,25 @@ public class InsetsFrameProvider implements Parcelable {
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.
+ * If null, the size set in insetsSize will be applied to all window types. If it contains
+ * element of some types, the insets reported to the window with that types will be overridden.
*/
- public Insets imeInsetsSize = null;
+ public InsetsSizeOverride[] insetsSizeOverrides = 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);
+ this(type, SOURCE_FRAME, insetsSize, null);
}
public InsetsFrameProvider(int type, int source, Insets insetsSize,
- Insets imeInsetsSize) {
+ InsetsSizeOverride[] insetsSizeOverride) {
this.type = type;
this.source = source;
this.insetsSize = insetsSize;
- this.imeInsetsSize = imeInsetsSize;
+ this.insetsSizeOverrides = insetsSizeOverride;
}
@Override
@@ -127,8 +129,8 @@ public class InsetsFrameProvider implements Parcelable {
if (insetsSize != null) {
sb.append(", insetsSize=").append(insetsSize);
}
- if (imeInsetsSize != null) {
- sb.append(", imeInsetsSize=").append(imeInsetsSize);
+ if (insetsSizeOverrides != null) {
+ sb.append(", insetsSizeOverrides=").append(Arrays.toString(insetsSizeOverrides));
}
sb.append("}");
return sb.toString();
@@ -141,8 +143,8 @@ public class InsetsFrameProvider implements Parcelable {
if ((insetsSizeModified & HAS_INSETS_SIZE) != 0) {
insetsSize = Insets.CREATOR.createFromParcel(in);
}
- if ((insetsSizeModified & HAS_IME_INSETS_SIZE) != 0) {
- imeInsetsSize = Insets.CREATOR.createFromParcel(in);
+ if ((insetsSizeModified & HAS_INSETS_SIZE_OVERRIDE) != 0) {
+ insetsSizeOverrides = in.createTypedArray(InsetsSizeOverride.CREATOR);
}
}
@@ -152,8 +154,8 @@ public class InsetsFrameProvider implements Parcelable {
if (insetsSize != null) {
insetsSizeModified |= HAS_INSETS_SIZE;
}
- if (imeInsetsSize != null) {
- insetsSizeModified |= HAS_IME_INSETS_SIZE;
+ if (insetsSizeOverrides != null) {
+ insetsSizeModified |= HAS_INSETS_SIZE_OVERRIDE;
}
out.writeInt(insetsSizeModified);
out.writeInt(type);
@@ -161,8 +163,8 @@ public class InsetsFrameProvider implements Parcelable {
if (insetsSize != null) {
insetsSize.writeToParcel(out, flags);
}
- if (imeInsetsSize != null) {
- imeInsetsSize.writeToParcel(out, flags);
+ if (insetsSizeOverrides != null) {
+ out.writeTypedArray(insetsSizeOverrides, flags);
}
}
@@ -177,16 +179,12 @@ public class InsetsFrameProvider implements Parcelable {
InsetsFrameProvider other = (InsetsFrameProvider) o;
return type == other.type && source == other.source
&& Objects.equals(insetsSize, other.insetsSize)
- && Objects.equals(imeInsetsSize, other.imeInsetsSize);
+ && Arrays.equals(insetsSizeOverrides, other.insetsSizeOverrides);
}
@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;
+ return Objects.hash(type, source, insetsSize, Arrays.hashCode(insetsSizeOverrides));
}
public static final @android.annotation.NonNull Parcelable.Creator<InsetsFrameProvider>
@@ -201,5 +199,96 @@ public class InsetsFrameProvider implements Parcelable {
return new InsetsFrameProvider[size];
}
};
+
+ public static void calculateInsetsFrame(Rect displayFrame, Rect containerBounds,
+ Rect displayCutoutSafe, Rect inOutFrame, int source, Insets insetsSize,
+ @WindowManager.LayoutParams.PrivateFlags int privateFlags) {
+ boolean extendByCutout = false;
+ if (source == InsetsFrameProvider.SOURCE_DISPLAY) {
+ inOutFrame.set(displayFrame);
+ } else if (source == InsetsFrameProvider.SOURCE_CONTAINER_BOUNDS) {
+ inOutFrame.set(containerBounds);
+ } else {
+ extendByCutout = (privateFlags & PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT) != 0;
+ }
+ if (insetsSize == null) {
+ 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;
+ } else {
+ inOutFrame.setEmpty();
+ }
+
+ if (extendByCutout) {
+ WindowLayout.extendFrameByCutout(displayCutoutSafe, displayFrame, inOutFrame, sTmpRect);
+ }
+ }
+
+ /**
+ * 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.
+ */
+ public static class InsetsSizeOverride implements Parcelable {
+ public final int windowType;
+ public Insets insetsSize;
+
+ protected InsetsSizeOverride(Parcel in) {
+ windowType = in.readInt();
+ insetsSize = in.readParcelable(null, android.graphics.Insets.class);
+ }
+
+ public InsetsSizeOverride(int type, Insets size) {
+ windowType = type;
+ insetsSize = size;
+ }
+
+ public static final Creator<InsetsSizeOverride> CREATOR =
+ new Creator<InsetsSizeOverride>() {
+ @Override
+ public InsetsSizeOverride createFromParcel(Parcel in) {
+ return new InsetsSizeOverride(in);
+ }
+
+ @Override
+ public InsetsSizeOverride[] newArray(int size) {
+ return new InsetsSizeOverride[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeInt(windowType);
+ out.writeParcelable(insetsSize, flags);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder(32);
+ sb.append("TypedInsetsSize: {");
+ sb.append("windowType=").append(windowType);
+ sb.append(", insetsSize=").append(insetsSize);
+ sb.append("}");
+ return sb.toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(windowType, insetsSize);
+ }
+ }
}
diff --git a/core/java/android/view/WindowLayout.java b/core/java/android/view/WindowLayout.java
index 0941ee8a714f..57a0330e3c18 100644
--- a/core/java/android/view/WindowLayout.java
+++ b/core/java/android/view/WindowLayout.java
@@ -274,7 +274,7 @@ public class WindowLayout {
}
if (extendedByCutout) {
- extendFrameByCutout(attrs.gravity, displayCutoutSafe, outDisplayFrame, outFrame,
+ extendFrameByCutout(displayCutoutSafe, outDisplayFrame, outFrame,
mTempRect);
}
@@ -291,7 +291,7 @@ public class WindowLayout {
+ " requestedVisibilities=" + requestedVisibilities);
}
- public static void extendFrameByCutout(int gravity, Rect displayCutoutSafe,
+ public static void extendFrameByCutout(Rect displayCutoutSafe,
Rect displayFrame, Rect inOutFrame, Rect tempRect) {
if (displayCutoutSafe.contains(inOutFrame)) {
return;
diff --git a/core/proto/android/server/windowmanagerservice.proto b/core/proto/android/server/windowmanagerservice.proto
index 92ac389ece67..505ef30949ce 100644
--- a/core/proto/android/server/windowmanagerservice.proto
+++ b/core/proto/android/server/windowmanagerservice.proto
@@ -578,7 +578,7 @@ message InsetsSourceProviderProto {
optional WindowStateProto pending_control_target = 6;
optional WindowStateProto fake_control_target = 7;
optional .android.view.SurfaceControlProto captured_leash = 8;
- optional .android.graphics.RectProto ime_overridden_frame = 9;
+ optional .android.graphics.RectProto ime_overridden_frame = 9 [deprecated=true];
optional bool is_leash_ready_for_dispatching = 10;
optional bool client_visible = 11;
optional bool server_visible = 12;
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 288777bdb324..124b8a654a78 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -1362,7 +1362,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
void setInsetProvider(@InternalInsetsType int type, WindowContainer win,
@Nullable TriConsumer<DisplayFrames, WindowContainer, Rect> frameProvider) {
- setInsetProvider(type, win, frameProvider, null /* imeFrameProvider */);
+ setInsetProvider(type, win, frameProvider, null /* overrideFrameProviders */);
}
/**
@@ -1371,15 +1371,18 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
* @param type The type of inset this window provides.
* @param win The window.
* @param frameProvider Function to compute the frame, or {@code null} if the just the frame of
- * the window should be taken.
- * @param imeFrameProvider Function to compute the frame when dispatching insets to the IME, or
- * {@code null} if the normal frame should be taken.
+ * the window should be taken. Only for non-WindowState providers, nav bar
+ * and status bar.
+ * @param overrideFrameProviders Functions to compute the frame when dispatching insets to the
+ * given window types, or {@code null} if the normal frame should
+ * be taken.
*/
void setInsetProvider(@InternalInsetsType int type, WindowContainer win,
@Nullable TriConsumer<DisplayFrames, WindowContainer, Rect> frameProvider,
- @Nullable TriConsumer<DisplayFrames, WindowContainer, Rect> imeFrameProvider) {
+ @Nullable SparseArray<TriConsumer<DisplayFrames, WindowContainer, Rect>>
+ overrideFrameProviders) {
mInsetsStateController.getSourceProvider(type).setWindowContainer(win, frameProvider,
- imeFrameProvider);
+ overrideFrameProviders);
}
InsetsStateController getInsetsStateController() {
@@ -3865,7 +3868,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
mAtmService.onImeWindowSetOnDisplayArea(imePid, mImeWindowsContainer);
}
mInsetsStateController.getSourceProvider(ITYPE_IME).setWindowContainer(win,
- mDisplayPolicy.getImeSourceFrameProvider(), null /* imeFrameProvider */);
+ mDisplayPolicy.getImeSourceFrameProvider(), null);
computeImeTarget(true /* updateImeTarget */);
updateImeControlTarget();
}
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 95f76180c600..98a51a97110d 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -46,9 +46,9 @@ import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INTERCEPT_GLOBAL_DRAG_AND_DROP;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
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;
@@ -1156,7 +1156,7 @@ public class DisplayPolicy {
break;
case TYPE_NAVIGATION_BAR:
mNavigationBar = win;
- mDisplayContent.setInsetProvider(ITYPE_NAVIGATION_BAR, win,
+ final TriConsumer<DisplayFrames, WindowContainer, Rect> navFrameProvider =
(displayFrames, windowContainer, inOutFrame) -> {
if (!mNavButtonForcedVisible) {
final LayoutParams lp =
@@ -1166,19 +1166,22 @@ public class DisplayPolicy {
if (provider.type != ITYPE_NAVIGATION_BAR) {
continue;
}
- calculateInsetsFrame(displayFrames, win, inOutFrame,
- provider.source, provider.insetsSize,
- lp.privateFlags, lp.gravity
- );
+ InsetsFrameProvider.calculateInsetsFrame(
+ displayFrames.mUnrestricted,
+ win.getBounds(), displayFrames.mDisplayCutoutSafe,
+ inOutFrame, provider.source,
+ provider.insetsSize, lp.privateFlags);
}
}
inOutFrame.inset(win.mGivenContentInsets);
}
- },
-
- (displayFrames, windowContainer, inOutFrame) -> {
- // For IME, we don't modify the frame.
- });
+ };
+ 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) -> {
@@ -1246,25 +1249,48 @@ public class DisplayPolicy {
final LayoutParams lp =
win.mAttrs.forRotation(displayFrames.mRotation);
final InsetsFrameProvider ifp =
- lp.providedInsets[index];
- calculateInsetsFrame(displayFrames, windowContainer,
- inOutFrame, ifp.source, ifp.insetsSize,
- lp.privateFlags, lp.gravity);
- } : null;
- final TriConsumer<DisplayFrames, WindowContainer, Rect> imeFrameProvider =
- provider.imeInsetsSize != null
- ? (displayFrames, windowContainer, inOutFrame) -> {
- inOutFrame.inset(win.mGivenContentInsets);
- final LayoutParams lp =
- win.mAttrs.forRotation(displayFrames.mRotation);
- final InsetsFrameProvider ifp =
- lp.providedInsets[index];
- calculateInsetsFrame(displayFrames, windowContainer,
- inOutFrame, ifp.source, ifp.imeInsetsSize,
- lp.privateFlags, lp.gravity);
+ win.mAttrs.forRotation(displayFrames.mRotation)
+ .providedInsets[index];
+ InsetsFrameProvider.calculateInsetsFrame(
+ displayFrames.mUnrestricted,
+ windowContainer.getBounds(),
+ displayFrames.mDisplayCutoutSafe,
+ inOutFrame, ifp.source,
+ ifp.insetsSize, lp.privateFlags);
} : null;
+ final InsetsFrameProvider.InsetsSizeOverride[] overrides =
+ provider.insetsSizeOverrides;
+ final SparseArray<TriConsumer<DisplayFrames, WindowContainer, Rect>>
+ overrideProviders;
+ 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);
+ };
+ overrideProviders.put(overrides[j].windowType,
+ overrideFrameProvider);
+ }
+ } else {
+ overrideProviders = null;
+ }
mDisplayContent.setInsetProvider(provider.type, win, frameProvider,
- imeFrameProvider);
+ overrideProviders);
mInsetsSourceWindowsExceptIme.add(win);
}
}
@@ -1272,40 +1298,6 @@ public class DisplayPolicy {
}
}
- private void calculateInsetsFrame(DisplayFrames df, WindowContainer container, Rect inOutFrame,
- int source, Insets insetsSize, @LayoutParams.PrivateFlags int privateFlags,
- int windowGravity) {
- boolean extendByCutout = false;
- if (source == InsetsFrameProvider.SOURCE_DISPLAY) {
- inOutFrame.set(df.mUnrestricted);
- } else if (source == InsetsFrameProvider.SOURCE_CONTAINER_BOUNDS) {
- inOutFrame.set(container.getBounds());
- } else {
- extendByCutout = (privateFlags & PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT) != 0;
- }
- if (insetsSize == null) {
- 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;
- } else {
- inOutFrame.setEmpty();
- }
-
- if (extendByCutout) {
- WindowLayout.extendFrameByCutout(windowGravity, df.mDisplayCutoutSafe,
- df.mUnrestricted, inOutFrame, sTmpRect);
- }
- }
-
@WindowManagerPolicy.AltBarPosition
private int getAltBarPosition(WindowManager.LayoutParams params) {
switch (params.gravity) {
diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java
index ee1ff2cd61ff..620a56d18dcd 100644
--- a/services/core/java/com/android/server/wm/InsetsPolicy.java
+++ b/services/core/java/com/android/server/wm/InsetsPolicy.java
@@ -289,7 +289,7 @@ class InsetsPolicy {
// contains all insets types.
final InsetsState originalState = mDisplayContent.getInsetsPolicy()
.enforceInsetsPolicyForTarget(type, WINDOWING_MODE_FULLSCREEN, alwaysOnTop,
- mStateController.getRawInsetsState());
+ attrs.type, mStateController.getRawInsetsState());
InsetsState state = adjustVisibilityForTransientTypes(originalState);
return adjustInsetsForRoundedCorners(token, state, state == originalState);
}
@@ -351,12 +351,13 @@ class InsetsPolicy {
* @param type the inset type provided by the target
* @param windowingMode the windowing mode of the target
* @param isAlwaysOnTop is the target always on top
+ * @param windowType the type of the target
* @param state the input inset state containing all the sources
* @return The state stripped of the necessary information.
*/
InsetsState enforceInsetsPolicyForTarget(@InternalInsetsType int type,
@WindowConfiguration.WindowingMode int windowingMode, boolean isAlwaysOnTop,
- InsetsState state) {
+ int windowType, InsetsState state) {
boolean stateCopied = false;
if (type != ITYPE_INVALID) {
@@ -377,21 +378,20 @@ class InsetsPolicy {
if (type == ITYPE_STATUS_BAR || type == ITYPE_CLIMATE_BAR) {
state.removeSource(ITYPE_CAPTION_BAR);
}
-
- // IME needs different frames for certain cases (e.g. navigation bar in gesture nav).
- if (type == ITYPE_IME) {
- ArrayMap<Integer, WindowContainerInsetsSourceProvider> providers = mStateController
- .getSourceProviders();
- for (int i = providers.size() - 1; i >= 0; i--) {
- WindowContainerInsetsSourceProvider otherProvider = providers.valueAt(i);
- if (otherProvider.overridesImeFrame()) {
- InsetsSource override =
- new InsetsSource(
- state.getSource(otherProvider.getSource().getType()));
- override.setFrame(otherProvider.getImeOverrideFrame());
- state.addSource(override);
- }
+ }
+ ArrayMap<Integer, WindowContainerInsetsSourceProvider> providers = mStateController
+ .getSourceProviders();
+ for (int i = providers.size() - 1; i >= 0; i--) {
+ WindowContainerInsetsSourceProvider otherProvider = providers.valueAt(i);
+ if (otherProvider.overridesFrame(windowType)) {
+ if (!stateCopied) {
+ state = new InsetsState(state);
+ stateCopied = true;
}
+ InsetsSource override =
+ new InsetsSource(state.getSource(otherProvider.getSource().getType()));
+ override.setFrame(otherProvider.getOverriddenFrame(windowType));
+ state.addSource(override);
}
}
diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index 610bf0594c66..86a73c935e52 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -27,7 +27,6 @@ import static com.android.server.wm.InsetsSourceProviderProto.CONTROL_TARGET;
import static com.android.server.wm.InsetsSourceProviderProto.FAKE_CONTROL;
import static com.android.server.wm.InsetsSourceProviderProto.FAKE_CONTROL_TARGET;
import static com.android.server.wm.InsetsSourceProviderProto.FRAME;
-import static com.android.server.wm.InsetsSourceProviderProto.IME_OVERRIDDEN_FRAME;
import static com.android.server.wm.InsetsSourceProviderProto.IS_LEASH_READY_FOR_DISPATCHING;
import static com.android.server.wm.InsetsSourceProviderProto.PENDING_CONTROL_TARGET;
import static com.android.server.wm.InsetsSourceProviderProto.SEAMLESS_ROTATING;
@@ -41,6 +40,7 @@ import android.annotation.Nullable;
import android.graphics.Insets;
import android.graphics.Point;
import android.graphics.Rect;
+import android.util.SparseArray;
import android.util.proto.ProtoOutputStream;
import android.view.InsetsFrameProvider;
import android.view.InsetsSource;
@@ -78,8 +78,8 @@ abstract class InsetsSourceProvider {
private @Nullable ControlAdapter mAdapter;
private TriConsumer<DisplayFrames, WindowContainer, Rect> mFrameProvider;
- private TriConsumer<DisplayFrames, WindowContainer, Rect> mImeFrameProvider;
- private final Rect mImeOverrideFrame = new Rect();
+ private SparseArray<TriConsumer<DisplayFrames, WindowContainer, Rect>> mOverrideFrameProviders;
+ private final SparseArray<Rect> mOverrideFrames = new SparseArray<Rect>();
private boolean mIsLeashReadyForDispatching;
private final Rect mSourceFrame = new Rect();
private final Rect mLastSourceFrame = new Rect();
@@ -146,12 +146,15 @@ abstract class InsetsSourceProvider {
* @param windowContainer The window container that links to this source.
* @param frameProvider Based on display frame state and the window, calculates the resulting
* frame that should be reported to clients.
- * @param imeFrameProvider Based on display frame state and the window, calculates the resulting
- * frame that should be reported to IME.
+ * This will only be used when the window container providing the insets is
+ * not a WindowState.
+ * @param overrideFrameProviders Based on display frame state and the window, calculates the
+ * resulting frame that should be reported to given window type.
*/
void setWindowContainer(@Nullable WindowContainer windowContainer,
@Nullable TriConsumer<DisplayFrames, WindowContainer, Rect> frameProvider,
- @Nullable TriConsumer<DisplayFrames, WindowContainer, Rect> imeFrameProvider) {
+ @Nullable SparseArray<TriConsumer<DisplayFrames, WindowContainer, Rect>>
+ overrideFrameProviders) {
if (mWindowContainer != null) {
if (mControllable) {
mWindowContainer.setControllableInsetProvider(null);
@@ -167,8 +170,9 @@ abstract class InsetsSourceProvider {
ProtoLog.d(WM_DEBUG_WINDOW_INSETS, "InsetsSource setWin %s for type %s",
windowContainer, InsetsState.typeToString(mSource.getType()));
mWindowContainer = windowContainer;
+ // TODO: remove the frame provider for non-WindowState container.
mFrameProvider = frameProvider;
- mImeFrameProvider = imeFrameProvider;
+ mOverrideFrameProviders = overrideFrameProviders;
if (windowContainer == null) {
setServerVisible(false);
mSource.setVisibleFrame(null);
@@ -228,10 +232,25 @@ abstract class InsetsSourceProvider {
}
updateSourceFrameForServerVisibility();
- if (mImeFrameProvider != null) {
- mImeOverrideFrame.set(frame);
- mImeFrameProvider.accept(mWindowContainer.getDisplayContent().mDisplayFrames,
- mWindowContainer, mImeOverrideFrame);
+ if (mOverrideFrameProviders != null) {
+ for (int i = mOverrideFrameProviders.size() - 1; i >= 0; i--) {
+ final int windowType = mOverrideFrameProviders.keyAt(i);
+ final Rect overrideFrame;
+ if (mOverrideFrames.contains(windowType)) {
+ overrideFrame = mOverrideFrames.get(windowType);
+ overrideFrame.set(frame);
+ } else {
+ overrideFrame = new Rect(frame);
+ }
+ final TriConsumer<DisplayFrames, WindowContainer, Rect> provider =
+ mOverrideFrameProviders.get(windowType);
+ if (provider != null) {
+ mOverrideFrameProviders.get(windowType).accept(
+ mWindowContainer.getDisplayContent().mDisplayFrames, mWindowContainer,
+ overrideFrame);
+ }
+ mOverrideFrames.put(windowType, overrideFrame);
+ }
}
if (win.mGivenVisibleInsets.left != 0 || win.mGivenVisibleInsets.top != 0
@@ -552,32 +571,30 @@ abstract class InsetsSourceProvider {
return mClientVisible;
}
- /**
- * @return Whether this provider uses a different frame to dispatch to the IME.
- */
- boolean overridesImeFrame() {
- return mImeFrameProvider != null;
+ boolean overridesFrame(int windowType) {
+ return mOverrideFrames.contains(windowType);
}
- /**
- * @return Rect to dispatch to the IME as frame. Only valid if {@link #overridesImeFrame()}
- * returns {@code true}.
- */
- Rect getImeOverrideFrame() {
- return mImeOverrideFrame;
+ Rect getOverriddenFrame(int windowType) {
+ return mOverrideFrames.get(windowType);
}
public void dump(PrintWriter pw, String prefix) {
pw.println(prefix + getClass().getSimpleName());
prefix = prefix + " ";
pw.print(prefix + "mSource="); mSource.dump("", pw);
+ pw.print(prefix + "mSourceFrame=");
+ pw.println(mSourceFrame);
+ if (mOverrideFrames.size() > 0) {
+ pw.print(prefix + "mOverrideFrames=");
+ pw.println(mOverrideFrames);
+ }
if (mControl != null) {
pw.print(prefix + "mControl=");
mControl.dump("", pw);
}
pw.print(prefix);
pw.print("mIsLeashReadyForDispatching="); pw.print(mIsLeashReadyForDispatching);
- pw.print(" mImeOverrideFrame="); pw.print(mImeOverrideFrame.toShortString());
pw.println();
if (mWindowContainer != null) {
pw.print(prefix + "mWindowContainer=");
@@ -621,7 +638,6 @@ abstract class InsetsSourceProvider {
if (mAdapter != null && mAdapter.mCapturedLeash != null) {
mAdapter.mCapturedLeash.dumpDebug(proto, CAPTURED_LEASH);
}
- mImeOverrideFrame.dumpDebug(proto, IME_OVERRIDDEN_FRAME);
proto.write(IS_LEASH_READY_FOR_DISPATCHING, mIsLeashReadyForDispatching);
proto.write(CLIENT_VISIBLE, mClientVisible);
proto.write(SERVER_VISIBLE, mServerVisible);
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 46091d842c2a..ba82b4117875 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -1703,7 +1703,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
mFrozenInsetsState != null ? mFrozenInsetsState : getMergedInsetsState();
final InsetsState insetsStateForWindow = insetsPolicy
.enforceInsetsPolicyForTarget(insetTypeProvidedByWindow,
- getWindowingMode(), isAlwaysOnTop(), rawInsetsState);
+ getWindowingMode(), isAlwaysOnTop(), mAttrs.type, rawInsetsState);
return insetsPolicy.adjustInsetsForWindow(this, insetsStateForWindow,
includeTransient);
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
index ffa21fadff6b..6c161cf088f7 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
@@ -27,6 +27,7 @@ import static android.view.InsetsState.ITYPE_STATUS_BAR;
import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
@@ -44,12 +45,15 @@ import static org.mockito.Mockito.verify;
import android.graphics.Rect;
import android.platform.test.annotations.Presubmit;
+import android.util.SparseArray;
import android.view.InsetsSourceControl;
import android.view.InsetsState;
import android.view.InsetsVisibilities;
import androidx.test.filters.SmallTest;
+import com.android.internal.util.function.TriConsumer;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -269,15 +273,18 @@ public class InsetsStateControllerTest extends WindowTestsBase {
@Test
public void testImeForDispatch() {
final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
- final WindowState ime = createWindow(null, TYPE_APPLICATION, "ime");
+ final WindowState ime = createWindow(null, TYPE_INPUT_METHOD, "ime");
// IME cannot be the IME target.
ime.mAttrs.flags |= FLAG_NOT_FOCUSABLE;
WindowContainerInsetsSourceProvider statusBarProvider =
getController().getSourceProvider(ITYPE_STATUS_BAR);
- statusBarProvider.setWindowContainer(statusBar, null, ((displayFrames, windowState, rect) ->
+ final SparseArray<TriConsumer<DisplayFrames, WindowContainer, Rect>> imeOverrideProviders =
+ new SparseArray<>();
+ imeOverrideProviders.put(TYPE_INPUT_METHOD, ((displayFrames, windowState, rect) ->
rect.set(0, 1, 2, 3)));
+ statusBarProvider.setWindowContainer(statusBar, null, imeOverrideProviders);
getController().getSourceProvider(ITYPE_IME).setWindowContainer(ime, null, null);
statusBar.setControllableInsetProvider(statusBarProvider);
statusBar.updateSourceFrame(statusBar.getFrame());