Merge "Add fallback animation for auto-enter without source rect hint" into sc-dev

This commit is contained in:
Winson Chung
2021-05-14 23:44:23 +00:00
committed by Android (Google) Code Review
11 changed files with 143 additions and 53 deletions

View File

@@ -18,6 +18,7 @@ package android.view;
import android.app.ActivityManager; import android.app.ActivityManager;
import android.view.IRemoteAnimationFinishedCallback; import android.view.IRemoteAnimationFinishedCallback;
import android.view.SurfaceControl;
import android.graphics.GraphicBuffer; import android.graphics.GraphicBuffer;
import android.window.PictureInPictureSurfaceTransaction; import android.window.PictureInPictureSurfaceTransaction;
import android.window.TaskSnapshot; import android.window.TaskSnapshot;
@@ -43,9 +44,10 @@ interface IRecentsAnimationController {
* updated accordingly. This should be called before `finish` * updated accordingly. This should be called before `finish`
* @param taskId for which the leash should be updated * @param taskId for which the leash should be updated
* @param finishTransaction leash operations for the final transform. * @param finishTransaction leash operations for the final transform.
* @param overlay the surface control for an overlay being shown above the pip (can be null)
*/ */
void setFinishTaskTransaction(int taskId, void setFinishTaskTransaction(int taskId,
in PictureInPictureSurfaceTransaction finishTransaction); in PictureInPictureSurfaceTransaction finishTransaction, in SurfaceControl overlay);
/** /**
* Notifies to the system that the animation into Recents should end, and all leashes associated * Notifies to the system that the animation into Recents should end, and all leashes associated

View File

@@ -24,6 +24,9 @@
<!-- Animation duration for resizing of PIP. --> <!-- Animation duration for resizing of PIP. -->
<integer name="config_pipResizeAnimationDuration">425</integer> <integer name="config_pipResizeAnimationDuration">425</integer>
<!-- Animation duration for crossfading of PIP (specifically to fade out the layer on top). -->
<integer name="config_pipCrossfadeAnimationDuration">150</integer>
<!-- Allow dragging the PIP to a location to close it --> <!-- Allow dragging the PIP to a location to close it -->
<bool name="config_pipEnableDismissDragToEdge">true</bool> <bool name="config_pipEnableDismissDragToEdge">true</bool>

View File

@@ -42,7 +42,7 @@ public class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener {
private final SyncTransactionQueue mSyncQueue; private final SyncTransactionQueue mSyncQueue;
private final SparseArray<SurfaceControl> mLeashByTaskId = new SparseArray<>(); private final SparseArray<TaskData> mDataByTaskId = new SparseArray<>();
public FullscreenTaskListener(SyncTransactionQueue syncQueue) { public FullscreenTaskListener(SyncTransactionQueue syncQueue) {
mSyncQueue = syncQueue; mSyncQueue = syncQueue;
@@ -50,14 +50,14 @@ public class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener {
@Override @Override
public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) { public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) {
if (mLeashByTaskId.get(taskInfo.taskId) != null) { if (mDataByTaskId.get(taskInfo.taskId) != null) {
throw new IllegalStateException("Task appeared more than once: #" + taskInfo.taskId); throw new IllegalStateException("Task appeared more than once: #" + taskInfo.taskId);
} }
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Fullscreen Task Appeared: #%d", ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Fullscreen Task Appeared: #%d",
taskInfo.taskId); taskInfo.taskId);
mLeashByTaskId.put(taskInfo.taskId, leash);
if (Transitions.ENABLE_SHELL_TRANSITIONS) return;
final Point positionInParent = taskInfo.positionInParent; final Point positionInParent = taskInfo.positionInParent;
mDataByTaskId.put(taskInfo.taskId, new TaskData(leash, positionInParent));
if (Transitions.ENABLE_SHELL_TRANSITIONS) return;
mSyncQueue.runInSync(t -> { mSyncQueue.runInSync(t -> {
// Reset several properties back to fullscreen (PiP, for example, leaves all these // Reset several properties back to fullscreen (PiP, for example, leaves all these
// properties in a bad state). // properties in a bad state).
@@ -72,45 +72,57 @@ public class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener {
@Override @Override
public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) { public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) {
if (Transitions.ENABLE_SHELL_TRANSITIONS) return; if (Transitions.ENABLE_SHELL_TRANSITIONS) return;
final SurfaceControl leash = mLeashByTaskId.get(taskInfo.taskId); final TaskData data = mDataByTaskId.get(taskInfo.taskId);
final Point positionInParent = taskInfo.positionInParent; final Point positionInParent = taskInfo.positionInParent;
mSyncQueue.runInSync(t -> { if (!positionInParent.equals(data.positionInParent)) {
// Reset several properties back. For instance, when an Activity enters PiP with data.positionInParent.set(positionInParent.x, positionInParent.y);
// multiple activities in the same task, a new task will be created from that Activity mSyncQueue.runInSync(t -> {
// and we want reset the leash of the original task. t.setPosition(data.surface, positionInParent.x, positionInParent.y);
t.setPosition(leash, positionInParent.x, positionInParent.y); });
t.setWindowCrop(leash, null); }
});
} }
@Override @Override
public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) { public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
if (mLeashByTaskId.get(taskInfo.taskId) == null) { if (mDataByTaskId.get(taskInfo.taskId) == null) {
Slog.e(TAG, "Task already vanished: #" + taskInfo.taskId); Slog.e(TAG, "Task already vanished: #" + taskInfo.taskId);
return; return;
} }
mLeashByTaskId.remove(taskInfo.taskId); mDataByTaskId.remove(taskInfo.taskId);
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Fullscreen Task Vanished: #%d", ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Fullscreen Task Vanished: #%d",
taskInfo.taskId); taskInfo.taskId);
} }
@Override @Override
public void attachChildSurfaceToTask(int taskId, SurfaceControl.Builder b) { public void attachChildSurfaceToTask(int taskId, SurfaceControl.Builder b) {
if (!mLeashByTaskId.contains(taskId)) { if (!mDataByTaskId.contains(taskId)) {
throw new IllegalArgumentException("There is no surface for taskId=" + taskId); throw new IllegalArgumentException("There is no surface for taskId=" + taskId);
} }
b.setParent(mLeashByTaskId.get(taskId)); b.setParent(mDataByTaskId.get(taskId).surface);
} }
@Override @Override
public void dump(@NonNull PrintWriter pw, String prefix) { public void dump(@NonNull PrintWriter pw, String prefix) {
final String innerPrefix = prefix + " "; final String innerPrefix = prefix + " ";
pw.println(prefix + this); pw.println(prefix + this);
pw.println(innerPrefix + mLeashByTaskId.size() + " Tasks"); pw.println(innerPrefix + mDataByTaskId.size() + " Tasks");
} }
@Override @Override
public String toString() { public String toString() {
return TAG + ":" + taskListenerTypeToString(TASK_LISTENER_TYPE_FULLSCREEN); return TAG + ":" + taskListenerTypeToString(TASK_LISTENER_TYPE_FULLSCREEN);
} }
/**
* Per-task data for each managed task.
*/
private static class TaskData {
public final SurfaceControl surface;
public final Point positionInParent;
public TaskData(SurfaceControl surface, Point positionInParent) {
this.surface = surface;
this.positionInParent = positionInParent;
}
}
} }

