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.util.Log; 13 14 import com.android.launcher3.LauncherSettings.Favorites; 15 import com.android.launcher3.util.ContentWriter; 16 17 public class AppWidgetsRestoredReceiver extends BroadcastReceiver { 18 19 private static final String TAG = "AWRestoredReceiver"; 20 21 @Override 22 public void onReceive(final Context context, Intent intent) { 23 if (AppWidgetManager.ACTION_APPWIDGET_HOST_RESTORED.equals(intent.getAction())) { 24 final int[] oldIds = intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_OLD_IDS); 25 final int[] newIds = intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS); 26 if (oldIds.length == newIds.length) { 27 final PendingResult asyncResult = goAsync(); 28 new Handler(LauncherModel.getWorkerLooper()) 29 .postAtFrontOfQueue(new Runnable() { 30 @Override 31 public void run() { 32 restoreAppWidgetIds(context, asyncResult, oldIds, newIds); 33 } 34 }); 35 } else { 36 Log.e(TAG, "Invalid host restored received"); 37 } 38 } 39 } 40 41 /** 42 * Updates the app widgets whose id has changed during the restore process. 43 */ 44 static void restoreAppWidgetIds(Context context, PendingResult asyncResult, 45 int[] oldWidgetIds, int[] newWidgetIds) { 46 final ContentResolver cr = context.getContentResolver(); 47 final AppWidgetManager widgets = AppWidgetManager.getInstance(context); 48 AppWidgetHost appWidgetHost = new AppWidgetHost(context, Launcher.APPWIDGET_HOST_ID); 49 50 for (int i = 0; i < oldWidgetIds.length; i++) { 51 Log.i(TAG, "Widget state restore id " + oldWidgetIds[i] + " => " + newWidgetIds[i]); 52 53 final AppWidgetProviderInfo provider = widgets.getAppWidgetInfo(newWidgetIds[i]); 54 final int state; 55 if (LauncherModel.isValidProvider(provider)) { 56 // This will ensure that we show 'Click to setup' UI if required. 57 state = LauncherAppWidgetInfo.FLAG_UI_NOT_READY; 58 } else { 59 state = LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY; 60 } 61 62 String[] widgetIdParams = new String[] { Integer.toString(oldWidgetIds[i]) }; 63 int result = new ContentWriter(context, new ContentWriter.CommitParams( 64 "appWidgetId=? and (restored & 1) = 1", widgetIdParams)) 65 .put(LauncherSettings.Favorites.APPWIDGET_ID, newWidgetIds[i]) 66 .put(LauncherSettings.Favorites.RESTORED, state) 67 .commit(); 68 69 if (result == 0) { 70 Cursor cursor = cr.query(Favorites.CONTENT_URI, 71 new String[] {Favorites.APPWIDGET_ID}, 72 "appWidgetId=?", widgetIdParams, null); 73 try { 74 if (!cursor.moveToFirst()) { 75 // The widget no long exists. 76 appWidgetHost.deleteAppWidgetId(newWidgetIds[i]); 77 } 78 } finally { 79 cursor.close(); 80 } 81 } 82 } 83 84 LauncherAppState app = LauncherAppState.getInstanceNoCreate(); 85 if (app != null) { 86 app.getModel().forceReload(); 87 } 88 asyncResult.finish(); 89 } 90 } 91