diff options
5 files changed, 80 insertions, 26 deletions
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index b4919a4fb9ff..db18276b1124 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -76,6 +76,7 @@ import static android.view.WindowManagerGlobal.ADD_PERMISSION_DENIED; import static android.view.contentprotection.flags.Flags.createAccessibilityOverlayAppOpEnabled; import static com.android.hardware.input.Flags.emojiAndScreenshotKeycodesAvailable; +import static com.android.server.flags.Flags.newBugreportKeyboardShortcut; import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.SCREENSHOT_KEYCHORD_DELAY; import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_COVERED; import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_COVER_ABSENT; @@ -466,8 +467,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { // Assigned on main thread, accessed on UI thread volatile VrManagerInternal mVrManagerInternal; - /** If true, hitting shift & menu will broadcast Intent.ACTION_BUG_REPORT */ - boolean mEnableShiftMenuBugReports = false; + /** If true, can use a keyboard shortcut to trigger a bugreport. */ + boolean mEnableBugReportKeyboardShortcut = false; /** Controller that supports enabling an AccessibilityService by holding down the volume keys */ private AccessibilityShortcutController mAccessibilityShortcutController; @@ -2303,7 +2304,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { "PhoneWindowManager.mBroadcastWakeLock"); mPowerKeyWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "PhoneWindowManager.mPowerKeyWakeLock"); - mEnableShiftMenuBugReports = "1".equals(SystemProperties.get("ro.debuggable")); + mEnableBugReportKeyboardShortcut = "1".equals(SystemProperties.get("ro.debuggable")); mLidKeyboardAccessibility = mContext.getResources().getInteger( com.android.internal.R.integer.config_lidKeyboardAccessibility); mLidNavigationAccessibility = mContext.getResources().getInteger( @@ -2360,8 +2361,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { mDisplayFoldController = DisplayFoldController.create(mContext, DEFAULT_DISPLAY); - mAccessibilityManager = (AccessibilityManager) mContext.getSystemService( - Context.ACCESSIBILITY_SERVICE); + mAccessibilityManager = mContext.getSystemService(AccessibilityManager.class); // register for dock events IntentFilter filter = new IntentFilter(); @@ -3409,19 +3409,6 @@ public class PhoneWindowManager implements WindowManagerPolicy { switch (keyCode) { case KeyEvent.KEYCODE_HOME: return handleHomeShortcuts(focusedToken, event); - case KeyEvent.KEYCODE_MENU: - // Hijack modified menu keys for debugging features - final int chordBug = KeyEvent.META_SHIFT_ON; - - if (mEnableShiftMenuBugReports && firstDown - && (metaState & chordBug) == chordBug) { - Intent intent = new Intent(Intent.ACTION_BUG_REPORT); - mContext.sendOrderedBroadcastAsUser(intent, UserHandle.CURRENT, - null, null, null, 0, null, null); - logKeyboardSystemsEvent(event, KeyboardLogEvent.TRIGGER_BUG_REPORT); - return true; - } - break; case KeyEvent.KEYCODE_RECENT_APPS: if (firstDown) { showRecentApps(false /* triggeredFromAltTab */); @@ -3487,6 +3474,19 @@ public class PhoneWindowManager implements WindowManagerPolicy { } break; case KeyEvent.KEYCODE_DEL: + if (newBugreportKeyboardShortcut()) { + if (mEnableBugReportKeyboardShortcut && firstDown + && event.isMetaPressed() && event.isCtrlPressed()) { + try { + mActivityManagerService.requestInteractiveBugReport(); + } catch (RemoteException e) { + Slog.d(TAG, "Error taking bugreport", e); + } + logKeyboardSystemsEvent(event, KeyboardLogEvent.TRIGGER_BUG_REPORT); + return true; + } + } + // fall through case KeyEvent.KEYCODE_ESCAPE: if (firstDown && event.isMetaPressed()) { logKeyboardSystemsEvent(event, KeyboardLogEvent.BACK); diff --git a/services/tests/wmtests/AndroidManifest.xml b/services/tests/wmtests/AndroidManifest.xml index d6c51736316a..777f6189fdea 100644 --- a/services/tests/wmtests/AndroidManifest.xml +++ b/services/tests/wmtests/AndroidManifest.xml @@ -51,6 +51,7 @@ <uses-permission android:name="android.permission.MONITOR_INPUT"/> <uses-permission android:name="android.permission.OBSERVE_ROLE_HOLDERS"/> <uses-permission android:name="android.permission.MANAGE_DEFAULT_APPLICATIONS"/> + <uses-permission android:name="android.permission.DUMP"/> <!-- TODO: Remove largeHeap hack when memory leak is fixed (b/123984854) --> <application android:debuggable="true" diff --git a/services/tests/wmtests/src/com/android/server/policy/ModifierShortcutTests.java b/services/tests/wmtests/src/com/android/server/policy/ModifierShortcutTests.java index 3c02eee7772e..0ed02dd0f429 100644 --- a/services/tests/wmtests/src/com/android/server/policy/ModifierShortcutTests.java +++ b/services/tests/wmtests/src/com/android/server/policy/ModifierShortcutTests.java @@ -21,6 +21,7 @@ import static android.view.KeyEvent.KEYCODE_B; import static android.view.KeyEvent.KEYCODE_BRIGHTNESS_DOWN; import static android.view.KeyEvent.KEYCODE_C; import static android.view.KeyEvent.KEYCODE_CTRL_LEFT; +import static android.view.KeyEvent.KEYCODE_DEL; import static android.view.KeyEvent.KEYCODE_E; import static android.view.KeyEvent.KEYCODE_ENTER; import static android.view.KeyEvent.KEYCODE_H; @@ -42,16 +43,25 @@ import android.app.role.RoleManager; import android.content.Intent; import android.os.RemoteException; import android.platform.test.annotations.Presubmit; +import android.platform.test.annotations.RequiresFlagsDisabled; +import android.platform.test.annotations.RequiresFlagsEnabled; +import android.platform.test.flag.junit.CheckFlagsRule; +import android.platform.test.flag.junit.DeviceFlagsValueProvider; import android.util.SparseArray; import androidx.test.filters.SmallTest; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; @Presubmit @SmallTest public class ModifierShortcutTests extends ShortcutKeyTestBase { + + @Rule + public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); + private static final SparseArray<String> INTENT_SHORTCUTS = new SparseArray<>(); private static final SparseArray<String> ROLE_SHORTCUTS = new SparseArray<>(); static { @@ -228,4 +238,25 @@ public class ModifierShortcutTests extends ShortcutKeyTestBase { sendKeyCombination(new int[]{KEYCODE_SCREENSHOT}, 0); mPhoneWindowManager.assertTakeScreenshotNotCalled(); } + + /** + * META+CTRL+BACKSPACE for taking a bugreport when the flag is enabled. + */ + @Test + @RequiresFlagsEnabled(com.android.server.flags.Flags.FLAG_NEW_BUGREPORT_KEYBOARD_SHORTCUT) + public void testTakeBugReport_flagEnabled() throws RemoteException { + sendKeyCombination(new int[]{KEYCODE_META_LEFT, KEYCODE_CTRL_LEFT, KEYCODE_DEL}, 0); + mPhoneWindowManager.assertTakeBugreport(true); + } + + /** + * META+CTRL+BACKSPACE for taking a bugreport does nothing when the flag is disabledd. + */ + @Test + @RequiresFlagsDisabled(com.android.server.flags.Flags.FLAG_NEW_BUGREPORT_KEYBOARD_SHORTCUT) + public void testTakeBugReport_flagDisabled() throws RemoteException { + sendKeyCombination(new int[]{KEYCODE_META_LEFT, KEYCODE_CTRL_LEFT, KEYCODE_DEL}, 0); + mPhoneWindowManager.assertTakeBugreport(false); + } + } diff --git a/services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java b/services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java index 60716cbbb693..fd69217c9778 100644 --- a/services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java +++ b/services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java @@ -23,6 +23,9 @@ import static com.android.server.policy.PhoneWindowManager.LONG_PRESS_HOME_NOTIF import static com.android.server.policy.PhoneWindowManager.SHORT_PRESS_SETTINGS_NOTIFICATION_PANEL; import android.platform.test.annotations.Presubmit; +import android.platform.test.annotations.RequiresFlagsEnabled; +import android.platform.test.flag.junit.CheckFlagsRule; +import android.platform.test.flag.junit.DeviceFlagsValueProvider; import android.view.KeyEvent; import androidx.test.filters.MediumTest; @@ -34,6 +37,7 @@ import junitparams.JUnitParamsRunner; import junitparams.Parameters; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -42,6 +46,10 @@ import org.junit.runner.RunWith; @RunWith(JUnitParamsRunner.class) public class ShortcutLoggingTests extends ShortcutKeyTestBase { + @Rule + public final CheckFlagsRule mCheckFlagsRule = + DeviceFlagsValueProvider.createCheckFlagsRule(); + private static final int VENDOR_ID = 0x123; private static final int PRODUCT_ID = 0x456; private static final int DEVICE_BUS = 0x789; @@ -153,8 +161,6 @@ public class ShortcutLoggingTests extends ShortcutKeyTestBase { new int[]{META_KEY, CTRL_KEY, KeyEvent.KEYCODE_DPAD_RIGHT}, KeyboardLogEvent.SPLIT_SCREEN_NAVIGATION, KeyEvent.KEYCODE_DPAD_RIGHT, META_ON | CTRL_ON}, - {"Shift + Menu -> Trigger Bug Report", new int[]{SHIFT_KEY, KeyEvent.KEYCODE_MENU}, - KeyboardLogEvent.TRIGGER_BUG_REPORT, KeyEvent.KEYCODE_MENU, SHIFT_ON}, {"Meta + L -> Lock Homescreen", new int[]{META_KEY, KeyEvent.KEYCODE_L}, KeyboardLogEvent.LOCK_SCREEN, KeyEvent.KEYCODE_L, META_ON}, {"Meta + Ctrl + N -> Open Notes", new int[]{META_KEY, CTRL_KEY, KeyEvent.KEYCODE_N}, @@ -353,4 +359,13 @@ public class ShortcutLoggingTests extends ShortcutKeyTestBase { expectedKey, expectedModifierState, DEVICE_BUS, "Failed while executing " + testName); } + + @Test + @RequiresFlagsEnabled(com.android.server.flags.Flags.FLAG_NEW_BUGREPORT_KEYBOARD_SHORTCUT) + public void testBugreportShortcutPress() { + sendKeyCombination(new int[]{META_KEY, CTRL_KEY, KeyEvent.KEYCODE_DEL}, 0); + mPhoneWindowManager.assertShortcutLogged(VENDOR_ID, PRODUCT_ID, + KeyboardLogEvent.TRIGGER_BUG_REPORT, KeyEvent.KEYCODE_DEL, META_ON | CTRL_ON, + DEVICE_BUS, "Failed to log bugreport shortcut."); + } } diff --git a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java index eac99298559e..dd9d05aec8c5 100644 --- a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java +++ b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java @@ -88,6 +88,7 @@ import android.telecom.TelecomManager; import android.view.Display; import android.view.InputDevice; import android.view.KeyEvent; +import android.view.accessibility.AccessibilityManager; import android.view.autofill.AutofillManagerInternal; import com.android.dx.mockito.inline.extended.StaticMockitoSession; @@ -155,6 +156,7 @@ class TestPhoneWindowManager { @Mock private AudioManagerInternal mAudioManagerInternal; @Mock private SearchManager mSearchManager; @Mock private RoleManager mRoleManager; + @Mock private AccessibilityManager mAccessibilityManager; @Mock private Display mDisplay; @Mock private DisplayRotation mDisplayRotation; @@ -305,6 +307,9 @@ class TestPhoneWindowManager { eq(SensorPrivacyManager.class)); doReturn(mSearchManager).when(mContext).getSystemService(eq(SearchManager.class)); doReturn(mRoleManager).when(mContext).getSystemService(eq(RoleManager.class)); + doReturn(mAccessibilityManager).when(mContext).getSystemService( + eq(AccessibilityManager.class)); + doReturn(false).when(mAccessibilityManager).isEnabled(); doReturn(false).when(mPackageManager).hasSystemFeature(any()); try { doThrow(new PackageManager.NameNotFoundException("test")).when(mPackageManager) @@ -602,7 +607,7 @@ class TestPhoneWindowManager { } void overrideEnableBugReportTrigger(boolean enable) { - mPhoneWindowManager.mEnableShiftMenuBugReports = enable; + mPhoneWindowManager.mEnableBugReportKeyboardShortcut = enable; } void overrideStartActivity() { @@ -746,12 +751,14 @@ class TestPhoneWindowManager { eq(displayId), eq(mImeTargetWindowToken)); } - void assertTakeBugreport() { + void assertTakeBugreport(boolean wasCalled) throws RemoteException { mTestLooper.dispatchAll(); - ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); - verify(mContext).sendOrderedBroadcastAsUser(intentCaptor.capture(), any(), any(), any(), - any(), anyInt(), any(), any()); - Assert.assertTrue(intentCaptor.getValue().getAction() == Intent.ACTION_BUG_REPORT); + if (wasCalled) { + verify(mActivityManagerService).requestInteractiveBugReport(); + } else { + verify(mActivityManagerService, never()).requestInteractiveBugReport(); + } + } void assertTogglePanel() throws RemoteException { |