Merge "Add fallback animation for auto-enter without source rect hint" into sc-dev
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
if (!positionInParent.equals(data.positionInParent)) {
|
||||||
|
data.positionInParent.set(positionInParent.x, positionInParent.y);
|
||||||
mSyncQueue.runInSync(t -> {
|
mSyncQueue.runInSync(t -> {
|
||||||
// Reset several properties back. For instance, when an Activity enters PiP with
|
t.setPosition(data.surface, positionInParent.x, positionInParent.y);
|
||||||
// multiple activities in the same task, a new task will be created from that Activity
|
|
||||||
// and we want reset the leash of the original task.
|
|
||||||
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -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);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user