View File

@@ -17,6 +17,7 @@
package com.android.wm.shell.pip; package com.android.wm.shell.pip;
import android.app.PictureInPictureParams; import android.app.PictureInPictureParams;
import android.view.SurfaceControl;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.pm.ActivityInfo; import android.content.pm.ActivityInfo;
import android.graphics.Rect; import android.graphics.Rect;
@@ -48,8 +49,10 @@ interface IPip {
* *
* @param componentName ComponentName represents the Activity * @param componentName ComponentName represents the Activity
* @param destinationBounds the destination bounds the PiP window lands into * @param destinationBounds the destination bounds the PiP window lands into
* @param overlay an optional overlay to fade out after entering PiP
*/ */
oneway void stopSwipePipToHome(in ComponentName componentName, in Rect destinationBounds) = 2; oneway void stopSwipePipToHome(in ComponentName componentName, in Rect destinationBounds,
in SurfaceControl overlay) = 2;
/** /**
* Sets listener to get pinned stack animation callbacks. * Sets listener to get pinned stack animation callbacks.

View File

@@ -147,6 +147,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
private final PipUiEventLogger mPipUiEventLoggerLogger; private final PipUiEventLogger mPipUiEventLoggerLogger;
private final int mEnterAnimationDuration; private final int mEnterAnimationDuration;
private final int mExitAnimationDuration; private final int mExitAnimationDuration;
private final int mCrossFadeAnimationDuration;
private final PipSurfaceTransactionHelper mSurfaceTransactionHelper; private final PipSurfaceTransactionHelper mSurfaceTransactionHelper;
private final Optional<LegacySplitScreenController> mSplitScreenOptional; private final Optional<LegacySplitScreenController> mSplitScreenOptional;
protected final ShellTaskOrganizer mTaskOrganizer; protected final ShellTaskOrganizer mTaskOrganizer;
@@ -257,6 +258,12 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
*/ */
private boolean mInSwipePipToHomeTransition; private boolean mInSwipePipToHomeTransition;
/**
* An optional overlay used to mask content changing between an app in/out of PiP, only set if
* {@link #mInSwipePipToHomeTransition} is true.
*/
private SurfaceControl mSwipePipToHomeOverlay;
public PipTaskOrganizer(Context context, public PipTaskOrganizer(Context context,
@NonNull SyncTransactionQueue syncTransactionQueue, @NonNull SyncTransactionQueue syncTransactionQueue,
@NonNull PipBoundsState pipBoundsState, @NonNull PipBoundsState pipBoundsState,
@@ -280,6 +287,8 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
.getInteger(R.integer.config_pipEnterAnimationDuration); .getInteger(R.integer.config_pipEnterAnimationDuration);
mExitAnimationDuration = context.getResources() mExitAnimationDuration = context.getResources()
.getInteger(R.integer.config_pipExitAnimationDuration); .getInteger(R.integer.config_pipExitAnimationDuration);
mCrossFadeAnimationDuration = context.getResources()
.getInteger(R.integer.config_pipCrossfadeAnimationDuration);
mSurfaceTransactionHelper = surfaceTransactionHelper; mSurfaceTransactionHelper = surfaceTransactionHelper;
mPipAnimationController = pipAnimationController; mPipAnimationController = pipAnimationController;
mPipUiEventLoggerLogger = pipUiEventLogger; mPipUiEventLoggerLogger = pipUiEventLogger;
@@ -350,10 +359,12 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
* Callback when launcher finishes swipe-pip-to-home operation. * Callback when launcher finishes swipe-pip-to-home operation.
* Expect {@link #onTaskAppeared(ActivityManager.RunningTaskInfo, SurfaceControl)} afterwards. * Expect {@link #onTaskAppeared(ActivityManager.RunningTaskInfo, SurfaceControl)} afterwards.
*/ */
public void stopSwipePipToHome(ComponentName componentName, Rect destinationBounds) { public void stopSwipePipToHome(ComponentName componentName, Rect destinationBounds,
SurfaceControl overlay) {
// do nothing if there is no startSwipePipToHome being called before // do nothing if there is no startSwipePipToHome being called before
if (mInSwipePipToHomeTransition) { if (mInSwipePipToHomeTransition) {
mPipBoundsState.setBounds(destinationBounds); mPipBoundsState.setBounds(destinationBounds);
mSwipePipToHomeOverlay = overlay;
} }
} }
@@ -599,6 +610,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
private void onEndOfSwipePipToHomeTransition() { private void onEndOfSwipePipToHomeTransition() {
final Rect destinationBounds = mPipBoundsState.getBounds(); final Rect destinationBounds = mPipBoundsState.getBounds();
final SurfaceControl swipeToHomeOverlay = mSwipePipToHomeOverlay;
final SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction(); final SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction();
mSurfaceTransactionHelper.resetScale(tx, mLeash, destinationBounds); mSurfaceTransactionHelper.resetScale(tx, mLeash, destinationBounds);
mSurfaceTransactionHelper.crop(tx, mLeash, destinationBounds); mSurfaceTransactionHelper.crop(tx, mLeash, destinationBounds);
@@ -607,8 +619,14 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
// Ensure menu's settled in its final bounds first. // Ensure menu's settled in its final bounds first.
finishResizeForMenu(destinationBounds); finishResizeForMenu(destinationBounds);
sendOnPipTransitionFinished(TRANSITION_DIRECTION_TO_PIP); sendOnPipTransitionFinished(TRANSITION_DIRECTION_TO_PIP);
// Remove the swipe to home overlay
if (swipeToHomeOverlay != null) {
fadeOutAndRemoveOverlay(swipeToHomeOverlay);
}
}, tx); }, tx);
mInSwipePipToHomeTransition = false; mInSwipePipToHomeTransition = false;
mSwipePipToHomeOverlay = null;
} }
private void applyEnterPipSyncTransaction(Rect destinationBounds, Runnable runnable, private void applyEnterPipSyncTransaction(Rect destinationBounds, Runnable runnable,
@@ -1139,25 +1157,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
mSurfaceTransactionHelper.scale(t, snapshotSurface, snapshotSrc, snapshotDest); mSurfaceTransactionHelper.scale(t, snapshotSurface, snapshotSrc, snapshotDest);
// Start animation to fade out the snapshot. // Start animation to fade out the snapshot.
final ValueAnimator animator = ValueAnimator.ofFloat(1.0f, 0.0f); fadeOutAndRemoveOverlay(snapshotSurface);
animator.setDuration(mEnterAnimationDuration);
animator.addUpdateListener(animation -> {
final float alpha = (float) animation.getAnimatedValue();
final SurfaceControl.Transaction transaction =
mSurfaceControlTransactionFactory.getTransaction();
transaction.setAlpha(snapshotSurface, alpha);
transaction.apply();
});
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
final SurfaceControl.Transaction tx =
mSurfaceControlTransactionFactory.getTransaction();
tx.remove(snapshotSurface);
tx.apply();
}
});
animator.start();
}); });
} else { } else {
applyFinishBoundsResize(wct, direction); applyFinishBoundsResize(wct, direction);
@@ -1300,6 +1300,35 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
return true; return true;
} }
/**
* Fades out and removes an overlay surface.
*/
private void fadeOutAndRemoveOverlay(SurfaceControl surface) {
if (surface == null) {
return;
}
final ValueAnimator animator = ValueAnimator.ofFloat(1.0f, 0.0f);
animator.setDuration(mCrossFadeAnimationDuration);
animator.addUpdateListener(animation -> {
final float alpha = (float) animation.getAnimatedValue();
final SurfaceControl.Transaction transaction =
mSurfaceControlTransactionFactory.getTransaction();
transaction.setAlpha(surface, alpha);
transaction.apply();
});
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
final SurfaceControl.Transaction tx =
mSurfaceControlTransactionFactory.getTransaction();
tx.remove(surface);
tx.apply();
}
});
animator.start();
}
/** /**
* Dumps internal states. * Dumps internal states.
*/ */

