From 5a22eceefeeccc61c48925bb11d07405811f825f Mon Sep 17 00:00:00 2001 From: Chris Li Date: Tue, 1 Nov 2022 18:16:18 +0800 Subject: [PATCH] Fix launching ActivityGroup with ActivityEmbedding ActivityGroup has been deprecated since Android H, but there are still apps using it. When it is used, the child Activity will not have its own corresponding ActivityRecord. If we treat it as normal Activity, there will be issue because we can't find Task with its token, nor reparent it with its token. Skip child Activity (the one launched in ActivityGroup) for any lifecycle event. Fix: 256533615 Test: manually verify Change-Id: Ibccf1575c3b229a0912f843f6468a6c3e24a893f --- .../extensions/embedding/SplitController.java | 26 ++++++++++++++++++- .../extensions/embedding/SplitPresenter.java | 2 +- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java index 1d513e444050e..16760e26b3f1a 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java @@ -1873,6 +1873,11 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen @Override public void onActivityPreCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) { + if (activity.isChild()) { + // Skip Activity that is child of another Activity (ActivityGroup) because it's + // window will just be a child of the parent Activity window. + return; + } synchronized (mLock) { final IBinder activityToken = activity.getActivityToken(); final IBinder initialTaskFragmentToken = @@ -1904,6 +1909,11 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen @Override public void onActivityPostCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) { + if (activity.isChild()) { + // Skip Activity that is child of another Activity (ActivityGroup) because it's + // window will just be a child of the parent Activity window. + return; + } // Calling after Activity#onCreate is complete to allow the app launch something // first. In case of a configured placeholder activity we want to make sure // that we don't launch it if an activity itself already requested something to be @@ -1921,6 +1931,11 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen @Override public void onActivityConfigurationChanged(@NonNull Activity activity) { + if (activity.isChild()) { + // Skip Activity that is child of another Activity (ActivityGroup) because it's + // window will just be a child of the parent Activity window. + return; + } synchronized (mLock) { final TransactionRecord transactionRecord = mTransactionManager .startNewTransaction(); @@ -1934,6 +1949,11 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen @Override public void onActivityPostDestroyed(@NonNull Activity activity) { + if (activity.isChild()) { + // Skip Activity that is child of another Activity (ActivityGroup) because it's + // window will just be a child of the parent Activity window. + return; + } synchronized (mLock) { SplitController.this.onActivityDestroyed(activity); } @@ -1969,7 +1989,11 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen if (who instanceof Activity) { // We will check if the new activity should be split with the activity that launched // it. - launchingActivity = (Activity) who; + final Activity activity = (Activity) who; + // For Activity that is child of another Activity (ActivityGroup), treat the parent + // Activity as the launching one because it's window will just be a child of the + // parent Activity window. + launchingActivity = activity.isChild() ? activity.getParent() : activity; if (isInPictureInPicture(launchingActivity)) { // We don't embed activity when it is in PIP. return super.onStartActivity(who, intent, options); diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java index 79603233ae141..362f1fa096cce 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java @@ -227,7 +227,7 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { final TaskFragmentContainer curSecondaryContainer = mController.getContainerWithActivity( secondaryActivity); TaskFragmentContainer containerToAvoid = primaryContainer; - if (curSecondaryContainer != null + if (curSecondaryContainer != null && curSecondaryContainer != primaryContainer && (rule.shouldClearTop() || primaryContainer.isAbove(curSecondaryContainer))) { // Do not reuse the current TaskFragment if the rule is to clear top, or if it is below // the primary TaskFragment.