blob: f1560d96120998b5c2578b598457027cfdc1a08d [file] [log] [blame]
Winson Chunge2d72172018-01-25 17:46:20 +00001/*
2 * Copyright (C) 2018 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
Wale Ogunwale59507092018-10-29 09:00:30 -070017package com.android.server.wm;
Winson Chunge2d72172018-01-25 17:46:20 +000018
Jorim Jaggi54cff642018-03-15 15:51:32 +010019import static android.app.ActivityManager.START_TASK_TO_FRONT;
Winson Chungf9930162018-02-12 14:51:46 -080020import static android.app.AppOpsManager.OP_ASSIST_STRUCTURE;
21import static android.app.AppOpsManager.OP_NONE;
Winson Chunge2d72172018-01-25 17:46:20 +000022import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
Winson Chung3e2980e2018-03-29 17:28:57 -070023import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
24import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Winson Chunge2d72172018-01-25 17:46:20 +000025import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
26import static android.content.Intent.FLAG_ACTIVITY_NO_ANIMATION;
Winson Chung584d6522018-02-07 23:57:38 +000027import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
Winson Chunge2d72172018-01-25 17:46:20 +000028import static android.view.WindowManager.TRANSIT_NONE;
Winson Chungfbbb1582018-11-13 16:09:01 -080029
Wale Ogunwale59507092018-10-29 09:00:30 -070030import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
Winson Chung3e2980e2018-03-29 17:28:57 -070031import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
32import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
33import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_TOP;
lumark54284462019-03-05 20:44:27 +080034import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_RECENTS_ANIMATIONS;
Winson Chunge2d72172018-01-25 17:46:20 +000035
36import android.app.ActivityOptions;
Winson Chungf9930162018-02-12 14:51:46 -080037import android.app.AppOpsManager;
38import android.app.IAssistDataReceiver;
Winson Chunge2d72172018-01-25 17:46:20 +000039import android.content.ComponentName;
Winson Chungf9930162018-02-12 14:51:46 -080040import android.content.Context;
Winson Chunge2d72172018-01-25 17:46:20 +000041import android.content.Intent;
Winson Chungfbbb1582018-11-13 16:09:01 -080042import android.os.Bundle;
43import android.os.IBinder;
Winson Chungddf62972018-02-12 11:10:04 -080044import android.os.RemoteException;
Winson Chung584d6522018-02-07 23:57:38 +000045import android.os.Trace;
Winson Chungddf62972018-02-12 11:10:04 -080046import android.util.Slog;
Winson Chunge2d72172018-01-25 17:46:20 +000047import android.view.IRecentsAnimationRunner;
lumark588a3e82018-07-20 18:53:54 +080048
Winson Chungfbbb1582018-11-13 16:09:01 -080049import com.android.server.LocalServices;
Wale Ogunwale59507092018-10-29 09:00:30 -070050import com.android.server.am.AssistDataRequester;
Felipe Leme749b8892018-12-03 16:30:30 -080051import com.android.server.contentcapture.ContentCaptureManagerInternal;
Winson Chunge2d72172018-01-25 17:46:20 +000052import com.android.server.wm.RecentsAnimationController.RecentsAnimationCallbacks;
Winson Chunge2d72172018-01-25 17:46:20 +000053
Winson Chungfbbb1582018-11-13 16:09:01 -080054import java.util.List;
55
Winson Chunge2d72172018-01-25 17:46:20 +000056/**
57 * Manages the recents animation, including the reordering of the stacks for the transition and
58 * cleanup. See {@link com.android.server.wm.RecentsAnimationController}.
59 */
Winson Chung0f7ec962018-05-03 18:03:15 -070060class RecentsAnimation implements RecentsAnimationCallbacks,
61 ActivityDisplay.OnStackOrderChangedListener {
Winson Chunge2d72172018-01-25 17:46:20 +000062 private static final String TAG = RecentsAnimation.class.getSimpleName();
lumark54284462019-03-05 20:44:27 +080063 private static final boolean DEBUG = DEBUG_RECENTS_ANIMATIONS;
Winson Chunge2d72172018-01-25 17:46:20 +000064
Wale Ogunwalea6191b42018-05-09 07:41:32 -070065 private final ActivityTaskManagerService mService;
Winson Chunge2d72172018-01-25 17:46:20 +000066 private final ActivityStackSupervisor mStackSupervisor;
67 private final ActivityStartController mActivityStartController;
68 private final WindowManagerService mWindowManager;
Winson Chung3e2980e2018-03-29 17:28:57 -070069 private final ActivityDisplay mDefaultDisplay;
Jorim Jaggibc2aabe2018-03-08 17:27:43 +010070 private final int mCallingPid;
Winson Chunge2d72172018-01-25 17:46:20 +000071
Winson Chung3e2980e2018-03-29 17:28:57 -070072 private int mTargetActivityType;
Winson Chungf9930162018-02-12 14:51:46 -080073 private AssistDataRequester mAssistDataRequester;
Winson Chung3e2980e2018-03-29 17:28:57 -070074
75 // The stack to restore the target stack behind when the animation is finished
76 private ActivityStack mRestoreTargetBehindStack;
Winson Chunge2d72172018-01-25 17:46:20 +000077
Wale Ogunwalea6191b42018-05-09 07:41:32 -070078 RecentsAnimation(ActivityTaskManagerService atm, ActivityStackSupervisor stackSupervisor,
Winson Chunge2d72172018-01-25 17:46:20 +000079 ActivityStartController activityStartController, WindowManagerService wm,
Wale Ogunwalea6191b42018-05-09 07:41:32 -070080 int callingPid) {
81 mService = atm;
Winson Chunge2d72172018-01-25 17:46:20 +000082 mStackSupervisor = stackSupervisor;
Wale Ogunwaled32da472018-11-16 07:19:28 -080083 mDefaultDisplay = mService.mRootActivityContainer.getDefaultDisplay();
Winson Chunge2d72172018-01-25 17:46:20 +000084 mActivityStartController = activityStartController;
Winson Chunge2d72172018-01-25 17:46:20 +000085 mWindowManager = wm;
Jorim Jaggibc2aabe2018-03-08 17:27:43 +010086 mCallingPid = callingPid;
Winson Chunge2d72172018-01-25 17:46:20 +000087 }
88
89 void startRecentsActivity(Intent intent, IRecentsAnimationRunner recentsAnimationRunner,
Winson Chungf9930162018-02-12 14:51:46 -080090 ComponentName recentsComponent, int recentsUid,
Winson Chungfbbb1582018-11-13 16:09:01 -080091 @Deprecated IAssistDataReceiver assistDataReceiver) {
Winson Chungf9930162018-02-12 14:51:46 -080092 if (DEBUG) Slog.d(TAG, "startRecentsActivity(): intent=" + intent
93 + " assistDataReceiver=" + assistDataReceiver);
Winson Chung584d6522018-02-07 23:57:38 +000094 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "RecentsAnimation#startRecentsActivity");
Winson Chungddf62972018-02-12 11:10:04 -080095
lumark588a3e82018-07-20 18:53:54 +080096 // TODO(multi-display) currently only support recents animation in default display.
Wale Ogunwale3a256e62018-12-06 14:41:18 -080097 final DisplayContent dc =
98 mService.mRootActivityContainer.getDefaultDisplay().mDisplayContent;
Winson Chungddf62972018-02-12 11:10:04 -080099 if (!mWindowManager.canStartRecentsAnimation()) {
100 notifyAnimationCancelBeforeStart(recentsAnimationRunner);
Winson Chungc6c3f852018-04-09 15:41:03 -0700101 if (DEBUG) Slog.d(TAG, "Can't start recents animation, nextAppTransition="
Wale Ogunwale3a256e62018-12-06 14:41:18 -0800102 + dc.mAppTransition.getAppTransition());
Winson Chungddf62972018-02-12 11:10:04 -0800103 return;
104 }
105
Winson Chung3e2980e2018-03-29 17:28:57 -0700106 // If the activity is associated with the recents stack, then try and get that first
107 mTargetActivityType = intent.getComponent() != null
108 && recentsComponent.equals(intent.getComponent())
109 ? ACTIVITY_TYPE_RECENTS
110 : ACTIVITY_TYPE_HOME;
Winson Chung93442032018-12-04 13:24:29 -0800111 ActivityStack targetStack = mDefaultDisplay.getStack(WINDOWING_MODE_UNDEFINED,
Winson Chung3e2980e2018-03-29 17:28:57 -0700112 mTargetActivityType);
Winson Chung00a09692018-04-19 16:14:09 -0700113 ActivityRecord targetActivity = getTargetActivity(targetStack, intent.getComponent());
Winson Chung3e2980e2018-03-29 17:28:57 -0700114 final boolean hasExistingActivity = targetActivity != null;
115 if (hasExistingActivity) {
116 final ActivityDisplay display = targetActivity.getDisplay();
117 mRestoreTargetBehindStack = display.getStackAbove(targetStack);
118 if (mRestoreTargetBehindStack == null) {
Winson Chungddf62972018-02-12 11:10:04 -0800119 notifyAnimationCancelBeforeStart(recentsAnimationRunner);
Winson Chungc6c3f852018-04-09 15:41:03 -0700120 if (DEBUG) Slog.d(TAG, "No stack above target stack=" + targetStack);
Winson Chungddf62972018-02-12 11:10:04 -0800121 return;
122 }
123 }
124
Winson Chung3e2980e2018-03-29 17:28:57 -0700125 // Send launch hint if we are actually launching the target. If it's already visible
126 // (shouldn't happen in general) we don't need to send it.
127 if (targetActivity == null || !targetActivity.visible) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800128 mService.mRootActivityContainer.sendPowerHintForLaunchStartIfNeeded(
129 true /* forceSend */, targetActivity);
Jorim Jaggiac960522018-03-22 23:20:36 +0100130 }
131
Igor Murashkin212d06c2018-10-22 16:34:39 -0700132 mStackSupervisor.getActivityMetricsLogger().notifyActivityLaunching(intent);
Jorim Jaggi54cff642018-03-15 15:51:32 +0100133
Wale Ogunwale1f5e53d2018-11-05 05:12:46 -0800134 mService.mH.post(() -> mService.mAmInternal.setRunningRemoteAnimation(mCallingPid, true));
Jorim Jaggibc2aabe2018-03-08 17:27:43 +0100135
Winson Chung1e6d4a92018-01-26 10:04:20 -0800136 mWindowManager.deferSurfaceLayout();
137 try {
Winson Chungf9930162018-02-12 14:51:46 -0800138 // Kick off the assist data request in the background before showing the target activity
Winson Chung3be4f262018-12-19 12:22:14 -0800139 requestAssistData(recentsComponent, recentsUid, assistDataReceiver);
Winson Chungf9930162018-02-12 14:51:46 -0800140
Winson Chung3e2980e2018-03-29 17:28:57 -0700141 if (hasExistingActivity) {
142 // Move the recents activity into place for the animation if it is not top most
Winson Chung0f7ec962018-05-03 18:03:15 -0700143 mDefaultDisplay.moveStackBehindBottomMostVisibleStack(targetStack);
Winson Chungc6c3f852018-04-09 15:41:03 -0700144 if (DEBUG) Slog.d(TAG, "Moved stack=" + targetStack + " behind stack="
Winson Chung0f7ec962018-05-03 18:03:15 -0700145 + mDefaultDisplay.getStackAbove(targetStack));
Winson Chung00a09692018-04-19 16:14:09 -0700146
147 // If there are multiple tasks in the target stack (ie. the home stack, with 3p
148 // and default launchers coexisting), then move the task to the top as a part of
149 // moving the stack to the front
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800150 if (targetStack.topTask() != targetActivity.getTaskRecord()) {
151 targetStack.addTask(targetActivity.getTaskRecord(), true /* toTop */,
Winson Chung00a09692018-04-19 16:14:09 -0700152 "startRecentsActivity");
153 }
Winson Chungddf62972018-02-12 11:10:04 -0800154 } else {
Winson Chung93442032018-12-04 13:24:29 -0800155 // No recents activity, create the new recents activity bottom most
Winson Chung3e2980e2018-03-29 17:28:57 -0700156 ActivityOptions options = ActivityOptions.makeBasic();
157 options.setLaunchActivityType(mTargetActivityType);
158 options.setAvoidMoveToFront();
Winson Chung1e6d4a92018-01-26 10:04:20 -0800159 intent.addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_NO_ANIMATION);
Winson Chunge2d72172018-01-25 17:46:20 +0000160
Winson Chung1e6d4a92018-01-26 10:04:20 -0800161 mActivityStartController
Winson Chung3e2980e2018-03-29 17:28:57 -0700162 .obtainStarter(intent, "startRecentsActivity_noTargetActivity")
Winson Chung1e6d4a92018-01-26 10:04:20 -0800163 .setCallingUid(recentsUid)
164 .setCallingPackage(recentsComponent.getPackageName())
Winson Chung3e2980e2018-03-29 17:28:57 -0700165 .setActivityOptions(SafeActivityOptions.fromBundle(options.toBundle()))
Winson Chung3be4f262018-12-19 12:22:14 -0800166 .setMayWait(mService.getCurrentUserId())
Winson Chung1e6d4a92018-01-26 10:04:20 -0800167 .execute();
Winson Chung93442032018-12-04 13:24:29 -0800168
169 // Move the recents activity into place for the animation
170 targetActivity = mDefaultDisplay.getStack(WINDOWING_MODE_UNDEFINED,
171 mTargetActivityType).getTopActivity();
172 targetStack = targetActivity.getActivityStack();
173 mDefaultDisplay.moveStackBehindBottomMostVisibleStack(targetStack);
174 if (DEBUG) {
175 Slog.d(TAG, "Moved stack=" + targetStack + " behind stack="
176 + mDefaultDisplay.getStackAbove(targetStack));
177 }
178
Winson Chung1e6d4a92018-01-26 10:04:20 -0800179 mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
Winson Chungba40d3a2018-05-16 09:40:16 -0700180 mWindowManager.executeAppTransition();
Winson Chunge2d72172018-01-25 17:46:20 +0000181
Winson Chungddf62972018-02-12 11:10:04 -0800182
Winson Chung1e6d4a92018-01-26 10:04:20 -0800183 // TODO: Maybe wait for app to draw in this particular case?
Winson Chungc6c3f852018-04-09 15:41:03 -0700184
185 if (DEBUG) Slog.d(TAG, "Started intent=" + intent);
Winson Chung1e6d4a92018-01-26 10:04:20 -0800186 }
Winson Chunge2d72172018-01-25 17:46:20 +0000187
Winson Chung3e2980e2018-03-29 17:28:57 -0700188 // Mark the target activity as launch-behind to bump its visibility for the
Winson Chung1e6d4a92018-01-26 10:04:20 -0800189 // duration of the gesture that is driven by the recents component
Winson Chung3e2980e2018-03-29 17:28:57 -0700190 targetActivity.mLaunchTaskBehind = true;
Winson Chung1e6d4a92018-01-26 10:04:20 -0800191
192 // Fetch all the surface controls and pass them to the client to get the animation
Winson Chung65c5f992018-04-20 14:58:57 -0700193 // started. Cancel any existing recents animation running synchronously (do not hold the
194 // WM lock)
195 mWindowManager.cancelRecentsAnimationSynchronously(REORDER_MOVE_TO_ORIGINAL_POSITION,
Winson Chungc6c3f852018-04-09 15:41:03 -0700196 "startRecentsActivity");
Winson Chung3e2980e2018-03-29 17:28:57 -0700197 mWindowManager.initializeRecentsAnimation(mTargetActivityType, recentsAnimationRunner,
Winson Chung0f7ec962018-05-03 18:03:15 -0700198 this, mDefaultDisplay.mDisplayId,
199 mStackSupervisor.mRecentTasks.getRecentTaskIds());
Winson Chung1e6d4a92018-01-26 10:04:20 -0800200
201 // If we updated the launch-behind state, update the visibility of the activities after
202 // we fetch the visible tasks to be controlled by the animation
Wale Ogunwaled32da472018-11-16 07:19:28 -0800203 mService.mRootActivityContainer.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS);
Jorim Jaggi54cff642018-03-15 15:51:32 +0100204
205 mStackSupervisor.getActivityMetricsLogger().notifyActivityLaunched(START_TASK_TO_FRONT,
Winson Chung3e2980e2018-03-29 17:28:57 -0700206 targetActivity);
Winson Chung0f7ec962018-05-03 18:03:15 -0700207
208 // Register for stack order changes
209 mDefaultDisplay.registerStackOrderChangedListener(this);
Winson Chungc6c3f852018-04-09 15:41:03 -0700210 } catch (Exception e) {
211 Slog.e(TAG, "Failed to start recents activity", e);
212 throw e;
Winson Chung1e6d4a92018-01-26 10:04:20 -0800213 } finally {
214 mWindowManager.continueSurfaceLayout();
Winson Chung584d6522018-02-07 23:57:38 +0000215 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
Winson Chunge2d72172018-01-25 17:46:20 +0000216 }
Winson Chunge2d72172018-01-25 17:46:20 +0000217 }
218
Winson Chungfbbb1582018-11-13 16:09:01 -0800219 /**
220 * Requests assist data for the top visible activities.
221 */
222 private void requestAssistData(ComponentName recentsComponent, int recentsUid,
Winson Chung3be4f262018-12-19 12:22:14 -0800223 @Deprecated IAssistDataReceiver assistDataReceiver) {
Winson Chungfbbb1582018-11-13 16:09:01 -0800224 final AppOpsManager appOpsManager = (AppOpsManager)
225 mService.mContext.getSystemService(Context.APP_OPS_SERVICE);
Wale Ogunwaled32da472018-11-16 07:19:28 -0800226 final List<IBinder> topActivities =
227 mService.mRootActivityContainer.getTopVisibleActivities();
Winson Chungfbbb1582018-11-13 16:09:01 -0800228 final AssistDataRequester.AssistDataRequesterCallbacks assistDataCallbacks;
229 if (assistDataReceiver != null) {
230 assistDataCallbacks = new AssistDataReceiverProxy(assistDataReceiver,
231 recentsComponent.getPackageName()) {
232 @Override
233 public void onAssistDataReceivedLocked(Bundle data, int activityIndex,
234 int activityCount) {
235 // Try to notify the intelligence service first
Felipe Leme749b8892018-12-03 16:30:30 -0800236 final ContentCaptureManagerInternal imService =
237 LocalServices.getService(ContentCaptureManagerInternal.class);
Winson Chungfbbb1582018-11-13 16:09:01 -0800238 final IBinder activityToken = topActivities.get(activityIndex);
Winson Chung3be4f262018-12-19 12:22:14 -0800239 final ActivityRecord r = ActivityRecord.forTokenLocked(activityToken);
240 if (r != null && (imService == null
241 || !imService.sendActivityAssistData(r.mUserId, activityToken, data))) {
Winson Chungfbbb1582018-11-13 16:09:01 -0800242 // Otherwise, use the provided assist data receiver
243 super.onAssistDataReceivedLocked(data, activityIndex, activityCount);
244 }
245 }
246 };
247 } else {
Felipe Leme749b8892018-12-03 16:30:30 -0800248 final ContentCaptureManagerInternal imService =
249 LocalServices.getService(ContentCaptureManagerInternal.class);
Winson Chungfbbb1582018-11-13 16:09:01 -0800250 if (imService == null) {
251 // There is no intelligence service, so there is no point requesting assist data
252 return;
253 }
254
255 assistDataCallbacks = new AssistDataRequester.AssistDataRequesterCallbacks() {
256 @Override
257 public boolean canHandleReceivedAssistDataLocked() {
258 return true;
259 }
260
261 @Override
262 public void onAssistDataReceivedLocked(Bundle data, int activityIndex,
263 int activityCount) {
264 // Try to notify the intelligence service
265 final IBinder activityToken = topActivities.get(activityIndex);
Winson Chung3be4f262018-12-19 12:22:14 -0800266 final ActivityRecord r = ActivityRecord.forTokenLocked(activityToken);
267 if (r != null) {
268 imService.sendActivityAssistData(r.mUserId, activityToken, data);
269 }
Winson Chungfbbb1582018-11-13 16:09:01 -0800270 }
271 };
272 }
273 mAssistDataRequester = new AssistDataRequester(mService.mContext, mWindowManager,
274 appOpsManager, assistDataCallbacks, this, OP_ASSIST_STRUCTURE, OP_NONE);
Winson Chung48b2bbd2018-11-15 16:02:56 -0800275 mAssistDataRequester.requestAutofillData(topActivities,
Winson Chungfbbb1582018-11-13 16:09:01 -0800276 recentsUid, recentsComponent.getPackageName());
277 }
278
Winson Chung65c5f992018-04-20 14:58:57 -0700279 private void finishAnimation(@RecentsAnimationController.ReorderMode int reorderMode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700280 synchronized (mService.mGlobalLock) {
Winson Chungc6c3f852018-04-09 15:41:03 -0700281 if (DEBUG) Slog.d(TAG, "onAnimationFinished(): controller="
Winson Chung65c5f992018-04-20 14:58:57 -0700282 + mWindowManager.getRecentsAnimationController()
283 + " reorderMode=" + reorderMode);
Winson Chungf9930162018-02-12 14:51:46 -0800284
285 // Cancel the associated assistant data request
286 if (mAssistDataRequester != null) {
287 mAssistDataRequester.cancel();
288 mAssistDataRequester = null;
289 }
290
Winson Chung0f7ec962018-05-03 18:03:15 -0700291 // Unregister for stack order changes
292 mDefaultDisplay.unregisterStackOrderChangedListener(this);
293
Winson Chunge2d72172018-01-25 17:46:20 +0000294 if (mWindowManager.getRecentsAnimationController() == null) return;
295
Winson Chung3e2980e2018-03-29 17:28:57 -0700296 // Just to be sure end the launch hint in case the target activity was never launched.
297 // However, if we're keeping the activity and making it visible, we can leave it on.
298 if (reorderMode != REORDER_KEEP_IN_PLACE) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800299 mService.mRootActivityContainer.sendPowerHintForLaunchEndIfNeeded();
Jorim Jaggiac960522018-03-22 23:20:36 +0100300 }
301
Wale Ogunwale1f5e53d2018-11-05 05:12:46 -0800302 mService.mH.post(
303 () -> mService.mAmInternal.setRunningRemoteAnimation(mCallingPid, false));
Jorim Jaggibc2aabe2018-03-08 17:27:43 +0100304
Winson Chunge2d72172018-01-25 17:46:20 +0000305 mWindowManager.inSurfaceTransaction(() -> {
Winson Chung584d6522018-02-07 23:57:38 +0000306 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER,
307 "RecentsAnimation#onAnimationFinished_inSurfaceTransaction");
Winson Chung1e6d4a92018-01-26 10:04:20 -0800308 mWindowManager.deferSurfaceLayout();
309 try {
Winson Chung6a38fca2018-03-28 17:57:09 -0700310 mWindowManager.cleanupRecentsAnimation(reorderMode);
Winson Chunge2d72172018-01-25 17:46:20 +0000311
Winson Chung3e2980e2018-03-29 17:28:57 -0700312 final ActivityStack targetStack = mDefaultDisplay.getStack(
313 WINDOWING_MODE_UNDEFINED, mTargetActivityType);
Winson Chung82389a92018-05-03 10:43:51 -0700314 final ActivityRecord targetActivity = targetStack != null
315 ? targetStack.getTopActivity()
316 : null;
Winson Chungc6c3f852018-04-09 15:41:03 -0700317 if (DEBUG) Slog.d(TAG, "onAnimationFinished(): targetStack=" + targetStack
318 + " targetActivity=" + targetActivity
319 + " mRestoreTargetBehindStack=" + mRestoreTargetBehindStack);
Winson Chung3e2980e2018-03-29 17:28:57 -0700320 if (targetActivity == null) {
Winson Chung1e6d4a92018-01-26 10:04:20 -0800321 return;
322 }
323
324 // Restore the launched-behind state
Winson Chung3e2980e2018-03-29 17:28:57 -0700325 targetActivity.mLaunchTaskBehind = false;
Winson Chung1e6d4a92018-01-26 10:04:20 -0800326
Winson Chung3e2980e2018-03-29 17:28:57 -0700327 if (reorderMode == REORDER_MOVE_TO_TOP) {
328 // Bring the target stack to the front
329 mStackSupervisor.mNoAnimActivities.add(targetActivity);
330 targetStack.moveToFront("RecentsAnimation.onAnimationFinished()");
Winson Chungc6c3f852018-04-09 15:41:03 -0700331 if (DEBUG) {
332 final ActivityStack topStack = getTopNonAlwaysOnTopStack();
333 if (topStack != targetStack) {
334 Slog.w(TAG, "Expected target stack=" + targetStack
335 + " to be top most but found stack=" + topStack);
336 }
337 }
Winson Chung3e2980e2018-03-29 17:28:57 -0700338 } else if (reorderMode == REORDER_MOVE_TO_ORIGINAL_POSITION){
339 // Restore the target stack to its previous position
340 final ActivityDisplay display = targetActivity.getDisplay();
341 display.moveStackBehindStack(targetStack, mRestoreTargetBehindStack);
Winson Chungc6c3f852018-04-09 15:41:03 -0700342 if (DEBUG) {
343 final ActivityStack aboveTargetStack =
344 mDefaultDisplay.getStackAbove(targetStack);
345 if (mRestoreTargetBehindStack != null
346 && aboveTargetStack != mRestoreTargetBehindStack) {
347 Slog.w(TAG, "Expected target stack=" + targetStack
348 + " to restored behind stack=" + mRestoreTargetBehindStack
349 + " but it is behind stack=" + aboveTargetStack);
350 }
351 }
Winson Chung6a38fca2018-03-28 17:57:09 -0700352 } else {
Winson Chung3e2980e2018-03-29 17:28:57 -0700353 // Keep target stack in place, nothing changes, so ignore the transition
354 // logic below
Winson Chung6a38fca2018-03-28 17:57:09 -0700355 return;
Winson Chung1e6d4a92018-01-26 10:04:20 -0800356 }
357
358 mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
Wale Ogunwaled32da472018-11-16 07:19:28 -0800359 mService.mRootActivityContainer.ensureActivitiesVisible(null, 0, false);
360 mService.mRootActivityContainer.resumeFocusedStacksTopActivities();
Winson Chung1e6d4a92018-01-26 10:04:20 -0800361
362 // No reason to wait for the pausing activity in this case, as the hiding of
363 // surfaces needs to be done immediately.
364 mWindowManager.executeAppTransition();
Winson Chungf557c3b2018-03-16 10:55:20 -0700365
366 // After reordering the stacks, reset the minimized state. At this point, either
Winson Chung3e2980e2018-03-29 17:28:57 -0700367 // the target activity is now top-most and we will stay minimized (if in
368 // split-screen), or we will have returned to the app, and the minimized state
369 // should be reset
Winson Chungf557c3b2018-03-16 10:55:20 -0700370 mWindowManager.checkSplitScreenMinimizedChanged(true /* animate */);
Winson Chungc6c3f852018-04-09 15:41:03 -0700371 } catch (Exception e) {
372 Slog.e(TAG, "Failed to clean up recents activity", e);
373 throw e;
Winson Chung1e6d4a92018-01-26 10:04:20 -0800374 } finally {
375 mWindowManager.continueSurfaceLayout();
Winson Chung584d6522018-02-07 23:57:38 +0000376 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
Winson Chunge2d72172018-01-25 17:46:20 +0000377 }
Winson Chunge2d72172018-01-25 17:46:20 +0000378 });
379 }
380 }
Winson Chungddf62972018-02-12 11:10:04 -0800381
Winson Chung65c5f992018-04-20 14:58:57 -0700382 @Override
383 public void onAnimationFinished(@RecentsAnimationController.ReorderMode int reorderMode,
384 boolean runSychronously) {
385 if (runSychronously) {
386 finishAnimation(reorderMode);
387 } else {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700388 mService.mH.post(() -> finishAnimation(reorderMode));
Winson Chung65c5f992018-04-20 14:58:57 -0700389 }
390 }
391
Winson Chung0f7ec962018-05-03 18:03:15 -0700392 @Override
Winson Chung65d66d32018-12-13 17:48:39 -0800393 public void onStackOrderChanged(ActivityStack stack) {
394 if (DEBUG) Slog.d(TAG, "onStackOrderChanged(): stack=" + stack);
395 if (mDefaultDisplay.getIndexOf(stack) == -1 || !stack.shouldBeVisible(null)) {
396 // The stack is not visible, so ignore this change
397 return;
398 }
lumark54284462019-03-05 20:44:27 +0800399 final RecentsAnimationController controller =
400 mWindowManager.getRecentsAnimationController();
Winson Chung65d66d32018-12-13 17:48:39 -0800401
lumark54284462019-03-05 20:44:27 +0800402 // Cancel running recents animation and screenshot previous task when the next
403 // transition starts in below cases:
404 // 1) The next launching task is not in recents animation task.
405 // 2) The next task is home activity. (i.e. pressing home key to back home in recents).
406 if ((!controller.isAnimatingTask(stack.getTaskStack().getTopChild())
407 || controller.isTargetApp(stack.getTopActivity().mAppWindowToken))
408 && controller.shouldCancelWithDeferredScreenshot()) {
409 controller.cancelOnNextTransitionStart();
410 } else {
411 // Just cancel directly to unleash from launcher when the next launching task is the
412 // current top task.
413 mWindowManager.cancelRecentsAnimationSynchronously(REORDER_KEEP_IN_PLACE,
414 "stackOrderChanged");
415 }
Winson Chung0f7ec962018-05-03 18:03:15 -0700416 }
417
Winson Chungddf62972018-02-12 11:10:04 -0800418 /**
419 * Called only when the animation should be canceled prior to starting.
420 */
421 private void notifyAnimationCancelBeforeStart(IRecentsAnimationRunner recentsAnimationRunner) {
422 try {
lumark54284462019-03-05 20:44:27 +0800423 recentsAnimationRunner.onAnimationCanceled(false /* deferredWithScreenshot */);
Winson Chungddf62972018-02-12 11:10:04 -0800424 } catch (RemoteException e) {
425 Slog.e(TAG, "Failed to cancel recents animation before start", e);
426 }
427 }
Winson Chungc6c3f852018-04-09 15:41:03 -0700428
429 /**
430 * @return The top stack that is not always-on-top.
431 */
432 private ActivityStack getTopNonAlwaysOnTopStack() {
433 for (int i = mDefaultDisplay.getChildCount() - 1; i >= 0; i--) {
434 final ActivityStack s = mDefaultDisplay.getChildAt(i);
435 if (s.getWindowConfiguration().isAlwaysOnTop()) {
436 continue;
437 }
438 return s;
439 }
440 return null;
441 }
Winson Chung00a09692018-04-19 16:14:09 -0700442
443 /**
444 * @return the top activity in the {@param targetStack} matching the {@param component}, or just
445 * the top activity of the top task if no task matches the component.
446 */
447 private ActivityRecord getTargetActivity(ActivityStack targetStack, ComponentName component) {
448 if (targetStack == null) {
449 return null;
450 }
451
452 for (int i = targetStack.getChildCount() - 1; i >= 0; i--) {
Winson Chung65d66d32018-12-13 17:48:39 -0800453 final TaskRecord task = targetStack.getChildAt(i);
Winson Chung00a09692018-04-19 16:14:09 -0700454 if (task.getBaseIntent().getComponent().equals(component)) {
455 return task.getTopActivity();
456 }
457 }
458 return targetStack.getTopActivity();
459 }
Winson Chunge2d72172018-01-25 17:46:20 +0000460}