View File

@@ -44,6 +44,7 @@ import android.util.Pair;
import android.util.Size; import android.util.Size;
import android.util.Slog; import android.util.Slog;
import android.view.DisplayInfo; import android.view.DisplayInfo;
import android.view.SurfaceControl;
import android.view.WindowManagerGlobal; import android.view.WindowManagerGlobal;
import android.window.WindowContainerTransaction; import android.window.WindowContainerTransaction;
@@ -557,8 +558,9 @@ public class PipController implements PipTransitionController.PipTransitionCallb
return entryBounds; return entryBounds;
} }
private void stopSwipePipToHome(ComponentName componentName, Rect destinationBounds) { private void stopSwipePipToHome(ComponentName componentName, Rect destinationBounds,
mPipTaskOrganizer.stopSwipePipToHome(componentName, destinationBounds); SurfaceControl overlay) {
mPipTaskOrganizer.stopSwipePipToHome(componentName, destinationBounds, overlay);
} }
@Override @Override
@@ -850,10 +852,11 @@ public class PipController implements PipTransitionController.PipTransitionCallb
} }
@Override @Override
public void stopSwipePipToHome(ComponentName componentName, Rect destinationBounds) { public void stopSwipePipToHome(ComponentName componentName, Rect destinationBounds,
SurfaceControl overlay) {
executeRemoteCallWithTaskPermission(mController, "stopSwipePipToHome", executeRemoteCallWithTaskPermission(mController, "stopSwipePipToHome",
(controller) -> { (controller) -> {
controller.stopSwipePipToHome(componentName, destinationBounds); controller.stopSwipePipToHome(componentName, destinationBounds, overlay);
}); });
} }

