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

Commit 2d622277 authored by Rahul Banerjee's avatar Rahul Banerjee Committed by Android (Google) Code Review
Browse files

Merge "Migrate CentralSurfacesImpl to Predictive Back api" into tm-qpr-dev

parents cd32f20a a3147f13
Loading
Loading
Loading
Loading
+58 −1
Original line number Diff line number Diff line
@@ -100,11 +100,14 @@ import android.view.MotionEvent;
import android.view.ThreadedRenderer;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewRootImpl;
import android.view.WindowInsetsController.Appearance;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
import android.view.accessibility.AccessibilityManager;
import android.widget.DateTimeView;
import android.window.OnBackInvokedCallback;
import android.window.OnBackInvokedDispatcher;

import androidx.annotation.NonNull;
import androidx.lifecycle.Lifecycle;
@@ -526,10 +529,17 @@ public class CentralSurfacesImpl extends CoreStartable implements
    private CentralSurfacesComponent mCentralSurfacesComponent;

    // Flags for disabling the status bar
    // Two variables becaseu the first one evidently ran out of room for new flags.
    // Two variables because the first one evidently ran out of room for new flags.
    private int mDisabled1 = 0;
    private int mDisabled2 = 0;

    /**
     * This keeps track of whether we have (or haven't) registered the predictive back callback.
     * Since we can have visible -> visible transitions, we need to avoid
     * double-registering (or double-unregistering) our callback.
     */
    private boolean mIsBackCallbackRegistered = false;

    /** @see android.view.WindowInsetsController#setSystemBarsAppearance(int, int) */
    private @Appearance int mAppearance;

@@ -653,6 +663,12 @@ public class CentralSurfacesImpl extends CoreStartable implements

    private final InteractionJankMonitor mJankMonitor;

    private final OnBackInvokedCallback mOnBackInvokedCallback = () -> {
        if (DEBUG) {
            Log.d(TAG, "mOnBackInvokedCallback() called");
        }
        onBackPressed();
    };

    /**
     * Public constructor for CentralSurfaces.
@@ -2751,9 +2767,38 @@ public class CentralSurfacesImpl extends CoreStartable implements
        if (visibleToUser) {
            handleVisibleToUserChangedImpl(visibleToUser);
            mNotificationLogger.startNotificationLogging();

            if (!mIsBackCallbackRegistered) {
                ViewRootImpl viewRootImpl = getViewRootImpl();
                if (viewRootImpl != null) {
                    viewRootImpl.getOnBackInvokedDispatcher()
                            .registerOnBackInvokedCallback(OnBackInvokedDispatcher.PRIORITY_DEFAULT,
                                    mOnBackInvokedCallback);
                    mIsBackCallbackRegistered = true;
                    if (DEBUG) Log.d(TAG, "is now VISIBLE to user AND callback registered");
                }
            } else {
                if (DEBUG) Log.d(TAG, "is now VISIBLE to user, BUT callback ALREADY unregistered");
            }
        } else {
            mNotificationLogger.stopNotificationLogging();
            handleVisibleToUserChangedImpl(visibleToUser);

            if (mIsBackCallbackRegistered) {
                ViewRootImpl viewRootImpl = getViewRootImpl();
                if (viewRootImpl != null) {
                    viewRootImpl.getOnBackInvokedDispatcher()
                            .unregisterOnBackInvokedCallback(mOnBackInvokedCallback);
                    mIsBackCallbackRegistered = false;
                    if (DEBUG) Log.d(TAG, "is NOT VISIBLE to user, AND callback unregistered");
                }
            } else {
                if (DEBUG) {
                    Log.d(TAG,
                            "is NOT VISIBLE to user, BUT NO callback (or callback ALREADY "
                                    + "unregistered)");
                }
            }
        }
    }

@@ -3464,6 +3509,12 @@ public class CentralSurfacesImpl extends CoreStartable implements
        return mNotificationPanelViewController.getKeyguardBottomAreaView();
    }

    protected ViewRootImpl getViewRootImpl()  {
        NotificationShadeWindowView nswv = getNotificationShadeWindowView();
        if (nswv != null) return nswv.getViewRootImpl();

        return null;
    }
    /**
     * Propagation of the bouncer state, indicating that it's fully visible.
     */
