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

Commit 6a129229 authored by Beth Thibodeau's avatar Beth Thibodeau Committed by Android (Google) Code Review
Browse files

Merge "Open QS when swiping from status bar in power menu" into sc-v2-dev

parents 4d6457de c3b9dc3f
Loading
Loading
Loading
Loading
+10 −5
Original line number Diff line number Diff line
@@ -72,6 +72,7 @@ import com.android.systemui.plugins.GlobalActions.GlobalActionsManager;
import com.android.systemui.plugins.GlobalActionsPanelPlugin;
import com.android.systemui.statusbar.NotificationShadeDepthController;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.telephony.TelephonyListenerManager;
@@ -133,7 +134,8 @@ public class GlobalActionsDialog extends GlobalActionsDialogLite
            IWindowManager iWindowManager,
            @Background Executor backgroundExecutor,
            UiEventLogger uiEventLogger,
            RingerModeTracker ringerModeTracker, SysUiState sysUiState, @Main Handler handler) {
            RingerModeTracker ringerModeTracker, SysUiState sysUiState, @Main Handler handler,
            StatusBar statusBar) {

        super(context, windowManagerFuncs,
                audioManager, iDreamManager,
@@ -151,7 +153,7 @@ public class GlobalActionsDialog extends GlobalActionsDialogLite
                iWindowManager,
                backgroundExecutor,
                uiEventLogger,
                ringerModeTracker, sysUiState, handler);
                ringerModeTracker, sysUiState, handler, statusBar);

        mLockPatternUtils = lockPatternUtils;
        mKeyguardStateController = keyguardStateController;
@@ -226,7 +228,8 @@ public class GlobalActionsDialog extends GlobalActionsDialogLite
        ActionsDialog dialog = new ActionsDialog(getContext(), mAdapter, mOverflowAdapter,
                this::getWalletViewController, mDepthController, mSysuiColorExtractor,
                mStatusBarService, mNotificationShadeWindowController,
                mSysUiState, this::onRotate, isKeyguardShowing(), mPowerAdapter, getEventLogger());
                mSysUiState, this::onRotate, isKeyguardShowing(), mPowerAdapter, getEventLogger(),
                getStatusBar());

        if (shouldShowLockMessage(dialog)) {
            dialog.showLockMessage();
@@ -294,11 +297,13 @@ public class GlobalActionsDialog extends GlobalActionsDialogLite
                SysuiColorExtractor sysuiColorExtractor, IStatusBarService statusBarService,
                NotificationShadeWindowController notificationShadeWindowController,
                SysUiState sysuiState, Runnable onRotateCallback, boolean keyguardShowing,
                MyPowerOptionsAdapter powerAdapter, UiEventLogger uiEventLogger) {
                MyPowerOptionsAdapter powerAdapter, UiEventLogger uiEventLogger,
                StatusBar statusBar) {
            super(context, com.android.systemui.R.style.Theme_SystemUI_Dialog_GlobalActions,
                    adapter, overflowAdapter, depthController, sysuiColorExtractor,
                    statusBarService, notificationShadeWindowController, sysuiState,
                    onRotateCallback, keyguardShowing, powerAdapter, uiEventLogger);
                    onRotateCallback, keyguardShowing, powerAdapter, uiEventLogger,
                    statusBar);
            mWalletFactory = walletFactory;

            // Update window attributes