View File

@@ -19,6 +19,7 @@ package com.android.systemui.shared.system;
import android.os.RemoteException; import android.os.RemoteException;
import android.util.Log; import android.util.Log;
import android.view.IRecentsAnimationController; import android.view.IRecentsAnimationController;
import android.view.SurfaceControl;
import android.window.PictureInPictureSurfaceTransaction; import android.window.PictureInPictureSurfaceTransaction;
import android.window.TaskSnapshot; import android.window.TaskSnapshot;
@@ -76,11 +77,13 @@ public class RecentsAnimationControllerCompat {
* updated accordingly. This should be called before `finish` * updated accordingly. This should be called before `finish`
* @param taskId Task id of the Activity in PiP mode. * @param taskId Task id of the Activity in PiP mode.
* @param finishTransaction leash operations for the final transform. * @param finishTransaction leash operations for the final transform.
* @param overlay the surface control for an overlay being shown above the pip (can be null)
*/ */
public void setFinishTaskTransaction(int taskId, public void setFinishTaskTransaction(int taskId,
PictureInPictureSurfaceTransaction finishTransaction) { PictureInPictureSurfaceTransaction finishTransaction,
SurfaceControl overlay) {
try { try {
mAnimationController.setFinishTaskTransaction(taskId, finishTransaction); mAnimationController.setFinishTaskTransaction(taskId, finishTransaction, overlay);
} catch (RemoteException e) { } catch (RemoteException e) {
Log.d(TAG, "Failed to set finish task bounds", e); Log.d(TAG, "Failed to set finish task bounds", e);
} }

View File

@@ -236,9 +236,9 @@ public class RemoteTransitionCompat implements Parcelable {
} }
@Override public void setFinishTaskTransaction(int taskId, @Override public void setFinishTaskTransaction(int taskId,
PictureInPictureSurfaceTransaction finishTransaction) { PictureInPictureSurfaceTransaction finishTransaction, SurfaceControl overlay) {
if (mWrapped != null) { if (mWrapped != null) {
mWrapped.setFinishTaskTransaction(taskId, finishTransaction); mWrapped.setFinishTaskTransaction(taskId, finishTransaction, overlay);
} }
} }

View File

@@ -231,7 +231,8 @@ public class RecentsAnimationController implements DeathRecipient {
@Override @Override
public void setFinishTaskTransaction(int taskId, public void setFinishTaskTransaction(int taskId,
PictureInPictureSurfaceTransaction finishTransaction) { PictureInPictureSurfaceTransaction finishTransaction,
SurfaceControl overlay) {
ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS,
"setFinishTaskTransaction(%d): transaction=%s", taskId, finishTransaction); "setFinishTaskTransaction(%d): transaction=%s", taskId, finishTransaction);
final long token = Binder.clearCallingIdentity(); final long token = Binder.clearCallingIdentity();
@@ -241,6 +242,7 @@ public class RecentsAnimationController implements DeathRecipient {
final TaskAnimationAdapter taskAdapter = mPendingAnimations.get(i); final TaskAnimationAdapter taskAdapter = mPendingAnimations.get(i);
if (taskAdapter.mTask.mTaskId == taskId) { if (taskAdapter.mTask.mTaskId == taskId) {
taskAdapter.mFinishTransaction = finishTransaction; taskAdapter.mFinishTransaction = finishTransaction;
taskAdapter.mFinishOverlay = overlay;
break; break;
} }
} }
@@ -512,7 +514,6 @@ public class RecentsAnimationController implements DeathRecipient {
void removeAnimation(TaskAnimationAdapter taskAdapter) { void removeAnimation(TaskAnimationAdapter taskAdapter) {
ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS,
"removeAnimation(%d)", taskAdapter.mTask.mTaskId); "removeAnimation(%d)", taskAdapter.mTask.mTaskId);
taskAdapter.mTask.setCanAffectSystemUiFlags(true);
taskAdapter.mCapturedFinishCallback.onAnimationFinished(taskAdapter.mLastAnimationType, taskAdapter.mCapturedFinishCallback.onAnimationFinished(taskAdapter.mLastAnimationType,
taskAdapter); taskAdapter);
mPendingAnimations.remove(taskAdapter); mPendingAnimations.remove(taskAdapter);
@@ -1100,6 +1101,8 @@ public class RecentsAnimationController implements DeathRecipient {
private final Rect mLocalBounds = new Rect(); private final Rect mLocalBounds = new Rect();
// The final surface transaction when animation is finished. // The final surface transaction when animation is finished.
private PictureInPictureSurfaceTransaction mFinishTransaction; private PictureInPictureSurfaceTransaction mFinishTransaction;
// An overlay used to mask the content as an app goes into PIP
private SurfaceControl mFinishOverlay;
TaskAnimationAdapter(Task task, boolean isRecentTaskInvisible) { TaskAnimationAdapter(Task task, boolean isRecentTaskInvisible) {
mTask = task; mTask = task;
@@ -1137,20 +1140,38 @@ public class RecentsAnimationController implements DeathRecipient {
void onCleanup() { void onCleanup() {
if (mFinishTransaction != null) { if (mFinishTransaction != null) {
final Transaction pendingTransaction = mTask.getPendingTransaction(); final Transaction pendingTransaction = mTask.getPendingTransaction();
// Reparent the overlay
if (mFinishOverlay != null) {
pendingTransaction.reparent(mFinishOverlay, mTask.mSurfaceControl);
}
// Transfer the transform from the leash to the task
PictureInPictureSurfaceTransaction.apply(mFinishTransaction, PictureInPictureSurfaceTransaction.apply(mFinishTransaction,
mTask.mSurfaceControl, pendingTransaction); mTask.mSurfaceControl, pendingTransaction);
mTask.setLastRecentsAnimationTransaction(mFinishTransaction); mTask.setLastRecentsAnimationTransaction(mFinishTransaction, mFinishOverlay);
if (mDisplayContent.isFixedRotationLaunchingApp(mTargetActivityRecord)) { if (mDisplayContent.isFixedRotationLaunchingApp(mTargetActivityRecord)) {
// The transaction is needed for position when rotating the display. // The transaction is needed for position when rotating the display.
mDisplayContent.mPinnedTaskController.setEnterPipTransaction( mDisplayContent.mPinnedTaskController.setEnterPipTransaction(
mFinishTransaction); mFinishTransaction);
} }
mFinishTransaction = null; mFinishTransaction = null;
mFinishOverlay = null;
pendingTransaction.apply(); pendingTransaction.apply();
// In the case where we are transferring the transform to the task in preparation
// for entering PIP, we disable the task being able to affect sysui flags otherwise
// it may cause a flash
if (mTask.getActivityType() != mTargetActivityType) {
mTask.setCanAffectSystemUiFlags(false);
}
} else if (!mTask.isAttached()) { } else if (!mTask.isAttached()) {
// Apply the task's pending transaction in case it is detached and its transaction // Apply the task's pending transaction in case it is detached and its transaction
// is not reachable. // is not reachable.
mTask.getPendingTransaction().apply(); mTask.getPendingTransaction().apply();
// Reset whether this task can affect the sysui flags
mTask.setCanAffectSystemUiFlags(true);
} }
} }

View File

@@ -2139,7 +2139,8 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
// Move the last recents animation transaction from original task to the new one. // Move the last recents animation transaction from original task to the new one.
if (task.mLastRecentsAnimationTransaction != null) { if (task.mLastRecentsAnimationTransaction != null) {
rootTask.setLastRecentsAnimationTransaction( rootTask.setLastRecentsAnimationTransaction(
task.mLastRecentsAnimationTransaction); task.mLastRecentsAnimationTransaction,
task.mLastRecentsAnimationOverlay);
task.clearLastRecentsAnimationTransaction(); task.clearLastRecentsAnimationTransaction();
} }

View File

@@ -482,6 +482,9 @@ class Task extends WindowContainer<WindowContainer> {
// Do not forget to reset this after reparenting. // Do not forget to reset this after reparenting.
// TODO: remove this once the recents animation is moved to the Shell // TODO: remove this once the recents animation is moved to the Shell
PictureInPictureSurfaceTransaction mLastRecentsAnimationTransaction; PictureInPictureSurfaceTransaction mLastRecentsAnimationTransaction;
// The content overlay to be applied with mLastRecentsAnimationTransaction
// TODO: remove this once the recents animation is moved to the Shell
SurfaceControl mLastRecentsAnimationOverlay;
static final int LAYER_RANK_INVISIBLE = -1; static final int LAYER_RANK_INVISIBLE = -1;
// Ranking (from top) of this task among all visible tasks. (-1 means it's not visible) // Ranking (from top) of this task among all visible tasks. (-1 means it's not visible)
@@ -5383,6 +5386,10 @@ class Task extends WindowContainer<WindowContainer> {
: WINDOWING_MODE_FULLSCREEN; : WINDOWING_MODE_FULLSCREEN;
} }
if (currentMode == WINDOWING_MODE_PINNED) { if (currentMode == WINDOWING_MODE_PINNED) {
// In the case that we've disabled affecting the SysUI flags as a part of seamlessly
// transferring the transform on the leash to the task, reset this state once we've
// actually entered pip
setCanAffectSystemUiFlags(true);
mRootWindowContainer.notifyActivityPipModeChanged(null); mRootWindowContainer.notifyActivityPipModeChanged(null);
} }
if (likelyResolvedMode == WINDOWING_MODE_PINNED if (likelyResolvedMode == WINDOWING_MODE_PINNED
@@ -7616,22 +7623,28 @@ class Task extends WindowContainer<WindowContainer> {
reparent(newParent, onTop ? POSITION_TOP : POSITION_BOTTOM); reparent(newParent, onTop ? POSITION_TOP : POSITION_BOTTOM);
} }
void setLastRecentsAnimationTransaction( void setLastRecentsAnimationTransaction(@NonNull PictureInPictureSurfaceTransaction transaction,
@NonNull PictureInPictureSurfaceTransaction transaction) { @Nullable SurfaceControl overlay) {
mLastRecentsAnimationTransaction = new PictureInPictureSurfaceTransaction(transaction); mLastRecentsAnimationTransaction = new PictureInPictureSurfaceTransaction(transaction);
mLastRecentsAnimationOverlay = overlay;
} }
void clearLastRecentsAnimationTransaction() { void clearLastRecentsAnimationTransaction() {
mLastRecentsAnimationTransaction = null; mLastRecentsAnimationTransaction = null;
mLastRecentsAnimationOverlay = null;
// reset also the transform introduced by mLastRecentsAnimationTransaction // reset also the transform introduced by mLastRecentsAnimationTransaction
getPendingTransaction().setMatrix(mSurfaceControl, Matrix.IDENTITY_MATRIX, new float[9]); getPendingTransaction().setMatrix(mSurfaceControl, Matrix.IDENTITY_MATRIX, new float[9]);
} }
void maybeApplyLastRecentsAnimationTransaction() { void maybeApplyLastRecentsAnimationTransaction() {
if (mLastRecentsAnimationTransaction != null) { if (mLastRecentsAnimationTransaction != null) {
if (mLastRecentsAnimationOverlay != null) {
getPendingTransaction().reparent(mLastRecentsAnimationOverlay, mSurfaceControl);
}
PictureInPictureSurfaceTransaction.apply(mLastRecentsAnimationTransaction, PictureInPictureSurfaceTransaction.apply(mLastRecentsAnimationTransaction,
mSurfaceControl, getPendingTransaction()); mSurfaceControl, getPendingTransaction());
mLastRecentsAnimationTransaction = null; mLastRecentsAnimationTransaction = null;
mLastRecentsAnimationOverlay = null;
} }
} }