The Android Open Source Project | 31dd503 | 2009-03-03 19:32:27 -0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2008 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 | |
Daniel Sandler | 325dc23 | 2013-06-05 22:57:57 -0400 | [diff] [blame] | 17 | package com.android.launcher3; |
The Android Open Source Project | 31dd503 | 2009-03-03 19:32:27 -0800 | [diff] [blame] | 18 | |
| 19 | import android.content.BroadcastReceiver; |
Winson Chung | f561bdf | 2012-05-03 11:20:19 -0700 | [diff] [blame] | 20 | import android.content.ContentResolver; |
The Android Open Source Project | 31dd503 | 2009-03-03 19:32:27 -0800 | [diff] [blame] | 21 | import android.content.Context; |
| 22 | import android.content.Intent; |
Winson Chung | a241375 | 2012-04-03 14:22:34 -0700 | [diff] [blame] | 23 | import android.content.SharedPreferences; |
The Android Open Source Project | 31dd503 | 2009-03-03 19:32:27 -0800 | [diff] [blame] | 24 | import android.database.Cursor; |
| 25 | import android.net.Uri; |
Romain Guy | d93a7d1 | 2009-03-24 21:17:50 -0700 | [diff] [blame] | 26 | import android.widget.Toast; |
The Android Open Source Project | 31dd503 | 2009-03-03 19:32:27 -0800 | [diff] [blame] | 27 | |
Winson Chung | f561bdf | 2012-05-03 11:20:19 -0700 | [diff] [blame] | 28 | import java.net.URISyntaxException; |
| 29 | import java.util.ArrayList; |
| 30 | import java.util.HashSet; |
| 31 | import java.util.Iterator; |
| 32 | import java.util.Set; |
| 33 | |
The Android Open Source Project | 31dd503 | 2009-03-03 19:32:27 -0800 | [diff] [blame] | 34 | public class UninstallShortcutReceiver extends BroadcastReceiver { |
Romain Guy | 51ed5b9 | 2009-06-17 10:20:34 -0700 | [diff] [blame] | 35 | private static final String ACTION_UNINSTALL_SHORTCUT = |
Daniel Sandler | 325dc23 | 2013-06-05 22:57:57 -0400 | [diff] [blame] | 36 | "com.android.launcher3.action.UNINSTALL_SHORTCUT"; |
Romain Guy | 51ed5b9 | 2009-06-17 10:20:34 -0700 | [diff] [blame] | 37 | |
Winson Chung | f561bdf | 2012-05-03 11:20:19 -0700 | [diff] [blame] | 38 | // The set of shortcuts that are pending uninstall |
| 39 | private static ArrayList<PendingUninstallShortcutInfo> mUninstallQueue = |
| 40 | new ArrayList<PendingUninstallShortcutInfo>(); |
| 41 | |
| 42 | // Determines whether to defer uninstalling shortcuts immediately until |
| 43 | // disableAndFlushUninstallQueue() is called. |
| 44 | private static boolean mUseUninstallQueue = false; |
| 45 | |
| 46 | private static class PendingUninstallShortcutInfo { |
| 47 | Intent data; |
| 48 | |
| 49 | public PendingUninstallShortcutInfo(Intent rawData) { |
| 50 | data = rawData; |
| 51 | } |
| 52 | } |
| 53 | |
The Android Open Source Project | 31dd503 | 2009-03-03 19:32:27 -0800 | [diff] [blame] | 54 | public void onReceive(Context context, Intent data) { |
Romain Guy | 51ed5b9 | 2009-06-17 10:20:34 -0700 | [diff] [blame] | 55 | if (!ACTION_UNINSTALL_SHORTCUT.equals(data.getAction())) { |
| 56 | return; |
| 57 | } |
Winson Chung | f561bdf | 2012-05-03 11:20:19 -0700 | [diff] [blame] | 58 | |
| 59 | PendingUninstallShortcutInfo info = new PendingUninstallShortcutInfo(data); |
| 60 | if (mUseUninstallQueue) { |
| 61 | mUninstallQueue.add(info); |
| 62 | } else { |
| 63 | processUninstallShortcut(context, info); |
| 64 | } |
| 65 | } |
| 66 | |
| 67 | static void enableUninstallQueue() { |
| 68 | mUseUninstallQueue = true; |
| 69 | } |
| 70 | |
| 71 | static void disableAndFlushUninstallQueue(Context context) { |
| 72 | mUseUninstallQueue = false; |
| 73 | Iterator<PendingUninstallShortcutInfo> iter = mUninstallQueue.iterator(); |
| 74 | while (iter.hasNext()) { |
| 75 | processUninstallShortcut(context, iter.next()); |
| 76 | iter.remove(); |
| 77 | } |
| 78 | } |
| 79 | |
| 80 | private static void processUninstallShortcut(Context context, |
| 81 | PendingUninstallShortcutInfo pendingInfo) { |
Winson Chung | f561bdf | 2012-05-03 11:20:19 -0700 | [diff] [blame] | 82 | final Intent data = pendingInfo.data; |
| 83 | |
Daniel Sandler | cc8befa | 2013-06-11 14:45:48 -0400 | [diff] [blame] | 84 | LauncherAppState app = LauncherAppState.getInstance(); |
Daniel Sandler | e4f9891 | 2013-06-25 15:13:26 -0400 | [diff] [blame] | 85 | synchronized (app) { // TODO: make removeShortcut internally threadsafe |
Winson Chung | 997a923 | 2013-07-24 15:33:46 -0700 | [diff] [blame^] | 86 | removeShortcut(context, data); |
Winson Chung | a241375 | 2012-04-03 14:22:34 -0700 | [diff] [blame] | 87 | } |
| 88 | } |
| 89 | |
Winson Chung | 997a923 | 2013-07-24 15:33:46 -0700 | [diff] [blame^] | 90 | private static void removeShortcut(Context context, Intent data) { |
The Android Open Source Project | 31dd503 | 2009-03-03 19:32:27 -0800 | [diff] [blame] | 91 | Intent intent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT); |
| 92 | String name = data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME); |
| 93 | boolean duplicate = data.getBooleanExtra(Launcher.EXTRA_SHORTCUT_DUPLICATE, true); |
| 94 | |
| 95 | if (intent != null && name != null) { |
| 96 | final ContentResolver cr = context.getContentResolver(); |
| 97 | Cursor c = cr.query(LauncherSettings.Favorites.CONTENT_URI, |
Romain Guy | 73b979d | 2009-06-09 12:57:21 -0700 | [diff] [blame] | 98 | new String[] { LauncherSettings.Favorites._ID, LauncherSettings.Favorites.INTENT }, |
The Android Open Source Project | 31dd503 | 2009-03-03 19:32:27 -0800 | [diff] [blame] | 99 | LauncherSettings.Favorites.TITLE + "=?", new String[] { name }, null); |
| 100 | |
| 101 | final int intentIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.INTENT); |
| 102 | final int idIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites._ID); |
| 103 | |
| 104 | boolean changed = false; |
| 105 | |
| 106 | try { |
| 107 | while (c.moveToNext()) { |
| 108 | try { |
Romain Guy | 1ce1a24 | 2009-06-23 17:34:54 -0700 | [diff] [blame] | 109 | if (intent.filterEquals(Intent.parseUri(c.getString(intentIndex), 0))) { |
The Android Open Source Project | 31dd503 | 2009-03-03 19:32:27 -0800 | [diff] [blame] | 110 | final long id = c.getLong(idIndex); |
| 111 | final Uri uri = LauncherSettings.Favorites.getContentUri(id, false); |
| 112 | cr.delete(uri, null, null); |
| 113 | changed = true; |
| 114 | if (!duplicate) { |
| 115 | break; |
| 116 | } |
| 117 | } |
| 118 | } catch (URISyntaxException e) { |
| 119 | // Ignore |
| 120 | } |
| 121 | } |
| 122 | } finally { |
| 123 | c.close(); |
| 124 | } |
| 125 | |
Romain Guy | d93a7d1 | 2009-03-24 21:17:50 -0700 | [diff] [blame] | 126 | if (changed) { |
| 127 | cr.notifyChange(LauncherSettings.Favorites.CONTENT_URI, null); |
| 128 | Toast.makeText(context, context.getString(R.string.shortcut_uninstalled, name), |
| 129 | Toast.LENGTH_SHORT).show(); |
| 130 | } |
The Android Open Source Project | 31dd503 | 2009-03-03 19:32:27 -0800 | [diff] [blame] | 131 | } |
| 132 | } |
| 133 | } |