Merge "Migrate GlobalActionsDialogLite to predictive back" into tm-qpr-dev am: d651e0b3ce
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/19669384 Change-Id: If976c82b6662360af426ef65f7234bd207df1e73 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -202,6 +209,58 @@ public class GlobalActionsDialogLiteTest extends SysuiTestCase {
|
||||
verifyLogPosted(GlobalActionsDialogLite.GlobalActionsEvent.GA_CLOSE_BACK);
|
||||
}
|
||||
|
||||
@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);
|
||||
|
||||
Reference in New Issue
Block a user