summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/com/android/launcher3/LauncherModel.java4
-rw-r--r--src/com/android/launcher3/LauncherProvider.java83
-rw-r--r--src/com/android/launcher3/LauncherSettings.java2
3 files changed, 66 insertions, 23 deletions
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index 4cc75acd0..5938fba38 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -1236,6 +1236,10 @@ public class LauncherModel extends BroadcastReceiver
sBgDataModel.folders.remove(folderId);
sBgDataModel.itemsIdMap.remove(folderId);
}
+
+ // Remove any ghost widgets
+ LauncherSettings.Settings.call(contentResolver,
+ LauncherSettings.Settings.METHOD_REMOVE_GHOST_WIDGETS);
}
// Unpin shortcuts that don't exist on the workspace.
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index d2574fa6f..03ca24226 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -65,10 +65,11 @@ import com.android.launcher3.util.Thunk;
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.lang.reflect.Method;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.Locale;
+import java.util.HashSet;
public class LauncherProvider extends ContentProvider {
private static final String TAG = "LauncherProvider";
@@ -83,7 +84,7 @@ public class LauncherProvider extends ContentProvider {
* overtime. These must be backwards compatible, else we risk breaking old devices during
* restore or binary version downgrade.
*/
- private static final int DATA_VERSION = 2;
+ private static final int DATA_VERSION = 3;
private static final String PREF_KEY_DATA_VERISON = "provider_data_version";
@@ -260,10 +261,11 @@ public class LauncherProvider extends ContentProvider {
if (cn != null) {
try {
- int appWidgetId = new AppWidgetHost(getContext(), Launcher.APPWIDGET_HOST_ID)
- .allocateAppWidgetId();
+ AppWidgetHost widgetHost = mOpenHelper.newLauncherWidgetHost();
+ int appWidgetId = widgetHost.allocateAppWidgetId();
values.put(LauncherSettings.Favorites.APPWIDGET_ID, appWidgetId);
if (!appWidgetManager.bindAppWidgetIdIfAllowed(appWidgetId,cn)) {
+ widgetHost.deleteAppWidgetId(appWidgetId);
return false;
}
} catch (RuntimeException e) {
@@ -345,23 +347,7 @@ public class LauncherProvider extends ContentProvider {
if (Binder.getCallingPid() != Process.myPid()
&& Favorites.TABLE_NAME.equalsIgnoreCase(args.table)) {
- String widgetSelection = TextUtils.isEmpty(args.where) ? "1=1" : args.where;
- widgetSelection = String.format(Locale.ENGLISH, "%1$s = %2$d AND ( %3$s )",
- Favorites.ITEM_TYPE, Favorites.ITEM_TYPE_APPWIDGET, widgetSelection);
- try (Cursor c = db.query(Favorites.TABLE_NAME, new String[] { Favorites.APPWIDGET_ID },
- widgetSelection, args.args, null, null, null)) {
- AppWidgetHost host = new AppWidgetHost(getContext(), Launcher.APPWIDGET_HOST_ID);
- while (c.moveToNext()) {
- int widgetId = c.getInt(0);
- if (widgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
- try {
- host.deleteAppWidgetId(widgetId);
- } catch (RuntimeException e) {
- Log.e(TAG, "Error deleting widget id " + widgetId, e);
- }
- }
- }
- }
+ mOpenHelper.removeGhostWidgets(mOpenHelper.getWritableDatabase());
}
int count = db.delete(args.table, args.where, args.args);
if (count > 0) {
@@ -439,6 +425,10 @@ public class LauncherProvider extends ContentProvider {
loadDefaultFavoritesIfNecessary();
return null;
}
+ case LauncherSettings.Settings.METHOD_REMOVE_GHOST_WIDGETS: {
+ mOpenHelper.removeGhostWidgets(mOpenHelper.getWritableDatabase());
+ return null;
+ }
}
return null;
}
@@ -507,7 +497,7 @@ public class LauncherProvider extends ContentProvider {
if (sp.getBoolean(EMPTY_DATABASE_CREATED, false)) {
Log.d(TAG, "loading default workspace");
- AppWidgetHost widgetHost = new AppWidgetHost(getContext(), Launcher.APPWIDGET_HOST_ID);
+ AppWidgetHost widgetHost = mOpenHelper.newLauncherWidgetHost();
AutoInstallsLayout loader = createWorkspaceLoaderFromAppRestriction(widgetHost);
if (loader == null) {
loader = AutoInstallsLayout.get(getContext(),widgetHost, mOpenHelper);
@@ -657,7 +647,7 @@ public class LauncherProvider extends ContentProvider {
protected void onEmptyDbCreated() {
// Database was just created, so wipe any previous widgets
if (mWidgetHostResetHandler != null) {
- new AppWidgetHost(mContext, Launcher.APPWIDGET_HOST_ID).deleteHost();
+ newLauncherWidgetHost().deleteHost();
mWidgetHostResetHandler.sendEmptyMessage(
ChangeListenerWrapper.MSG_APP_WIDGET_HOST_RESET);
}
@@ -763,6 +753,8 @@ public class LauncherProvider extends ContentProvider {
}
}
case 2:
+ removeGhostWidgets(db);
+ case 3:
// data updated
return;
}
@@ -904,6 +896,47 @@ public class LauncherProvider extends ContentProvider {
}
/**
+ * Removes widgets which are registered to the Launcher's host, but are not present
+ * in our model.
+ */
+ public void removeGhostWidgets(SQLiteDatabase db) {
+ // Get all existing widget ids.
+ final AppWidgetHost host = newLauncherWidgetHost();
+ final int[] allWidgets;
+ try {
+ Method getter = AppWidgetHost.class.getDeclaredMethod("getAppWidgetIds");
+ getter.setAccessible(true);
+ allWidgets = (int[]) getter.invoke(host);
+ } catch (Exception e) {
+ Log.e(TAG, "getAppWidgetIds not supported", e);
+ return;
+ }
+ try {
+ Cursor c = db.query(Favorites.TABLE_NAME,
+ new String[] {Favorites.APPWIDGET_ID },
+ "itemType=" + Favorites.ITEM_TYPE_APPWIDGET, null, null, null, null);
+ HashSet<Integer> validWidgets = new HashSet<>();
+ while (c.moveToNext()) {
+ validWidgets.add(c.getInt(0));
+ }
+ c.close();
+
+ for (int widgetId : allWidgets) {
+ if (!validWidgets.contains(widgetId)) {
+ try {
+ FileLog.d(TAG, "Deleting invalid widget " + widgetId);
+ host.deleteAppWidgetId(widgetId);
+ } catch (RuntimeException e) {
+ // Ignore
+ }
+ }
+ }
+ } catch (SQLException ex) {
+ Log.w(TAG, "Error getting widgets list", ex);
+ }
+ }
+
+ /**
* Replaces all shortcuts of type {@link Favorites#ITEM_TYPE_SHORTCUT} which have a valid
* launcher activity target with {@link Favorites#ITEM_TYPE_APPLICATION}.
*/
@@ -1072,6 +1105,10 @@ public class LauncherProvider extends ContentProvider {
return mMaxItemId;
}
+ public AppWidgetHost newLauncherWidgetHost() {
+ return new AppWidgetHost(mContext, Launcher.APPWIDGET_HOST_ID);
+ }
+
@Override
public long insertAndCheck(SQLiteDatabase db, ContentValues values) {
return dbInsertAndCheck(this, db, Favorites.TABLE_NAME, null, values);
diff --git a/src/com/android/launcher3/LauncherSettings.java b/src/com/android/launcher3/LauncherSettings.java
index 3f047f511..87f62eb01 100644
--- a/src/com/android/launcher3/LauncherSettings.java
+++ b/src/com/android/launcher3/LauncherSettings.java
@@ -309,6 +309,8 @@ public class LauncherSettings {
public static final String EXTRA_EXTRACTED_COLORS = "extra_extractedColors";
public static final String EXTRA_WALLPAPER_ID = "extra_wallpaperId";
+ public static final String METHOD_REMOVE_GHOST_WIDGETS = "remove_ghost_widgets";
+
public static final String EXTRA_VALUE = "value";
public static Bundle call(ContentResolver cr, String method) {