If Launcher wants to modify the single-layer desktop, there are three places that need to be modified.
- Block Cancel Swipe up to show all apps
- Automatically load application icons to a single-layer desktop, including startup and subsequent installed applications
- Remove the “remove” button of long-press desktop icon
1. Block and cancel and swipe up to show all apps
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java index 9016c1bea6..d50e062396 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java + + + b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java @@ -69,9 + 69,6 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr // Otherwise, don't intercept so they can scroll recents, dismiss a task, etc. return false; } - if (LauncherAppState.isUserSingleLayerStyle() & amp; & amp; mLauncher.isInState(NORMAL)) { - return false; - } if (mLauncher.isInState(ALL_APPS)) { // In all-apps only listen if the container cannot scroll itself if (!mLauncher.getAppsView().shouldContainerScroll(ev)) { @@ -100,6 + 97,9 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr } else if (fromState == OVERVIEW) { return isDragTowardPositive ? OVERVIEW : NORMAL; } else if (fromState == NORMAL & amp; & amp; isDragTowardPositive) { + if (LauncherAppState.isUserSingleLayerStyle()) { + return fromState; + } return ALL_APPS; }
2. Automatically load application icons to the single-layer desktop, including startup and subsequent installed applications
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java index 33eed47236..a80de99614 100644 --- a/src/com/android/launcher3/LauncherAppState.java + + + b/src/com/android/launcher3/LauncherAppState.java @@ -226,4 + 226,8 @@ public class LauncherAppState implements SafeCloseable { } } } + + public static boolean isUserSingleLayerStyle() { + return true; + } } diff --git a/src/com/android/launcher3/model/AddWorkspaceItemsTask.java b/src/com/android/launcher3/model/AddWorkspaceItemsTask.java index 0d978e1b23..df0d629b83 100644 --- a/src/com/android/launcher3/model/AddWorkspaceItemsTask.java + + + b/src/com/android/launcher3/model/AddWorkspaceItemsTask.java @@ -104,8 + 104,13 @@ public class AddWorkspaceItemsTask extends BaseModelUpdateTask { continue; } + boolean mForceAdd = false; + if (item.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION + & amp; & amp; item instanceof WorkspaceItemInfo) { + mForceAdd = ((WorkspaceItemInfo) item).hasExtraFlag(WorkspaceItemInfo.EXTRA_FLAG_FORCE_ADD); + } // b/139663018 Short-circuit this logic if the icon is a system app - if (PackageManagerHelper.isSystemApp(app.getContext(), + if (!mForceAdd & amp; & amp; PackageManagerHelper.isSystemApp(app.getContext(), Objects.requireNonNull(item.getIntent()))) { if (TestProtocol.sDebugTracing) { Log.d(TestProtocol.MISSING_PROMISE_ICON, diff --git a/src/com/android/launcher3/model/BgDataModel.java b/src/com/android/launcher3/model/BgDataModel.java index b0f6e13ae3..54997fff9f 100644 --- a/src/com/android/launcher3/model/BgDataModel.java + + + b/src/com/android/launcher3/model/BgDataModel.java @@ -404,6 + 404,12 @@ public class BgDataModel { return items; } + public synchronized ArrayList<ItemInfo> getAllWorkspaceItemsWithoutAppWidget() { + ArrayList<ItemInfo> items = new ArrayList<>(workspaceItems.size()); + items.addAll(workspaceItems); + return items; + } + /** * Calls the provided {@code op} for all workspaceItems in the in-memory model (both persisted * items and dynamic/predicted items for the provided {@code userHandle}. diff --git a/src/com/android/launcher3/model/ItemInstallQueue.java b/src/com/android/launcher3/model/ItemInstallQueue.java index 69f9b53090..b21bb91650 100644 --- a/src/com/android/launcher3/model/ItemInstallQueue.java + + + b/src/com/android/launcher3/model/ItemInstallQueue.java @@ -187,6 + 187,13 @@ public class ItemInstallQueue { queuePendingShortcutInfo(new PendingInstallShortcutInfo(packageName, userHandle)); } + /** + * Adds an item to the install queue + */ + public void queueItem(LauncherActivityInfo launcherActivityInfo, UserHandle userHandle) { + queuePendingShortcutInfo(new PendingInstallShortcutInfo(launcherActivityInfo, userHandle)); + } + /** * Returns a stream of all pending shortcuts in the queue */ @@ -251,6 + 258,8 @@ public class ItemInstallQueue { final Intent intent; + LauncherActivityInfo activityInfo = null; + @Nullable ShortcutInfo shortcutInfo; @Nullable AppWidgetProviderInfo providerInfo; @@ -263,6 + 272,13 @@ public class ItemInstallQueue { user = userHandle; } + public PendingInstallShortcutInfo(LauncherActivityInfo activityInfo, UserHandle userHandle) { + itemType = Favorites.ITEM_TYPE_APPLICATION; + intent = new Intent().setComponent(activityInfo.getComponentName()); + this.activityInfo = activityInfo; + user = userHandle; + } + /** * Initializes a PendingInstallShortcutInfo to represent a deep shortcut. */ @@ -293,6 + 309,33 @@ public class ItemInstallQueue { return intent; } + @Override + public boolean equals(Object obj) { + if (obj instanceof PendingInstallShortcutInfo) { + PendingInstallShortcutInfo other = (PendingInstallShortcutInfo) obj; + + boolean userMatches = user.equals(other.user); + boolean itemTypeMatches = itemType == other.itemType; + boolean intentMatches = intent.toUri(0).equals(other.intent.toUri(0)); + boolean shortcutInfoMatches = shortcutInfo == null + ? other.shortcutInfo == null + : other.shortcutInfo != null + & amp; & amp; shortcutInfo.getId().equals(other.shortcutInfo.getId()) + & amp; & amp; shortcutInfo.getPackage().equals(other.shortcutInfo.getPackage()); + boolean providerInfoMatches = providerInfo == null + ? other.providerInfo == null + : other.providerInfo != null + & amp; & amp; providerInfo.provider.equals(other.providerInfo.provider); + + return userMatches + & amp; & amp; itemTypeMatches + & amp; & amp; intentMatches + & amp; & amp; shortcutInfoMatches + & amp; & amp; providerInfoMatches; + } + return false; + } + public Pair<ItemInfo, Object> getItemInfo(Context context) { switch (itemType) { case ITEM_TYPE_APPLICATION: { @@ -306,6 + 349,11 @@ public class ItemInstallQueue { si.itemType = ITEM_TYPE_APPLICATION; LauncherActivityInfo lai; + if (activityInfo != null) { + laiList.clear(); + laiList.add(activityInfo); + si.addExtraFlag(WorkspaceItemInfo.EXTRA_FLAG_FORCE_ADD); + } boolean usePackageIcon = laiList.isEmpty(); if (usePackageIcon) { lai = null; @@ -343,33 + 391,6 @@ public class ItemInstallQueue { } return null; } - - @Override - public boolean equals(Object obj) { - if (obj instanceof PendingInstallShortcutInfo) { - PendingInstallShortcutInfo other = (PendingInstallShortcutInfo) obj; - - boolean userMatches = user.equals(other.user); - boolean itemTypeMatches = itemType == other.itemType; - boolean intentMatches = intent.toUri(0).equals(other.intent.toUri(0)); - boolean shortcutInfoMatches = shortcutInfo == null - ? other.shortcutInfo == null - : other.shortcutInfo != null - & amp; & amp; shortcutInfo.getId().equals(other.shortcutInfo.getId()) - & amp; & amp; shortcutInfo.getPackage().equals(other.shortcutInfo.getPackage()); - boolean providerInfoMatches = providerInfo == null - ? other.providerInfo == null - : other.providerInfo != null - & amp; & amp; providerInfo.provider.equals(other.providerInfo.provider); - - return userMatches - & amp; & amp; itemTypeMatches - & amp; & amp; intentMatches - & amp; & amp; shortcutInfoMatches - & amp; & amp; providerInfoMatches; - } - return false; - } } private static String getIntentPackage(Intent intent) { diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java index 1d6971e27d..f0861e1697 100644 --- a/src/com/android/launcher3/model/LoaderTask.java + + + b/src/com/android/launcher3/model/LoaderTask.java @@ -117,6 + 117,7 @@ public class LoaderTask implements Runnable { private static final String TAG = "LoaderTask"; private static final boolean DEBUG = true; + private static final boolean DEBUG_BOBO = true; protected final LauncherAppState mApp; private final AllAppsList mBgAllAppsList; @@ -186,6 + 187,21 @@ public class LoaderTask implements Runnable { filterCurrentWorkspaceItems(firstScreens, allItems, firstScreenItems, new ArrayList<>() /* otherScreenItems are ignored */); + + if (DEBUG_BOBO) { + Log.d(TAG, "sendFirstScreenActiveInstallsBroadcast firstScreenItems size: " + + firstScreenItems.size()); + for (ItemInfo itemInfo : firstScreenItems) { + Log.d(TAG, "firstScreenItems: " + itemInfo); + } + Log.d(TAG, "sendFirstScreenActiveInstallsBroadcast firstScreenItems end"); + Log.d(TAG, "sendFirstScreenActiveInstallsBroadcast allItems size: " + + allItems.size()); + for (ItemInfo itemInfo : allItems) { + Log.d(TAG, "allItems: " + itemInfo); + } + Log.d(TAG, "sendFirstScreenActiveInstallsBroadcast allItems end"); + } mFirstScreenBroadcast.sendBroadcasts(mApp.getContext(), firstScreenItems); } @@ -196,6 + 212,9 @@ public class LoaderTask implements Runnable { return; } } + if (DEBUG_BOBO) { + Log.d(TAG, "run start"); + } Object traceToken = TraceHelper.INSTANCE.beginSection(TAG); TimingLogger logger = new TimingLogger(TAG, "run"); @@ -208,6 + 227,13 @@ public class LoaderTask implements Runnable { } finally { Trace.endSection(); } + if (DEBUG_BOBO) { + Log.d(TAG, "shortcutInfo size: " + allShortcuts.size()); + for (ShortcutInfo shortcutInfo : allShortcuts) { + Log.d(TAG, "shortcutInfo: " + shortcutInfo); + } + Log.d(TAG, "shortcutInfo end"); + } logASplit(logger, "loadWorkspace"); // Sanitize data re-syncs widgets/shortcuts based on the workspace loaded from db. @@ -242,6 + 268,13 @@ public class LoaderTask implements Runnable { } finally { Trace.endSection(); } + if (DEBUG_BOBO) { + Log.d(TAG, "allActivityList size: " + allActivityList.size()); + for (LauncherActivityInfo activityInfo : allActivityList) { + Log.d(TAG, "activityInfo: " + activityInfo.getComponentName()); + } + Log.d(TAG, "allActivityList end"); + } logASplit(logger, "loadAllApps"); verifyNotStopped(); @@ -268,6 + 301,13 @@ public class LoaderTask implements Runnable { // third step List<ShortcutInfo> allDeepShortcuts = loadDeepShortcuts(); + if (DEBUG_BOBO) { + Log.d(TAG, "allDeepShortcuts size: " + allDeepShortcuts.size()); + for (ShortcutInfo shortcutInfo : allDeepShortcuts) { + Log.d(TAG, "shortcutInfo: " + shortcutInfo); + } + Log.d(TAG, "allDeepShortcuts end"); + } logASplit(logger, "loadDeepShortcuts"); verifyNotStopped(); @@ -287,6 + 327,13 @@ public class LoaderTask implements Runnable { // fourth step List<ComponentWithLabelAndIcon> allWidgetsList = mBgDataModel.widgetsModel.update(mApp, null); + if (DEBUG_BOBO) { + Log.d(TAG, "allWidgetsList size: " + allWidgetsList.size()); + for (ComponentWithLabelAndIcon componentWithLabelAndIcon : allWidgetsList) { + Log.d(TAG, "componentWithLabelAndIcon: " + componentWithLabelAndIcon.getComponent()); + } + Log.d(TAG, "allWidgetsList end"); + } logASplit(logger, "load widgets"); verifyNotStopped(); @@ -306,6 + 353,9 @@ public class LoaderTask implements Runnable { updateHandler.finish(); logASplit(logger, "finish icon update"); + // add apps for single layer--bobo + updateForSingleLayerStyle(allActivityList); + mModelDelegate.modelLoadComplete(); transaction.commit(); memoryLogger.clearLogs(); @@ -318,9 + 368,56 @@ public class LoaderTask implements Runnable { } finally { logger.dumpToLog(); } + if (DEBUG_BOBO) { + Log.d(TAG, "run end"); + } TraceHelper.INSTANCE.endSection(traceToken); } + private void updateForSingleLayerStyle(List<LauncherActivityInfo> allActivityList) { + if (!LauncherAppState.isUserSingleLayerStyle()) { + return; + } + if (allActivityList == null || allActivityList.size() <= 0) { + return; + } + Map<String, LauncherActivityInfo> newAppsMap = new HashMap<>(); + for (LauncherActivityInfo info : allActivityList) { + newAppsMap.put(getComponentKey(info.getComponentName(), info.getUser().getIdentifier()), +info); + } + ArrayList<ItemInfo> addedItems = mBgDataModel.getAllWorkspaceItemsWithoutAppWidget(); + for (ItemInfo info : addedItems) { + if (info.getTargetComponent() == null) continue; + if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) { + newAppsMap.remove(getComponentKey(info.getTargetComponent(), info.user.getIdentifier())); + } else if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_FOLDER) { + //TODO + } + } + if (DEBUG_BOBO) { + Log.d(TAG, "updateForSingleLayerStyle newAppsMap:" + newAppsMap.size()); + newAppsMap.values().stream().forEach(item->{ + Log.d(TAG, "updateForSingleLayerStyle activityInfo: " + item.getComponentName()); + }); + } + ItemInstallQueue.INSTANCE.get(mApp.getContext()) + .pauseModelPush(ItemInstallQueue.FLAG_LOADER_RUNNING); + newAppsMap.values().stream().forEach(item->{ + ItemInstallQueue.INSTANCE.get(mApp.getContext()) + .queueItem(item, item.getUser()); + }); + ItemInstallQueue.INSTANCE.get(mApp.getContext()) + .resumeModelPush(ItemInstallQueue.FLAG_LOADER_RUNNING); + if (DEBUG_BOBO) { + Log.d(TAG, "updateForSingleLayerStyle end"); + } + } + + private String getComponentKey(ComponentName componentName, int userId) { + return componentName.toString() + "_" + userId; + } + public synchronized void stopLocked() { mStopped = true; this.notify(); @@ -1053,6 + 1150,15 @@ public class LoaderTask implements Runnable { info.suggestedFolderNames = suggestionInfos; } } + if (DEBUG_BOBO) { + Log.d(TAG, "loadFolderNames mBgDataModel.folders size: " + mBgDataModel.folders.size()); + for (int i = 0; i < mBgDataModel.folders.size(); i + + ) { + FolderInfo info = mBgDataModel.folders.valueAt(i); + Log.d(TAG, "info: " + + info.suggestedFolderNames); + } + Log.d(TAG, "loadFolderNames end"); + } } } diff --git a/src/com/android/launcher3/model/WorkspaceItemSpaceFinder.java b/src/com/android/launcher3/model/WorkspaceItemSpaceFinder.java index 93fc6a539f..ec685f7902 100644 --- a/src/com/android/launcher3/model/WorkspaceItemSpaceFinder.java + + + b/src/com/android/launcher3/model/WorkspaceItemSpaceFinder.java @@ -66,7 + 66,7 @@ public class WorkspaceItemSpaceFinder { int screenCount = workspaceScreens.size(); // First check the preferred screen. IntSet screensToExclude = new IntSet(); - if (FeatureFlags.QSB_ON_FIRST_SCREEN) { + if (FeatureFlags.QSB_ON_FIRST_SCREEN || LauncherAppState.isUserSingleLayerStyle()) { screensToExclude.add(FIRST_SCREEN_ID); } diff --git a/src/com/android/launcher3/model/data/WorkspaceItemInfo.java b/src/com/android/launcher3/model/data/WorkspaceItemInfo.java index 59ef320120..26299c91e9 100644 --- a/src/com/android/launcher3/model/data/WorkspaceItemInfo.java + + + b/src/com/android/launcher3/model/data/WorkspaceItemInfo.java @@ -100,7 + 100,6 @@ public class WorkspaceItemInfo extends ItemInfoWithIcon { public int options; - public WorkspaceItemInfo() { itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT; } @@ -112,6 + 111,7 @@ public class WorkspaceItemInfo extends ItemInfoWithIcon { iconResource = info.iconResource; status = info.status; personKeys = info.personKeys.clone(); + mExtraFlags = info.mExtraFlags; } /** TODO: Remove this. It's only called by ApplicationInfo.makeWorkspaceItem. */ @@ -231,4 + 231,19 @@ public class WorkspaceItemInfo extends ItemInfoWithIcon { public WorkspaceItemInfo clone() { return new WorkspaceItemInfo(this); } + + + public static final int EXTRA_FLAG_FORCE_ADD = 1; + private int mExtraFlags = 0; + public void addExtraFlag(int flag) { + mExtraFlags |= flag; + } + + public void removeExtraFlag(int flag) { + mExtraFlags & amp;= ~flag; + } + + public boolean hasExtraFlag(int flag) { + return (mExtraFlags & amp; flag) == flag; + } }
3. Delete the “remove” button of long-press the desktop icon
diff --git a/src/com/android/launcher3/DeleteDropTarget.java b/src/com/android/launcher3/DeleteDropTarget.java index 95d3ad9dbb..96b98e4667 100644 --- a/src/com/android/launcher3/DeleteDropTarget.java + + + b/src/com/android/launcher3/DeleteDropTarget.java @@ -89,6 + 89,11 @@ public class DeleteDropTarget extends ButtonDropTarget { @Override protected boolean supportsDrop(ItemInfo info) { + if (info != null & amp; & amp; + info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION + & amp; & amp; LauncherAppState.isUserSingleLayerStyle()) { + return false; + } return true; }