Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 40fc6de5 authored by Louis Chang's avatar Louis Chang
Browse files

Keeps the intercepted activity on the existing secondary container

When intercepting an activity start request, a new split pair
was always created and launch the activity to the side of the
caller activity.

This CL launches the activity on top of the caller activity
if the caller activity is already on the secondary container.

This is needed for the case that the activity is started
into a new Task, or new Task will be escaped from the current
host Task and be displayed in fullscreen.

However, the interception won't work if the activity is started
from another process.

Also adding logs for TaskFragment errors.

Bug: 194997356
Test: manually, start activity with sample app
Change-Id: I268c1dad191cdfdbf48cac84e18f1dfda761b0d3
parent 5214873a
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -2599,6 +2599,12 @@
      "group": "WM_DEBUG_CONFIGURATION",
      "at": "com\/android\/server\/wm\/ActivityRecord.java"
    },
    "743418423": {
      "message": "Sending TaskFragment error exception=%s",
      "level": "VERBOSE",
      "group": "WM_DEBUG_WINDOW_ORGANIZER",
      "at": "com\/android\/server\/wm\/TaskFragmentOrganizerController.java"
    },
    "744171317": {
      "message": "      SKIP: %s",
      "level": "VERBOSE",
+60 −2
Original line number Diff line number Diff line
@@ -686,10 +686,24 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
            }
            final Activity launchingActivity = (Activity) who;

            if (!setLaunchingToSideContainer(launchingActivity, intent, options)) {
                setLaunchingInSameContainer(launchingActivity, intent, options);
            }

            return super.onStartActivity(who, intent, options);
        }

        /**
         * Returns {@code true} if the activity that is going to be started via the
         * {@code intent} should be paired with the {@code launchingActivity} and is set to be
         * launched in an empty side container.
         */
        private boolean setLaunchingToSideContainer(Activity launchingActivity, Intent intent,
                Bundle options) {
            final ExtensionSplitPairRule splitPairRule = getSplitRule(
                    launchingActivity.getComponentName(), intent.getComponent(), getSplitRules());
            if (splitPairRule == null) {
                return super.onStartActivity(who, intent, options);
                return false;
            }

            // Create a new split with an empty side container
@@ -700,8 +714,52 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
            // dedicated container.
            options.putBinder(ActivityOptions.KEY_LAUNCH_TASK_FRAGMENT_TOKEN,
                    secondaryContainer.getTaskFragmentToken());
            return true;
        }

            return super.onStartActivity(who, intent, options);
        /**
         * Checks if the activity that is going to be started via the {@code intent} should be
         * paired with the existing top activity which is currently paired with the
         * {@code launchingActivity}. If so, set the activity to be launched in the same
         * container of the {@code launchingActivity}.
         */
        private void setLaunchingInSameContainer(Activity launchingActivity, Intent intent,
                Bundle options) {
            final TaskFragmentContainer launchingContainer = getContainerWithActivity(
                    launchingActivity.getActivityToken());
            if (launchingContainer == null) {
                return;
            }

            final SplitContainer splitContainer = getActiveSplitForContainer(launchingContainer);
            if (splitContainer == null) {
                return;
            }

            if (splitContainer.getSecondaryContainer() != launchingContainer) {
                return;
            }

            // The launching activity is on the secondary container. Retrieve the primary
            // activity from the other container.
            Activity primaryActivity =
                    splitContainer.getPrimaryContainer().getTopNonFinishingActivity();
            if (primaryActivity == null) {
                return;
            }

            final ExtensionSplitPairRule splitPairRule = getSplitRule(
                    primaryActivity.getComponentName(), intent.getComponent(), getSplitRules());
            if (splitPairRule == null) {
                return;
            }

            // Amend the request to let the WM know that the activity should be placed in the
            // dedicated container. This is necessary for the case that the activity is started
            // into a new Task, or new Task will be escaped from the current host Task and be
            // displayed in fullscreen.
            options.putBinder(ActivityOptions.KEY_LAUNCH_TASK_FRAGMENT_TOKEN,
                    launchingContainer.getTaskFragmentToken());
        }
    }
}
+3 −0
Original line number Diff line number Diff line
@@ -199,6 +199,8 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr

        void onTaskFragmentError(ITaskFragmentOrganizer organizer, IBinder errorCallbackToken,
                Throwable exception) {
            ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER,
                    "Sending TaskFragment error exception=%s", exception.toString());
            final Bundle exceptionBundle = putExceptionInBundle(exception);
            try {
                organizer.onTaskFragmentError(errorCallbackToken, exceptionBundle);
@@ -313,6 +315,7 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
    void onTaskFragmentError(ITaskFragmentOrganizer organizer, IBinder errorCallbackToken,
            Throwable exception) {
        validateAndGetState(organizer);
        Slog.w(TAG, "onTaskFragmentError ", exception);
        PendingTaskFragmentEvent pendingEvent = new PendingTaskFragmentEvent(organizer,
                errorCallbackToken, exception, PendingTaskFragmentEvent.EVENT_ERROR);
        mPendingTaskFragmentEvents.add(pendingEvent);