Override desktop tasks corner radius during recents transition
Set the corner radius of desktop task surfaces to 0 during recents transitions so that corner radius doesn't interfere with the surface bounds and corner radius applied to the RemoteAnimationTarget leashes. Bug: 378657004 Test: manual Flag: com.android.window.flags.enable_desktop_recents_transitions_corners_bugfix Change-Id: Ia653ace883cabfcd573ac138cb22affd96f7f229
This commit is contained in:
@@ -98,6 +98,7 @@ import android.view.animation.Interpolator;
|
||||
import android.widget.Toast;
|
||||
import android.window.DesktopModeFlags;
|
||||
import android.window.PictureInPictureSurfaceTransaction;
|
||||
import android.window.TransitionInfo;
|
||||
import android.window.WindowAnimationState;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
@@ -954,10 +955,10 @@ public abstract class AbsSwipeUpHandler<
|
||||
|
||||
@Override
|
||||
public void onRecentsAnimationStart(RecentsAnimationController controller,
|
||||
RecentsAnimationTargets targets) {
|
||||
super.onRecentsAnimationStart(controller, targets);
|
||||
RecentsAnimationTargets targets, TransitionInfo transitionInfo) {
|
||||
super.onRecentsAnimationStart(controller, targets, transitionInfo);
|
||||
if (targets.hasDesktopTasks(mContext)) {
|
||||
mRemoteTargetHandles = mTargetGluer.assignTargetsForDesktop(targets);
|
||||
mRemoteTargetHandles = mTargetGluer.assignTargetsForDesktop(targets, transitionInfo);
|
||||
} else {
|
||||
int untrimmedAppCount = mRemoteTargetHandles.length;
|
||||
mRemoteTargetHandles = mTargetGluer.assignTargetsForSplitScreen(targets);
|
||||
|
||||
@@ -33,6 +33,7 @@ import android.content.Intent;
|
||||
import android.os.SystemClock;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.RemoteAnimationTarget;
|
||||
import android.window.TransitionInfo;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
@@ -491,7 +492,7 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL
|
||||
|
||||
@Override
|
||||
public void onRecentsAnimationStart(RecentsAnimationController controller,
|
||||
RecentsAnimationTargets targets) {
|
||||
RecentsAnimationTargets targets, TransitionInfo info) {
|
||||
mStateCallback.setState(STATE_RECENTS_ANIMATION_STARTED);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import android.os.SystemClock
|
||||
import android.os.Trace
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.window.TransitionInfo
|
||||
import androidx.annotation.BinderThread
|
||||
import androidx.annotation.UiThread
|
||||
import androidx.annotation.VisibleForTesting
|
||||
@@ -369,6 +370,7 @@ constructor(
|
||||
override fun onRecentsAnimationStart(
|
||||
controller: RecentsAnimationController,
|
||||
targets: RecentsAnimationTargets,
|
||||
transitionInfo: TransitionInfo,
|
||||
) {
|
||||
Log.d(TAG, "recents animation started: $command")
|
||||
updateRecentsViewFocus(command)
|
||||
|
||||
@@ -26,6 +26,7 @@ import android.graphics.Rect;
|
||||
import android.os.Bundle;
|
||||
import android.util.ArraySet;
|
||||
import android.view.RemoteAnimationTarget;
|
||||
import android.window.TransitionInfo;
|
||||
|
||||
import androidx.annotation.BinderThread;
|
||||
import androidx.annotation.NonNull;
|
||||
@@ -93,7 +94,7 @@ public class RecentsAnimationCallbacks implements
|
||||
RemoteAnimationTarget[] appTargets, Rect homeContentInsets,
|
||||
Rect minimizedHomeBounds, Bundle extras) {
|
||||
onAnimationStart(controller, appTargets, new RemoteAnimationTarget[0],
|
||||
homeContentInsets, minimizedHomeBounds, extras);
|
||||
homeContentInsets, minimizedHomeBounds, extras, /* transitionInfo= */ null);
|
||||
}
|
||||
|
||||
// Called only in R+ platform
|
||||
@@ -101,7 +102,8 @@ public class RecentsAnimationCallbacks implements
|
||||
public final void onAnimationStart(RecentsAnimationControllerCompat animationController,
|
||||
RemoteAnimationTarget[] appTargets,
|
||||
RemoteAnimationTarget[] wallpaperTargets,
|
||||
Rect homeContentInsets, Rect minimizedHomeBounds, Bundle extras) {
|
||||
Rect homeContentInsets, Rect minimizedHomeBounds, Bundle extras,
|
||||
TransitionInfo transitionInfo) {
|
||||
long appCount = Arrays.stream(appTargets)
|
||||
.filter(app -> app.mode == MODE_CLOSING)
|
||||
.count();
|
||||
@@ -141,7 +143,7 @@ public class RecentsAnimationCallbacks implements
|
||||
Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(), () -> {
|
||||
ActiveGestureProtoLogProxy.logOnRecentsAnimationStart(targets.apps.length);
|
||||
for (RecentsAnimationListener listener : getListeners()) {
|
||||
listener.onRecentsAnimationStart(mController, targets);
|
||||
listener.onRecentsAnimationStart(mController, targets, transitionInfo);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -205,7 +207,7 @@ public class RecentsAnimationCallbacks implements
|
||||
*/
|
||||
public interface RecentsAnimationListener {
|
||||
default void onRecentsAnimationStart(RecentsAnimationController controller,
|
||||
RecentsAnimationTargets targets) {}
|
||||
RecentsAnimationTargets targets, TransitionInfo transitionInfo) {}
|
||||
|
||||
/**
|
||||
* Callback from the system when the recents animation is canceled. {@param thumbnailData}
|
||||
|
||||
@@ -24,6 +24,7 @@ import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
import android.util.Log;
|
||||
import android.view.RemoteAnimationTarget;
|
||||
import android.window.TransitionInfo;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
@@ -213,7 +214,8 @@ public class RemoteTargetGluer {
|
||||
* Similar to {@link #assignTargets(RemoteAnimationTargets)}, except this creates distinct
|
||||
* transform params per app in {@code targets.apps} list.
|
||||
*/
|
||||
public RemoteTargetHandle[] assignTargetsForDesktop(RemoteAnimationTargets targets) {
|
||||
public RemoteTargetHandle[] assignTargetsForDesktop(
|
||||
RemoteAnimationTargets targets, TransitionInfo transitionInfo) {
|
||||
resizeRemoteTargetHandles(targets);
|
||||
|
||||
for (int i = 0; i < mRemoteTargetHandles.length; i++) {
|
||||
@@ -222,6 +224,7 @@ public class RemoteTargetGluer {
|
||||
.filter(target -> target.taskId != primaryTaskTarget.taskId).toList();
|
||||
mRemoteTargetHandles[i].mTransformParams.setTargetSet(
|
||||
createRemoteAnimationTargetsForTarget(targets, excludeTargets));
|
||||
mRemoteTargetHandles[i].mTransformParams.setTransitionInfo(transitionInfo);
|
||||
mRemoteTargetHandles[i].mTaskViewSimulator.setPreview(primaryTaskTarget, null);
|
||||
}
|
||||
return mRemoteTargetHandles;
|
||||
|
||||
@@ -45,6 +45,7 @@ import android.window.IOnBackInvokedCallback
|
||||
import android.window.RemoteTransition
|
||||
import android.window.TaskSnapshot
|
||||
import android.window.TransitionFilter
|
||||
import android.window.TransitionInfo
|
||||
import androidx.annotation.MainThread
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import androidx.annotation.WorkerThread
|
||||
@@ -1174,6 +1175,7 @@ class SystemUiProxy @Inject constructor(@ApplicationContext private val context:
|
||||
homeContentInsets: Rect?,
|
||||
minimizedHomeBounds: Rect?,
|
||||
extras: Bundle?,
|
||||
transitionInfo: TransitionInfo?,
|
||||
) =
|
||||
listener.onAnimationStart(
|
||||
RecentsAnimationControllerCompat(controller),
|
||||
@@ -1186,6 +1188,7 @@ class SystemUiProxy @Inject constructor(@ApplicationContext private val context:
|
||||
// https://developer.android.com/guide/components/aidl#Bundles
|
||||
classLoader = SplitBounds::class.java.classLoader
|
||||
},
|
||||
transitionInfo,
|
||||
)
|
||||
|
||||
override fun onAnimationCanceled(taskIds: IntArray?, taskSnapshots: Array<TaskSnapshot>?) =
|
||||
|
||||
@@ -36,6 +36,7 @@ import android.content.Intent;
|
||||
import android.os.SystemProperties;
|
||||
import android.util.Log;
|
||||
import android.view.RemoteAnimationTarget;
|
||||
import android.window.TransitionInfo;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
@@ -69,6 +70,7 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn
|
||||
private RecentsAnimationController mController;
|
||||
private RecentsAnimationCallbacks mCallbacks;
|
||||
private RecentsAnimationTargets mTargets;
|
||||
private TransitionInfo mTransitionInfo;
|
||||
private RecentsAnimationDeviceState mDeviceState;
|
||||
|
||||
// Temporary until we can hook into gesture state events
|
||||
@@ -166,7 +168,7 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn
|
||||
mCallbacks.addListener(new RecentsAnimationCallbacks.RecentsAnimationListener() {
|
||||
@Override
|
||||
public void onRecentsAnimationStart(RecentsAnimationController controller,
|
||||
RecentsAnimationTargets targets) {
|
||||
RecentsAnimationTargets targets, TransitionInfo transitionInfo) {
|
||||
if (enableHandleDelayedGestureCallbacks() && mRecentsAnimationStartPending) {
|
||||
ActiveGestureProtoLogProxy.logStartRecentsAnimationCallback(
|
||||
"onRecentsAnimationStart");
|
||||
@@ -180,6 +182,7 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn
|
||||
}
|
||||
mController = controller;
|
||||
mTargets = targets;
|
||||
mTransitionInfo = transitionInfo;
|
||||
// TODO(b/236226779): We can probably get away w/ setting mLastAppearedTaskTargets
|
||||
// to all appeared targets directly vs just looking at running ones
|
||||
int[] runningTaskIds = mLastGestureState.getRunningTaskIds(targets.apps.length > 1);
|
||||
@@ -448,7 +451,7 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn
|
||||
public void notifyRecentsAnimationState(
|
||||
RecentsAnimationCallbacks.RecentsAnimationListener listener) {
|
||||
if (isRecentsAnimationRunning()) {
|
||||
listener.onRecentsAnimationStart(mController, mTargets);
|
||||
listener.onRecentsAnimationStart(mController, mTargets, mTransitionInfo);
|
||||
}
|
||||
// TODO: Do we actually need to report canceled/finished?
|
||||
}
|
||||
@@ -488,6 +491,7 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn
|
||||
mController = null;
|
||||
mCallbacks = null;
|
||||
mTargets = null;
|
||||
mTransitionInfo = null;
|
||||
mLastGestureState = null;
|
||||
mLastAppearedTaskTargets = null;
|
||||
}
|
||||
|
||||
@@ -189,7 +189,8 @@ public final class TaskViewUtils {
|
||||
RemoteTargetGluer gluer = new RemoteTargetGluer(v.getContext(),
|
||||
recentsView.getSizeStrategy(), targets, forDesktop);
|
||||
if (forDesktop) {
|
||||
remoteTargetHandles = gluer.assignTargetsForDesktop(targets);
|
||||
remoteTargetHandles =
|
||||
gluer.assignTargetsForDesktop(targets, /* transitionInfo=*/ null);
|
||||
} else if (v.containsMultipleTasks()) {
|
||||
remoteTargetHandles = gluer.assignTargetsForSplitScreen(targets,
|
||||
((GroupedTaskView) v).getSplitBoundsConfig());
|
||||
|
||||
@@ -49,6 +49,7 @@ import android.view.Surface;
|
||||
import android.view.SurfaceControl;
|
||||
import android.view.SurfaceControl.Transaction;
|
||||
import android.view.animation.Interpolator;
|
||||
import android.window.TransitionInfo;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
@@ -126,8 +127,8 @@ public class RecentsWindowSwipeHandler extends AbsSwipeUpHandler<RecentsWindowMa
|
||||
|
||||
@Override
|
||||
public void onRecentsAnimationStart(RecentsAnimationController controller,
|
||||
RecentsAnimationTargets targets) {
|
||||
super.onRecentsAnimationStart(controller, targets);
|
||||
RecentsAnimationTargets targets, TransitionInfo transitionInfo) {
|
||||
super.onRecentsAnimationStart(controller, targets, transitionInfo);
|
||||
initTransformParams();
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ import android.graphics.PointF;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.RemoteAnimationTarget;
|
||||
import android.view.VelocityTracker;
|
||||
import android.window.TransitionInfo;
|
||||
|
||||
import com.android.app.animation.Interpolators;
|
||||
import com.android.launcher3.R;
|
||||
@@ -248,7 +249,7 @@ public class DeviceLockedInputConsumer implements InputConsumer,
|
||||
|
||||
@Override
|
||||
public void onRecentsAnimationStart(RecentsAnimationController controller,
|
||||
RecentsAnimationTargets targets) {
|
||||
RecentsAnimationTargets targets, TransitionInfo transitionInfo) {
|
||||
mRecentsAnimationController = controller;
|
||||
mTransformParams.setTargetSet(targets);
|
||||
applyTransform();
|
||||
|
||||
+2
-1
@@ -28,6 +28,7 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Point;
|
||||
import android.view.MotionEvent;
|
||||
import android.window.TransitionInfo;
|
||||
|
||||
import com.android.launcher3.anim.AnimatedFloat;
|
||||
import com.android.launcher3.anim.AnimatorListeners;
|
||||
@@ -172,7 +173,7 @@ public class ProgressDelegateInputConsumer implements InputConsumer,
|
||||
|
||||
@Override
|
||||
public void onRecentsAnimationStart(RecentsAnimationController controller,
|
||||
RecentsAnimationTargets targets) {
|
||||
RecentsAnimationTargets targets, TransitionInfo transitionInfo) {
|
||||
mRecentsAnimationController = controller;
|
||||
mStateCallback.setState(STATE_TARGET_RECEIVED);
|
||||
}
|
||||
|
||||
@@ -678,7 +678,7 @@ public class SplitSelectStateController {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startAnimation(IBinder transition, TransitionInfo info,
|
||||
public void startAnimation(IBinder transition, TransitionInfo transitionInfo,
|
||||
SurfaceControl.Transaction t,
|
||||
IRemoteTransitionFinishedCallback finishedCallback) {
|
||||
final Runnable finishAdapter = () -> {
|
||||
@@ -708,7 +708,7 @@ public class SplitSelectStateController {
|
||||
null /* nonApps */,
|
||||
mStateManager,
|
||||
mDepthController,
|
||||
info, t, () -> {
|
||||
transitionInfo, t, () -> {
|
||||
finishAdapter.run();
|
||||
cleanup(true /*success*/);
|
||||
},
|
||||
@@ -920,7 +920,7 @@ public class SplitSelectStateController {
|
||||
|
||||
@Override
|
||||
public void onRecentsAnimationStart(RecentsAnimationController controller,
|
||||
RecentsAnimationTargets targets) {
|
||||
RecentsAnimationTargets targets, TransitionInfo transitionInfo) {
|
||||
StatsLogManager.LauncherEvent launcherDesktopSplitEvent =
|
||||
mSplitPosition == STAGE_POSITION_BOTTOM_OR_RIGHT ?
|
||||
LAUNCHER_DESKTOP_MODE_SPLIT_RIGHT_BOTTOM :
|
||||
|
||||
@@ -30,6 +30,7 @@ import android.app.ActivityManager;
|
||||
import android.app.ActivityOptions;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.window.TransitionInfo;
|
||||
|
||||
import androidx.annotation.BinderThread;
|
||||
|
||||
@@ -122,7 +123,7 @@ public class SplitWithKeyboardShortcutController {
|
||||
|
||||
@Override
|
||||
public void onRecentsAnimationStart(RecentsAnimationController controller,
|
||||
RecentsAnimationTargets targets) {
|
||||
RecentsAnimationTargets targets, TransitionInfo transitionInfo) {
|
||||
mController.setInitialTaskSelect(mRunningTaskInfo,
|
||||
mLeftOrTop ? STAGE_POSITION_TOP_OR_LEFT : STAGE_POSITION_BOTTOM_OR_RIGHT,
|
||||
null /* itemInfo */,
|
||||
|
||||
@@ -19,9 +19,12 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
|
||||
|
||||
import android.util.FloatProperty;
|
||||
import android.view.RemoteAnimationTarget;
|
||||
import android.view.SurfaceControl;
|
||||
import android.window.TransitionInfo;
|
||||
|
||||
import com.android.quickstep.RemoteAnimationTargets;
|
||||
import com.android.quickstep.util.SurfaceTransaction.SurfaceProperties;
|
||||
import com.android.window.flags.Flags;
|
||||
|
||||
public class TransformParams {
|
||||
|
||||
@@ -56,6 +59,7 @@ public class TransformParams {
|
||||
private float mTargetAlpha;
|
||||
private float mCornerRadius;
|
||||
private RemoteAnimationTargets mTargetSet;
|
||||
private TransitionInfo mTransitionInfo;
|
||||
private SurfaceTransactionApplier mSyncTransactionApplier;
|
||||
|
||||
private BuilderProxy mHomeBuilderProxy = BuilderProxy.ALWAYS_VISIBLE;
|
||||
@@ -106,6 +110,14 @@ public class TransformParams {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the {@code TransitionInfo} of the transition that this transformation stems from.
|
||||
*/
|
||||
public TransformParams setTransitionInfo(TransitionInfo transitionInfo) {
|
||||
mTransitionInfo = transitionInfo;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the SyncRtSurfaceTransactionApplierCompat that will apply the SurfaceParams that
|
||||
* are computed based on these TransformParams.
|
||||
@@ -152,6 +164,9 @@ public class TransformParams {
|
||||
builder.setAlpha(getTargetAlpha());
|
||||
}
|
||||
targetProxy.onBuildTargetParams(builder, app, this);
|
||||
// Override the corner radius for {@code app} with the leash used by Shell, so that it
|
||||
// doesn't interfere with the window clip and corner radius applied here.
|
||||
overrideChangeLeashCornerRadiusToZero(app, transaction.getTransaction());
|
||||
}
|
||||
|
||||
// always put wallpaper layer to bottom.
|
||||
@@ -163,6 +178,28 @@ public class TransformParams {
|
||||
return transaction;
|
||||
}
|
||||
|
||||
private void overrideChangeLeashCornerRadiusToZero(
|
||||
RemoteAnimationTarget app, SurfaceControl.Transaction transaction) {
|
||||
if (!Flags.enableDesktopRecentsTransitionsCornersBugfix()) {
|
||||
return;
|
||||
}
|
||||
SurfaceControl changeLeash = getChangeLeashForApp(app);
|
||||
if (changeLeash != null) {
|
||||
transaction.setCornerRadius(changeLeash, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private SurfaceControl getChangeLeashForApp(RemoteAnimationTarget app) {
|
||||
if (mTransitionInfo == null) return null;
|
||||
for (TransitionInfo.Change change : mTransitionInfo.getChanges()) {
|
||||
if (change.getTaskInfo() == null) continue;
|
||||
if (change.getTaskInfo().taskId == app.taskId) {
|
||||
return change.getLeash();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Pubic getters so outside packages can read the values.
|
||||
|
||||
public float getProgress() {
|
||||
|
||||
@@ -5867,7 +5867,8 @@ public abstract class RecentsView<
|
||||
if (recentsAnimationTargets.hasDesktopTasks(mContext)) {
|
||||
gluer = new RemoteTargetGluer(getContext(), getSizeStrategy(), recentsAnimationTargets,
|
||||
true /* forDesktop */);
|
||||
mRemoteTargetHandles = gluer.assignTargetsForDesktop(recentsAnimationTargets);
|
||||
mRemoteTargetHandles = gluer.assignTargetsForDesktop(
|
||||
recentsAnimationTargets, /* transitionInfo= */ null);
|
||||
} else {
|
||||
gluer = new RemoteTargetGluer(getContext(), getSizeStrategy(), recentsAnimationTargets,
|
||||
false);
|
||||
|
||||
+1
-1
@@ -370,7 +370,7 @@ public abstract class AbsSwipeUpHandlerTestCase<
|
||||
|
||||
private void onRecentsAnimationStart(SWIPE_HANDLER absSwipeUpHandler) {
|
||||
runOnMainSync(() -> absSwipeUpHandler.onRecentsAnimationStart(
|
||||
mRecentsAnimationController, mRecentsAnimationTargets));
|
||||
mRecentsAnimationController, mRecentsAnimationTargets, /* transitionInfo= */null));
|
||||
}
|
||||
|
||||
protected static void runOnMainSync(Runnable runnable) {
|
||||
|
||||
Reference in New Issue
Block a user