• 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.util.Log;
12 
13 import com.android.launcher3.LauncherSettings.Favorites;
14 import com.android.launcher3.config.FeatureFlags;
15 import com.android.launcher3.model.LoaderTask;
16 import com.android.launcher3.provider.RestoreDbTask;
17 import com.android.launcher3.util.ContentWriter;
18 
19 import androidx.annotation.WorkerThread;
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 != null && newIds != null && oldIds.length == newIds.length) {
37                 RestoreDbTask.setRestoredAppWidgetIds(context, oldIds, newIds);
38             } else {
39                 Log.e(TAG, "Invalid host restored received");
40             }
41         }
42     }
43 
44     /**
45      * Updates the app widgets whose id has changed during the restore process.
46      */
47     @WorkerThread
restoreAppWidgetIds(Context context, int[] oldWidgetIds, int[] newWidgetIds)48     public static void restoreAppWidgetIds(Context context, int[] oldWidgetIds, int[] newWidgetIds) {
49         AppWidgetHost appWidgetHost = new LauncherAppWidgetHost(context);
50         if (FeatureFlags.GO_DISABLE_WIDGETS) {
51             Log.e(TAG, "Skipping widget ID remap as widgets not supported");
52             appWidgetHost.deleteHost();
53             return;
54         }
55         if (!RestoreDbTask.isPending(context)) {
56             // Someone has already gone through our DB once, probably LoaderTask. Skip any further
57             // modifications of the DB.
58             Log.e(TAG, "Skipping widget ID remap as DB already in use");
59             for (int widgetId : newWidgetIds) {
60                 Log.d(TAG, "Deleting widgetId: " + widgetId);
61                 appWidgetHost.deleteAppWidgetId(widgetId);
62             }
63             return;
64         }
65         final ContentResolver cr = context.getContentResolver();
66         final AppWidgetManager widgets = AppWidgetManager.getInstance(context);
67 
68         for (int i = 0; i < oldWidgetIds.length; i++) {
69             Log.i(TAG, "Widget state restore id " + oldWidgetIds[i] + " => " + newWidgetIds[i]);
70 
71             final AppWidgetProviderInfo provider = widgets.getAppWidgetInfo(newWidgetIds[i]);
72             final int state;
73             if (LoaderTask.isValidProvider(provider)) {
74                 // This will ensure that we show 'Click to setup' UI if required.
75                 state = LauncherAppWidgetInfo.FLAG_UI_NOT_READY;
76             } else {
77                 state = LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY;
78             }
79 
80             String[] widgetIdParams = new String[] { Integer.toString(oldWidgetIds[i]) };
81             int result = new ContentWriter(context, new ContentWriter.CommitParams(
82                     "appWidgetId=? and (restored & 1) = 1", widgetIdParams))
83                     .put(LauncherSettings.Favorites.APPWIDGET_ID, newWidgetIds[i])
84                     .put(LauncherSettings.Favorites.RESTORED, state)
85                     .commit();
86 
87             if (result == 0) {
88                 Cursor cursor = cr.query(Favorites.CONTENT_URI,
89                         new String[] {Favorites.APPWIDGET_ID},
90                         "appWidgetId=?", widgetIdParams, null);
91                 try {
92                     if (!cursor.moveToFirst()) {
93                         // The widget no long exists.
94                         appWidgetHost.deleteAppWidgetId(newWidgetIds[i]);
95                     }
96                 } finally {
97                     cursor.close();
98                 }
99             }
100         }
101 
102         LauncherAppState app = LauncherAppState.getInstanceNoCreate();
103         if (app != null) {
104             app.getModel().forceReload();
105         }
106     }
107 }
108