mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-02-27 15:26:58 +00:00
fixed issue applying lawnchair as recents provider in A15
- fixed animation app to home - action buttons in recents
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* Copyright (c) 2019, The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.view;
|
||||
|
||||
import android.graphics.Region;
|
||||
|
||||
/**
|
||||
* Listener for changes to the system gesture exclusion region
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
oneway interface ISystemGestureExclusionListener {
|
||||
/**
|
||||
* Called when the system gesture exclusion for the given display changed.
|
||||
* @param displayId the display whose system gesture exclusion changed
|
||||
* @param systemGestureExclusion a {@code Region} where the app would like priority over the
|
||||
* system gestures, in display coordinates. Certain restrictions
|
||||
* might be applied such that apps don't get all the exclusions
|
||||
* they request.
|
||||
* @param systemGestureExclusionUnrestricted a {@code Region} where the app would like priority
|
||||
* over the system gestures, in display coordinates, without
|
||||
* any restrictions applied. Null if no restrictions have been
|
||||
* applied.
|
||||
*/
|
||||
void onSystemGestureExclusionChanged(int displayId, in Region systemGestureExclusion,
|
||||
in Region systemGestureExclusionUnrestricted);
|
||||
}
|
||||
411
compatLib/src/main/java/android/view/InsetsFrameProvider.java
Normal file
411
compatLib/src/main/java/android/view/InsetsFrameProvider.java
Normal file
@@ -0,0 +1,411 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.view;
|
||||
|
||||
import android.annotation.IntRange;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.graphics.Insets;
|
||||
import android.graphics.Rect;
|
||||
import android.os.IBinder;
|
||||
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
|
||||
* 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.
|
||||
* @hide
|
||||
*/
|
||||
public class InsetsFrameProvider implements Parcelable {
|
||||
|
||||
/**
|
||||
* Uses the display frame as the source.
|
||||
*/
|
||||
public static final int SOURCE_DISPLAY = 0;
|
||||
|
||||
/**
|
||||
* Uses the window bounds as the source.
|
||||
*/
|
||||
public static final int SOURCE_CONTAINER_BOUNDS = 1;
|
||||
|
||||
/**
|
||||
* Uses the window frame as the source.
|
||||
*/
|
||||
public static final int SOURCE_FRAME = 2;
|
||||
|
||||
/**
|
||||
* Uses {@link #mArbitraryRectangle} as the source.
|
||||
*/
|
||||
public static final int SOURCE_ARBITRARY_RECTANGLE = 3;
|
||||
|
||||
private final int mId;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
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).
|
||||
*/
|
||||
private Insets mInsetsSize = null;
|
||||
|
||||
/**
|
||||
* Various behavioral options/flags. Default is none.
|
||||
*
|
||||
* @see Flags
|
||||
*/
|
||||
private @Flags int mFlags;
|
||||
|
||||
/**
|
||||
* If null, the size set in insetsSize will be applied to all window types. If it contains
|
||||
* element of some types, the insets reported to the window with that types will be overridden.
|
||||
*/
|
||||
private InsetsSizeOverride[] mInsetsSizeOverrides = null;
|
||||
|
||||
/**
|
||||
* This field, if set, is indicating the insets needs to be at least the given size inside the
|
||||
* display cutout safe area. This will be compared to the insets size calculated based on other
|
||||
* attributes, and will be applied when this is larger. This is independent of the
|
||||
* PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT in LayoutParams, as this is not going to change
|
||||
* 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.
|
||||
*/
|
||||
private Insets mMinimalInsetsSizeInDisplayCutoutSafe = null;
|
||||
|
||||
/**
|
||||
* Indicates the bounding rectangles within the provided insets frame, in relative coordinates
|
||||
* to the source frame.
|
||||
*/
|
||||
private Rect[] mBoundingRects = null;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @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].
|
||||
* @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) {
|
||||
mId = InsetsSource.createId(owner, index, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an unique integer which identifies the insets source.
|
||||
*/
|
||||
public int getId() {
|
||||
return mId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index specified in {@link #InsetsFrameProvider(IBinder, int, int)}.
|
||||
*/
|
||||
public int getIndex() {
|
||||
return InsetsSource.getIndex(mId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link InsetsType} specified in {@link #InsetsFrameProvider(IBinder, int, int)}.
|
||||
*/
|
||||
public int getType() {
|
||||
return InsetsSource.getType(mId);
|
||||
}
|
||||
|
||||
public InsetsFrameProvider setSource(int source) {
|
||||
mSource = source;
|
||||
return this;
|
||||
}
|
||||
|
||||
public int getSource() {
|
||||
return mSource;
|
||||
}
|
||||
|
||||
public InsetsFrameProvider setFlags(@Flags int flags, @Flags int mask) {
|
||||
mFlags = (mFlags & ~mask) | (flags & mask);
|
||||
return this;
|
||||
}
|
||||
|
||||
public @Flags int getFlags() {
|
||||
return mFlags;
|
||||
}
|
||||
|
||||
public boolean hasFlags(@Flags int mask) {
|
||||
return (mFlags & mask) == mask;
|
||||
}
|
||||
|
||||
public InsetsFrameProvider setInsetsSize(Insets insetsSize) {
|
||||
mInsetsSize = insetsSize;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Insets getInsetsSize() {
|
||||
return mInsetsSize;
|
||||
}
|
||||
|
||||
public InsetsFrameProvider setArbitraryRectangle(Rect rect) {
|
||||
mArbitraryRectangle = new Rect(rect);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Rect getArbitraryRectangle() {
|
||||
return mArbitraryRectangle;
|
||||
}
|
||||
|
||||
public InsetsFrameProvider setInsetsSizeOverrides(InsetsSizeOverride[] insetsSizeOverrides) {
|
||||
mInsetsSizeOverrides = insetsSizeOverrides;
|
||||
return this;
|
||||
}
|
||||
|
||||
public InsetsSizeOverride[] getInsetsSizeOverrides() {
|
||||
return mInsetsSizeOverrides;
|
||||
}
|
||||
|
||||
public InsetsFrameProvider setMinimalInsetsSizeInDisplayCutoutSafe(
|
||||
Insets minimalInsetsSizeInDisplayCutoutSafe) {
|
||||
mMinimalInsetsSizeInDisplayCutoutSafe = minimalInsetsSizeInDisplayCutoutSafe;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Insets getMinimalInsetsSizeInDisplayCutoutSafe() {
|
||||
return mMinimalInsetsSizeInDisplayCutoutSafe;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
@Nullable
|
||||
public Rect[] getBoundingRects() {
|
||||
return mBoundingRects;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder("InsetsFrameProvider: {");
|
||||
sb.append("id=#").append(Integer.toHexString(mId));
|
||||
sb.append(", index=").append(getIndex());
|
||||
sb.append(", type=").append(WindowInsets.Type.toString(getType()));
|
||||
sb.append(", source=").append(sourceToString(mSource));
|
||||
sb.append(", flags=[").append(InsetsSource.flagsToString(mFlags)).append("]");
|
||||
if (mInsetsSize != null) {
|
||||
sb.append(", insetsSize=").append(mInsetsSize);
|
||||
}
|
||||
if (mInsetsSizeOverrides != null) {
|
||||
sb.append(", insetsSizeOverrides=").append(Arrays.toString(mInsetsSizeOverrides));
|
||||
}
|
||||
if (mArbitraryRectangle != null) {
|
||||
sb.append(", mArbitraryRectangle=").append(mArbitraryRectangle.toShortString());
|
||||
}
|
||||
if (mMinimalInsetsSizeInDisplayCutoutSafe != null) {
|
||||
sb.append(", mMinimalInsetsSizeInDisplayCutoutSafe=")
|
||||
.append(mMinimalInsetsSizeInDisplayCutoutSafe);
|
||||
}
|
||||
if (mBoundingRects != null) {
|
||||
sb.append(", mBoundingRects=").append(Arrays.toString(mBoundingRects));
|
||||
}
|
||||
sb.append("}");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static String sourceToString(int source) {
|
||||
switch (source) {
|
||||
case SOURCE_DISPLAY:
|
||||
return "DISPLAY";
|
||||
case SOURCE_CONTAINER_BOUNDS:
|
||||
return "CONTAINER_BOUNDS";
|
||||
case SOURCE_FRAME:
|
||||
return "FRAME";
|
||||
case SOURCE_ARBITRARY_RECTANGLE:
|
||||
return "ARBITRARY_RECTANGLE";
|
||||
}
|
||||
return "UNDEFINED";
|
||||
}
|
||||
|
||||
public InsetsFrameProvider(Parcel in) {
|
||||
mId = in.readInt();
|
||||
mSource = in.readInt();
|
||||
mFlags = in.readInt();
|
||||
mInsetsSize = in.readTypedObject(Insets.CREATOR);
|
||||
mInsetsSizeOverrides = in.createTypedArray(InsetsSizeOverride.CREATOR);
|
||||
mArbitraryRectangle = in.readTypedObject(Rect.CREATOR);
|
||||
mMinimalInsetsSizeInDisplayCutoutSafe = in.readTypedObject(Insets.CREATOR);
|
||||
mBoundingRects = in.createTypedArray(Rect.CREATOR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
out.writeInt(mId);
|
||||
out.writeInt(mSource);
|
||||
out.writeInt(mFlags);
|
||||
out.writeTypedObject(mInsetsSize, flags);
|
||||
out.writeTypedArray(mInsetsSizeOverrides, flags);
|
||||
out.writeTypedObject(mArbitraryRectangle, flags);
|
||||
out.writeTypedObject(mMinimalInsetsSizeInDisplayCutoutSafe, flags);
|
||||
out.writeTypedArray(mBoundingRects, flags);
|
||||
}
|
||||
|
||||
public boolean idEquals(InsetsFrameProvider o) {
|
||||
return mId == o.mId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final InsetsFrameProvider other = (InsetsFrameProvider) o;
|
||||
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,
|
||||
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));
|
||||
}
|
||||
|
||||
public static final @NonNull Parcelable.Creator<InsetsFrameProvider> CREATOR =
|
||||
new Parcelable.Creator<>() {
|
||||
@Override
|
||||
public InsetsFrameProvider createFromParcel(Parcel in) {
|
||||
return new InsetsFrameProvider(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InsetsFrameProvider[] newArray(int size) {
|
||||
return new InsetsFrameProvider[size];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* 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 {
|
||||
|
||||
private final int mWindowType;
|
||||
private final Insets mInsetsSize;
|
||||
|
||||
protected InsetsSizeOverride(Parcel in) {
|
||||
mWindowType = in.readInt();
|
||||
mInsetsSize = in.readTypedObject(Insets.CREATOR);
|
||||
}
|
||||
|
||||
public InsetsSizeOverride(int windowType, Insets insetsSize) {
|
||||
mWindowType = windowType;
|
||||
mInsetsSize = insetsSize;
|
||||
}
|
||||
public int getWindowType() {
|
||||
return mWindowType;
|
||||
}
|
||||
|
||||
public Insets getInsetsSize() {
|
||||
return mInsetsSize;
|
||||
}
|
||||
|
||||
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 int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
out.writeInt(mWindowType);
|
||||
out.writeTypedObject(mInsetsSize, flags);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder(32);
|
||||
sb.append("TypedInsetsSize: {");
|
||||
sb.append("windowType=").append(ViewDebug.intToString(
|
||||
WindowManager.LayoutParams.class, "type", mWindowType));
|
||||
sb.append(", insetsSize=").append(mInsetsSize);
|
||||
sb.append("}");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(mWindowType, mInsetsSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,7 @@ package android.window;
|
||||
import android.view.SurfaceControl;
|
||||
import android.window.IRemoteTransitionFinishedCallback;
|
||||
import android.window.TransitionInfo;
|
||||
import android.window.WindowAnimationState;
|
||||
|
||||
/**
|
||||
* Interface allowing remote processes to play transition animations.
|
||||
@@ -36,7 +37,6 @@ import android.window.TransitionInfo;
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
|
||||
oneway interface IRemoteTransition {
|
||||
/**
|
||||
* Starts a transition animation. Once complete, the implementation should call
|
||||
@@ -46,6 +46,7 @@ oneway interface IRemoteTransition {
|
||||
*/
|
||||
void startAnimation(in IBinder token, in TransitionInfo info, in SurfaceControl.Transaction t,
|
||||
in IRemoteTransitionFinishedCallback finishCallback);
|
||||
|
||||
/**
|
||||
* Attempts to merge a transition animation into the animation that is currently
|
||||
* being played by this remote. If merge is not possible/supported, this should be a no-op.
|
||||
@@ -59,4 +60,25 @@ oneway interface IRemoteTransition {
|
||||
void mergeAnimation(in IBinder transition, in TransitionInfo info,
|
||||
in SurfaceControl.Transaction t, in IBinder mergeTarget,
|
||||
in IRemoteTransitionFinishedCallback finishCallback);
|
||||
|
||||
/**
|
||||
* Takes over the animation of the windows from an existing transition. Once complete, the
|
||||
* implementation should call `finishCallback`.
|
||||
*
|
||||
* @param transition An identifier for the transition to be taken over.
|
||||
* @param states The animation states of the windows involved in the transition. These must be
|
||||
* sorted in the same way as the Changes inside `info`, and each state may be
|
||||
* null.
|
||||
*/
|
||||
void takeOverAnimation(in IBinder transition, in TransitionInfo info,
|
||||
in SurfaceControl.Transaction t, in IRemoteTransitionFinishedCallback finishCallback,
|
||||
in WindowAnimationState[] states);
|
||||
|
||||
/**
|
||||
* Called when a different handler has consumed the transition
|
||||
*
|
||||
* @param transition An identifier for the transition that was consumed.
|
||||
* @param aborted Whether the transition is aborted or not.
|
||||
*/
|
||||
void onTransitionConsumed(in IBinder transition, in boolean aborted);
|
||||
}
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.window;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
@@ -5,16 +21,14 @@ import android.annotation.Nullable;
|
||||
import android.app.IApplicationThread;
|
||||
import android.os.IBinder;
|
||||
import android.os.Parcelable;
|
||||
import com.android.internal.util.DataClass;
|
||||
|
||||
/**
|
||||
* Represents a remote transition animation and information required to run it (eg. the app thread
|
||||
* that needs to be boosted).
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@DataClass(genToString = true, genSetters = true, genAidl = true)
|
||||
public class RemoteTransition implements Parcelable {
|
||||
public final class RemoteTransition implements Parcelable {
|
||||
|
||||
/** The actual remote-transition interface used to run the transition animation. */
|
||||
private @NonNull IRemoteTransition mRemoteTransition;
|
||||
|
||||
@@ -24,14 +38,20 @@ public class RemoteTransition implements Parcelable {
|
||||
/** A name for this that can be used for debugging. */
|
||||
private @Nullable String mDebugName;
|
||||
|
||||
/** Constructs with no app thread (animation runs in shell). */
|
||||
/**
|
||||
* Constructs with no app thread (animation runs in shell).
|
||||
* @hide
|
||||
*/
|
||||
public RemoteTransition(@NonNull IRemoteTransition remoteTransition) {
|
||||
this(remoteTransition, null /* appThread */, null /* debugName */);
|
||||
}
|
||||
|
||||
/** Constructs with no app thread (animation runs in shell). */
|
||||
public RemoteTransition(
|
||||
@NonNull IRemoteTransition remoteTransition, @Nullable String debugName) {
|
||||
/**
|
||||
* Constructs with no app thread (animation runs in shell).
|
||||
* @hide
|
||||
*/
|
||||
public RemoteTransition(@NonNull IRemoteTransition remoteTransition,
|
||||
@Nullable String debugName) {
|
||||
this(remoteTransition, null /* appThread */, debugName);
|
||||
}
|
||||
|
||||
@@ -40,26 +60,17 @@ public class RemoteTransition implements Parcelable {
|
||||
return mRemoteTransition.asBinder();
|
||||
}
|
||||
|
||||
// Code below generated by codegen v1.0.23.
|
||||
//
|
||||
// DO NOT MODIFY!
|
||||
// CHECKSTYLE:OFF Generated code
|
||||
//
|
||||
// To regenerate run:
|
||||
// $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/window/RemoteTransition.java
|
||||
//
|
||||
// To exclude the generated code from IntelliJ auto-formatting enable (one-time):
|
||||
// Settings > Editor > Code Style > Formatter Control
|
||||
// @formatter:off
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public RemoteTransition(
|
||||
@NonNull IRemoteTransition remoteTransition,
|
||||
@Nullable IApplicationThread appThread,
|
||||
@@ -69,29 +80,37 @@ public class RemoteTransition implements Parcelable {
|
||||
NonNull.class, null, mRemoteTransition);
|
||||
this.mAppThread = appThread;
|
||||
this.mDebugName = debugName;
|
||||
|
||||
// onConstructed(); // You can define this method to get a callback
|
||||
}
|
||||
|
||||
/** The actual remote-transition interface used to run the transition animation. */
|
||||
@DataClass.Generated.Member
|
||||
/**
|
||||
* The actual remote-transition interface used to run the transition animation.
|
||||
* @hide
|
||||
*/
|
||||
public @NonNull IRemoteTransition getRemoteTransition() {
|
||||
return mRemoteTransition;
|
||||
}
|
||||
|
||||
/** The application thread that will be running the remote transition. */
|
||||
@DataClass.Generated.Member
|
||||
/**
|
||||
* 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. */
|
||||
@DataClass.Generated.Member
|
||||
/**
|
||||
* 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. */
|
||||
@DataClass.Generated.Member
|
||||
/**
|
||||
* The actual remote-transition interface used to run the transition animation.
|
||||
* @hide
|
||||
*/
|
||||
public @NonNull RemoteTransition setRemoteTransition(@NonNull IRemoteTransition value) {
|
||||
mRemoteTransition = value;
|
||||
com.android.internal.util.AnnotationValidations.validate(
|
||||
@@ -99,42 +118,40 @@ public class RemoteTransition implements Parcelable {
|
||||
return this;
|
||||
}
|
||||
|
||||
/** The application thread that will be running the remote transition. */
|
||||
@DataClass.Generated.Member
|
||||
/**
|
||||
* The application thread that will be running the remote transition.
|
||||
* @hide
|
||||
*/
|
||||
public @NonNull RemoteTransition setAppThread(@NonNull IApplicationThread value) {
|
||||
mAppThread = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** A name for this that can be used for debugging. */
|
||||
@DataClass.Generated.Member
|
||||
/**
|
||||
* A name for this that can be used for debugging.
|
||||
*/
|
||||
public @NonNull RemoteTransition setDebugName(@NonNull String value) {
|
||||
mDebugName = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@DataClass.Generated.Member
|
||||
public String toString() {
|
||||
// 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
|
||||
@DataClass.Generated.Member
|
||||
public void writeToParcel(@NonNull android.os.Parcel dest, int flags) {
|
||||
// You can override field parcelling by defining methods like:
|
||||
// void parcelFieldName(Parcel dest, int flags) { ... }
|
||||
|
||||
byte flg = 0;
|
||||
if (mAppThread != null) flg |= 0x2;
|
||||
if (mDebugName != null) flg |= 0x4;
|
||||
@@ -145,55 +162,36 @@ public class RemoteTransition implements Parcelable {
|
||||
}
|
||||
|
||||
@Override
|
||||
@DataClass.Generated.Member
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
public int describeContents() { return 0; }
|
||||
|
||||
/** @hide */
|
||||
@SuppressWarnings({"unchecked", "RedundantCast"})
|
||||
@DataClass.Generated.Member
|
||||
protected RemoteTransition(@NonNull android.os.Parcel in) {
|
||||
// You can override field unparcelling by defining methods like:
|
||||
// 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;
|
||||
com.android.internal.util.AnnotationValidations.validate(
|
||||
NonNull.class, null, mRemoteTransition);
|
||||
this.mAppThread = appThread;
|
||||
this.mDebugName = debugName;
|
||||
// onConstructed(); // You can define this method to get a callback
|
||||
}
|
||||
|
||||
@DataClass.Generated.Member
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
@DataClass.Generated(
|
||||
time = 1678926409863L,
|
||||
codegenVersion = "1.0.23",
|
||||
sourceFile = "frameworks/base/core/java/android/window/RemoteTransition.java",
|
||||
inputSignatures =
|
||||
"private @android.annotation.NonNull android.window.IRemoteTransition mRemoteTransition\nprivate @android.annotation.Nullable android.app.IApplicationThread mAppThread\nprivate @android.annotation.Nullable java.lang.String mDebugName\npublic @android.annotation.Nullable android.os.IBinder asBinder()\nclass RemoteTransition extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genSetters=true, genAidl=true)")
|
||||
@Deprecated
|
||||
private void __metadata() {}
|
||||
// @formatter:on
|
||||
// End of generated code
|
||||
}
|
||||
@Override
|
||||
public RemoteTransition createFromParcel(@NonNull android.os.Parcel in) {
|
||||
return new RemoteTransition(in);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package android.window;
|
||||
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.view.SurfaceControl;
|
||||
|
||||
/**
|
||||
* Utility base implementation of {@link IRemoteTransition} that users can extend to avoid stubbing.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public abstract class RemoteTransitionStub extends IRemoteTransition.Stub {
|
||||
@Override
|
||||
public void mergeAnimation(IBinder transition, TransitionInfo info,
|
||||
SurfaceControl.Transaction t, IBinder mergeTarget,
|
||||
IRemoteTransitionFinishedCallback finishCallback) throws RemoteException {}
|
||||
|
||||
|
||||
@Override
|
||||
public void takeOverAnimation(IBinder transition, TransitionInfo info,
|
||||
SurfaceControl.Transaction startTransaction,
|
||||
IRemoteTransitionFinishedCallback finishCallback,
|
||||
WindowAnimationState[] states) throws RemoteException {
|
||||
throw new RemoteException("Takeovers are not supported by this IRemoteTransition");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onTransitionConsumed(IBinder transition, boolean aborted)
|
||||
throws RemoteException {}
|
||||
}
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.window;
|
||||
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
|
||||
@@ -24,30 +25,30 @@ import android.annotation.Nullable;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.WindowConfiguration;
|
||||
import android.content.ComponentName;
|
||||
import android.os.IBinder;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
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
|
||||
*/
|
||||
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 {}
|
||||
|
||||
/**
|
||||
@@ -62,10 +63,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();
|
||||
@@ -74,9 +78,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.
|
||||
@@ -179,8 +181,10 @@ public final class TransitionFilter implements Parcelable {
|
||||
|
||||
public @ContainerOrder int mOrder = CONTAINER_ORDER_ANY;
|
||||
public ComponentName mTopActivity;
|
||||
public IBinder mLaunchCookie;
|
||||
|
||||
public Requirement() {}
|
||||
public Requirement() {
|
||||
}
|
||||
|
||||
private Requirement(Parcel in) {
|
||||
mActivityType = in.readInt();
|
||||
@@ -191,6 +195,7 @@ public final class TransitionFilter implements Parcelable {
|
||||
mMustBeTask = in.readBoolean();
|
||||
mOrder = in.readInt();
|
||||
mTopActivity = in.readTypedObject(ComponentName.CREATOR);
|
||||
mLaunchCookie = in.readStrongBinder();
|
||||
}
|
||||
|
||||
/** Go through changes and find if at-least one change matches this filter */
|
||||
@@ -210,7 +215,9 @@ public final class TransitionFilter implements Parcelable {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!matchesTopActivity(change.getTaskInfo())) continue;
|
||||
if (!matchesTopActivity(change.getTaskInfo(), change.getActivityComponent())) {
|
||||
continue;
|
||||
}
|
||||
if (mModes != null) {
|
||||
boolean pass = false;
|
||||
for (int m = 0; m < mModes.length; ++m) {
|
||||
@@ -227,16 +234,34 @@ public final class TransitionFilter implements Parcelable {
|
||||
if (mMustBeTask && change.getTaskInfo() == null) {
|
||||
continue;
|
||||
}
|
||||
if (!matchesCookie(change.getTaskInfo())) {
|
||||
continue;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean matchesTopActivity(ActivityManager.RunningTaskInfo info) {
|
||||
private boolean matchesTopActivity(ActivityManager.RunningTaskInfo taskInfo,
|
||||
@Nullable ComponentName activityComponent) {
|
||||
if (mTopActivity == null) return true;
|
||||
if (activityComponent != null) {
|
||||
return mTopActivity.equals(activityComponent);
|
||||
} else if (taskInfo != null) {
|
||||
return mTopActivity.equals(taskInfo.topActivity);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean matchesCookie(ActivityManager.RunningTaskInfo info) {
|
||||
if (mLaunchCookie == null) return true;
|
||||
if (info == null) return false;
|
||||
final ComponentName component = info.topActivity;
|
||||
return mTopActivity.equals(component);
|
||||
for (IBinder cookie : info.launchCookies) {
|
||||
if (mLaunchCookie.equals(cookie)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Check if the request matches this filter. It may generate false positives */
|
||||
@@ -245,7 +270,8 @@ public final class TransitionFilter implements Parcelable {
|
||||
if (mActivityType == ACTIVITY_TYPE_UNDEFINED) return true;
|
||||
return request.getTriggerTask() != null
|
||||
&& request.getTriggerTask().getActivityType() == mActivityType
|
||||
&& matchesTopActivity(request.getTriggerTask());
|
||||
&& matchesTopActivity(request.getTriggerTask(), null /* activityCmp */)
|
||||
&& matchesCookie(request.getTriggerTask());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -259,6 +285,7 @@ public final class TransitionFilter implements Parcelable {
|
||||
dest.writeBoolean(mMustBeTask);
|
||||
dest.writeInt(mOrder);
|
||||
dest.writeTypedObject(mTopActivity, flags);
|
||||
dest.writeStrongBinder(mLaunchCookie);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@@ -299,6 +326,7 @@ public final class TransitionFilter implements Parcelable {
|
||||
out.append(" mustBeTask=" + mMustBeTask);
|
||||
out.append(" order=" + containerOrderToString(mOrder));
|
||||
out.append(" topActivity=").append(mTopActivity);
|
||||
out.append(" launchCookie=").append(mLaunchCookie);
|
||||
out.append("}");
|
||||
return out.toString();
|
||||
}
|
||||
@@ -306,11 +334,9 @@ 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 + ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -14,6 +14,23 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.wm.shell.common.bubbles;
|
||||
package android.window;
|
||||
|
||||
parcelable BubbleBarLocation;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.RectF;
|
||||
|
||||
/**
|
||||
* Properties of a window animation at a given point in time.
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
parcelable WindowAnimationState {
|
||||
long timestamp;
|
||||
RectF bounds;
|
||||
float scale;
|
||||
float topLeftRadius;
|
||||
float topRightRadius;
|
||||
float bottomRightRadius;
|
||||
float bottomLeftRadius;
|
||||
PointF velocityPxPerMs;
|
||||
}
|
||||
139
lawnchair/res/layout/overview_actions_container.xml
Normal file
139
lawnchair/res/layout/overview_actions_container.xml
Normal file
@@ -0,0 +1,139 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2020 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.
|
||||
-->
|
||||
<!-- NOTE! don't add dimensions for margins / gravity to root view in this file, they need to be
|
||||
loaded at runtime. -->
|
||||
<app.lawnchair.overview.LawnchairOverviewActionsView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal|bottom">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/action_buttons"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/overview_actions_height"
|
||||
android:layout_gravity="bottom|center_horizontal"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Space
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="1dp"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<app.lawnchair.views.CustomButton
|
||||
android:id="@+id/action_screenshot"
|
||||
style="@style/OverviewActionButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawableStart="@drawable/ic_screenshot"
|
||||
android:text="@string/action_screenshot" />
|
||||
|
||||
<Space
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="1dp"
|
||||
android:layout_weight="1"
|
||||
android:visibility="gone" />
|
||||
|
||||
<app.lawnchair.views.CustomButton
|
||||
android:id="@+id/action_share"
|
||||
style="@style/OverviewActionButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawableStart="@drawable/ic_share"
|
||||
android:text="@string/action_share" />
|
||||
|
||||
<Space
|
||||
android:id="@+id/oav_three_button_space"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="1dp"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/action_split"
|
||||
style="@style/OverviewActionButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/action_split"
|
||||
android:theme="@style/ThemeControlHighlightWorkspaceColor"
|
||||
android:visibility="gone" />
|
||||
|
||||
<Space
|
||||
android:id="@+id/action_split_space"
|
||||
android:layout_width="@dimen/overview_actions_button_spacing"
|
||||
android:layout_height="1dp"
|
||||
android:visibility="gone" />
|
||||
|
||||
<app.lawnchair.views.CustomButton
|
||||
android:id="@+id/action_lens"
|
||||
style="@style/OverviewActionButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawableStart="@drawable/ic_lens"
|
||||
android:text="@string/action_lens" />
|
||||
|
||||
<Space
|
||||
android:id="@+id/lens_space"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="1dp"
|
||||
android:layout_weight="1"
|
||||
android:visibility="gone" />
|
||||
|
||||
<app.lawnchair.views.CustomButton
|
||||
style="@style/OverviewActionButton"
|
||||
android:id="@+id/action_clear_all"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/recents_clear_all"
|
||||
android:drawableStart="@drawable/ic_clear_all_recents"
|
||||
android:visibility="gone"
|
||||
/>
|
||||
|
||||
<Space
|
||||
android:id="@+id/clear_all_space"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="1dp"
|
||||
android:layout_weight="1"
|
||||
android:visibility="gone" />
|
||||
|
||||
<app.lawnchair.views.CustomButton
|
||||
style="@style/OverviewActionButton"
|
||||
android:id="@+id/action_locked"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/action_lock"
|
||||
android:drawableStart="@drawable/ic_locked_recents"
|
||||
android:visibility="gone" />
|
||||
|
||||
<Space
|
||||
android:id="@+id/locked_space"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="1dp"
|
||||
android:layout_weight="1"
|
||||
android:visibility="gone" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<app.lawnchair.views.CustomButton
|
||||
android:id="@+id/action_save_app_pair"
|
||||
style="@style/OverviewActionButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/action_save_app_pair"
|
||||
android:layout_gravity="bottom|center_horizontal"
|
||||
android:visibility="gone" />
|
||||
|
||||
</app.lawnchair.overview.LawnchairOverviewActionsView>
|
||||
@@ -40,7 +40,7 @@
|
||||
<string name="clock_component_name" translatable="false">com.google.android.deskclock/com.android.deskclock.DeskClock</string>
|
||||
<string name="launcher_activity_logic_class" translatable="false">app.lawnchair.LauncherActivityCachingLogic</string>
|
||||
<string name="main_process_initializer_class" translatable="false">app.lawnchair.LawnchairProcessInitializer</string>
|
||||
<!-- <string name="task_overlay_factory_class" translatable="false">app.lawnchair.overview.TaskOverlayFactoryImpl</string>-->
|
||||
<string name="task_overlay_factory_class" translatable="false">app.lawnchair.overview.TaskOverlayFactoryImpl</string>
|
||||
<string name="wallpaper_picker_package" translatable="false">com.android.wallpaper</string>
|
||||
<string name="wallpaper_picker_package_alt" translatable="false">com.google.android.apps.wallpaper</string>
|
||||
<string name="widget_holder_factory_class" translatable="false">app.lawnchair.factory.LawnchairWidgetHolder$LawnchairHolderFactory</string>
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
package app.lawnchair.overview
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
import android.widget.Button
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.Space
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.isVisible
|
||||
import app.lawnchair.preferences.PreferenceManager
|
||||
import app.lawnchair.util.isOnePlusStock
|
||||
import com.android.launcher3.R
|
||||
import com.android.quickstep.views.OverviewActionsView
|
||||
|
||||
class LawnchairOverviewActionsView @JvmOverloads constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
defStyleAttr: Int = 0,
|
||||
) : OverviewActionsView<TaskOverlayFactoryImpl.OverlayUICallbacks>(context, attrs, defStyleAttr) {
|
||||
|
||||
private val prefs = PreferenceManager.getInstance(context)
|
||||
private lateinit var container: LinearLayout
|
||||
private lateinit var screenshotAction: Button
|
||||
private lateinit var shareAction: Button
|
||||
private lateinit var lensAction: Button
|
||||
private lateinit var clearAllAction: Button
|
||||
private lateinit var lockedAction: Button
|
||||
|
||||
override fun onFinishInflate() {
|
||||
super.onFinishInflate()
|
||||
|
||||
container = ViewCompat.requireViewById(this, R.id.action_buttons)
|
||||
clearAllAction = ViewCompat.requireViewById(this, R.id.action_clear_all)
|
||||
shareAction = ViewCompat.requireViewById(this, R.id.action_share)
|
||||
lensAction = ViewCompat.requireViewById(this, R.id.action_lens)
|
||||
screenshotAction = ViewCompat.requireViewById(this, R.id.action_screenshot)
|
||||
lockedAction = ViewCompat.requireViewById(this, R.id.action_locked)
|
||||
|
||||
shareAction.setOnClickListener { mCallbacks?.onShare() }
|
||||
lensAction.setOnClickListener { mCallbacks?.onLens() }
|
||||
|
||||
prefs.recentsActionClearAll.subscribeChanges(this, ::updateVisibilities)
|
||||
prefs.recentsActionLens.subscribeChanges(this, ::updateVisibilities)
|
||||
prefs.recentsActionScreenshot.subscribeChanges(this, ::updateVisibilities)
|
||||
prefs.recentsActionShare.subscribeChanges(this, ::updateVisibilities)
|
||||
prefs.recentsActionLocked.subscribeChanges(this, ::updateVisibilities)
|
||||
prefs.recentActionOrder.subscribeChanges(this, ::updateVisibilities)
|
||||
|
||||
updateVisibilities()
|
||||
}
|
||||
|
||||
private fun updateVisibilities() {
|
||||
val order = prefs.recentActionOrder.get().split(",").map { it.toInt() }
|
||||
|
||||
val buttonMap = mutableMapOf<Int, View>()
|
||||
if (prefs.recentsActionScreenshot.get() && !isOnePlusStock) {
|
||||
buttonMap[0] = screenshotAction
|
||||
}
|
||||
if (prefs.recentsActionShare.get()) {
|
||||
buttonMap[1] = shareAction
|
||||
}
|
||||
if (prefs.recentsActionLens.get() && isLensAvailable()) {
|
||||
buttonMap[2] = lensAction
|
||||
}
|
||||
if (prefs.recentsActionLocked.get()) {
|
||||
buttonMap[3] = lockedAction
|
||||
}
|
||||
if (prefs.recentsActionClearAll.get()) {
|
||||
buttonMap[4] = clearAllAction
|
||||
}
|
||||
|
||||
val buttonsInOrder = order.mapNotNull { buttonMap[it] }
|
||||
|
||||
container.removeAllViews()
|
||||
container.addView(createSpace())
|
||||
buttonsInOrder.forEach { view ->
|
||||
view.isVisible = true
|
||||
container.addView(view)
|
||||
container.addView(createSpace())
|
||||
}
|
||||
}
|
||||
|
||||
private fun isLensAvailable(): Boolean {
|
||||
val lensIntent = context.packageManager.getLaunchIntentForPackage("com.google.ar.lens")
|
||||
return lensIntent != null
|
||||
}
|
||||
|
||||
private fun createSpace(): View {
|
||||
return Space(context).apply {
|
||||
layoutParams = LinearLayout.LayoutParams(0, 1).apply { weight = 1f }
|
||||
}
|
||||
}
|
||||
|
||||
override fun setClearAllClickListener(clearAllClickListener: OnClickListener?) {
|
||||
clearAllAction.setOnClickListener(clearAllClickListener)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package app.lawnchair.overview
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Matrix
|
||||
import androidx.annotation.Keep
|
||||
import app.lawnchair.util.RecentHelper
|
||||
import app.lawnchair.util.TaskUtilLockState
|
||||
import com.android.quickstep.TaskOverlayFactory
|
||||
import com.android.quickstep.views.OverviewActionsView
|
||||
import com.android.quickstep.views.TaskView.TaskContainer
|
||||
import com.android.systemui.shared.recents.model.Task
|
||||
import com.android.systemui.shared.recents.model.ThumbnailData
|
||||
|
||||
@Keep
|
||||
class TaskOverlayFactoryImpl(@Suppress("UNUSED_PARAMETER") context: Context) : TaskOverlayFactory() {
|
||||
|
||||
override fun createOverlay(thumbnailView: TaskContainer) = TaskOverlay(thumbnailView)
|
||||
|
||||
class TaskOverlay(
|
||||
taskThumbnailView: TaskContainer,
|
||||
) : TaskOverlayFactory.TaskOverlay<LawnchairOverviewActionsView>(taskThumbnailView) {
|
||||
|
||||
override fun initOverlay(
|
||||
task: Task?,
|
||||
thumbnail: ThumbnailData?,
|
||||
matrix: Matrix,
|
||||
rotated: Boolean,
|
||||
) {
|
||||
actionsView.updateDisabledFlags(
|
||||
OverviewActionsView.DISABLED_NO_THUMBNAIL,
|
||||
thumbnail == null,
|
||||
)
|
||||
|
||||
if (thumbnail != null) {
|
||||
actionsView.updateDisabledFlags(OverviewActionsView.DISABLED_ROTATED, rotated)
|
||||
val isAllowedByPolicy = mTaskContainer.thumbnailViewDeprecated.isRealSnapshot
|
||||
actionsView.setCallbacks(OverlayUICallbacksImpl(isAllowedByPolicy, task))
|
||||
}
|
||||
}
|
||||
|
||||
private inner class OverlayUICallbacksImpl(
|
||||
isAllowedByPolicy: Boolean,
|
||||
task: Task?,
|
||||
) : TaskOverlayFactory.TaskOverlay<LawnchairOverviewActionsView>.OverlayUICallbacksImpl(
|
||||
isAllowedByPolicy,
|
||||
task,
|
||||
),
|
||||
OverlayUICallbacks {
|
||||
|
||||
override fun onShare() {
|
||||
if (mIsAllowedByPolicy) {
|
||||
endLiveTileMode { mImageApi.startShareActivity(null) }
|
||||
} else {
|
||||
showBlockedByPolicyMessage()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onLens() {
|
||||
if (mIsAllowedByPolicy) {
|
||||
endLiveTileMode { mImageApi.startLensActivity() }
|
||||
} else {
|
||||
showBlockedByPolicyMessage()
|
||||
}
|
||||
}
|
||||
override fun onLocked(context: Context, task: Task) {
|
||||
val isLocked = !RecentHelper.isAppLocked(task.key.packageName, context)
|
||||
TaskUtilLockState.setTaskLockState(
|
||||
context,
|
||||
task.key.component,
|
||||
isLocked,
|
||||
task.key,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sealed interface OverlayUICallbacks : TaskOverlayFactory.OverlayUICallbacks {
|
||||
fun onShare()
|
||||
fun onLens()
|
||||
fun onLocked(context: Context, task: Task)
|
||||
}
|
||||
}
|
||||
@@ -184,7 +184,7 @@ import app.lawnchair.compat.LawnchairQuickstepCompat;
|
||||
public class QuickstepTransitionManager implements OnDeviceProfileChangeListener {
|
||||
|
||||
private static final boolean ENABLE_SHELL_STARTING_SURFACE =
|
||||
SystemProperties.getBoolean("persist.debug.shell_starting_surface", true);
|
||||
SystemProperties.getBoolean("persist.debug.shell_starting_surface", false);
|
||||
|
||||
/** Duration of status bar animations. */
|
||||
public static final int STATUS_BAR_TRANSITION_DURATION = 120;
|
||||
|
||||
@@ -32,19 +32,14 @@ import android.view.ViewTreeObserver;
|
||||
import com.android.launcher3.BaseActivity;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.anim.PendingAnimation;
|
||||
import com.android.launcher3.statemanager.StateManager.StateHandler;
|
||||
import com.android.launcher3.states.StateAnimationConfig;
|
||||
import com.android.quickstep.util.BaseDepthController;
|
||||
import com.patrykmichalik.opto.core.PreferenceExtensionsKt;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import app.lawnchair.compat.LawnchairQuickstepCompat;
|
||||
import app.lawnchair.preferences2.PreferenceManager2;
|
||||
|
||||
/**
|
||||
* Controls blur and wallpaper zoom, for the Launcher surface only.
|
||||
*/
|
||||
@@ -62,25 +57,14 @@ public class DepthController extends BaseDepthController implements StateHandler
|
||||
|
||||
private View.OnAttachStateChangeListener mOnAttachListener;
|
||||
|
||||
private final boolean mEnableDepth;
|
||||
|
||||
public DepthController(Launcher l) {
|
||||
super(l);
|
||||
var pref = PreferenceManager2.getInstance(l).getWallpaperDepthEffect();
|
||||
mEnableDepth = PreferenceExtensionsKt.firstBlocking(pref);
|
||||
}
|
||||
|
||||
private void onLauncherDraw() {
|
||||
View view = mLauncher.getDragLayer();
|
||||
ViewRootImpl viewRootImpl = view.getViewRootImpl();
|
||||
try {
|
||||
if (Utilities.ATLEAST_Q) {
|
||||
setSurface(viewRootImpl != null ? viewRootImpl.getSurfaceControl() : null);
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
|
||||
}
|
||||
|
||||
setSurface(viewRootImpl != null ? viewRootImpl.getSurfaceControl() : null);
|
||||
view.post(() -> view.getViewTreeObserver().removeOnDrawListener(mOnDrawListener));
|
||||
}
|
||||
|
||||
@@ -90,13 +74,8 @@ public class DepthController extends BaseDepthController implements StateHandler
|
||||
mOnAttachListener = new View.OnAttachStateChangeListener() {
|
||||
@Override
|
||||
public void onViewAttachedToWindow(View view) {
|
||||
try {
|
||||
CrossWindowBlurListeners.getInstance().addListener(mLauncher.getMainExecutor(),
|
||||
mCrossWindowBlurListener);
|
||||
} catch (Throwable t) {
|
||||
// Ignore
|
||||
}
|
||||
|
||||
CrossWindowBlurListeners.getInstance().addListener(mLauncher.getMainExecutor(),
|
||||
mCrossWindowBlurListener);
|
||||
mLauncher.getScrimView().addOpaquenessListener(mOpaquenessListener);
|
||||
|
||||
// To handle the case where window token is invalid during last setDepth call.
|
||||
@@ -116,8 +95,7 @@ public class DepthController extends BaseDepthController implements StateHandler
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans up after this controller so it can be garbage collected without
|
||||
* leaving traces.
|
||||
* Cleans up after this controller so it can be garbage collected without leaving traces.
|
||||
*/
|
||||
public void dispose() {
|
||||
removeSecondaryListeners();
|
||||
@@ -130,11 +108,7 @@ public class DepthController extends BaseDepthController implements StateHandler
|
||||
|
||||
private void removeSecondaryListeners() {
|
||||
if (mCrossWindowBlurListener != null) {
|
||||
try {
|
||||
CrossWindowBlurListeners.getInstance().removeListener(mCrossWindowBlurListener);
|
||||
} catch (Throwable t) {
|
||||
// Ignore
|
||||
}
|
||||
CrossWindowBlurListeners.getInstance().removeListener(mCrossWindowBlurListener);
|
||||
}
|
||||
if (mOpaquenessListener != null) {
|
||||
mLauncher.getScrimView().removeOpaquenessListener(mOpaquenessListener);
|
||||
@@ -167,7 +141,7 @@ public class DepthController extends BaseDepthController implements StateHandler
|
||||
|
||||
@Override
|
||||
public void setStateWithAnimation(LauncherState toState, StateAnimationConfig config,
|
||||
PendingAnimation animation) {
|
||||
PendingAnimation animation) {
|
||||
if (config.hasAnimationFlag(SKIP_DEPTH_CONTROLLER)
|
||||
|| mIgnoreStateChangesDuringMultiWindowAnimation) {
|
||||
return;
|
||||
@@ -179,15 +153,9 @@ public class DepthController extends BaseDepthController implements StateHandler
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyDepthAndBlur() {
|
||||
try {
|
||||
if (LawnchairQuickstepCompat.ATLEAST_R && mEnableDepth) {
|
||||
ensureDependencies();
|
||||
super.applyDepthAndBlur();
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
// Ignore
|
||||
}
|
||||
protected void applyDepthAndBlur() {
|
||||
ensureDependencies();
|
||||
super.applyDepthAndBlur();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -201,7 +169,7 @@ public class DepthController extends BaseDepthController implements StateHandler
|
||||
mIgnoreStateChangesDuringMultiWindowAnimation = true;
|
||||
|
||||
ObjectAnimator mwAnimation = ObjectAnimator.ofFloat(stateDepth, MULTI_PROPERTY_VALUE,
|
||||
mLauncher.getStateManager().getState().getDepth(mLauncher, isInMultiWindowMode))
|
||||
mLauncher.getStateManager().getState().getDepth(mLauncher, isInMultiWindowMode))
|
||||
.setDuration(300);
|
||||
mwAnimation.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
@@ -225,5 +193,6 @@ public class DepthController extends BaseDepthController implements StateHandler
|
||||
writer.println(prefix + "\tmIgnoreStateChangesDuringMultiWindowAnimation="
|
||||
+ mIgnoreStateChangesDuringMultiWindowAnimation);
|
||||
writer.println(prefix + "\tmPauseBlurs=" + mPauseBlurs);
|
||||
writer.println(prefix + "\tmWaitingOnSurfaceValidity=" + mWaitingOnSurfaceValidity);
|
||||
}
|
||||
}
|
||||
@@ -59,7 +59,7 @@ import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import app.lawnchair.LawnchairApp;
|
||||
import app.lawnchair.icons.LawnchairIconProvider;
|
||||
import app.lawnchair.compat.LawnchairQuickstepCompat;
|
||||
|
||||
/**
|
||||
* Singleton class to load and manage recents model.
|
||||
@@ -68,10 +68,9 @@ import app.lawnchair.icons.LawnchairIconProvider;
|
||||
public class RecentsModel implements RecentTasksDataSource, IconChangeListener,
|
||||
TaskStackChangeListener, TaskVisualsChangeListener, SafeCloseable {
|
||||
|
||||
// We do not need any synchronization for this variable as its only written on
|
||||
// UI thread.
|
||||
public static final MainThreadInitializedObject<RecentsModel> INSTANCE = new MainThreadInitializedObject<>(
|
||||
RecentsModel::new);
|
||||
// We do not need any synchronization for this variable as its only written on UI thread.
|
||||
public static final MainThreadInitializedObject<RecentsModel> INSTANCE =
|
||||
new MainThreadInitializedObject<>(RecentsModel::new);
|
||||
|
||||
private static final Executor RECENTS_MODEL_EXECUTOR = Executors.newSingleThreadExecutor(
|
||||
new SimpleThreadFactory("TaskThumbnailIconCache-", THREAD_PRIORITY_BACKGROUND));
|
||||
@@ -104,12 +103,11 @@ public class RecentsModel implements RecentTasksDataSource, IconChangeListener,
|
||||
|
||||
@VisibleForTesting
|
||||
RecentsModel(Context context, RecentTasksList taskList, TaskIconCache iconCache,
|
||||
TaskThumbnailCache thumbnailCache, IconProvider iconProvider,
|
||||
TaskStackChangeListeners taskStackChangeListeners) {
|
||||
TaskThumbnailCache thumbnailCache, IconProvider iconProvider,
|
||||
TaskStackChangeListeners taskStackChangeListeners) {
|
||||
mContext = context;
|
||||
mTaskList = taskList;
|
||||
iconProvider = new LawnchairIconProvider(context);
|
||||
mIconCache = new TaskIconCache(context, RECENTS_MODEL_EXECUTOR, iconProvider);
|
||||
mIconCache = iconCache;
|
||||
mIconCache.registerTaskVisualsChangeListener(this);
|
||||
mThumbnailCache = thumbnailCache;
|
||||
if (enableGridOnlyOverview()) {
|
||||
@@ -144,13 +142,11 @@ public class RecentsModel implements RecentTasksDataSource, IconChangeListener,
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the list of recent tasks. Tasks are ordered by recency, with the
|
||||
* latest active tasks
|
||||
* Fetches the list of recent tasks. Tasks are ordered by recency, with the latest active tasks
|
||||
* at the end of the list.
|
||||
*
|
||||
* @param callback The callback to receive the task plan once its complete or
|
||||
* null. This is
|
||||
* always called on the UI thread.
|
||||
* @param callback The callback to receive the task plan once its complete or null. This is
|
||||
* always called on the UI thread.
|
||||
* @return the request id associated with this call.
|
||||
*/
|
||||
@Override
|
||||
@@ -162,12 +158,10 @@ public class RecentsModel implements RecentTasksDataSource, IconChangeListener,
|
||||
/**
|
||||
* Fetches the list of recent tasks, based on a filter
|
||||
*
|
||||
* @param callback The callback to receive the task plan once its complete or
|
||||
* null. This is
|
||||
* always called on the UI thread.
|
||||
* @param filter Returns true if a GroupTask should be included into the list
|
||||
* passed into
|
||||
* callback.
|
||||
* @param callback The callback to receive the task plan once its complete or null. This is
|
||||
* always called on the UI thread.
|
||||
* @param filter Returns true if a GroupTask should be included into the list passed into
|
||||
* callback.
|
||||
* @return the request id associated with this call.
|
||||
*/
|
||||
public int getTasks(@Nullable Consumer<List<GroupTask>> callback, Predicate<GroupTask> filter) {
|
||||
@@ -175,8 +169,7 @@ public class RecentsModel implements RecentTasksDataSource, IconChangeListener,
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Whether the provided {@param changeId} is the latest recent tasks
|
||||
* list id.
|
||||
* @return Whether the provided {@param changeId} is the latest recent tasks list id.
|
||||
*/
|
||||
public boolean isTaskListValid(int changeId) {
|
||||
return mTaskList.isTaskListValid(changeId);
|
||||
@@ -194,12 +187,10 @@ public class RecentsModel implements RecentTasksDataSource, IconChangeListener,
|
||||
* Checks if a task has been removed or not.
|
||||
*
|
||||
* @param callback Receives true if task is removed, false otherwise
|
||||
* @param filter Returns true if GroupTask should be in the list of
|
||||
* considerations
|
||||
* @param filter Returns true if GroupTask should be in the list of considerations
|
||||
*/
|
||||
public void isTaskRemoved(int taskId, Consumer<Boolean> callback, Predicate<GroupTask> filter) {
|
||||
// Invalidate the existing list before checking to ensure this reflects the
|
||||
// current state in
|
||||
// Invalidate the existing list before checking to ensure this reflects the current state in
|
||||
// the system
|
||||
mTaskList.onRecentTasksChanged();
|
||||
mTaskList.getTasks(true /* loadKeysOnly */, (taskGroups) -> {
|
||||
@@ -227,7 +218,8 @@ public class RecentsModel implements RecentTasksDataSource, IconChangeListener,
|
||||
}
|
||||
|
||||
// Keep the cache up to date with the latest thumbnails
|
||||
ActivityManager.RunningTaskInfo runningTask = ActivityManagerWrapper.getInstance().getRunningTask();
|
||||
ActivityManager.RunningTaskInfo runningTask =
|
||||
LawnchairQuickstepCompat.getActivityManagerCompat().getRunningTask(true);
|
||||
int runningTaskId = runningTask != null ? runningTask.id : -1;
|
||||
mTaskList.getTaskKeys(mThumbnailCache.getCacheSize(), taskGroups -> {
|
||||
for (GroupTask group : taskGroups) {
|
||||
@@ -392,4 +384,4 @@ public class RecentsModel implements RecentTasksDataSource, IconChangeListener,
|
||||
*/
|
||||
void onRunningTasksChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -64,6 +64,7 @@ import androidx.annotation.WorkerThread;
|
||||
import com.android.internal.logging.InstanceId;
|
||||
import com.android.internal.util.ScreenshotRequest;
|
||||
import com.android.internal.view.AppearanceRegion;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.util.MainThreadInitializedObject;
|
||||
import com.android.launcher3.util.Preconditions;
|
||||
import com.android.launcher3.util.SafeCloseable;
|
||||
@@ -109,6 +110,8 @@ import java.util.Arrays;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
|
||||
import app.lawnchair.compat.LawnchairQuickstepCompat;
|
||||
|
||||
/**
|
||||
* Holds the reference to SystemUI.
|
||||
*/
|
||||
@@ -191,9 +194,17 @@ public class SystemUiProxy implements ISystemUiProxy, NavHandle, SafeCloseable {
|
||||
mContext = context;
|
||||
mAsyncHandler = new Handler(UI_HELPER_EXECUTOR.getLooper(), this::handleMessageAsync);
|
||||
final Intent baseIntent = new Intent().setPackage(mContext.getPackageName());
|
||||
mRecentsPendingIntent = PendingIntent.getActivity(mContext, 0, baseIntent,
|
||||
final ActivityOptions options = ActivityOptions.makeBasic();
|
||||
if (Utilities.ATLEAST_U) {
|
||||
options.setPendingIntentCreatorBackgroundActivityStartMode(
|
||||
ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED);
|
||||
}
|
||||
|
||||
mRecentsPendingIntent = LawnchairQuickstepCompat.ATLEAST_V ? PendingIntent.getActivity(mContext, 0, baseIntent,
|
||||
PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_ALLOW_UNSAFE_IMPLICIT_INTENT
|
||||
| Intent.FILL_IN_COMPONENT);
|
||||
| Intent.FILL_IN_COMPONENT) : PendingIntent.getActivity(mContext, 0, baseIntent,
|
||||
PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_ALLOW_UNSAFE_IMPLICIT_INTENT
|
||||
| Intent.FILL_IN_COMPONENT, options.toBundle()) ;
|
||||
|
||||
mUnfoldTransitionProvider =
|
||||
(enableUnfoldStateAnimation() && new ResourceUnfoldTransitionConfig().isEnabled())
|
||||
@@ -1200,8 +1211,9 @@ public class SystemUiProxy implements ISystemUiProxy, NavHandle, SafeCloseable {
|
||||
* if Launcher and SystemUI need to coordinate transactions (eg. for shell transitions).
|
||||
*/
|
||||
public void shareTransactionQueue() {
|
||||
if (!LawnchairQuickstepCompat.ATLEAST_V) return;
|
||||
if (mOriginalTransactionToken == null) {
|
||||
// mOriginalTransactionToken = SurfaceControl.Transaction.getDefaultApplyToken();
|
||||
mOriginalTransactionToken = SurfaceControl.Transaction.getDefaultApplyToken();
|
||||
}
|
||||
setupTransactionQueue();
|
||||
}
|
||||
@@ -1210,19 +1222,21 @@ public class SystemUiProxy implements ISystemUiProxy, NavHandle, SafeCloseable {
|
||||
* Switch back to using Launcher's independent transaction queue.
|
||||
*/
|
||||
public void unshareTransactionQueue() {
|
||||
if (!LawnchairQuickstepCompat.ATLEAST_V) return;
|
||||
if (mOriginalTransactionToken == null) {
|
||||
return;
|
||||
}
|
||||
// SurfaceControl.Transaction.setDefaultApplyToken(mOriginalTransactionToken);
|
||||
SurfaceControl.Transaction.setDefaultApplyToken(mOriginalTransactionToken);
|
||||
mOriginalTransactionToken = null;
|
||||
}
|
||||
|
||||
private void setupTransactionQueue() {
|
||||
if (!LawnchairQuickstepCompat.ATLEAST_V) return;
|
||||
if (mOriginalTransactionToken == null) {
|
||||
return;
|
||||
}
|
||||
if (mShellTransitions == null) {
|
||||
// SurfaceControl.Transaction.setDefaultApplyToken(mOriginalTransactionToken);
|
||||
SurfaceControl.Transaction.setDefaultApplyToken(mOriginalTransactionToken);
|
||||
return;
|
||||
}
|
||||
final IBinder shellApplyToken;
|
||||
@@ -1236,7 +1250,7 @@ public class SystemUiProxy implements ISystemUiProxy, NavHandle, SafeCloseable {
|
||||
Log.e(TAG, "Didn't receive apply token from Shell");
|
||||
return;
|
||||
}
|
||||
// SurfaceControl.Transaction.setDefaultApplyToken(shellApplyToken);
|
||||
SurfaceControl.Transaction.setDefaultApplyToken(shellApplyToken);
|
||||
}
|
||||
|
||||
//
|
||||
@@ -1624,4 +1638,4 @@ public class SystemUiProxy implements ISystemUiProxy, NavHandle, SafeCloseable {
|
||||
pw.println("\tmUnfoldAnimationListener=" + mUnfoldAnimationListener);
|
||||
pw.println("\tmDragAndDrop=" + mDragAndDrop);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -58,7 +58,7 @@ import java.io.PrintWriter;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAnimationListener {
|
||||
public static final boolean ENABLE_SHELL_TRANSITIONS = false;
|
||||
public static final boolean ENABLE_SHELL_TRANSITIONS = true;
|
||||
public static final boolean SHELL_TRANSITIONS_ROTATION = ENABLE_SHELL_TRANSITIONS
|
||||
&& SystemProperties.getBoolean("persist.wm.debug.shell_transit_rotate", false);
|
||||
|
||||
@@ -100,11 +100,6 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn
|
||||
TaskAnimationManager(Context ctx) {
|
||||
mCtx = ctx;
|
||||
}
|
||||
|
||||
SystemUiProxy getSystemUiProxy() {
|
||||
return SystemUiProxy.INSTANCE.get(mCtx);
|
||||
}
|
||||
|
||||
/**
|
||||
* Preloads the recents animation.
|
||||
*/
|
||||
@@ -158,7 +153,7 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn
|
||||
final BaseContainerInterface containerInterface = gestureState.getContainerInterface();
|
||||
mLastGestureState = gestureState;
|
||||
RecentsAnimationCallbacks newCallbacks = new RecentsAnimationCallbacks(
|
||||
getSystemUiProxy(), containerInterface.allowMinimizeSplitScreen());
|
||||
SystemUiProxy.INSTANCE.get(mCtx), containerInterface.allowMinimizeSplitScreen());
|
||||
mCallbacks = newCallbacks;
|
||||
mCallbacks.addListener(new RecentsAnimationCallbacks.RecentsAnimationListener() {
|
||||
@Override
|
||||
@@ -265,7 +260,7 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn
|
||||
}
|
||||
|
||||
RemoteAnimationTarget[] nonAppTargets = ENABLE_SHELL_TRANSITIONS
|
||||
? null : getSystemUiProxy().onStartingSplitLegacy(
|
||||
? null : SystemUiProxy.INSTANCE.get(mCtx).onStartingSplitLegacy(
|
||||
appearedTaskTargets);
|
||||
if (nonAppTargets == null) {
|
||||
nonAppTargets = new RemoteAnimationTarget[0];
|
||||
@@ -332,13 +327,12 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn
|
||||
|
||||
if (ENABLE_SHELL_TRANSITIONS) {
|
||||
final ActivityOptions options = ActivityOptions.makeBasic();
|
||||
options.setPendingIntentBackgroundActivityLaunchAllowedByPermission(true);
|
||||
// Use regular (non-transient) launch for all apps page to control IME.
|
||||
if (!containerInterface.allowAllAppsFromOverview()) {
|
||||
options.setTransientLaunch();
|
||||
}
|
||||
options.setSourceInfo(ActivityOptions.SourceInfo.TYPE_RECENTS_ANIMATION, eventTime);
|
||||
mRecentsAnimationStartPending = getSystemUiProxy()
|
||||
mRecentsAnimationStartPending = SystemUiProxy.INSTANCE.get(mCtx)
|
||||
.startRecentsActivity(intent, options, mCallbacks);
|
||||
if (enableHandleDelayedGestureCallbacks()) {
|
||||
ActiveGestureLog.INSTANCE.addLog(new ActiveGestureLog.CompoundString(
|
||||
@@ -546,4 +540,4 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn
|
||||
mLastGestureState.dump(prefix + '\t', pw);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -162,7 +162,7 @@ public class TouchInteractionService extends Service {
|
||||
private static final String TAG = "TouchInteractionService";
|
||||
|
||||
private static final ConstantItem<Boolean> HAS_ENABLED_QUICKSTEP_ONCE = backedUpItem(
|
||||
"launcher.has_enabled_quickstep_once", false, EncryptionType.ENCRYPTED);
|
||||
"launcher.has_enabled_quickstep_once", true, EncryptionType.ENCRYPTED);
|
||||
|
||||
private final TISBinder mTISBinder = new TISBinder(this);
|
||||
|
||||
|
||||
@@ -16,9 +16,11 @@
|
||||
|
||||
package com.android.quickstep.util
|
||||
|
||||
import android.annotation.BinderThread
|
||||
import android.graphics.Region
|
||||
import android.util.Log
|
||||
import android.view.Display.DEFAULT_DISPLAY
|
||||
import android.view.ISystemGestureExclusionListener
|
||||
import android.view.IWindowManager
|
||||
import android.view.WindowManagerGlobal
|
||||
import androidx.annotation.VisibleForTesting
|
||||
@@ -33,26 +35,25 @@ class GestureExclusionManager(private val windowManager: IWindowManager) {
|
||||
private var lastUnrestrictedOrNull: Region? = null
|
||||
|
||||
@VisibleForTesting
|
||||
val exclusionListener = null
|
||||
// object : ISystemGestureExclusionListener.Stub() {
|
||||
// @BinderThread
|
||||
// override fun onSystemGestureExclusionChanged(
|
||||
// displayId: Int,
|
||||
// exclusionRegion: Region?,
|
||||
// unrestrictedOrNull: Region?
|
||||
// ) {
|
||||
// if (displayId != DEFAULT_DISPLAY) {
|
||||
// return
|
||||
// }
|
||||
// Executors.MAIN_EXECUTOR.execute {
|
||||
// lastExclusionRegion = exclusionRegion
|
||||
// lastUnrestrictedOrNull = unrestrictedOrNull
|
||||
// listeners.forEach {
|
||||
// it.onGestureExclusionChanged(exclusionRegion, unrestrictedOrNull)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
val exclusionListener = object : ISystemGestureExclusionListener.Stub() {
|
||||
@BinderThread
|
||||
override fun onSystemGestureExclusionChanged(
|
||||
displayId: Int,
|
||||
exclusionRegion: Region?,
|
||||
unrestrictedOrNull: Region?
|
||||
) {
|
||||
if (displayId != DEFAULT_DISPLAY) {
|
||||
return
|
||||
}
|
||||
Executors.MAIN_EXECUTOR.execute {
|
||||
lastExclusionRegion = exclusionRegion
|
||||
lastUnrestrictedOrNull = unrestrictedOrNull
|
||||
listeners.forEach {
|
||||
it.onGestureExclusionChanged(exclusionRegion, unrestrictedOrNull)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Adds a listener for receiving gesture exclusion regions */
|
||||
fun addListener(listener: ExclusionListener) {
|
||||
|
||||
@@ -41,7 +41,6 @@ import static com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_50_
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.RequiresApi;
|
||||
import android.annotation.UiThread;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.ActivityOptions;
|
||||
@@ -53,7 +52,6 @@ import android.content.pm.ShortcutInfo;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
@@ -170,10 +168,28 @@ public class SplitSelectStateController {
|
||||
*/
|
||||
private Pair<InstanceId, com.android.launcher3.logging.InstanceId> mSessionInstanceIds;
|
||||
|
||||
private final BackPressHandler mSplitBackHandler = new BackPressHandler() {
|
||||
@Override
|
||||
public boolean canHandleBack() {
|
||||
return FeatureFlags.enableSplitContextually() && isSplitSelectActive();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackInvoked() {
|
||||
// When exiting from split selection, leave current context to go to
|
||||
// homescreen as well
|
||||
getSplitAnimationController().playPlaceholderDismissAnim(mContainer,
|
||||
LAUNCHER_SPLIT_SELECTION_EXIT_HOME);
|
||||
if (mActivityBackCallback != null) {
|
||||
mActivityBackCallback.run();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public SplitSelectStateController(RecentsViewContainer container, Handler handler,
|
||||
StateManager stateManager, DepthController depthController,
|
||||
StatsLogManager statsLogManager, SystemUiProxy systemUiProxy, RecentsModel recentsModel,
|
||||
Runnable activityBackCallback) {
|
||||
StateManager stateManager, DepthController depthController,
|
||||
StatsLogManager statsLogManager, SystemUiProxy systemUiProxy, RecentsModel recentsModel,
|
||||
Runnable activityBackCallback) {
|
||||
mContainer = container;
|
||||
mHandler = handler;
|
||||
mStatsLogManager = statsLogManager;
|
||||
@@ -203,8 +219,8 @@ public class SplitSelectStateController {
|
||||
* @param intent will be ignored if @param alreadyRunningTask is set
|
||||
*/
|
||||
public void setInitialTaskSelect(@Nullable Intent intent, @StagePosition int stagePosition,
|
||||
@NonNull ItemInfo itemInfo, StatsLogManager.EventEnum splitEvent,
|
||||
int alreadyRunningTask) {
|
||||
@NonNull ItemInfo itemInfo, StatsLogManager.EventEnum splitEvent,
|
||||
int alreadyRunningTask) {
|
||||
mSplitSelectDataHolder.setInitialTaskSelect(intent, stagePosition, itemInfo, splitEvent,
|
||||
alreadyRunningTask);
|
||||
createAndLogInstanceIdsForSession();
|
||||
@@ -215,8 +231,8 @@ public class SplitSelectStateController {
|
||||
* running app.
|
||||
*/
|
||||
public void setInitialTaskSelect(ActivityManager.RunningTaskInfo info,
|
||||
@StagePosition int stagePosition, @NonNull ItemInfo itemInfo,
|
||||
StatsLogManager.EventEnum splitEvent) {
|
||||
@StagePosition int stagePosition, @NonNull ItemInfo itemInfo,
|
||||
StatsLogManager.EventEnum splitEvent) {
|
||||
mSplitSelectDataHolder.setInitialTaskSelect(info, stagePosition, itemInfo, splitEvent);
|
||||
createAndLogInstanceIdsForSession();
|
||||
}
|
||||
@@ -231,7 +247,7 @@ public class SplitSelectStateController {
|
||||
* tasks (i.e. searching for a running pair of tasks.)
|
||||
*/
|
||||
public void findLastActiveTasksAndRunCallback(@Nullable List<ComponentKey> componentKeys,
|
||||
boolean findExactPairMatch, Consumer<Task[]> callback) {
|
||||
boolean findExactPairMatch, Consumer<Task[]> callback) {
|
||||
mRecentTasksModel.getTasks(taskGroups -> {
|
||||
if (componentKeys == null || componentKeys.isEmpty()) {
|
||||
callback.accept(new Task[]{});
|
||||
@@ -301,7 +317,7 @@ public class SplitSelectStateController {
|
||||
* both permutations because task order is not guaranteed in GroupTasks.
|
||||
*/
|
||||
public boolean isInstanceOfAppPair(GroupTask groupTask, @NonNull ComponentKey componentKey1,
|
||||
@NonNull ComponentKey componentKey2) {
|
||||
@NonNull ComponentKey componentKey2) {
|
||||
return ((isInstanceOfComponent(groupTask.task1, componentKey1)
|
||||
&& isInstanceOfComponent(groupTask.task2, componentKey2))
|
||||
||
|
||||
@@ -335,7 +351,7 @@ public class SplitSelectStateController {
|
||||
* animations are complete.
|
||||
*/
|
||||
public void launchSplitTasks(@PersistentSnapPosition int snapPosition,
|
||||
@Nullable Consumer<Boolean> callback) {
|
||||
@Nullable Consumer<Boolean> callback) {
|
||||
launchTasks(callback, false /* freezeTaskList */, snapPosition, mSessionInstanceIds.first);
|
||||
|
||||
mStatsLogManager.logger()
|
||||
@@ -420,7 +436,7 @@ public class SplitSelectStateController {
|
||||
* foreground (quickswitch, launching previous pairs from overview)
|
||||
*/
|
||||
public void launchTasks(@Nullable Consumer<Boolean> callback, boolean freezeTaskList,
|
||||
@PersistentSnapPosition int snapPosition, @Nullable InstanceId shellInstanceId) {
|
||||
@PersistentSnapPosition int snapPosition, @Nullable InstanceId shellInstanceId) {
|
||||
TestLogging.recordEvent(
|
||||
TestProtocol.SEQUENCE_MAIN, "launchSplitTasks");
|
||||
final ActivityOptions options1 = ActivityOptions.makeBasic();
|
||||
@@ -524,9 +540,9 @@ public class SplitSelectStateController {
|
||||
* GroupedTaskView, int, int, int, Consumer, boolean, int, RemoteTransition)}
|
||||
*/
|
||||
public void launchExistingSplitPair(@Nullable GroupedTaskView groupedTaskView,
|
||||
int firstTaskId, int secondTaskId, @StagePosition int stagePosition,
|
||||
Consumer<Boolean> callback, boolean freezeTaskList,
|
||||
@PersistentSnapPosition int snapPosition) {
|
||||
int firstTaskId, int secondTaskId, @StagePosition int stagePosition,
|
||||
Consumer<Boolean> callback, boolean freezeTaskList,
|
||||
@PersistentSnapPosition int snapPosition) {
|
||||
launchExistingSplitPair(
|
||||
groupedTaskView,
|
||||
firstTaskId,
|
||||
@@ -549,9 +565,9 @@ public class SplitSelectStateController {
|
||||
* NOTE: This is not to be used to launch AppPairs.
|
||||
*/
|
||||
public void launchExistingSplitPair(@Nullable GroupedTaskView groupedTaskView,
|
||||
int firstTaskId, int secondTaskId, @StagePosition int stagePosition,
|
||||
Consumer<Boolean> callback, boolean freezeTaskList,
|
||||
@PersistentSnapPosition int snapPosition, @Nullable RemoteTransition remoteTransition) {
|
||||
int firstTaskId, int secondTaskId, @StagePosition int stagePosition,
|
||||
Consumer<Boolean> callback, boolean freezeTaskList,
|
||||
@PersistentSnapPosition int snapPosition, @Nullable RemoteTransition remoteTransition) {
|
||||
mLaunchingTaskView = groupedTaskView;
|
||||
final ActivityOptions options1 = ActivityOptions.makeBasic();
|
||||
if (freezeTaskList) {
|
||||
@@ -562,7 +578,7 @@ public class SplitSelectStateController {
|
||||
if (TaskAnimationManager.ENABLE_SHELL_TRANSITIONS) {
|
||||
final RemoteTransition transition = remoteTransition == null
|
||||
? getShellRemoteTransition(
|
||||
firstTaskId, secondTaskId, callback, "LaunchExistingPair")
|
||||
firstTaskId, secondTaskId, callback, "LaunchExistingPair")
|
||||
: remoteTransition;
|
||||
mSystemUiProxy.startTasks(firstTaskId, optionsBundle, secondTaskId, null /* options2 */,
|
||||
stagePosition, snapPosition, transition, null /*shellInstanceId*/);
|
||||
@@ -633,7 +649,7 @@ public class SplitSelectStateController {
|
||||
* Init {@code SplitFromDesktopController}
|
||||
*/
|
||||
public void initSplitFromDesktopController(QuickstepLauncher launcher,
|
||||
OverviewComponentObserver overviewComponentObserver) {
|
||||
OverviewComponentObserver overviewComponentObserver) {
|
||||
initSplitFromDesktopController(
|
||||
new SplitFromDesktopController(launcher, overviewComponentObserver));
|
||||
}
|
||||
@@ -644,7 +660,7 @@ public class SplitSelectStateController {
|
||||
}
|
||||
|
||||
private RemoteTransition getShellRemoteTransition(int firstTaskId, int secondTaskId,
|
||||
@Nullable Consumer<Boolean> callback, String transitionName) {
|
||||
@Nullable Consumer<Boolean> callback, String transitionName) {
|
||||
final RemoteSplitLaunchTransitionRunner animationRunner =
|
||||
new RemoteSplitLaunchTransitionRunner(firstTaskId, secondTaskId, callback);
|
||||
return new RemoteTransition(animationRunner,
|
||||
@@ -652,7 +668,7 @@ public class SplitSelectStateController {
|
||||
}
|
||||
|
||||
private RemoteAnimationAdapter getLegacyRemoteAdapter(int firstTaskId, int secondTaskId,
|
||||
@Nullable Consumer<Boolean> callback) {
|
||||
@Nullable Consumer<Boolean> callback) {
|
||||
final RemoteSplitLaunchAnimationRunner animationRunner =
|
||||
new RemoteSplitLaunchAnimationRunner(firstTaskId, secondTaskId, callback);
|
||||
return new RemoteAnimationAdapter(animationRunner, 300, 150,
|
||||
@@ -725,7 +741,7 @@ public class SplitSelectStateController {
|
||||
private Consumer<Boolean> mFinishCallback;
|
||||
|
||||
RemoteSplitLaunchTransitionRunner(int initialTaskId, int secondTaskId,
|
||||
@Nullable Consumer<Boolean> callback) {
|
||||
@Nullable Consumer<Boolean> callback) {
|
||||
mInitialTaskId = initialTaskId;
|
||||
mSecondTaskId = secondTaskId;
|
||||
mFinishCallback = callback;
|
||||
@@ -733,8 +749,8 @@ public class SplitSelectStateController {
|
||||
|
||||
@Override
|
||||
public void startAnimation(IBinder transition, TransitionInfo info,
|
||||
SurfaceControl.Transaction t,
|
||||
IRemoteTransitionFinishedCallback finishedCallback) {
|
||||
SurfaceControl.Transaction t,
|
||||
IRemoteTransitionFinishedCallback finishedCallback) {
|
||||
final Runnable finishAdapter = () -> {
|
||||
try {
|
||||
finishedCallback.onTransitionFinished(null /* wct */, null /* sct */);
|
||||
@@ -799,7 +815,7 @@ public class SplitSelectStateController {
|
||||
private final Consumer<Boolean> mSuccessCallback;
|
||||
|
||||
RemoteSplitLaunchAnimationRunner(int initialTaskId, int secondTaskId,
|
||||
@Nullable Consumer<Boolean> successCallback) {
|
||||
@Nullable Consumer<Boolean> successCallback) {
|
||||
mInitialTaskId = initialTaskId;
|
||||
mSecondTaskId = secondTaskId;
|
||||
mSuccessCallback = successCallback;
|
||||
@@ -807,8 +823,8 @@ public class SplitSelectStateController {
|
||||
|
||||
@Override
|
||||
public void onAnimationStart(int transit, RemoteAnimationTarget[] apps,
|
||||
RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps,
|
||||
Runnable finishedCallback) {
|
||||
RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps,
|
||||
Runnable finishedCallback) {
|
||||
postAsyncCallback(mHandler,
|
||||
() -> mSplitAnimationController.playSplitLaunchAnimation(mLaunchingTaskView,
|
||||
mLaunchingIconView, mInitialTaskId, mSecondTaskId, apps, wallpapers,
|
||||
@@ -923,25 +939,8 @@ public class SplitSelectStateController {
|
||||
mLaunchingIconView = launchingIconView;
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
|
||||
public BackPressHandler getSplitBackHandler() {
|
||||
return new BackPressHandler() {
|
||||
@Override
|
||||
public boolean canHandleBack() {
|
||||
return FeatureFlags.enableSplitContextually() && isSplitSelectActive();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackInvoked() {
|
||||
// When exiting from split selection, leave current context to go to
|
||||
// homescreen as well
|
||||
getSplitAnimationController().playPlaceholderDismissAnim(mContainer,
|
||||
LAUNCHER_SPLIT_SELECTION_EXIT_HOME);
|
||||
if (mActivityBackCallback != null) {
|
||||
mActivityBackCallback.run();
|
||||
}
|
||||
}
|
||||
};
|
||||
return mSplitBackHandler;
|
||||
}
|
||||
|
||||
public void dump(String prefix, PrintWriter writer) {
|
||||
@@ -962,7 +961,7 @@ public class SplitSelectStateController {
|
||||
private Drawable mAppIcon;
|
||||
|
||||
public SplitFromDesktopController(QuickstepLauncher launcher,
|
||||
OverviewComponentObserver overviewComponentObserver) {
|
||||
OverviewComponentObserver overviewComponentObserver) {
|
||||
mLauncher = launcher;
|
||||
mOverviewComponentObserver = overviewComponentObserver;
|
||||
mSplitPlaceholderSize = mLauncher.getResources().getDimensionPixelSize(
|
||||
@@ -972,7 +971,7 @@ public class SplitSelectStateController {
|
||||
mSplitSelectListener = new ISplitSelectListener.Stub() {
|
||||
@Override
|
||||
public boolean onRequestSplitSelect(ActivityManager.RunningTaskInfo taskInfo,
|
||||
int splitPosition, Rect taskBounds) {
|
||||
int splitPosition, Rect taskBounds) {
|
||||
MAIN_EXECUTOR.execute(() -> enterSplitSelect(taskInfo, splitPosition,
|
||||
taskBounds));
|
||||
return true;
|
||||
@@ -994,14 +993,14 @@ public class SplitSelectStateController {
|
||||
* @param taskBounds the bounds of the task, used for {@link FloatingTaskView} animation
|
||||
*/
|
||||
public void enterSplitSelect(ActivityManager.RunningTaskInfo taskInfo,
|
||||
int splitPosition, Rect taskBounds) {
|
||||
int splitPosition, Rect taskBounds) {
|
||||
mTaskInfo = taskInfo;
|
||||
String packageName = mTaskInfo.realActivity.getPackageName();
|
||||
PackageManager pm = mLauncher.getApplicationContext().getPackageManager();
|
||||
IconProvider provider = new IconProvider(mLauncher.getApplicationContext());
|
||||
try {
|
||||
mAppIcon = provider.getIcon(pm.getActivityInfo(mTaskInfo.baseActivity,
|
||||
PackageManager.ComponentInfoFlags.of(0)));
|
||||
PackageManager.ComponentInfoFlags.of(0)));
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
Log.w(TAG, "Package not found: " + packageName, e);
|
||||
}
|
||||
@@ -1036,11 +1035,11 @@ public class SplitSelectStateController {
|
||||
|
||||
@Override
|
||||
public void onRecentsAnimationStart(RecentsAnimationController controller,
|
||||
RecentsAnimationTargets targets) {
|
||||
RecentsAnimationTargets targets) {
|
||||
StatsLogManager.LauncherEvent launcherDesktopSplitEvent =
|
||||
mSplitPosition == STAGE_POSITION_BOTTOM_OR_RIGHT ?
|
||||
LAUNCHER_DESKTOP_MODE_SPLIT_RIGHT_BOTTOM :
|
||||
LAUNCHER_DESKTOP_MODE_SPLIT_LEFT_TOP;
|
||||
LAUNCHER_DESKTOP_MODE_SPLIT_RIGHT_BOTTOM :
|
||||
LAUNCHER_DESKTOP_MODE_SPLIT_LEFT_TOP;
|
||||
setInitialTaskSelect(mTaskInfo, mSplitPosition,
|
||||
null, launcherDesktopSplitEvent);
|
||||
|
||||
@@ -1076,4 +1075,4 @@ public class SplitSelectStateController {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.android.quickstep.util;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.view.SurfaceControl;
|
||||
@@ -23,8 +25,6 @@ import android.view.View;
|
||||
import android.view.View.OnAttachStateChangeListener;
|
||||
import android.view.ViewRootImpl;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.android.quickstep.RemoteAnimationTargets.ReleaseCheck;
|
||||
|
||||
import app.lawnchair.compat.LawnchairQuickstepCompat;
|
||||
@@ -34,6 +34,7 @@ import app.lawnchair.compat.LawnchairQuickstepCompat;
|
||||
* android.view.SyncRtSurfaceTransactionApplier
|
||||
* with some Launcher specific utility methods
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.R)
|
||||
public class SurfaceTransactionApplier extends ReleaseCheck {
|
||||
|
||||
private static final int MSG_UPDATE_SEQUENCE_NUMBER = 0;
|
||||
@@ -49,7 +50,7 @@ public class SurfaceTransactionApplier extends ReleaseCheck {
|
||||
/**
|
||||
* @param targetView The view in the surface that acts as synchronization anchor.
|
||||
*/
|
||||
public SurfaceTransactionApplier(@NonNull View targetView) {
|
||||
public SurfaceTransactionApplier(View targetView) {
|
||||
if (targetView.isAttachedToWindow()) {
|
||||
initialize(targetView);
|
||||
} else {
|
||||
@@ -75,7 +76,7 @@ public class SurfaceTransactionApplier extends ReleaseCheck {
|
||||
|
||||
private void initialize(View view) {
|
||||
mTargetViewRootImpl = view.getViewRootImpl();
|
||||
// mBarrierSurfaceControl = mTargetViewRootImpl.getSurfaceControl();
|
||||
mBarrierSurfaceControl = mTargetViewRootImpl.getSurfaceControl();
|
||||
mInitialized = true;
|
||||
}
|
||||
|
||||
@@ -108,7 +109,7 @@ public class SurfaceTransactionApplier extends ReleaseCheck {
|
||||
final int toApplySeqNo = mLastSequenceNumber;
|
||||
setCanRelease(false);
|
||||
mTargetViewRootImpl.registerRtFrameCallback(frame -> {
|
||||
if (mBarrierSurfaceControl == null && !mBarrierSurfaceControl.isValid()) {
|
||||
if (mBarrierSurfaceControl == null || !mBarrierSurfaceControl.isValid()) {
|
||||
Message.obtain(mApplyHandler, MSG_UPDATE_SEQUENCE_NUMBER, toApplySeqNo, 0)
|
||||
.sendToTarget();
|
||||
return;
|
||||
|
||||
@@ -59,8 +59,7 @@ import com.android.systemui.shared.recents.model.ThumbnailData;
|
||||
import com.android.systemui.shared.recents.utilities.PreviewPositionHelper;
|
||||
|
||||
/**
|
||||
* A utility class which emulates the layout behavior of TaskView and
|
||||
* RecentsView
|
||||
* A utility class which emulates the layout behavior of TaskView and RecentsView
|
||||
*/
|
||||
public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||
|
||||
@@ -100,7 +99,6 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||
private final FullscreenDrawParams mCurrentFullscreenParams;
|
||||
public final AnimatedFloat taskPrimaryTranslation = new AnimatedFloat();
|
||||
public final AnimatedFloat taskSecondaryTranslation = new AnimatedFloat();
|
||||
public final AnimatedFloat scrollScale = new AnimatedFloat();
|
||||
|
||||
// Carousel properties
|
||||
public final AnimatedFloat carouselScale = new AnimatedFloat();
|
||||
@@ -130,8 +128,7 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||
mSizeStrategy = sizeStrategy;
|
||||
|
||||
mOrientationState = TraceHelper.allowIpcs("TaskViewSimulator.init",
|
||||
() -> new RecentsOrientedState(context, sizeStrategy, i -> {
|
||||
}));
|
||||
() -> new RecentsOrientedState(context, sizeStrategy, i -> { }));
|
||||
mOrientationState.setGestureActive(true);
|
||||
mCurrentFullscreenParams = new FullscreenDrawParams(context);
|
||||
mOrientationStateId = mOrientationState.getStateId();
|
||||
@@ -170,8 +167,7 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||
|
||||
if (mSplitBounds != null) {
|
||||
// The task rect changes according to the staged split task sizes, but recents
|
||||
// fullscreen scale and pivot remains the same since the task fits into the
|
||||
// existing
|
||||
// fullscreen scale and pivot remains the same since the task fits into the existing
|
||||
// sized task space bounds
|
||||
mTaskRect.set(mFullTaskSize);
|
||||
mOrientationState.getOrientationHandler()
|
||||
@@ -179,10 +175,8 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||
mTaskRect.offset(mTaskRectTranslationX, mTaskRectTranslationY);
|
||||
} else if (mIsDesktopTask) {
|
||||
// For desktop, tasks can take up only part of the screen size.
|
||||
// Full task size represents the whole screen size, but scaled down to fit in
|
||||
// recents.
|
||||
// Task rect will represent the scaled down thumbnail position and is placed
|
||||
// inside
|
||||
// Full task size represents the whole screen size, but scaled down to fit in recents.
|
||||
// Task rect will represent the scaled down thumbnail position and is placed inside
|
||||
// full task size as it is on the home screen.
|
||||
PointF fullscreenTaskDimension = new PointF();
|
||||
BaseActivityInterface.getTaskDimension(mContext, mDp, fullscreenTaskDimension);
|
||||
@@ -213,8 +207,7 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||
if (mDp == null) {
|
||||
return 1;
|
||||
}
|
||||
// Copy mFullTaskSize instead of updating it directly so it could be reused next
|
||||
// time
|
||||
// Copy mFullTaskSize instead of updating it directly so it could be reused next time
|
||||
// without recalculating
|
||||
Rect scaleRect = new Rect();
|
||||
if (mScaleToCarouselTaskSize) {
|
||||
@@ -242,8 +235,7 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the targets which the simulator will control specifically for targets to
|
||||
* animate when
|
||||
* Sets the targets which the simulator will control specifically for targets to animate when
|
||||
* in split screen
|
||||
*
|
||||
* @param splitInfo set to {@code null} when not in staged split mode
|
||||
@@ -255,8 +247,7 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||
mStagePosition = STAGE_POSITION_UNDEFINED;
|
||||
} else {
|
||||
mStagePosition = runningTarget.taskId == splitInfo.leftTopTaskId
|
||||
? STAGE_POSITION_TOP_OR_LEFT
|
||||
: STAGE_POSITION_BOTTOM_OR_RIGHT;
|
||||
? STAGE_POSITION_TOP_OR_LEFT : STAGE_POSITION_BOTTOM_OR_RIGHT;
|
||||
mPositionHelper.setSplitBounds(convertLauncherSplitBoundsToShell(mSplitBounds),
|
||||
mStagePosition);
|
||||
}
|
||||
@@ -311,17 +302,14 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds animation for all the components corresponding to transition from an app
|
||||
* to overview.
|
||||
* Adds animation for all the components corresponding to transition from an app to overview.
|
||||
*/
|
||||
public void addAppToOverviewAnim(PendingAnimation pa, Interpolator interpolator) {
|
||||
pa.addFloat(fullScreenProgress, AnimatedFloat.VALUE, 1, 0, interpolator);
|
||||
float fullScreenScale;
|
||||
if (enableGridOnlyOverview() && mDp.isTablet && mDp.isGestureMode) {
|
||||
// Move pivot to top right edge of the screen, to avoid task scaling down in
|
||||
// opposite
|
||||
// direction of app window movement, otherwise the animation will wiggle left
|
||||
// and right.
|
||||
// Move pivot to top right edge of the screen, to avoid task scaling down in opposite
|
||||
// direction of app window movement, otherwise the animation will wiggle left and right.
|
||||
// Also translate the app window to top right edge of the screen to simplify
|
||||
// calculations.
|
||||
taskPrimaryTranslation.value = mIsRecentsRtl
|
||||
@@ -330,8 +318,7 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||
taskSecondaryTranslation.value = -mFullTaskSize.top;
|
||||
mPivotOverride = new PointF(mIsRecentsRtl ? mDp.widthPx : 0, 0);
|
||||
|
||||
// Scale down to the carousel and use the carousel Rect to calculate
|
||||
// fullScreenScale.
|
||||
// Scale down to the carousel and use the carousel Rect to calculate fullScreenScale.
|
||||
mScaleToCarouselTaskSize = true;
|
||||
carouselScale.value = mCarouselTaskSize.width() / (float) mFullTaskSize.width();
|
||||
fullScreenScale = getFullScreenScale();
|
||||
@@ -344,18 +331,15 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||
// Expected carousel position's center is in the middle, and invariant of
|
||||
// recentsViewScale.
|
||||
float exceptedCarouselCenterX = mCarouselTaskSize.centerX();
|
||||
// Animating carousel translations linearly will result in a curved path,
|
||||
// therefore
|
||||
// we'll need to calculate the expected translation at each recentsView scale.
|
||||
// Luckily
|
||||
// primary and secondary follow the same translation, and primary is used here
|
||||
// due to
|
||||
// Animating carousel translations linearly will result in a curved path, therefore
|
||||
// we'll need to calculate the expected translation at each recentsView scale. Luckily
|
||||
// primary and secondary follow the same translation, and primary is used here due to
|
||||
// it being simpler.
|
||||
Interpolator carouselTranslationInterpolator = t -> {
|
||||
// recentsViewScale is calculated rather than using recentsViewScale.value, so
|
||||
// that
|
||||
// recentsViewScale is calculated rather than using recentsViewScale.value, so that
|
||||
// this interpolator works independently even if recentsViewScale don't animate.
|
||||
float recentsViewScale = Utilities.mapToRange(t, 0, 1, fullScreenScale, 1, Interpolators.LINEAR);
|
||||
float recentsViewScale =
|
||||
Utilities.mapToRange(t, 0, 1, fullScreenScale, 1, Interpolators.LINEAR);
|
||||
// Without the translation, the app window will animate from fullscreen into top
|
||||
// right corner.
|
||||
float expectedTaskCenterX = mIsRecentsRtl
|
||||
@@ -363,7 +347,8 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||
: mCarouselTaskSize.width() * recentsViewScale / 2f;
|
||||
// Calculate the expected translation, then work back the animatedFraction that
|
||||
// results in this value.
|
||||
float carouselPrimaryTranslation = (exceptedCarouselCenterX - expectedTaskCenterX) / recentsViewScale;
|
||||
float carouselPrimaryTranslation =
|
||||
(exceptedCarouselCenterX - expectedTaskCenterX) / recentsViewScale;
|
||||
return carouselPrimaryTranslation / carouselPrimaryTranslationTarget;
|
||||
};
|
||||
|
||||
@@ -380,8 +365,7 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds animation for all the components corresponding to transition from
|
||||
* overview to the app.
|
||||
* Adds animation for all the components corresponding to transition from overview to the app.
|
||||
*/
|
||||
public void addOverviewToAppAnim(PendingAnimation pa, TimeInterpolator interpolator) {
|
||||
pa.addFloat(fullScreenProgress, AnimatedFloat.VALUE, 0, 1, interpolator);
|
||||
@@ -389,8 +373,7 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current clipped/visible window bounds in the window coordinate
|
||||
* space
|
||||
* Returns the current clipped/visible window bounds in the window coordinate space
|
||||
*/
|
||||
public RectF getCurrentCropRect() {
|
||||
// Crop rect is the inverse of thumbnail matrix
|
||||
@@ -423,15 +406,14 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the rotation on the matrix to so that it maps from launcher
|
||||
* coordinate space to
|
||||
* Applies the rotation on the matrix to so that it maps from launcher coordinate space to
|
||||
* window coordinate space.
|
||||
*/
|
||||
public void applyWindowToHomeRotation(Matrix matrix) {
|
||||
matrix.postTranslate(mDp.windowX, mDp.windowY);
|
||||
postDisplayRotation(deltaRotation(
|
||||
mOrientationState.getRecentsActivityRotation(),
|
||||
mOrientationState.getDisplayRotation()),
|
||||
mOrientationState.getRecentsActivityRotation(),
|
||||
mOrientationState.getDisplayRotation()),
|
||||
mDp.widthPx, mDp.heightPx, matrix);
|
||||
}
|
||||
|
||||
@@ -443,8 +425,7 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the target to the previously set parameters, optionally with an
|
||||
* overridden
|
||||
* Applies the target to the previously set parameters, optionally with an overridden
|
||||
* surface transaction
|
||||
*/
|
||||
public void apply(TransformParams params, @Nullable SurfaceTransaction surfaceTransaction) {
|
||||
@@ -457,8 +438,7 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||
|
||||
getFullScreenScale();
|
||||
if (TaskAnimationManager.SHELL_TRANSITIONS_ROTATION) {
|
||||
// With shell transitions, the display is rotated early so we need to actually
|
||||
// use
|
||||
// With shell transitions, the display is rotated early so we need to actually use
|
||||
// the rotation when the gesture starts
|
||||
mThumbnailData.rotation = mOrientationState.getTouchRotation();
|
||||
} else {
|
||||
@@ -477,7 +457,6 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||
}
|
||||
|
||||
float fullScreenProgress = Utilities.boundToRange(this.fullScreenProgress.value, 0, 1);
|
||||
float scrollScale = this.scrollScale.value * (1f - fullScreenProgress) + fullScreenProgress;
|
||||
mCurrentFullscreenParams.setProgress(fullScreenProgress, recentsViewScale.value,
|
||||
carouselScale.value);
|
||||
|
||||
@@ -489,8 +468,6 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||
|
||||
// Apply TaskView matrix: taskRect, translate
|
||||
mMatrix.postTranslate(mTaskRect.left, mTaskRect.top);
|
||||
mMatrix.postScale(scrollScale, scrollScale, mTaskRect.left + (mTaskRect.width() / 2),
|
||||
mTaskRect.top + (mTaskRect.height() / 2));
|
||||
mOrientationState.getOrientationHandler().setPrimary(mMatrix, MATRIX_POST_TRANSLATE,
|
||||
taskPrimaryTranslation.value);
|
||||
mOrientationState.getOrientationHandler().setSecondary(mMatrix, MATRIX_POST_TRANSLATE,
|
||||
@@ -520,8 +497,7 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||
|
||||
params.setProgress(1f - fullScreenProgress);
|
||||
params.applySurfaceParams(surfaceTransaction == null
|
||||
? params.createSurfaceParams(this)
|
||||
: surfaceTransaction);
|
||||
? params.createSurfaceParams(this) : surfaceTransaction);
|
||||
|
||||
if (!DEBUG) {
|
||||
return;
|
||||
@@ -540,9 +516,8 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||
+ " recentsPrimaryT: " + recentsViewPrimaryTranslation.value
|
||||
+ " recentsSecondaryT: " + recentsViewSecondaryTranslation.value
|
||||
+ " recentsScroll: " + recentsViewScroll.value
|
||||
+ " scrollScale: " + scrollScale
|
||||
+ " this.scrollScale.value: " + this.scrollScale.value
|
||||
+ " pivot: " + mPivot);
|
||||
+ " pivot: " + mPivot
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -555,12 +530,9 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||
// If mDrawsBelowRecents is unset, no reordering will be enforced.
|
||||
if (mDrawsBelowRecents != null) {
|
||||
// In legacy transitions, the animation leashes remain in same hierarchy in the
|
||||
// TaskDisplayArea, so we don't want to bump the layer too high otherwise it
|
||||
// will
|
||||
// conflict with layers that WM core positions (ie. the input consumers). For
|
||||
// shell
|
||||
// transitions, the animation leashes are reparented to an animation container
|
||||
// so we
|
||||
// TaskDisplayArea, so we don't want to bump the layer too high otherwise it will
|
||||
// conflict with layers that WM core positions (ie. the input consumers). For shell
|
||||
// transitions, the animation leashes are reparented to an animation container so we
|
||||
// can bump layers as needed.
|
||||
if (ENABLE_SHELL_TRANSITIONS) {
|
||||
builder.setLayer(mDrawsBelowRecents
|
||||
@@ -576,8 +548,7 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the corner radius that should be applied to the target so that it
|
||||
* matches the
|
||||
* Returns the corner radius that should be applied to the target so that it matches the
|
||||
* TaskView
|
||||
*/
|
||||
public float getCurrentCornerRadius() {
|
||||
@@ -586,8 +557,7 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||
mTempPoint[1] = 0;
|
||||
mInversePositionMatrix.mapVectors(mTempPoint);
|
||||
|
||||
// Ideally we should use square-root. This is an optimization as one of the
|
||||
// dimension is 0.
|
||||
// Ideally we should use square-root. This is an optimization as one of the dimension is 0.
|
||||
return Math.max(Math.abs(mTempPoint[0]), Math.abs(mTempPoint[1]));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,46 +16,40 @@
|
||||
package com.android.quickstep.util;
|
||||
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
|
||||
import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
|
||||
|
||||
import android.util.FloatProperty;
|
||||
import android.view.RemoteAnimationTarget;
|
||||
import android.view.SurfaceControl;
|
||||
|
||||
import com.android.app.animation.Interpolators;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.quickstep.RemoteAnimationTargets;
|
||||
import com.android.quickstep.util.SurfaceTransaction.SurfaceProperties;
|
||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
|
||||
import app.lawnchair.compat.LawnchairQuickstepCompat;
|
||||
|
||||
public class TransformParams {
|
||||
|
||||
public static FloatProperty<TransformParams> PROGRESS = new FloatProperty<TransformParams>("progress") {
|
||||
@Override
|
||||
public void setValue(TransformParams params, float v) {
|
||||
params.setProgress(v);
|
||||
}
|
||||
public static FloatProperty<TransformParams> PROGRESS =
|
||||
new FloatProperty<TransformParams>("progress") {
|
||||
@Override
|
||||
public void setValue(TransformParams params, float v) {
|
||||
params.setProgress(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Float get(TransformParams params) {
|
||||
return params.getProgress();
|
||||
}
|
||||
};
|
||||
@Override
|
||||
public Float get(TransformParams params) {
|
||||
return params.getProgress();
|
||||
}
|
||||
};
|
||||
|
||||
public static FloatProperty<TransformParams> TARGET_ALPHA = new FloatProperty<TransformParams>("targetAlpha") {
|
||||
@Override
|
||||
public void setValue(TransformParams params, float v) {
|
||||
params.setTargetAlpha(v);
|
||||
}
|
||||
public static FloatProperty<TransformParams> TARGET_ALPHA =
|
||||
new FloatProperty<TransformParams>("targetAlpha") {
|
||||
@Override
|
||||
public void setValue(TransformParams params, float v) {
|
||||
params.setTargetAlpha(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Float get(TransformParams params) {
|
||||
return params.getTargetAlpha();
|
||||
}
|
||||
};
|
||||
@Override
|
||||
public Float get(TransformParams params) {
|
||||
return params.getTargetAlpha();
|
||||
}
|
||||
};
|
||||
|
||||
/** Progress from 0 to 1 where 0 is in-app and 1 is Overview */
|
||||
private float mProgress;
|
||||
@@ -74,12 +68,9 @@ public class TransformParams {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the progress of the transformation, where 0 is the source and 1 is the
|
||||
* target. We
|
||||
* automatically adjust properties such as currentRect and cornerRadius based on
|
||||
* this
|
||||
* progress, unless they are manually overridden by setting them on this
|
||||
* TransformParams.
|
||||
* Sets the progress of the transformation, where 0 is the source and 1 is the target. We
|
||||
* automatically adjust properties such as currentRect and cornerRadius based on this
|
||||
* progress, unless they are manually overridden by setting them on this TransformParams.
|
||||
*/
|
||||
public TransformParams setProgress(float progress) {
|
||||
mProgress = progress;
|
||||
@@ -87,10 +78,8 @@ public class TransformParams {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the corner radius of the transformed window, in pixels. If unspecified
|
||||
* (-1), we
|
||||
* simply interpolate between the window's corner radius to the task view's
|
||||
* corner radius,
|
||||
* Sets the corner radius of the transformed window, in pixels. If unspecified (-1), we
|
||||
* simply interpolate between the window's corner radius to the task view's corner radius,
|
||||
* based on {@link #mProgress}.
|
||||
*/
|
||||
public TransformParams setCornerRadius(float cornerRadius) {
|
||||
@@ -107,12 +96,9 @@ public class TransformParams {
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the set of RemoteAnimationTargetCompats that are included in the
|
||||
* transformation
|
||||
* that these TransformParams help compute. These TransformParams generally only
|
||||
* apply to
|
||||
* the targetSet.apps which match the targetSet.targetMode (e.g. the
|
||||
* MODE_CLOSING app when
|
||||
* Specifies the set of RemoteAnimationTargetCompats that are included in the transformation
|
||||
* that these TransformParams help compute. These TransformParams generally only apply to
|
||||
* the targetSet.apps which match the targetSet.targetMode (e.g. the MODE_CLOSING app when
|
||||
* swiping to home).
|
||||
*/
|
||||
public TransformParams setTargetSet(RemoteAnimationTargets targetSet) {
|
||||
@@ -121,8 +107,7 @@ public class TransformParams {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the SyncRtSurfaceTransactionApplierCompat that will apply the
|
||||
* SurfaceParams that
|
||||
* Sets the SyncRtSurfaceTransactionApplierCompat that will apply the SurfaceParams that
|
||||
* are computed based on these TransformParams.
|
||||
*/
|
||||
public TransformParams setSyncTransactionApplier(SurfaceTransactionApplier applier) {
|
||||
@@ -131,8 +116,7 @@ public class TransformParams {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an alternate function to control transform for non-target apps. The
|
||||
* default
|
||||
* Sets an alternate function to control transform for non-target apps. The default
|
||||
* implementation keeps the targets visible with alpha=1
|
||||
*/
|
||||
public TransformParams setBaseBuilderProxy(BuilderProxy proxy) {
|
||||
@@ -165,19 +149,7 @@ public class TransformParams {
|
||||
if (activityType == ACTIVITY_TYPE_HOME) {
|
||||
mHomeBuilderProxy.onBuildTargetParams(builder, app, this);
|
||||
} else {
|
||||
// Fade out translucent overlay.
|
||||
// TODO(b/303351074): use app.isNotInRecents directly once it is fixed.
|
||||
boolean isNotInRecents = LawnchairQuickstepCompat.ATLEAST_S && app.taskInfo != null
|
||||
&& (app.taskInfo.baseIntent.getFlags()
|
||||
& FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) != 0;
|
||||
if (app.isTranslucent && isNotInRecents) {
|
||||
float progress = Utilities.boundToRange(getProgress(), 0, 1);
|
||||
builder.setAlpha(1 - Interpolators.DECELERATE_QUINT
|
||||
.getInterpolation(progress));
|
||||
} else {
|
||||
builder.setAlpha(getTargetAlpha());
|
||||
}
|
||||
|
||||
builder.setAlpha(getTargetAlpha());
|
||||
proxy.onBuildTargetParams(builder, app, this);
|
||||
}
|
||||
} else {
|
||||
@@ -223,11 +195,10 @@ public class TransformParams {
|
||||
@FunctionalInterface
|
||||
public interface BuilderProxy {
|
||||
|
||||
BuilderProxy NO_OP = (builder, app, params) -> {
|
||||
};
|
||||
BuilderProxy NO_OP = (builder, app, params) -> { };
|
||||
BuilderProxy ALWAYS_VISIBLE = (builder, app, params) -> builder.setAlpha(1);
|
||||
|
||||
void onBuildTargetParams(SurfaceProperties builder,
|
||||
RemoteAnimationTarget app, TransformParams params);
|
||||
RemoteAnimationTarget app, TransformParams params);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -438,4 +438,8 @@ public class OverviewActionsView<T extends OverlayUICallbacks> extends FrameLayo
|
||||
mSaveAppPairButton.setCompoundDrawablesRelativeWithIntrinsicBounds(
|
||||
appPairIconRes, 0, 0, 0);
|
||||
}
|
||||
|
||||
protected void setClearAllClickListener(OnClickListener listener) {
|
||||
// No-op
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1103,6 +1103,7 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
|
||||
mActionsView.updateFor3pLauncher(!supportsAppPairs());
|
||||
mSplitSelectStateController = splitController;
|
||||
mDesktopRecentsTransitionController = desktopRecentsTransitionController;
|
||||
mActionsView.setClearAllClickListener(this::dismissAllTasks);
|
||||
}
|
||||
|
||||
public SplitSelectStateController getSplitSelectController() {
|
||||
|
||||
@@ -16,9 +16,12 @@
|
||||
|
||||
package com.android.launcher3.model;
|
||||
|
||||
import static com.android.launcher3.BuildConfigs.WIDGET_ON_FIRST_SCREEN;
|
||||
import static com.android.launcher3.Flags.enableLauncherBrMetricsFixed;
|
||||
import static com.android.launcher3.Flags.enableSmartspaceAsAWidget;
|
||||
import static com.android.launcher3.Flags.enableSmartspaceRemovalToggle;
|
||||
import static com.android.launcher3.LauncherPrefs.IS_FIRST_LOAD_AFTER_RESTORE;
|
||||
import static com.android.launcher3.LauncherPrefs.SHOULD_SHOW_SMARTSPACE;
|
||||
import static com.android.launcher3.LauncherSettings.Favorites.TABLE_NAME;
|
||||
import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_HAS_SHORTCUT_PERMISSION;
|
||||
import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_PRIVATE_PROFILE_QUIET_MODE_ENABLED;
|
||||
@@ -186,8 +189,7 @@ public class LoaderTask implements Runnable {
|
||||
LooperIdleLock idleLock = mLauncherBinder.newIdleLock(this);
|
||||
// Just in case mFlushingWorkerThread changes but we aren't woken up,
|
||||
// wait no longer than 1sec at a time
|
||||
while (!mStopped && idleLock.awaitLocked(1000))
|
||||
;
|
||||
while (!mStopped && idleLock.awaitLocked(1000));
|
||||
}
|
||||
|
||||
private synchronized void verifyNotStopped() throws CancellationException {
|
||||
@@ -340,17 +342,17 @@ public class LoaderTask implements Runnable {
|
||||
verifyNotStopped();
|
||||
LauncherPrefs prefs = LauncherPrefs.get(mApp.getContext());
|
||||
|
||||
// if (enableSmartspaceAsAWidget() && prefs.get(SHOULD_SHOW_SMARTSPACE)) {
|
||||
// mLauncherBinder.bindSmartspaceWidget();
|
||||
// // Turn off pref.
|
||||
// prefs.putSync(SHOULD_SHOW_SMARTSPACE.to(false));
|
||||
// logASplit("bindSmartspaceWidget");
|
||||
// verifyNotStopped();
|
||||
// } else if (!enableSmartspaceAsAWidget() && WIDGET_ON_FIRST_SCREEN
|
||||
// && !prefs.get(LauncherPrefs.SHOULD_SHOW_SMARTSPACE)) {
|
||||
// // Turn on pref.
|
||||
// prefs.putSync(SHOULD_SHOW_SMARTSPACE.to(true));
|
||||
// }
|
||||
if (enableSmartspaceAsAWidget() && prefs.get(SHOULD_SHOW_SMARTSPACE)) {
|
||||
mLauncherBinder.bindSmartspaceWidget();
|
||||
// Turn off pref.
|
||||
prefs.putSync(SHOULD_SHOW_SMARTSPACE.to(false));
|
||||
logASplit("bindSmartspaceWidget");
|
||||
verifyNotStopped();
|
||||
} else if (!enableSmartspaceAsAWidget() && WIDGET_ON_FIRST_SCREEN
|
||||
&& !prefs.get(SHOULD_SHOW_SMARTSPACE)) {
|
||||
// Turn on pref.
|
||||
prefs.putSync(SHOULD_SHOW_SMARTSPACE.to(true));
|
||||
}
|
||||
|
||||
if (FeatureFlags.CHANGE_MODEL_DELEGATE_LOADING_ORDER.get()) {
|
||||
mModelDelegate.loadAndBindOtherItems(mLauncherBinder.mCallbacksList);
|
||||
|
||||
@@ -34,8 +34,13 @@ object LawnchairQuickstepCompat {
|
||||
@JvmField
|
||||
val ATLEAST_U: Boolean = Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE
|
||||
|
||||
@ChecksSdkIntAtLeast(api = Build.VERSION_CODES.VANILLA_ICE_CREAM)
|
||||
@JvmField
|
||||
val ATLEAST_V: Boolean = Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM
|
||||
|
||||
@JvmStatic
|
||||
val factory: QuickstepCompatFactory = when {
|
||||
ATLEAST_V -> QuickstepCompatFactoryVU()
|
||||
ATLEAST_U -> QuickstepCompatFactoryVU()
|
||||
ATLEAST_T -> QuickstepCompatFactoryVT()
|
||||
ATLEAST_S -> QuickstepCompatFactoryVS()
|
||||
|
||||
@@ -36,6 +36,8 @@ import com.android.systemui.shared.recents.model.ThumbnailData;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import app.lawnchair.compat.LawnchairQuickstepCompat;
|
||||
|
||||
/**
|
||||
* Tracks all the task stack listeners
|
||||
*/
|
||||
@@ -167,7 +169,8 @@ public class TaskStackChangeListeners {
|
||||
if (!mRegistered) {
|
||||
// Register mTaskStackListener to IActivityManager only once if needed.
|
||||
try {
|
||||
// ActivityTaskManager.getService().registerTaskStackListener(this);
|
||||
if (!LawnchairQuickstepCompat.ATLEAST_V) return;
|
||||
ActivityTaskManager.getService().registerTaskStackListener(this);
|
||||
mRegistered = true;
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "Failed to call registerTaskStackListener", e);
|
||||
@@ -184,7 +187,8 @@ public class TaskStackChangeListeners {
|
||||
if (isEmpty && mRegistered) {
|
||||
// Unregister mTaskStackListener once we have no more listeners
|
||||
try {
|
||||
// ActivityTaskManager.getService().unregisterTaskStackListener(this);
|
||||
if (!LawnchairQuickstepCompat.ATLEAST_V) return;
|
||||
ActivityTaskManager.getService().unregisterTaskStackListener(this);
|
||||
mRegistered = false;
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "Failed to call unregisterTaskStackListener", e);
|
||||
|
||||
@@ -12,7 +12,7 @@ android {
|
||||
sourceSets {
|
||||
main {
|
||||
java.srcDirs = ['shared/src']
|
||||
aidl.srcDirs = ['shared/src', 'wmshell/shared/aidl']
|
||||
aidl.srcDirs = ['shared/src']
|
||||
manifest.srcFile 'AndroidManifest.xml'
|
||||
res.srcDirs = ['shared']
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.android.wm.shell.common.desktopmode;
|
||||
|
||||
parcelable DesktopModeTransitionSource;
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.android.wm.shell.shared;
|
||||
|
||||
import android.window.RemoteTransition;
|
||||
import android.window.TransitionFilter;
|
||||
|
||||
/**
|
||||
* Listener interface that Launcher attaches to SystemUI to get home activity transition callbacks
|
||||
* on the default display.
|
||||
*/
|
||||
oneway interface IHomeTransitionListener {
|
||||
|
||||
/**
|
||||
* Called when a transition changes the visibility of the home activity on the default display.
|
||||
*/
|
||||
void onHomeVisibilityChanged(in boolean isVisible);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user