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.Context;
      9 import android.content.Intent;
     10 import android.database.Cursor;
     11 import android.os.Handler;
     12 import android.support.annotation.WorkerThread;
     13 import android.util.Log;
     14 
     15 import com.android.launcher3.LauncherSettings.Favorites;
     16 import com.android.launcher3.config.FeatureFlags;
     17 import com.android.launcher3.model.LoaderTask;
     18 import com.android.launcher3.provider.RestoreDbTask;
     19 import com.android.launcher3.util.ContentWriter;
     20 
     21 public class AppWidgetsRestoredReceiver extends BroadcastReceiver {
     22 
     23     private static final String TAG = "AWRestoredReceiver";
     24 
     25     @Override
     26     public void onReceive(final Context context, Intent intent) {
     27         if (AppWidgetManager.ACTION_APPWIDGET_HOST_RESTORED.equals(intent.getAction())) {
     28             int hostId = intent.getIntExtra(AppWidgetManager.EXTRA_HOST_ID, 0);
     29             Log.d(TAG, "Widget ID map received for host:" + hostId);
     30             if (hostId != LauncherAppWidgetHost.APPWIDGET_HOST_ID) {
     31                 return;
     32             }
     33 
     34             final int[] oldIds = intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_OLD_IDS);
     35             final int[] newIds = intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);
     36             if (oldIds.length == newIds.length) {
     37                 final PendingResult asyncResult = goAsync();
     38                 new Handler(LauncherModel.getWorkerLooper())
     39                         .postAtFrontOfQueue(new Runnable() {
     40                             @Override
     41                             public void run() {
     42                                 restoreAppWidgetIds(context, oldIds, newIds);
     43                                 asyncResult.finish();
     44                             }
     45                         });
     46             } else {
     47                 Log.e(TAG, "Invalid host restored received");
     48             }
     49         }
     50     }
     51 
     52     /**
     53      * Updates the app widgets whose id has changed during the restore process.
     54      */
     55     @WorkerThread
     56     static void restoreAppWidgetIds(Context context, int[] oldWidgetIds, int[] newWidgetIds) {
     57         AppWidgetHost appWidgetHost = new LauncherAppWidgetHost(context);
     58         if (FeatureFlags.GO_DISABLE_WIDGETS) {
     59             Log.e(TAG, "Skipping widget ID remap as widgets not supported");
     60             appWidgetHost.deleteHost();
     61             return;
     62         }
     63         if (!RestoreDbTask.isPending(context)) {
     64             // Someone has already gone through our DB once, probably LoaderTask. Skip any further
     65             // modifications of the DB.
     66             Log.e(TAG, "Skipping widget ID remap as DB already in use");
     67             for (int widgetId : newWidgetIds) {
     68                 Log.d(TAG, "Deleting widgetId: " + widgetId);
     69                 appWidgetHost.deleteAppWidgetId(widgetId);
     70             }
     71             return;
     72         }
     73         final ContentResolver cr = context.getContentResolver();
     74         final AppWidgetManager widgets = AppWidgetManager.getInstance(context);
     75 
     76         for (int i = 0; i < oldWidgetIds.length; i++) {
     77             Log.i(TAG, "Widget state restore id " + oldWidgetIds[i] + " => " + newWidgetIds[i]);
     78 
     79             final AppWidgetProviderInfo provider = widgets.getAppWidgetInfo(newWidgetIds[i]);
     80             final int state;
     81             if (LoaderTask.isValidProvider(provider)) {
     82                 // This will ensure that we show 'Click to setup' UI if required.
     83                 state = LauncherAppWidgetInfo.FLAG_UI_NOT_READY;
     84             } else {
     85                 state = LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY;
     86             }
     87 
     88             String[] widgetIdParams = new String[] { Integer.toString(oldWidgetIds[i]) };
     89             int result = new ContentWriter(context, new ContentWriter.CommitParams(
     90                     "appWidgetId=? and (restored & 1) = 1", widgetIdParams))
     91                     .put(LauncherSettings.Favorites.APPWIDGET_ID, newWidgetIds[i])
     92                     .put(LauncherSettings.Favorites.RESTORED, state)
     93                     .commit();
     94 
     95             if (result == 0) {
     96                 Cursor cursor = cr.query(Favorites.CONTENT_URI,
     97                         new String[] {Favorites.APPWIDGET_ID},
     98                         "appWidgetId=?", widgetIdParams, null);
     99                 try {
    100                     if (!cursor.moveToFirst()) {
    101                         // The widget no long exists.
    102                         appWidgetHost.deleteAppWidgetId(newWidgetIds[i]);
    103                     }
    104                 } finally {
    105                     cursor.close();
    106                 }
    107             }
    108         }
    109 
    110         LauncherAppState app = LauncherAppState.getInstanceNoCreate();
    111         if (app != null) {
    112             app.getModel().forceReload();
    113         }
    114     }
    115 }
    116