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

Commit 4b08007b authored by wilsonshih's avatar wilsonshih
Browse files

Support task fragment for back navigation while adjacent.

Extends the opening targets to two activities.
For supports TaskFragment when adjacent, the opening target can be two
activities, here are the extra scenarios:

1. Task switch. The opening task can contains two activities, so when
using launchBehind to draw the activities, there will need to set flag
for them. And there should no extra work when using task snapshot.

2. Activity switch.
- If the close activity is adjacent to another one, and that one is the
previous activity, no predict animation because we don't know what will
happen.
- If the close activity is adjacent to another one, but that one isn't
the previous activity, start cross-activity animation as usual.
- If there is only one close activity, but the previous activity is
adjacent to another one, the opening target should be two activities.
TODO: for Activity switch case, the windowless starting window might be
two activity snapshot, or one splash screen to occlude two activities.

Bug: 274997067
Bug: 290845371
Test: atest BackNavigationControllerTests BackGestureInvokedTest
Test: invoke back navigation to the TaskFragment when adjacent.

Change-Id: I23e8f0156d1ba92d0a000c16c6c8469865885349
parent 253e11fc
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -353,7 +353,6 @@ public class CrossActivityAnimation extends ShellBackAnimation {
        closingLeft += mapRange(interpolatedProgress, deltaXMin, deltaXMax);

        // Move the window along the Y axis.
        final float deltaYRatio = (touchY - mInitialTouchPos.y) / height;
        final float closingTop = (height - closingHeight) * 0.5f;
        targetRect.set(
                closingLeft, closingTop, closingLeft + closingWidth, closingTop + closingHeight);
+0 −6
Original line number Diff line number Diff line
@@ -40,7 +40,6 @@ import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_UNSPECI
import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE;
import static android.view.WindowManager.TRANSIT_RELAUNCH;
import static android.window.TransitionInfo.FLAG_BACK_GESTURE_ANIMATED;
import static android.window.TransitionInfo.FLAG_CROSS_PROFILE_OWNER_THUMBNAIL;
import static android.window.TransitionInfo.FLAG_CROSS_PROFILE_WORK_THUMBNAIL;
import static android.window.TransitionInfo.FLAG_DISPLAY_HAS_ALERT_WINDOWS;
@@ -422,11 +421,6 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
                continue;
            }

            // The back gesture has animated this change before transition happen, so here we don't
            // play the animation again.
            if (change.hasFlags(FLAG_BACK_GESTURE_ANIMATED)) {
                continue;
            }
            // Don't animate anything that isn't independent.
            if (!TransitionInfo.isIndependent(change, info)) continue;

+6 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import static android.view.WindowManager.TRANSIT_SLEEP;
import static android.view.WindowManager.TRANSIT_TO_BACK;
import static android.view.WindowManager.TRANSIT_TO_FRONT;
import static android.view.WindowManager.fixScale;
import static android.window.TransitionInfo.FLAG_BACK_GESTURE_ANIMATED;
import static android.window.TransitionInfo.FLAG_IS_BEHIND_STARTING_WINDOW;
import static android.window.TransitionInfo.FLAG_IS_OCCLUDED;
import static android.window.TransitionInfo.FLAG_IS_WALLPAPER;
@@ -743,6 +744,11 @@ public class Transitions implements RemoteCallable<Transitions>,
            if (!change.hasFlags(FLAG_IS_OCCLUDED)) {
                allOccluded = false;
            }
            // The change has already animated by back gesture, don't need to play transition
            // animation on it.
            if (change.hasFlags(FLAG_BACK_GESTURE_ANIMATED)) {
                info.getChanges().remove(i);
            }
        }
        // There does not need animation when:
        // A. Transfer starting window. Apply transfer starting window directly if there is no other
