Merge "Allow Launcher to automatically restore widgets" into ub-launcher3-master
This commit is contained in:
commit
fe41c3af21
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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"));
|
||||
|
|
Loading…
Reference in New Issue