Lock free app animations (4/n): Implement thubmnail
Bug: 64674361
Test: go/wm-smoke
Change-Id: I8f25dae04b69613c93ccb5416c2cda2df6373103
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index ad0a2d3..1278f75 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -626,9 +626,6 @@
/** Cancels the window transitions for the given task. */
void cancelTaskWindowTransition(int taskId);
- /** Cancels the thumbnail transitions for the given task. */
- void cancelTaskThumbnailTransition(int taskId);
-
/**
* @param taskId the id of the task to retrieve the sAutoapshots for
* @param reducedResolution if set, if the snapshot needs to be loaded from disk, this will load
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
index eb2d12e..1c99d38 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
@@ -413,15 +413,4 @@
Log.w(TAG, "Failed to cancel window transition for task=" + taskId, e);
}
}
-
- /**
- * Cancels the current thumbnail transtion to/from Recents for the given task id.
- */
- public void cancelThumbnailTransition(int taskId) {
- try {
- ActivityManager.getService().cancelTaskThumbnailTransition(taskId);
- } catch (RemoteException e) {
- Log.w(TAG, "Failed to cancel window transition for task=" + taskId, e);
- }
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
index 2963506..db999c4 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
@@ -198,20 +198,6 @@
* Expands the PIP.
*/
public final void onBusEvent(ExpandPipEvent event) {
- if (event.clearThumbnailWindows) {
- try {
- StackInfo stackInfo = mActivityManager.getStackInfo(
- WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED);
- if (stackInfo != null && stackInfo.taskIds != null) {
- ActivityManagerWrapper am = ActivityManagerWrapper.getInstance();
- for (int taskId : stackInfo.taskIds) {
- am.cancelThumbnailTransition(taskId);
- }
- }
- } catch (RemoteException e) {
- // Do nothing
- }
- }
mTouchHandler.getMotionHelper().expandPip(false /* skipAnimation */);
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index ca9a553..06dfd18 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -709,7 +709,6 @@
(event.launchTask == null || launchToTaskId != event.launchTask.key.id)) {
ActivityManagerWrapper am = ActivityManagerWrapper.getInstance();
am.cancelWindowTransition(launchState.launchedToTaskId);
- am.cancelThumbnailTransition(getTaskId());
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/component/ExpandPipEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/component/ExpandPipEvent.java
index 8fe4975..37266f6 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/events/component/ExpandPipEvent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/component/ExpandPipEvent.java
@@ -22,5 +22,4 @@
* This is sent when the PiP should be expanded due to being relaunched.
*/
public class ExpandPipEvent extends EventBus.Event {
- public final boolean clearThumbnailWindows = true;
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index bc25a32..d92b3b8 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -10364,26 +10364,6 @@
}
@Override
- public void cancelTaskThumbnailTransition(int taskId) {
- enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
- "cancelTaskThumbnailTransition()");
- final long ident = Binder.clearCallingIdentity();
- try {
- synchronized (this) {
- final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
- MATCH_TASK_IN_STACKS_ONLY);
- if (task == null) {
- Slog.w(TAG, "cancelTaskThumbnailTransition: taskId=" + taskId + " not found");
- return;
- }
- task.cancelThumbnailTransition();
- }
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-
- @Override
public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
final long ident = Binder.clearCallingIdentity();
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 91b3315..4aef95d 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -772,10 +772,6 @@
mWindowContainerController.cancelWindowTransition();
}
- void cancelThumbnailTransition() {
- mWindowContainerController.cancelThumbnailTransition();
- }
-
/**
* DO NOT HOLD THE ACTIVITY MANAGER LOCK WHEN CALLING THIS METHOD!
*/
diff --git a/services/core/java/com/android/server/wm/AppWindowAnimator.java b/services/core/java/com/android/server/wm/AppWindowAnimator.java
index 6274745..4f38f73 100644
--- a/services/core/java/com/android/server/wm/AppWindowAnimator.java
+++ b/services/core/java/com/android/server/wm/AppWindowAnimator.java
@@ -25,10 +25,6 @@
// TODO: Move all remaining fields to AppWindowToken and remove this class.
public class AppWindowAnimator {
- static final String TAG = TAG_WITH_CLASS_NAME ? "AppWindowAnimator" : TAG_WM;
-
- static final int PROLONG_ANIMATION_AT_END = 1;
- static final int PROLONG_ANIMATION_AT_START = 2;
// Have we been asked to have this token keep the screen frozen?
// Protect with mAnimator.
@@ -46,17 +42,4 @@
// Propagated from AppWindowToken.allDrawn, to determine when
// the state changes.
boolean allDrawn;
-
- // Special surface for thumbnail animation. If deferThumbnailDestruction is enabled, then we
- // will make sure that the thumbnail is destroyed after the other surface is completed. This
- // requires that the duration of the two animations are the same.
- SurfaceControl thumbnail;
- int thumbnailTransactionSeq;
-
- Animation thumbnailAnimation;
-
- // This flag indicates that the destruction of the thumbnail surface is synchronized with
- // another animation, so defer the destruction of this thumbnail surface for a single frame
- // after the secondary animation completes.
- boolean deferThumbnailDestruction;
}
diff --git a/services/core/java/com/android/server/wm/AppWindowThumbnail.java b/services/core/java/com/android/server/wm/AppWindowThumbnail.java
new file mode 100644
index 0000000..a8bc270d0
--- /dev/null
+++ b/services/core/java/com/android/server/wm/AppWindowThumbnail.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+import static com.android.server.wm.WindowManagerService.MAX_ANIMATION_DURATION;
+
+import android.graphics.GraphicBuffer;
+import android.graphics.PixelFormat;
+import android.graphics.Point;
+import android.os.Binder;
+import android.util.Slog;
+import android.view.Surface;
+import android.view.SurfaceControl;
+import android.view.SurfaceControl.Builder;
+import android.view.SurfaceControl.Transaction;
+import android.view.animation.Animation;
+
+import com.android.server.wm.SurfaceAnimator.Animatable;
+
+/**
+ * Represents a surface that is displayed over an {@link AppWindowToken}
+ */
+class AppWindowThumbnail implements Animatable {
+
+ private static final String TAG = TAG_WITH_CLASS_NAME ? "AppWindowThumbnail" : TAG_WM;
+
+ private final AppWindowToken mAppToken;
+ private final SurfaceControl mSurfaceControl;
+ private final SurfaceAnimator mSurfaceAnimator;
+ private final int mWidth;
+ private final int mHeight;
+
+ AppWindowThumbnail(Transaction t, AppWindowToken appToken, GraphicBuffer thumbnailHeader) {
+ mAppToken = appToken;
+ mSurfaceAnimator = new SurfaceAnimator(this, this::onAnimationFinished, appToken.mService);
+ mWidth = thumbnailHeader.getWidth();
+ mHeight = thumbnailHeader.getHeight();
+
+ // Create a new surface for the thumbnail
+ WindowState window = appToken.findMainWindow();
+
+ // TODO: This should be attached as a child to the app token, once the thumbnail animations
+ // use relative coordinates. Once we start animating task we can also consider attaching
+ // this to the task.
+ mSurfaceControl = appToken.makeSurface()
+ .setName("thumbnail anim: " + appToken.toString())
+ .setSize(mWidth, mHeight)
+ .setFormat(PixelFormat.TRANSLUCENT)
+ .setMetadata(appToken.windowType,
+ window != null ? window.mOwnerUid : Binder.getCallingUid())
+ .build();
+
+ if (SHOW_TRANSACTIONS) {
+ Slog.i(TAG, " THUMBNAIL " + mSurfaceControl + ": CREATE");
+ }
+
+ // Transfer the thumbnail to the surface
+ Surface drawSurface = new Surface();
+ drawSurface.copyFrom(mSurfaceControl);
+ drawSurface.attachAndQueueBuffer(thumbnailHeader);
+ drawSurface.release();
+ t.show(mSurfaceControl);
+
+ // We parent the thumbnail to the task, and just place it on top of anything else in the
+ // task.
+ t.setLayer(mSurfaceControl, Integer.MAX_VALUE);
+ }
+
+ void startAnimation(Transaction t, Animation anim) {
+ anim.restrictDuration(MAX_ANIMATION_DURATION);
+ anim.scaleCurrentDuration(mAppToken.mService.getTransitionAnimationScaleLocked());
+ mSurfaceAnimator.startAnimation(t, new LocalAnimationAdapter(new WindowAnimationSpec(anim,
+ new Point()), mAppToken.mService.mSurfaceAnimationRunner),
+ false /* hidden */);
+ }
+
+ private void onAnimationFinished() {
+ }
+
+ void setShowing(Transaction pendingTransaction, boolean show) {
+ if (show) {
+ pendingTransaction.show(mSurfaceControl);
+ } else {
+ pendingTransaction.hide(mSurfaceControl);
+ }
+ }
+
+ void destroy() {
+ mSurfaceAnimator.cancelAnimation();
+ mSurfaceControl.destroy();
+ }
+
+ @Override
+ public Transaction getPendingTransaction() {
+ return mAppToken.getPendingTransaction();
+ }
+
+ @Override
+ public void commitPendingTransaction() {
+ mAppToken.commitPendingTransaction();
+ }
+
+ @Override
+ public void destroyAfterPendingTransaction(SurfaceControl surface) {
+ mAppToken.destroyAfterPendingTransaction(surface);
+ }
+
+ @Override
+ public void onAnimationLeashCreated(Transaction t, SurfaceControl leash) {
+ t.setLayer(leash, Integer.MAX_VALUE);
+ }
+
+ @Override
+ public void onAnimationLeashDestroyed(Transaction t) {
+ t.hide(mSurfaceControl);
+ }
+
+ @Override
+ public Builder makeAnimationLeash() {
+ return mAppToken.makeSurface();
+ }
+
+ @Override
+ public SurfaceControl getSurfaceControl() {
+ return mSurfaceControl;
+ }
+
+ @Override
+ public SurfaceControl getParentSurfaceControl() {
+ return mAppToken.getParentSurfaceControl();
+ }
+
+ @Override
+ public int getSurfaceWidth() {
+ return mWidth;
+ }
+
+ @Override
+ public int getSurfaceHeight() {
+ return mHeight;
+ }
+}
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index dcf2a87..de4b426 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -55,6 +55,7 @@
import android.annotation.NonNull;
import android.app.Activity;
import android.content.res.Configuration;
+import android.graphics.GraphicBuffer;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Binder;
@@ -208,6 +209,8 @@
/** Whether our surface was set to be showing in the last call to {@link #prepareSurfaces} */
private boolean mLastSurfaceShowing;
+ private AppWindowThumbnail mThumbnail;
+
AppWindowToken(WindowManagerService service, IApplicationToken token, boolean voiceInteraction,
DisplayContent dc, long inputDispatchingTimeoutNanos, boolean fullscreen,
boolean showForAllUsers, int targetSdk, int orientation, int rotationAnimationHint,
@@ -1618,6 +1621,8 @@
setAppLayoutChanges(FINISH_LAYOUT_REDO_ANIM | FINISH_LAYOUT_REDO_WALLPAPER,
"AppWindowToken");
+ clearThumbnail();
+
if (mService.mInputMethodTarget != null && mService.mInputMethodTarget.mAppToken == this) {
getDisplayContent().computeImeTarget(true /* updateImeTarget */);
}
@@ -1657,6 +1662,12 @@
return super.isSelfAnimating();
}
+ @Override
+ void cancelAnimation() {
+ super.cancelAnimation();
+ clearThumbnail();
+ }
+
boolean isWaitingForTransitionStart() {
return mService.mAppTransition.isTransitionSet()
&& (mService.mOpeningApps.contains(this) || mService.mClosingApps.contains(this));
@@ -1670,8 +1681,44 @@
return mTransitFlags;
}
- void clearThumbnail() {
- // TODO
+ void attachThumbnailAnimation() {
+ if (!isReallyAnimating()) {
+ return;
+ }
+ final int taskId = getTask().mTaskId;
+ final GraphicBuffer thumbnailHeader =
+ mService.mAppTransition.getAppTransitionThumbnailHeader(taskId);
+ if (thumbnailHeader == null) {
+ if (DEBUG_APP_TRANSITIONS) Slog.d(TAG, "No thumbnail header bitmap for: " + taskId);
+ return;
+ }
+ clearThumbnail();
+ mThumbnail = new AppWindowThumbnail(getPendingTransaction(), this, thumbnailHeader);
+ mThumbnail.startAnimation(getPendingTransaction(), loadThumbnailAnimation(thumbnailHeader));
+ }
+
+ private Animation loadThumbnailAnimation(GraphicBuffer thumbnailHeader) {
+ final DisplayInfo displayInfo = mDisplayContent.getDisplayInfo();
+
+ // If this is a multi-window scenario, we use the windows frame as
+ // destination of the thumbnail header animation. If this is a full screen
+ // window scenario, we use the whole display as the target.
+ WindowState win = findMainWindow();
+ Rect appRect = win != null ? win.getContentFrameLw() :
+ new Rect(0, 0, displayInfo.appWidth, displayInfo.appHeight);
+ Rect insets = win != null ? win.mContentInsets : null;
+ final Configuration displayConfig = mDisplayContent.getConfiguration();
+ return mService.mAppTransition.createThumbnailAspectScaleAnimationLocked(
+ appRect, insets, thumbnailHeader, getTask().mTaskId, displayConfig.uiMode,
+ displayConfig.orientation);
+ }
+
+ private void clearThumbnail() {
+ if (mThumbnail == null) {
+ return;
+ }
+ mThumbnail.destroy();
+ mThumbnail = null;
}
@Override
@@ -1753,6 +1800,9 @@
} else if (!show && mLastSurfaceShowing) {
mPendingTransaction.hide(mSurfaceControl);
}
+ if (mThumbnail != null) {
+ mThumbnail.setShowing(mPendingTransaction, show);
+ }
mLastSurfaceShowing = show;
super.prepareSurfaces();
}
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 274ac04..056ece3 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -399,14 +399,6 @@
}
}
}
- final AppWindowAnimator appAnimator = winAnimator.mAppAnimator;
- if (appAnimator != null && appAnimator.thumbnail != null) {
- if (appAnimator.thumbnailTransactionSeq
- != mTmpWindowAnimator.mAnimTransactionSequence) {
- appAnimator.thumbnailTransactionSeq =
- mTmpWindowAnimator.mAnimTransactionSequence;
- }
- }
};
private final Consumer<WindowState> mUpdateWallpaperForAnimator = w -> {
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 81be595..374c06c 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -540,13 +540,6 @@
}
}
- /** Cancels any running thumbnail transitions associated with the task. */
- void cancelTaskThumbnailTransition() {
- for (int i = mChildren.size() - 1; i >= 0; --i) {
- mChildren.get(i).clearThumbnail();
- }
- }
-
boolean showForAllUsers() {
final int tokensCount = mChildren.size();
return (tokensCount != 0) && mChildren.get(tokensCount - 1).mShowForAllUsers;
diff --git a/services/core/java/com/android/server/wm/TaskWindowContainerController.java b/services/core/java/com/android/server/wm/TaskWindowContainerController.java
index 5caae32..d83f28c 100644
--- a/services/core/java/com/android/server/wm/TaskWindowContainerController.java
+++ b/services/core/java/com/android/server/wm/TaskWindowContainerController.java
@@ -199,16 +199,6 @@
}
}
- public void cancelThumbnailTransition() {
- synchronized (mWindowMap) {
- if (mContainer == null) {
- Slog.w(TAG_WM, "cancelThumbnailTransition: taskId " + mTaskId + " not found.");
- return;
- }
- mContainer.cancelTaskThumbnailTransition();
- }
- }
-
public void setTaskDescription(TaskDescription taskDescription) {
synchronized (mWindowMap) {
if (mContainer == null) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 6e2dbe1..b00c727 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -71,13 +71,9 @@
import static com.android.server.LockGuard.installLock;
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
-import static com.android.server.wm.AppTransition.TRANSIT_UNSET;
-import static com.android.server.wm.AppWindowAnimator.PROLONG_ANIMATION_AT_END;
-import static com.android.server.wm.AppWindowAnimator.PROLONG_ANIMATION_AT_START;
import static com.android.server.wm.KeyguardDisableHandler.KEYGUARD_POLICY_CHANGED;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_BOOT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_CONFIGURATION;
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index 76faf4b..cfe8672 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -97,9 +97,6 @@
static final int SET_TURN_ON_SCREEN = 1 << 4;
static final int SET_WALLPAPER_ACTION_PENDING = 1 << 5;
- private final Rect mTmpStartRect = new Rect();
- private final Rect mTmpContentRect = new Rect();
-
private boolean mTraversalScheduled;
private int mDeferDepth = 0;
@@ -431,7 +428,7 @@
}
}
if (mService.mAppTransition.isNextAppTransitionThumbnailUp()) {
- createThumbnailAppAnimator(transit, wtoken);
+ wtoken.attachThumbnailAnimation();
}
}
return topOpeningApp;
@@ -469,7 +466,7 @@
}
}
if (mService.mAppTransition.isNextAppTransitionThumbnailDown()) {
- createThumbnailAppAnimator(transit, wtoken);
+ wtoken.attachThumbnailAnimation();
}
}
}
@@ -656,88 +653,6 @@
}
}
- private void createThumbnailAppAnimator(int transit, AppWindowToken appToken) {
- AppWindowAnimator openingAppAnimator = (appToken == null) ? null : appToken.mAppAnimator;
- if (appToken == null || !appToken.isSelfAnimating()) {
- return;
- }
- final int taskId = appToken.getTask().mTaskId;
- final GraphicBuffer thumbnailHeader =
- mService.mAppTransition.getAppTransitionThumbnailHeader(taskId);
- if (thumbnailHeader == null) {
- if (DEBUG_APP_TRANSITIONS) Slog.d(TAG, "No thumbnail header bitmap for: " + taskId);
- return;
- }
- // This thumbnail animation is very special, we need to have
- // an extra surface with the thumbnail included with the animation.
- Rect dirty = new Rect(0, 0, thumbnailHeader.getWidth(), thumbnailHeader.getHeight());
- try {
- // TODO(multi-display): support other displays
- final DisplayContent displayContent = mService.getDefaultDisplayContentLocked();
- final Display display = displayContent.getDisplay();
- final DisplayInfo displayInfo = displayContent.getDisplayInfo();
-
- // Create a new surface for the thumbnail
- WindowState window = appToken.findMainWindow();
- final SurfaceControl surfaceControl = appToken.makeSurface()
- .setName("thumbnail anim")
- .setSize(dirty.width(), dirty.height())
- .setFormat(PixelFormat.TRANSLUCENT)
- .setMetadata(appToken.windowType,
- window != null ? window.mOwnerUid : Binder.getCallingUid())
- .build();
-
- if (SHOW_TRANSACTIONS) {
- Slog.i(TAG, " THUMBNAIL " + surfaceControl + ": CREATE");
- }
-
- // Transfer the thumbnail to the surface
- Surface drawSurface = new Surface();
- drawSurface.copyFrom(surfaceControl);
- drawSurface.attachAndQueueBuffer(thumbnailHeader);
- drawSurface.release();
-
- // Get the thumbnail animation
- Animation anim;
- if (mService.mAppTransition.isNextThumbnailTransitionAspectScaled()) {
- // If this is a multi-window scenario, we use the windows frame as
- // destination of the thumbnail header animation. If this is a full screen
- // window scenario, we use the whole display as the target.
- WindowState win = appToken.findMainWindow();
- Rect appRect = win != null ? win.getContentFrameLw() :
- new Rect(0, 0, displayInfo.appWidth, displayInfo.appHeight);
- Rect insets = win != null ? win.mContentInsets : null;
- final Configuration displayConfig = displayContent.getConfiguration();
- // For the new aspect-scaled transition, we want it to always show
- // above the animating opening/closing window, and we want to
- // synchronize its thumbnail surface with the surface for the
- // open/close animation (only on the way down)
- anim = mService.mAppTransition.createThumbnailAspectScaleAnimationLocked(appRect,
- insets, thumbnailHeader, taskId, displayConfig.uiMode,
- displayConfig.orientation);
- openingAppAnimator.deferThumbnailDestruction =
- !mService.mAppTransition.isNextThumbnailTransitionScaleUp();
- } else {
- anim = mService.mAppTransition.createThumbnailScaleAnimationLocked(
- displayInfo.appWidth, displayInfo.appHeight, transit, thumbnailHeader);
- }
- anim.restrictDuration(MAX_ANIMATION_DURATION);
- anim.scaleCurrentDuration(mService.getTransitionAnimationScaleLocked());
-
- openingAppAnimator.thumbnail = surfaceControl;
- openingAppAnimator.thumbnailAnimation = anim;
- mService.mAppTransition.getNextAppTransitionStartRect(taskId, mTmpStartRect);
-
- // We parent the thumbnail to the app token, and just place it
- // on top of anything else in the app token.
- surfaceControl.setLayer(Integer.MAX_VALUE);
- } catch (Surface.OutOfResourcesException e) {
- Slog.e(TAG, "Can't allocate thumbnail/Canvas surface w="
- + dirty.width() + " h=" + dirty.height(), e);
- appToken.clearThumbnail();
- }
- }
-
void requestTraversal() {
if (!mTraversalScheduled) {
mTraversalScheduled = true;
diff --git a/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java b/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java
index f384044..5a21102 100644
--- a/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java
@@ -572,7 +572,6 @@
});
assertSecurityException(expectCallable, () -> mService.getTaskDescription(0));
assertSecurityException(expectCallable, () -> mService.cancelTaskWindowTransition(0));
- assertSecurityException(expectCallable, () -> mService.cancelTaskThumbnailTransition(0));
assertSecurityException(expectCallable, () -> mService.startRecentsActivity(null, null,
null, 0));
}