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
This commit is contained in:
Chris Li
2022-11-01 18:16:18 +08:00
parent 96e8a788ef
commit 5a22eceefe
2 changed files with 26 additions and 2 deletions

View File

@@ -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);

View File

@@ -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.