diff options
author | Beth Thibodeau <ethibodeau@google.com> | 2021-06-16 15:42:18 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2021-06-16 15:42:18 +0000 |
commit | 6962b10349b8949960d781be61c6f2024fa26d82 (patch) | |
tree | 86929611be7afa230e749bf49e01dc9688c003d0 | |
parent | 1090459a0e17ac181ee4b4336f697b39a45712d2 (diff) | |
parent | 66bf99808573feeedc87e73ee0bf60285c8234a9 (diff) |
Merge "[DO NOT MERGE] Open QS when swiping from status bar in power menu" into sc-dev
4 files changed, 152 insertions, 17 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java index dfd85fe4dc90..1fb36d7fbd3b 100644 --- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java +++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java @@ -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, @@ -152,7 +154,7 @@ public class GlobalActionsDialog extends GlobalActionsDialogLite backgroundExecutor, uiEventLogger, null, - ringerModeTracker, sysUiState, handler); + ringerModeTracker, sysUiState, handler, statusBar); mLockPatternUtils = lockPatternUtils; mKeyguardStateController = keyguardStateController; @@ -227,7 +229,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(); @@ -295,11 +298,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, null); + onRotateCallback, keyguardShowing, powerAdapter, uiEventLogger, null, + statusBar); mWalletFactory = walletFactory; // Update window attributes diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java index 8e152830e208..ad920cbc0192 100644 --- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java +++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java @@ -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; @@ -228,6 +231,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 { @@ -322,7 +326,8 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene @Background Executor backgroundExecutor, UiEventLogger uiEventLogger, GlobalActionsInfoProvider infoProvider, - RingerModeTracker ringerModeTracker, SysUiState sysUiState, @Main Handler handler) { + RingerModeTracker ringerModeTracker, SysUiState sysUiState, @Main Handler handler, + StatusBar statusBar) { mContext = context; mWindowManagerFuncs = windowManagerFuncs; mAudioManager = audioManager; @@ -352,6 +357,7 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene mSysUiState = sysUiState; mMainHandler = handler; mSmallestScreenWidthDp = mContext.getResources().getConfiguration().smallestScreenWidthDp; + mStatusBar = statusBar; // receive broadcasts IntentFilter filter = new IntentFilter(); @@ -392,6 +398,10 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene return mUiEventLogger; } + protected StatusBar getStatusBar() { + return mStatusBar; + } + /** * Show the global actions dialog (creating if necessary) * @@ -625,7 +635,7 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene mDepthController, mSysuiColorExtractor, mStatusBarService, mNotificationShadeWindowController, mSysUiState, this::onRotate, mKeyguardShowing, mPowerAdapter, mUiEventLogger, - mInfoProvider); + mInfoProvider, mStatusBar); dialog.setOnDismissListener(this); dialog.setOnShowListener(this); @@ -2100,9 +2110,53 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene protected final Runnable mOnRotateCallback; private UiEventLogger mUiEventLogger; private GlobalActionsInfoProvider mInfoProvider; + 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, @@ -2110,7 +2164,7 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene NotificationShadeWindowController notificationShadeWindowController, SysUiState sysuiState, Runnable onRotateCallback, boolean keyguardShowing, MyPowerOptionsAdapter powerAdapter, UiEventLogger uiEventLogger, - @Nullable GlobalActionsInfoProvider infoProvider) { + @Nullable GlobalActionsInfoProvider infoProvider, StatusBar statusBar) { super(context, themeRes); mContext = context; mAdapter = adapter; @@ -2125,6 +2179,9 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene mKeyguardShowing = keyguardShowing; mUiEventLogger = uiEventLogger; mInfoProvider = infoProvider; + mStatusBar = statusBar; + + mGestureDetector = new GestureDetector(mContext, mGestureListener); // Window initialization Window window = getWindow(); @@ -2146,6 +2203,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( @@ -2194,9 +2268,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( diff --git a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java index 83e7b17eb746..f0f5420b2531 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java @@ -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; @@ -109,6 +111,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; @@ -150,7 +153,8 @@ public class GlobalActionsDialogLiteTest extends SysuiTestCase { mInfoProvider, mRingerModeTracker, mSysUiState, - mHandler + mHandler, + mStatusBar ); mGlobalActionsDialogLite.setZeroDialogPressDelayForTesting(); @@ -194,7 +198,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()); @@ -207,9 +211,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 diff --git a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java index 3130e977dc83..c54347063487 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java @@ -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(); |