+82 −6
Original line number Diff line number Diff line
@@ -74,8 +74,10 @@ import android.telephony.TelephonyManager;
import android.util.ArraySet;
import android.util.Log;
import android.view.ContextThemeWrapper;
import android.view.GestureDetector;
import android.view.IWindowManager;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
@@ -119,6 +121,7 @@ import com.android.systemui.plugins.GlobalActionsPanelPlugin;
import com.android.systemui.scrim.ScrimDrawable;
import com.android.systemui.statusbar.NotificationShadeDepthController;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.telephony.TelephonyListenerManager;
@@ -227,6 +230,7 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
    private int mDialogPressDelay = DIALOG_PRESS_DELAY; // ms
    protected Handler mMainHandler;
    private int mSmallestScreenWidthDp;
    private final StatusBar mStatusBar;

    @VisibleForTesting
    public enum GlobalActionsEvent implements UiEventLogger.UiEventEnum {
@@ -320,7 +324,8 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
            IWindowManager iWindowManager,
            @Background Executor backgroundExecutor,
            UiEventLogger uiEventLogger,
            RingerModeTracker ringerModeTracker, SysUiState sysUiState, @Main Handler handler) {
            RingerModeTracker ringerModeTracker, SysUiState sysUiState, @Main Handler handler,
            StatusBar statusBar) {
        mContext = context;
        mWindowManagerFuncs = windowManagerFuncs;
        mAudioManager = audioManager;
@@ -349,6 +354,7 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
        mSysUiState = sysUiState;
        mMainHandler = handler;
        mSmallestScreenWidthDp = mContext.getResources().getConfiguration().smallestScreenWidthDp;
        mStatusBar = statusBar;

        // receive broadcasts
        IntentFilter filter = new IntentFilter();
@@ -389,6 +395,10 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
        return mUiEventLogger;
    }

    protected StatusBar getStatusBar() {
        return mStatusBar;
    }

    /**
     * Show the global actions dialog (creating if necessary)
     *
@@ -621,7 +631,8 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
                mAdapter, mOverflowAdapter,
                mDepthController, mSysuiColorExtractor,
                mStatusBarService, mNotificationShadeWindowController,
                mSysUiState, this::onRotate, mKeyguardShowing, mPowerAdapter, mUiEventLogger);
                mSysUiState, this::onRotate, mKeyguardShowing, mPowerAdapter, mUiEventLogger,
                mStatusBar);

        dialog.setOnDismissListener(this);
        dialog.setOnShowListener(this);
@@ -2095,16 +2106,61 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
        private Dialog mPowerOptionsDialog;
        protected final Runnable mOnRotateCallback;
        private UiEventLogger mUiEventLogger;
        private GestureDetector mGestureDetector;
        private StatusBar mStatusBar;

        protected ViewGroup mContainer;

        @VisibleForTesting
        protected GestureDetector.SimpleOnGestureListener mGestureListener =
                new GestureDetector.SimpleOnGestureListener() {
                    @Override
                    public boolean onDown(MotionEvent e) {
                        // All gestures begin with this message, so continue listening
                        return true;
                    }

                    @Override
                    public boolean onSingleTapConfirmed(MotionEvent e) {
                        // Close without opening shade
                        mUiEventLogger.log(GlobalActionsEvent.GA_CLOSE_TAP_OUTSIDE);
                        cancel();
                        return false;
                    }

                    @Override
                    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
                            float distanceY) {
                        if (distanceY < 0 && distanceY > distanceX
                                && e1.getY() <= mStatusBar.getStatusBarHeight()) {
                            // Downwards scroll from top
                            openShadeAndDismiss();
                            return true;
                        }
                        return false;
                    }

                    @Override
                    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                            float velocityY) {
                        if (velocityY > 0 && Math.abs(velocityY) > Math.abs(velocityX)
                                && e1.getY() <= mStatusBar.getStatusBarHeight()) {
                            // Downwards fling from top
                            openShadeAndDismiss();
                            return true;
                        }
                        return false;
                    }
                };

        ActionsDialogLite(Context context, int themeRes, MyAdapter adapter,
                MyOverflowAdapter overflowAdapter,
                NotificationShadeDepthController depthController,
                SysuiColorExtractor sysuiColorExtractor, IStatusBarService statusBarService,
                NotificationShadeWindowController notificationShadeWindowController,
                SysUiState sysuiState, Runnable onRotateCallback, boolean keyguardShowing,
                MyPowerOptionsAdapter powerAdapter, UiEventLogger uiEventLogger) {
                MyPowerOptionsAdapter powerAdapter, UiEventLogger uiEventLogger,
                StatusBar statusBar) {
            super(context, themeRes);
            mContext = context;
            mAdapter = adapter;
@@ -2118,6 +2174,9 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
            mOnRotateCallback = onRotateCallback;
            mKeyguardShowing = keyguardShowing;
            mUiEventLogger = uiEventLogger;
            mStatusBar = statusBar;

            mGestureDetector = new GestureDetector(mContext, mGestureListener);

            // Window initialization
            Window window = getWindow();
@@ -2139,6 +2198,23 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
            initializeLayout();
        }

        @Override
        public boolean onTouchEvent(MotionEvent event) {
            return mGestureDetector.onTouchEvent(event) || super.onTouchEvent(event);
        }

        private void openShadeAndDismiss() {
            mUiEventLogger.log(GlobalActionsEvent.GA_CLOSE_TAP_OUTSIDE);
            if (mStatusBar.isKeyguardShowing()) {
                // match existing lockscreen behavior to open QS when swiping from status bar
                mStatusBar.animateExpandSettingsPanel(null);
            } else {
                // otherwise, swiping down should expand notification shade
                mStatusBar.animateExpandNotificationsPanel();
            }
            dismiss();
        }

        private ListPopupWindow createPowerOverflowPopup() {
            GlobalActionsPopupMenu popup = new GlobalActionsPopupMenu(
                    new ContextThemeWrapper(
@@ -2187,9 +2263,9 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
            mGlobalActionsLayout.setRotationListener(this::onRotate);
            mGlobalActionsLayout.setAdapter(mAdapter);
            mContainer = findViewById(com.android.systemui.R.id.global_actions_container);
            mContainer.setOnClickListener(v -> {
                mUiEventLogger.log(GlobalActionsEvent.GA_CLOSE_TAP_OUTSIDE);
                cancel();
            mContainer.setOnTouchListener((v, event) -> {
                mGestureDetector.onTouchEvent(event);
                return v.onTouchEvent(event);
            });

            View overflowButton = findViewById(
+58 −5
Original line number Diff line number Diff line
@@ -38,8 +38,9 @@ import android.os.UserManager;
import android.service.dreams.IDreamManager;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.GestureDetector;
import android.view.IWindowManager;
import android.view.View;
import android.view.MotionEvent;
import android.view.WindowManagerPolicyConstants;

import androidx.test.filters.SmallTest;
@@ -57,6 +58,7 @@ import com.android.systemui.plugins.GlobalActions;
import com.android.systemui.settings.UserContextProvider;
import com.android.systemui.statusbar.NotificationShadeDepthController;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.telephony.TelephonyListenerManager;
@@ -108,6 +110,7 @@ public class GlobalActionsDialogLiteTest extends SysuiTestCase {
    @Mock private SysUiState mSysUiState;
    @Mock private Handler mHandler;
    @Mock private UserContextProvider mUserContextProvider;
    @Mock private StatusBar mStatusBar;

    private TestableLooper mTestableLooper;

@@ -148,7 +151,8 @@ public class GlobalActionsDialogLiteTest extends SysuiTestCase {
                mUiEventLogger,
                mRingerModeTracker,
                mSysUiState,
                mHandler
                mHandler,
                mStatusBar
        );
        mGlobalActionsDialogLite.setZeroDialogPressDelayForTesting();

@@ -192,7 +196,7 @@ public class GlobalActionsDialogLiteTest extends SysuiTestCase {
    }

    @Test
    public void testShouldLogOnTapOutside() {
    public void testSingleTap_logAndDismiss() {
        mGlobalActionsDialogLite = spy(mGlobalActionsDialogLite);
        doReturn(4).when(mGlobalActionsDialogLite).getMaxShownPowerItems();
        doReturn(true).when(mGlobalActionsDialogLite).shouldDisplayLockdown(any());
@@ -205,9 +209,58 @@ public class GlobalActionsDialogLiteTest extends SysuiTestCase {
        };
        doReturn(actions).when(mGlobalActionsDialogLite).getDefaultActions();
        GlobalActionsDialogLite.ActionsDialogLite dialog = mGlobalActionsDialogLite.createDialog();
        View container = dialog.findViewById(com.android.systemui.R.id.global_actions_container);
        container.callOnClick();

        GestureDetector.SimpleOnGestureListener gestureListener = spy(dialog.mGestureListener);
        gestureListener.onSingleTapConfirmed(null);
        verifyLogPosted(GlobalActionsDialog.GlobalActionsEvent.GA_CLOSE_TAP_OUTSIDE);
    }

    @Test
    public void testSwipeDownLockscreen_logAndOpenQS() {
        mGlobalActionsDialogLite = spy(mGlobalActionsDialogLite);
        doReturn(4).when(mGlobalActionsDialogLite).getMaxShownPowerItems();
        doReturn(true).when(mGlobalActionsDialogLite).shouldDisplayLockdown(any());
        doReturn(true).when(mGlobalActionsDialogLite).shouldShowAction(any());
        doReturn(true).when(mStatusBar).isKeyguardShowing();
        String[] actions = {
                GlobalActionsDialog.GLOBAL_ACTION_KEY_EMERGENCY,
                GlobalActionsDialog.GLOBAL_ACTION_KEY_LOCKDOWN,
                GlobalActionsDialog.GLOBAL_ACTION_KEY_POWER,
                GlobalActionsDialog.GLOBAL_ACTION_KEY_RESTART,
        };
        doReturn(actions).when(mGlobalActionsDialogLite).getDefaultActions();
        GlobalActionsDialogLite.ActionsDialogLite dialog = mGlobalActionsDialogLite.createDialog();

        GestureDetector.SimpleOnGestureListener gestureListener = spy(dialog.mGestureListener);
        MotionEvent start = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0);
        MotionEvent end = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 500, 0);
        gestureListener.onFling(start, end, 0, 1000);
        verifyLogPosted(GlobalActionsDialog.GlobalActionsEvent.GA_CLOSE_TAP_OUTSIDE);
        verify(mStatusBar).animateExpandSettingsPanel(null);
    }

    @Test
    public void testSwipeDown_logAndOpenNotificationShade() {
        mGlobalActionsDialogLite = spy(mGlobalActionsDialogLite);
        doReturn(4).when(mGlobalActionsDialogLite).getMaxShownPowerItems();
        doReturn(true).when(mGlobalActionsDialogLite).shouldDisplayLockdown(any());
        doReturn(true).when(mGlobalActionsDialogLite).shouldShowAction(any());
        doReturn(false).when(mStatusBar).isKeyguardShowing();
        String[] actions = {
                GlobalActionsDialog.GLOBAL_ACTION_KEY_EMERGENCY,
                GlobalActionsDialog.GLOBAL_ACTION_KEY_LOCKDOWN,
                GlobalActionsDialog.GLOBAL_ACTION_KEY_POWER,
                GlobalActionsDialog.GLOBAL_ACTION_KEY_RESTART,
        };
        doReturn(actions).when(mGlobalActionsDialogLite).getDefaultActions();
        GlobalActionsDialogLite.ActionsDialogLite dialog = mGlobalActionsDialogLite.createDialog();

        GestureDetector.SimpleOnGestureListener gestureListener = spy(dialog.mGestureListener);
        MotionEvent start = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0);
        MotionEvent end = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 500, 0);
        gestureListener.onFling(start, end, 0, 1000);
        verifyLogPosted(GlobalActionsDialog.GlobalActionsEvent.GA_CLOSE_TAP_OUTSIDE);
        verify(mStatusBar).animateExpandNotificationsPanel();
    }

    @Test
+4 −1
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ import com.android.systemui.plugins.GlobalActionsPanelPlugin;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.NotificationShadeDepthController;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.telephony.TelephonyListenerManager;
@@ -124,6 +125,7 @@ public class GlobalActionsDialogTest extends SysuiTestCase {
    @Mock private Handler mHandler;
    @Mock private UserTracker mUserTracker;
    @Mock private SecureSettings mSecureSettings;
    @Mock private StatusBar mStatusBar;

    private TestableLooper mTestableLooper;

@@ -164,7 +166,8 @@ public class GlobalActionsDialogTest extends SysuiTestCase {
                mUiEventLogger,
                mRingerModeTracker,
                mSysUiState,
                mHandler
                mHandler,
                mStatusBar
        );
        mGlobalActionsDialog.setZeroDialogPressDelayForTesting();