Merge "Refactor ShortcutManager to ModifierShortcutManager" into sc-dev
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,18 +16,24 @@
|
||||
|
||||
package com.android.server.policy;
|
||||
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.XmlResourceParser;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.util.LongSparseArray;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseArray;
|
||||
import android.view.KeyCharacterMap;
|
||||
import android.view.KeyEvent;
|
||||
|
||||
import com.android.internal.policy.IShortcutService;
|
||||
import com.android.internal.util.XmlUtils;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
@@ -39,8 +45,9 @@ import java.io.IOException;
|
||||
* Manages quick launch shortcuts by:
|
||||
* <li> Keeping the local copy in sync with the database (this is an observer)
|
||||
* <li> Returning a shortcut-matching intent to clients
|
||||
* <li> Returning particular kind of application intent by special key.
|
||||
*/
|
||||
class ShortcutManager {
|
||||
class ModifierShortcutManager {
|
||||
private static final String TAG = "ShortcutManager";
|
||||
|
||||
private static final String TAG_BOOKMARKS = "bookmarks";
|
||||
@@ -52,12 +59,39 @@ class ShortcutManager {
|
||||
private static final String ATTRIBUTE_CATEGORY = "category";
|
||||
private static final String ATTRIBUTE_SHIFT = "shift";
|
||||
|
||||
private final SparseArray<ShortcutInfo> mShortcuts = new SparseArray<>();
|
||||
private final SparseArray<ShortcutInfo> mIntentShortcuts = new SparseArray<>();
|
||||
private final SparseArray<ShortcutInfo> mShiftShortcuts = new SparseArray<>();
|
||||
|
||||
private LongSparseArray<IShortcutService> mShortcutKeyServices = new LongSparseArray<>();
|
||||
|
||||
/* Table of Application Launch keys. Maps from key codes to intent categories.
|
||||
*
|
||||
* These are special keys that are used to launch particular kinds of applications,
|
||||
* such as a web browser. HID defines nearly a hundred of them in the Consumer (0x0C)
|
||||
* usage page. We don't support quite that many yet...
|
||||
*/
|
||||
static SparseArray<String> sApplicationLaunchKeyCategories;
|
||||
static {
|
||||
sApplicationLaunchKeyCategories = new SparseArray<String>();
|
||||
sApplicationLaunchKeyCategories.append(
|
||||
KeyEvent.KEYCODE_EXPLORER, Intent.CATEGORY_APP_BROWSER);
|
||||
sApplicationLaunchKeyCategories.append(
|
||||
KeyEvent.KEYCODE_ENVELOPE, Intent.CATEGORY_APP_EMAIL);
|
||||
sApplicationLaunchKeyCategories.append(
|
||||
KeyEvent.KEYCODE_CONTACTS, Intent.CATEGORY_APP_CONTACTS);
|
||||
sApplicationLaunchKeyCategories.append(
|
||||
KeyEvent.KEYCODE_CALENDAR, Intent.CATEGORY_APP_CALENDAR);
|
||||
sApplicationLaunchKeyCategories.append(
|
||||
KeyEvent.KEYCODE_MUSIC, Intent.CATEGORY_APP_MUSIC);
|
||||
sApplicationLaunchKeyCategories.append(
|
||||
KeyEvent.KEYCODE_CALCULATOR, Intent.CATEGORY_APP_CALCULATOR);
|
||||
}
|
||||
|
||||
private final Context mContext;
|
||||
|
||||
public ShortcutManager(Context context) {
|
||||
private boolean mSearchKeyShortcutPending = false;
|
||||
private boolean mConsumeSearchKeyUp = true;
|
||||
|
||||
ModifierShortcutManager(Context context) {
|
||||
mContext = context;
|
||||
loadShortcuts();
|
||||
}
|
||||
@@ -70,19 +104,19 @@ class ShortcutManager {
|
||||
* <p>
|
||||
* This will first try an exact match (with modifiers), and then try a
|
||||
* match without modifiers (primary character on a key).
|
||||
*
|
||||
*
|
||||
* @param kcm The key character map of the device on which the key was pressed.
|
||||
* @param keyCode The key code.
|
||||
* @param metaState The meta state, omitting any modifiers that were used
|
||||
* to invoke the shortcut.
|
||||
* @return The intent that matches the shortcut, or null if not found.
|
||||
*/
|
||||
public Intent getIntent(KeyCharacterMap kcm, int keyCode, int metaState) {
|
||||
private Intent getIntent(KeyCharacterMap kcm, int keyCode, int metaState) {
|
||||
ShortcutInfo shortcut = null;
|
||||
|
||||
// If the Shift key is pressed, then search for the shift shortcuts.
|
||||
boolean isShiftOn = (metaState & KeyEvent.META_SHIFT_ON) == KeyEvent.META_SHIFT_ON;
|
||||
SparseArray<ShortcutInfo> shortcutMap = isShiftOn ? mShiftShortcuts : mShortcuts;
|
||||
SparseArray<ShortcutInfo> shortcutMap = isShiftOn ? mShiftShortcuts : mIntentShortcuts;
|
||||
|
||||
// First try the exact keycode (with modifiers).
|
||||
int shortcutChar = kcm.get(keyCode, metaState);
|
||||
@@ -176,7 +210,7 @@ class ShortcutManager {
|
||||
if (isShiftShortcut) {
|
||||
mShiftShortcuts.put(shortcutChar, shortcut);
|
||||
} else {
|
||||
mShortcuts.put(shortcutChar, shortcut);
|
||||
mIntentShortcuts.put(shortcutChar, shortcut);
|
||||
}
|
||||
}
|
||||
} catch (XmlPullParserException e) {
|
||||
@@ -186,11 +220,159 @@ class ShortcutManager {
|
||||
}
|
||||
}
|
||||
|
||||
void registerShortcutKey(long shortcutCode, IShortcutService shortcutService)
|
||||
throws RemoteException {
|
||||
IShortcutService service = mShortcutKeyServices.get(shortcutCode);
|
||||
if (service != null && service.asBinder().pingBinder()) {
|
||||
throw new RemoteException("Key already exists.");
|
||||
}
|
||||
|
||||
mShortcutKeyServices.put(shortcutCode, shortcutService);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the shortcut to {@link IShortcutService}
|
||||
* @param keyCode The key code of the event.
|
||||
* @param metaState The meta key modifier state.
|
||||
* @return True if invoked the shortcut, otherwise false.
|
||||
*/
|
||||
private boolean handleShortcutService(int keyCode, int metaState) {
|
||||
long shortcutCode = keyCode;
|
||||
if ((metaState & KeyEvent.META_CTRL_ON) != 0) {
|
||||
shortcutCode |= ((long) KeyEvent.META_CTRL_ON) << Integer.SIZE;
|
||||
}
|
||||
|
||||
if ((metaState & KeyEvent.META_ALT_ON) != 0) {
|
||||
shortcutCode |= ((long) KeyEvent.META_ALT_ON) << Integer.SIZE;
|
||||
}
|
||||
|
||||
if ((metaState & KeyEvent.META_SHIFT_ON) != 0) {
|
||||
shortcutCode |= ((long) KeyEvent.META_SHIFT_ON) << Integer.SIZE;
|
||||
}
|
||||
|
||||
if ((metaState & KeyEvent.META_META_ON) != 0) {
|
||||
shortcutCode |= ((long) KeyEvent.META_META_ON) << Integer.SIZE;
|
||||
}
|
||||
|
||||
IShortcutService shortcutService = mShortcutKeyServices.get(shortcutCode);
|
||||
if (shortcutService != null) {
|
||||
try {
|
||||
shortcutService.notifyShortcutKeyPressed(shortcutCode);
|
||||
} catch (RemoteException e) {
|
||||
mShortcutKeyServices.delete(shortcutCode);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the shortcut to {@link Intent}
|
||||
*
|
||||
* @param kcm the {@link KeyCharacterMap} associated with the keyboard device.
|
||||
* @param keyCode The key code of the event.
|
||||
* @param metaState The meta key modifier state.
|
||||
* @return True if invoked the shortcut, otherwise false.
|
||||
*/
|
||||
private boolean handleIntentShortcut(KeyCharacterMap kcm, int keyCode, int metaState) {
|
||||
// Shortcuts are invoked through Search+key, so intercept those here
|
||||
// Any printing key that is chorded with Search should be consumed
|
||||
// even if no shortcut was invoked. This prevents text from being
|
||||
// inadvertently inserted when using a keyboard that has built-in macro
|
||||
// shortcut keys (that emit Search+x) and some of them are not registered.
|
||||
if (mSearchKeyShortcutPending) {
|
||||
if (kcm.isPrintingKey(keyCode)) {
|
||||
mConsumeSearchKeyUp = true;
|
||||
mSearchKeyShortcutPending = false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else if ((metaState & KeyEvent.META_META_MASK) != 0) {
|
||||
// Invoke shortcuts using Meta.
|
||||
metaState &= ~KeyEvent.META_META_MASK;
|
||||
} else {
|
||||
// Handle application launch keys.
|
||||
String category = sApplicationLaunchKeyCategories.get(keyCode);
|
||||
if (category != null) {
|
||||
Intent intent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN, category);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
try {
|
||||
mContext.startActivityAsUser(intent, UserHandle.CURRENT);
|
||||
} catch (ActivityNotFoundException ex) {
|
||||
Slog.w(TAG, "Dropping application launch key because "
|
||||
+ "the activity to which it is registered was not found: "
|
||||
+ "keyCode=" + KeyEvent.keyCodeToString(keyCode) + ","
|
||||
+ " category=" + category, ex);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
final Intent shortcutIntent = getIntent(kcm, keyCode, metaState);
|
||||
if (shortcutIntent != null) {
|
||||
shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
try {
|
||||
mContext.startActivityAsUser(shortcutIntent, UserHandle.CURRENT);
|
||||
} catch (ActivityNotFoundException ex) {
|
||||
Slog.w(TAG, "Dropping shortcut key combination because "
|
||||
+ "the activity to which it is registered was not found: "
|
||||
+ "META+ or SEARCH" + KeyEvent.keyCodeToString(keyCode), ex);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the shortcut from {@link KeyEvent}
|
||||
*
|
||||
* @param event Description of the key event.
|
||||
* @return True if invoked the shortcut, otherwise false.
|
||||
*/
|
||||
boolean interceptKey(KeyEvent event) {
|
||||
if (event.getRepeatCount() != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final int metaState = event.getModifiers();
|
||||
final int keyCode = event.getKeyCode();
|
||||
if (keyCode == KeyEvent.KEYCODE_SEARCH) {
|
||||
if (event.getAction() == KeyEvent.ACTION_DOWN) {
|
||||
mSearchKeyShortcutPending = true;
|
||||
mConsumeSearchKeyUp = false;
|
||||
} else {
|
||||
mSearchKeyShortcutPending = false;
|
||||
if (mConsumeSearchKeyUp) {
|
||||
mConsumeSearchKeyUp = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (event.getAction() != KeyEvent.ACTION_DOWN) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final KeyCharacterMap kcm = event.getKeyCharacterMap();
|
||||
if (handleIntentShortcut(kcm, keyCode, metaState)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (handleShortcutService(keyCode, metaState)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static final class ShortcutInfo {
|
||||
public final String title;
|
||||
public final Intent intent;
|
||||
|
||||
public ShortcutInfo(String title, Intent intent) {
|
||||
ShortcutInfo(String title, Intent intent) {
|
||||
this.title = title;
|
||||
this.intent = intent;
|
||||
}
|
||||
@@ -163,7 +163,6 @@ import android.service.vr.IPersistentVrStateCallbacks;
|
||||
import android.speech.RecognizerIntent;
|
||||
import android.telecom.TelecomManager;
|
||||
import android.util.Log;
|
||||
import android.util.LongSparseArray;
|
||||
import android.util.MutableBoolean;
|
||||
import android.util.PrintWriterPrinter;
|
||||
import android.util.Slog;
|
||||
@@ -318,29 +317,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
*/
|
||||
private boolean mKeyguardDrawnOnce;
|
||||
|
||||
/* Table of Application Launch keys. Maps from key codes to intent categories.
|
||||
*
|
||||
* These are special keys that are used to launch particular kinds of applications,
|
||||
* such as a web browser. HID defines nearly a hundred of them in the Consumer (0x0C)
|
||||
* usage page. We don't support quite that many yet...
|
||||
*/
|
||||
static SparseArray<String> sApplicationLaunchKeyCategories;
|
||||
static {
|
||||
sApplicationLaunchKeyCategories = new SparseArray<String>();
|
||||
sApplicationLaunchKeyCategories.append(
|
||||
KeyEvent.KEYCODE_EXPLORER, Intent.CATEGORY_APP_BROWSER);
|
||||
sApplicationLaunchKeyCategories.append(
|
||||
KeyEvent.KEYCODE_ENVELOPE, Intent.CATEGORY_APP_EMAIL);
|
||||
sApplicationLaunchKeyCategories.append(
|
||||
KeyEvent.KEYCODE_CONTACTS, Intent.CATEGORY_APP_CONTACTS);
|
||||
sApplicationLaunchKeyCategories.append(
|
||||
KeyEvent.KEYCODE_CALENDAR, Intent.CATEGORY_APP_CALENDAR);
|
||||
sApplicationLaunchKeyCategories.append(
|
||||
KeyEvent.KEYCODE_MUSIC, Intent.CATEGORY_APP_MUSIC);
|
||||
sApplicationLaunchKeyCategories.append(
|
||||
KeyEvent.KEYCODE_CALCULATOR, Intent.CATEGORY_APP_CALCULATOR);
|
||||
}
|
||||
|
||||
/** Amount of time (in milliseconds) to wait for windows drawn before powering on. */
|
||||
static final int WAITING_FOR_DRAWN_TIMEOUT = 1000;
|
||||
|
||||
@@ -419,8 +395,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
boolean mSafeMode;
|
||||
private WindowState mKeyguardCandidate = null;
|
||||
|
||||
private LongSparseArray<IShortcutService> mShortcutKeyServices = new LongSparseArray<>();
|
||||
|
||||
// Whether to allow dock apps with METADATA_DOCK_HOME to temporarily take over the Home key.
|
||||
// This is for car dock and this is updated from resource.
|
||||
private boolean mEnableCarDockHomeCapture = true;
|
||||
@@ -516,8 +490,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
Intent mCarDockIntent;
|
||||
Intent mDeskDockIntent;
|
||||
Intent mVrHeadsetHomeIntent;
|
||||
boolean mSearchKeyShortcutPending;
|
||||
boolean mConsumeSearchKeyUp;
|
||||
boolean mPendingMetaAction;
|
||||
boolean mPendingCapsLockToggle;
|
||||
|
||||
@@ -578,7 +550,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
private static final int BRIGHTNESS_STEPS = 10;
|
||||
|
||||
SettingsObserver mSettingsObserver;
|
||||
ShortcutManager mShortcutManager;
|
||||
ModifierShortcutManager mModifierShortcutManager;
|
||||
PowerManager.WakeLock mBroadcastWakeLock;
|
||||
PowerManager.WakeLock mPowerKeyWakeLock;
|
||||
boolean mHavePendingMediaKeyRepeatWithWakeLock;
|
||||
@@ -1772,7 +1744,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
mWakeGestureListener = new MyWakeGestureListener(mContext, mHandler);
|
||||
mSettingsObserver = new SettingsObserver(mHandler);
|
||||
mSettingsObserver.observe();
|
||||
mShortcutManager = new ShortcutManager(context);
|
||||
mModifierShortcutManager = new ModifierShortcutManager(context);
|
||||
mUiMode = context.getResources().getInteger(
|
||||
com.android.internal.R.integer.config_defaultUiModeType);
|
||||
mHomeIntent = new Intent(Intent.ACTION_MAIN, null);
|
||||
@@ -2574,6 +2546,15 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
mPendingCapsLockToggle = false;
|
||||
}
|
||||
|
||||
if (isUserSetupComplete() && !keyguardOn) {
|
||||
if (mModifierShortcutManager.interceptKey(event)) {
|
||||
dismissKeyboardShortcutsMenu();
|
||||
mPendingMetaAction = false;
|
||||
mPendingCapsLockToggle = false;
|
||||
return key_consumed;
|
||||
}
|
||||
}
|
||||
|
||||
switch(keyCode) {
|
||||
case KeyEvent.KEYCODE_HOME:
|
||||
// First we always handle the home key here, so applications
|
||||
@@ -2599,20 +2580,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
}
|
||||
}
|
||||
break;
|
||||
case KeyEvent.KEYCODE_SEARCH:
|
||||
if (down) {
|
||||
if (repeatCount == 0) {
|
||||
mSearchKeyShortcutPending = true;
|
||||
mConsumeSearchKeyUp = false;
|
||||
}
|
||||
} else {
|
||||
mSearchKeyShortcutPending = false;
|
||||
if (mConsumeSearchKeyUp) {
|
||||
mConsumeSearchKeyUp = false;
|
||||
return key_consumed;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
case KeyEvent.KEYCODE_APP_SWITCH:
|
||||
if (!keyguardOn) {
|
||||
if (down && repeatCount == 0) {
|
||||
@@ -2820,114 +2787,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
break;
|
||||
}
|
||||
|
||||
// Shortcuts are invoked through Search+key, so intercept those here
|
||||
// Any printing key that is chorded with Search should be consumed
|
||||
// even if no shortcut was invoked. This prevents text from being
|
||||
// inadvertently inserted when using a keyboard that has built-in macro
|
||||
// shortcut keys (that emit Search+x) and some of them are not registered.
|
||||
if (mSearchKeyShortcutPending) {
|
||||
final KeyCharacterMap kcm = event.getKeyCharacterMap();
|
||||
if (kcm.isPrintingKey(keyCode)) {
|
||||
mConsumeSearchKeyUp = true;
|
||||
mSearchKeyShortcutPending = false;
|
||||
if (down && repeatCount == 0 && !keyguardOn) {
|
||||
Intent shortcutIntent = mShortcutManager.getIntent(kcm, keyCode, metaState);
|
||||
if (shortcutIntent != null) {
|
||||
shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
try {
|
||||
startActivityAsUser(shortcutIntent, UserHandle.CURRENT);
|
||||
dismissKeyboardShortcutsMenu();
|
||||
} catch (ActivityNotFoundException ex) {
|
||||
Slog.w(TAG, "Dropping shortcut key combination because "
|
||||
+ "the activity to which it is registered was not found: "
|
||||
+ "SEARCH+" + KeyEvent.keyCodeToString(keyCode), ex);
|
||||
}
|
||||
} else {
|
||||
Slog.i(TAG, "Dropping unregistered shortcut key combination: "
|
||||
+ "SEARCH+" + KeyEvent.keyCodeToString(keyCode));
|
||||
}
|
||||
}
|
||||
return key_consumed;
|
||||
}
|
||||
}
|
||||
|
||||
// Invoke shortcuts using Meta.
|
||||
if (down && repeatCount == 0 && !keyguardOn
|
||||
&& (metaState & KeyEvent.META_META_ON) != 0) {
|
||||
final KeyCharacterMap kcm = event.getKeyCharacterMap();
|
||||
if (kcm.isPrintingKey(keyCode)) {
|
||||
Intent shortcutIntent = mShortcutManager.getIntent(kcm, keyCode,
|
||||
metaState & ~(KeyEvent.META_META_ON
|
||||
| KeyEvent.META_META_LEFT_ON | KeyEvent.META_META_RIGHT_ON));
|
||||
if (shortcutIntent != null) {
|
||||
shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
try {
|
||||
startActivityAsUser(shortcutIntent, UserHandle.CURRENT);
|
||||
dismissKeyboardShortcutsMenu();
|
||||
} catch (ActivityNotFoundException ex) {
|
||||
Slog.w(TAG, "Dropping shortcut key combination because "
|
||||
+ "the activity to which it is registered was not found: "
|
||||
+ "META+" + KeyEvent.keyCodeToString(keyCode), ex);
|
||||
}
|
||||
return key_consumed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle application launch keys.
|
||||
if (down && repeatCount == 0 && !keyguardOn) {
|
||||
String category = sApplicationLaunchKeyCategories.get(keyCode);
|
||||
if (category != null) {
|
||||
Intent intent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN, category);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
try {
|
||||
startActivityAsUser(intent, UserHandle.CURRENT);
|
||||
dismissKeyboardShortcutsMenu();
|
||||
} catch (ActivityNotFoundException ex) {
|
||||
Slog.w(TAG, "Dropping application launch key because "
|
||||
+ "the activity to which it is registered was not found: "
|
||||
+ "keyCode=" + keyCode + ", category=" + category, ex);
|
||||
}
|
||||
return key_consumed;
|
||||
}
|
||||
}
|
||||
|
||||
if (isValidGlobalKey(keyCode)
|
||||
&& mGlobalKeyManager.handleGlobalKey(mContext, keyCode, event)) {
|
||||
return key_consumed;
|
||||
}
|
||||
|
||||
if (down) {
|
||||
long shortcutCode = keyCode;
|
||||
if (event.isCtrlPressed()) {
|
||||
shortcutCode |= ((long) KeyEvent.META_CTRL_ON) << Integer.SIZE;
|
||||
}
|
||||
|
||||
if (event.isAltPressed()) {
|
||||
shortcutCode |= ((long) KeyEvent.META_ALT_ON) << Integer.SIZE;
|
||||
}
|
||||
|
||||
if (event.isShiftPressed()) {
|
||||
shortcutCode |= ((long) KeyEvent.META_SHIFT_ON) << Integer.SIZE;
|
||||
}
|
||||
|
||||
if (event.isMetaPressed()) {
|
||||
shortcutCode |= ((long) KeyEvent.META_META_ON) << Integer.SIZE;
|
||||
}
|
||||
|
||||
IShortcutService shortcutService = mShortcutKeyServices.get(shortcutCode);
|
||||
if (shortcutService != null) {
|
||||
try {
|
||||
if (isUserSetupComplete()) {
|
||||
shortcutService.notifyShortcutKeyPressed(shortcutCode);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
mShortcutKeyServices.delete(shortcutCode);
|
||||
}
|
||||
return key_consumed;
|
||||
}
|
||||
}
|
||||
|
||||
// Reserve all the META modifier combos for system behavior
|
||||
if ((metaState & KeyEvent.META_META_ON) != 0) {
|
||||
return key_consumed;
|
||||
@@ -3113,12 +2977,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
public void registerShortcutKey(long shortcutCode, IShortcutService shortcutService)
|
||||
throws RemoteException {
|
||||
synchronized (mLock) {
|
||||
IShortcutService service = mShortcutKeyServices.get(shortcutCode);
|
||||
if (service != null && service.asBinder().pingBinder()) {
|
||||
throw new RemoteException("Key already exists.");
|
||||
}
|
||||
|
||||
mShortcutKeyServices.put(shortcutCode, shortcutService);
|
||||
mModifierShortcutManager.registerShortcutKey(shortcutCode, shortcutService);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user