feat(QuickSwitch): Reimpl Baklava compat
Signed-off-by: Pun Butrach <pun.butrach@gmail.com>
This commit is contained in:
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -38,4 +38,4 @@ oneway interface ISystemGestureExclusionListener {
|
||||
*/
|
||||
void onSystemGestureExclusionChanged(int displayId, in Region systemGestureExclusion,
|
||||
in Region systemGestureExclusionUnrestricted);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
* <p>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.
|
||||
*
|
||||
* <p>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}.
|
||||
*
|
||||
* <p>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.
|
||||
*
|
||||
* <p>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<InsetsFrameProvider> CREATOR =
|
||||
@@ -333,8 +358,8 @@ public class InsetsFrameProvider implements Parcelable {
|
||||
* Class to describe the insets size to be provided to window with specific window type. If not
|
||||
* used, same insets size will be sent as instructed in the insetsSize and source.
|
||||
*
|
||||
* <p>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<InsetsSizeOverride> CREATOR =
|
||||
new Creator<>() {
|
||||
@Override
|
||||
public InsetsSizeOverride createFromParcel(Parcel in) {
|
||||
return new InsetsSizeOverride(in);
|
||||
}
|
||||
public static final Creator<InsetsSizeOverride> CREATOR = new Creator<>() {
|
||||
@Override
|
||||
public InsetsSizeOverride createFromParcel(Parcel in) {
|
||||
return new InsetsSizeOverride(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InsetsSizeOverride[] newArray(int size) {
|
||||
return new InsetsSizeOverride[size];
|
||||
}
|
||||
};
|
||||
@Override
|
||||
public InsetsSizeOverride[] newArray(int size) {
|
||||
return new InsetsSizeOverride[size];
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
@@ -387,10 +410,8 @@ public class InsetsFrameProvider implements Parcelable {
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder(32);
|
||||
sb.append("TypedInsetsSize: {");
|
||||
sb.append("windowType=")
|
||||
.append(
|
||||
ViewDebug.intToString(
|
||||
WindowManager.LayoutParams.class, "type", mWindowType));
|
||||
sb.append("windowType=").append(ViewDebug.intToString(
|
||||
WindowManager.LayoutParams.class, "type", mWindowType));
|
||||
sb.append(", insetsSize=").append(mInsetsSize);
|
||||
sb.append("}");
|
||||
return sb.toString();
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package android.view;
|
||||
|
||||
import static android.view.InsetsSourceProto.ATTACHED_INSETS;
|
||||
import static android.view.InsetsSourceProto.FRAME;
|
||||
import static android.view.InsetsSourceProto.TYPE;
|
||||
import static android.view.InsetsSourceProto.TYPE_NUMBER;
|
||||
@@ -34,6 +35,7 @@ import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.util.proto.ProtoOutputStream;
|
||||
import android.view.WindowInsets.Type.InsetsType;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
@@ -44,15 +46,19 @@ import java.util.StringJoiner;
|
||||
|
||||
/**
|
||||
* Represents the state of a single entity generating insets for clients.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public class InsetsSource implements Parcelable {
|
||||
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(
|
||||
prefix = "SIDE_",
|
||||
value = {SIDE_NONE, SIDE_LEFT, SIDE_TOP, SIDE_RIGHT, SIDE_BOTTOM, SIDE_UNKNOWN})
|
||||
@IntDef(prefix = "SIDE_", value = {
|
||||
SIDE_NONE,
|
||||
SIDE_LEFT,
|
||||
SIDE_TOP,
|
||||
SIDE_RIGHT,
|
||||
SIDE_BOTTOM,
|
||||
SIDE_UNKNOWN
|
||||
})
|
||||
public @interface InternalInsetsSide {}
|
||||
|
||||
static final int SIDE_NONE = 0;
|
||||
@@ -83,28 +89,46 @@ public class InsetsSource implements Parcelable {
|
||||
* Controls whether the insets frame will be used to move {@link RoundedCorner} inward with the
|
||||
* insets frame size when calculating the rounded corner insets to other windows.
|
||||
*
|
||||
* <p>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<InsetsSource> CREATOR =
|
||||
new Creator<>() {
|
||||
public static final @NonNull Creator<InsetsSource> CREATOR = new Creator<>() {
|
||||
|
||||
public InsetsSource createFromParcel(Parcel in) {
|
||||
return new InsetsSource(in);
|
||||
}
|
||||
public InsetsSource createFromParcel(Parcel in) {
|
||||
return new InsetsSource(in);
|
||||
}
|
||||
|
||||
public InsetsSource[] newArray(int size) {
|
||||
return new InsetsSource[size];
|
||||
}
|
||||
};
|
||||
public InsetsSource[] newArray(int size) {
|
||||
return new InsetsSource[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -81,4 +81,4 @@ oneway interface IRemoteTransition {
|
||||
* @param aborted Whether the transition is aborted or not.
|
||||
*/
|
||||
void onTransitionConsumed(in IBinder transition, in boolean aborted);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,9 +13,12 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License
|
||||
*/
|
||||
|
||||
package android.window;
|
||||
|
||||
import android.view.SurfaceControl;
|
||||
import android.window.WindowContainerTransaction;
|
||||
|
||||
/**
|
||||
* Interface to be invoked by the controlling process when a remote transition has finished.
|
||||
*
|
||||
@@ -27,4 +30,4 @@ import android.window.WindowContainerTransaction;
|
||||
*/
|
||||
interface IRemoteTransitionFinishedCallback {
|
||||
void onTransitionFinished(in WindowContainerTransaction wct, in SurfaceControl.Transaction sct);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
package android.window;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.app.Activity;
|
||||
import android.app.Dialog;
|
||||
@@ -22,30 +21,29 @@ import android.view.View;
|
||||
import android.view.Window;
|
||||
|
||||
/**
|
||||
* Interface for applications to register back animation callbacks along their custom back handling.
|
||||
*
|
||||
* <p>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.
|
||||
* <p>
|
||||
* This allows the client to customize various back behaviors by overriding the corresponding
|
||||
* callback methods.
|
||||
*
|
||||
* <p>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()}.
|
||||
*
|
||||
* <p>When back is triggered, callbacks on the in-focus window are invoked in reverse order in which
|
||||
* <p>
|
||||
* 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()}.
|
||||
* <p>
|
||||
* 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.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @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() { }
|
||||
}
|
||||
|
||||
@@ -23,32 +23,31 @@ import android.view.Window;
|
||||
|
||||
/**
|
||||
* Callback allowing applications to handle back events in place of the system.
|
||||
*
|
||||
* <p>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()}.
|
||||
*
|
||||
* <p>When back is triggered, callbacks on the in-focus window are invoked in reverse order in which
|
||||
* <p>
|
||||
* 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()}.
|
||||
* <p>
|
||||
* 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.
|
||||
*
|
||||
* <p>This replaces {@link Activity#onBackPressed()}, {@link Dialog#onBackPressed()} and {@link
|
||||
* android.view.KeyEvent#KEYCODE_BACK}
|
||||
*
|
||||
* <p>If you want to customize back animation behaviors, in addition to handling back invocations,
|
||||
* register its subclass instances {@link OnBackAnimationCallback} instead.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* This replaces {@link Activity#onBackPressed()}, {@link Dialog#onBackPressed()} and
|
||||
* {@link android.view.KeyEvent#KEYCODE_BACK}
|
||||
* <p>
|
||||
* If you want to customize back animation behaviors, in addition to handling back invocations,
|
||||
* register its subclass instances {@link OnBackAnimationCallback} instead.
|
||||
* <p>
|
||||
* @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();
|
||||
}
|
||||
|
||||
@@ -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<RemoteTransition> CREATOR =
|
||||
new Parcelable.Creator<RemoteTransition>() {
|
||||
@Override
|
||||
public RemoteTransition[] newArray(int size) {
|
||||
return new RemoteTransition[size];
|
||||
}
|
||||
public static final @NonNull Parcelable.Creator<RemoteTransition> CREATOR
|
||||
= new Parcelable.Creator<RemoteTransition>() {
|
||||
@Override
|
||||
public RemoteTransition[] newArray(int size) {
|
||||
return new RemoteTransition[size];
|
||||
}
|
||||
|
||||
@Override
|
||||
public RemoteTransition createFromParcel(@NonNull android.os.Parcel in) {
|
||||
return new RemoteTransition(in);
|
||||
}
|
||||
};
|
||||
@Override
|
||||
public RemoteTransition createFromParcel(@NonNull android.os.Parcel in) {
|
||||
return new RemoteTransition(in);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -27,25 +27,21 @@ import android.view.SurfaceControl;
|
||||
*/
|
||||
public abstract class RemoteTransitionStub extends IRemoteTransition.Stub {
|
||||
@Override
|
||||
public void mergeAnimation(
|
||||
IBinder transition,
|
||||
TransitionInfo info,
|
||||
SurfaceControl.Transaction t,
|
||||
IBinder mergeTarget,
|
||||
IRemoteTransitionFinishedCallback finishCallback)
|
||||
throws RemoteException {}
|
||||
public void mergeAnimation(IBinder transition, TransitionInfo info,
|
||||
SurfaceControl.Transaction t, IBinder mergeTarget,
|
||||
IRemoteTransitionFinishedCallback finishCallback) throws RemoteException {}
|
||||
|
||||
|
||||
@Override
|
||||
public void takeOverAnimation(
|
||||
IBinder transition,
|
||||
TransitionInfo info,
|
||||
public void takeOverAnimation(IBinder transition, TransitionInfo info,
|
||||
SurfaceControl.Transaction startTransaction,
|
||||
IRemoteTransitionFinishedCallback finishCallback,
|
||||
WindowAnimationState[] states)
|
||||
throws RemoteException {
|
||||
WindowAnimationState[] states) throws RemoteException {
|
||||
throw new RemoteException("Takeovers are not supported by this IRemoteTransition");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onTransitionConsumed(IBinder transition, boolean aborted) throws RemoteException {}
|
||||
public void onTransitionConsumed(IBinder transition, boolean aborted)
|
||||
throws RemoteException {}
|
||||
}
|
||||
|
||||
@@ -16,4 +16,4 @@
|
||||
|
||||
package android.window;
|
||||
|
||||
parcelable TransitionFilter;
|
||||
parcelable TransitionFilter;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package android.window;
|
||||
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
||||
import static android.view.WindowManager.TransitionType;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
@@ -32,7 +33,8 @@ import android.view.WindowManager;
|
||||
|
||||
/**
|
||||
* A parcelable filter that can be used for rerouting transitions to a remote. This is a local
|
||||
* representation so that the transition system doesn't need to make blocking queries over binder.
|
||||
* representation so that the transition system doesn't need to make blocking queries over
|
||||
* binder.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@@ -40,17 +42,14 @@ public final class TransitionFilter implements Parcelable {
|
||||
|
||||
/** The associated requirement doesn't care about the z-order. */
|
||||
public static final int CONTAINER_ORDER_ANY = 0;
|
||||
|
||||
/** The associated requirement only matches the top-most (z-order) container. */
|
||||
public static final int CONTAINER_ORDER_TOP = 1;
|
||||
|
||||
/** @hide */
|
||||
@IntDef(
|
||||
prefix = {"CONTAINER_ORDER_"},
|
||||
value = {
|
||||
CONTAINER_ORDER_ANY,
|
||||
CONTAINER_ORDER_TOP,
|
||||
})
|
||||
@IntDef(prefix = { "CONTAINER_ORDER_" }, value = {
|
||||
CONTAINER_ORDER_ANY,
|
||||
CONTAINER_ORDER_TOP,
|
||||
})
|
||||
public @interface ContainerOrder {}
|
||||
|
||||
/**
|
||||
@@ -65,10 +64,13 @@ public final class TransitionFilter implements Parcelable {
|
||||
/** All flags must NOT be set on a transition. */
|
||||
public @WindowManager.TransitionFlags int mNotFlags = 0;
|
||||
|
||||
/** A list of required changes. To pass, a transition must meet all requirements. */
|
||||
/**
|
||||
* A list of required changes. To pass, a transition must meet all requirements.
|
||||
*/
|
||||
@Nullable public Requirement[] mRequirements = null;
|
||||
|
||||
public TransitionFilter() {}
|
||||
public TransitionFilter() {
|
||||
}
|
||||
|
||||
private TransitionFilter(Parcel in) {
|
||||
mTypeSet = in.createIntArray();
|
||||
@@ -77,9 +79,7 @@ public final class TransitionFilter implements Parcelable {
|
||||
mRequirements = in.createTypedArray(Requirement.CREATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if `info` meets all the requirements to pass this filter.
|
||||
*/
|
||||
/** @return true if `info` meets all the requirements to pass this filter. */
|
||||
public boolean matches(@NonNull TransitionInfo info) {
|
||||
if (mTypeSet != null) {
|
||||
// non-null typeset, so make sure info is one of the types.
|
||||
@@ -184,7 +184,14 @@ public final class TransitionFilter implements Parcelable {
|
||||
public ComponentName mTopActivity;
|
||||
public IBinder mLaunchCookie;
|
||||
|
||||
public Requirement() {}
|
||||
/** If non-null, requires the change to specifically have or not-have a custom animation. */
|
||||
public Boolean mCustomAnimation = null;
|
||||
public IBinder mTaskFragmentToken = null;
|
||||
|
||||
public int mWindowingMode = WINDOWING_MODE_UNDEFINED;
|
||||
|
||||
public Requirement() {
|
||||
}
|
||||
|
||||
private Requirement(Parcel in) {
|
||||
mActivityType = in.readInt();
|
||||
@@ -196,12 +203,23 @@ public final class TransitionFilter implements Parcelable {
|
||||
mOrder = in.readInt();
|
||||
mTopActivity = in.readTypedObject(ComponentName.CREATOR);
|
||||
mLaunchCookie = in.readStrongBinder();
|
||||
// 0: null, 1: false, 2: true
|
||||
final int customAnimRaw = in.readInt();
|
||||
mCustomAnimation = customAnimRaw == 0 ? null : Boolean.valueOf(customAnimRaw == 2);
|
||||
mTaskFragmentToken = in.readStrongBinder();
|
||||
mWindowingMode = in.readInt();
|
||||
}
|
||||
|
||||
/** Go through changes and find if at-least one change matches this filter */
|
||||
boolean matches(@NonNull TransitionInfo info) {
|
||||
for (int i = info.getChanges().size() - 1; i >= 0; --i) {
|
||||
final TransitionInfo.Change change = info.getChanges().get(i);
|
||||
|
||||
if (mTaskFragmentToken != null
|
||||
&& !mTaskFragmentToken.equals(change.getTaskFragmentToken())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mMustBeIndependent && !TransitionInfo.isIndependent(change, info)) {
|
||||
// Only look at independent animating windows.
|
||||
continue;
|
||||
@@ -237,13 +255,33 @@ public final class TransitionFilter implements Parcelable {
|
||||
if (!matchesCookie(change.getTaskInfo())) {
|
||||
continue;
|
||||
}
|
||||
if (mCustomAnimation != null
|
||||
// only applies to activity/task
|
||||
&& (change.getTaskInfo() != null
|
||||
|| change.getActivityComponent() != null)) {
|
||||
final TransitionInfo.AnimationOptions opts = change.getAnimationOptions();
|
||||
if (opts != null) {
|
||||
boolean canActuallyOverride = change.getTaskInfo() == null
|
||||
|| opts.getOverrideTaskTransition();
|
||||
if (mCustomAnimation != canActuallyOverride) {
|
||||
continue;
|
||||
}
|
||||
} else if (mCustomAnimation) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (mWindowingMode != WINDOWING_MODE_UNDEFINED) {
|
||||
if (change.getTaskInfo() == null
|
||||
|| change.getTaskInfo().getWindowingMode() != mWindowingMode) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean matchesTopActivity(
|
||||
ActivityManager.RunningTaskInfo taskInfo,
|
||||
private boolean matchesTopActivity(ActivityManager.RunningTaskInfo taskInfo,
|
||||
@Nullable ComponentName activityComponent) {
|
||||
if (mTopActivity == null) return true;
|
||||
if (activityComponent != null) {
|
||||
@@ -287,6 +325,10 @@ public final class TransitionFilter implements Parcelable {
|
||||
dest.writeInt(mOrder);
|
||||
dest.writeTypedObject(mTopActivity, flags);
|
||||
dest.writeStrongBinder(mLaunchCookie);
|
||||
int customAnimRaw = mCustomAnimation == null ? 0 : (mCustomAnimation ? 2 : 1);
|
||||
dest.writeInt(customAnimRaw);
|
||||
dest.writeStrongBinder(mTaskFragmentToken);
|
||||
dest.writeInt(mWindowingMode);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@@ -328,6 +370,14 @@ public final class TransitionFilter implements Parcelable {
|
||||
out.append(" order=" + containerOrderToString(mOrder));
|
||||
out.append(" topActivity=").append(mTopActivity);
|
||||
out.append(" launchCookie=").append(mLaunchCookie);
|
||||
if (mCustomAnimation != null) {
|
||||
out.append(" customAnim=").append(mCustomAnimation.booleanValue());
|
||||
}
|
||||
if (mTaskFragmentToken != null) {
|
||||
out.append(" taskFragmentToken=").append(mTaskFragmentToken);
|
||||
}
|
||||
out.append(" windowingMode="
|
||||
+ WindowConfiguration.windowingModeToString(mWindowingMode));
|
||||
out.append("}");
|
||||
return out.toString();
|
||||
}
|
||||
@@ -335,10 +385,8 @@ public final class TransitionFilter implements Parcelable {
|
||||
|
||||
private static String containerOrderToString(int order) {
|
||||
switch (order) {
|
||||
case CONTAINER_ORDER_ANY:
|
||||
return "ANY";
|
||||
case CONTAINER_ORDER_TOP:
|
||||
return "TOP";
|
||||
case CONTAINER_ORDER_ANY: return "ANY";
|
||||
case CONTAINER_ORDER_TOP: return "TOP";
|
||||
}
|
||||
return "UNKNOWN(" + order + ")";
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.window;
|
||||
|
||||
parcelable TransitionInfo;
|
||||
parcelable TransitionInfo.Change;
|
||||
parcelable TransitionInfo.Change;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -33,4 +33,4 @@ parcelable WindowAnimationState {
|
||||
float bottomRightRadius;
|
||||
float bottomLeftRadius;
|
||||
PointF velocityPxPerMs;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import android.app.ActivityManager;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Rect;
|
||||
import android.view.IRecentsAnimationController;
|
||||
import com.android.wm.shell.recents.IRecentsAnimationController;
|
||||
import android.window.TaskSnapshot;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
package app.lawnchair.compatlib;
|
||||
|
||||
import android.graphics.Rect;
|
||||
import android.view.IRecentsAnimationController;
|
||||
import com.android.wm.shell.recents.IRecentsAnimationController;
|
||||
import android.view.RemoteAnimationTarget;
|
||||
import android.window.TaskSnapshot;
|
||||
|
||||
public interface RecentsAnimationRunnerCompat {
|
||||
|
||||
void onAnimationStart(
|
||||
IRecentsAnimationController controller,
|
||||
Object controller,
|
||||
RemoteAnimationTarget[] apps,
|
||||
RemoteAnimationTarget[] wallpapers,
|
||||
Rect homeContentInsets,
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
package com.android.wm.shell.recents;
|
||||
parcelable IRecentsAnimationController;
|
||||
Reference in New Issue
Block a user