ShortcutManager.java revision 6b53e8daa69cba1a2a5a7c95a01e37ce9c53226c
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 17package com.android.internal.policy.impl; 18 19import android.content.Context; 20import android.content.Intent; 21import android.database.ContentObserver; 22import android.database.Cursor; 23import android.os.Handler; 24import android.provider.Settings; 25import android.util.Log; 26import android.util.SparseArray; 27import android.view.KeyCharacterMap; 28 29import java.net.URISyntaxException; 30 31/** 32 * Manages quick launch shortcuts by: 33 * <li> Keeping the local copy in sync with the database (this is an observer) 34 * <li> Returning a shortcut-matching intent to clients 35 */ 36class ShortcutManager extends ContentObserver { 37 38 private static final String TAG = "ShortcutManager"; 39 40 private static final int COLUMN_SHORTCUT = 0; 41 private static final int COLUMN_INTENT = 1; 42 private static final String[] sProjection = new String[] { 43 Settings.Bookmarks.SHORTCUT, Settings.Bookmarks.INTENT 44 }; 45 46 private Context mContext; 47 private Cursor mCursor; 48 /** Map of a shortcut to its intent. */ 49 private SparseArray<Intent> mShortcutIntents; 50 51 public ShortcutManager(Context context, Handler handler) { 52 super(handler); 53 54 mContext = context; 55 mShortcutIntents = new SparseArray<Intent>(); 56 } 57 58 /** Observes the provider of shortcut+intents */ 59 public void observe() { 60 mCursor = mContext.getContentResolver().query( 61 Settings.Bookmarks.CONTENT_URI, sProjection, null, null, null); 62 mCursor.registerContentObserver(this); 63 updateShortcuts(); 64 } 65 66 @Override 67 public void onChange(boolean selfChange) { 68 updateShortcuts(); 69 } 70 71 private void updateShortcuts() { 72 Cursor c = mCursor; 73 if (!c.requery()) { 74 Log.e(TAG, "ShortcutObserver could not re-query shortcuts."); 75 return; 76 } 77 78 mShortcutIntents.clear(); 79 while (c.moveToNext()) { 80 int shortcut = c.getInt(COLUMN_SHORTCUT); 81 if (shortcut == 0) continue; 82 String intentURI = c.getString(COLUMN_INTENT); 83 Intent intent = null; 84 try { 85 intent = Intent.getIntent(intentURI); 86 } catch (URISyntaxException e) { 87 Log.w(TAG, "Intent URI for shortcut invalid.", e); 88 } 89 if (intent == null) continue; 90 mShortcutIntents.put(shortcut, intent); 91 } 92 } 93 94 /** 95 * Gets the shortcut intent for a given keycode+modifier. Make sure you 96 * strip whatever modifier is used for invoking shortcuts (for example, 97 * if 'Sym+A' should invoke a shortcut on 'A', you should strip the 98 * 'Sym' bit from the modifiers before calling this method. 99 * <p> 100 * This will first try an exact match (with modifiers), and then try a 101 * match without modifiers (primary character on a key). 102 * 103 * @param keyCode The keycode of the key pushed. 104 * @param modifiers The modifiers without any that are used for chording 105 * to invoke a shortcut. 106 * @return The intent that matches the shortcut, or null if not found. 107 */ 108 public Intent getIntent(int keyCode, int modifiers) { 109 KeyCharacterMap kcm = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD); 110 // First try the exact keycode (with modifiers) 111 int shortcut = kcm.get(keyCode, modifiers); 112 Intent intent = shortcut != 0 ? mShortcutIntents.get(shortcut) : null; 113 if (intent != null) return intent; 114 115 // Next try the keycode without modifiers (the primary character on that key) 116 shortcut = Character.toLowerCase(kcm.get(keyCode, 0)); 117 return shortcut != 0 ? mShortcutIntents.get(shortcut) : null; 118 } 119 120} 121