mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-02-20 11:18:21 +00:00
Merge "Load Delegate Items in correct order when loading Launcher Data." into udc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
eac832aedd
@@ -48,11 +48,15 @@ import android.os.UserHandle;
|
||||
import android.util.Log;
|
||||
import android.util.StatsEvent;
|
||||
|
||||
import androidx.annotation.AnyThread;
|
||||
import androidx.annotation.CallSuper;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.WorkerThread;
|
||||
|
||||
import com.android.launcher3.InvariantDeviceProfile;
|
||||
import com.android.launcher3.LauncherAppState;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.logger.LauncherAtom;
|
||||
import com.android.launcher3.logging.InstanceId;
|
||||
import com.android.launcher3.logging.InstanceIdSequence;
|
||||
@@ -62,6 +66,7 @@ import com.android.launcher3.model.data.FolderInfo;
|
||||
import com.android.launcher3.model.data.ItemInfo;
|
||||
import com.android.launcher3.model.data.WorkspaceItemInfo;
|
||||
import com.android.launcher3.shortcuts.ShortcutKey;
|
||||
import com.android.launcher3.util.Executors;
|
||||
import com.android.launcher3.util.IntSparseArrayMap;
|
||||
import com.android.launcher3.util.PersistedItemArray;
|
||||
import com.android.quickstep.logging.SettingsChangeLogger;
|
||||
@@ -111,45 +116,80 @@ public class QuickstepModelDelegate extends ModelDelegate {
|
||||
mStatsManager = context.getSystemService(StatsManager.class);
|
||||
}
|
||||
|
||||
@CallSuper
|
||||
@Override
|
||||
public void loadHotseatItems(UserManagerState ums,
|
||||
Map<ShortcutKey, ShortcutInfo> pinnedShortcuts) {
|
||||
// TODO: Implement caching and preloading
|
||||
super.loadHotseatItems(ums, pinnedShortcuts);
|
||||
|
||||
WorkspaceItemFactory hotseatFactory = new WorkspaceItemFactory(mApp, ums, pinnedShortcuts,
|
||||
mIDP.numDatabaseHotseatIcons, mHotseatState.containerId);
|
||||
FixedContainerItems hotseatItems = new FixedContainerItems(mHotseatState.containerId,
|
||||
mHotseatState.storage.read(mApp.getContext(), hotseatFactory, ums.allUsers::get));
|
||||
mDataModel.extraItems.put(mHotseatState.containerId, hotseatItems);
|
||||
public void loadAndBindWorkspaceItems(@NonNull UserManagerState ums,
|
||||
@NonNull BgDataModel.Callbacks[] callbacks,
|
||||
@NonNull Map<ShortcutKey, ShortcutInfo> pinnedShortcuts) {
|
||||
loadAndBindItems(ums, pinnedShortcuts, callbacks, mIDP.numDatabaseHotseatIcons,
|
||||
mHotseatState);
|
||||
}
|
||||
|
||||
@CallSuper
|
||||
@Override
|
||||
public void loadAllAppsItems(UserManagerState ums,
|
||||
Map<ShortcutKey, ShortcutInfo> pinnedShortcuts) {
|
||||
// TODO: Implement caching and preloading
|
||||
super.loadAllAppsItems(ums, pinnedShortcuts);
|
||||
|
||||
WorkspaceItemFactory allAppsFactory = new WorkspaceItemFactory(mApp, ums, pinnedShortcuts,
|
||||
mIDP.numDatabaseAllAppsColumns, mAllAppsState.containerId);
|
||||
FixedContainerItems allAppsPredictionItems = new FixedContainerItems(
|
||||
mAllAppsState.containerId, mAllAppsState.storage.read(mApp.getContext(),
|
||||
allAppsFactory, ums.allUsers::get));
|
||||
mDataModel.extraItems.put(mAllAppsState.containerId, allAppsPredictionItems);
|
||||
public void loadAndBindAllAppsItems(@NonNull UserManagerState ums,
|
||||
@NonNull BgDataModel.Callbacks[] callbacks,
|
||||
@NonNull Map<ShortcutKey, ShortcutInfo> pinnedShortcuts) {
|
||||
loadAndBindItems(ums, pinnedShortcuts, callbacks, mIDP.numDatabaseAllAppsColumns,
|
||||
mAllAppsState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadWidgetsRecommendationItems() {
|
||||
@WorkerThread
|
||||
private void loadAndBindItems(@NonNull UserManagerState ums,
|
||||
@NonNull Map<ShortcutKey, ShortcutInfo> pinnedShortcuts,
|
||||
@NonNull BgDataModel.Callbacks[] callbacks,
|
||||
int numColumns, @NonNull PredictorState state) {
|
||||
// TODO: Implement caching and preloading
|
||||
super.loadWidgetsRecommendationItems();
|
||||
|
||||
WorkspaceItemFactory factory =
|
||||
new WorkspaceItemFactory(mApp, ums, pinnedShortcuts, numColumns, state.containerId);
|
||||
FixedContainerItems fci = new FixedContainerItems(state.containerId,
|
||||
state.storage.read(mApp.getContext(), factory, ums.allUsers::get));
|
||||
if (FeatureFlags.CHANGE_MODEL_DELEGATE_LOADING_ORDER.get()) {
|
||||
bindPredictionItems(callbacks, fci);
|
||||
}
|
||||
mDataModel.extraItems.put(state.containerId, fci);
|
||||
}
|
||||
|
||||
@CallSuper
|
||||
@Override
|
||||
public void loadAndBindOtherItems(@NonNull BgDataModel.Callbacks[] callbacks) {
|
||||
FixedContainerItems widgetPredictionFCI = new FixedContainerItems(
|
||||
mWidgetsRecommendationState.containerId, new ArrayList<>());
|
||||
|
||||
// Widgets prediction isn't used frequently. And thus, it is not persisted on disk.
|
||||
mDataModel.extraItems.put(mWidgetsRecommendationState.containerId,
|
||||
new FixedContainerItems(mWidgetsRecommendationState.containerId,
|
||||
new ArrayList<>()));
|
||||
mDataModel.extraItems.put(mWidgetsRecommendationState.containerId, widgetPredictionFCI);
|
||||
|
||||
bindPredictionItems(callbacks, widgetPredictionFCI);
|
||||
loadStringCache(mDataModel.stringCache);
|
||||
}
|
||||
|
||||
@AnyThread
|
||||
private void bindPredictionItems(@NonNull BgDataModel.Callbacks[] callbacks,
|
||||
@NonNull FixedContainerItems fci) {
|
||||
Executors.MAIN_EXECUTOR.execute(() -> {
|
||||
for (BgDataModel.Callbacks c : callbacks) {
|
||||
c.bindExtraContainerItems(fci);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@WorkerThread
|
||||
public void bindAllModelExtras(@NonNull BgDataModel.Callbacks[] callbacks) {
|
||||
Iterable<FixedContainerItems> containerItems;
|
||||
synchronized (mDataModel.extraItems) {
|
||||
containerItems = mDataModel.extraItems.clone();
|
||||
}
|
||||
Executors.MAIN_EXECUTOR.execute(() -> {
|
||||
for (BgDataModel.Callbacks c : callbacks) {
|
||||
for (FixedContainerItems fci : containerItems) {
|
||||
c.bindExtraContainerItems(fci);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void markActive() {
|
||||
super.markActive();
|
||||
mActive = true;
|
||||
|
||||
@@ -421,6 +421,9 @@ public class LauncherModel extends LauncherApps.Callback implements InstallSessi
|
||||
launcherBinder.bindAllApps();
|
||||
launcherBinder.bindDeepShortcuts();
|
||||
launcherBinder.bindWidgets();
|
||||
if (FeatureFlags.CHANGE_MODEL_DELEGATE_LOADING_ORDER.get()) {
|
||||
mModelDelegate.bindAllModelExtras(callbacksList);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
stopLoader();
|
||||
|
||||
@@ -349,6 +349,11 @@ public final class FeatureFlags {
|
||||
"load the current workspace screen visible to the user before the rest rather than "
|
||||
+ "loading all of them at once.");
|
||||
|
||||
public static final BooleanFlag CHANGE_MODEL_DELEGATE_LOADING_ORDER = getDebugFlag(251502424,
|
||||
"CHANGE_MODEL_DELEGATE_LOADING_ORDER", DISABLED,
|
||||
"changes the timing of the loading and binding of delegate items during "
|
||||
+ "data preparation for loading the home screen");
|
||||
|
||||
public static final BooleanFlag ENABLE_GRID_ONLY_OVERVIEW = getDebugFlag(270397206,
|
||||
"ENABLE_GRID_ONLY_OVERVIEW", DISABLED,
|
||||
"Enable a grid-only overview without a focused task.");
|
||||
|
||||
@@ -229,8 +229,8 @@ public class PreviewSurfaceRenderer {
|
||||
query += " or " + LauncherSettings.Favorites.SCREEN + " = "
|
||||
+ Workspace.SECOND_SCREEN_ID;
|
||||
}
|
||||
loadWorkspace(new ArrayList<>(), LauncherSettings.Favorites.PREVIEW_CONTENT_URI,
|
||||
query);
|
||||
loadWorkspaceForPreviewSurfaceRenderer(new ArrayList<>(),
|
||||
LauncherSettings.Favorites.PREVIEW_CONTENT_URI, query);
|
||||
|
||||
final SparseArray<Size> spanInfo =
|
||||
getLoadedLauncherWidgetInfo(previewContext.getBaseContext());
|
||||
|
||||
@@ -63,7 +63,7 @@ public abstract class BaseLauncherBinder {
|
||||
protected final BgDataModel mBgDataModel;
|
||||
private final AllAppsList mBgAllAppsList;
|
||||
|
||||
private final Callbacks[] mCallbacksList;
|
||||
final Callbacks[] mCallbacksList;
|
||||
|
||||
private int mMyBindingId;
|
||||
|
||||
@@ -293,8 +293,10 @@ public abstract class BaseLauncherBinder {
|
||||
// Load items on the current page.
|
||||
bindWorkspaceItems(currentWorkspaceItems, mUiExecutor);
|
||||
bindAppWidgets(currentAppWidgets, mUiExecutor);
|
||||
mExtraItems.forEach(item ->
|
||||
executeCallbacksTask(c -> c.bindExtraContainerItems(item), mUiExecutor));
|
||||
if (!FeatureFlags.CHANGE_MODEL_DELEGATE_LOADING_ORDER.get()) {
|
||||
mExtraItems.forEach(item ->
|
||||
executeCallbacksTask(c -> c.bindExtraContainerItems(item), mUiExecutor));
|
||||
}
|
||||
|
||||
RunnableList pendingTasks = new RunnableList();
|
||||
Executor pendingExecutor = pendingTasks::add;
|
||||
@@ -382,14 +384,22 @@ public abstract class BaseLauncherBinder {
|
||||
// Save a copy of all the bg-thread collections
|
||||
ArrayList<ItemInfo> workspaceItems;
|
||||
ArrayList<LauncherAppWidgetInfo> appWidgets;
|
||||
ArrayList<FixedContainerItems> fciList = new ArrayList<>();
|
||||
|
||||
synchronized (mBgDataModel) {
|
||||
workspaceItems = new ArrayList<>(mBgDataModel.workspaceItems);
|
||||
appWidgets = new ArrayList<>(mBgDataModel.appWidgets);
|
||||
if (!FeatureFlags.CHANGE_MODEL_DELEGATE_LOADING_ORDER.get()) {
|
||||
mBgDataModel.extraItems.forEach(fciList::add);
|
||||
}
|
||||
}
|
||||
|
||||
workspaceItems.forEach(it -> mBoundItemIds.add(it.id));
|
||||
appWidgets.forEach(it -> mBoundItemIds.add(it.id));
|
||||
if (!FeatureFlags.CHANGE_MODEL_DELEGATE_LOADING_ORDER.get()) {
|
||||
fciList.forEach(item ->
|
||||
executeCallbacksTask(c -> c.bindExtraContainerItems(item), mUiExecutor));
|
||||
}
|
||||
|
||||
sortWorkspaceItemsSpatially(mApp.getInvariantDeviceProfile(), workspaceItems);
|
||||
|
||||
|
||||
@@ -138,6 +138,7 @@ public class LoaderTask implements Runnable {
|
||||
private final UserManagerState mUserManagerState = new UserManagerState();
|
||||
|
||||
protected final Map<ComponentKey, AppWidgetProviderInfo> mWidgetProvidersMap = new ArrayMap<>();
|
||||
private Map<ShortcutKey, ShortcutInfo> mShortcutKeyToPinnedShortcuts;
|
||||
|
||||
private boolean mStopped;
|
||||
|
||||
@@ -211,6 +212,14 @@ public class LoaderTask implements Runnable {
|
||||
}
|
||||
logASplit(timingLogger, "loadWorkspace");
|
||||
|
||||
if (FeatureFlags.CHANGE_MODEL_DELEGATE_LOADING_ORDER.get()) {
|
||||
verifyNotStopped();
|
||||
mModelDelegate.loadAndBindWorkspaceItems(mUserManagerState,
|
||||
mLauncherBinder.mCallbacksList, mShortcutKeyToPinnedShortcuts);
|
||||
mModelDelegate.markActive();
|
||||
logASplit(timingLogger, "workspaceDelegateItems");
|
||||
}
|
||||
|
||||
// Sanitize data re-syncs widgets/shortcuts based on the workspace loaded from db.
|
||||
// sanitizeData should not be invoked if the workspace is loaded from a db different
|
||||
// from the main db as defined in the invariant device profile.
|
||||
@@ -246,6 +255,11 @@ public class LoaderTask implements Runnable {
|
||||
}
|
||||
logASplit(timingLogger, "loadAllApps");
|
||||
|
||||
if (FeatureFlags.CHANGE_MODEL_DELEGATE_LOADING_ORDER.get()) {
|
||||
mModelDelegate.loadAndBindAllAppsItems(mUserManagerState,
|
||||
mLauncherBinder.mCallbacksList, mShortcutKeyToPinnedShortcuts);
|
||||
logASplit(timingLogger, "allAppsDelegateItems");
|
||||
}
|
||||
verifyNotStopped();
|
||||
mLauncherBinder.bindAllApps();
|
||||
logASplit(timingLogger, "bindAllApps");
|
||||
@@ -296,6 +310,12 @@ public class LoaderTask implements Runnable {
|
||||
logASplit(timingLogger, "bindWidgets");
|
||||
verifyNotStopped();
|
||||
|
||||
if (FeatureFlags.CHANGE_MODEL_DELEGATE_LOADING_ORDER.get()) {
|
||||
mModelDelegate.loadAndBindOtherItems(mLauncherBinder.mCallbacksList);
|
||||
logASplit(timingLogger, "otherDelegateItems");
|
||||
verifyNotStopped();
|
||||
}
|
||||
|
||||
updateHandler.updateIcons(allWidgetsList,
|
||||
new ComponentWithIconCachingLogic(mApp.getContext(), true),
|
||||
mApp.getModel()::onWidgetLabelsUpdated);
|
||||
@@ -334,9 +354,14 @@ public class LoaderTask implements Runnable {
|
||||
null /* selection */, memoryLogger);
|
||||
}
|
||||
|
||||
protected void loadWorkspace(
|
||||
protected void loadWorkspaceForPreviewSurfaceRenderer(
|
||||
List<ShortcutInfo> allDeepShortcuts, Uri contentUri, String selection) {
|
||||
loadWorkspace(allDeepShortcuts, contentUri, selection, null);
|
||||
if (FeatureFlags.CHANGE_MODEL_DELEGATE_LOADING_ORDER.get()) {
|
||||
mModelDelegate.loadAndBindWorkspaceItems(mUserManagerState,
|
||||
mLauncherBinder.mCallbacksList, mShortcutKeyToPinnedShortcuts);
|
||||
mModelDelegate.markActive();
|
||||
}
|
||||
}
|
||||
|
||||
protected void loadWorkspace(
|
||||
@@ -376,7 +401,7 @@ public class LoaderTask implements Runnable {
|
||||
final PackageUserKey tempPackageKey = new PackageUserKey(null, null);
|
||||
mFirstScreenBroadcast = new FirstScreenBroadcast(installingPkgs);
|
||||
|
||||
Map<ShortcutKey, ShortcutInfo> shortcutKeyToPinnedShortcuts = new HashMap<>();
|
||||
mShortcutKeyToPinnedShortcuts = new HashMap<>();
|
||||
final LoaderCursor c = new LoaderCursor(
|
||||
contentResolver.query(contentUri, null, selection, null, null), contentUri,
|
||||
mApp, mUserManagerState);
|
||||
@@ -397,7 +422,7 @@ public class LoaderTask implements Runnable {
|
||||
.query(ShortcutRequest.PINNED);
|
||||
if (pinnedShortcuts.wasSuccess()) {
|
||||
for (ShortcutInfo shortcut : pinnedShortcuts) {
|
||||
shortcutKeyToPinnedShortcuts.put(ShortcutKey.fromInfo(shortcut),
|
||||
mShortcutKeyToPinnedShortcuts.put(ShortcutKey.fromInfo(shortcut),
|
||||
shortcut);
|
||||
}
|
||||
} else {
|
||||
@@ -414,7 +439,7 @@ public class LoaderTask implements Runnable {
|
||||
|
||||
while (!mStopped && c.moveToNext()) {
|
||||
processWorkspaceItem(c, memoryLogger, installingPkgs, isSdCardReady,
|
||||
tempPackageKey, widgetHelper, pmHelper, shortcutKeyToPinnedShortcuts,
|
||||
tempPackageKey, widgetHelper, pmHelper,
|
||||
iconRequestInfos, unlockedUsers, isSafeMode, allDeepShortcuts);
|
||||
}
|
||||
tryLoadWorkspaceIconsInBulk(iconRequestInfos);
|
||||
@@ -422,14 +447,14 @@ public class LoaderTask implements Runnable {
|
||||
IOUtils.closeSilently(c);
|
||||
}
|
||||
|
||||
// Load delegate items
|
||||
mModelDelegate.loadHotseatItems(mUserManagerState, shortcutKeyToPinnedShortcuts);
|
||||
mModelDelegate.loadAllAppsItems(mUserManagerState, shortcutKeyToPinnedShortcuts);
|
||||
mModelDelegate.loadWidgetsRecommendationItems();
|
||||
mModelDelegate.markActive();
|
||||
|
||||
// Load string cache
|
||||
mModelDelegate.loadStringCache(mBgDataModel.stringCache);
|
||||
if (!FeatureFlags.CHANGE_MODEL_DELEGATE_LOADING_ORDER.get()) {
|
||||
mModelDelegate.loadAndBindWorkspaceItems(mUserManagerState,
|
||||
mLauncherBinder.mCallbacksList, mShortcutKeyToPinnedShortcuts);
|
||||
mModelDelegate.loadAndBindAllAppsItems(mUserManagerState,
|
||||
mLauncherBinder.mCallbacksList, mShortcutKeyToPinnedShortcuts);
|
||||
mModelDelegate.loadAndBindOtherItems(mLauncherBinder.mCallbacksList);
|
||||
mModelDelegate.markActive();
|
||||
}
|
||||
|
||||
// Break early if we've stopped loading
|
||||
if (mStopped) {
|
||||
@@ -474,7 +499,6 @@ public class LoaderTask implements Runnable {
|
||||
PackageUserKey tempPackageKey,
|
||||
WidgetManagerHelper widgetHelper,
|
||||
PackageManagerHelper pmHelper,
|
||||
Map<ShortcutKey, ShortcutInfo> shortcutKeyToPinnedShortcuts,
|
||||
List<IconRequestInfo<WorkspaceItemInfo>> iconRequestInfos,
|
||||
LongSparseArray<Boolean> unlockedUsers,
|
||||
boolean isSafeMode,
|
||||
@@ -603,7 +627,7 @@ public class LoaderTask implements Runnable {
|
||||
} else if (c.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
|
||||
ShortcutKey key = ShortcutKey.fromIntent(intent, c.user);
|
||||
if (unlockedUsers.get(c.serialNumber)) {
|
||||
ShortcutInfo pinnedShortcut = shortcutKeyToPinnedShortcuts.get(key);
|
||||
ShortcutInfo pinnedShortcut = mShortcutKeyToPinnedShortcuts.get(key);
|
||||
if (pinnedShortcut == null) {
|
||||
// The shortcut is no longer valid.
|
||||
c.markDeleted("Pinned shortcut not found");
|
||||
|
||||
@@ -20,6 +20,7 @@ import static com.android.launcher3.util.PackageManagerHelper.hasShortcutsPermis
|
||||
import android.content.Context;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.WorkerThread;
|
||||
|
||||
import com.android.launcher3.LauncherAppState;
|
||||
@@ -68,9 +69,7 @@ public class ModelDelegate implements ResourceBasedOverride {
|
||||
this.mContext = context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called periodically to validate and update any data
|
||||
*/
|
||||
/** Called periodically to validate and update any data */
|
||||
@WorkerThread
|
||||
public void validateData() {
|
||||
if (hasShortcutsPermission(mApp.getContext())
|
||||
@@ -79,36 +78,32 @@ public class ModelDelegate implements ResourceBasedOverride {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load hot seat items if any in the data model
|
||||
*/
|
||||
/** Load workspace items (for example, those in the hot seat) if any in the data model */
|
||||
@WorkerThread
|
||||
public void loadHotseatItems(UserManagerState ums,
|
||||
Map<ShortcutKey, ShortcutInfo> pinnedShortcuts) { }
|
||||
public void loadAndBindWorkspaceItems(@NonNull UserManagerState ums,
|
||||
@NonNull BgDataModel.Callbacks[] callbacks,
|
||||
@NonNull Map<ShortcutKey, ShortcutInfo> pinnedShortcuts) { }
|
||||
|
||||
/**
|
||||
* Load all apps items if any in the data model
|
||||
*/
|
||||
/** Load all apps items if any in the data model */
|
||||
@WorkerThread
|
||||
public void loadAllAppsItems(UserManagerState ums,
|
||||
Map<ShortcutKey, ShortcutInfo> pinnedShortcuts) { }
|
||||
public void loadAndBindAllAppsItems(@NonNull UserManagerState ums,
|
||||
@NonNull BgDataModel.Callbacks[] callbacks,
|
||||
@NonNull Map<ShortcutKey, ShortcutInfo> pinnedShortcuts) { }
|
||||
|
||||
/**
|
||||
* Load widget recommendation items if any in the data model
|
||||
*/
|
||||
/** Load other items like widget recommendations if any in the data model */
|
||||
@WorkerThread
|
||||
public void loadWidgetsRecommendationItems() { }
|
||||
public void loadAndBindOtherItems(@NonNull BgDataModel.Callbacks[] callbacks) { }
|
||||
|
||||
/**
|
||||
* Marks the ModelDelegate as active
|
||||
*/
|
||||
/** binds everything not bound by launcherBinder */
|
||||
@WorkerThread
|
||||
public void bindAllModelExtras(@NonNull BgDataModel.Callbacks[] callbacks) { }
|
||||
|
||||
/** Marks the ModelDelegate as active */
|
||||
public void markActive() { }
|
||||
|
||||
/**
|
||||
* Load String cache
|
||||
*/
|
||||
/** Load String cache */
|
||||
@WorkerThread
|
||||
public void loadStringCache(StringCache cache) {
|
||||
public void loadStringCache(@NonNull StringCache cache) {
|
||||
cache.loadStrings(mContext);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user