diff --git a/compatLib/build.gradle b/compatLib/build.gradle index 5c3b5a0e13..39e1752ab9 100644 --- a/compatLib/build.gradle +++ b/compatLib/build.gradle @@ -1,5 +1,6 @@ plugins { alias(libs.plugins.android.library) +// alias(libs.plugins.google.protobuf) } android { @@ -13,8 +14,16 @@ android { sourceSets { main { aidl.srcDirs = ['src/main/java'] +// proto { +// srcDirs = ['src/main/java'] +// } } } } -addFrameworkJar('framework-15.jar') +addFrameworkJar('framework-16.jar') +dependencies { + compileOnly files('../prebuilts/libs/framework-16.jar') + compileOnly files('../prebuilts/libs/WindowManager-Shell-16.jar') + compileOnly files('../prebuilts/libs/SystemUI-core-16.jar') +} diff --git a/compatLib/compatLibVQ/src/main/java/app/lawnchair/compatlib/ten/ActivityManagerCompatVQ.java b/compatLib/compatLibVQ/src/main/java/app/lawnchair/compatlib/ten/ActivityManagerCompatVQ.java index 7f799a27b4..b1e4fc5c8a 100644 --- a/compatLib/compatLibVQ/src/main/java/app/lawnchair/compatlib/ten/ActivityManagerCompatVQ.java +++ b/compatLib/compatLibVQ/src/main/java/app/lawnchair/compatlib/ten/ActivityManagerCompatVQ.java @@ -134,7 +134,8 @@ public class ActivityManagerCompatVQ implements ActivityManagerCompat { } } - @Override +// @Override + // pE-TODO(QuickSwitch): Investigate public ThumbnailData takeScreenshot( IRecentsAnimationController animationController, int taskId) { try { diff --git a/compatLib/src/main/java/android/internal/perfetto/protos/insets.proto b/compatLib/src/main/java/android/internal/perfetto/protos/insets.proto new file mode 100644 index 0000000000..4a04c2bcf3 --- /dev/null +++ b/compatLib/src/main/java/android/internal/perfetto/protos/insets.proto @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2025 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. + */ + +syntax = "proto2"; + +option java_package = "android.internal.perfetto.protos"; +option java_outer_classname = "Insets"; + +package perfetto.protos; + +message InsetsProto { + optional int32 left = 1; + optional int32 top = 2; + optional int32 right = 3; + optional int32 bottom = 4; +} diff --git a/compatLib/src/main/java/android/internal/perfetto/protos/insetssource.proto b/compatLib/src/main/java/android/internal/perfetto/protos/insetssource.proto new file mode 100644 index 0000000000..7ef8642625 --- /dev/null +++ b/compatLib/src/main/java/android/internal/perfetto/protos/insetssource.proto @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2024 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. + */ + +syntax = "proto2"; + +option java_package = "android.internal.perfetto.protos"; +option java_outer_classname = "Insetssource"; + +import "main/java/android/internal/perfetto/protos/insets.proto"; +import "main/java/android/internal/perfetto/protos/rect.proto"; + +// Represents a {@link android.view.InsetsSource} object +message InsetsSourceProto { + optional string type = 1 [deprecated = true]; + optional .perfetto.protos.RectProto frame = 2; + optional .perfetto.protos.RectProto visible_frame = 3; + optional bool visible = 4; + optional int32 type_number = 5; + optional .perfetto.protos.InsetsProto attached_insets = 6; +} diff --git a/compatLib/src/main/java/android/internal/perfetto/protos/rect.proto b/compatLib/src/main/java/android/internal/perfetto/protos/rect.proto new file mode 100644 index 0000000000..9f66c04388 --- /dev/null +++ b/compatLib/src/main/java/android/internal/perfetto/protos/rect.proto @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2024 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. + */ + +syntax = "proto2"; + +option java_package = "android.internal.perfetto.protos"; +option java_outer_classname = "Rect"; + +package perfetto.protos; + +message RectProto { + optional int32 left = 1; + optional int32 top = 2; + optional int32 right = 3; + optional int32 bottom = 4; +} diff --git a/compatLib/src/main/java/android/view/ISystemGestureExclusionListener.aidl b/compatLib/src/main/java/android/view/ISystemGestureExclusionListener.aidl index 9c2f9a6a19..729edd91dc 100644 --- a/compatLib/src/main/java/android/view/ISystemGestureExclusionListener.aidl +++ b/compatLib/src/main/java/android/view/ISystemGestureExclusionListener.aidl @@ -38,4 +38,4 @@ oneway interface ISystemGestureExclusionListener { */ void onSystemGestureExclusionChanged(int displayId, in Region systemGestureExclusion, in Region systemGestureExclusionUnrestricted); -} \ No newline at end of file +} diff --git a/compatLib/src/main/java/android/view/InsetsFrameProvider.java b/compatLib/src/main/java/android/view/InsetsFrameProvider.java index 19f016b917..86e9e566b9 100644 --- a/compatLib/src/main/java/android/view/InsetsFrameProvider.java +++ b/compatLib/src/main/java/android/view/InsetsFrameProvider.java @@ -26,50 +26,68 @@ import android.os.Parcel; import android.os.Parcelable; import android.view.InsetsSource.Flags; import android.view.WindowInsets.Type.InsetsType; + import java.util.Arrays; 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 + * 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. * - *
The InsetsFrameProvider should be self-contained. Nothing describing the window itself, such - * as contentInsets, visibleInsets, etc. won't affect the insets providing to other windows when - * this is set. - * + * The InsetsFrameProvider should be self-contained. Nothing describing the window itself, such as + * contentInsets, visibleInsets, etc. won't affect the insets providing to other windows when this + * is set. * @hide */ public class InsetsFrameProvider implements Parcelable { - /** Uses the display frame as the source. */ + /** + * Uses the display frame as the source. + */ public static final int SOURCE_DISPLAY = 0; - /** Uses the window bounds as the source. */ + /** + * Uses the window bounds as the source. + */ public static final int SOURCE_CONTAINER_BOUNDS = 1; - /** Uses the window frame as the source. */ + /** + * Uses the window frame as the source. + */ public static final int SOURCE_FRAME = 2; - /** Uses {@link #mArbitraryRectangle} as the source. */ + /** + * Uses {@link #mArbitraryRectangle} as the source. + */ public static final int SOURCE_ARBITRARY_RECTANGLE = 3; + /** + * Uses the container bounds to which the insets attached as the source. + * Only use this if the insets is a local insets only applied to the children of the container. + */ + public static final int SOURCE_ATTACHED_CONTAINER_BOUNDS = 4; + private final int mId; - /** The selection of the starting rectangle to be converted into source frame. */ + /** + * The selection of the starting rectangle to be converted into source frame. + */ private int mSource = SOURCE_FRAME; - /** This is used as the source frame only if SOURCE_ARBITRARY_RECTANGLE is applied. */ + /** + * This is used as the source frame only if SOURCE_ARBITRARY_RECTANGLE is applied. + */ private Rect mArbitraryRectangle; /** * Modifies the starting rectangle selected by {@link #mSource}. * - *
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). + * 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). */ private Insets mInsetsSize = null; @@ -94,8 +112,7 @@ public class InsetsFrameProvider implements Parcelable { * the layout of the window, but only change the insets frame. This can be applied to insets * calculated based on all three source frames. * - *
Be cautious, this will not be in effect for the window types whose insets size is
- * overridden.
+ * Be cautious, this will not be in effect for the window types whose insets size is overridden.
*/
private Insets mMinimalInsetsSizeInDisplayCutoutSafe = null;
@@ -109,23 +126,28 @@ public class InsetsFrameProvider implements Parcelable {
* Creates an InsetsFrameProvider which describes what frame an insets source should have.
*
* @param owner the owner of this provider. We might have multiple sources with the same type on
- * a display, this is used to identify them.
+ * a display, this is used to identify them.
* @param index the index of this provider. An owner might provide multiple sources with the
- * same type, this is used to identify them. The value must be in a range of [0, 2047].
+ * same type, this is used to identify them.
+ * The value must be in a range of [0, 2047].
* @param type the {@link InsetsType}.
* @see InsetsSource#createId(Object, int, int)
*/
- public InsetsFrameProvider(
- Object owner, @IntRange(from = 0, to = 2047) int index, @InsetsType int type) {
+ public InsetsFrameProvider(Object owner, @IntRange(from = 0, to = 2047) int index,
+ @InsetsType int type) {
mId = InsetsSource.createId(owner, index, type);
}
- /** Returns an unique integer which identifies the insets source. */
+ /**
+ * Returns an unique integer which identifies the insets source.
+ */
public int getId() {
return mId;
}
- /** Returns the index specified in {@link #InsetsFrameProvider(IBinder, int, int)}. */
+ /**
+ * Returns the index specified in {@link #InsetsFrameProvider(IBinder, int, int)}.
+ */
public int getIndex() {
return InsetsSource.getIndex(mId);
}
@@ -146,6 +168,12 @@ public class InsetsFrameProvider implements Parcelable {
return mSource;
}
+ /** Set the flags of this provider. */
+ public InsetsFrameProvider setFlags(@Flags int flags) {
+ mFlags = flags;
+ return this;
+ }
+
public InsetsFrameProvider setFlags(@Flags int flags, @Flags int mask) {
mFlags = (mFlags & ~mask) | (flags & mask);
return this;
@@ -196,13 +224,17 @@ public class InsetsFrameProvider implements Parcelable {
return mMinimalInsetsSizeInDisplayCutoutSafe;
}
- /** Sets the bounding rectangles within and relative to the source frame. */
+ /**
+ * Sets the bounding rectangles within and relative to the source frame.
+ */
public InsetsFrameProvider setBoundingRects(@Nullable Rect[] boundingRects) {
mBoundingRects = boundingRects == null ? null : boundingRects.clone();
return this;
}
- /** Returns the arbitrary bounding rects, or null if none were set. */
+ /**
+ * Returns the arbitrary bounding rects, or null if none were set.
+ */
@Nullable
public Rect[] getBoundingRects() {
return mBoundingRects;
@@ -251,6 +283,8 @@ public class InsetsFrameProvider implements Parcelable {
return "FRAME";
case SOURCE_ARBITRARY_RECTANGLE:
return "ARBITRARY_RECTANGLE";
+ case SOURCE_ATTACHED_CONTAINER_BOUNDS:
+ return "ATTACHED_CONTAINER_BOUNDS";
}
return "UNDEFINED";
}
@@ -291,29 +325,20 @@ public class InsetsFrameProvider implements Parcelable {
return false;
}
final InsetsFrameProvider other = (InsetsFrameProvider) o;
- return mId == other.mId
- && mSource == other.mSource
- && mFlags == other.mFlags
+ return mId == other.mId && mSource == other.mSource && mFlags == other.mFlags
&& Objects.equals(mInsetsSize, other.mInsetsSize)
&& Arrays.equals(mInsetsSizeOverrides, other.mInsetsSizeOverrides)
&& Objects.equals(mArbitraryRectangle, other.mArbitraryRectangle)
- && Objects.equals(
- mMinimalInsetsSizeInDisplayCutoutSafe,
+ && Objects.equals(mMinimalInsetsSizeInDisplayCutoutSafe,
other.mMinimalInsetsSizeInDisplayCutoutSafe)
&& Arrays.equals(mBoundingRects, other.mBoundingRects);
}
@Override
public int hashCode() {
- return Objects.hash(
- mId,
- mSource,
- mFlags,
- mInsetsSize,
- Arrays.hashCode(mInsetsSizeOverrides),
- mArbitraryRectangle,
- mMinimalInsetsSizeInDisplayCutoutSafe,
- Arrays.hashCode(mBoundingRects));
+ return Objects.hash(mId, mSource, mFlags, mInsetsSize,
+ Arrays.hashCode(mInsetsSizeOverrides), mArbitraryRectangle,
+ mMinimalInsetsSizeInDisplayCutoutSafe, Arrays.hashCode(mBoundingRects));
}
public static final @NonNull Parcelable.Creator If the insetsSize of given type is set to {@code null}, the insets source frame will be
- * used directly for that window type.
+ * If the insetsSize of given type is set to {@code null}, the insets source frame will be used
+ * directly for that window type.
*/
public static class InsetsSizeOverride implements Parcelable {
@@ -350,7 +375,6 @@ public class InsetsFrameProvider implements Parcelable {
mWindowType = windowType;
mInsetsSize = insetsSize;
}
-
public int getWindowType() {
return mWindowType;
}
@@ -359,18 +383,17 @@ public class InsetsFrameProvider implements Parcelable {
return mInsetsSize;
}
- public static final Creator For example, task bar will draw fake rounded corners above itself, so we need to move the
+ * For example, task bar will draw fake rounded corners above itself, so we need to move the
* rounded corner up by the task bar insets size to make other windows see a rounded corner
* above the task bar.
*/
public static final int FLAG_INSETS_ROUNDED_CORNER = 1 << 1;
- /** Controls whether the insets provided by this source should be forcibly consumed. */
+ /**
+ * Controls whether the insets provided by this source should be forcibly consumed.
+ */
public static final int FLAG_FORCE_CONSUMING = 1 << 2;
- /** Controls whether the insets source will play an animation when resizing. */
+ /**
+ * Controls whether the insets source will play an animation when resizing.
+ */
public static final int FLAG_ANIMATE_RESIZING = 1 << 3;
+ /**
+ * Controls whether the {@link WindowInsets.Type#captionBar()} insets provided by this source
+ * should always be forcibly consumed. Unlike with {@link #FLAG_FORCE_CONSUMING}, when this
+ * flag is used the caption bar will be consumed even when the bar is requested to be visible.
+ *
+ * Note: this flag does not take effect when the window applies
+ * {@link WindowInsetsController.Appearance#APPEARANCE_TRANSPARENT_CAPTION_BAR_BACKGROUND}.
+ */
+ public static final int FLAG_FORCE_CONSUMING_OPAQUE_CAPTION_BAR = 1 << 4;
+
+ /**
+ * Indicates whether the insets source is valid.
+ */
+ public static final int FLAG_INVALID = 1 << 5;
+
@Retention(RetentionPolicy.SOURCE)
- @IntDef(
- flag = true,
- prefix = "FLAG_",
- value = {
- FLAG_SUPPRESS_SCRIM,
- FLAG_INSETS_ROUNDED_CORNER,
- FLAG_FORCE_CONSUMING,
- FLAG_ANIMATE_RESIZING,
- })
+ @IntDef(flag = true, prefix = "FLAG_", value = {
+ FLAG_SUPPRESS_SCRIM,
+ FLAG_INSETS_ROUNDED_CORNER,
+ FLAG_FORCE_CONSUMING,
+ FLAG_ANIMATE_RESIZING,
+ FLAG_FORCE_CONSUMING_OPAQUE_CAPTION_BAR,
+ FLAG_INVALID,
+ })
public @interface Flags {}
/**
@@ -115,17 +139,22 @@ public class InsetsSource implements Parcelable {
private @Flags int mFlags;
- /** An unique integer to identify this source across processes. */
+ /**
+ * An unique integer to identify this source across processes.
+ */
private final int mId;
private final @InsetsType int mType;
/** Frame of the source in screen coordinate space */
private final Rect mFrame;
-
private @Nullable Rect mVisibleFrame;
private @Nullable Rect[] mBoundingRects;
+ // If not null, this will be used to calculate insets based on the container bounds the insets
+ // source attached to, and all other frame, including side hints will be ignored.
+ private @Nullable Insets mAttachedInsets;
+
private boolean mVisible;
/**
@@ -135,7 +164,7 @@ public class InsetsSource implements Parcelable {
private @InternalInsetsSide int mSideHint = SIDE_NONE;
private final Rect mTmpFrame = new Rect();
- private final Rect mTmpBoundingRect = new Rect();
+ private final Rect mTmpFrame2 = new Rect();
public InsetsSource(int id, @InsetsType int type) {
mId = id;
@@ -149,19 +178,29 @@ public class InsetsSource implements Parcelable {
mType = other.mType;
mFrame = new Rect(other.mFrame);
mVisible = other.mVisible;
- mVisibleFrame = other.mVisibleFrame != null ? new Rect(other.mVisibleFrame) : null;
+ mVisibleFrame = other.mVisibleFrame != null
+ ? new Rect(other.mVisibleFrame)
+ : null;
mFlags = other.mFlags;
mSideHint = other.mSideHint;
- mBoundingRects = other.mBoundingRects != null ? other.mBoundingRects.clone() : null;
+ mBoundingRects = other.mBoundingRects != null
+ ? other.mBoundingRects.clone()
+ : null;
+ mAttachedInsets = other.mAttachedInsets;
}
public void set(InsetsSource other) {
mFrame.set(other.mFrame);
mVisible = other.mVisible;
- mVisibleFrame = other.mVisibleFrame != null ? new Rect(other.mVisibleFrame) : null;
+ mVisibleFrame = other.mVisibleFrame != null
+ ? new Rect(other.mVisibleFrame)
+ : null;
mFlags = other.mFlags;
mSideHint = other.mSideHint;
- mBoundingRects = other.mBoundingRects != null ? other.mBoundingRects.clone() : null;
+ mBoundingRects = other.mBoundingRects != null
+ ? other.mBoundingRects.clone()
+ : null;
+ mAttachedInsets = other.mAttachedInsets;
}
public InsetsSource setFrame(int left, int top, int right, int bottom) {
@@ -179,6 +218,11 @@ public class InsetsSource implements Parcelable {
return this;
}
+ public InsetsSource setAttachedInsets(@Nullable Insets attachedInsets) {
+ mAttachedInsets = attachedInsets;
+ return this;
+ }
+
public InsetsSource setVisible(boolean visible) {
mVisible = visible;
return this;
@@ -201,7 +245,9 @@ public class InsetsSource implements Parcelable {
* @param bounds A rectangle which contains the frame. It will be used to calculate the hint.
*/
public InsetsSource updateSideHint(Rect bounds) {
- mSideHint = getInsetSide(calculateInsets(bounds, mFrame, true /* ignoreVisibility */));
+ mSideHint = getInsetSide(mAttachedInsets != null
+ ? mAttachedInsets
+ : calculateArbitraryInsets(bounds, mFrame, true /* ignoreVisibility */));
return this;
}
@@ -242,35 +288,67 @@ public class InsetsSource implements Parcelable {
return (mFlags & flags) == flags;
}
- /** Returns the bounding rectangles of this source. */
+ /**
+ * Returns the bounding rectangles of this source.
+ */
public @Nullable Rect[] getBoundingRects() {
return mBoundingRects;
}
+ public @Nullable Insets getAttachedInsets() {
+ return mAttachedInsets;
+ }
+
/**
* Calculates the insets this source will cause to a client window.
*
* @param relativeFrame The frame to calculate the insets relative to.
+ * @param hostBounds the bounds of the host window. Can be none if no local insets with
+ * attached insets is set.
* @param ignoreVisibility If true, always reports back insets even if source isn't visible.
* @return The resulting insets. The contract is that only one side will be occupied by a
- * source.
+ * source.
*/
- public Insets calculateInsets(Rect relativeFrame, boolean ignoreVisibility) {
- return calculateInsets(relativeFrame, mFrame, ignoreVisibility);
+ public Insets calculateInsets(Rect relativeFrame, @Nullable Rect hostBounds,
+ boolean ignoreVisibility) {
+ if (mAttachedInsets != null) {
+ return calculateAttachedInsets(relativeFrame, hostBounds, ignoreVisibility);
+ } else {
+ return calculateArbitraryInsets(relativeFrame, mFrame, ignoreVisibility);
+ }
}
- /** Like {@link #calculateInsets(Rect, boolean)}, but will return visible insets. */
- public Insets calculateVisibleInsets(Rect relativeFrame) {
- return calculateInsets(
- relativeFrame,
- mVisibleFrame != null ? mVisibleFrame : mFrame,
- false /* ignoreVisibility */);
+ /**
+ * Like {@link #calculateInsets(Rect, Rect, boolean)}, but will return visible insets.
+ */
+ public Insets calculateVisibleInsets(Rect relativeFrame, Rect hostBounds) {
+ if (mAttachedInsets != null) {
+ return calculateAttachedInsets(relativeFrame, hostBounds,
+ false /* ignoreVisibility */);
+ } else {
+ return calculateArbitraryInsets(relativeFrame, mVisibleFrame != null
+ ? mVisibleFrame : mFrame, false /* ignoreVisibility */);
+ }
}
- private Insets calculateInsets(Rect relativeFrame, Rect frame, boolean ignoreVisibility) {
+ /**
+ * Calculates the insets this source will cause to a client window. The insets frame is a given
+ * rectangle on a display coordinate system, and the client window frame is also on the same
+ * coordinate system.
+ *
+ * @param relativeFrame The frame to calculate the insets relative to. The client window
+ * frame.
+ * @param frame the frame of the insets to be used during the calculation.
+ * @param ignoreVisibility If true, always reports back insets even if source isn't visible.
+ * @return The resulting insets. The contract is that only one side will be occupied by a
+ * source.
+ */
+ private Insets calculateArbitraryInsets(Rect relativeFrame, Rect frame,
+ boolean ignoreVisibility) {
if (!ignoreVisibility && !mVisible) {
return Insets.NONE;
}
+
// During drag-move and drag-resizing, the caption insets position may not get updated
// before the app frame get updated. To layout the app content correctly during drag events,
// we always return the insets with the corresponding height covering the top.
@@ -282,10 +360,9 @@ public class InsetsSource implements Parcelable {
: Insets.of(0, frame.height(), 0, 0);
}
// Checks for whether there is shared edge with insets for 0-width/height window.
- final boolean hasIntersection =
- relativeFrame.isEmpty()
- ? getIntersection(frame, relativeFrame, mTmpFrame)
- : mTmpFrame.setIntersect(frame, relativeFrame);
+ final boolean hasIntersection = relativeFrame.isEmpty()
+ ? getIntersection(frame, relativeFrame, mTmpFrame)
+ : mTmpFrame.setIntersect(frame, relativeFrame);
if (!hasIntersection) {
return Insets.NONE;
}
@@ -329,11 +406,71 @@ public class InsetsSource implements Parcelable {
} else if (mTmpFrame.right == relativeFrame.right) {
return Insets.of(0, 0, mTmpFrame.width(), 0);
}
+ } else {
+ // The source doesn't cover the width or the height of relativeFrame, but just parts of
+ // them. Here uses mSideHint to decide which side should be inset.
+ switch (mSideHint) {
+ case SIDE_LEFT:
+ if (mTmpFrame.left == relativeFrame.left) {
+ return Insets.of(mTmpFrame.width(), 0, 0, 0);
+ }
+ break;
+ case SIDE_TOP:
+ if (mTmpFrame.top == relativeFrame.top) {
+ return Insets.of(0, mTmpFrame.height(), 0, 0);
+ }
+ break;
+ case SIDE_RIGHT:
+ if (mTmpFrame.right == relativeFrame.right) {
+ return Insets.of(0, 0, mTmpFrame.width(), 0);
+ }
+ break;
+ case SIDE_BOTTOM:
+ if (mTmpFrame.bottom == relativeFrame.bottom) {
+ return Insets.of(0, 0, 0, mTmpFrame.height());
+ }
+ break;
+ }
}
return Insets.NONE;
}
- /** Calculates the bounding rects the source will cause to a client window. */
+ /**
+ * Calculates the insets this source will cause to a client window when the insets is attached
+ * to a container.
+ *
+ * @param relativeFrame The frame to calculate the insets relative to.
+ * @param hostBounds the bounds of the container where the insets attached to.
+ * @param ignoreVisibility If true, always reports back insets even if source isn't visible.
+ * @return The resulting insets. The contract is that only one side will be occupied by a
+ * source.
+ */
+ private Insets calculateAttachedInsets(Rect relativeFrame, Rect hostBounds,
+ boolean ignoreVisibility) {
+ if (hostBounds == null) {
+ throw new IllegalArgumentException("A local relative insets requires the host "
+ + "container bounds to be calculated correctly.");
+ }
+ if (!ignoreVisibility && !mVisible) {
+ return Insets.NONE;
+ }
+ if (!mAttachedInsets.equals(Insets.NONE)) {
+ mTmpFrame2.set(hostBounds);
+ mTmpFrame2.inset(mAttachedInsets);
+ return mTmpFrame.setIntersect(mTmpFrame2, relativeFrame)
+ ? Insets.of(
+ mTmpFrame.left - relativeFrame.left,
+ mTmpFrame.top - relativeFrame.top,
+ relativeFrame.right - mTmpFrame.right,
+ relativeFrame.bottom - mTmpFrame.bottom)
+ : Insets.NONE;
+ }
+ return Insets.NONE;
+ }
+
+ /**
+ * Calculates the bounding rects the source will cause to a client window.
+ */
public @NonNull Rect[] calculateBoundingRects(Rect relativeFrame, boolean ignoreVisibility) {
if (!ignoreVisibility && !mVisible) {
return NO_BOUNDING_RECTS;
@@ -343,13 +480,14 @@ public class InsetsSource implements Parcelable {
if (mBoundingRects == null) {
// No bounding rects set, make a single bounding rect that covers the intersection of
// the |frame| and the |relativeFrame|. Also make it relative to the window origin.
- return mTmpBoundingRect.setIntersect(frame, relativeFrame)
- ? new Rect[] {
- new Rect(
- mTmpBoundingRect.left - relativeFrame.left,
- mTmpBoundingRect.top - relativeFrame.top,
- mTmpBoundingRect.right - relativeFrame.left,
- mTmpBoundingRect.bottom - relativeFrame.top)
+ return mTmpFrame2.setIntersect(frame, relativeFrame)
+ ? new Rect[]{
+ new Rect(
+ mTmpFrame2.left - relativeFrame.left,
+ mTmpFrame2.top - relativeFrame.top,
+ mTmpFrame2.right - relativeFrame.left,
+ mTmpFrame2.bottom - relativeFrame.top
+ )
}
: NO_BOUNDING_RECTS;
}
@@ -368,11 +506,11 @@ public class InsetsSource implements Parcelable {
// |frame| either is already relative to |relativeFrame| (for top captionBar()), or
// just needs to be made relative to |relativeFrame| for bottom bars.
final int frameHeight = frame.height();
- mTmpBoundingRect.set(boundingRect);
+ mTmpFrame2.set(boundingRect);
if (getId() == ID_IME_CAPTION_BAR) {
- mTmpBoundingRect.offset(0, relativeFrame.height() - frameHeight);
+ mTmpFrame2.offset(0, relativeFrame.height() - frameHeight);
}
- validBoundingRects.add(new Rect(mTmpBoundingRect));
+ validBoundingRects.add(new Rect(mTmpFrame2));
}
return validBoundingRects.toArray(new Rect[validBoundingRects.size()]);
}
@@ -382,15 +520,15 @@ public class InsetsSource implements Parcelable {
for (final Rect boundingRect : mBoundingRects) {
// |boundingRect| was provided relative to |frame|. Make it absolute to be in the same
// coordinate system as |frame|.
- final Rect absBoundingRect =
- new Rect(
- boundingRect.left + frame.left,
- boundingRect.top + frame.top,
- boundingRect.right + frame.left,
- boundingRect.bottom + frame.top);
+ final Rect absBoundingRect = new Rect(
+ boundingRect.left + frame.left,
+ boundingRect.top + frame.top,
+ boundingRect.right + frame.left,
+ boundingRect.bottom + frame.top
+ );
// Now find the intersection of that |absBoundingRect| with |relativeFrame|. In other
// words, whichever part of the bounding rect is inside the window frame.
- if (!mTmpBoundingRect.setIntersect(absBoundingRect, relativeFrame)) {
+ if (!mTmpFrame2.setIntersect(absBoundingRect, relativeFrame)) {
// It's possible for this to be empty if the frame and bounding rects were larger
// than the |relativeFrame|, such as when a system window is wider than the app
// window width. Just ignore that rect since it will have no effect on the
@@ -400,12 +538,11 @@ public class InsetsSource implements Parcelable {
// At this point, |mTmpBoundingRect| is a valid bounding rect located fully inside the
// window, convert it to be relative to the window so that apps don't need to know the
// location of the window to understand bounding rects.
- validBoundingRects.add(
- new Rect(
- mTmpBoundingRect.left - relativeFrame.left,
- mTmpBoundingRect.top - relativeFrame.top,
- mTmpBoundingRect.right - relativeFrame.left,
- mTmpBoundingRect.bottom - relativeFrame.top));
+ validBoundingRects.add(new Rect(
+ mTmpFrame2.left - relativeFrame.left,
+ mTmpFrame2.top - relativeFrame.top,
+ mTmpFrame2.right - relativeFrame.left,
+ mTmpFrame2.bottom - relativeFrame.top));
}
if (validBoundingRects.isEmpty()) {
return NO_BOUNDING_RECTS;
@@ -479,13 +616,13 @@ public class InsetsSource implements Parcelable {
*
* @param owner An object owned by the owner. Only the owner can modify its own sources.
* @param index An owner may have multiple sources with the same type. For example, the system
- * server might have multiple display cutout sources. This is used to identify which one is
- * which. The value must be in a range of [0, 2047].
+ * server might have multiple display cutout sources. This is used to identify
+ * which one is which. The value must be in a range of [0, 2047].
* @param type The {@link InsetsType type} of the source.
* @return a unique integer as the identifier.
*/
- public static int createId(
- Object owner, @IntRange(from = 0, to = 2047) int index, @InsetsType int type) {
+ public static int createId(Object owner, @IntRange(from = 0, to = 2047) int index,
+ @InsetsType int type) {
if (index < 0 || index >= 2048) {
throw new IllegalArgumentException();
}
@@ -536,13 +673,19 @@ public class InsetsSource implements Parcelable {
if ((flags & FLAG_ANIMATE_RESIZING) != 0) {
joiner.add("ANIMATE_RESIZING");
}
+ if ((flags & FLAG_FORCE_CONSUMING_OPAQUE_CAPTION_BAR) != 0) {
+ joiner.add("FORCE_CONSUMING_OPAQUE_CAPTION_BAR");
+ }
+ if ((flags & FLAG_INVALID) != 0) {
+ joiner.add("INVALID");
+ }
return joiner.toString();
}
/**
* Export the state of {@link InsetsSource} into a protocol buffer output stream.
*
- * @param proto Stream to write the state to
+ * @param proto Stream to write the state to
* @param fieldId FieldId of InsetsSource as defined in the parent message
*/
public void dumpDebug(ProtoOutputStream proto, long fieldId) {
@@ -557,29 +700,28 @@ public class InsetsSource implements Parcelable {
}
proto.write(VISIBLE, mVisible);
proto.write(TYPE_NUMBER, mType);
+ if (mAttachedInsets != null) {
+ mAttachedInsets.dumpDebug(proto, ATTACHED_INSETS);
+ }
proto.end(token);
}
public void dump(String prefix, PrintWriter pw) {
pw.print(prefix);
- pw.print("InsetsSource id=");
- pw.print(Integer.toHexString(mId));
- pw.print(" type=");
- pw.print(WindowInsets.Type.toString(mType));
- pw.print(" frame=");
- pw.print(mFrame.toShortString());
- if (mVisibleFrame != null) {
- pw.print(" visibleFrame=");
- pw.print(mVisibleFrame.toShortString());
+ pw.print("InsetsSource id="); pw.print(Integer.toHexString(mId));
+ pw.print(" type="); pw.print(WindowInsets.Type.toString(mType));
+ if (mAttachedInsets != null) {
+ pw.print(" attachedInsets="); pw.print(mAttachedInsets);
+ } else {
+ pw.print(" frame="); pw.print(mFrame.toShortString());
}
- pw.print(" visible=");
- pw.print(mVisible);
- pw.print(" flags=");
- pw.print(flagsToString(mFlags));
- pw.print(" sideHint=");
- pw.print(sideToString(mSideHint));
- pw.print(" boundingRects=");
- pw.print(Arrays.toString(mBoundingRects));
+ if (mVisibleFrame != null) {
+ pw.print(" visibleFrame="); pw.print(mVisibleFrame.toShortString());
+ }
+ pw.print(" visible="); pw.print(mVisible);
+ pw.print(" flags="); pw.print(flagsToString(mFlags));
+ pw.print(" sideHint="); pw.print(sideToString(mSideHint));
+ pw.print(" boundingRects="); pw.print(Arrays.toString(mBoundingRects));
pw.println();
}
@@ -590,7 +732,7 @@ public class InsetsSource implements Parcelable {
/**
* @param excludeInvisibleImeFrames If {@link WindowInsets.Type#ime()} frames should be ignored
- * when IME is not visible.
+ * when IME is not visible.
*/
public boolean equals(@Nullable Object o, boolean excludeInvisibleImeFrames) {
if (this == o) return true;
@@ -611,14 +753,7 @@ public class InsetsSource implements Parcelable {
@Override
public int hashCode() {
- return Objects.hash(
- mId,
- mType,
- mFrame,
- mVisibleFrame,
- mVisible,
- mFlags,
- mSideHint,
+ return Objects.hash(mId, mType, mFrame, mVisibleFrame, mVisible, mFlags, mSideHint,
Arrays.hashCode(mBoundingRects));
}
@@ -635,6 +770,11 @@ public class InsetsSource implements Parcelable {
mFlags = in.readInt();
mSideHint = in.readInt();
mBoundingRects = in.createTypedArray(Rect.CREATOR);
+ if (in.readInt() != 0) {
+ mAttachedInsets = Insets.CREATOR.createFromParcel(in);
+ } else {
+ mAttachedInsets = null;
+ }
}
@Override
@@ -657,36 +797,35 @@ public class InsetsSource implements Parcelable {
dest.writeInt(mFlags);
dest.writeInt(mSideHint);
dest.writeTypedArray(mBoundingRects, flags);
+ if (mAttachedInsets != null) {
+ dest.writeInt(1);
+ mAttachedInsets.writeToParcel(dest, flags);
+ } else {
+ dest.writeInt(0);
+ }
}
@Override
public String toString() {
- return "InsetsSource: {"
- + Integer.toHexString(mId)
- + " mType="
- + WindowInsets.Type.toString(mType)
- + " mFrame="
- + mFrame.toShortString()
- + " mVisible="
- + mVisible
- + " mFlags="
- + flagsToString(mFlags)
- + " mSideHint="
- + sideToString(mSideHint)
- + " mBoundingRects="
- + Arrays.toString(mBoundingRects)
+ return "InsetsSource: {" + Integer.toHexString(mId)
+ + " mType=" + WindowInsets.Type.toString(mType)
+ + " mFrame=" + mFrame.toShortString()
+ + " mAttachedInsets=" + mAttachedInsets
+ + " mVisible=" + mVisible
+ + " mFlags=" + flagsToString(mFlags)
+ + " mSideHint=" + sideToString(mSideHint)
+ + " mBoundingRects=" + Arrays.toString(mBoundingRects)
+ "}";
}
- public static final @NonNull Creator This allows the client to customize various back behaviors by overriding the corresponding
+ * Interface for applications to register back animation callbacks along their custom back
+ * handling.
+ *
+ * This allows the client to customize various back behaviors by overriding the corresponding
* callback methods.
- *
- * Callback instances can be added to and removed from {@link OnBackInvokedDispatcher}, which is
- * held at window level and accessible through {@link Activity#getOnBackInvokedDispatcher()}, {@link
- * Dialog#getOnBackInvokedDispatcher()}, {@link Window#getOnBackInvokedDispatcher()} and {@link
- * View#findOnBackInvokedDispatcher()}.
- *
- * When back is triggered, callbacks on the in-focus window are invoked in reverse order in which
+ *
+ * Callback instances can be added to and removed from {@link OnBackInvokedDispatcher}, which
+ * is held at window level and accessible through {@link Activity#getOnBackInvokedDispatcher()},
+ * {@link Dialog#getOnBackInvokedDispatcher()}, {@link Window#getOnBackInvokedDispatcher()}
+ * and {@link View#findOnBackInvokedDispatcher()}.
+ *
+ * When back is triggered, callbacks on the in-focus window are invoked in reverse order in which
* they are added within the same priority. Between different priorities, callbacks with higher
* priority are invoked first.
- *
*
- *
* @see OnBackInvokedCallback
*/
public interface OnBackAnimationCallback extends OnBackInvokedCallback {
/**
* Called when a back gesture has been started, or back button has been pressed down.
*
- * @param backEvent The {@link BackEvent} containing information about the touch or button
- * press.
+ * @param backEvent The {@link BackEvent} containing information about the touch or
+ * button press.
* @see BackEvent
*/
default void onBackStarted(@NonNull BackEvent backEvent) {}
@@ -54,10 +52,12 @@ public interface OnBackAnimationCallback extends OnBackInvokedCallback {
* Called when a back gesture progresses.
*
* @param backEvent An {@link BackEvent} object describing the progress event.
+ *
* @see BackEvent
*/
- default void onBackProgressed(@NonNull BackEvent backEvent) {}
-
- /** Called when a back gesture or back button press has been cancelled. */
- default void onBackCancelled() {}
+ default void onBackProgressed(@NonNull BackEvent backEvent) { }
+ /**
+ * Called when a back gesture or back button press has been cancelled.
+ */
+ default void onBackCancelled() { }
}
diff --git a/compatLib/src/main/java/android/window/OnBackInvokedCallback.java b/compatLib/src/main/java/android/window/OnBackInvokedCallback.java
index ab6b08971e..6beaad339b 100644
--- a/compatLib/src/main/java/android/window/OnBackInvokedCallback.java
+++ b/compatLib/src/main/java/android/window/OnBackInvokedCallback.java
@@ -23,32 +23,31 @@ import android.view.Window;
/**
* Callback allowing applications to handle back events in place of the system.
- *
- * Callback instances can be added to and removed from {@link OnBackInvokedDispatcher}, which is
- * held at window level and accessible through {@link Activity#getOnBackInvokedDispatcher()}, {@link
- * Dialog#getOnBackInvokedDispatcher()}, {@link Window#getOnBackInvokedDispatcher()} and {@link
- * View#findOnBackInvokedDispatcher()}.
- *
- * When back is triggered, callbacks on the in-focus window are invoked in reverse order in which
+ *
+ * Callback instances can be added to and removed from {@link OnBackInvokedDispatcher}, which
+ * is held at window level and accessible through {@link Activity#getOnBackInvokedDispatcher()},
+ * {@link Dialog#getOnBackInvokedDispatcher()}, {@link Window#getOnBackInvokedDispatcher()}
+ * and {@link View#findOnBackInvokedDispatcher()}.
+ *
+ * When back is triggered, callbacks on the in-focus window are invoked in reverse order in which
* they are added within the same priority. Between different priorities, callbacks with higher
* priority are invoked first.
- *
- * This replaces {@link Activity#onBackPressed()}, {@link Dialog#onBackPressed()} and {@link
- * android.view.KeyEvent#KEYCODE_BACK}
- *
- * If you want to customize back animation behaviors, in addition to handling back invocations,
- * register its subclass instances {@link OnBackAnimationCallback} instead.
- *
*
- *
+ * This replaces {@link Activity#onBackPressed()}, {@link Dialog#onBackPressed()} and
+ * {@link android.view.KeyEvent#KEYCODE_BACK}
+ *
+ * If you want to customize back animation behaviors, in addition to handling back invocations,
+ * register its subclass instances {@link OnBackAnimationCallback} instead.
+ *
* @see OnBackInvokedDispatcher#registerOnBackInvokedCallback(int, OnBackInvokedCallback)
- * registerOnBackInvokedCallback(priority, OnBackInvokedCallback) to specify callback priority.
+ * registerOnBackInvokedCallback(priority, OnBackInvokedCallback)
+ * to specify callback priority.
*/
@SuppressWarnings("deprecation")
public interface OnBackInvokedCallback {
/**
- * Called when a back gesture has been completed and committed, or back button pressed has been
- * released and committed.
+ * Called when a back gesture has been completed and committed, or back button pressed
+ * has been released and committed.
*/
void onBackInvoked();
}
diff --git a/compatLib/src/main/java/android/window/RemoteTransition.java b/compatLib/src/main/java/android/window/RemoteTransition.java
index e7635b5cb2..15b3c4490f 100644
--- a/compatLib/src/main/java/android/window/RemoteTransition.java
+++ b/compatLib/src/main/java/android/window/RemoteTransition.java
@@ -25,7 +25,6 @@ import android.os.Parcelable;
/**
* Represents a remote transition animation and information required to run it (eg. the app thread
* that needs to be boosted).
- *
* @hide
*/
public final class RemoteTransition implements Parcelable {
@@ -41,7 +40,6 @@ public final class RemoteTransition implements Parcelable {
/**
* Constructs with no app thread (animation runs in shell).
- *
* @hide
*/
public RemoteTransition(@NonNull IRemoteTransition remoteTransition) {
@@ -50,11 +48,10 @@ public final class RemoteTransition implements Parcelable {
/**
* Constructs with no app thread (animation runs in shell).
- *
* @hide
*/
- public RemoteTransition(
- @NonNull IRemoteTransition remoteTransition, @Nullable String debugName) {
+ public RemoteTransition(@NonNull IRemoteTransition remoteTransition,
+ @Nullable String debugName) {
this(remoteTransition, null /* appThread */, debugName);
}
@@ -66,10 +63,12 @@ public final class RemoteTransition implements Parcelable {
/**
* Creates a new RemoteTransition.
*
- * @param remoteTransition The actual remote-transition interface used to run the transition
- * animation.
- * @param appThread The application thread that will be running the remote transition.
- * @param debugName A name for this that can be used for debugging.
+ * @param remoteTransition
+ * The actual remote-transition interface used to run the transition animation.
+ * @param appThread
+ * The application thread that will be running the remote transition.
+ * @param debugName
+ * A name for this that can be used for debugging.
* @hide
*/
public RemoteTransition(
@@ -87,7 +86,6 @@ public final class RemoteTransition implements Parcelable {
/**
* The actual remote-transition interface used to run the transition animation.
- *
* @hide
*/
public @NonNull IRemoteTransition getRemoteTransition() {
@@ -96,21 +94,21 @@ public final class RemoteTransition implements Parcelable {
/**
* The application thread that will be running the remote transition.
- *
* @hide
*/
public @Nullable IApplicationThread getAppThread() {
return mAppThread;
}
- /** A name for this that can be used for debugging. */
+ /**
+ * A name for this that can be used for debugging.
+ */
public @Nullable String getDebugName() {
return mDebugName;
}
/**
* The actual remote-transition interface used to run the transition animation.
- *
* @hide
*/
public @NonNull RemoteTransition setRemoteTransition(@NonNull IRemoteTransition value) {
@@ -122,7 +120,6 @@ public final class RemoteTransition implements Parcelable {
/**
* The application thread that will be running the remote transition.
- *
* @hide
*/
public @NonNull RemoteTransition setAppThread(@NonNull IApplicationThread value) {
@@ -130,7 +127,9 @@ public final class RemoteTransition implements Parcelable {
return this;
}
- /** A name for this that can be used for debugging. */
+ /**
+ * A name for this that can be used for debugging.
+ */
public @NonNull RemoteTransition setDebugName(@NonNull String value) {
mDebugName = value;
return this;
@@ -141,16 +140,11 @@ public final class RemoteTransition implements Parcelable {
// You can override field toString logic by defining methods like:
// String fieldNameToString() { ... }
- return "RemoteTransition { "
- + "remoteTransition = "
- + mRemoteTransition
- + ", "
- + "appThread = "
- + mAppThread
- + ", "
- + "debugName = "
- + mDebugName
- + " }";
+ return "RemoteTransition { " +
+ "remoteTransition = " + mRemoteTransition + ", " +
+ "appThread = " + mAppThread + ", " +
+ "debugName = " + mDebugName +
+ " }";
}
@Override
@@ -168,9 +162,7 @@ public final class RemoteTransition implements Parcelable {
}
@Override
- public int describeContents() {
- return 0;
- }
+ public int describeContents() { return 0; }
/** @hide */
@SuppressWarnings({"unchecked", "RedundantCast"})
@@ -179,12 +171,8 @@ public final class RemoteTransition implements Parcelable {
// static FieldType unparcelFieldName(Parcel in) { ... }
byte flg = in.readByte();
- IRemoteTransition remoteTransition =
- IRemoteTransition.Stub.asInterface(in.readStrongBinder());
- IApplicationThread appThread =
- (flg & 0x2) == 0
- ? null
- : IApplicationThread.Stub.asInterface(in.readStrongBinder());
+ IRemoteTransition remoteTransition = IRemoteTransition.Stub.asInterface(in.readStrongBinder());
+ IApplicationThread appThread = (flg & 0x2) == 0 ? null : IApplicationThread.Stub.asInterface(in.readStrongBinder());
String debugName = (flg & 0x4) == 0 ? null : in.readString();
this.mRemoteTransition = remoteTransition;
@@ -194,16 +182,16 @@ public final class RemoteTransition implements Parcelable {
this.mDebugName = debugName;
}
- public static final @NonNull Parcelable.Creator