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.LinearLayout;
|
||||||
import android.widget.ListPopupWindow;
|
import android.widget.ListPopupWindow;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
import android.window.OnBackInvokedCallback;
|
||||||
|
import android.window.OnBackInvokedDispatcher;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.lifecycle.Lifecycle;
|
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_GLOBAL_ACTIONS = "globalactions";
|
||||||
public static final String SYSTEM_DIALOG_REASON_DREAM = "dream";
|
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 TAG = "GlobalActionsDialogLite";
|
||||||
|
|
||||||
private static final String INTERACTION_JANK_TAG = "global_actions";
|
private static final String INTERACTION_JANK_TAG = "global_actions";
|
||||||
@@ -2177,6 +2181,11 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
|
|||||||
|
|
||||||
protected ViewGroup mContainer;
|
protected ViewGroup mContainer;
|
||||||
|
|
||||||
|
private final OnBackInvokedCallback mOnBackInvokedCallback = () -> {
|
||||||
|
logOnBackInvocation();
|
||||||
|
dismiss();
|
||||||
|
};
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
protected GestureDetector.SimpleOnGestureListener mGestureListener =
|
protected GestureDetector.SimpleOnGestureListener mGestureListener =
|
||||||
new GestureDetector.SimpleOnGestureListener() {
|
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,
|
ActionsDialogLite(Context context, int themeRes, MyAdapter adapter,
|
||||||
MyOverflowAdapter overflowAdapter,
|
MyOverflowAdapter overflowAdapter,
|
||||||
SysuiColorExtractor sysuiColorExtractor, IStatusBarService statusBarService,
|
SysuiColorExtractor sysuiColorExtractor, IStatusBarService statusBarService,
|
||||||
@@ -2254,6 +2273,22 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
|
|||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
initializeLayout();
|
initializeLayout();
|
||||||
mWindowDimAmount = getWindow().getAttributes().dimAmount;
|
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
|
@Override
|
||||||
@@ -2453,7 +2488,12 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
|
|||||||
@Override
|
@Override
|
||||||
public void onBackPressed() {
|
public void onBackPressed() {
|
||||||
super.onBackPressed();
|
super.onBackPressed();
|
||||||
|
logOnBackInvocation();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void logOnBackInvocation() {
|
||||||
mUiEventLogger.log(GlobalActionsEvent.GA_CLOSE_BACK);
|
mUiEventLogger.log(GlobalActionsEvent.GA_CLOSE_BACK);
|
||||||
|
if (DEBUG) Log.d(TAG, "onBack invoked");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -53,7 +53,8 @@
|
|||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||||
<uses-permission android:name="android.permission.REGISTER_WINDOW_MANAGER_LISTENERS" />
|
<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" />
|
<uses-library android:name="android.test.runner" />
|
||||||
|
|
||||||
<receiver android:name="com.android.systemui.SliceBroadcastRelayHandlerTest$Receiver"
|
<receiver android:name="com.android.systemui.SliceBroadcastRelayHandlerTest$Receiver"
|
||||||
|
|||||||
@@ -42,8 +42,11 @@ import android.testing.AndroidTestingRunner;
|
|||||||
import android.testing.TestableLooper;
|
import android.testing.TestableLooper;
|
||||||
import android.view.GestureDetector;
|
import android.view.GestureDetector;
|
||||||
import android.view.IWindowManager;
|
import android.view.IWindowManager;
|
||||||
|
import android.view.KeyEvent;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.WindowManagerPolicyConstants;
|
import android.view.WindowManagerPolicyConstants;
|
||||||
|
import android.window.OnBackInvokedCallback;
|
||||||
|
import android.window.OnBackInvokedDispatcher;
|
||||||
|
|
||||||
import androidx.test.filters.SmallTest;
|
import androidx.test.filters.SmallTest;
|
||||||
|
|
||||||
@@ -73,6 +76,8 @@ import com.android.systemui.util.settings.SecureSettings;
|
|||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import org.mockito.Captor;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
@@ -117,6 +122,8 @@ public class GlobalActionsDialogLiteTest extends SysuiTestCase {
|
|||||||
@Mock private CentralSurfaces mCentralSurfaces;
|
@Mock private CentralSurfaces mCentralSurfaces;
|
||||||
@Mock private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
@Mock private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
||||||
@Mock private DialogLaunchAnimator mDialogLaunchAnimator;
|
@Mock private DialogLaunchAnimator mDialogLaunchAnimator;
|
||||||
|
@Mock private OnBackInvokedDispatcher mOnBackInvokedDispatcher;
|
||||||
|
@Captor private ArgumentCaptor<OnBackInvokedCallback> mOnBackInvokedCallback;
|
||||||
|
|
||||||
private TestableLooper mTestableLooper;
|
private TestableLooper mTestableLooper;
|
||||||
|
|
||||||
@@ -202,6 +209,58 @@ public class GlobalActionsDialogLiteTest extends SysuiTestCase {
|
|||||||
verifyLogPosted(GlobalActionsDialogLite.GlobalActionsEvent.GA_CLOSE_BACK);
|
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
|
@Test
|
||||||
public void testSingleTap_logAndDismiss() {
|
public void testSingleTap_logAndDismiss() {
|
||||||
mGlobalActionsDialogLite = spy(mGlobalActionsDialogLite);
|
mGlobalActionsDialogLite = spy(mGlobalActionsDialogLite);
|
||||||
|
|||||||
Reference in New Issue
Block a user