diff options
Diffstat (limited to 'src/com/android/launcher3/AppWidgetsRestoredReceiver.java')
-rw-r--r-- | src/com/android/launcher3/AppWidgetsRestoredReceiver.java | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/src/com/android/launcher3/AppWidgetsRestoredReceiver.java b/src/com/android/launcher3/AppWidgetsRestoredReceiver.java new file mode 100644 index 000000000..880aaf1ec --- /dev/null +++ b/src/com/android/launcher3/AppWidgetsRestoredReceiver.java @@ -0,0 +1,94 @@ +package com.android.launcher3; + +import android.appwidget.AppWidgetHost; +import android.appwidget.AppWidgetManager; +import android.appwidget.AppWidgetProviderInfo; +import android.content.BroadcastReceiver; +import android.content.ContentResolver; +import android.content.ContentValues; +import android.content.Context; +import android.content.Intent; +import android.database.Cursor; +import android.os.AsyncTask; +import android.util.Log; + +import com.android.launcher3.LauncherSettings.Favorites; + +import java.util.ArrayList; +import java.util.List; + +public class AppWidgetsRestoredReceiver extends BroadcastReceiver { + + private static final String TAG = "AppWidgetsRestoredReceiver"; + + @Override + public void onReceive(Context context, Intent intent) { + if (AppWidgetManager.ACTION_APPWIDGET_HOST_RESTORED.equals(intent.getAction())) { + int[] oldIds = intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_OLD_IDS); + int[] newIds = intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS); + if (oldIds.length == newIds.length) { + restoreAppWidgetIds(context, oldIds, newIds); + } else { + Log.e(TAG, "Invalid host restored received"); + } + } + } + + /** + * Updates the app widgets whose id has changed during the restore process. + */ + static void restoreAppWidgetIds(Context context, int[] oldWidgetIds, int[] newWidgetIds) { + final ContentResolver cr = context.getContentResolver(); + final List<Integer> idsToRemove = new ArrayList<Integer>(); + final AppWidgetManager widgets = AppWidgetManager.getInstance(context); + + for (int i = 0; i < oldWidgetIds.length; i++) { + Log.i(TAG, "Widget state restore id " + oldWidgetIds[i] + " => " + newWidgetIds[i]); + + final AppWidgetProviderInfo provider = widgets.getAppWidgetInfo(newWidgetIds[i]); + final int state; + if (LauncherModel.isValidProvider(provider)) { + state = LauncherAppWidgetInfo.RESTORE_COMPLETED; + } else { + state = LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY; + } + + ContentValues values = new ContentValues(); + values.put(LauncherSettings.Favorites.APPWIDGET_ID, newWidgetIds[i]); + values.put(LauncherSettings.Favorites.RESTORED, state); + + String[] widgetIdParams = new String[] { Integer.toString(oldWidgetIds[i]) }; + + int result = cr.update(Favorites.CONTENT_URI, values, + "appWidgetId=? and (restored & 1) = 1", widgetIdParams); + if (result == 0) { + Cursor cursor = cr.query(Favorites.CONTENT_URI, + new String[] {Favorites.APPWIDGET_ID}, + "appWidgetId=?", widgetIdParams, null); + try { + if (!cursor.moveToFirst()) { + // The widget no long exists. + idsToRemove.add(newWidgetIds[i]); + } + } finally { + cursor.close(); + } + } + } + // Unregister the widget IDs which are not present on the workspace. This could happen + // when a widget place holder is removed from workspace, before this method is called. + if (!idsToRemove.isEmpty()) { + final AppWidgetHost appWidgetHost = + new AppWidgetHost(context, Launcher.APPWIDGET_HOST_ID); + new AsyncTask<Void, Void, Void>() { + public Void doInBackground(Void ... args) { + for (Integer id : idsToRemove) { + appWidgetHost.deleteAppWidgetId(id); + Log.e(TAG, "Widget no longer present, appWidgetId=" + id); + } + return null; + } + }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null); + } + } +} |