blob: ec2d6737ee51ca2bc33b0a8d78a494d5c3129fb3 [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;
Winson Chunge2d72172018-01-25 17:46:20 +000034
35import android.app.ActivityOptions;
Winson Chungf9930162018-02-12 14:51:46 -080036import android.app.AppOpsManager;
37import android.app.IAssistDataReceiver;
Winson Chunge2d72172018-01-25 17:46:20 +000038import android.content.ComponentName;
Winson Chungf9930162018-02-12 14:51:46 -080039import android.content.Context;
Winson Chunge2d72172018-01-25 17:46:20 +000040import android.content.Intent;
Winson Chungfbbb1582018-11-13 16:09:01 -080041import android.os.Bundle;
42import android.os.IBinder;
Winson Chungddf62972018-02-12 11:10:04 -080043import android.os.RemoteException;
Winson Chung584d6522018-02-07 23:57:38 +000044import android.os.Trace;
Winson Chungddf62972018-02-12 11:10:04 -080045import android.util.Slog;
Winson Chunge2d72172018-01-25 17:46:20 +000046import android.view.IRecentsAnimationRunner;
lumark588a3e82018-07-20 18:53:54 +080047
Winson Chungfbbb1582018-11-13 16:09:01 -080048import com.android.server.LocalServices;
Wale Ogunwale59507092018-10-29 09:00:30 -070049import com.android.server.am.AssistDataRequester;
Felipe Leme749b8892018-12-03 16:30:30 -080050import com.android.server.contentcapture.ContentCaptureManagerInternal;
Winson Chunge2d72172018-01-25 17:46:20 +000051import com.android.server.wm.RecentsAnimationController.RecentsAnimationCallbacks;
Winson Chunge2d72172018-01-25 17:46:20 +000052
Winson Chungfbbb1582018-11-13 16:09:01 -080053import java.util.List;
54
Winson Chunge2d72172018-01-25 17:46:20 +000055/**
56 * Manages the recents animation, including the reordering of the stacks for the transition and
57 * cleanup. See {@link com.android.server.wm.RecentsAnimationController}.
58 */
Winson Chung0f7ec962018-05-03 18:03:15 -070059class RecentsAnimation implements RecentsAnimationCallbacks,
60 ActivityDisplay.OnStackOrderChangedListener {
Winson Chunge2d72172018-01-25 17:46:20 +000061 private static final String TAG = RecentsAnimation.class.getSimpleName();
Winson Chung44a7e2e2018-05-15 11:08:35 -070062 private static final boolean DEBUG = false;
Winson Chunge2d72172018-01-25 17:46:20 +000063
Wale Ogunwalea6191b42018-05-09 07:41:32 -070064 private final ActivityTaskManagerService mService;
Winson Chunge2d72172018-01-25 17:46:20 +000065 private final ActivityStackSupervisor mStackSupervisor;
66 private final ActivityStartController mActivityStartController;
67 private final WindowManagerService mWindowManager;
Winson Chung3e2980e2018-03-29 17:28:57 -070068 private final ActivityDisplay mDefaultDisplay;
Jorim Jaggibc2aabe2018-03-08 17:27:43 +010069 private final int mCallingPid;
Winson Chunge2d72172018-01-25 17:46:20 +000070
Winson Chung3e2980e2018-03-29 17:28:57 -070071 private int mTargetActivityType;
Winson Chungf9930162018-02-12 14:51:46 -080072 private AssistDataRequester mAssistDataRequester;
Winson Chung3e2980e2018-03-29 17:28:57 -070073
74 // The stack to restore the target stack behind when the animation is finished
75 private ActivityStack mRestoreTargetBehindStack;
Winson Chunge2d72172018-01-25 17:46:20 +000076
Wale Ogunwalea6191b42018-05-09 07:41:32 -070077 RecentsAnimation(ActivityTaskManagerService atm, ActivityStackSupervisor stackSupervisor,
Winson Chunge2d72172018-01-25 17:46:20 +000078 ActivityStartController activityStartController, WindowManagerService wm,
Wale Ogunwalea6191b42018-05-09 07:41:32 -070079 int callingPid) {
80 mService = atm;
Winson Chunge2d72172018-01-25 17:46:20 +000081 mStackSupervisor = stackSupervisor;
Wale Ogunwaled32da472018-11-16 07:19:28 -080082 mDefaultDisplay = mService.mRootActivityContainer.getDefaultDisplay();
Winson Chunge2d72172018-01-25 17:46:20 +000083 mActivityStartController = activityStartController;
Winson Chunge2d72172018-01-25 17:46:20 +000084 mWindowManager = wm;
Jorim Jaggibc2aabe2018-03-08 17:27:43 +010085 mCallingPid = callingPid;
Winson Chunge2d72172018-01-25 17:46:20 +000086 }
87
88 void startRecentsActivity(Intent intent, IRecentsAnimationRunner recentsAnimationRunner,
Winson Chungf9930162018-02-12 14:51:46 -080089 ComponentName recentsComponent, int recentsUid,
Winson Chungfbbb1582018-11-13 16:09:01 -080090 @Deprecated IAssistDataReceiver assistDataReceiver) {
Winson Chungf9930162018-02-12 14:51:46 -080091 if (DEBUG) Slog.d(TAG, "startRecentsActivity(): intent=" + intent
92 + " assistDataReceiver=" + assistDataReceiver);
Winson Chung584d6522018-02-07 23:57:38 +000093 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "RecentsAnimation#startRecentsActivity");
Winson Chungddf62972018-02-12 11:10:04 -080094
lumark588a3e82018-07-20 18:53:54 +080095 // TODO(multi-display) currently only support recents animation in default display.
Wale Ogunwale3a256e62018-12-06 14:41:18 -080096 final DisplayContent dc =
97 mService.mRootActivityContainer.getDefaultDisplay().mDisplayContent;
Winson Chungddf62972018-02-12 11:10:04 -080098 if (!mWindowManager.canStartRecentsAnimation()) {
99 notifyAnimationCancelBeforeStart(recentsAnimationRunner);
Winson Chungc6c3f852018-04-09 15:41:03 -0700100 if (DEBUG) Slog.d(TAG, "Can't start recents animation, nextAppTransition="
Wale Ogunwale3a256e62018-12-06 14:41:18 -0800101 + dc.mAppTransition.getAppTransition());
Winson Chungddf62972018-02-12 11:10:04 -0800102 return;
103 }
104
Winson Chung3e2980e2018-03-29 17:28:57 -0700105 // If the activity is associated with the recents stack, then try and get that first
106 mTargetActivityType = intent.getComponent() != null
107 && recentsComponent.equals(intent.getComponent())
108 ? ACTIVITY_TYPE_RECENTS
109 : ACTIVITY_TYPE_HOME;
Winson Chung93442032018-12-04 13:24:29 -0800110 ActivityStack targetStack = mDefaultDisplay.getStack(WINDOWING_MODE_UNDEFINED,
Winson Chung3e2980e2018-03-29 17:28:57 -0700111 mTargetActivityType);
Winson Chung00a09692018-04-19 16:14:09 -0700112 ActivityRecord targetActivity = getTargetActivity(targetStack, intent.getComponent());
Winson Chung3e2980e2018-03-29 17:28:57 -0700113 final boolean hasExistingActivity = targetActivity != null;
114 if (hasExistingActivity) {
115 final ActivityDisplay display = targetActivity.getDisplay();
116 mRestoreTargetBehindStack = display.getStackAbove(targetStack);
117 if (mRestoreTargetBehindStack == null) {
Winson Chungddf62972018-02-12 11:10:04 -0800118 notifyAnimationCancelBeforeStart(recentsAnimationRunner);
Winson Chungc6c3f852018-04-09 15:41:03 -0700119 if (DEBUG) Slog.d(TAG, "No stack above target stack=" + targetStack);
Winson Chungddf62972018-02-12 11:10:04 -0800120 return;
121 }
122 }
123
Winson Chung3e2980e2018-03-29 17:28:57 -0700124 // Send launch hint if we are actually launching the target. If it's already visible
125 // (shouldn't happen in general) we don't need to send it.
126 if (targetActivity == null || !targetActivity.visible) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800127 mService.mRootActivityContainer.sendPowerHintForLaunchStartIfNeeded(
128 true /* forceSend */, targetActivity);
Jorim Jaggiac960522018-03-22 23:20:36 +0100129 }
130
Igor Murashkin212d06c2018-10-22 16:34:39 -0700131 mStackSupervisor.getActivityMetricsLogger().notifyActivityLaunching(intent);
Jorim Jaggi54cff642018-03-15 15:51:32 +0100132
Wale Ogunwale1f5e53d2018-11-05 05:12:46 -0800133 mService.mH.post(() -> mService.mAmInternal.setRunningRemoteAnimation(mCallingPid, true));
Jorim Jaggibc2aabe2018-03-08 17:27:43 +0100134
Winson Chung1e6d4a92018-01-26 10:04:20 -0800135 mWindowManager.deferSurfaceLayout();
136 try {
Winson Chungfbbb1582018-11-13 16:09:01 -0800137 final int userId = mService.getCurrentUserId();
138
Winson Chungf9930162018-02-12 14:51:46 -0800139 // Kick off the assist data request in the background before showing the target activity
Winson Chungfbbb1582018-11-13 16:09:01 -0800140 requestAssistData(recentsComponent, recentsUid, assistDataReceiver, userId);
Winson Chungf9930162018-02-12 14:51:46 -0800141
Winson Chung3e2980e2018-03-29 17:28:57 -0700142 if (hasExistingActivity) {
143 // Move the recents activity into place for the animation if it is not top most
Winson Chung0f7ec962018-05-03 18:03:15 -0700144 mDefaultDisplay.moveStackBehindBottomMostVisibleStack(targetStack);
Winson Chungc6c3f852018-04-09 15:41:03 -0700145 if (DEBUG) Slog.d(TAG, "Moved stack=" + targetStack + " behind stack="
Winson Chung0f7ec962018-05-03 18:03:15 -0700146 + mDefaultDisplay.getStackAbove(targetStack));
Winson Chung00a09692018-04-19 16:14:09 -0700147
148 // If there are multiple tasks in the target stack (ie. the home stack, with 3p
149 // and default launchers coexisting), then move the task to the top as a part of
150 // moving the stack to the front
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800151 if (targetStack.topTask() != targetActivity.getTaskRecord()) {
152 targetStack.addTask(targetActivity.getTaskRecord(), true /* toTop */,
Winson Chung00a09692018-04-19 16:14:09 -0700153 "startRecentsActivity");
154 }
Winson Chungddf62972018-02-12 11:10:04 -0800155 } else {
Winson Chung93442032018-12-04 13:24:29 -0800156 // No recents activity, create the new recents activity bottom most
Winson Chung3e2980e2018-03-29 17:28:57 -0700157 ActivityOptions options = ActivityOptions.makeBasic();
158 options.setLaunchActivityType(mTargetActivityType);
159 options.setAvoidMoveToFront();
Winson Chung1e6d4a92018-01-26 10:04:20 -0800160 intent.addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_NO_ANIMATION);
Winson Chunge2d72172018-01-25 17:46:20 +0000161
Winson Chung1e6d4a92018-01-26 10:04:20 -0800162 mActivityStartController
Winson Chung3e2980e2018-03-29 17:28:57 -0700163 .obtainStarter(intent, "startRecentsActivity_noTargetActivity")
Winson Chung1e6d4a92018-01-26 10:04:20 -0800164 .setCallingUid(recentsUid)
165 .setCallingPackage(recentsComponent.getPackageName())
Winson Chung3e2980e2018-03-29 17:28:57 -0700166 .setActivityOptions(SafeActivityOptions.fromBundle(options.toBundle()))
Winson Chungfbbb1582018-11-13 16:09:01 -0800167 .setMayWait(userId)
Winson Chung1e6d4a92018-01-26 10:04:20 -0800168 .execute();
Winson Chung93442032018-12-04 13:24:29 -0800169
170 // Move the recents activity into place for the animation
171 targetActivity = mDefaultDisplay.getStack(WINDOWING_MODE_UNDEFINED,
172 mTargetActivityType).getTopActivity();
173 targetStack = targetActivity.getActivityStack();
174 mDefaultDisplay.moveStackBehindBottomMostVisibleStack(targetStack);
175 if (DEBUG) {
176 Slog.d(TAG, "Moved stack=" + targetStack + " behind stack="
177 + mDefaultDisplay.getStackAbove(targetStack));
178 }
179
Winson Chung1e6d4a92018-01-26 10:04:20 -0800180 mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
Winson Chungba40d3a2018-05-16 09:40:16 -0700181 mWindowManager.executeAppTransition();
Winson Chunge2d72172018-01-25 17:46:20 +0000182
Winson Chungddf62972018-02-12 11:10:04 -0800183
Winson Chung1e6d4a92018-01-26 10:04:20 -0800184 // TODO: Maybe wait for app to draw in this particular case?
Winson Chungc6c3f852018-04-09 15:41:03 -0700185
186 if (DEBUG) Slog.d(TAG, "Started intent=" + intent);
Winson Chung1e6d4a92018-01-26 10:04:20 -0800187 }
Winson Chunge2d72172018-01-25 17:46:20 +0000188
Winson Chung3e2980e2018-03-29 17:28:57 -0700189 // Mark the target activity as launch-behind to bump its visibility for the
Winson Chung1e6d4a92018-01-26 10:04:20 -0800190 // duration of the gesture that is driven by the recents component
Winson Chung3e2980e2018-03-29 17:28:57 -0700191 targetActivity.mLaunchTaskBehind = true;
Winson Chung1e6d4a92018-01-26 10:04:20 -0800192
193 // Fetch all the surface controls and pass them to the client to get the animation
Winson Chung65c5f992018-04-20 14:58:57 -0700194 // started. Cancel any existing recents animation running synchronously (do not hold the
195 // WM lock)
196 mWindowManager.cancelRecentsAnimationSynchronously(REORDER_MOVE_TO_ORIGINAL_POSITION,
Winson Chungc6c3f852018-04-09 15:41:03 -0700197 "startRecentsActivity");
Winson Chung3e2980e2018-03-29 17:28:57 -0700198 mWindowManager.initializeRecentsAnimation(mTargetActivityType, recentsAnimationRunner,
Winson Chung0f7ec962018-05-03 18:03:15 -0700199 this, mDefaultDisplay.mDisplayId,
200 mStackSupervisor.mRecentTasks.getRecentTaskIds());
Winson Chung1e6d4a92018-01-26 10:04:20 -0800201
202 // If we updated the launch-behind state, update the visibility of the activities after
203 // we fetch the visible tasks to be controlled by the animation
Wale Ogunwaled32da472018-11-16 07:19:28 -0800204 mService.mRootActivityContainer.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS);
Jorim Jaggi54cff642018-03-15 15:51:32 +0100205
206 mStackSupervisor.getActivityMetricsLogger().notifyActivityLaunched(START_TASK_TO_FRONT,
Winson Chung3e2980e2018-03-29 17:28:57 -0700207 targetActivity);
Winson Chung0f7ec962018-05-03 18:03:15 -0700208
209 // Register for stack order changes
210 mDefaultDisplay.registerStackOrderChangedListener(this);
Winson Chungc6c3f852018-04-09 15:41:03 -0700211 } catch (Exception e) {
212 Slog.e(TAG, "Failed to start recents activity", e);
213 throw e;
Winson Chung1e6d4a92018-01-26 10:04:20 -0800214 } finally {
215 mWindowManager.continueSurfaceLayout();
Winson Chung584d6522018-02-07 23:57:38 +0000216 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
Winson Chunge2d72172018-01-25 17:46:20 +0000217 }
Winson Chunge2d72172018-01-25 17:46:20 +0000218 }
219
Winson Chungfbbb1582018-11-13 16:09:01 -0800220 /**
221 * Requests assist data for the top visible activities.
222 */
223 private void requestAssistData(ComponentName recentsComponent, int recentsUid,
224 @Deprecated IAssistDataReceiver assistDataReceiver, int userId) {
225 final AppOpsManager appOpsManager = (AppOpsManager)
226 mService.mContext.getSystemService(Context.APP_OPS_SERVICE);
Wale Ogunwaled32da472018-11-16 07:19:28 -0800227 final List<IBinder> topActivities =
228 mService.mRootActivityContainer.getTopVisibleActivities();
Winson Chungfbbb1582018-11-13 16:09:01 -0800229 final AssistDataRequester.AssistDataRequesterCallbacks assistDataCallbacks;
230 if (assistDataReceiver != null) {
231 assistDataCallbacks = new AssistDataReceiverProxy(assistDataReceiver,
232 recentsComponent.getPackageName()) {
233 @Override
234 public void onAssistDataReceivedLocked(Bundle data, int activityIndex,
235 int activityCount) {
236 // Try to notify the intelligence service first
Felipe Leme749b8892018-12-03 16:30:30 -0800237 final ContentCaptureManagerInternal imService =
238 LocalServices.getService(ContentCaptureManagerInternal.class);
Winson Chungfbbb1582018-11-13 16:09:01 -0800239 final IBinder activityToken = topActivities.get(activityIndex);
240 if (imService == null
241 || !imService.sendActivityAssistData(userId, activityToken, data)) {
242 // 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);
266 imService.sendActivityAssistData(userId, activityToken, data);
267 }
268 };
269 }
270 mAssistDataRequester = new AssistDataRequester(mService.mContext, mWindowManager,
271 appOpsManager, assistDataCallbacks, this, OP_ASSIST_STRUCTURE, OP_NONE);
Winson Chung48b2bbd2018-11-15 16:02:56 -0800272 mAssistDataRequester.requestAutofillData(topActivities,
Winson Chungfbbb1582018-11-13 16:09:01 -0800273 recentsUid, recentsComponent.getPackageName());
274 }
275
Winson Chung65c5f992018-04-20 14:58:57 -0700276 private void finishAnimation(@RecentsAnimationController.ReorderMode int reorderMode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700277 synchronized (mService.mGlobalLock) {
Winson Chungc6c3f852018-04-09 15:41:03 -0700278 if (DEBUG) Slog.d(TAG, "onAnimationFinished(): controller="
Winson Chung65c5f992018-04-20 14:58:57 -0700279 + mWindowManager.getRecentsAnimationController()
280 + " reorderMode=" + reorderMode);
Winson Chungf9930162018-02-12 14:51:46 -0800281
282 // Cancel the associated assistant data request
283 if (mAssistDataRequester != null) {
284 mAssistDataRequester.cancel();
285 mAssistDataRequester = null;
286 }
287
Winson Chung0f7ec962018-05-03 18:03:15 -0700288 // Unregister for stack order changes
289 mDefaultDisplay.unregisterStackOrderChangedListener(this);
290
Winson Chunge2d72172018-01-25 17:46:20 +0000291 if (mWindowManager.getRecentsAnimationController() == null) return;
292
Winson Chung3e2980e2018-03-29 17:28:57 -0700293 // Just to be sure end the launch hint in case the target activity was never launched.
294 // However, if we're keeping the activity and making it visible, we can leave it on.
295 if (reorderMode != REORDER_KEEP_IN_PLACE) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800296 mService.mRootActivityContainer.sendPowerHintForLaunchEndIfNeeded();
Jorim Jaggiac960522018-03-22 23:20:36 +0100297 }
298
Wale Ogunwale1f5e53d2018-11-05 05:12:46 -0800299 mService.mH.post(
300 () -> mService.mAmInternal.setRunningRemoteAnimation(mCallingPid, false));
Jorim Jaggibc2aabe2018-03-08 17:27:43 +0100301
Winson Chunge2d72172018-01-25 17:46:20 +0000302 mWindowManager.inSurfaceTransaction(() -> {
Winson Chung584d6522018-02-07 23:57:38 +0000303 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER,
304 "RecentsAnimation#onAnimationFinished_inSurfaceTransaction");
Winson Chung1e6d4a92018-01-26 10:04:20 -0800305 mWindowManager.deferSurfaceLayout();
306 try {
Winson Chung6a38fca2018-03-28 17:57:09 -0700307 mWindowManager.cleanupRecentsAnimation(reorderMode);
Winson Chunge2d72172018-01-25 17:46:20 +0000308
Winson Chung3e2980e2018-03-29 17:28:57 -0700309 final ActivityStack targetStack = mDefaultDisplay.getStack(
310 WINDOWING_MODE_UNDEFINED, mTargetActivityType);
Winson Chung82389a92018-05-03 10:43:51 -0700311 final ActivityRecord targetActivity = targetStack != null
312 ? targetStack.getTopActivity()
313 : null;
Winson Chungc6c3f852018-04-09 15:41:03 -0700314 if (DEBUG) Slog.d(TAG, "onAnimationFinished(): targetStack=" + targetStack
315 + " targetActivity=" + targetActivity
316 + " mRestoreTargetBehindStack=" + mRestoreTargetBehindStack);
Winson Chung3e2980e2018-03-29 17:28:57 -0700317 if (targetActivity == null) {
Winson Chung1e6d4a92018-01-26 10:04:20 -0800318 return;
319 }
320
321 // Restore the launched-behind state
Winson Chung3e2980e2018-03-29 17:28:57 -0700322 targetActivity.mLaunchTaskBehind = false;
Winson Chung1e6d4a92018-01-26 10:04:20 -0800323
Winson Chung3e2980e2018-03-29 17:28:57 -0700324 if (reorderMode == REORDER_MOVE_TO_TOP) {
325 // Bring the target stack to the front
326 mStackSupervisor.mNoAnimActivities.add(targetActivity);
327 targetStack.moveToFront("RecentsAnimation.onAnimationFinished()");
Winson Chungc6c3f852018-04-09 15:41:03 -0700328 if (DEBUG) {
329 final ActivityStack topStack = getTopNonAlwaysOnTopStack();
330 if (topStack != targetStack) {
331 Slog.w(TAG, "Expected target stack=" + targetStack
332 + " to be top most but found stack=" + topStack);
333 }
334 }
Winson Chung3e2980e2018-03-29 17:28:57 -0700335 } else if (reorderMode == REORDER_MOVE_TO_ORIGINAL_POSITION){
336 // Restore the target stack to its previous position
337 final ActivityDisplay display = targetActivity.getDisplay();
338 display.moveStackBehindStack(targetStack, mRestoreTargetBehindStack);
Winson Chungc6c3f852018-04-09 15:41:03 -0700339 if (DEBUG) {
340 final ActivityStack aboveTargetStack =
341 mDefaultDisplay.getStackAbove(targetStack);
342 if (mRestoreTargetBehindStack != null
343 && aboveTargetStack != mRestoreTargetBehindStack) {
344 Slog.w(TAG, "Expected target stack=" + targetStack
345 + " to restored behind stack=" + mRestoreTargetBehindStack
346 + " but it is behind stack=" + aboveTargetStack);
347 }
348 }
Winson Chung6a38fca2018-03-28 17:57:09 -0700349 } else {
Winson Chung3e2980e2018-03-29 17:28:57 -0700350 // Keep target stack in place, nothing changes, so ignore the transition
351 // logic below
Winson Chung6a38fca2018-03-28 17:57:09 -0700352 return;
Winson Chung1e6d4a92018-01-26 10:04:20 -0800353 }
354
355 mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
Wale Ogunwaled32da472018-11-16 07:19:28 -0800356 mService.mRootActivityContainer.ensureActivitiesVisible(null, 0, false);
357 mService.mRootActivityContainer.resumeFocusedStacksTopActivities();
Winson Chung1e6d4a92018-01-26 10:04:20 -0800358
359 // No reason to wait for the pausing activity in this case, as the hiding of
360 // surfaces needs to be done immediately.
361 mWindowManager.executeAppTransition();
Winson Chungf557c3b2018-03-16 10:55:20 -0700362
363 // After reordering the stacks, reset the minimized state. At this point, either
Winson Chung3e2980e2018-03-29 17:28:57 -0700364 // the target activity is now top-most and we will stay minimized (if in
365 // split-screen), or we will have returned to the app, and the minimized state
366 // should be reset
Winson Chungf557c3b2018-03-16 10:55:20 -0700367 mWindowManager.checkSplitScreenMinimizedChanged(true /* animate */);
Winson Chungc6c3f852018-04-09 15:41:03 -0700368 } catch (Exception e) {
369 Slog.e(TAG, "Failed to clean up recents activity", e);
370 throw e;
Winson Chung1e6d4a92018-01-26 10:04:20 -0800371 } finally {
372 mWindowManager.continueSurfaceLayout();
Winson Chung584d6522018-02-07 23:57:38 +0000373 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
Winson Chunge2d72172018-01-25 17:46:20 +0000374 }
Winson Chunge2d72172018-01-25 17:46:20 +0000375 });
376 }
377 }
Winson Chungddf62972018-02-12 11:10:04 -0800378
Winson Chung65c5f992018-04-20 14:58:57 -0700379 @Override
380 public void onAnimationFinished(@RecentsAnimationController.ReorderMode int reorderMode,
381 boolean runSychronously) {
382 if (runSychronously) {
383 finishAnimation(reorderMode);
384 } else {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700385 mService.mH.post(() -> finishAnimation(reorderMode));
Winson Chung65c5f992018-04-20 14:58:57 -0700386 }
387 }
388
Winson Chung0f7ec962018-05-03 18:03:15 -0700389 @Override
Winson Chung65d66d32018-12-13 17:48:39 -0800390 public void onStackOrderChanged(ActivityStack stack) {
391 if (DEBUG) Slog.d(TAG, "onStackOrderChanged(): stack=" + stack);
392 if (mDefaultDisplay.getIndexOf(stack) == -1 || !stack.shouldBeVisible(null)) {
393 // The stack is not visible, so ignore this change
394 return;
395 }
396
Winson Chung0f7ec962018-05-03 18:03:15 -0700397 // If the activity display stack order changes, cancel any running recents animation in
398 // place
399 mWindowManager.cancelRecentsAnimationSynchronously(REORDER_KEEP_IN_PLACE,
400 "stackOrderChanged");
401 }
402
Winson Chungddf62972018-02-12 11:10:04 -0800403 /**
404 * Called only when the animation should be canceled prior to starting.
405 */
406 private void notifyAnimationCancelBeforeStart(IRecentsAnimationRunner recentsAnimationRunner) {
407 try {
408 recentsAnimationRunner.onAnimationCanceled();
409 } catch (RemoteException e) {
410 Slog.e(TAG, "Failed to cancel recents animation before start", e);
411 }
412 }
Winson Chungc6c3f852018-04-09 15:41:03 -0700413
414 /**
415 * @return The top stack that is not always-on-top.
416 */
417 private ActivityStack getTopNonAlwaysOnTopStack() {
418 for (int i = mDefaultDisplay.getChildCount() - 1; i >= 0; i--) {
419 final ActivityStack s = mDefaultDisplay.getChildAt(i);
420 if (s.getWindowConfiguration().isAlwaysOnTop()) {
421 continue;
422 }
423 return s;
424 }
425 return null;
426 }
Winson Chung00a09692018-04-19 16:14:09 -0700427
428 /**
429 * @return the top activity in the {@param targetStack} matching the {@param component}, or just
430 * the top activity of the top task if no task matches the component.
431 */
432 private ActivityRecord getTargetActivity(ActivityStack targetStack, ComponentName component) {
433 if (targetStack == null) {
434 return null;
435 }
436
437 for (int i = targetStack.getChildCount() - 1; i >= 0; i--) {
Winson Chung65d66d32018-12-13 17:48:39 -0800438 final TaskRecord task = targetStack.getChildAt(i);
Winson Chung00a09692018-04-19 16:14:09 -0700439 if (task.getBaseIntent().getComponent().equals(component)) {
440 return task.getTopActivity();
441 }
442 }
443 return targetStack.getTopActivity();
444 }
Winson Chunge2d72172018-01-25 17:46:20 +0000445}