Using WidgetInflater in loader task
This removes duplicate logic for widget inflation.
Since the widget inflation can now happen during loader,
the restore logging can also be moved completely to the loader
Bug: 318539160
Test: atest TaplBinderTests
Flag: None
Change-Id: If9f336e7bf49ee7df121d7d9852b674d98124895
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index b5dd10e..a2f6bf9 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -52,7 +52,6 @@
import static com.android.launcher3.LauncherConstants.TraceEvents.ON_NEW_INTENT_EVT;
import static com.android.launcher3.LauncherConstants.TraceEvents.ON_RESUME_EVT;
import static com.android.launcher3.LauncherConstants.TraceEvents.ON_START_EVT;
-import static com.android.launcher3.LauncherPrefs.IS_FIRST_LOAD_AFTER_RESTORE;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_DESKTOP;
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET;
@@ -65,8 +64,6 @@
import static com.android.launcher3.LauncherState.NO_SCALE;
import static com.android.launcher3.LauncherState.SPRING_LOADED;
import static com.android.launcher3.Utilities.postAsyncCallback;
-import static com.android.launcher3.backuprestore.LauncherRestoreEventLogger.RESTORE_ERROR_BIND_FAILURE;
-import static com.android.launcher3.backuprestore.LauncherRestoreEventLogger.RESTORE_ERROR_INVALID_LOCATION;
import static com.android.launcher3.config.FeatureFlags.ENABLE_SMARTSPACE_REMOVAL;
import static com.android.launcher3.config.FeatureFlags.FOLDABLE_SINGLE_PAGE;
import static com.android.launcher3.config.FeatureFlags.MULTI_SELECT_EDIT_MODE;
@@ -165,7 +162,6 @@
import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.PropertyListBuilder;
import com.android.launcher3.apppairs.AppPairIcon;
-import com.android.launcher3.backuprestore.LauncherRestoreEventLogger;
import com.android.launcher3.celllayout.CellPosMapper;
import com.android.launcher3.celllayout.CellPosMapper.CellPos;
import com.android.launcher3.celllayout.CellPosMapper.TwoPanelCellPosMapper;
@@ -2161,13 +2157,6 @@
int newItemsScreenId = -1;
int end = items.size();
View newView = null;
- LauncherRestoreEventLogger restoreEventLogger = null;
- Boolean isRestoreFromBackup = (Boolean) LauncherPrefs.get(getApplicationContext())
- .get(IS_FIRST_LOAD_AFTER_RESTORE);
- if (isRestoreFromBackup) {
- restoreEventLogger = LauncherRestoreEventLogger.Companion
- .newInstance(getApplicationContext());
- }
for (int i = 0; i < end; i++) {
final ItemInfo item = items.get(i);
// Short circuit if we are loading dock items for a configuration which has no dock
@@ -2198,15 +2187,10 @@
}
case ITEM_TYPE_APPWIDGET:
case LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET: {
- view = inflateAppWidget((LauncherAppWidgetInfo) item, restoreEventLogger);
+ view = inflateAppWidget((LauncherAppWidgetInfo) item);
if (view == null) {
continue;
}
- // Widgets have more checks when inflating, so we have to wait until here
- // to mark restored, instead of logging in LoaderTask.
- if (restoreEventLogger != null) {
- restoreEventLogger.logSingleFavoritesItemRestored(item.itemType);
- }
break;
}
default:
@@ -2230,10 +2214,6 @@
if (FeatureFlags.IS_STUDIO_BUILD) {
throw (new RuntimeException(desc));
} else {
- if (restoreEventLogger != null) {
- restoreEventLogger.logSingleFavoritesItemRestoreFailed(item.itemType,
- RESTORE_ERROR_INVALID_LOCATION);
- }
getModelWriter().deleteItemFromDatabase(item, desc);
continue;
}
@@ -2292,9 +2272,6 @@
} else if (focusFirstItemForAccessibility && viewToFocus != null) {
viewToFocus.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
}
- if (restoreEventLogger != null) {
- restoreEventLogger.reportLauncherRestoreResults();
- }
workspace.requestLayout();
}
@@ -2302,24 +2279,19 @@
* Add the views for a widget to the workspace.
*/
public void bindAppWidget(LauncherAppWidgetInfo item) {
- View view = inflateAppWidget(item, null);
+ View view = inflateAppWidget(item);
if (view != null) {
mWorkspace.addInScreen(view, item);
mWorkspace.requestLayout();
}
}
- private View inflateAppWidget(LauncherAppWidgetInfo item,
- @Nullable LauncherRestoreEventLogger restoreEventLogger) {
+ private View inflateAppWidget(LauncherAppWidgetInfo item) {
TraceHelper.INSTANCE.beginSection("BIND_WIDGET_id=" + item.appWidgetId);
try {
InflationResult inflationResult = mWidgetInflater.inflateAppWidget(item);
if (inflationResult.getType() == WidgetInflater.TYPE_DELETE) {
getModelWriter().deleteItemFromDatabase(item, inflationResult.getReason());
- if (restoreEventLogger != null) {
- restoreEventLogger.logSingleFavoritesItemRestoreFailed(
- ITEM_TYPE_APPWIDGET, RESTORE_ERROR_BIND_FAILURE);
- }
return null;
}
diff --git a/src/com/android/launcher3/backuprestore/LauncherRestoreEventLogger.kt b/src/com/android/launcher3/backuprestore/LauncherRestoreEventLogger.kt
index 063dad1..e6654b1 100644
--- a/src/com/android/launcher3/backuprestore/LauncherRestoreEventLogger.kt
+++ b/src/com/android/launcher3/backuprestore/LauncherRestoreEventLogger.kt
@@ -1,6 +1,7 @@
package com.android.launcher3.backuprestore
import android.content.Context
+import androidx.annotation.StringDef
import com.android.launcher3.LauncherSettings.Favorites
import com.android.launcher3.R
import com.android.launcher3.util.ResourceBasedOverride
@@ -11,20 +12,42 @@
*/
open class LauncherRestoreEventLogger : ResourceBasedOverride {
+ /** Enumeration of potential errors returned to calls of pause/resume app updates. */
+ @Retention(AnnotationRetention.SOURCE)
+ @StringDef(
+ RestoreError.PROFILE_DELETED,
+ RestoreError.MISSING_INFO,
+ RestoreError.MISSING_WIDGET_PROVIDER,
+ RestoreError.INVALID_LOCATION,
+ RestoreError.SHORTCUT_NOT_FOUND,
+ RestoreError.APP_NOT_INSTALLED,
+ RestoreError.WIDGETS_DISABLED,
+ RestoreError.PROFILE_NOT_RESTORED,
+ RestoreError.WIDGET_REMOVED,
+ RestoreError.GRID_MIGRATION_FAILURE,
+ RestoreError.NO_SEARCH_WIDGET,
+ RestoreError.INVALID_WIDGET_ID
+ )
+ annotation class RestoreError {
+ companion object {
+ const val PROFILE_DELETED = "user_profile_deleted"
+ const val MISSING_INFO = "missing_information_when_loading"
+ const val MISSING_WIDGET_PROVIDER = "missing_widget_provider"
+ const val INVALID_LOCATION = "invalid_size_or_location"
+ const val SHORTCUT_NOT_FOUND = "shortcut_not_found"
+ const val APP_NOT_INSTALLED = "app_not_installed"
+ const val WIDGETS_DISABLED = "widgets_disabled"
+ const val PROFILE_NOT_RESTORED = "profile_not_restored"
+ const val WIDGET_REMOVED = "widget_not_found"
+ const val GRID_MIGRATION_FAILURE = "grid_migration_failed"
+ const val NO_SEARCH_WIDGET = "no_search_widget"
+ const val INVALID_WIDGET_ID = "invalid_widget_id"
+ }
+ }
+
companion object {
const val TAG = "LauncherRestoreEventLogger"
- // Restore Errors
- const val RESTORE_ERROR_PROFILE_DELETED = "user_profile_deleted"
- const val RESTORE_ERROR_MISSING_INFO = "missing_information_when_loading"
- const val RESTORE_ERROR_BIND_FAILURE = "binding_to_view_failed"
- const val RESTORE_ERROR_INVALID_LOCATION = "invalid_size_or_location"
- const val RESTORE_ERROR_SHORTCUT_NOT_FOUND = "shortcut_not_found"
- const val RESTORE_ERROR_APP_NOT_INSTALLED = "app_not_installed"
- const val RESTORE_ERROR_WIDGETS_DISABLED = "widgets_disabled"
- const val RESTORE_ERROR_PROFILE_NOT_RESTORED = "profile_not_restored"
- const val RESTORE_ERROR_WIDGET_REMOVED = "widget_not_found"
-
fun newInstance(context: Context?): LauncherRestoreEventLogger {
return ResourceBasedOverride.Overrides.getObject(
LauncherRestoreEventLogger::class.java,
@@ -80,7 +103,7 @@
* @param favoritesId The id of the item type from [Favorites] that was not restored.
* @param error error type for why the data was not restored.
*/
- open fun logSingleFavoritesItemRestoreFailed(favoritesId: Int, error: String?) {
+ open fun logSingleFavoritesItemRestoreFailed(favoritesId: Int, @RestoreError error: String?) {
// no-op
}
@@ -91,7 +114,11 @@
* @param count number of items that failed to restore.
* @param error error type for why the data was not restored.
*/
- open fun logFavoritesItemsRestoreFailed(favoritesId: Int, count: Int, error: String?) {
+ open fun logFavoritesItemsRestoreFailed(
+ favoritesId: Int,
+ count: Int,
+ @RestoreError error: String?
+ ) {
// no-op
}
diff --git a/src/com/android/launcher3/model/LoaderCursor.java b/src/com/android/launcher3/model/LoaderCursor.java
index 4370043..1044dfb 100644
--- a/src/com/android/launcher3/model/LoaderCursor.java
+++ b/src/com/android/launcher3/model/LoaderCursor.java
@@ -41,6 +41,8 @@
import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.Utilities;
import com.android.launcher3.Workspace;
+import com.android.launcher3.backuprestore.LauncherRestoreEventLogger;
+import com.android.launcher3.backuprestore.LauncherRestoreEventLogger.RestoreError;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.logging.FileLog;
@@ -70,6 +72,7 @@
private final Context mContext;
private final IconCache mIconCache;
private final InvariantDeviceProfile mIDP;
+ private final @Nullable LauncherRestoreEventLogger mRestoreEventLogger;
private final IntArray mItemsToRemove = new IntArray();
private final IntArray mRestoredRows = new IntArray();
@@ -107,7 +110,8 @@
public int itemType;
public int restoreFlag;
- public LoaderCursor(Cursor cursor, LauncherAppState app, UserManagerState userManagerState) {
+ public LoaderCursor(Cursor cursor, LauncherAppState app, UserManagerState userManagerState,
+ @Nullable LauncherRestoreEventLogger restoreEventLogger) {
super(cursor);
mApp = app;
@@ -115,6 +119,7 @@
mContext = app.getContext();
mIconCache = app.getIconCache();
mIDP = app.getInvariantDeviceProfile();
+ mRestoreEventLogger = restoreEventLogger;
// Init column indices
mIconIndex = getColumnIndexOrThrow(Favorites.ICON);
@@ -390,9 +395,12 @@
/**
* Marks the current item for removal
*/
- public void markDeleted(String reason) {
+ public void markDeleted(String reason, @RestoreError String errorType) {
FileLog.e(TAG, reason);
mItemsToRemove.add(id);
+ if (mRestoreEventLogger != null) {
+ mRestoreEventLogger.logSingleFavoritesItemRestoreFailed(itemType, errorType);
+ }
}
/**
@@ -431,6 +439,9 @@
mApp.getModel().getModelDbController().update(TABLE_NAME, values,
Utilities.createDbSelectionQuery(Favorites._ID, mRestoredRows), null);
}
+ if (mRestoreEventLogger != null) {
+ mRestoreEventLogger.reportLauncherRestoreResults();
+ }
}
/**
@@ -473,8 +484,11 @@
}
if (checkItemPlacement(info, dataModel.isFirstPagePinnedItemEnabled)) {
dataModel.addItem(mContext, info, false, logger);
+ if (mRestoreEventLogger != null) {
+ mRestoreEventLogger.logSingleFavoritesItemRestored(itemType);
+ }
} else {
- markDeleted("Item position overlap");
+ markDeleted("Item position overlap", RestoreError.INVALID_LOCATION);
}
}
diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java
index 795450a..7c3d758 100644
--- a/src/com/android/launcher3/model/LoaderTask.java
+++ b/src/com/android/launcher3/model/LoaderTask.java
@@ -95,7 +95,7 @@
import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.util.PackageUserKey;
import com.android.launcher3.util.TraceHelper;
-import com.android.launcher3.widget.WidgetManagerHelper;
+import com.android.launcher3.widget.WidgetInflater;
import java.util.ArrayList;
import java.util.Collections;
@@ -403,9 +403,8 @@
@Nullable LauncherRestoreEventLogger restoreEventLogger) {
final Context context = mApp.getContext();
final PackageManagerHelper pmHelper = new PackageManagerHelper(context);
- final boolean isSafeMode = pmHelper.isSafeMode();
final boolean isSdCardReady = Utilities.isBootCompleted();
- final WidgetManagerHelper widgetHelper = new WidgetManagerHelper(context);
+ final WidgetInflater widgetInflater = new WidgetInflater(context);
ModelDbController dbController = mApp.getModel().getModelDbController();
dbController.tryMigrateDB(restoreEventLogger);
@@ -422,13 +421,12 @@
FileLog.d(TAG, "loadWorkspace: Packages with active install sessions: "
+ installingPkgs.keySet().stream().map(info -> info.mPackageName).toList());
- final PackageUserKey tempPackageKey = new PackageUserKey(null, null);
mFirstScreenBroadcast = new FirstScreenBroadcast(installingPkgs);
mShortcutKeyToPinnedShortcuts = new HashMap<>();
final LoaderCursor c = new LoaderCursor(
dbController.query(TABLE_NAME, null, selection, null, null),
- mApp, mUserManagerState);
+ mApp, mUserManagerState, mIsRestoreFromBackup ? restoreEventLogger : null);
final Bundle extras = c.getExtras();
mDbName = extras == null ? null : extras.getString(ModelDbController.EXTRA_DB_NAME);
try {
@@ -438,11 +436,11 @@
List<IconRequestInfo<WorkspaceItemInfo>> iconRequestInfos = new ArrayList<>();
WorkspaceItemProcessor itemProcessor = new WorkspaceItemProcessor(c, memoryLogger,
- restoreEventLogger, mUserManagerState, mLauncherApps, mPendingPackages,
- mShortcutKeyToPinnedShortcuts, mApp, mIconCache, mBgDataModel,
- mWidgetProvidersMap, mIsRestoreFromBackup, installingPkgs, isSdCardReady,
- tempPackageKey, widgetHelper, pmHelper, iconRequestInfos, unlockedUsers,
- isSafeMode, allDeepShortcuts);
+ mUserManagerState, mLauncherApps, mPendingPackages,
+ mShortcutKeyToPinnedShortcuts, mApp, mBgDataModel,
+ mWidgetProvidersMap, installingPkgs, isSdCardReady,
+ widgetInflater, pmHelper, iconRequestInfos, unlockedUsers,
+ allDeepShortcuts);
while (!mStopped && c.moveToNext()) {
itemProcessor.processItem();
diff --git a/src/com/android/launcher3/model/ModelDbController.java b/src/com/android/launcher3/model/ModelDbController.java
index c68274a..6c64713 100644
--- a/src/com/android/launcher3/model/ModelDbController.java
+++ b/src/com/android/launcher3/model/ModelDbController.java
@@ -65,6 +65,7 @@
import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.Utilities;
import com.android.launcher3.backuprestore.LauncherRestoreEventLogger;
+import com.android.launcher3.backuprestore.LauncherRestoreEventLogger.RestoreError;
import com.android.launcher3.logging.FileLog;
import com.android.launcher3.pm.UserCache;
import com.android.launcher3.provider.LauncherDbUtils;
@@ -89,7 +90,6 @@
private static final String TAG = "LauncherProvider";
private static final String EMPTY_DATABASE_CREATED = "EMPTY_DATABASE_CREATED";
- private static final String RESTORE_ERROR_GRID_MIGRATION_FAILURE = "grid_migration_failed";
public static final String EXTRA_DB_NAME = "db_name";
protected DatabaseHelper mOpenHelper;
@@ -335,7 +335,7 @@
restoreEventLogger.logFavoritesItemsRestoreFailed(
cursor.getInt(cursor.getColumnIndexOrThrow(ITEM_TYPE)),
cursor.getInt(cursor.getColumnIndexOrThrow("count")),
- RESTORE_ERROR_GRID_MIGRATION_FAILURE
+ RestoreError.GRID_MIGRATION_FAILURE
);
} while (cursor.moveToNext());
}
diff --git a/src/com/android/launcher3/model/WorkspaceItemProcessor.kt b/src/com/android/launcher3/model/WorkspaceItemProcessor.kt
index 5389d38..697fbc8 100644
--- a/src/com/android/launcher3/model/WorkspaceItemProcessor.kt
+++ b/src/com/android/launcher3/model/WorkspaceItemProcessor.kt
@@ -32,22 +32,19 @@
import com.android.launcher3.LauncherAppState
import com.android.launcher3.LauncherSettings.Favorites
import com.android.launcher3.Utilities
-import com.android.launcher3.backuprestore.LauncherRestoreEventLogger
-import com.android.launcher3.icons.IconCache
+import com.android.launcher3.backuprestore.LauncherRestoreEventLogger.RestoreError
import com.android.launcher3.logging.FileLog
import com.android.launcher3.model.data.IconRequestInfo
import com.android.launcher3.model.data.ItemInfoWithIcon
import com.android.launcher3.model.data.LauncherAppWidgetInfo
import com.android.launcher3.model.data.WorkspaceItemInfo
import com.android.launcher3.pm.PackageInstallInfo
-import com.android.launcher3.qsb.QsbContainerView
import com.android.launcher3.shortcuts.ShortcutKey
import com.android.launcher3.util.ComponentKey
import com.android.launcher3.util.PackageManagerHelper
import com.android.launcher3.util.PackageUserKey
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo
-import com.android.launcher3.widget.WidgetManagerHelper
-import com.android.launcher3.widget.custom.CustomWidgetManager
+import com.android.launcher3.widget.WidgetInflater
/**
* This items is used by LoaderTask to process items that have been loaded from the Launcher's DB.
@@ -59,26 +56,26 @@
class WorkspaceItemProcessor(
private val c: LoaderCursor,
private val memoryLogger: LoaderMemoryLogger?,
- private val restoreEventLogger: LauncherRestoreEventLogger?,
private val userManagerState: UserManagerState,
private val launcherApps: LauncherApps,
private val pendingPackages: MutableSet<PackageUserKey>,
private val shortcutKeyToPinnedShortcuts: Map<ShortcutKey, ShortcutInfo>,
private val app: LauncherAppState,
- private val iconCache: IconCache,
private val bgDataModel: BgDataModel,
private val widgetProvidersMap: MutableMap<ComponentKey, AppWidgetProviderInfo?>,
- private val isRestoreFromBackup: Boolean,
private val installingPkgs: HashMap<PackageUserKey, PackageInstaller.SessionInfo>,
private val isSdCardReady: Boolean,
- private val tempPackageKey: PackageUserKey,
- private val widgetHelper: WidgetManagerHelper,
+ private val widgetInflater: WidgetInflater,
private val pmHelper: PackageManagerHelper,
private val iconRequestInfos: MutableList<IconRequestInfo<WorkspaceItemInfo>>,
private val unlockedUsers: LongSparseArray<Boolean>,
- private val isSafeMode: Boolean,
private val allDeepShortcuts: MutableList<ShortcutInfo>
) {
+
+ private val isSafeMode = app.isSafeModeEnabled
+ private val tempPackageKey = PackageUserKey(null, null)
+ private val iconCache = app.iconCache
+
/**
* This is the entry point for processing 1 workspace item. This method is like the midfielder
* that delegates the actual processing to either processAppShortcut, processFolder, or
@@ -91,13 +88,7 @@
try {
if (c.user == null) {
// User has been deleted, remove the item.
- c.markDeleted("User has been deleted")
- if (isRestoreFromBackup) {
- restoreEventLogger?.logSingleFavoritesItemRestoreFailed(
- c.itemType,
- LauncherRestoreEventLogger.RESTORE_ERROR_PROFILE_DELETED
- )
- }
+ c.markDeleted("User has been deleted", RestoreError.PROFILE_DELETED)
return
}
when (c.itemType) {
@@ -140,13 +131,7 @@
var allowMissingTarget = false
var intent = c.parseIntent()
if (intent == null) {
- c.markDeleted("Invalid or null intent")
- if (isRestoreFromBackup) {
- restoreEventLogger?.logSingleFavoritesItemRestoreFailed(
- c.itemType,
- LauncherRestoreEventLogger.RESTORE_ERROR_MISSING_INFO
- )
- }
+ c.markDeleted("Invalid or null intent", RestoreError.MISSING_INFO)
return
}
var disabledState =
@@ -156,13 +141,7 @@
var cn = intent.component
val targetPkg = if (cn == null) intent.getPackage() else cn.packageName
if (TextUtils.isEmpty(targetPkg)) {
- c.markDeleted("Shortcuts can't have null package")
- if (isRestoreFromBackup) {
- restoreEventLogger?.logSingleFavoritesItemRestoreFailed(
- c.itemType,
- LauncherRestoreEventLogger.RESTORE_ERROR_MISSING_INFO
- )
- }
+ c.markDeleted("Shortcuts can't have null package", RestoreError.MISSING_INFO)
return
}
@@ -179,9 +158,6 @@
if (launcherApps.isActivityEnabled(cn, c.user)) {
// no special handling necessary for this item
c.markRestored()
- if (isRestoreFromBackup) {
- restoreEventLogger?.logSingleFavoritesItemRestored(c.itemType)
- }
} else {
// Gracefully try to find a fallback activity.
intent = pmHelper.getAppLaunchIntent(targetPkg, c.user)
@@ -189,13 +165,10 @@
c.restoreFlag = 0
c.updater().put(Favorites.INTENT, intent.toUri(0)).commit()
} else {
- c.markDeleted("Intent null, unable to find a launch target")
- if (isRestoreFromBackup) {
- restoreEventLogger?.logSingleFavoritesItemRestoreFailed(
- c.itemType,
- LauncherRestoreEventLogger.RESTORE_ERROR_MISSING_INFO
- )
- }
+ c.markDeleted(
+ "Intent null, unable to find a launch target",
+ RestoreError.MISSING_INFO
+ )
return
}
}
@@ -225,14 +198,9 @@
}
else -> {
c.markDeleted(
- "removing app that is not restored and not installing. package: $targetPkg"
+ "removing app that is not restored and not installing. package: $targetPkg",
+ RestoreError.APP_NOT_INSTALLED
)
- if (isRestoreFromBackup) {
- restoreEventLogger?.logSingleFavoritesItemRestoreFailed(
- c.itemType,
- LauncherRestoreEventLogger.RESTORE_ERROR_APP_NOT_INSTALLED
- )
- }
return
}
}
@@ -254,13 +222,10 @@
}
else -> {
// Do not wait for external media load anymore.
- c.markDeleted("Invalid package removed: $targetPkg")
- if (isRestoreFromBackup) {
- restoreEventLogger?.logSingleFavoritesItemRestoreFailed(
- c.itemType,
- LauncherRestoreEventLogger.RESTORE_ERROR_APP_NOT_INSTALLED
- )
- }
+ c.markDeleted(
+ "Invalid package removed: $targetPkg",
+ RestoreError.APP_NOT_INSTALLED
+ )
return
}
}
@@ -290,14 +255,9 @@
if (pinnedShortcut == null) {
// The shortcut is no longer valid.
c.markDeleted(
- "Pinned shortcut not found from request. package=${key.packageName}, user=${c.user}"
+ "Pinned shortcut not found from request. package=${key.packageName}, user=${c.user}",
+ RestoreError.SHORTCUT_NOT_FOUND
)
- if (isRestoreFromBackup) {
- restoreEventLogger?.logSingleFavoritesItemRestoreFailed(
- c.itemType,
- LauncherRestoreEventLogger.RESTORE_ERROR_SHORTCUT_NOT_FOUND
- )
- }
return
}
info = WorkspaceItemInfo(pinnedShortcut, app.context)
@@ -316,9 +276,6 @@
info.runtimeStatusFlags =
info.runtimeStatusFlags or ItemInfoWithIcon.FLAG_DISABLED_LOCKED_USER
}
- if (isRestoreFromBackup) {
- restoreEventLogger?.logSingleFavoritesItemRestored(c.itemType)
- }
}
else -> { // item type == ITEM_TYPE_SHORTCUT
info = c.loadSimpleWorkspaceItem()
@@ -416,9 +373,6 @@
// no special handling required for restored folders
c.markRestored()
- if (isRestoreFromBackup) {
- restoreEventLogger?.logSingleFavoritesItemRestored(c.itemType)
- }
c.checkAndAddItem(folderInfo, bgDataModel, memoryLogger)
}
@@ -441,185 +395,94 @@
*/
@VisibleForTesting
fun processWidget() {
- if (WidgetsModel.GO_DISABLE_WIDGETS && c.itemType == Favorites.ITEM_TYPE_APPWIDGET) {
- c.markDeleted("Only legacy shortcuts can have null package")
- if (isRestoreFromBackup) {
- restoreEventLogger?.logSingleFavoritesItemRestoreFailed(
- c.itemType,
- LauncherRestoreEventLogger.RESTORE_ERROR_WIDGETS_DISABLED
- )
- }
+ val component = ComponentName.unflattenFromString(c.appWidgetProvider)!!
+ val appWidgetInfo = LauncherAppWidgetInfo(c.appWidgetId, component)
+ c.applyCommonProperties(appWidgetInfo)
+ appWidgetInfo.spanX = c.spanX
+ appWidgetInfo.spanY = c.spanY
+ appWidgetInfo.options = c.options
+ appWidgetInfo.user = c.user
+ appWidgetInfo.sourceContainer = c.appWidgetSource
+ appWidgetInfo.restoreStatus = c.restoreFlag
+ if (appWidgetInfo.spanX <= 0 || appWidgetInfo.spanY <= 0) {
+ c.markDeleted(
+ "Widget has invalid size: ${appWidgetInfo.spanX}x${appWidgetInfo.spanY}",
+ RestoreError.INVALID_LOCATION
+ )
+ return
+ }
+ if (!c.isOnWorkspaceOrHotseat) {
+ c.markDeleted(
+ "Widget found where container != CONTAINER_DESKTOP nor CONTAINER_HOTSEAT - ignoring!",
+ RestoreError.INVALID_LOCATION
+ )
+ return
+ }
+ if (appWidgetInfo.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_DIRECT_CONFIG)) {
+ appWidgetInfo.bindOptions = c.parseIntent()
+ }
+ val inflationResult = widgetInflater.inflateAppWidget(appWidgetInfo)
+ var shouldUpdate = inflationResult.isUpdate
+ if (inflationResult.type == WidgetInflater.TYPE_DELETE) {
+ c.markDeleted(inflationResult.reason, inflationResult.restoreErrorType)
return
}
- // Read all Launcher-specific widget details
- val customWidget = (c.itemType == Favorites.ITEM_TYPE_CUSTOM_APPWIDGET)
- val appWidgetId = c.appWidgetId
- val savedProvider = c.appWidgetProvider
- val component: ComponentName?
- if (c.options and LauncherAppWidgetInfo.OPTION_SEARCH_WIDGET != 0) {
- component = QsbContainerView.getSearchComponentName(app.context)
- if (component == null) {
- c.markDeleted("Discarding SearchWidget without package name")
- if (isRestoreFromBackup) {
- restoreEventLogger?.logSingleFavoritesItemRestoreFailed(
- c.itemType,
- LauncherRestoreEventLogger.RESTORE_ERROR_MISSING_INFO
- )
- }
- return
- }
- } else {
- component = ComponentName.unflattenFromString(savedProvider)
- }
- val isIdValid = !c.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_ID_NOT_VALID)
- val wasProviderReady = !c.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY)
- val providerKey = ComponentKey(component, c.user)
- if (!widgetProvidersMap.containsKey(providerKey)) {
- if (customWidget) {
- widgetProvidersMap[providerKey] =
- CustomWidgetManager.INSTANCE[app.context].getWidgetProvider(component)
- } else {
- widgetProvidersMap[providerKey] = widgetHelper.findProvider(component, c.user)
- }
- }
- val provider = widgetProvidersMap[providerKey]
- val isProviderReady = LoaderTask.isValidProvider(provider)
- if (!isSafeMode && !customWidget && wasProviderReady && !isProviderReady) {
- c.markDeleted("Deleting widget that isn't installed anymore: $provider")
- if (isRestoreFromBackup) {
- restoreEventLogger?.logSingleFavoritesItemRestoreFailed(
- c.itemType,
- LauncherRestoreEventLogger.RESTORE_ERROR_APP_NOT_INSTALLED
- )
- }
- } else {
- val appWidgetInfo: LauncherAppWidgetInfo
- if (isProviderReady) {
- appWidgetInfo = LauncherAppWidgetInfo(appWidgetId, provider!!.provider)
+ val lapi = inflationResult.widgetInfo
+ if (inflationResult.type == WidgetInflater.TYPE_PENDING) {
+ tempPackageKey.update(component.packageName, c.user)
+ val si = installingPkgs[tempPackageKey]
- // The provider is available. So the widget is either
- // available or not available. We do not need to track
- // any future restore updates.
- var status =
- (c.restoreFlag and
- LauncherAppWidgetInfo.FLAG_RESTORE_STARTED.inv() and
- LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY.inv())
- if (!wasProviderReady) {
- // If provider was not previously ready, update status and UI flag.
-
- // Id would be valid only if the widget restore broadcast received.
- if (isIdValid) {
- status = status or LauncherAppWidgetInfo.FLAG_UI_NOT_READY
- }
- }
- appWidgetInfo.restoreStatus = status
- } else {
- Log.v(
- TAG,
- "Widget restore pending id=${c.id} appWidgetId=$appWidgetId status=${c.restoreFlag}"
- )
- appWidgetInfo = LauncherAppWidgetInfo(appWidgetId, component)
- appWidgetInfo.restoreStatus = c.restoreFlag
- tempPackageKey.update(component!!.packageName, c.user)
- val si = installingPkgs[tempPackageKey]
- val installProgress = if (si == null) null else (si.getProgress() * 100).toInt()
- when {
- c.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_RESTORE_STARTED) -> {
- // Restore has started once.
- }
- installProgress != null -> {
- // App restore has started. Update the flag
- appWidgetInfo.restoreStatus =
- appWidgetInfo.restoreStatus or
- LauncherAppWidgetInfo.FLAG_RESTORE_STARTED
- }
- !isSafeMode -> {
- c.markDeleted("Unrestored widget removed: $component")
- if (isRestoreFromBackup) {
- restoreEventLogger?.logSingleFavoritesItemRestoreFailed(
- c.itemType,
- LauncherRestoreEventLogger.RESTORE_ERROR_APP_NOT_INSTALLED
- )
- }
- return
- }
- }
- appWidgetInfo.installProgress = installProgress ?: 0
- }
- if (appWidgetInfo.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_DIRECT_CONFIG)) {
- appWidgetInfo.bindOptions = c.parseIntent()
- }
- c.applyCommonProperties(appWidgetInfo)
- appWidgetInfo.spanX = c.spanX
- appWidgetInfo.spanY = c.spanY
- appWidgetInfo.options = c.options
- appWidgetInfo.user = c.user
- appWidgetInfo.sourceContainer = c.appWidgetSource
- if (appWidgetInfo.spanX <= 0 || appWidgetInfo.spanY <= 0) {
- c.markDeleted(
- "Widget has invalid size: ${appWidgetInfo.spanX}x${appWidgetInfo.spanY}"
- )
- if (isRestoreFromBackup) {
- restoreEventLogger?.logSingleFavoritesItemRestoreFailed(
- c.itemType,
- LauncherRestoreEventLogger.RESTORE_ERROR_INVALID_LOCATION
- )
- }
- return
- }
- val widgetProviderInfo =
- widgetHelper.getLauncherAppWidgetInfo(appWidgetId, appWidgetInfo.targetComponent)
if (
- widgetProviderInfo != null &&
- (appWidgetInfo.spanX < widgetProviderInfo.minSpanX ||
- appWidgetInfo.spanY < widgetProviderInfo.minSpanY)
+ !c.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_RESTORE_STARTED) &&
+ !isSafeMode &&
+ (si == null) &&
+ (lapi == null)
) {
+ // Restore never started
+ c.markDeleted(
+ "Unrestored widget removed: $component",
+ RestoreError.APP_NOT_INSTALLED
+ )
+ return
+ } else if (
+ !c.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_RESTORE_STARTED) && si != null
+ ) {
+ shouldUpdate = true
+ appWidgetInfo.restoreStatus =
+ appWidgetInfo.restoreStatus or LauncherAppWidgetInfo.FLAG_RESTORE_STARTED
+ }
+ appWidgetInfo.installProgress = if (si == null) 0 else (si.getProgress() * 100).toInt()
+ appWidgetInfo.pendingItemInfo =
+ WidgetsModel.newPendingItemInfo(
+ app.context,
+ appWidgetInfo.providerName,
+ appWidgetInfo.user
+ )
+ iconCache.getTitleAndIconForApp(appWidgetInfo.pendingItemInfo, false)
+ }
+ if (shouldUpdate) {
+ c.updater()
+ .put(Favorites.APPWIDGET_PROVIDER, component.flattenToString())
+ .put(Favorites.APPWIDGET_ID, appWidgetInfo.appWidgetId)
+ .put(Favorites.RESTORED, appWidgetInfo.restoreStatus)
+ .commit()
+ }
+ if (lapi != null) {
+ widgetProvidersMap[ComponentKey(lapi.provider, lapi.user)] = inflationResult.widgetInfo
+ if (appWidgetInfo.spanX < lapi.minSpanX || appWidgetInfo.spanY < lapi.minSpanY) {
FileLog.d(
TAG,
- "Widget ${widgetProviderInfo.component} minSizes not meet:" +
- " span=${appWidgetInfo.spanX}x${appWidgetInfo.spanY}" +
- " minSpan=${widgetProviderInfo.minSpanX}x${widgetProviderInfo.minSpanY}"
+ "Widget ${lapi.component} minSizes not meet: span=${appWidgetInfo.spanX}x${appWidgetInfo.spanY} minSpan=${lapi.minSpanX}x${lapi.minSpanY}"
)
- logWidgetInfo(app.invariantDeviceProfile, widgetProviderInfo)
+ logWidgetInfo(app.invariantDeviceProfile, lapi)
}
- if (!c.isOnWorkspaceOrHotseat) {
- c.markDeleted(
- "Widget found where container != CONTAINER_DESKTOP" +
- " nor CONTAINER_HOTSEAT - ignoring!"
- )
- if (isRestoreFromBackup) {
- restoreEventLogger?.logSingleFavoritesItemRestoreFailed(
- c.itemType,
- LauncherRestoreEventLogger.RESTORE_ERROR_INVALID_LOCATION
- )
- }
- return
- }
- if (!customWidget) {
- val providerName = appWidgetInfo.providerName.flattenToString()
- if (providerName != savedProvider || appWidgetInfo.restoreStatus != c.restoreFlag) {
- c.updater()
- .put(Favorites.APPWIDGET_PROVIDER, providerName)
- .put(Favorites.RESTORED, appWidgetInfo.restoreStatus)
- .commit()
- }
- }
- if (appWidgetInfo.restoreStatus != LauncherAppWidgetInfo.RESTORE_COMPLETED) {
- appWidgetInfo.pendingItemInfo =
- WidgetsModel.newPendingItemInfo(
- app.context,
- appWidgetInfo.providerName,
- appWidgetInfo.user
- )
- iconCache.getTitleAndIconForApp(appWidgetInfo.pendingItemInfo, false)
- }
- c.checkAndAddItem(appWidgetInfo, bgDataModel)
}
+ c.checkAndAddItem(appWidgetInfo, bgDataModel)
}
companion object {
- private val TAG = WorkspaceItemProcessor::class.java.simpleName
+ private const val TAG = "WorkspaceItemProcessor"
private fun logWidgetInfo(
idp: InvariantDeviceProfile,
widgetProviderInfo: LauncherAppWidgetProviderInfo
diff --git a/src/com/android/launcher3/provider/LauncherDbUtils.java b/src/com/android/launcher3/provider/LauncherDbUtils.java
index 30958d9..1f15947 100644
--- a/src/com/android/launcher3/provider/LauncherDbUtils.java
+++ b/src/com/android/launcher3/provider/LauncherDbUtils.java
@@ -109,7 +109,7 @@
UserManagerState ums = new UserManagerState();
ums.init(UserCache.INSTANCE.get(context),
context.getSystemService(UserManager.class));
- LoaderCursor lc = new LoaderCursor(c, LauncherAppState.getInstance(context), ums);
+ LoaderCursor lc = new LoaderCursor(c, LauncherAppState.getInstance(context), ums, null);
IntSet deletedShortcuts = new IntSet();
while (lc.moveToNext()) {
diff --git a/src/com/android/launcher3/provider/RestoreDbTask.java b/src/com/android/launcher3/provider/RestoreDbTask.java
index 9750d25..1c53855 100644
--- a/src/com/android/launcher3/provider/RestoreDbTask.java
+++ b/src/com/android/launcher3/provider/RestoreDbTask.java
@@ -27,9 +27,6 @@
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE;
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET;
-import static com.android.launcher3.backuprestore.LauncherRestoreEventLogger.RESTORE_ERROR_PROFILE_NOT_RESTORED;
-import static com.android.launcher3.backuprestore.LauncherRestoreEventLogger.RESTORE_ERROR_WIDGETS_DISABLED;
-import static com.android.launcher3.backuprestore.LauncherRestoreEventLogger.RESTORE_ERROR_WIDGET_REMOVED;
import static com.android.launcher3.provider.LauncherDbUtils.dropTable;
import static com.android.launcher3.widget.LauncherWidgetHolder.APPWIDGET_HOST_ID;
@@ -60,6 +57,7 @@
import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.Utilities;
import com.android.launcher3.backuprestore.LauncherRestoreEventLogger;
+import com.android.launcher3.backuprestore.LauncherRestoreEventLogger.RestoreError;
import com.android.launcher3.logging.FileLog;
import com.android.launcher3.model.DeviceGridState;
import com.android.launcher3.model.LoaderTask;
@@ -394,7 +392,7 @@
FileLog.e(TAG, "Skipping widget ID remap as widgets not supported");
host.deleteHost();
launcherRestoreEventLogger.logFavoritesItemsRestoreFailed(Favorites.ITEM_TYPE_APPWIDGET,
- oldWidgetIds.length, RESTORE_ERROR_WIDGETS_DISABLED);
+ oldWidgetIds.length, RestoreError.WIDGETS_DISABLED);
return;
}
if (!RestoreDbTask.isPending(context)) {
@@ -460,7 +458,7 @@
host.deleteAppWidgetId(newWidgetIds[i]);
launcherRestoreEventLogger.logSingleFavoritesItemRestoreFailed(
ITEM_TYPE_APPWIDGET,
- RESTORE_ERROR_WIDGET_REMOVED
+ RestoreError.WIDGET_REMOVED
);
}
}
@@ -620,7 +618,7 @@
restoreEventLogger.logFavoritesItemsRestoreFailed(
cursor.getInt(cursor.getColumnIndexOrThrow(ITEM_TYPE)),
cursor.getInt(cursor.getColumnIndexOrThrow("count")),
- RESTORE_ERROR_PROFILE_NOT_RESTORED
+ RestoreError.PROFILE_NOT_RESTORED
);
} while (cursor.moveToNext());
}
diff --git a/src/com/android/launcher3/util/PackageManagerHelper.java b/src/com/android/launcher3/util/PackageManagerHelper.java
index 3f7a128..2b5aaf5 100644
--- a/src/com/android/launcher3/util/PackageManagerHelper.java
+++ b/src/com/android/launcher3/util/PackageManagerHelper.java
@@ -119,10 +119,6 @@
}
}
- public boolean isSafeMode() {
- return mPm.isSafeMode();
- }
-
@Nullable
public Intent getAppLaunchIntent(@Nullable final String pkg, @NonNull final UserHandle user) {
List<LauncherActivityInfo> activities = mLauncherApps.getActivityList(pkg, user);
diff --git a/src/com/android/launcher3/widget/WidgetInflater.kt b/src/com/android/launcher3/widget/WidgetInflater.kt
index 00707f5..dd50b71 100644
--- a/src/com/android/launcher3/widget/WidgetInflater.kt
+++ b/src/com/android/launcher3/widget/WidgetInflater.kt
@@ -19,6 +19,7 @@
import android.content.Context
import com.android.launcher3.Launcher
import com.android.launcher3.LauncherAppState
+import com.android.launcher3.backuprestore.LauncherRestoreEventLogger.RestoreError
import com.android.launcher3.logging.FileLog
import com.android.launcher3.model.WidgetsModel
import com.android.launcher3.model.data.LauncherAppWidgetInfo
@@ -37,7 +38,8 @@
if (item.providerName == null) {
return InflationResult(
TYPE_DELETE,
- reason = "search widget removed because search component cannot be found"
+ reason = "search widget removed because search component cannot be found",
+ restoreErrorType = RestoreError.NO_SEARCH_WIDGET
)
}
}
@@ -46,19 +48,25 @@
}
val appWidgetInfo: LauncherAppWidgetProviderInfo?
var removalReason = ""
- if (item.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY)) {
- // If the provider is not ready, bind as a pending widget.
- appWidgetInfo = null
- removalReason = "the provider isn't ready."
- } else if (item.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_ID_NOT_VALID)) {
+ @RestoreError var logReason = RestoreError.APP_NOT_INSTALLED
+ var update = false
+
+ if (item.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_ID_NOT_VALID)) {
// The widget id is not valid. Try to find the widget based on the provider info.
appWidgetInfo = widgetHelper.findProvider(item.providerName, item.user)
if (appWidgetInfo == null) {
if (WidgetsModel.GO_DISABLE_WIDGETS) {
removalReason = "widgets are disabled on go device."
+ logReason = RestoreError.WIDGETS_DISABLED
} else {
removalReason = "WidgetManagerHelper cannot find a provider from provider info."
+ logReason = RestoreError.MISSING_WIDGET_PROVIDER
}
+ } else if (item.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY)) {
+ // since appWidgetInfo is not null anymore, update the provider status
+ item.restoreStatus =
+ item.restoreStatus and LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY.inv()
+ update = true
}
} else {
appWidgetInfo =
@@ -66,19 +74,19 @@
if (appWidgetInfo == null) {
if (item.appWidgetId <= LauncherAppWidgetInfo.CUSTOM_WIDGET_ID) {
removalReason = "CustomWidgetManager cannot find provider from that widget id."
+ logReason = RestoreError.MISSING_INFO
} else {
removalReason =
("AppWidgetManager cannot find provider for that widget id." +
" It could be because AppWidgetService is not available, or the" +
" appWidgetId has not been bound to a the provider yet, or you" +
" don't have access to that appWidgetId.")
+ logReason = RestoreError.INVALID_WIDGET_ID
}
}
}
- var update = false
-
- // If the provider is ready, but the width is not yet restored, try to restore it.
+ // If the provider is ready, but the widget is not yet restored, try to restore it.
if (
!item.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY) &&
item.restoreStatus != LauncherAppWidgetInfo.RESTORE_COMPLETED
@@ -87,9 +95,8 @@
return InflationResult(
type = TYPE_DELETE,
reason =
- "Removing restored widget: id=${item.appWidgetId} belongs to component" +
- " ${item.providerName} user ${item.user}" +
- ", as the provider is null and $removalReason"
+ "Removing restored widget: id=${item.appWidgetId} belongs to component ${item.providerName} user ${item.user}, as the provider is null and $removalReason",
+ restoreErrorType = logReason
)
}
@@ -182,6 +189,7 @@
data class InflationResult(
val type: Int,
val reason: String? = null,
+ @RestoreError val restoreErrorType: String = RestoreError.APP_NOT_INSTALLED,
val isUpdate: Boolean = false,
val widgetInfo: LauncherAppWidgetProviderInfo? = null
)
diff --git a/src/com/android/launcher3/widget/WidgetManagerHelper.java b/src/com/android/launcher3/widget/WidgetManagerHelper.java
index 0860e72..058523b 100644
--- a/src/com/android/launcher3/widget/WidgetManagerHelper.java
+++ b/src/com/android/launcher3/widget/WidgetManagerHelper.java
@@ -61,8 +61,7 @@
int appWidgetId, ComponentName componentName) {
// For custom widgets.
- if (appWidgetId <= LauncherAppWidgetInfo.CUSTOM_WIDGET_ID && !CustomWidgetManager
- .INSTANCE.get(mContext).getWidgetIdForCustomProvider(componentName).equals("")) {
+ if (appWidgetId <= LauncherAppWidgetInfo.CUSTOM_WIDGET_ID) {
return CustomWidgetManager.INSTANCE.get(mContext).getWidgetProvider(componentName);
}
diff --git a/src/com/android/launcher3/widget/custom/CustomAppWidgetProviderInfo.java b/src/com/android/launcher3/widget/custom/CustomAppWidgetProviderInfo.java
index 44571a6..398b1df 100644
--- a/src/com/android/launcher3/widget/custom/CustomAppWidgetProviderInfo.java
+++ b/src/com/android/launcher3/widget/custom/CustomAppWidgetProviderInfo.java
@@ -33,13 +33,9 @@
public class CustomAppWidgetProviderInfo extends LauncherAppWidgetProviderInfo
implements Parcelable {
- public final String providerId;
-
- protected CustomAppWidgetProviderInfo(Parcel parcel, boolean readSelf, String providerId) {
+ protected CustomAppWidgetProviderInfo(Parcel parcel, boolean readSelf) {
super(parcel);
if (readSelf) {
- this.providerId = parcel.readString();
-
provider = new ComponentName(parcel.readString(),
CLS_CUSTOM_WIDGET_PREFIX + parcel.readString());
@@ -53,8 +49,6 @@
spanY = parcel.readInt();
minSpanX = parcel.readInt();
minSpanY = parcel.readInt();
- } else {
- this.providerId = providerId;
}
}
@@ -77,7 +71,6 @@
@Override
public void writeToParcel(Parcel out, int flags) {
super.writeToParcel(out, flags);
- out.writeString(providerId);
out.writeString(provider.getPackageName());
out.writeString(provider.getClassName());
@@ -93,12 +86,12 @@
out.writeInt(minSpanY);
}
- public static final Parcelable.Creator<CustomAppWidgetProviderInfo> CREATOR
- = new Parcelable.Creator<CustomAppWidgetProviderInfo>() {
+ public static final Parcelable.Creator<CustomAppWidgetProviderInfo> CREATOR =
+ new Parcelable.Creator<>() {
@Override
public CustomAppWidgetProviderInfo createFromParcel(Parcel parcel) {
- return new CustomAppWidgetProviderInfo(parcel, true, "");
+ return new CustomAppWidgetProviderInfo(parcel, true);
}
@Override
diff --git a/src/com/android/launcher3/widget/custom/CustomWidgetManager.java b/src/com/android/launcher3/widget/custom/CustomWidgetManager.java
index 7cf0221..2fdf354 100644
--- a/src/com/android/launcher3/widget/custom/CustomWidgetManager.java
+++ b/src/com/android/launcher3/widget/custom/CustomWidgetManager.java
@@ -18,6 +18,7 @@
import static com.android.launcher3.config.FeatureFlags.SMARTSPACE_AS_A_WIDGET;
import static com.android.launcher3.model.data.LauncherAppWidgetInfo.CUSTOM_WIDGET_ID;
+import static com.android.launcher3.widget.LauncherAppWidgetProviderInfo.CLS_CUSTOM_WIDGET_PREFIX;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProviderInfo;
@@ -44,7 +45,6 @@
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
-import java.util.Map;
import java.util.function.Consumer;
import java.util.stream.Stream;
@@ -57,17 +57,16 @@
new MainThreadInitializedObject<>(CustomWidgetManager::new);
private static final String TAG = "CustomWidgetManager";
+ private static final String PLUGIN_PKG = "android";
private final Context mContext;
- private final HashMap<String, CustomWidgetPlugin> mPlugins;
+ private final HashMap<ComponentName, CustomWidgetPlugin> mPlugins;
private final List<CustomAppWidgetProviderInfo> mCustomWidgets;
- private final HashMap<ComponentName, String> mWidgetsIdMap;
private Consumer<PackageUserKey> mWidgetRefreshCallback;
private CustomWidgetManager(Context context) {
mContext = context;
mPlugins = new HashMap<>();
mCustomWidgets = new ArrayList<>();
- mWidgetsIdMap = new HashMap<>();
PluginManagerWrapper.INSTANCE.get(context)
.addPluginListener(this, CustomWidgetPlugin.class, true);
@@ -78,8 +77,7 @@
Class<?> cls = Class.forName(s);
CustomWidgetPlugin plugin = (CustomWidgetPlugin)
cls.getDeclaredConstructor(Context.class).newInstance(context);
- mPlugins.put(plugin.getId(), plugin);
- onPluginConnected(mPlugins.get(plugin.getId()), context);
+ onPluginConnected(plugin, context);
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException
| ClassCastException | NoSuchMethodException
| InvocationTargetException e) {
@@ -102,35 +100,17 @@
Parcel parcel = Parcel.obtain();
providers.get(0).writeToParcel(parcel, 0);
parcel.setDataPosition(0);
- CustomAppWidgetProviderInfo info = newInfo(plugin.getId(), plugin, parcel, context);
+ CustomAppWidgetProviderInfo info = newInfo(plugin, parcel);
parcel.recycle();
+ mPlugins.put(info.provider, plugin);
mCustomWidgets.add(info);
- mWidgetsIdMap.put(info.provider, plugin.getId());
}
@Override
public void onPluginDisconnected(CustomWidgetPlugin plugin) {
- String providerId = plugin.getId();
- if (mPlugins.containsKey(providerId)) {
- mPlugins.remove(providerId);
- }
-
- ComponentName cn = null;
- for (Map.Entry entry: mWidgetsIdMap.entrySet()) {
- if (entry.getValue().equals(providerId)) {
- cn = (ComponentName) entry.getKey();
- }
- }
-
- if (cn != null) {
- mWidgetsIdMap.remove(cn);
- for (int i = 0; i < mCustomWidgets.size(); i++) {
- if (mCustomWidgets.get(i).getComponent().equals(cn)) {
- mCustomWidgets.remove(i);
- return;
- }
- }
- }
+ ComponentName cn = getWidgetProviderComponent(plugin);
+ mPlugins.remove(cn);
+ mCustomWidgets.removeIf(w -> w.getComponent().equals(cn));
}
/**
@@ -145,7 +125,7 @@
*/
public void onViewCreated(LauncherAppWidgetHostView view) {
CustomAppWidgetProviderInfo info = (CustomAppWidgetProviderInfo) view.getAppWidgetInfo();
- CustomWidgetPlugin plugin = mPlugins.get(info.providerId);
+ CustomWidgetPlugin plugin = mPlugins.get(info.provider);
if (plugin == null) return;
plugin.onViewCreated(view);
}
@@ -159,32 +139,18 @@
}
/**
- * Returns the widget id for a specific provider.
- */
- public String getWidgetIdForCustomProvider(@NonNull ComponentName provider) {
- if (mWidgetsIdMap.containsKey(provider)) {
- return mWidgetsIdMap.get(provider);
- } else {
- return "";
- }
- }
-
- /**
* Returns the widget provider in respect to given widget id.
*/
@Nullable
- public LauncherAppWidgetProviderInfo getWidgetProvider(ComponentName componentName) {
- for (LauncherAppWidgetProviderInfo info : mCustomWidgets) {
- if (info.provider.equals(componentName)) return info;
- }
- return null;
+ public LauncherAppWidgetProviderInfo getWidgetProvider(ComponentName cn) {
+ return mCustomWidgets.stream()
+ .filter(w -> w.getComponent().equals(cn)).findAny().orElse(null);
}
- private static CustomAppWidgetProviderInfo newInfo(String providerId, CustomWidgetPlugin plugin,
- Parcel parcel, Context context) {
- CustomAppWidgetProviderInfo info = new CustomAppWidgetProviderInfo(
- parcel, false, providerId);
- plugin.updateWidgetInfo(info, context);
+ private CustomAppWidgetProviderInfo newInfo(CustomWidgetPlugin plugin, Parcel parcel) {
+ CustomAppWidgetProviderInfo info = new CustomAppWidgetProviderInfo(parcel, false);
+ info.provider = getWidgetProviderComponent(plugin);
+ plugin.updateWidgetInfo(info, mContext);
return info;
}
@@ -195,4 +161,8 @@
return CUSTOM_WIDGET_ID - mCustomWidgets.indexOf(getWidgetProvider(componentName));
}
+ private ComponentName getWidgetProviderComponent(CustomWidgetPlugin plugin) {
+ return new ComponentName(
+ PLUGIN_PKG, CLS_CUSTOM_WIDGET_PREFIX + plugin.getClass().getName());
+ }
}