diff options
author | 2011-11-28 12:59:11 -0800 | |
---|---|---|
committer | 2011-11-29 12:17:22 -0800 | |
commit | 6651a638348c15e89e265b0a53c775cac9beafa2 (patch) | |
tree | f42e59d99363cada07cdb6f4bff69fa51bfae2ad | |
parent | 500afb87a7a8b5928ef1a5196bdfd0bcc2b87e4a (diff) |
Fix application launch shortcuts.
Improved quick launch bookmarks to support category-based shortcuts
instead of hardcoding package and class names for all apps.
Added a set of Intent categories for typical applications on the
platform.
Added support for some of the HID application launch usages to
reduce reliance on quick launch for special purpose keys. Some
keyboard vendors have hardcoded launch keys that synthesize
"Search + X" type key combos. The goal is to encourage them
to stop doing this by implementing more of HID.
Bug: 5674723
Change-Id: I79f1147c65a208efc3f67228c9f0fa5cd050c593
-rw-r--r-- | api/current.txt | 15 | ||||
-rw-r--r-- | core/java/android/content/Intent.java | 68 | ||||
-rw-r--r-- | core/java/android/provider/MediaStore.java | 5 | ||||
-rwxr-xr-x | core/java/android/view/KeyEvent.java | 22 | ||||
-rwxr-xr-x | core/res/res/values/attrs.xml | 4 | ||||
-rw-r--r-- | data/keyboards/Generic.kl | 9 | ||||
-rwxr-xr-x | include/ui/KeycodeLabels.h | 4 | ||||
-rw-r--r-- | native/include/android/keycodes.h | 4 | ||||
-rw-r--r-- | packages/SettingsProvider/res/xml/bookmarks.xml | 25 | ||||
-rw-r--r-- | packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java | 83 | ||||
-rwxr-xr-x | policy/src/com/android/internal/policy/impl/PhoneWindowManager.java | 43 |
11 files changed, 222 insertions, 60 deletions
diff --git a/api/current.txt b/api/current.txt index 23b441b776ef..de8cab1fe317 100644 --- a/api/current.txt +++ b/api/current.txt @@ -5502,7 +5502,16 @@ package android.content { field public static final java.lang.String ACTION_WALLPAPER_CHANGED = "android.intent.action.WALLPAPER_CHANGED"; field public static final java.lang.String ACTION_WEB_SEARCH = "android.intent.action.WEB_SEARCH"; field public static final java.lang.String CATEGORY_ALTERNATIVE = "android.intent.category.ALTERNATIVE"; + field public static final java.lang.String CATEGORY_APP_BROWSER = "android.intent.category.APP_BROWSER"; + field public static final java.lang.String CATEGORY_APP_CALCULATOR = "android.intent.category.APP_CALCULATOR"; + field public static final java.lang.String CATEGORY_APP_CALENDAR = "android.intent.category.APP_CALENDAR"; + field public static final java.lang.String CATEGORY_APP_CONTACTS = "android.intent.category.APP_CONTACTS"; + field public static final java.lang.String CATEGORY_APP_EMAIL = "android.intent.category.APP_EMAIL"; + field public static final java.lang.String CATEGORY_APP_GALLERY = "android.intent.category.APP_GALLERY"; + field public static final java.lang.String CATEGORY_APP_MAPS = "android.intent.category.APP_MAPS"; field public static final java.lang.String CATEGORY_APP_MARKET = "android.intent.category.APP_MARKET"; + field public static final java.lang.String CATEGORY_APP_MESSAGING = "android.intent.category.APP_MESSAGING"; + field public static final java.lang.String CATEGORY_APP_MUSIC = "android.intent.category.APP_MUSIC"; field public static final java.lang.String CATEGORY_BROWSABLE = "android.intent.category.BROWSABLE"; field public static final java.lang.String CATEGORY_CAR_DOCK = "android.intent.category.CAR_DOCK"; field public static final java.lang.String CATEGORY_CAR_MODE = "android.intent.category.CAR_MODE"; @@ -17056,7 +17065,7 @@ package android.provider { field public static final java.lang.String EXTRA_VIDEO_QUALITY = "android.intent.extra.videoQuality"; field public static final java.lang.String INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH = "android.media.action.MEDIA_PLAY_FROM_SEARCH"; field public static final java.lang.String INTENT_ACTION_MEDIA_SEARCH = "android.intent.action.MEDIA_SEARCH"; - field public static final java.lang.String INTENT_ACTION_MUSIC_PLAYER = "android.intent.action.MUSIC_PLAYER"; + field public static final deprecated java.lang.String INTENT_ACTION_MUSIC_PLAYER = "android.intent.action.MUSIC_PLAYER"; field public static final java.lang.String INTENT_ACTION_STILL_IMAGE_CAMERA = "android.media.action.STILL_IMAGE_CAMERA"; field public static final java.lang.String INTENT_ACTION_VIDEO_CAMERA = "android.media.action.VIDEO_CAMERA"; field public static final java.lang.String MEDIA_IGNORE_FILENAME = ".nomedia"; @@ -22215,6 +22224,8 @@ package android.view { field public static final int KEYCODE_BUTTON_Y = 100; // 0x64 field public static final int KEYCODE_BUTTON_Z = 101; // 0x65 field public static final int KEYCODE_C = 31; // 0x1f + field public static final int KEYCODE_CALCULATOR = 210; // 0xd2 + field public static final int KEYCODE_CALENDAR = 208; // 0xd0 field public static final int KEYCODE_CALL = 5; // 0x5 field public static final int KEYCODE_CAMERA = 27; // 0x1b field public static final int KEYCODE_CAPS_LOCK = 115; // 0x73 @@ -22223,6 +22234,7 @@ package android.view { field public static final int KEYCODE_CHANNEL_UP = 166; // 0xa6 field public static final int KEYCODE_CLEAR = 28; // 0x1c field public static final int KEYCODE_COMMA = 55; // 0x37 + field public static final int KEYCODE_CONTACTS = 207; // 0xcf field public static final int KEYCODE_CTRL_LEFT = 113; // 0x71 field public static final int KEYCODE_CTRL_RIGHT = 114; // 0x72 field public static final int KEYCODE_D = 32; // 0x20 @@ -22290,6 +22302,7 @@ package android.view { field public static final int KEYCODE_MINUS = 69; // 0x45 field public static final int KEYCODE_MOVE_END = 123; // 0x7b field public static final int KEYCODE_MOVE_HOME = 122; // 0x7a + field public static final int KEYCODE_MUSIC = 209; // 0xd1 field public static final int KEYCODE_MUTE = 91; // 0x5b field public static final int KEYCODE_N = 42; // 0x2a field public static final int KEYCODE_NOTIFICATION = 83; // 0x53 diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 45a42e44f1cd..9948985ce14d 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -2310,6 +2310,74 @@ public class Intent implements Parcelable, Cloneable { // --------------------------------------------------------------------- // --------------------------------------------------------------------- + // Application launch intent categories (see addCategory()). + + /** + * Used with {@link #ACTION_MAIN} to launch the browser application. + * The activity should be able to browse the Internet. + */ + @SdkConstant(SdkConstantType.INTENT_CATEGORY) + public static final String CATEGORY_APP_BROWSER = "android.intent.category.APP_BROWSER"; + + /** + * Used with {@link #ACTION_MAIN} to launch the calculator application. + * The activity should be able to perform standard arithmetic operations. + */ + @SdkConstant(SdkConstantType.INTENT_CATEGORY) + public static final String CATEGORY_APP_CALCULATOR = "android.intent.category.APP_CALCULATOR"; + + /** + * Used with {@link #ACTION_MAIN} to launch the calendar application. + * The activity should be able to view and manipulate calendar entries. + */ + @SdkConstant(SdkConstantType.INTENT_CATEGORY) + public static final String CATEGORY_APP_CALENDAR = "android.intent.category.APP_CALENDAR"; + + /** + * Used with {@link #ACTION_MAIN} to launch the contacts application. + * The activity should be able to view and manipulate address book entries. + */ + @SdkConstant(SdkConstantType.INTENT_CATEGORY) + public static final String CATEGORY_APP_CONTACTS = "android.intent.category.APP_CONTACTS"; + + /** + * Used with {@link #ACTION_MAIN} to launch the email application. + * The activity should be able to send and receive email. + */ + @SdkConstant(SdkConstantType.INTENT_CATEGORY) + public static final String CATEGORY_APP_EMAIL = "android.intent.category.APP_EMAIL"; + + /** + * Used with {@link #ACTION_MAIN} to launch the gallery application. + * The activity should be able to view and manipulate image and video files + * stored on the device. + */ + @SdkConstant(SdkConstantType.INTENT_CATEGORY) + public static final String CATEGORY_APP_GALLERY = "android.intent.category.APP_GALLERY"; + + /** + * Used with {@link #ACTION_MAIN} to launch the maps application. + * The activity should be able to show the user's current location and surroundings. + */ + @SdkConstant(SdkConstantType.INTENT_CATEGORY) + public static final String CATEGORY_APP_MAPS = "android.intent.category.APP_MAPS"; + + /** + * Used with {@link #ACTION_MAIN} to launch the messaging application. + * The activity should be able to send and receive text messages. + */ + @SdkConstant(SdkConstantType.INTENT_CATEGORY) + public static final String CATEGORY_APP_MESSAGING = "android.intent.category.APP_MESSAGING"; + + /** + * Used with {@link #ACTION_MAIN} to launch the music application. + * The activity should be able to play, browse, or manipulate music files stored on the device. + */ + @SdkConstant(SdkConstantType.INTENT_CATEGORY) + public static final String CATEGORY_APP_MUSIC = "android.intent.category.APP_MUSIC"; + + // --------------------------------------------------------------------- + // --------------------------------------------------------------------- // Standard extra data keys. /** diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java index 5f111eb8e73c..4e016723eba3 100644 --- a/core/java/android/provider/MediaStore.java +++ b/core/java/android/provider/MediaStore.java @@ -40,8 +40,6 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.io.UnsupportedEncodingException; -import java.text.Collator; /** * The Media provider contains meta data for all available media on both internal @@ -66,7 +64,10 @@ public final class MediaStore { /** * Activity Action: Launch a music player. * The activity should be able to play, browse, or manipulate music files stored on the device. + * + * @deprecated Use {@link android.content.Intent#CATEGORY_APP_MUSIC} instead. */ + @Deprecated @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) public static final String INTENT_ACTION_MUSIC_PLAYER = "android.intent.action.MUSIC_PLAYER"; diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java index 6c3d387a5fd7..f53e42cb4603 100755 --- a/core/java/android/view/KeyEvent.java +++ b/core/java/android/view/KeyEvent.java @@ -579,8 +579,20 @@ public class KeyEvent extends InputEvent implements Parcelable { /** Key code constant: 3D Mode key. * Toggles the display between 2D and 3D mode. */ public static final int KEYCODE_3D_MODE = 206; - - private static final int LAST_KEYCODE = KEYCODE_BUTTON_16; + /** Key code constant: Contacts special function key. + * Used to launch an address book application. */ + public static final int KEYCODE_CONTACTS = 207; + /** Key code constant: Calendar special function key. + * Used to launch a calendar application. */ + public static final int KEYCODE_CALENDAR = 208; + /** Key code constant: Music special function key. + * Used to launch a music player application. */ + public static final int KEYCODE_MUSIC = 209; + /** Key code constant: Calculator special function key. + * Used to launch a calculator application. */ + public static final int KEYCODE_CALCULATOR = 210; + + private static final int LAST_KEYCODE = KEYCODE_CALCULATOR; // NOTE: If you add a new keycode here you must also add it to: // isSystem() @@ -589,6 +601,8 @@ public class KeyEvent extends InputEvent implements Parcelable { // external/webkit/WebKit/android/plugins/ANPKeyCodes.h // frameworks/base/core/res/res/values/attrs.xml // emulator? + // LAST_KEYCODE + // KEYCODE_SYMBOLIC_NAMES // // Also Android currently does not reserve code ranges for vendor- // specific key codes. If you have new key codes to have, you @@ -807,6 +821,10 @@ public class KeyEvent extends InputEvent implements Parcelable { names.append(KEYCODE_LANGUAGE_SWITCH, "KEYCODE_LANGUAGE_SWITCH"); names.append(KEYCODE_MANNER_MODE, "KEYCODE_MANNER_MODE"); names.append(KEYCODE_3D_MODE, "KEYCODE_3D_MODE"); + names.append(KEYCODE_CONTACTS, "KEYCODE_CONTACTS"); + names.append(KEYCODE_CALENDAR, "KEYCODE_CALENDAR"); + names.append(KEYCODE_MUSIC, "KEYCODE_MUSIC"); + names.append(KEYCODE_CALCULATOR, "KEYCODE_CALCULATOR"); }; // Symbolic names of all metakeys in bit order from least significant to most significant. diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index d0ab8b116d06..af59198fcef1 100755 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -1493,6 +1493,10 @@ <enum name="KEYCODE_LANGUAGE_SWITCH" value="204" /> <enum name="KEYCODE_MANNER_MODE" value="205" /> <enum name="KEYCODE_3D_MODE" value="206" /> + <enum name="KEYCODE_CONTACTS" value="207" /> + <enum name="KEYCODE_CALENDAR" value="208" /> + <enum name="KEYCODE_MUSIC" value="209" /> + <enum name="KEYCODE_CALCULATOR" value="210" /> </attr> <!-- ***************************************************************** --> diff --git a/data/keyboards/Generic.kl b/data/keyboards/Generic.kl index 10de6ac9cf12..fdd9040d7348 100644 --- a/data/keyboards/Generic.kl +++ b/data/keyboards/Generic.kl @@ -159,7 +159,7 @@ key 128 MEDIA_STOP # key 137 "KEY_CUT" # key 138 "KEY_HELP" key 139 MENU WAKE_DROPPED -# key 140 "KEY_CALC" +key 140 CALCULATOR # key 141 "KEY_SETUP" key 142 POWER WAKE key 143 POWER WAKE @@ -190,7 +190,7 @@ key 167 MEDIA_RECORD key 168 MEDIA_REWIND key 169 CALL # key 170 "KEY_ISO" -# key 171 "KEY_CONFIG" +key 171 MUSIC key 172 HOME # key 173 "KEY_REFRESH" # key 174 "KEY_EXIT" @@ -232,7 +232,7 @@ key 208 MEDIA_FAST_FORWARD # key 210 "KEY_PRINT" # key 211 "KEY_HP" key 212 CAMERA -# key 213 "KEY_SOUND" +key 213 MUSIC # key 214 "KEY_QUESTION" key 215 ENVELOPE # key 216 "KEY_CHAT" @@ -344,7 +344,7 @@ key 377 TV # key 394 "KEY_DIRECTORY" # key 395 "KEY_LIST" # key 396 "KEY_MEMO" -# key 397 "KEY_CALENDAR" +key 397 CALENDAR # key 398 "KEY_RED" # key 399 "KEY_GREEN" # key 400 "KEY_YELLOW" @@ -364,6 +364,7 @@ key 403 CHANNEL_DOWN # key 414 "KEY_TEEN" # key 415 "KEY_TWEN" +key 429 CONTACTS # key 448 "KEY_DEL_EOL" # key 449 "KEY_DEL_EOS" diff --git a/include/ui/KeycodeLabels.h b/include/ui/KeycodeLabels.h index 2efe8ca0ee50..c5bd0c544673 100755 --- a/include/ui/KeycodeLabels.h +++ b/include/ui/KeycodeLabels.h @@ -231,6 +231,10 @@ static const KeycodeLabel KEYCODES[] = { { "LANGUAGE_SWITCH", 204 }, { "MANNER_MODE", 205 }, { "3D_MODE", 206 }, + { "CONTACTS", 207 }, + { "CALENDAR", 208 }, + { "MUSIC", 209 }, + { "CALCULATOR", 210 }, // NOTE: If you add a new keycode here you must also add it to several other files. // Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list. diff --git a/native/include/android/keycodes.h b/native/include/android/keycodes.h index 5d49775cb2c8..8414ff6eadc9 100644 --- a/native/include/android/keycodes.h +++ b/native/include/android/keycodes.h @@ -250,6 +250,10 @@ enum { AKEYCODE_LANGUAGE_SWITCH = 204, AKEYCODE_MANNER_MODE = 205, AKEYCODE_3D_MODE = 206, + AKEYCODE_CONTACTS = 207, + AKEYCODE_CALENDAR = 208, + AKEYCODE_MUSIC = 209, + AKEYCODE_CALCULATOR = 210, // NOTE: If you add a new keycode here you must also add it to several other files. // Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list. diff --git a/packages/SettingsProvider/res/xml/bookmarks.xml b/packages/SettingsProvider/res/xml/bookmarks.xml index 83229f410d59..454f4562a239 100644 --- a/packages/SettingsProvider/res/xml/bookmarks.xml +++ b/packages/SettingsProvider/res/xml/bookmarks.xml @@ -19,6 +19,7 @@ Bookmarks for vendor apps should be added to a bookmarks resource overlay; not here. Typical shortcuts (not necessarily defined here): + 'a': Calculator 'b': Browser 'c': Contacts 'e': Email @@ -32,27 +33,27 @@ --> <bookmarks> <bookmark - package="com.android.browser" - class="com.android.browser.BrowserActivity" + category="android.intent.category.APP_CALCULATOR" + shortcut="a" /> + <bookmark + category="android.intent.category.APP_BROWSER" shortcut="b" /> <bookmark - package="com.android.contacts" - class="com.android.contacts.activities.ContactsFrontDoor" + category="android.intent.category.APP_CONTACTS" shortcut="c" /> <bookmark - package="com.google.android.email" - class="com.android.email.activity.Welcome" + category="android.intent.category.APP_EMAIL" shortcut="e" /> <bookmark - package="com.google.android.calendar" - class="com.android.calendar.LaunchActivity" + category="android.intent.category.APP_CALENDAR" shortcut="l" /> <bookmark - package="com.android.music" - class="com.android.music.MusicBrowserActivity" + category="android.intent.category.APP_MAPS" + shortcut="m" /> + <bookmark + category="android.intent.category.APP_MUSIC" shortcut="p" /> <bookmark - package="com.android.mms" - class="com.android.mms.ui.ConversationList" + category="android.intent.category.APP_MESSAGING" shortcut="s" /> </bookmarks> diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java index aa08e64353d8..080d345e51d9 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java @@ -63,7 +63,7 @@ public class DatabaseHelper extends SQLiteOpenHelper { // database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion' // is properly propagated through your change. Not doing so will result in a loss of user // settings. - private static final int DATABASE_VERSION = 70; + private static final int DATABASE_VERSION = 71; private Context mContext; @@ -946,6 +946,12 @@ public class DatabaseHelper extends SQLiteOpenHelper { upgradeVersion = 70; } + if (upgradeVersion == 70) { + // Update all built-in bookmarks. Some of the package names have changed. + loadBookmarks(db); + upgradeVersion = 71; + } + // *** Remember to update DATABASE_VERSION above! if (upgradeVersion != currentVersion) { @@ -1086,16 +1092,11 @@ public class DatabaseHelper extends SQLiteOpenHelper { * Loads the default set of bookmarked shortcuts from an xml file. * * @param db The database to write the values into - * @param startingIndex The zero-based position at which bookmarks in this file should begin */ - private int loadBookmarks(SQLiteDatabase db, int startingIndex) { - Intent intent = new Intent(Intent.ACTION_MAIN, null); - intent.addCategory(Intent.CATEGORY_LAUNCHER); + private void loadBookmarks(SQLiteDatabase db) { ContentValues values = new ContentValues(); PackageManager packageManager = mContext.getPackageManager(); - int i = startingIndex; - try { XmlResourceParser parser = mContext.getResources().getXml(R.xml.bookmarks); XmlUtils.beginDocument(parser, "bookmarks"); @@ -1118,54 +1119,60 @@ public class DatabaseHelper extends SQLiteOpenHelper { String pkg = parser.getAttributeValue(null, "package"); String cls = parser.getAttributeValue(null, "class"); String shortcutStr = parser.getAttributeValue(null, "shortcut"); + String category = parser.getAttributeValue(null, "category"); int shortcutValue = shortcutStr.charAt(0); if (TextUtils.isEmpty(shortcutStr)) { Log.w(TAG, "Unable to get shortcut for: " + pkg + "/" + cls); + continue; } - ActivityInfo info = null; - ComponentName cn = new ComponentName(pkg, cls); - try { - info = packageManager.getActivityInfo(cn, 0); - } catch (PackageManager.NameNotFoundException e) { - String[] packages = packageManager.canonicalToCurrentPackageNames( - new String[] { pkg }); - cn = new ComponentName(packages[0], cls); + final Intent intent; + final String title; + if (pkg != null && cls != null) { + ActivityInfo info = null; + ComponentName cn = new ComponentName(pkg, cls); try { info = packageManager.getActivityInfo(cn, 0); - } catch (PackageManager.NameNotFoundException e1) { - Log.w(TAG, "Unable to add bookmark: " + pkg + "/" + cls, e); + } catch (PackageManager.NameNotFoundException e) { + String[] packages = packageManager.canonicalToCurrentPackageNames( + new String[] { pkg }); + cn = new ComponentName(packages[0], cls); + try { + info = packageManager.getActivityInfo(cn, 0); + } catch (PackageManager.NameNotFoundException e1) { + Log.w(TAG, "Unable to add bookmark: " + pkg + "/" + cls, e); + continue; + } } - } - - if (info != null) { + + intent = new Intent(Intent.ACTION_MAIN, null); + intent.addCategory(Intent.CATEGORY_LAUNCHER); intent.setComponent(cn); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - values.put(Settings.Bookmarks.INTENT, intent.toUri(0)); - values.put(Settings.Bookmarks.TITLE, - info.loadLabel(packageManager).toString()); - values.put(Settings.Bookmarks.SHORTCUT, shortcutValue); - db.insert("bookmarks", null, values); - i++; + title = info.loadLabel(packageManager).toString(); + } else if (category != null) { + intent = new Intent(Intent.ACTION_MAIN, null); + intent.addCategory(category); + title = ""; + } else { + Log.w(TAG, "Unable to add bookmark for shortcut " + shortcutStr + + ": missing package/class or category attributes"); + continue; } + + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + values.put(Settings.Bookmarks.INTENT, intent.toUri(0)); + values.put(Settings.Bookmarks.TITLE, title); + values.put(Settings.Bookmarks.SHORTCUT, shortcutValue); + db.delete("bookmarks", "shortcut = ?", + new String[] { Integer.toString(shortcutValue) }); + db.insert("bookmarks", null, values); } } catch (XmlPullParserException e) { Log.w(TAG, "Got execption parsing bookmarks.", e); } catch (IOException e) { Log.w(TAG, "Got execption parsing bookmarks.", e); } - - return i; - } - - /** - * Loads the default set of bookmark packages. - * - * @param db The database to write the values into - */ - private void loadBookmarks(SQLiteDatabase db) { - loadBookmarks(db, 0); } /** diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index fd9e095a5d0c..aea425b54d9e 100755 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -69,6 +69,7 @@ import android.util.DisplayMetrics; import android.util.EventLog; import android.util.Log; import android.util.Slog; +import android.util.SparseArray; import android.view.Gravity; import android.view.HapticFeedbackConstants; import android.view.IWindowManager; @@ -230,7 +231,30 @@ public class PhoneWindowManager implements WindowManagerPolicy { // Useful scan codes. private static final int SW_LID = 0x00; private static final int BTN_MOUSE = 0x110; - + + /* 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); + } + /** * Lock protecting internal state. Must not call out into window * manager with lock held. (This lock will be acquired in places @@ -1649,6 +1673,23 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } + // Handle application launch keys. + if (down && repeatCount == 0) { + String category = sApplicationLaunchKeyCategories.get(keyCode); + if (category != null) { + Intent intent = new Intent(Intent.ACTION_MAIN); + intent.addCategory(category); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + try { + mContext.startActivity(intent); + } 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 0; } |