Exposing content insets and minimized home bounds for recents transition

- In order to calculate the final target rect and window clip for the
  app currently transitioning into the task view in launcher (similar to
  how we did in SysUI), we need to provide the content insets and bounds
  for both the app and launcher (whose activity may not yet have been
  shown).  For the existing recents transition, this was calculated
  internally in the AppTransition aspect-scaled transition, but now that
  we are implementing this via remote animations, the same information is
  needed in the implementation of the recents animation runner.

Bug: 70294936
Test: Swipe up from launcher with window transitions when in multi window
Change-Id: I2afc6bdfe112cc7bb1b07ba65213653f6f0634f9
This commit is contained in:
Winson Chung
2018-01-31 10:29:12 -08:00
parent bca6e66c4d
commit 67f31199fb
8 changed files with 87 additions and 17 deletions

View File

@@ -16,6 +16,7 @@
package android.view;
import android.graphics.Rect;
import android.view.RemoteAnimationTarget;
import android.view.IRecentsAnimationController;
@@ -28,15 +29,26 @@ import android.view.IRecentsAnimationController;
oneway interface IRecentsAnimationRunner {
/**
* Called when the system is ready for the handler to start animating all the visible tasks.
* Deprecated, to be removed once Launcher updates
*/
void onAnimationStart(in IRecentsAnimationController controller,
in RemoteAnimationTarget[] apps);
in RemoteAnimationTarget[] apps) = 0;
/**
* Called when the system needs to cancel the current animation. This can be due to the
* wallpaper not drawing in time, or the handler not finishing the animation within a predefined
* amount of time.
*/
void onAnimationCanceled();
void onAnimationCanceled() = 1;
/**
* Called when the system is ready for the handler to start animating all the visible tasks.
*
* @param homeContentInsets The current home app content insets
* @param minimizedHomeBounds Specifies the bounds of the minimized home app, will be
* {@code null} if the device is not currently in split screen
*/
void onAnimationStart_New(in IRecentsAnimationController controller,
in RemoteAnimationTarget[] apps, in Rect homeContentInsets,
in Rect minimizedHomeBounds) = 2;
}

View File

@@ -78,6 +78,11 @@ public class RemoteAnimationTarget implements Parcelable {
*/
public final Rect clipRect;
/**
* The insets of the main app window.
*/
public final Rect contentInsets;
/**
* The index of the element in the tree in prefix order. This should be used for z-layering
* to preserve original z-layer order in the hierarchy tree assuming no "boosting" needs to
@@ -105,13 +110,14 @@ public class RemoteAnimationTarget implements Parcelable {
public final WindowConfiguration windowConfiguration;
public RemoteAnimationTarget(int taskId, int mode, SurfaceControl leash, boolean isTranslucent,
Rect clipRect, int prefixOrderIndex, Point position, Rect sourceContainerBounds,
WindowConfiguration windowConfig) {
Rect clipRect, Rect contentInsets, int prefixOrderIndex, Point position,
Rect sourceContainerBounds, WindowConfiguration windowConfig) {
this.mode = mode;
this.taskId = taskId;
this.leash = leash;
this.isTranslucent = isTranslucent;
this.clipRect = new Rect(clipRect);
this.contentInsets = new Rect(contentInsets);
this.prefixOrderIndex = prefixOrderIndex;
this.position = new Point(position);
this.sourceContainerBounds = new Rect(sourceContainerBounds);
@@ -124,6 +130,7 @@ public class RemoteAnimationTarget implements Parcelable {
leash = in.readParcelable(null);
isTranslucent = in.readBoolean();
clipRect = in.readParcelable(null);
contentInsets = in.readParcelable(null);
prefixOrderIndex = in.readInt();
position = in.readParcelable(null);
sourceContainerBounds = in.readParcelable(null);
@@ -142,6 +149,7 @@ public class RemoteAnimationTarget implements Parcelable {
dest.writeParcelable(leash, 0 /* flags */);
dest.writeBoolean(isTranslucent);
dest.writeParcelable(clipRect, 0 /* flags */);
dest.writeParcelable(contentInsets, 0 /* flags */);
dest.writeInt(prefixOrderIndex);
dest.writeParcelable(position, 0 /* flags */);
dest.writeParcelable(sourceContainerBounds, 0 /* flags */);

View File

