Remove LiveFolders when corresponding package is uninstalled.
Bug #2298872
diff --git a/src/com/android/launcher2/LauncherModel.java b/src/com/android/launcher2/LauncherModel.java
index cafb9fa..29de3f7 100644
--- a/src/com/android/launcher2/LauncherModel.java
+++ b/src/com/android/launcher2/LauncherModel.java
@@ -18,18 +18,21 @@
import android.content.BroadcastReceiver;
import android.content.ComponentName;
+import android.content.ContentProviderClient;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Intent;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
+import android.content.pm.ProviderInfo;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
+import android.os.RemoteException;
import android.util.Log;
import android.os.Process;
import android.os.SystemClock;
@@ -602,6 +605,7 @@
final Context context = mContext;
final ContentResolver contentResolver = context.getContentResolver();
final PackageManager manager = context.getPackageManager();
+ final boolean isSafeMode = manager.isSafeMode();
/* TODO
if (mLocaleChanged) {
@@ -613,6 +617,8 @@
mAppWidgets.clear();
mFolders.clear();
+ final ArrayList<Long> itemsToRemove = new ArrayList<Long>();
+
final Cursor c = contentResolver.query(
LauncherSettings.Favorites.CONTENT_URI, null, null, null, null);
@@ -733,40 +739,50 @@
break;
case LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER:
-
id = c.getLong(idIndex);
- LiveFolderInfo liveFolderInfo = findOrMakeLiveFolder(mFolders, id);
+ Uri uri = Uri.parse(c.getString(uriIndex));
- intentDescription = c.getString(intentIndex);
- intent = null;
- if (intentDescription != null) {
- try {
- intent = Intent.parseUri(intentDescription, 0);
- } catch (URISyntaxException e) {
- // Ignore, a live folder might not have a base intent
+ // Make sure the live folder exists
+ final ProviderInfo providerInfo =
+ context.getPackageManager().resolveContentProvider(
+ uri.getAuthority(), 0);
+
+ if (providerInfo == null && !isSafeMode) {
+ itemsToRemove.add(id);
+ } else {
+ LiveFolderInfo liveFolderInfo = findOrMakeLiveFolder(mFolders, id);
+
+ intentDescription = c.getString(intentIndex);
+ intent = null;
+ if (intentDescription != null) {
+ try {
+ intent = Intent.parseUri(intentDescription, 0);
+ } catch (URISyntaxException e) {
+ // Ignore, a live folder might not have a base intent
+ }
}
+
+ liveFolderInfo.title = c.getString(titleIndex);
+ liveFolderInfo.id = id;
+ liveFolderInfo.uri = uri;
+ container = c.getInt(containerIndex);
+ liveFolderInfo.container = container;
+ liveFolderInfo.screen = c.getInt(screenIndex);
+ liveFolderInfo.cellX = c.getInt(cellXIndex);
+ liveFolderInfo.cellY = c.getInt(cellYIndex);
+ liveFolderInfo.baseIntent = intent;
+ liveFolderInfo.displayMode = c.getInt(displayModeIndex);
+
+ loadLiveFolderIcon(context, c, iconTypeIndex, iconPackageIndex,
+ iconResourceIndex, liveFolderInfo);
+
+ switch (container) {
+ case LauncherSettings.Favorites.CONTAINER_DESKTOP:
+ mItems.add(liveFolderInfo);
+ break;
+ }
+ mFolders.put(liveFolderInfo.id, liveFolderInfo);
}
-
- liveFolderInfo.title = c.getString(titleIndex);
- liveFolderInfo.id = id;
- container = c.getInt(containerIndex);
- liveFolderInfo.container = container;
- liveFolderInfo.screen = c.getInt(screenIndex);
- liveFolderInfo.cellX = c.getInt(cellXIndex);
- liveFolderInfo.cellY = c.getInt(cellYIndex);
- liveFolderInfo.uri = Uri.parse(c.getString(uriIndex));
- liveFolderInfo.baseIntent = intent;
- liveFolderInfo.displayMode = c.getInt(displayModeIndex);
-
- loadLiveFolderIcon(context, c, iconTypeIndex, iconPackageIndex,
- iconResourceIndex, liveFolderInfo);
-
- switch (container) {
- case LauncherSettings.Favorites.CONTAINER_DESKTOP:
- mItems.add(liveFolderInfo);
- break;
- }
- mFolders.put(liveFolderInfo.id, liveFolderInfo);
break;
case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:
@@ -798,6 +814,25 @@
} finally {
c.close();
}
+
+ if (itemsToRemove.size() > 0) {
+ ContentProviderClient client = contentResolver.acquireContentProviderClient(
+ LauncherSettings.Favorites.CONTENT_URI);
+ // Remove dead items
+ for (long id : itemsToRemove) {
+ if (DEBUG_LOADERS) {
+ Log.d(TAG, "Removed id = " + id);
+ }
+ // Don't notify content observers
+ try {
+ client.delete(LauncherSettings.Favorites.getContentUri(id, false),
+ null, null);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Could not remove id = " + id);
+ }
+ }
+ }
+
if (DEBUG_LOADERS) {
Log.d(TAG, "loaded workspace in " + (SystemClock.uptimeMillis()-t) + "ms");
}
@@ -956,7 +991,7 @@
private void bindAllApps() {
synchronized (mLock) {
final ArrayList<ApplicationInfo> results
- = (ArrayList<ApplicationInfo>)mAllAppsList.data.clone();
+ = (ArrayList<ApplicationInfo>) mAllAppsList.data.clone();
// We're adding this now, so clear out this so we don't re-send them.
mAllAppsList.added = new ArrayList<ApplicationInfo>();
mHandler.post(new Runnable() {
@@ -971,7 +1006,7 @@
if (DEBUG_LOADERS) {
Log.d(TAG, "bound app " + count + " icons in "
- + (SystemClock.uptimeMillis()-t) + "ms");
+ + (SystemClock.uptimeMillis() - t) + "ms");
}
}
});