Merge "Allow Launcher to automatically restore widgets" into ub-launcher3-master

This commit is contained in:
TreeHugger Robot 2020-03-04 00:16:09 +00:00 committed by Android (Google) Code Review
commit fe41c3af21
5 changed files with 77 additions and 6 deletions

View File

@ -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) {
@ -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);
}

View File

@ -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;
@ -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);
}
@ -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;
}
@ -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()) {
@ -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) {

View File

@ -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;
@ -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) {

View File

@ -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;
@ -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();

View File

@ -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;
@ -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;
@ -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;
@ -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
@ -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
@ -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
*/
@ -306,7 +331,7 @@ public class BindWidgetTest extends AbstractLauncherUiTest {
.keySet().forEach(packageUserKey -> packages.add(packageUserKey.mPackageName));
return packages;
});
while(true) {
while (true) {
try {
mTargetContext.getPackageManager().getPackageInfo(
pkg, PackageManager.GET_UNINSTALLED_PACKAGES);
@ -316,7 +341,7 @@ public class BindWidgetTest extends AbstractLauncherUiTest {
}
}
pkg = invalidPackage + count;
count ++;
count++;
}
LauncherAppWidgetInfo item = new LauncherAppWidgetInfo(10,
new ComponentName(pkg, "com.test.widgetprovider"));