From 4e871a217b286775dc6c07feb6d9f1d7a7e914be Mon Sep 17 00:00:00 2001 From: Bjorn Bringert Date: Thu, 17 Oct 2013 13:50:20 +0100 Subject: Fix ConcurrentModificationException in InstallShortcutReceiver Before, if two shortcuts were added, and then the package for one of them removed, all while Launcher wasn't visible, Launcher crashed. Bug: 11264076 Change-Id: I892c190101389aa42d84d66960f5b6f6f43f2dfc --- .../android/launcher3/InstallShortcutReceiver.java | 29 +++++++++++++++------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/com/android/launcher3/InstallShortcutReceiver.java b/src/com/android/launcher3/InstallShortcutReceiver.java index 821c15f52..7df73b1f6 100644 --- a/src/com/android/launcher3/InstallShortcutReceiver.java +++ b/src/com/android/launcher3/InstallShortcutReceiver.java @@ -36,6 +36,9 @@ import java.util.Set; import org.json.*; public class InstallShortcutReceiver extends BroadcastReceiver { + private static final String TAG = "InstallShortcutReceiver"; + private static final boolean DBG = false; + public static final String ACTION_INSTALL_SHORTCUT = "com.android.launcher.action.INSTALL_SHORTCUT"; @@ -94,10 +97,11 @@ public class InstallShortcutReceiver extends BroadcastReceiver { } json = json.endObject(); SharedPreferences.Editor editor = sharedPrefs.edit(); + if (DBG) Log.d(TAG, "Adding to APPS_PENDING_INSTALL: " + json); addToStringSet(sharedPrefs, editor, APPS_PENDING_INSTALL, json.toString()); editor.commit(); } catch (org.json.JSONException e) { - Log.d("InstallShortcutReceiver", "Exception when adding shortcut: " + e); + Log.d(TAG, "Exception when adding shortcut: " + e); } } } @@ -106,9 +110,15 @@ public class InstallShortcutReceiver extends BroadcastReceiver { ArrayList packageNames) { synchronized(sLock) { Set strings = sharedPrefs.getStringSet(APPS_PENDING_INSTALL, null); + if (DBG) { + Log.d(TAG, "APPS_PENDING_INSTALL: " + strings + + ", removing packages: " + packageNames); + } if (strings != null) { Set newStrings = new HashSet(strings); - for (String json : newStrings) { + Iterator newStringsIter = newStrings.iterator(); + while (newStringsIter.hasNext()) { + String json = newStringsIter.next(); try { JSONObject object = (JSONObject) new JSONTokener(json).nextValue(); Intent launchIntent = Intent.parseUri(object.getString(LAUNCH_INTENT_KEY), 0); @@ -117,12 +127,12 @@ public class InstallShortcutReceiver extends BroadcastReceiver { pn = launchIntent.getComponent().getPackageName(); } if (packageNames.contains(pn)) { - newStrings.remove(json); + newStringsIter.remove(); } } catch (org.json.JSONException e) { - Log.d("InstallShortcutReceiver", "Exception reading shortcut to remove: " + e); + Log.d(TAG, "Exception reading shortcut to remove: " + e); } catch (java.net.URISyntaxException e) { - Log.d("InstallShortcutReceiver", "Exception reading shortcut to remove: " + e); + Log.d(TAG, "Exception reading shortcut to remove: " + e); } } sharedPrefs.edit().putStringSet(APPS_PENDING_INSTALL, @@ -135,6 +145,7 @@ public class InstallShortcutReceiver extends BroadcastReceiver { SharedPreferences sharedPrefs) { synchronized(sLock) { Set strings = sharedPrefs.getStringSet(APPS_PENDING_INSTALL, null); + if (DBG) Log.d(TAG, "Getting and clearing APPS_PENDING_INSTALL: " + strings); if (strings == null) { return new ArrayList(); } @@ -167,11 +178,9 @@ public class InstallShortcutReceiver extends BroadcastReceiver { new PendingInstallShortcutInfo(data, name, launchIntent); infos.add(info); } catch (org.json.JSONException e) { - Log.d("InstallShortcutReceiver", - "Exception reading shortcut to add: " + e); + Log.d(TAG, "Exception reading shortcut to add: " + e); } catch (java.net.URISyntaxException e) { - Log.d("InstallShortcutReceiver", - "Exception reading shortcut to add: " + e); + Log.d(TAG, "Exception reading shortcut to add: " + e); } } sharedPrefs.edit().putStringSet(APPS_PENDING_INSTALL, new HashSet()).commit(); @@ -203,6 +212,8 @@ public class InstallShortcutReceiver extends BroadcastReceiver { return; } + if (DBG) Log.d(TAG, "Got INSTALL_SHORTCUT: " + data.toUri(0)); + Intent intent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT); if (intent == null) { return; -- cgit v1.2.3