From 9a0b544d9303516e18405f7f91c6444f468c9a14 Mon Sep 17 00:00:00 2001 From: Jeff Chang Date: Thu, 11 Aug 2022 18:44:12 +0800 Subject: [PATCH] Removes the redundant instance for singleInstance The activity with launchMode "singleInstance" was able to be created in multiple instances. It contradicts with developers' documentation. The conditions for searching the reusable tasks always ignore the start-for-result results in singleInstance instances being created. The CL finishes existing instance when a new instance of singleInstance activity launches, in order to keep only one instance in the system. Some compatibility issues might be introduced if app incorrectly depend on singleInstance activities to be multiple instances. Bug: 122967919 Test: atest IntentTests Change-Id: I6345985a0ee5bd47d100d529bc3b50e8ae4d2bab --- .../java/com/android/server/wm/ActivityStarter.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index 619d693068d40..9ad62af2d4176 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -1866,6 +1866,16 @@ class ActivityStarter { final ActivityRecord targetTaskTop = newTask ? null : targetTask.getTopNonFinishingActivity(); if (targetTaskTop != null) { + // Removes the existing singleInstance activity in another task (if any) while + // launching a singleInstance activity on sourceRecord's task. + if (LAUNCH_SINGLE_INSTANCE == mLaunchMode && mSourceRecord != null + && targetTask == mSourceRecord.getTask()) { + final ActivityRecord activity = mRootWindowContainer.findActivity(mIntent, + mStartActivity.info, false); + if (activity != null && activity.getTask() != targetTask) { + activity.destroyIfPossible("Removes redundant singleInstance"); + } + } // Recycle the target task for this launch. startResult = recycleTask(targetTask, targetTaskTop, reusedTask, intentGrants); if (startResult != START_SUCCESS) {