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

Commit da9d2b6d authored by Louis Chang's avatar Louis Chang Committed by Android (Google) Code Review
Browse files

Merge "Intercept back for task root activity only" into main

parents c7273ac9 0b463e53
Loading
Loading
Loading
Loading
+29 −20
Original line number Diff line number Diff line
@@ -156,12 +156,13 @@ class BackNavigationController {
        public void onBackInvoked() {
            synchronized (mWindowManagerService.mGlobalLock) {
                final ActivityRecord r = mActivityRecordRef.get();
                boolean handled = false;
                if (r != null) {
                    handled = mWindowManagerService.mAtmService.mTaskOrganizerController
                            .handleInterceptBackPressedOnTaskRoot(r);
                if (r != null && mWindowManagerService.mAtmService.mTaskOrganizerController
                        .handleInterceptBackPressedOnTaskRoot(r)) {
                    // Handled by the controller, exit early.
                    return;
                }
                if (handled || mFallbackCallbackRef == null) {

                if (mFallbackCallbackRef == null) {
                    return;
                }

@@ -304,21 +305,8 @@ class BackNavigationController {
                return null;
            }

            final boolean interceptBack = currentTask != null
                    && currentTask.mAtmService.mTaskOrganizerController
                            .shouldInterceptBackPressedOnRootTask(currentTask.getRootTask());
            final OnBackInvokedCallbackInfo callbackInfo;
            if (interceptBack) {
                final OnBackInvokedCallbackInfo info = window.getOnBackInvokedCallbackInfo();
                final IOnBackInvokedCallback callback =
                        new OnInterceptBackInvokedCallback(currentActivity,
                                info != null ? info.getCallback() : null);
                callbackInfo = new OnBackInvokedCallbackInfo(callback, PRIORITY_DEFAULT, false,
                        OVERRIDE_UNDEFINED);
            } else {
                // Now let's find if this window has a callback from the client side.
                callbackInfo = window.getOnBackInvokedCallbackInfo();
            }
            final OnBackInvokedCallbackInfo callbackInfo = getOnBackInvokedCallbackInfo(
                    window, currentTask, currentActivity);
            if (callbackInfo == null) {
                Slog.e(TAG, "No callback registered, returning null.");
                return null;
@@ -541,6 +529,27 @@ class BackNavigationController {
        }
    }

    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
    @Nullable OnBackInvokedCallbackInfo getOnBackInvokedCallbackInfo(@NonNull WindowState window,
            @Nullable Task task, @Nullable ActivityRecord activity) {
        final OnBackInvokedCallbackInfo info = window.getOnBackInvokedCallbackInfo();
        if (activity == null || task == null) {
            return info;
        }

        final ActivityRecord root = task.getRootActivity(
                false /*ignoreRelinquishIdentity*/, true /*setToBottomIfNone*/);
        if (activity != root || !task.mAtmService.mTaskOrganizerController
                        .shouldInterceptBackPressedOnRootTask(task.getRootTask())) {
            return info;
        }

        final IOnBackInvokedCallback callback = new OnInterceptBackInvokedCallback(activity,
                info != null ? info.getCallback() : null);
        return new OnBackInvokedCallbackInfo(callback, PRIORITY_DEFAULT, false,
                    OVERRIDE_UNDEFINED);
    }

    /**
     * Gets previous activities from currentActivity.
     *
+52 −0
Original line number Diff line number Diff line
@@ -517,6 +517,58 @@ public class BackNavigationControllerTests extends WindowTestsBase {
        assertThat(backNavigationInfo.getOnBackInvokedCallback()).isEqualTo(callback);
    }

    @Test
    public void testGetOnBackInvokedCallbackInfo_interceptBackDisabled_returnsCallbackInfo() {
        final Task topTask = createTopTaskWithActivity();
        final WindowState window = topTask.getTopVisibleAppMainWindow();
        final ActivityRecord r = window.getActivityRecord();
        final OnBackInvokedCallbackInfo callbackInfo = mock(OnBackInvokedCallbackInfo.class);
        window.setOnBackInvokedCallbackInfo(callbackInfo);
        spyOn(mAtm.mTaskOrganizerController);
        Mockito.doReturn(false).when(mAtm.mTaskOrganizerController)
                .shouldInterceptBackPressedOnRootTask(eq(topTask));

        final OnBackInvokedCallbackInfo info =
                mBackNavigationController.getOnBackInvokedCallbackInfo(window, topTask, r);

        assertThat(info).isEqualTo(callbackInfo);
    }

    @Test
    public void testGetOnBackInvokedCallbackInfo_interceptBackRootActivity_returnsNewCallback() {
        final Task topTask = createTopTaskWithActivity();
        final WindowState window = topTask.getTopVisibleAppMainWindow();
        final ActivityRecord root = window.getActivityRecord();
        final OnBackInvokedCallbackInfo callbackInfo = mock(OnBackInvokedCallbackInfo.class);
        window.setOnBackInvokedCallbackInfo(callbackInfo);
        spyOn(mAtm.mTaskOrganizerController);
        Mockito.doReturn(true).when(mAtm.mTaskOrganizerController)
                .shouldInterceptBackPressedOnRootTask(eq(topTask));

        final OnBackInvokedCallbackInfo info =
                mBackNavigationController.getOnBackInvokedCallbackInfo(window, topTask, root);

        assertThat(info).isNotNull();
        assertThat(info).isNotEqualTo(callbackInfo);
    }

    @Test
    public void testGetOnBackInvokedCallbackInfo_interceptBackChildActivity_returnsCallbackInfo() {
        final Task topTask = createTopTaskWithActivity();
        final WindowState window = topTask.getTopVisibleAppMainWindow();
        final ActivityRecord child = createActivityRecord(topTask);
        final OnBackInvokedCallbackInfo callbackInfo = mock(OnBackInvokedCallbackInfo.class);
        window.setOnBackInvokedCallbackInfo(callbackInfo);
        spyOn(mAtm.mTaskOrganizerController);
        Mockito.doReturn(true).when(mAtm.mTaskOrganizerController)
                .shouldInterceptBackPressedOnRootTask(eq(topTask));

        final OnBackInvokedCallbackInfo info =
                mBackNavigationController.getOnBackInvokedCallbackInfo(window, topTask, child);

        assertThat(info).isEqualTo(callbackInfo);
    }

    @Test
    public void preparesForBackToHome() {
        final Task topTask = createTopTaskWithActivity();