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