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                 // This will ensure that we show 'Click to setup' UI if required.
     52                 state = LauncherAppWidgetInfo.FLAG_UI_NOT_READY;
     53             } else {
     54                 state = LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY;
     55             }
     56 
     57             ContentValues values = new ContentValues();
     58             values.put(LauncherSettings.Favorites.APPWIDGET_ID, newWidgetIds[i]);
     59             values.put(LauncherSettings.Favorites.RESTORED, state);
     60 
     61             String[] widgetIdParams = new String[] { Integer.toString(oldWidgetIds[i]) };
     62 
     63             int result = cr.update(Favorites.CONTENT_URI, values,
     64                     "appWidgetId=? and (restored & 1) = 1", widgetIdParams);
     65             if (result == 0) {
     66                 Cursor cursor = cr.query(Favorites.CONTENT_URI,
     67                         new String[] {Favorites.APPWIDGET_ID},
     68                         "appWidgetId=?", widgetIdParams, null);
     69                 try {
     70                     if (!cursor.moveToFirst()) {
     71                         // The widget no long exists.
     72                         idsToRemove.add(newWidgetIds[i]);
     73                     }
     74                 } finally {
     75                     cursor.close();
     76                 }
     77             }
     78         }
     79         // Unregister the widget IDs which are not present on the workspace. This could happen
     80         // when a widget place holder is removed from workspace, before this method is called.
     81         if (!idsToRemove.isEmpty()) {
     82             final AppWidgetHost appWidgetHost =
     83                     new AppWidgetHost(context, Launcher.APPWIDGET_HOST_ID);
     84             new AsyncTask<Void, Void, Void>() {
     85                 public Void doInBackground(Void ... args) {
     86                     for (Integer id : idsToRemove) {
     87                         appWidgetHost.deleteAppWidgetId(id);
     88                         Log.e(TAG, "Widget no longer present, appWidgetId=" + id);
     89                     }
     90                     return null;
     91                 }
     92             }.executeOnExecutor(Utilities.THREAD_POOL_EXECUTOR);
     93         }
     94 
     95         LauncherAppState app = LauncherAppState.getInstanceNoCreate();
     96         if (app != null) {
     97             app.reloadWorkspace();
     98         }
     99     }
    100 }
    101