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

Commit 0b463e53 authored by Louis Chang's avatar Louis Chang
Browse files

Intercept back for task root activity only

Bubble always collapses even when the bubble task contains multiple
activities.

Bug: 432384513
Test: swipe back when bubble expanded
Test: BackNavigationControllerTests
Flag: EXEMPT bugfix
Change-Id: Ibb50ae0443aeb84ca288602ae66a5b8658c5e81b
parent d0358660
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();