From f65ee7e9e33a0f652832a4d56f2e3757cf477644 Mon Sep 17 00:00:00 2001 From: Bryce Lee Date: Mon, 26 Mar 2018 16:03:47 -0700 Subject: [PATCH] Do not set activity's task before clearing in some scenarios. When the clear top and reset task launch flags are specified for a standard launch mode activity, we should not add the activity to the task before taking these actions. Doing so leads to the potential of prematurely ending the starting activity and reparenting the activity without a window container controller set. This changelist ensures that the task is not associated until later. Fixes: 70635977 Test: atest CtsActivityManagerDeviceTestCases:ActivityStarterTests Change-Id: I8e2245f9ad9f07e259b099daefe9ebb2170ae28d --- .../android/server/am/ActivityStarter.java | 36 +++++++++++++------ 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java index a30a944b44f10..1b7e1edeffe91 100644 --- a/services/core/java/com/android/server/am/ActivityStarter.java +++ b/services/core/java/com/android/server/am/ActivityStarter.java @@ -46,6 +46,7 @@ import static android.content.Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED; import static android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS; import static android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP; import static android.content.pm.ActivityInfo.DOCUMENT_LAUNCH_ALWAYS; +import static android.content.pm.ActivityInfo.LAUNCH_MULTIPLE; import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE; import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK; import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TOP; @@ -1205,9 +1206,20 @@ class ActivityStarter { return START_RETURN_LOCK_TASK_MODE_VIOLATION; } - if (mStartActivity.getTask() == null) { + // True if we are clearing top and resetting of a standard (default) launch mode + // ({@code LAUNCH_MULTIPLE}) activity. The existing activity will be finished. + final boolean clearTopAndResetStandardLaunchMode = + (mLaunchFlags & (FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)) + == (FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) + && mLaunchMode == LAUNCH_MULTIPLE; + + // If mStartActivity does not have a task associated with it, associate it with the + // reused activity's task. Do not do so if we're clearing top and resetting for a + // standard launchMode activity. + if (mStartActivity.getTask() == null && !clearTopAndResetStandardLaunchMode) { mStartActivity.setTask(reusedActivity.getTask()); } + if (reusedActivity.getTask().intent == null) { // This task was started because of movement of the activity based on affinity... // Now that we are actually launching it, we can assign the base intent. @@ -1266,17 +1278,21 @@ class ActivityStarter { resumeTargetStackIfNeeded(); return START_RETURN_INTENT_TO_CALLER; } - setTaskFromIntentActivity(reusedActivity); - if (!mAddingToTask && mReuseTask == null) { - // We didn't do anything... but it was needed (a.k.a., client don't use that - // intent!) And for paranoia, make sure we have correctly resumed the top activity. - resumeTargetStackIfNeeded(); - if (outActivity != null && outActivity.length > 0) { - outActivity[0] = reusedActivity; + if (reusedActivity != null) { + setTaskFromIntentActivity(reusedActivity); + + if (!mAddingToTask && mReuseTask == null) { + // We didn't do anything... but it was needed (a.k.a., client don't use that + // intent!) And for paranoia, make sure we have correctly resumed the top activity. + + resumeTargetStackIfNeeded(); + if (outActivity != null && outActivity.length > 0) { + outActivity[0] = reusedActivity; + } + + return mMovedToFront ? START_TASK_TO_FRONT : START_DELIVERED_TO_TOP; } - - return mMovedToFront ? START_TASK_TO_FRONT : START_DELIVERED_TO_TOP; } }