@@ -43,6 +43,7 @@ import android.content.pm.UserInfo;
import android.content.res.Resources;
import android.content.res.Resources.NotFoundException;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
@@ -57,6 +58,7 @@ import android.view.IRecentsAnimationController;
import android.view.IRecentsAnimationRunner;
import android.view.RemoteAnimationTarget;
import android.view.WindowManagerGlobal;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.recents.model.Task.TaskKey;
import com.android.systemui.shared.recents.model.ThumbnailData;
@@ -271,11 +273,20 @@ public class ActivityManagerWrapper {
runner = new IRecentsAnimationRunner.Stub() {
public void onAnimationStart(IRecentsAnimationController controller,
RemoteAnimationTarget[] apps) {
final Rect stableInsets = new Rect();
WindowManagerWrapper.getInstance().getStableInsets(stableInsets);
onAnimationStart_New(controller, apps, stableInsets, null);
}
public void onAnimationStart_New(IRecentsAnimationController controller,
RemoteAnimationTarget[] apps, Rect homeContentInsets,
Rect minimizedHomeBounds) {
final RecentsAnimationControllerCompat controllerCompat =
new RecentsAnimationControllerCompat(controller);
final RemoteAnimationTargetCompat[] appsCompat =
RemoteAnimationTargetCompat.wrap(apps);
animationHandler.onAnimationStart(controllerCompat, appsCompat);
animationHandler.onAnimationStart(controllerCompat, appsCompat,
homeContentInsets, minimizedHomeBounds);
}
public void onAnimationCanceled() {

View File

@@ -16,13 +16,15 @@
package com.android.systemui.shared.system;
import android.graphics.Rect;
public interface RecentsAnimationListener {
/**
* Called when the animation into Recents can start. This call is made on the binder thread.
*/
void onAnimationStart(RecentsAnimationControllerCompat controller,
RemoteAnimationTargetCompat[] apps);
RemoteAnimationTargetCompat[] apps, Rect homeContentInsets, Rect minimizedHomeBounds);
/**
* Called when the animation into Recents was canceled. This call is made on the binder thread.

View File

@@ -16,6 +16,9 @@
package com.android.systemui.shared.system;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
import android.app.WindowConfiguration;
import android.graphics.Point;
import android.graphics.Rect;
import android.view.RemoteAnimationTarget;
@@ -37,7 +40,10 @@ public class RemoteAnimationTargetCompat {
public final Point position;
public final Rect sourceContainerBounds;
private final RemoteAnimationTarget mTarget;
public RemoteAnimationTargetCompat(RemoteAnimationTarget app) {
mTarget = app;
taskId = app.taskId;
mode = app.mode;
leash = new SurfaceControlCompat(app.leash);
@@ -56,4 +62,18 @@ public class RemoteAnimationTargetCompat {
}
return appsCompat;
}
/**
* TODO: Get as a method for compatibility (will move into ctor once Launcher updates)
*/
public Rect getContentInsets() {
return mTarget.contentInsets;
}
/**
* TODO: Get as a method for compatibility (will move into ctor once Launcher updates)
*/
public boolean isAssistantActivityType() {
return mTarget.windowConfiguration.getActivityType() == ACTIVITY_TYPE_ASSISTANT;
}
}

View File

@@ -20,6 +20,7 @@ import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.content.Intent.FLAG_ACTIVITY_NO_ANIMATION;
import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
import static android.view.WindowManager.TRANSIT_NONE;
import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
@@ -27,6 +28,7 @@ import android.app.ActivityOptions;
import android.content.ComponentName;
import android.content.Intent;
import android.os.Handler;
import android.os.Trace;
import android.view.IRecentsAnimationRunner;
import com.android.server.wm.RecentsAnimationController.RecentsAnimationCallbacks;
import com.android.server.wm.WindowManagerService;
@@ -70,6 +72,7 @@ class RecentsAnimation implements RecentsAnimationCallbacks {
void startRecentsActivity(Intent intent, IRecentsAnimationRunner recentsAnimationRunner,
ComponentName recentsComponent, int recentsUid) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "RecentsAnimation#startRecentsActivity");
mWindowManager.deferSurfaceLayout();
try {
// Cancel the previous recents animation if necessary
@@ -124,6 +127,7 @@ class RecentsAnimation implements RecentsAnimationCallbacks {
mHandler.postDelayed(mCancelAnimationRunnable, RECENTS_ANIMATION_TIMEOUT);
} finally {
mWindowManager.continueSurfaceLayout();
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
}
@@ -134,6 +138,8 @@ class RecentsAnimation implements RecentsAnimationCallbacks {
if (mWindowManager.getRecentsAnimationController() == null) return;
mWindowManager.inSurfaceTransaction(() -> {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER,
"RecentsAnimation#onAnimationFinished_inSurfaceTransaction");
mWindowManager.deferSurfaceLayout();
try {
mWindowManager.cleanupRecentsAnimation();
@@ -167,6 +173,7 @@ class RecentsAnimation implements RecentsAnimationCallbacks {
mWindowManager.executeAppTransition();
} finally {
mWindowManager.continueSurfaceLayout();
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
});
}

View File

@@ -62,6 +62,7 @@ public class RecentsAnimationController {
// The recents component app token that is shown behind the visibile tasks
private AppWindowToken mHomeAppToken;
private Rect mMinimizedHomeBounds = new Rect();
// We start the RecentsAnimationController in a pending-start state since we need to wait for
// the wallpaper/activity to draw before we can give control to the handler to start animating
@@ -105,7 +106,7 @@ public class RecentsAnimationController {
final AppWindowToken topChild = task.getTopChild();
final WindowState mainWindow = topChild.findMainWindow();
return new TaskSnapshot(buffer, topChild.getConfiguration().orientation,
mainWindow.mStableInsets,
mainWindow.mContentInsets,
ActivityManager.isLowRamDeviceStatic() /* reduced */,
1.0f /* scale */);
}
@@ -163,8 +164,6 @@ public class RecentsAnimationController {
* @param remoteAnimationRunner The remote runner which should be notified when the animation is
* ready to start or has been canceled
* @param callbacks Callbacks to be made when the animation finishes
* @param restoreHomeBehindStackId The stack id to restore the home stack behind once the
* animation is complete. Will be passed to the callback.
*/
RecentsAnimationController(WindowManagerService service,
IRecentsAnimationRunner remoteAnimationRunner, RecentsAnimationCallbacks callbacks,
@@ -200,13 +199,15 @@ public class RecentsAnimationController {
if (recentsComponentAppToken != null) {
if (DEBUG) Log.d(TAG, "setHomeApp(" + recentsComponentAppToken.getName() + ")");
mHomeAppToken = recentsComponentAppToken;
final WallpaperController wc = dc.mWallpaperController;
if (recentsComponentAppToken.windowsCanBeWallpaperTarget()) {
dc.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
dc.setLayoutNeeded();
}
}
// Save the minimized home height
dc.getDockedDividerController().getHomeStackBoundsInDockedMode(mMinimizedHomeBounds);
mService.mWindowPlacerLocked.performSurfacePlacement();
}
@@ -232,7 +233,12 @@ public class RecentsAnimationController {
appAnimations[i] = mPendingAnimations.get(i).createRemoteAnimationApp();
}
mPendingStart = false;
mRunner.onAnimationStart(mController, appAnimations);
final Rect minimizedHomeBounds =
mHomeAppToken != null && mHomeAppToken.inSplitScreenSecondaryWindowingMode()
? mMinimizedHomeBounds : null;
mRunner.onAnimationStart_New(mController, appAnimations,
mHomeAppToken.findMainWindow().mContentInsets, minimizedHomeBounds);
} catch (RemoteException e) {
Slog.e(TAG, "Failed to start recents animation", e);
}
@@ -334,11 +340,15 @@ public class RecentsAnimationController {
}
RemoteAnimationTarget createRemoteAnimationApp() {
// TODO: Do we need position and stack bounds?
final Point position = new Point();
final Rect bounds = new Rect();
final WindowContainer container = mTask.getParent();
container.getRelativePosition(position);
container.getBounds(bounds);
final WindowState mainWindow = mTask.getTopVisibleAppMainWindow();
return new RemoteAnimationTarget(mTask.mTaskId, MODE_CLOSING, mCapturedLeash,
!mTask.fillsParent(),
mTask.getTopVisibleAppMainWindow().mWinAnimator.mLastClipRect,
mTask.getPrefixOrderIndex(), new Point(), new Rect(),
!mTask.fillsParent(), mainWindow.mWinAnimator.mLastClipRect,
mainWindow.mContentInsets, mTask.getPrefixOrderIndex(), position, bounds,
mTask.getWindowConfiguration());
}

View File

@@ -166,7 +166,7 @@ class RemoteAnimationController {
}
return new RemoteAnimationTarget(task.mTaskId, getMode(),
mCapturedLeash, !mAppWindowToken.fillsParent(),
mainWindow.mWinAnimator.mLastClipRect,
mainWindow.mWinAnimator.mLastClipRect, mainWindow.mContentInsets,
mAppWindowToken.getPrefixOrderIndex(), mPosition, mStackBounds,
task.getWindowConfiguration());
}