• 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.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 import com.android.launcher3.compat.AppWidgetManagerCompat;
17 
18 import java.util.ArrayList;
19 import java.util.List;
20 
21 public class AppWidgetsRestoredReceiver extends BroadcastReceiver {
22 
23     private static final String TAG = "AppWidgetsRestoredReceiver";
24 
25     @Override
onReceive(Context context, Intent intent)26     public void onReceive(Context context, Intent intent) {
27         if (AppWidgetManager.ACTION_APPWIDGET_HOST_RESTORED.equals(intent.getAction())) {
28             int[] oldIds = intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_OLD_IDS);
29             int[] newIds = intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);
30             if (oldIds.length == newIds.length) {
31                 restoreAppWidgetIds(context, oldIds, newIds);
32             } else {
33                 Log.e(TAG, "Invalid host restored received");
34             }
35         }
36     }
37 
38     /**
39      * Updates the app widgets whose id has changed during the restore process.
40      */
restoreAppWidgetIds(Context context, int[] oldWidgetIds, int[] newWidgetIds)41     static void restoreAppWidgetIds(Context context, int[] oldWidgetIds, int[] newWidgetIds) {
42         final ContentResolver cr = context.getContentResolver();
43         final List<Integer> idsToRemove = new ArrayList<Integer>();
44         final AppWidgetManager widgets = AppWidgetManager.getInstance(context);
45 
46         for (int i = 0; i < oldWidgetIds.length; i++) {
47             Log.i(TAG, "Widget state restore id " + oldWidgetIds[i] + " => " + newWidgetIds[i]);
48 
49             final AppWidgetProviderInfo provider = widgets.getAppWidgetInfo(newWidgetIds[i]);
50             final int state;
51             if (LauncherModel.isValidProvider(provider)) {
52                 // This will ensure that we show 'Click to setup' UI if required.
53                 state = LauncherAppWidgetInfo.FLAG_UI_NOT_READY;
54             } else {
55                 state = LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY;
56             }
57 
58             ContentValues values = new ContentValues();
59             values.put(LauncherSettings.Favorites.APPWIDGET_ID, newWidgetIds[i]);
60             values.put(LauncherSettings.Favorites.RESTORED, state);
61 
62             String[] widgetIdParams = new String[] { Integer.toString(oldWidgetIds[i]) };
63 
64             int result = cr.update(Favorites.CONTENT_URI, values,
65                     "appWidgetId=? and (restored & 1) = 1", widgetIdParams);
66             if (result == 0) {
67                 Cursor cursor = cr.query(Favorites.CONTENT_URI,
68                         new String[] {Favorites.APPWIDGET_ID},
69                         "appWidgetId=?", widgetIdParams, null);
70                 try {
71                     if (!cursor.moveToFirst()) {
72                         // The widget no long exists.
73                         idsToRemove.add(newWidgetIds[i]);
74                     }
75                 } finally {
76                     cursor.close();
77                 }
78             }
79         }
80         // Unregister the widget IDs which are not present on the workspace. This could happen
81         // when a widget place holder is removed from workspace, before this method is called.
82         if (!idsToRemove.isEmpty()) {
83             final AppWidgetHost appWidgetHost =
84                     new AppWidgetHost(context, Launcher.APPWIDGET_HOST_ID);
85             new AsyncTask<Void, Void, Void>() {
86                 public Void doInBackground(Void ... args) {
87                     for (Integer id : idsToRemove) {
88                         appWidgetHost.deleteAppWidgetId(id);
89                         Log.e(TAG, "Widget no longer present, appWidgetId=" + id);
90                     }
91                     return null;
92                 }
93             }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);
94         }
95 
96         LauncherAppState app = LauncherAppState.getInstanceNoCreate();
97         if (app != null) {
98             app.reloadWorkspace();
99         }
100     }
101 }
102