@@ -3781,6 +3832,12 @@ public class CentralSurfacesImpl extends CoreStartable implements
        updateScrimController();
    }

    @VisibleForTesting
    public void setNotificationShadeWindowViewController(
            NotificationShadeWindowViewController nswvc) {
        mNotificationShadeWindowViewController = nswvc;
    }

    /**
     * Set the amount of progress we are currently in if we're transitioning to the full shade.
     * 0.0f means we're not transitioning yet, while 1 means we're all the way in the full
+62 −3
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -69,7 +70,11 @@ import android.util.DisplayMetrics;
import android.util.SparseArray;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewRootImpl;
import android.view.WindowManager;
import android.window.OnBackInvokedCallback;
import android.window.OnBackInvokedDispatcher;
import android.window.WindowOnBackInvokedDispatcher;

import androidx.test.filters.SmallTest;

@@ -168,6 +173,7 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

@@ -279,6 +285,15 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
    @Mock private InteractionJankMonitor mJankMonitor;
    @Mock private DeviceStateManager mDeviceStateManager;
    @Mock private WiredChargingRippleController mWiredChargingRippleController;
    /**
     * The process of registering/unregistering a predictive back callback requires a
     * ViewRootImpl, which is present IRL, but may be missing during a Mockito unit test.
     * To prevent an NPE during test execution, we explicitly craft and provide a fake ViewRootImpl.
     */
    @Mock private ViewRootImpl mViewRootImpl;
    @Mock private WindowOnBackInvokedDispatcher mOnBackInvokedDispatcher;
    @Captor private ArgumentCaptor<OnBackInvokedCallback> mOnBackInvokedCallback;

    private ShadeController mShadeController;
    private final FakeSystemClock mFakeSystemClock = new FakeSystemClock();
    private FakeExecutor mMainExecutor = new FakeExecutor(mFakeSystemClock);
@@ -368,10 +383,10 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
            return null;
        }).when(mNotificationShadeWindowController).batchApplyWindowLayoutParams(any());

        mShadeController = new ShadeControllerImpl(mCommandQueue,
        mShadeController = spy(new ShadeControllerImpl(mCommandQueue,
                mStatusBarStateController, mNotificationShadeWindowController,
                mStatusBarKeyguardViewManager, mContext.getSystemService(WindowManager.class),
                () -> Optional.of(mCentralSurfaces), () -> mAssistManager);
                () -> Optional.of(mCentralSurfaces), () -> mAssistManager));

        when(mOperatorNameViewControllerFactory.create(any()))
                .thenReturn(mOperatorNameViewController);
@@ -460,7 +475,14 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
                mActivityLaunchAnimator,
                mJankMonitor,
                mDeviceStateManager,
                mWiredChargingRippleController, mDreamManager);
                mWiredChargingRippleController, mDreamManager) {
            @Override
            protected ViewRootImpl getViewRootImpl() {
                return mViewRootImpl;
            }
        };
        when(mViewRootImpl.getOnBackInvokedDispatcher())
                .thenReturn(mOnBackInvokedDispatcher);
        when(mKeyguardViewMediator.registerCentralSurfaces(
                any(CentralSurfacesImpl.class),
                any(NotificationPanelViewController.class),
@@ -738,6 +760,43 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
        }
    }

    /**
     * Do the following:
     * 1. verify that a predictive back callback is registered when CSurf becomes visible
     * 2. verify that the same callback is unregistered when CSurf becomes invisible
     */
    @Test
    public void testPredictiveBackCallback_registration() {
        mCentralSurfaces.handleVisibleToUserChanged(true);
        verify(mOnBackInvokedDispatcher).registerOnBackInvokedCallback(
                eq(OnBackInvokedDispatcher.PRIORITY_DEFAULT),
                mOnBackInvokedCallback.capture());

        mCentralSurfaces.handleVisibleToUserChanged(false);
        verify(mOnBackInvokedDispatcher).unregisterOnBackInvokedCallback(
                eq(mOnBackInvokedCallback.getValue()));
    }

    /**
     * Do the following:
     * 1. capture the predictive back callback during registration
     * 2. call the callback directly
     * 3. verify that the ShadeController's panel collapse animation is invoked
     */
    @Test
    public void testPredictiveBackCallback_invocationCollapsesPanel() {
        mCentralSurfaces.setNotificationShadeWindowViewController(
                mNotificationShadeWindowViewController);
        mCentralSurfaces.handleVisibleToUserChanged(true);
        verify(mOnBackInvokedDispatcher).registerOnBackInvokedCallback(
                eq(OnBackInvokedDispatcher.PRIORITY_DEFAULT),
                mOnBackInvokedCallback.capture());

        when(mNotificationPanelViewController.canPanelBeCollapsed()).thenReturn(true);
        mOnBackInvokedCallback.getValue().onBackInvoked();
        verify(mShadeController).animateCollapsePanels();
    }

    @Test
    public void testPanelOpenForHeadsUp() {
        when(mDeviceProvisionedController.isDeviceProvisioned()).thenReturn(true);