/policy/src/com/android/internal/policy/impl/ShortcutManager.java

https://github.com/aizuzi/platform_frameworks_base · Java · 130 lines · 73 code · 18 blank · 39 comment · 12 complexity · 558234b1b65721f0cd8d7070c2e3b848 MD5 · raw file

  1. /*
  2. * Copyright (C) 2007 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package com.android.internal.policy.impl;
  17. import android.content.Context;
  18. import android.content.Intent;
  19. import android.database.ContentObserver;
  20. import android.database.Cursor;
  21. import android.os.Handler;
  22. import android.provider.Settings;
  23. import android.util.Log;
  24. import android.util.SparseArray;
  25. import android.view.KeyCharacterMap;
  26. import android.view.KeyEvent;
  27. import java.net.URISyntaxException;
  28. /**
  29. * Manages quick launch shortcuts by:
  30. * <li> Keeping the local copy in sync with the database (this is an observer)
  31. * <li> Returning a shortcut-matching intent to clients
  32. */
  33. class ShortcutManager extends ContentObserver {
  34. private static final String TAG = "ShortcutManager";
  35. private static final int COLUMN_SHORTCUT = 0;
  36. private static final int COLUMN_INTENT = 1;
  37. private static final String[] sProjection = new String[] {
  38. Settings.Bookmarks.SHORTCUT, Settings.Bookmarks.INTENT
  39. };
  40. private Context mContext;
  41. private Cursor mCursor;
  42. /** Map of a shortcut to its intent. */
  43. private SparseArray<Intent> mShortcutIntents;
  44. public ShortcutManager(Context context, Handler handler) {
  45. super(handler);
  46. mContext = context;
  47. mShortcutIntents = new SparseArray<Intent>();
  48. }
  49. /** Observes the provider of shortcut+intents */
  50. public void observe() {
  51. mCursor = mContext.getContentResolver().query(
  52. Settings.Bookmarks.CONTENT_URI, sProjection, null, null, null);
  53. mCursor.registerContentObserver(this);
  54. updateShortcuts();
  55. }
  56. @Override
  57. public void onChange(boolean selfChange) {
  58. updateShortcuts();
  59. }
  60. private void updateShortcuts() {
  61. Cursor c = mCursor;
  62. if (!c.requery()) {
  63. Log.e(TAG, "ShortcutObserver could not re-query shortcuts.");
  64. return;
  65. }
  66. mShortcutIntents.clear();
  67. while (c.moveToNext()) {
  68. int shortcut = c.getInt(COLUMN_SHORTCUT);
  69. if (shortcut == 0) continue;
  70. String intentURI = c.getString(COLUMN_INTENT);
  71. Intent intent = null;
  72. try {
  73. intent = Intent.getIntent(intentURI);
  74. } catch (URISyntaxException e) {
  75. Log.w(TAG, "Intent URI for shortcut invalid.", e);
  76. }
  77. if (intent == null) continue;
  78. mShortcutIntents.put(shortcut, intent);
  79. }
  80. }
  81. /**
  82. * Gets the shortcut intent for a given keycode+modifier. Make sure you
  83. * strip whatever modifier is used for invoking shortcuts (for example,
  84. * if 'Sym+A' should invoke a shortcut on 'A', you should strip the
  85. * 'Sym' bit from the modifiers before calling this method.
  86. * <p>
  87. * This will first try an exact match (with modifiers), and then try a
  88. * match without modifiers (primary character on a key).
  89. *
  90. * @param kcm The key character map of the device on which the key was pressed.
  91. * @param keyCode The key code.
  92. * @param metaState The meta state, omitting any modifiers that were used
  93. * to invoke the shortcut.
  94. * @return The intent that matches the shortcut, or null if not found.
  95. */
  96. public Intent getIntent(KeyCharacterMap kcm, int keyCode, int metaState) {
  97. Intent intent = null;
  98. // First try the exact keycode (with modifiers).
  99. int shortcut = kcm.get(keyCode, metaState);
  100. if (shortcut != 0) {
  101. intent = mShortcutIntents.get(shortcut);
  102. }
  103. // Next try the primary character on that key.
  104. if (intent == null) {
  105. shortcut = Character.toLowerCase(kcm.getDisplayLabel(keyCode));
  106. if (shortcut != 0) {
  107. intent = mShortcutIntents.get(shortcut);
  108. }
  109. }
  110. return intent;
  111. }
  112. }