blob: c03dabe660ad7edeeeee11a7dcb5b5e2da57ef28 [file] [log] [blame]
Winson Chunge2d72172018-01-25 17:46:20 +00001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
17package com.android.server.wm;
18
Jorim Jaggi54cff642018-03-15 15:51:32 +010019import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
Winson Chunge2d72172018-01-25 17:46:20 +000020import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
Winson Chung3e2980e2018-03-29 17:28:57 -070021import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Winson Chunge2d72172018-01-25 17:46:20 +000022import static android.view.RemoteAnimationTarget.MODE_CLOSING;
Winson Chung732446a2018-09-19 13:15:17 -070023import static android.view.RemoteAnimationTarget.MODE_OPENING;
Evan Roskyc5abbd82018-10-05 16:02:19 -070024import static android.view.WindowManager.DOCKED_INVALID;
Winson Chunga89ffed2018-01-25 17:46:11 +000025import static android.view.WindowManager.INPUT_CONSUMER_RECENTS_ANIMATION;
Evan Roskyc5abbd82018-10-05 16:02:19 -070026
Winson Chunge2d72172018-01-25 17:46:20 +000027import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070028import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_RECENTS_ANIM;
Yi Jin6c6e9ca2018-03-20 16:53:35 -070029import static com.android.server.wm.AnimationAdapterProto.REMOTE;
Tracy Zhou9c675d42019-04-08 00:32:40 -070030import static com.android.server.wm.BoundsAnimationController.FADE_IN;
Winson Chungc6c3f852018-04-09 15:41:03 -070031import static com.android.server.wm.RemoteAnimationAdapterWrapperProto.TARGET;
32import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_RECENTS_ANIMATIONS;
lumark54284462019-03-05 20:44:27 +080033import static com.android.server.wm.WindowManagerInternal.AppTransitionListener;
Winson Chunge2d72172018-01-25 17:46:20 +000034
Winson Chung6a38fca2018-03-28 17:57:09 -070035import android.annotation.IntDef;
Winson Chunge2d72172018-01-25 17:46:20 +000036import android.app.ActivityManager.TaskSnapshot;
37import android.app.WindowConfiguration;
Winson Chunge2d72172018-01-25 17:46:20 +000038import android.graphics.Point;
39import android.graphics.Rect;
40import android.os.Binder;
Adrian Roos842e7882018-03-26 17:34:06 +020041import android.os.IBinder.DeathRecipient;
Winson Chunge2d72172018-01-25 17:46:20 +000042import android.os.RemoteException;
43import android.os.SystemClock;
Winson Chung23aa7b12018-02-01 11:41:43 -080044import android.util.ArraySet;
Winson Chungc6c3f852018-04-09 15:41:03 -070045import android.util.Slog;
Vadim Tryshev593e9562018-03-08 17:15:45 -080046import android.util.SparseBooleanArray;
Jorim Jaggi54cff642018-03-15 15:51:32 +010047import android.util.SparseIntArray;
Winson Chungc6c3f852018-04-09 15:41:03 -070048import android.util.proto.ProtoOutputStream;
Winson Chunge2d72172018-01-25 17:46:20 +000049import android.view.IRecentsAnimationController;
50import android.view.IRecentsAnimationRunner;
Evan Roskyc5abbd82018-10-05 16:02:19 -070051import android.view.InputWindowHandle;
Winson Chunge2d72172018-01-25 17:46:20 +000052import android.view.RemoteAnimationTarget;
53import android.view.SurfaceControl;
54import android.view.SurfaceControl.Transaction;
Evan Roskyc5abbd82018-10-05 16:02:19 -070055
Winson Chungda876c92018-04-05 18:31:06 -070056import com.android.internal.annotations.VisibleForTesting;
Winson Chunga840c322018-04-20 15:58:18 -070057import com.android.server.LocalServices;
Yohei Yukawac3de83e2018-08-28 16:09:34 -070058import com.android.server.inputmethod.InputMethodManagerInternal;
Winson Chung67e49362019-05-17 16:40:38 -070059import com.android.server.statusbar.StatusBarManagerInternal;
Jorim Jaggif75d1612018-02-27 15:05:21 +010060import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
Jorim Jaggi817ebdd2018-03-26 15:46:01 +020061import com.android.server.wm.utils.InsetUtils;
Evan Roskyc5abbd82018-10-05 16:02:19 -070062
Vadim Tryshev257f86b2018-08-23 16:45:02 -070063import com.google.android.collect.Sets;
Evan Roskyc5abbd82018-10-05 16:02:19 -070064
Winson Chunge2d72172018-01-25 17:46:20 +000065import java.io.PrintWriter;
66import java.util.ArrayList;
Winson Chungc6c3f852018-04-09 15:41:03 -070067
Winson Chunge2d72172018-01-25 17:46:20 +000068/**
69 * Controls a single instance of the remote driven recents animation. In particular, this allows
70 * the calling SystemUI to animate the visible task windows as a part of the transition. The remote
71 * runner is provided an animation controller which allows it to take screenshots and to notify
72 * window manager when the animation is completed. In addition, window manager may also notify the
73 * app if it requires the animation to be canceled at any time (ie. due to timeout, etc.)
74 */
Adrian Roos842e7882018-03-26 17:34:06 +020075public class RecentsAnimationController implements DeathRecipient {
Winson Chungc6c3f852018-04-09 15:41:03 -070076 private static final String TAG = RecentsAnimationController.class.getSimpleName();
Adrian Roos842e7882018-03-26 17:34:06 +020077 private static final long FAILSAFE_DELAY = 1000;
Winson Chunge2d72172018-01-25 17:46:20 +000078
Winson Chung3e2980e2018-03-29 17:28:57 -070079 public static final int REORDER_KEEP_IN_PLACE = 0;
80 public static final int REORDER_MOVE_TO_TOP = 1;
81 public static final int REORDER_MOVE_TO_ORIGINAL_POSITION = 2;
Winson Chung6a38fca2018-03-28 17:57:09 -070082
83 @IntDef(prefix = { "REORDER_MODE_" }, value = {
Winson Chung3e2980e2018-03-29 17:28:57 -070084 REORDER_KEEP_IN_PLACE,
85 REORDER_MOVE_TO_TOP,
86 REORDER_MOVE_TO_ORIGINAL_POSITION
Winson Chung6a38fca2018-03-28 17:57:09 -070087 })
88 public @interface ReorderMode {}
89
Winson Chunge2d72172018-01-25 17:46:20 +000090 private final WindowManagerService mService;
Winson Chung67e49362019-05-17 16:40:38 -070091 private final StatusBarManagerInternal mStatusBar;
Winson Chung5c91e8f2018-05-07 10:06:55 -070092 private IRecentsAnimationRunner mRunner;
Winson Chunge2d72172018-01-25 17:46:20 +000093 private final RecentsAnimationCallbacks mCallbacks;
94 private final ArrayList<TaskAnimationAdapter> mPendingAnimations = new ArrayList<>();
Winson Chungddf62972018-02-12 11:10:04 -080095 private final int mDisplayId;
Winson Chung65c5f992018-04-20 14:58:57 -070096 private final Runnable mFailsafeRunnable = () ->
97 cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION, "failSafeRunnable");
Winson Chunge2d72172018-01-25 17:46:20 +000098
lumark54284462019-03-05 20:44:27 +080099 final Object mLock = new Object();
100
Winson Chunge2d72172018-01-25 17:46:20 +0000101 // The recents component app token that is shown behind the visibile tasks
Winson Chung3e2980e2018-03-29 17:28:57 -0700102 private AppWindowToken mTargetAppToken;
Winson Chung732446a2018-09-19 13:15:17 -0700103 private int mTargetActivityType;
Winson Chung584d6522018-02-07 23:57:38 +0000104 private Rect mMinimizedHomeBounds = new Rect();
Winson Chunge2d72172018-01-25 17:46:20 +0000105
106 // We start the RecentsAnimationController in a pending-start state since we need to wait for
107 // the wallpaper/activity to draw before we can give control to the handler to start animating
108 // the visible task surfaces
109 private boolean mPendingStart = true;
110
111 // Set when the animation has been canceled
Winson Chungf557c3b2018-03-16 10:55:20 -0700112 private boolean mCanceled;
Winson Chunge2d72172018-01-25 17:46:20 +0000113
114 // Whether or not the input consumer is enabled. The input consumer must be both registered and
115 // enabled for it to start intercepting touch events.
116 private boolean mInputConsumerEnabled;
117
Winson Chungf557c3b2018-03-16 10:55:20 -0700118 // Whether or not the recents animation should cause the primary split-screen stack to be
119 // minimized
120 private boolean mSplitScreenMinimized;
121
Adrian Roos653c6c12018-04-09 14:12:46 -0700122 private final Rect mTmpRect = new Rect();
123
124 private boolean mLinkedToDeathOfRunner;
Winson Chunga89ffed2018-01-25 17:46:11 +0000125
lumark54284462019-03-05 20:44:27 +0800126 private boolean mCancelWithDeferredScreenshot;
127
128 private boolean mCancelOnNextTransitionStart;
129
130 /**
131 * Animates the screenshot of task that used to be controlled by RecentsAnimation.
132 * @see {@link #cancelOnNextTransitionStart}
133 */
134 SurfaceAnimator mRecentScreenshotAnimator;
135
136 final AppTransitionListener mAppTransitionListener = new AppTransitionListener() {
137 @Override
138 public int onAppTransitionStartingLocked(int transit, long duration,
139 long statusBarAnimationStartTime, long statusBarAnimationDuration) {
140 onTransitionStart();
141 mService.mRoot.getDisplayContent(mDisplayId).mAppTransition
142 .unregisterListener(this);
143 return 0;
144 }
145 };
146
Winson Chunge2d72172018-01-25 17:46:20 +0000147 public interface RecentsAnimationCallbacks {
Tracy Zhou9c675d42019-04-08 00:32:40 -0700148 /** Callback when recents animation is finished. */
149 void onAnimationFinished(@ReorderMode int reorderMode, boolean runSychronously,
150 boolean sendUserLeaveHint);
Winson Chunge2d72172018-01-25 17:46:20 +0000151 }
152
153 private final IRecentsAnimationController mController =
154 new IRecentsAnimationController.Stub() {
155
156 @Override
157 public TaskSnapshot screenshotTask(int taskId) {
Winson Chungc6c3f852018-04-09 15:41:03 -0700158 if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "screenshotTask(" + taskId + "):"
159 + " mCanceled=" + mCanceled);
Winson Chungf557c3b2018-03-16 10:55:20 -0700160 final long token = Binder.clearCallingIdentity();
Winson Chunge2d72172018-01-25 17:46:20 +0000161 try {
162 synchronized (mService.getWindowManagerLock()) {
163 if (mCanceled) {
164 return null;
165 }
166 for (int i = mPendingAnimations.size() - 1; i >= 0; i--) {
167 final TaskAnimationAdapter adapter = mPendingAnimations.get(i);
168 final Task task = adapter.mTask;
169 if (task.mTaskId == taskId) {
Winson Chung23aa7b12018-02-01 11:41:43 -0800170 final TaskSnapshotController snapshotController =
171 mService.mTaskSnapshotController;
172 final ArraySet<Task> tasks = Sets.newArraySet(task);
173 snapshotController.snapshotTasks(tasks);
174 snapshotController.addSkipClosingAppSnapshotTasks(tasks);
175 return snapshotController.getSnapshot(taskId, 0 /* userId */,
176 false /* restoreFromDisk */, false /* reducedResolution */);
Winson Chunge2d72172018-01-25 17:46:20 +0000177 }
178 }
179 return null;
180 }
181 } finally {
182 Binder.restoreCallingIdentity(token);
183 }
184 }
185
186 @Override
Tracy Zhou9c675d42019-04-08 00:32:40 -0700187 public void finish(boolean moveHomeToTop, boolean sendUserLeaveHint) {
Winson Chungc6c3f852018-04-09 15:41:03 -0700188 if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "finish(" + moveHomeToTop + "):"
189 + " mCanceled=" + mCanceled);
Winson Chungf557c3b2018-03-16 10:55:20 -0700190 final long token = Binder.clearCallingIdentity();
Winson Chunge2d72172018-01-25 17:46:20 +0000191 try {
192 synchronized (mService.getWindowManagerLock()) {
193 if (mCanceled) {
194 return;
195 }
196 }
197
198 // Note, the callback will handle its own synchronization, do not lock on WM lock
199 // prior to calling the callback
Winson Chung6a38fca2018-03-28 17:57:09 -0700200 mCallbacks.onAnimationFinished(moveHomeToTop
Winson Chung3e2980e2018-03-29 17:28:57 -0700201 ? REORDER_MOVE_TO_TOP
Winson Chung65c5f992018-04-20 14:58:57 -0700202 : REORDER_MOVE_TO_ORIGINAL_POSITION,
Tracy Zhou9c675d42019-04-08 00:32:40 -0700203 true /* runSynchronously */, sendUserLeaveHint);
204 final DisplayContent dc = mService.mRoot.getDisplayContent(mDisplayId);
205 dc.mBoundsAnimationController.setAnimationType(FADE_IN);
Winson Chunge2d72172018-01-25 17:46:20 +0000206 } finally {
207 Binder.restoreCallingIdentity(token);
208 }
209 }
210
211 @Override
Jorim Jaggi50bf59c2018-03-09 17:29:48 +0100212 public void setAnimationTargetsBehindSystemBars(boolean behindSystemBars)
213 throws RemoteException {
Winson Chungf557c3b2018-03-16 10:55:20 -0700214 final long token = Binder.clearCallingIdentity();
Jorim Jaggi50bf59c2018-03-09 17:29:48 +0100215 try {
216 synchronized (mService.getWindowManagerLock()) {
217 for (int i = mPendingAnimations.size() - 1; i >= 0; i--) {
Winson Chungce48a252019-03-21 11:03:03 -0700218 final Task task = mPendingAnimations.get(i).mTask;
219 if (task.getActivityType() != mTargetActivityType) {
220 task.setCanAffectSystemUiFlags(behindSystemBars);
221 }
Jorim Jaggi50bf59c2018-03-09 17:29:48 +0100222 }
223 mService.mWindowPlacerLocked.requestTraversal();
224 }
225 } finally {
226 Binder.restoreCallingIdentity(token);
227 }
228 }
229
230 @Override
Winson Chunge2d72172018-01-25 17:46:20 +0000231 public void setInputConsumerEnabled(boolean enabled) {
Winson Chungc6c3f852018-04-09 15:41:03 -0700232 if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "setInputConsumerEnabled(" + enabled + "):"
233 + " mCanceled=" + mCanceled);
Winson Chungf557c3b2018-03-16 10:55:20 -0700234 final long token = Binder.clearCallingIdentity();
Winson Chunge2d72172018-01-25 17:46:20 +0000235 try {
236 synchronized (mService.getWindowManagerLock()) {
237 if (mCanceled) {
238 return;
239 }
240
241 mInputConsumerEnabled = enabled;
Arthur Hung95b38a92018-07-20 18:56:12 +0800242 final InputMonitor inputMonitor =
243 mService.mRoot.getDisplayContent(mDisplayId).getInputMonitor();
244 inputMonitor.updateInputWindowsLw(true /*force*/);
Winson Chunge2d72172018-01-25 17:46:20 +0000245 mService.scheduleAnimationLocked();
246 }
247 } finally {
248 Binder.restoreCallingIdentity(token);
249 }
250 }
Winson Chungf557c3b2018-03-16 10:55:20 -0700251
252 @Override
253 public void setSplitScreenMinimized(boolean minimized) {
254 final long token = Binder.clearCallingIdentity();
255 try {
256 synchronized (mService.getWindowManagerLock()) {
257 if (mCanceled) {
258 return;
259 }
260
261 mSplitScreenMinimized = minimized;
262 mService.checkSplitScreenMinimizedChanged(true /* animate */);
263 }
264 } finally {
265 Binder.restoreCallingIdentity(token);
266 }
267 }
Winson Chunga840c322018-04-20 15:58:18 -0700268
269 @Override
270 public void hideCurrentInputMethod() {
271 final long token = Binder.clearCallingIdentity();
272 try {
273 final InputMethodManagerInternal inputMethodManagerInternal =
274 LocalServices.getService(InputMethodManagerInternal.class);
275 if (inputMethodManagerInternal != null) {
276 inputMethodManagerInternal.hideCurrentInputMethod();
277 }
278 } finally {
279 Binder.restoreCallingIdentity(token);
280 }
281 }
lumark54284462019-03-05 20:44:27 +0800282
283 @Override
284 public void setCancelWithDeferredScreenshot(boolean screenshot) {
285 synchronized (mLock) {
286 setCancelWithDeferredScreenshotLocked(screenshot);
287 }
288 }
289
290 @Override
291 public void cleanupScreenshot() {
292 synchronized (mLock) {
293 if (mRecentScreenshotAnimator != null) {
294 mRecentScreenshotAnimator.cancelAnimation();
295 mRecentScreenshotAnimator = null;
296 }
297 }
298 }
Winson Chunge2d72172018-01-25 17:46:20 +0000299 };
300
301 /**
Winson Chunge2d72172018-01-25 17:46:20 +0000302 * @param remoteAnimationRunner The remote runner which should be notified when the animation is
303 * ready to start or has been canceled
304 * @param callbacks Callbacks to be made when the animation finishes
Winson Chunge2d72172018-01-25 17:46:20 +0000305 */
306 RecentsAnimationController(WindowManagerService service,
307 IRecentsAnimationRunner remoteAnimationRunner, RecentsAnimationCallbacks callbacks,
308 int displayId) {
309 mService = service;
310 mRunner = remoteAnimationRunner;
311 mCallbacks = callbacks;
Winson Chungddf62972018-02-12 11:10:04 -0800312 mDisplayId = displayId;
Winson Chung67e49362019-05-17 16:40:38 -0700313 mStatusBar = LocalServices.getService(StatusBarManagerInternal.class);
Winson Chungddf62972018-02-12 11:10:04 -0800314 }
Winson Chunge2d72172018-01-25 17:46:20 +0000315
Winson Chung732446a2018-09-19 13:15:17 -0700316 public void initialize(int targetActivityType, SparseBooleanArray recentTaskIds) {
317 initialize(mService.mRoot.getDisplayContent(mDisplayId), targetActivityType, recentTaskIds);
318 }
319
Winson Chungddf62972018-02-12 11:10:04 -0800320 /**
321 * Initializes the recents animation controller. This is a separate call from the constructor
322 * because it may call cancelAnimation() which needs to properly clean up the controller
323 * in the window manager.
324 */
Winson Chung732446a2018-09-19 13:15:17 -0700325 @VisibleForTesting
326 void initialize(DisplayContent dc, int targetActivityType, SparseBooleanArray recentTaskIds) {
327 mTargetActivityType = targetActivityType;
lumark54284462019-03-05 20:44:27 +0800328 dc.mAppTransition.registerListenerLocked(mAppTransitionListener);
Winson Chung732446a2018-09-19 13:15:17 -0700329
330 // Make leashes for each of the visible/target tasks and add it to the recents animation to
331 // be started
Winson Chungddf62972018-02-12 11:10:04 -0800332 final ArrayList<Task> visibleTasks = dc.getVisibleTasks();
Winson Chung732446a2018-09-19 13:15:17 -0700333 final TaskStack targetStack = dc.getStack(WINDOWING_MODE_UNDEFINED, targetActivityType);
334 if (targetStack != null) {
335 for (int i = targetStack.getChildCount() - 1; i >= 0; i--) {
336 final Task t = targetStack.getChildAt(i);
337 if (!visibleTasks.contains(t)) {
338 visibleTasks.add(t);
339 }
340 }
341 }
Winson Chunge2d72172018-01-25 17:46:20 +0000342 final int taskCount = visibleTasks.size();
343 for (int i = 0; i < taskCount; i++) {
344 final Task task = visibleTasks.get(i);
345 final WindowConfiguration config = task.getWindowConfiguration();
346 if (config.tasksAreFloating()
Winson Chung732446a2018-09-19 13:15:17 -0700347 || config.getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
Winson Chunge2d72172018-01-25 17:46:20 +0000348 continue;
349 }
Vadim Tryshev593e9562018-03-08 17:15:45 -0800350 addAnimation(task, !recentTaskIds.get(task.mTaskId));
Winson Chunge2d72172018-01-25 17:46:20 +0000351 }
352
Winson Chungddf62972018-02-12 11:10:04 -0800353 // Skip the animation if there is nothing to animate
354 if (mPendingAnimations.isEmpty()) {
Winson Chungc6c3f852018-04-09 15:41:03 -0700355 cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION, "initialize-noVisibleTasks");
Winson Chungddf62972018-02-12 11:10:04 -0800356 return;
357 }
358
Adrian Roos842e7882018-03-26 17:34:06 +0200359 try {
Adrian Roos653c6c12018-04-09 14:12:46 -0700360 linkToDeathOfRunner();
Adrian Roos842e7882018-03-26 17:34:06 +0200361 } catch (RemoteException e) {
Winson Chungc6c3f852018-04-09 15:41:03 -0700362 cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION, "initialize-failedToLinkToDeath");
Adrian Roos842e7882018-03-26 17:34:06 +0200363 return;
364 }
365
Winson Chung3e2980e2018-03-29 17:28:57 -0700366 // Adjust the wallpaper visibility for the showing target activity
367 final AppWindowToken recentsComponentAppToken = dc.getStack(WINDOWING_MODE_UNDEFINED,
368 targetActivityType).getTopChild().getTopFullscreenAppToken();
Winson Chunge2d72172018-01-25 17:46:20 +0000369 if (recentsComponentAppToken != null) {
Winson Chungc6c3f852018-04-09 15:41:03 -0700370 if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "setHomeApp("
371 + recentsComponentAppToken.getName() + ")");
Winson Chung3e2980e2018-03-29 17:28:57 -0700372 mTargetAppToken = recentsComponentAppToken;
Winson Chunge2d72172018-01-25 17:46:20 +0000373 if (recentsComponentAppToken.windowsCanBeWallpaperTarget()) {
374 dc.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
375 dc.setLayoutNeeded();
376 }
377 }
378
Winson Chung584d6522018-02-07 23:57:38 +0000379 // Save the minimized home height
Evan Roskyc5abbd82018-10-05 16:02:19 -0700380 final TaskStack dockedStack = dc.getSplitScreenPrimaryStackIgnoringVisibility();
381 dc.getDockedDividerController().getHomeStackBoundsInDockedMode(
382 dc.getConfiguration(),
383 dockedStack == null ? DOCKED_INVALID : dockedStack.getDockSide(),
384 mMinimizedHomeBounds);
Winson Chung584d6522018-02-07 23:57:38 +0000385
Winson Chunge2d72172018-01-25 17:46:20 +0000386 mService.mWindowPlacerLocked.performSurfacePlacement();
Winson Chung67e49362019-05-17 16:40:38 -0700387
388 // Notify that the animation has started
389 mStatusBar.onRecentsAnimationStateChanged(true /* running */);
Winson Chunge2d72172018-01-25 17:46:20 +0000390 }
391
Winson Chungda876c92018-04-05 18:31:06 -0700392 @VisibleForTesting
393 AnimationAdapter addAnimation(Task task, boolean isRecentTaskInvisible) {
Winson Chungc6c3f852018-04-09 15:41:03 -0700394 if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "addAnimation(" + task.getName() + ")");
Vadim Tryshev593e9562018-03-08 17:15:45 -0800395 final TaskAnimationAdapter taskAdapter = new TaskAnimationAdapter(task,
396 isRecentTaskInvisible);
Winson Chung5720d8e2018-08-03 15:50:00 -0700397 task.startAnimation(task.getPendingTransaction(), taskAdapter, false /* hidden */);
Winson Chunge2d72172018-01-25 17:46:20 +0000398 task.commitPendingTransaction();
399 mPendingAnimations.add(taskAdapter);
Winson Chungda876c92018-04-05 18:31:06 -0700400 return taskAdapter;
401 }
402
403 @VisibleForTesting
404 void removeAnimation(TaskAnimationAdapter taskAdapter) {
Winson Chungc6c3f852018-04-09 15:41:03 -0700405 if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "removeAnimation("
406 + taskAdapter.mTask.mTaskId + ")");
Winson Chungda876c92018-04-05 18:31:06 -0700407 taskAdapter.mTask.setCanAffectSystemUiFlags(true);
408 taskAdapter.mCapturedFinishCallback.onAnimationFinished(taskAdapter);
409 mPendingAnimations.remove(taskAdapter);
Winson Chunge2d72172018-01-25 17:46:20 +0000410 }
411
412 void startAnimation() {
Winson Chungc6c3f852018-04-09 15:41:03 -0700413 if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "startAnimation(): mPendingStart=" + mPendingStart
Winson Chungddf62972018-02-12 11:10:04 -0800414 + " mCanceled=" + mCanceled);
415 if (!mPendingStart || mCanceled) {
416 // Skip starting if we've already started or canceled the animation
Winson Chunge2d72172018-01-25 17:46:20 +0000417 return;
418 }
419 try {
Winson Chung2dc37362018-03-12 17:57:06 -0700420 final ArrayList<RemoteAnimationTarget> appAnimations = new ArrayList<>();
Winson Chunge2d72172018-01-25 17:46:20 +0000421 for (int i = mPendingAnimations.size() - 1; i >= 0; i--) {
Winson Chungda876c92018-04-05 18:31:06 -0700422 final TaskAnimationAdapter taskAdapter = mPendingAnimations.get(i);
423 final RemoteAnimationTarget target = taskAdapter.createRemoteAnimationApp();
Winson Chung2dc37362018-03-12 17:57:06 -0700424 if (target != null) {
425 appAnimations.add(target);
Winson Chungda876c92018-04-05 18:31:06 -0700426 } else {
427 removeAnimation(taskAdapter);
Winson Chung2dc37362018-03-12 17:57:06 -0700428 }
Winson Chunge2d72172018-01-25 17:46:20 +0000429 }
Winson Chungda876c92018-04-05 18:31:06 -0700430
431 // Skip the animation if there is nothing to animate
432 if (appAnimations.isEmpty()) {
Winson Chungc6c3f852018-04-09 15:41:03 -0700433 cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION, "startAnimation-noAppWindows");
Winson Chungda876c92018-04-05 18:31:06 -0700434 return;
435 }
436
Winson Chung2dc37362018-03-12 17:57:06 -0700437 final RemoteAnimationTarget[] appTargets = appAnimations.toArray(
438 new RemoteAnimationTarget[appAnimations.size()]);
Winson Chunge2d72172018-01-25 17:46:20 +0000439 mPendingStart = false;
Winson Chung584d6522018-02-07 23:57:38 +0000440
Winson Chung9e8b0cb2018-08-03 16:23:52 -0700441 // Perform layout if it was scheduled before to make sure that we get correct content
442 // insets for the target app window after a rotation
443 final DisplayContent displayContent = mService.mRoot.getDisplayContent(mDisplayId);
444 displayContent.performLayout(false /* initial */, false /* updateInputWindows */);
445
Winson Chung3e2980e2018-03-29 17:28:57 -0700446 final Rect minimizedHomeBounds = mTargetAppToken != null
447 && mTargetAppToken.inSplitScreenSecondaryWindowingMode()
448 ? mMinimizedHomeBounds
449 : null;
Vadim Tryshev257f86b2018-08-23 16:45:02 -0700450 final Rect contentInsets;
451 if (mTargetAppToken != null && mTargetAppToken.findMainWindow() != null) {
chaviw9c81e632018-07-31 11:17:52 -0700452 contentInsets = mTargetAppToken.findMainWindow().getContentInsets();
Vadim Tryshev257f86b2018-08-23 16:45:02 -0700453 } else {
454 // If the window for the activity had not yet been created, use the display insets.
455 mService.getStableInsets(mDisplayId, mTmpRect);
456 contentInsets = mTmpRect;
457 }
Winson Chung9e8b0cb2018-08-03 16:23:52 -0700458 mRunner.onAnimationStart(mController, appTargets, contentInsets, minimizedHomeBounds);
Winson Chungc6c3f852018-04-09 15:41:03 -0700459 if (DEBUG_RECENTS_ANIMATIONS) {
460 Slog.d(TAG, "startAnimation(): Notify animation start:");
461 for (int i = 0; i < mPendingAnimations.size(); i++) {
462 final Task task = mPendingAnimations.get(i).mTask;
463 Slog.d(TAG, "\t" + task.mTaskId);
464 }
465 }
Winson Chunge2d72172018-01-25 17:46:20 +0000466 } catch (RemoteException e) {
467 Slog.e(TAG, "Failed to start recents animation", e);
468 }
Jorim Jaggi54cff642018-03-15 15:51:32 +0100469 final SparseIntArray reasons = new SparseIntArray();
470 reasons.put(WINDOWING_MODE_FULLSCREEN, APP_TRANSITION_RECENTS_ANIM);
Yunfan Chencafc7062019-01-22 17:21:32 +0900471 mService.mAtmInternal.notifyAppTransitionStarting(reasons, SystemClock.uptimeMillis());
Winson Chunge2d72172018-01-25 17:46:20 +0000472 }
473
Winson Chungc6c3f852018-04-09 15:41:03 -0700474 void cancelAnimation(@ReorderMode int reorderMode, String reason) {
lumark54284462019-03-05 20:44:27 +0800475 cancelAnimation(reorderMode, false /* runSynchronously */, false /*screenshot */, reason);
Winson Chung65c5f992018-04-20 14:58:57 -0700476 }
477
478 void cancelAnimationSynchronously(@ReorderMode int reorderMode, String reason) {
lumark54284462019-03-05 20:44:27 +0800479 cancelAnimation(reorderMode, true /* runSynchronously */, false /* screenshot */, reason);
480 }
481
482 void cancelAnimationWithScreenShot() {
483 cancelAnimation(REORDER_KEEP_IN_PLACE, true /* sync */, true /* screenshot */,
484 "stackOrderChanged");
Winson Chung65c5f992018-04-20 14:58:57 -0700485 }
486
487 private void cancelAnimation(@ReorderMode int reorderMode, boolean runSynchronously,
lumark54284462019-03-05 20:44:27 +0800488 boolean screenshot, String reason) {
Winson Chung65c5f992018-04-20 14:58:57 -0700489 if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "cancelAnimation(): reason=" + reason
490 + " runSynchronously=" + runSynchronously);
Winson Chung65fc89a2018-02-28 08:32:12 -0800491 synchronized (mService.getWindowManagerLock()) {
492 if (mCanceled) {
493 // We've already canceled the animation
494 return;
495 }
Adrian Roos842e7882018-03-26 17:34:06 +0200496 mService.mH.removeCallbacks(mFailsafeRunnable);
Winson Chung65fc89a2018-02-28 08:32:12 -0800497 mCanceled = true;
498 try {
lumark54284462019-03-05 20:44:27 +0800499 if (screenshot) {
500 // Screen shot previous task when next task starts transition.
501 final Task task = mPendingAnimations.get(0).mTask;
502 screenshotRecentTask(task, reorderMode, runSynchronously);
503 mRunner.onAnimationCanceled(true /* deferredWithScreenshot */);
504 return;
505 }
506 mRunner.onAnimationCanceled(false /* deferredWithScreenshot */);
Winson Chung65fc89a2018-02-28 08:32:12 -0800507 } catch (RemoteException e) {
508 Slog.e(TAG, "Failed to cancel recents animation", e);
509 }
lumark54284462019-03-05 20:44:27 +0800510 // Clean up and return to the previous app
Tracy Zhou9c675d42019-04-08 00:32:40 -0700511 mCallbacks.onAnimationFinished(reorderMode, runSynchronously,
512 false /* sendUserLeaveHint */);
lumark54284462019-03-05 20:44:27 +0800513 }
514 }
515
516 /**
517 * Cancel recents animation when the next app transition starts.
518 * <p>
519 * When we cancel the recents animation due to a stack order change, we can't just cancel it
520 * immediately as it would lead to a flicker in Launcher if we just remove the task from the
521 * leash. Instead we screenshot the previous task and replace the child of the leash with the
522 * screenshot, so that Launcher can still control the leash lifecycle & make the next app
523 * transition animate smoothly without flickering.
524 */
525 void cancelOnNextTransitionStart() {
526 mCancelOnNextTransitionStart = true;
527 }
528
529 void setCancelWithDeferredScreenshotLocked(boolean screenshot) {
530 mCancelWithDeferredScreenshot = screenshot;
531 }
532
533 boolean shouldCancelWithDeferredScreenshot() {
534 return mCancelWithDeferredScreenshot;
535 }
536
537 void onTransitionStart() {
538 if (mCanceled) {
539 return;
Winson Chunge2d72172018-01-25 17:46:20 +0000540 }
Winson Chungf557c3b2018-03-16 10:55:20 -0700541
lumark54284462019-03-05 20:44:27 +0800542 if (mCancelOnNextTransitionStart) {
543 mCancelOnNextTransitionStart = false;
544 cancelAnimationWithScreenShot();
545 }
546 }
547
548 void screenshotRecentTask(Task task, @ReorderMode int reorderMode, boolean runSynchronously) {
549 final TaskScreenshotAnimatable animatable = TaskScreenshotAnimatable.create(task);
550 if (animatable != null) {
551 mRecentScreenshotAnimator = new SurfaceAnimator(
552 animatable,
553 () -> {
554 if (DEBUG_RECENTS_ANIMATIONS) {
555 Slog.d(TAG, "mRecentScreenshotAnimator finish");
556 }
Tracy Zhou9c675d42019-04-08 00:32:40 -0700557 mCallbacks.onAnimationFinished(reorderMode, runSynchronously,
558 false /* sendUserLeaveHint */);
lumark54284462019-03-05 20:44:27 +0800559 }, mService);
560 mRecentScreenshotAnimator.transferAnimation(task.mSurfaceAnimator);
561 }
Winson Chunge2d72172018-01-25 17:46:20 +0000562 }
563
Winson Chung6a38fca2018-03-28 17:57:09 -0700564 void cleanupAnimation(@ReorderMode int reorderMode) {
Winson Chungc6c3f852018-04-09 15:41:03 -0700565 if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG,
566 "cleanupAnimation(): Notify animation finished mPendingAnimations="
567 + mPendingAnimations.size() + " reorderMode=" + reorderMode);
Winson Chunge2d72172018-01-25 17:46:20 +0000568 for (int i = mPendingAnimations.size() - 1; i >= 0; i--) {
Winson Chungda876c92018-04-05 18:31:06 -0700569 final TaskAnimationAdapter taskAdapter = mPendingAnimations.get(i);
Winson Chung3e2980e2018-03-29 17:28:57 -0700570 if (reorderMode == REORDER_MOVE_TO_TOP || reorderMode == REORDER_KEEP_IN_PLACE) {
Winson Chungda876c92018-04-05 18:31:06 -0700571 taskAdapter.mTask.dontAnimateDimExit();
chaviw87ca63a2018-03-26 14:06:17 -0700572 }
Winson Chungda876c92018-04-05 18:31:06 -0700573 removeAnimation(taskAdapter);
Winson Chunge2d72172018-01-25 17:46:20 +0000574 }
Winson Chunge2d72172018-01-25 17:46:20 +0000575
Winson Chung7906b3e2018-05-10 10:32:39 -0700576 // Clear any pending failsafe runnables
577 mService.mH.removeCallbacks(mFailsafeRunnable);
578
Winson Chung5c91e8f2018-05-07 10:06:55 -0700579 // Clear references to the runner
Adrian Roos653c6c12018-04-09 14:12:46 -0700580 unlinkToDeathOfRunner();
Winson Chung5c91e8f2018-05-07 10:06:55 -0700581 mRunner = null;
Winson Chung7906b3e2018-05-10 10:32:39 -0700582 mCanceled = true;
Winson Chung5c91e8f2018-05-07 10:06:55 -0700583
lumark54284462019-03-05 20:44:27 +0800584 // Make sure previous animator has cleaned-up.
585 if (mRecentScreenshotAnimator != null) {
586 mRecentScreenshotAnimator.cancelAnimation();
587 mRecentScreenshotAnimator = null;
588 }
589
Winson Chungdb111ee2018-10-03 14:25:34 -0700590 // Update the input windows after the animation is complete
Arthur Hung95b38a92018-07-20 18:56:12 +0800591 final InputMonitor inputMonitor =
592 mService.mRoot.getDisplayContent(mDisplayId).getInputMonitor();
Arthur Hung95b38a92018-07-20 18:56:12 +0800593 inputMonitor.updateInputWindowsLw(true /*force*/);
Winson Chung0bb66cc2018-04-10 11:58:15 -0700594
595 // We have deferred all notifications to the target app as a part of the recents animation,
596 // so if we are actually transitioning there, notify again here
597 if (mTargetAppToken != null) {
598 if (reorderMode == REORDER_MOVE_TO_TOP || reorderMode == REORDER_KEEP_IN_PLACE) {
lumark588a3e82018-07-20 18:53:54 +0800599 mService.mRoot.getDisplayContent(mDisplayId)
600 .mAppTransition.notifyAppTransitionFinishedLocked(mTargetAppToken.token);
Winson Chung0bb66cc2018-04-10 11:58:15 -0700601 }
602 }
Winson Chung67e49362019-05-17 16:40:38 -0700603
604 // Notify that the animation has ended
605 mStatusBar.onRecentsAnimationStateChanged(false /* running */);
Winson Chunge2d72172018-01-25 17:46:20 +0000606 }
607
Adrian Roos842e7882018-03-26 17:34:06 +0200608 void scheduleFailsafe() {
609 mService.mH.postDelayed(mFailsafeRunnable, FAILSAFE_DELAY);
610 }
611
Adrian Roos653c6c12018-04-09 14:12:46 -0700612 private void linkToDeathOfRunner() throws RemoteException {
613 if (!mLinkedToDeathOfRunner) {
614 mRunner.asBinder().linkToDeath(this, 0);
615 mLinkedToDeathOfRunner = true;
616 }
617 }
618
619 private void unlinkToDeathOfRunner() {
620 if (mLinkedToDeathOfRunner) {
621 mRunner.asBinder().unlinkToDeath(this, 0);
622 mLinkedToDeathOfRunner = false;
623 }
624 }
625
Adrian Roos842e7882018-03-26 17:34:06 +0200626 @Override
627 public void binderDied() {
Winson Chungc6c3f852018-04-09 15:41:03 -0700628 cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION, "binderDied");
Winson Chungdb111ee2018-10-03 14:25:34 -0700629
Arthur Hung1b636fa2018-12-04 15:53:49 +0800630 synchronized (mService.getWindowManagerLock()) {
631 // Clear associated input consumers on runner death
632 final InputMonitor inputMonitor =
633 mService.mRoot.getDisplayContent(mDisplayId).getInputMonitor();
634 inputMonitor.destroyInputConsumer(INPUT_CONSUMER_RECENTS_ANIMATION);
635 }
Adrian Roos842e7882018-03-26 17:34:06 +0200636 }
637
Winson Chunge2d72172018-01-25 17:46:20 +0000638 void checkAnimationReady(WallpaperController wallpaperController) {
639 if (mPendingStart) {
Winson Chung3e2980e2018-03-29 17:28:57 -0700640 final boolean wallpaperReady = !isTargetOverWallpaper()
Winson Chunge2d72172018-01-25 17:46:20 +0000641 || (wallpaperController.getWallpaperTarget() != null
642 && wallpaperController.wallpaperTransitionReady());
643 if (wallpaperReady) {
644 mService.getRecentsAnimationController().startAnimation();
645 }
646 }
647 }
648
Winson Chungf557c3b2018-03-16 10:55:20 -0700649 boolean isSplitScreenMinimized() {
650 return mSplitScreenMinimized;
651 }
652
Winson Chunge2d72172018-01-25 17:46:20 +0000653 boolean isWallpaperVisible(WindowState w) {
Winson Chung3e2980e2018-03-29 17:28:57 -0700654 return w != null && w.mAppToken != null && mTargetAppToken == w.mAppToken
655 && isTargetOverWallpaper();
Winson Chunge2d72172018-01-25 17:46:20 +0000656 }
657
Winson Chungdb111ee2018-10-03 14:25:34 -0700658 /**
659 * @return Whether to use the input consumer to override app input to route home/recents.
660 */
661 boolean shouldApplyInputConsumer(AppWindowToken appToken) {
662 // Only apply the input consumer if it is enabled, it is not the target (home/recents)
663 // being revealed with the transition, and we are actively animating the app as a part of
664 // the animation
665 return mInputConsumerEnabled && mTargetAppToken != appToken && isAnimatingApp(appToken);
Winson Chunga89ffed2018-01-25 17:46:11 +0000666 }
667
Arthur Hung95b38a92018-07-20 18:56:12 +0800668 boolean updateInputConsumerForApp(InputWindowHandle inputWindowHandle,
Winson Chunga89ffed2018-01-25 17:46:11 +0000669 boolean hasFocus) {
Winson Chung3e2980e2018-03-29 17:28:57 -0700670 // Update the input consumer touchable region to match the target app main window
671 final WindowState targetAppMainWindow = mTargetAppToken != null
672 ? mTargetAppToken.findMainWindow()
Winson Chunga89ffed2018-01-25 17:46:11 +0000673 : null;
Winson Chung3e2980e2018-03-29 17:28:57 -0700674 if (targetAppMainWindow != null) {
675 targetAppMainWindow.getBounds(mTmpRect);
Arthur Hung95b38a92018-07-20 18:56:12 +0800676 inputWindowHandle.hasFocus = hasFocus;
677 inputWindowHandle.touchableRegion.set(mTmpRect);
Winson Chunga89ffed2018-01-25 17:46:11 +0000678 return true;
679 }
680 return false;
681 }
682
Winson Chung0bb66cc2018-04-10 11:58:15 -0700683 boolean isTargetApp(AppWindowToken token) {
684 return mTargetAppToken != null && token == mTargetAppToken;
685 }
686
Winson Chung3e2980e2018-03-29 17:28:57 -0700687 private boolean isTargetOverWallpaper() {
688 if (mTargetAppToken == null) {
Winson Chunge2d72172018-01-25 17:46:20 +0000689 return false;
690 }
Winson Chung3e2980e2018-03-29 17:28:57 -0700691 return mTargetAppToken.windowsCanBeWallpaperTarget();
Winson Chunge2d72172018-01-25 17:46:20 +0000692 }
693
Winson Chungd41f71d2018-03-16 15:26:07 -0700694 boolean isAnimatingTask(Task task) {
695 for (int i = mPendingAnimations.size() - 1; i >= 0; i--) {
696 if (task == mPendingAnimations.get(i).mTask) {
697 return true;
698 }
699 }
700 return false;
701 }
702
Winson Chunga89ffed2018-01-25 17:46:11 +0000703 private boolean isAnimatingApp(AppWindowToken appToken) {
Winson Chunge2d72172018-01-25 17:46:20 +0000704 for (int i = mPendingAnimations.size() - 1; i >= 0; i--) {
705 final Task task = mPendingAnimations.get(i).mTask;
706 for (int j = task.getChildCount() - 1; j >= 0; j--) {
707 final AppWindowToken app = task.getChildAt(j);
708 if (app == appToken) {
709 return true;
710 }
711 }
712 }
713 return false;
714 }
715
Winson Chungda876c92018-04-05 18:31:06 -0700716 @VisibleForTesting
717 class TaskAnimationAdapter implements AnimationAdapter {
Winson Chunge2d72172018-01-25 17:46:20 +0000718
Vadim Tryshev593e9562018-03-08 17:15:45 -0800719 private final Task mTask;
Winson Chunge2d72172018-01-25 17:46:20 +0000720 private SurfaceControl mCapturedLeash;
721 private OnAnimationFinishedCallback mCapturedFinishCallback;
Vadim Tryshev593e9562018-03-08 17:15:45 -0800722 private final boolean mIsRecentTaskInvisible;
Jorim Jaggif75d1612018-02-27 15:05:21 +0100723 private RemoteAnimationTarget mTarget;
Winson Chungd41f71d2018-03-16 15:26:07 -0700724 private final Point mPosition = new Point();
725 private final Rect mBounds = new Rect();
Winson Chunge2d72172018-01-25 17:46:20 +0000726
Vadim Tryshev593e9562018-03-08 17:15:45 -0800727 TaskAnimationAdapter(Task task, boolean isRecentTaskInvisible) {
Winson Chunge2d72172018-01-25 17:46:20 +0000728 mTask = task;
Vadim Tryshev593e9562018-03-08 17:15:45 -0800729 mIsRecentTaskInvisible = isRecentTaskInvisible;
Winson Chungd41f71d2018-03-16 15:26:07 -0700730 final WindowContainer container = mTask.getParent();
Evan Roskyed6767f2018-10-26 17:21:06 -0700731 container.getRelativeDisplayedPosition(mPosition);
732 mBounds.set(container.getDisplayedBounds());
Winson Chunge2d72172018-01-25 17:46:20 +0000733 }
734
735 RemoteAnimationTarget createRemoteAnimationApp() {
Winson Chung173020c2018-05-04 15:36:47 -0700736 final AppWindowToken topApp = mTask.getTopVisibleAppToken();
737 final WindowState mainWindow = topApp != null
738 ? topApp.findMainWindow()
739 : null;
Winson Chung2dc37362018-03-12 17:57:06 -0700740 if (mainWindow == null) {
741 return null;
742 }
chaviw9c81e632018-07-31 11:17:52 -0700743 final Rect insets = new Rect();
744 mainWindow.getContentInsets(insets);
Jorim Jaggi817ebdd2018-03-26 15:46:01 +0200745 InsetUtils.addInsets(insets, mainWindow.mAppToken.getLetterboxInsets());
Winson Chung732446a2018-09-19 13:15:17 -0700746 final int mode = topApp.getActivityType() == mTargetActivityType
747 ? MODE_OPENING
748 : MODE_CLOSING;
749 mTarget = new RemoteAnimationTarget(mTask.mTaskId, mode, mCapturedLeash,
Winson Chung173020c2018-05-04 15:36:47 -0700750 !topApp.fillsParent(), mainWindow.mWinAnimator.mLastClipRect,
Winson Chungd41f71d2018-03-16 15:26:07 -0700751 insets, mTask.getPrefixOrderIndex(), mPosition, mBounds,
Evan Rosky2289ba12018-11-19 18:28:18 -0800752 mTask.getWindowConfiguration(), mIsRecentTaskInvisible, null, null);
Jorim Jaggif75d1612018-02-27 15:05:21 +0100753 return mTarget;
Winson Chunge2d72172018-01-25 17:46:20 +0000754 }
755
756 @Override
Jorim Jaggi82c17862018-02-21 17:50:18 +0100757 public boolean getShowWallpaper() {
758 return false;
759 }
760
761 @Override
Winson Chunge2d72172018-01-25 17:46:20 +0000762 public int getBackgroundColor() {
763 return 0;
764 }
765
766 @Override
767 public void startAnimation(SurfaceControl animationLeash, Transaction t,
768 OnAnimationFinishedCallback finishCallback) {
Winson Chung65a05862018-04-12 17:14:50 -0700769 // Restore z-layering, position and stack crop until client has a chance to modify it.
770 t.setLayer(animationLeash, mTask.getPrefixOrderIndex());
Winson Chungd41f71d2018-03-16 15:26:07 -0700771 t.setPosition(animationLeash, mPosition.x, mPosition.y);
Winson Chung65a05862018-04-12 17:14:50 -0700772 mTmpRect.set(mBounds);
773 mTmpRect.offsetTo(0, 0);
774 t.setWindowCrop(animationLeash, mTmpRect);
Winson Chunge2d72172018-01-25 17:46:20 +0000775 mCapturedLeash = animationLeash;
776 mCapturedFinishCallback = finishCallback;
777 }
778
779 @Override
780 public void onAnimationCancelled(SurfaceControl animationLeash) {
Winson Chungc6c3f852018-04-09 15:41:03 -0700781 cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION, "taskAnimationAdapterCanceled");
Winson Chunge2d72172018-01-25 17:46:20 +0000782 }
783
784 @Override
785 public long getDurationHint() {
786 return 0;
787 }
788
789 @Override
790 public long getStatusBarTransitionsStartTime() {
791 return SystemClock.uptimeMillis();
792 }
Jorim Jaggif75d1612018-02-27 15:05:21 +0100793
794 @Override
795 public void dump(PrintWriter pw, String prefix) {
796 pw.print(prefix); pw.println("task=" + mTask);
797 if (mTarget != null) {
798 pw.print(prefix); pw.println("Target:");
799 mTarget.dump(pw, prefix + " ");
800 } else {
801 pw.print(prefix); pw.println("Target: null");
802 }
Winson Chungc6c3f852018-04-09 15:41:03 -0700803 pw.println("mIsRecentTaskInvisible=" + mIsRecentTaskInvisible);
804 pw.println("mPosition=" + mPosition);
805 pw.println("mBounds=" + mBounds);
806 pw.println("mIsRecentTaskInvisible=" + mIsRecentTaskInvisible);
Jorim Jaggif75d1612018-02-27 15:05:21 +0100807 }
808
809 @Override
810 public void writeToProto(ProtoOutputStream proto) {
811 final long token = proto.start(REMOTE);
812 if (mTarget != null) {
813 mTarget.writeToProto(proto, TARGET);
814 }
815 proto.end(token);
816 }
Winson Chunge2d72172018-01-25 17:46:20 +0000817 }
818
819 public void dump(PrintWriter pw, String prefix) {
820 final String innerPrefix = prefix + " ";
821 pw.print(prefix); pw.println(RecentsAnimationController.class.getSimpleName() + ":");
822 pw.print(innerPrefix); pw.println("mPendingStart=" + mPendingStart);
Winson Chungdb111ee2018-10-03 14:25:34 -0700823 pw.print(innerPrefix); pw.println("mPendingAnimations=" + mPendingAnimations.size());
Winson Chungc6c3f852018-04-09 15:41:03 -0700824 pw.print(innerPrefix); pw.println("mCanceled=" + mCanceled);
825 pw.print(innerPrefix); pw.println("mInputConsumerEnabled=" + mInputConsumerEnabled);
826 pw.print(innerPrefix); pw.println("mSplitScreenMinimized=" + mSplitScreenMinimized);
Winson Chung3e2980e2018-03-29 17:28:57 -0700827 pw.print(innerPrefix); pw.println("mTargetAppToken=" + mTargetAppToken);
Winson Chungc6c3f852018-04-09 15:41:03 -0700828 pw.print(innerPrefix); pw.println("isTargetOverWallpaper=" + isTargetOverWallpaper());
Winson Chunge2d72172018-01-25 17:46:20 +0000829 }
830}