Allow Launcher to automatically restore widgets
This replaces PendingAppWidgetHostView with configured widget view when
OPTION_APPWIDGET_RESTORE_COMPLETED is set to True by a widget provider.
Bug: 63667276
Test: Manual
Change-Id: Ide21f5e9a7dac7e3d6a745660a38ad0b951b47d3
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 33f5a95..d6e8710 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -2305,6 +2305,13 @@
item.restoreStatus = LauncherAppWidgetInfo.RESTORE_COMPLETED;
getModelWriter().updateItemInDatabase(item);
}
+ else if (item.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_UI_NOT_READY)
+ && appWidgetInfo.configure != null) {
+ if (mAppWidgetManager.isAppWidgetRestored(item.appWidgetId)) {
+ item.restoreStatus = LauncherAppWidgetInfo.RESTORE_COMPLETED;
+ getModelWriter().updateItemInDatabase(item);
+ }
+ }
}
if (item.restoreStatus == LauncherAppWidgetInfo.RESTORE_COMPLETED) {
@@ -2318,6 +2325,11 @@
item.minSpanX = appWidgetInfo.minSpanX;
item.minSpanY = appWidgetInfo.minSpanY;
view = mAppWidgetHost.createView(this, item.appWidgetId, appWidgetInfo);
+ } else if (!item.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_ID_NOT_VALID)
+ && appWidgetInfo != null) {
+ mAppWidgetHost.addPendingView(item.appWidgetId,
+ new PendingAppWidgetHostView(this, item, mIconCache, false));
+ view = mAppWidgetHost.createView(this, item.appWidgetId, appWidgetInfo);
} else {
view = new PendingAppWidgetHostView(this, item, mIconCache, false);
}
diff --git a/src/com/android/launcher3/LauncherAppWidgetHost.java b/src/com/android/launcher3/LauncherAppWidgetHost.java
index 4e29a95..9921f76 100644
--- a/src/com/android/launcher3/LauncherAppWidgetHost.java
+++ b/src/com/android/launcher3/LauncherAppWidgetHost.java
@@ -32,6 +32,7 @@
import com.android.launcher3.model.WidgetsModel;
import com.android.launcher3.widget.DeferredAppWidgetHostView;
import com.android.launcher3.widget.LauncherAppWidgetHostView;
+import com.android.launcher3.widget.PendingAppWidgetHostView;
import com.android.launcher3.widget.custom.CustomWidgetManager;
import java.util.ArrayList;
@@ -53,12 +54,14 @@
private final ArrayList<ProviderChangedListener> mProviderChangeListeners = new ArrayList<>();
private final SparseArray<LauncherAppWidgetHostView> mViews = new SparseArray<>();
+ private final SparseArray<PendingAppWidgetHostView> mPendingViews = new SparseArray<>();
private final Context mContext;
private int mFlags = FLAG_RESUMED;
private IntConsumer mAppWidgetRemovedCallback = null;
+
public LauncherAppWidgetHost(Context context) {
this(context, null);
}
@@ -73,7 +76,13 @@
@Override
protected LauncherAppWidgetHostView onCreateView(Context context, int appWidgetId,
AppWidgetProviderInfo appWidget) {
- LauncherAppWidgetHostView view = new LauncherAppWidgetHostView(context);
+ final LauncherAppWidgetHostView view;
+ if (mPendingViews.get(appWidgetId) != null) {
+ view = mPendingViews.get(appWidgetId);
+ mPendingViews.remove(appWidgetId);
+ } else {
+ view = new LauncherAppWidgetHostView(context);
+ }
mViews.put(appWidgetId, view);
return view;
}
@@ -189,6 +198,10 @@
}
}
+ void addPendingView(int appWidgetId, PendingAppWidgetHostView view) {
+ mPendingViews.put(appWidgetId, view);
+ }
+
public AppWidgetHostView createView(Context context, int appWidgetId,
LauncherAppWidgetProviderInfo appWidget) {
if (appWidget.isCustomWidget()) {
@@ -238,8 +251,8 @@
/**
* Called on an appWidget is removed for a widgetId
- * @param appWidgetId
- * TODO: make this override when SDK is updated
+ *
+ * @param appWidgetId TODO: make this override when SDK is updated
*/
public void onAppWidgetRemoved(int appWidgetId) {
if (mAppWidgetRemovedCallback == null) {
diff --git a/src/com/android/launcher3/widget/PendingAppWidgetHostView.java b/src/com/android/launcher3/widget/PendingAppWidgetHostView.java
index 6038873..895f8de 100644
--- a/src/com/android/launcher3/widget/PendingAppWidgetHostView.java
+++ b/src/com/android/launcher3/widget/PendingAppWidgetHostView.java
@@ -33,6 +33,7 @@
import android.view.ContextThemeWrapper;
import android.view.View;
import android.view.View.OnClickListener;
+import android.widget.RemoteViews;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.FastBitmapDrawable;
@@ -94,6 +95,15 @@
}
@Override
+ public void updateAppWidget(RemoteViews remoteViews) {
+ super.updateAppWidget(remoteViews);
+ WidgetManagerHelper widgetManagerHelper = new WidgetManagerHelper(getContext());
+ if (widgetManagerHelper.isAppWidgetRestored(mInfo.appWidgetId)) {
+ reInflate();
+ }
+ }
+
+ @Override
public void updateAppWidgetSize(Bundle newOptions, int minWidth, int minHeight, int maxWidth,
int maxHeight) {
// No-op
diff --git a/src/com/android/launcher3/widget/WidgetManagerHelper.java b/src/com/android/launcher3/widget/WidgetManagerHelper.java
index 8b08d77..f3c7822 100644
--- a/src/com/android/launcher3/widget/WidgetManagerHelper.java
+++ b/src/com/android/launcher3/widget/WidgetManagerHelper.java
@@ -49,6 +49,9 @@
*/
public class WidgetManagerHelper {
+ //TODO: replace this with OPTION_APPWIDGET_RESTORE_COMPLETED b/63667276
+ public static final String WIDGET_OPTION_RESTORE_COMPLETED = "appWidgetRestoreCompleted";
+
final AppWidgetManager mAppWidgetManager;
final Context mContext;
@@ -127,6 +130,14 @@
return null;
}
+ /**
+ * Returns if a AppWidgetProvider has marked a widget restored
+ */
+ public boolean isAppWidgetRestored(int appWidgetId) {
+ return !WidgetsModel.GO_DISABLE_WIDGETS && mAppWidgetManager.getAppWidgetOptions(
+ appWidgetId).getBoolean(WIDGET_OPTION_RESTORE_COMPLETED);
+ }
+
public static Map<ComponentKey, AppWidgetProviderInfo> getAllProvidersMap(Context context) {
if (WidgetsModel.GO_DISABLE_WIDGETS) {
return Collections.emptyMap();