+30 −35
Original line number Diff line number Diff line
@@ -1585,7 +1585,7 @@ class ActivityClientController extends IActivityClientController.Stub {
     * the Activities in the Task should be finished when it finishes. Otherwise, return {@code
     * false}.
     */
    private boolean isRelativeTaskRootActivity(ActivityRecord r, ActivityRecord taskRoot) {
    private static boolean isRelativeTaskRootActivity(ActivityRecord r, ActivityRecord taskRoot) {
        // Not a relative root if the given Activity is not the root Activity of its TaskFragment.
        final TaskFragment taskFragment = r.getTaskFragment();
        if (r != taskFragment.getActivity(ar -> !ar.finishing || ar == r,
@@ -1598,7 +1598,7 @@ class ActivityClientController extends IActivityClientController.Stub {
        return taskRoot.getTaskFragment().getCompanionTaskFragment() == taskFragment;
    }

    private boolean isTopActivityInTaskFragment(ActivityRecord activity) {
    private static boolean isTopActivityInTaskFragment(ActivityRecord activity) {
        return activity.getTaskFragment().topRunningActivity() == activity;
    }

@@ -1614,9 +1614,6 @@ class ActivityClientController extends IActivityClientController.Stub {
    public void onBackPressed(IBinder token, IRequestFinishCallback callback) {
        final long origId = Binder.clearCallingIdentity();
        try {
            final Intent baseActivityIntent;
            final boolean launchedFromHome;
            final boolean isLastRunningActivity;
            synchronized (mGlobalLock) {
                final ActivityRecord r = ActivityRecord.isInRootTaskLocked(token);
                if (r == null) return;
@@ -1624,27 +1621,32 @@ class ActivityClientController extends IActivityClientController.Stub {
                final Task task = r.getTask();
                final ActivityRecord root = task.getRootActivity(false /*ignoreRelinquishIdentity*/,
                        true /*setToBottomIfNone*/);
                final boolean isTaskRoot = r == root;
                if (isTaskRoot) {
                    if (mService.mWindowOrganizerController.mTaskOrganizerController
                if (r == root && mService.mWindowOrganizerController.mTaskOrganizerController
                        .handleInterceptBackPressedOnTaskRoot(r.getRootTask())) {
                    // This task is handled by a task organizer that has requested the back
                    // pressed callback.
                    return;
                }
                } else if (!isRelativeTaskRootActivity(r, root)) {
                    // Finish the Activity if the activity is not the task root or relative root.
                    requestCallbackFinish(callback);
                if (shouldMoveTaskToBack(r, root)) {
                    moveActivityTaskToBack(token, true /* nonRoot */);
                    return;
                }
            }

                isLastRunningActivity = isTopActivityInTaskFragment(isTaskRoot ? root : r);

                final boolean isBaseActivity = root.mActivityComponent.equals(task.realActivity);
                baseActivityIntent = isBaseActivity ? root.intent : null;
            // The default option for handling the back button is to finish the Activity.
            requestCallbackFinish(callback);
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
    }

                launchedFromHome = root.isLaunchSourceType(ActivityRecord.LAUNCH_SOURCE_TYPE_HOME);
    static boolean shouldMoveTaskToBack(ActivityRecord r, ActivityRecord rootActivity) {
        if (r != rootActivity && !isRelativeTaskRootActivity(r, rootActivity)) {
            return false;
        }
        final boolean isBaseActivity = rootActivity.mActivityComponent.equals(
                r.getTask().realActivity);
        final Intent baseActivityIntent = isBaseActivity ? rootActivity.intent : null;

        // If the activity was launched directly from the home screen, then we should
        // refrain from finishing the activity and instead move it to the back to keep it in
@@ -1653,17 +1655,10 @@ class ActivityClientController extends IActivityClientController.Stub {
        //   2. The current activity is the base activity for the task.
        //   3. The activity was launched by the home process, and is one of the main entry
        //      points for the application.
            if (baseActivityIntent != null && isLastRunningActivity
                    && launchedFromHome && ActivityRecord.isMainIntent(baseActivityIntent)) {
                moveActivityTaskToBack(token, true /* nonRoot */);
                return;
            }

            // The default option for handling the back button is to finish the Activity.
            requestCallbackFinish(callback);
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
        return baseActivityIntent != null
                && isTopActivityInTaskFragment(r)
                && rootActivity.isLaunchSourceType(ActivityRecord.LAUNCH_SOURCE_TYPE_HOME)
                && ActivityRecord.isMainIntent(baseActivityIntent);
    }

    @Override
+416 −132

File changed.

Preview size limit exceeded, changes collapsed.

Loading