summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java40
-rw-r--r--packages/SystemUI/tests/AndroidManifest.xml3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java59
3 files changed, 101 insertions, 1 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
index ca65d12e87e6..da5819a7f3bc 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
@@ -90,6 +90,8 @@ import android.widget.ImageView.ScaleType;
import android.widget.LinearLayout;
import android.widget.ListPopupWindow;
import android.widget.TextView;
+import android.window.OnBackInvokedCallback;
+import android.window.OnBackInvokedDispatcher;
import androidx.annotation.NonNull;
import androidx.lifecycle.Lifecycle;
@@ -155,6 +157,8 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
public static final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions";
public static final String SYSTEM_DIALOG_REASON_DREAM = "dream";
+ private static final boolean DEBUG = false;
+
private static final String TAG = "GlobalActionsDialogLite";
private static final String INTERACTION_JANK_TAG = "global_actions";
@@ -2177,6 +2181,11 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
protected ViewGroup mContainer;
+ private final OnBackInvokedCallback mOnBackInvokedCallback = () -> {
+ logOnBackInvocation();
+ dismiss();
+ };
+
@VisibleForTesting
protected GestureDetector.SimpleOnGestureListener mGestureListener =
new GestureDetector.SimpleOnGestureListener() {
@@ -2221,6 +2230,16 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
}
};
+
+ // this exists so that we can point it to a mock during Unit Testing
+ private OnBackInvokedDispatcher mOverriddenBackDispatcher;
+
+ // the following method exists so that a Unit Test can supply a `OnBackInvokedDispatcher`
+ @VisibleForTesting
+ void setBackDispatcherOverride(OnBackInvokedDispatcher mockDispatcher) {
+ mOverriddenBackDispatcher = mockDispatcher;
+ }
+
ActionsDialogLite(Context context, int themeRes, MyAdapter adapter,
MyOverflowAdapter overflowAdapter,
SysuiColorExtractor sysuiColorExtractor, IStatusBarService statusBarService,
@@ -2254,6 +2273,22 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
super.onCreate(savedInstanceState);
initializeLayout();
mWindowDimAmount = getWindow().getAttributes().dimAmount;
+ getOnBackInvokedDispatcher().registerOnBackInvokedCallback(
+ OnBackInvokedDispatcher.PRIORITY_DEFAULT, mOnBackInvokedCallback);
+ if (DEBUG) Log.d(TAG, "OnBackInvokedCallback handler registered");
+ }
+
+ @VisibleForTesting
+ @Override
+ public OnBackInvokedDispatcher getOnBackInvokedDispatcher() {
+ if (mOverriddenBackDispatcher != null) return mOverriddenBackDispatcher;
+ else return super.getOnBackInvokedDispatcher();
+ }
+
+ @Override
+ public void onDetachedFromWindow() {
+ getOnBackInvokedDispatcher().unregisterOnBackInvokedCallback(mOnBackInvokedCallback);
+ if (DEBUG) Log.d(TAG, "OnBackInvokedCallback handler unregistered");
}
@Override
@@ -2453,7 +2488,12 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
@Override
public void onBackPressed() {
super.onBackPressed();
+ logOnBackInvocation();
+ }
+
+ private void logOnBackInvocation() {
mUiEventLogger.log(GlobalActionsEvent.GA_CLOSE_BACK);
+ if (DEBUG) Log.d(TAG, "onBack invoked");
}
@Override
diff --git a/packages/SystemUI/tests/AndroidManifest.xml b/packages/SystemUI/tests/AndroidManifest.xml
index 763a5cb810f9..ba2804572ef5 100644
--- a/packages/SystemUI/tests/AndroidManifest.xml
+++ b/packages/SystemUI/tests/AndroidManifest.xml
@@ -53,7 +53,8 @@
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.REGISTER_WINDOW_MANAGER_LISTENERS" />
- <application android:debuggable="true" android:largeHeap="true">
+ <application android:debuggable="true" android:largeHeap="true"
+ android:enableOnBackInvokedCallback="true" >
<uses-library android:name="android.test.runner" />
<receiver android:name="com.android.systemui.SliceBroadcastRelayHandlerTest$Receiver"
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 141a213a5b6a..b42b7695cedd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java
@@ -42,8 +42,11 @@ import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.GestureDetector;
import android.view.IWindowManager;
+import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.WindowManagerPolicyConstants;
+import android.window.OnBackInvokedCallback;
+import android.window.OnBackInvokedDispatcher;
import androidx.test.filters.SmallTest;
@@ -73,6 +76,8 @@ import com.android.systemui.util.settings.SecureSettings;
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;
@@ -117,6 +122,8 @@ public class GlobalActionsDialogLiteTest extends SysuiTestCase {
@Mock private CentralSurfaces mCentralSurfaces;
@Mock private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@Mock private DialogLaunchAnimator mDialogLaunchAnimator;
+ @Mock private OnBackInvokedDispatcher mOnBackInvokedDispatcher;
+ @Captor private ArgumentCaptor<OnBackInvokedCallback> mOnBackInvokedCallback;
private TestableLooper mTestableLooper;
@@ -203,6 +210,58 @@ public class GlobalActionsDialogLiteTest extends SysuiTestCase {
}
@Test
+ public void testPredictiveBackCallbackRegisteredAndUnregistered() {
+ mGlobalActionsDialogLite = spy(mGlobalActionsDialogLite);
+ doReturn(4).when(mGlobalActionsDialogLite).getMaxShownPowerItems();
+ doReturn(true).when(mGlobalActionsDialogLite).shouldDisplayLockdown(any());
+ doReturn(true).when(mGlobalActionsDialogLite).shouldShowAction(any());
+ String[] actions = {
+ GlobalActionsDialogLite.GLOBAL_ACTION_KEY_EMERGENCY,
+ GlobalActionsDialogLite.GLOBAL_ACTION_KEY_LOCKDOWN,
+ GlobalActionsDialogLite.GLOBAL_ACTION_KEY_POWER,
+ GlobalActionsDialogLite.GLOBAL_ACTION_KEY_RESTART,
+ };
+ doReturn(actions).when(mGlobalActionsDialogLite).getDefaultActions();
+
+ GlobalActionsDialogLite.ActionsDialogLite dialog = mGlobalActionsDialogLite.createDialog();
+ dialog.setBackDispatcherOverride(mOnBackInvokedDispatcher);
+ dialog.create();
+ mTestableLooper.processAllMessages();
+ verify(mOnBackInvokedDispatcher).registerOnBackInvokedCallback(
+ eq(OnBackInvokedDispatcher.PRIORITY_DEFAULT), any());
+ dialog.onDetachedFromWindow();
+ mTestableLooper.processAllMessages();
+ verify(mOnBackInvokedDispatcher).unregisterOnBackInvokedCallback(any());
+ }
+
+ @Test
+ public void testPredictiveBackInvocationDismissesDialog() {
+ mGlobalActionsDialogLite = spy(mGlobalActionsDialogLite);
+ doReturn(4).when(mGlobalActionsDialogLite).getMaxShownPowerItems();
+ doReturn(true).when(mGlobalActionsDialogLite).shouldDisplayLockdown(any());
+ doReturn(true).when(mGlobalActionsDialogLite).shouldShowAction(any());
+ String[] actions = {
+ GlobalActionsDialogLite.GLOBAL_ACTION_KEY_EMERGENCY,
+ GlobalActionsDialogLite.GLOBAL_ACTION_KEY_LOCKDOWN,
+ GlobalActionsDialogLite.GLOBAL_ACTION_KEY_POWER,
+ GlobalActionsDialogLite.GLOBAL_ACTION_KEY_RESTART,
+ };
+ doReturn(actions).when(mGlobalActionsDialogLite).getDefaultActions();
+
+ GlobalActionsDialogLite.ActionsDialogLite dialog = mGlobalActionsDialogLite.createDialog();
+ dialog.create();
+ dialog.show();
+ mTestableLooper.processAllMessages();
+ dialog.getWindow().injectInputEvent(
+ new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK));
+ dialog.getWindow().injectInputEvent(
+ new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK));
+ mTestableLooper.processAllMessages();
+ verifyLogPosted(GlobalActionsDialogLite.GlobalActionsEvent.GA_CLOSE_BACK);
+ assertThat(dialog.isShowing()).isFalse();
+ }
+
+ @Test
public void testSingleTap_logAndDismiss() {
mGlobalActionsDialogLite = spy(mGlobalActionsDialogLite);
doReturn(4).when(mGlobalActionsDialogLite).getMaxShownPowerItems();