• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
onReceive(final Context context, Intent intent)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
restoreAppWidgetIds(Context context, int[] oldWidgetIds, int[] newWidgetIds)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