Loading src/com/android/launcher3/Launcher.java +12 −0 Original line number Diff line number Diff line Loading @@ -2305,6 +2305,13 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, 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) { Loading @@ -2318,6 +2325,11 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, 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); } Loading src/com/android/launcher3/LauncherAppWidgetHost.java +16 −3 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import android.widget.Toast; 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; Loading @@ -53,12 +54,14 @@ public class LauncherAppWidgetHost extends AppWidgetHost { 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); } Loading @@ -73,7 +76,13 @@ public class LauncherAppWidgetHost extends AppWidgetHost { @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; } Loading Loading @@ -189,6 +198,10 @@ public class LauncherAppWidgetHost extends AppWidgetHost { } } void addPendingView(int appWidgetId, PendingAppWidgetHostView view) { mPendingViews.put(appWidgetId, view); } public AppWidgetHostView createView(Context context, int appWidgetId, LauncherAppWidgetProviderInfo appWidget) { if (appWidget.isCustomWidget()) { Loading Loading @@ -238,8 +251,8 @@ public class LauncherAppWidgetHost extends AppWidgetHost { /** * 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) { Loading src/com/android/launcher3/widget/PendingAppWidgetHostView.java +10 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import android.util.TypedValue; 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; Loading Loading @@ -93,6 +94,15 @@ public class PendingAppWidgetHostView extends LauncherAppWidgetHostView } } @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) { Loading src/com/android/launcher3/widget/WidgetManagerHelper.java +11 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,9 @@ import java.util.stream.Stream; */ 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; Loading Loading @@ -127,6 +130,14 @@ public class WidgetManagerHelper { 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(); Loading tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java +28 −3 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static com.android.launcher3.widget.WidgetHostViewLoader.getDefaultOption import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import android.appwidget.AppWidgetHost; Loading @@ -33,6 +34,7 @@ import android.content.pm.PackageInstaller.SessionParams; import android.content.pm.PackageManager; import android.database.Cursor; import android.os.Bundle; import android.widget.RemoteViews; import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; Loading @@ -41,6 +43,7 @@ import com.android.launcher3.LauncherAppWidgetHost; import com.android.launcher3.LauncherAppWidgetInfo; import com.android.launcher3.LauncherAppWidgetProviderInfo; import com.android.launcher3.LauncherSettings; import com.android.launcher3.R; import com.android.launcher3.pm.InstallSessionHelper; import com.android.launcher3.tapl.Workspace; import com.android.launcher3.ui.AbstractLauncherUiTest; Loading Loading @@ -86,7 +89,8 @@ public class BindWidgetTest extends AbstractLauncherUiTest { // Clear all existing data LauncherSettings.Settings.call(mResolver, LauncherSettings.Settings.METHOD_CREATE_EMPTY_DB); LauncherSettings.Settings.call(mResolver, LauncherSettings.Settings.METHOD_CLEAR_EMPTY_DB_FLAG); LauncherSettings.Settings.call(mResolver, LauncherSettings.Settings.METHOD_CLEAR_EMPTY_DB_FLAG); } @After Loading Loading @@ -172,6 +176,26 @@ public class BindWidgetTest extends AbstractLauncherUiTest { assertNotNull(AppWidgetManager.getInstance(mTargetContext) .getAppWidgetInfo(mCursor.getInt(mCursor.getColumnIndex( LauncherSettings.Favorites.APPWIDGET_ID)))); // send OPTION_APPWIDGET_RESTORE_COMPLETED int appWidgetId = mCursor.getInt( mCursor.getColumnIndex(LauncherSettings.Favorites.APPWIDGET_ID)); AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(mTargetContext); Bundle b = new Bundle(); b.putBoolean(WidgetManagerHelper.WIDGET_OPTION_RESTORE_COMPLETED, true); RemoteViews remoteViews = new RemoteViews(mTargetPackage, R.layout.appwidget_not_ready); appWidgetManager.updateAppWidgetOptions(appWidgetId, b); appWidgetManager.updateAppWidget(appWidgetId, remoteViews); // verify changes are reflected waitForLauncherCondition("App widget options did not update", l -> appWidgetManager.getAppWidgetOptions(appWidgetId).getBoolean( WidgetManagerHelper.WIDGET_OPTION_RESTORE_COMPLETED)); executeOnLauncher(l -> l.getAppWidgetHost().startListening()); verifyWidgetPresent(info); assertNull(mLauncher.getWorkspace().tryGetPendingWidget(DEFAULT_UI_TIMEOUT)); } @Test Loading Loading @@ -254,6 +278,7 @@ public class BindWidgetTest extends AbstractLauncherUiTest { /** * Creates a LauncherAppWidgetInfo corresponding to {@param info} * * @param bindWidget if true the info is bound and a valid widgetId is assigned to * the LauncherAppWidgetInfo */ Loading Loading
src/com/android/launcher3/Launcher.java +12 −0 Original line number Diff line number Diff line Loading @@ -2305,6 +2305,13 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, 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) { Loading @@ -2318,6 +2325,11 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, 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); } Loading
src/com/android/launcher3/LauncherAppWidgetHost.java +16 −3 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import android.widget.Toast; 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; Loading @@ -53,12 +54,14 @@ public class LauncherAppWidgetHost extends AppWidgetHost { 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); } Loading @@ -73,7 +76,13 @@ public class LauncherAppWidgetHost extends AppWidgetHost { @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; } Loading Loading @@ -189,6 +198,10 @@ public class LauncherAppWidgetHost extends AppWidgetHost { } } void addPendingView(int appWidgetId, PendingAppWidgetHostView view) { mPendingViews.put(appWidgetId, view); } public AppWidgetHostView createView(Context context, int appWidgetId, LauncherAppWidgetProviderInfo appWidget) { if (appWidget.isCustomWidget()) { Loading Loading @@ -238,8 +251,8 @@ public class LauncherAppWidgetHost extends AppWidgetHost { /** * 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) { Loading
src/com/android/launcher3/widget/PendingAppWidgetHostView.java +10 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import android.util.TypedValue; 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; Loading Loading @@ -93,6 +94,15 @@ public class PendingAppWidgetHostView extends LauncherAppWidgetHostView } } @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) { Loading
src/com/android/launcher3/widget/WidgetManagerHelper.java +11 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,9 @@ import java.util.stream.Stream; */ 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; Loading Loading @@ -127,6 +130,14 @@ public class WidgetManagerHelper { 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(); Loading
tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java +28 −3 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static com.android.launcher3.widget.WidgetHostViewLoader.getDefaultOption import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import android.appwidget.AppWidgetHost; Loading @@ -33,6 +34,7 @@ import android.content.pm.PackageInstaller.SessionParams; import android.content.pm.PackageManager; import android.database.Cursor; import android.os.Bundle; import android.widget.RemoteViews; import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; Loading @@ -41,6 +43,7 @@ import com.android.launcher3.LauncherAppWidgetHost; import com.android.launcher3.LauncherAppWidgetInfo; import com.android.launcher3.LauncherAppWidgetProviderInfo; import com.android.launcher3.LauncherSettings; import com.android.launcher3.R; import com.android.launcher3.pm.InstallSessionHelper; import com.android.launcher3.tapl.Workspace; import com.android.launcher3.ui.AbstractLauncherUiTest; Loading Loading @@ -86,7 +89,8 @@ public class BindWidgetTest extends AbstractLauncherUiTest { // Clear all existing data LauncherSettings.Settings.call(mResolver, LauncherSettings.Settings.METHOD_CREATE_EMPTY_DB); LauncherSettings.Settings.call(mResolver, LauncherSettings.Settings.METHOD_CLEAR_EMPTY_DB_FLAG); LauncherSettings.Settings.call(mResolver, LauncherSettings.Settings.METHOD_CLEAR_EMPTY_DB_FLAG); } @After Loading Loading @@ -172,6 +176,26 @@ public class BindWidgetTest extends AbstractLauncherUiTest { assertNotNull(AppWidgetManager.getInstance(mTargetContext) .getAppWidgetInfo(mCursor.getInt(mCursor.getColumnIndex( LauncherSettings.Favorites.APPWIDGET_ID)))); // send OPTION_APPWIDGET_RESTORE_COMPLETED int appWidgetId = mCursor.getInt( mCursor.getColumnIndex(LauncherSettings.Favorites.APPWIDGET_ID)); AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(mTargetContext); Bundle b = new Bundle(); b.putBoolean(WidgetManagerHelper.WIDGET_OPTION_RESTORE_COMPLETED, true); RemoteViews remoteViews = new RemoteViews(mTargetPackage, R.layout.appwidget_not_ready); appWidgetManager.updateAppWidgetOptions(appWidgetId, b); appWidgetManager.updateAppWidget(appWidgetId, remoteViews); // verify changes are reflected waitForLauncherCondition("App widget options did not update", l -> appWidgetManager.getAppWidgetOptions(appWidgetId).getBoolean( WidgetManagerHelper.WIDGET_OPTION_RESTORE_COMPLETED)); executeOnLauncher(l -> l.getAppWidgetHost().startListening()); verifyWidgetPresent(info); assertNull(mLauncher.getWorkspace().tryGetPendingWidget(DEFAULT_UI_TIMEOUT)); } @Test Loading Loading @@ -254,6 +278,7 @@ public class BindWidgetTest extends AbstractLauncherUiTest { /** * Creates a LauncherAppWidgetInfo corresponding to {@param info} * * @param bindWidget if true the info is bound and a valid widgetId is assigned to * the LauncherAppWidgetInfo */ Loading