Home | History | Annotate | Download | only in launcher3
      1 package com.android.launcher3;
      2 
      3 import android.appwidget.AppWidgetHost;
      4 import android.appwidget.AppWidgetManager;
      5 import android.appwidget.AppWidgetProviderInfo;
      6 import android.content.BroadcastReceiver;
      7 import android.content.ContentResolver;
      8 import android.content.ContentValues;
      9 import android.content.Context;
     10 import android.content.Intent;
     11 import android.database.Cursor;
     12 import android.os.AsyncTask;
     13 import android.util.Log;
     14 
     15 import com.android.launcher3.LauncherSettings.Favorites;
     16 
     17 import java.util.ArrayList;
     18 import java.util.List;
     19 
     20 public class AppWidgetsRestoredReceiver extends BroadcastReceiver {
     21 
     22     private static final String TAG = "AppWidgetsRestoredReceiver";
     23 
     24     @Override
     25     public void onReceive(Context context, Intent intent) {
     26         if (AppWidgetManager.ACTION_APPWIDGET_HOST_RESTORED.equals(intent.getAction())) {
     27             int[] oldIds = intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_OLD_IDS);
     28             int[] newIds = intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);
     29             if (oldIds.length == newIds.length) {
     30                 restoreAppWidgetIds(context, oldIds, newIds);
     31             } else {
     32                 Log.e(TAG, "Invalid host restored received");
     33             }
     34         }
     35     }
     36 
     37     /**
     38      * Updates the app widgets whose id has changed during the restore process.
     39      */
     40     static void restoreAppWidgetIds(Context context, int[] oldWidgetIds, int[] newWidgetIds) {
     41         final ContentResolver cr = context.getContentResolver();
     42         final List<Integer> idsToRemove = new ArrayList<Integer>();
     43         final AppWidgetManager widgets = AppWidgetManager.getInstance(context);
     44 
     45         for (int i = 0; i < oldWidgetIds.length; i++) {
     46             Log.i(TAG, "Widget state restore id " + oldWidgetIds[i] + " => " + newWidgetIds[i]);
     47 
     48             final AppWidgetProviderInfo provider = widgets.getAppWidgetInfo(newWidgetIds[i]);
     49             final int state;
     50             if (LauncherModel.isValidProvider(provider)) {
     51                 state = LauncherAppWidgetInfo.RESTORE_COMPLETED;
     52             } else {
     53                 state = LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY;
     54             }
     55 
     56             ContentValues values = new ContentValues();
     57             values.put(LauncherSettings.Favorites.APPWIDGET_ID, newWidgetIds[i]);
     58             values.put(LauncherSettings.Favorites.RESTORED, state);
     59 
     60             String[] widgetIdParams = new String[] { Integer.toString(oldWidgetIds[i]) };
     61 
     62             int result = cr.update(Favorites.CONTENT_URI, values,
     63                     "appWidgetId=? and (restored & 1) = 1", widgetIdParams);
     64             if (result == 0) {
     65                 Cursor cursor = cr.query(Favorites.CONTENT_URI,
     66                         new String[] {Favorites.APPWIDGET_ID},
     67                         "appWidgetId=?", widgetIdParams, null);
     68                 try {
     69                     if (!cursor.moveToFirst()) {
     70                         // The widget no long exists.
     71                         idsToRemove.add(newWidgetIds[i]);
     72                     }
     73                 } finally {
     74                     cursor.close();
     75                 }
     76             }
     77         }
     78         // Unregister the widget IDs which are not present on the workspace. This could happen
     79         // when a widget place holder is removed from workspace, before this method is called.
     80         if (!idsToRemove.isEmpty()) {
     81             final AppWidgetHost appWidgetHost =
     82                     new AppWidgetHost(context, Launcher.APPWIDGET_HOST_ID);
     83             new AsyncTask<Void, Void, Void>() {
     84                 public Void doInBackground(Void ... args) {
     85                     for (Integer id : idsToRemove) {
     86                         appWidgetHost.deleteAppWidgetId(id);
     87                         Log.e(TAG, "Widget no longer present, appWidgetId=" + id);
     88                     }
     89                     return null;
     90                 }
     91             }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);
     92         }
     93     }
     94 }
     95