feat: Add option to clear home screen in settings (#6125)

Signed-off-by: abhixv <abhi.sharma1@hotmail.com>
This commit is contained in:
Abhishek Sharma
2025-12-20 03:26:30 +05:30
committed by Pun Butrach
parent 9898749619
commit 5f3a03f4fb
1577 changed files with 112563 additions and 80248 deletions
@@ -15,29 +15,26 @@
*/
package com.android.launcher3.taskbar;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_ALL_APPS;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT;
import static com.android.launcher3.model.data.AppInfo.COMPONENT_KEY_COMPARATOR;
import static com.android.launcher3.util.SplitConfigurationOptions.getLogEventForPosition;
import android.content.Intent;
import android.content.pm.LauncherApps;
import android.graphics.Point;
import android.util.Pair;
import android.util.SparseArray;
import android.view.MotionEvent;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.internal.logging.InstanceId;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.Flags;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.R;
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.dot.FolderDotInfo;
import com.android.launcher3.folder.Folder;
import com.android.launcher3.folder.FolderIcon;
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.notification.NotificationListener;
@@ -47,21 +44,19 @@ import com.android.launcher3.popup.SystemShortcut;
import com.android.launcher3.shortcuts.DeepShortcutView;
import com.android.launcher3.splitscreen.SplitShortcut;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.LauncherBindableItemsContainer;
import com.android.launcher3.util.PackageUserKey;
import com.android.launcher3.util.ShortcutUtil;
import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
import com.android.launcher3.views.ActivityContext;
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.util.LogUtils;
import com.android.quickstep.util.SingleTask;
import com.android.wm.shell.shared.bubbles.BubbleAnythingFlagHelper;
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -74,24 +69,16 @@ public class TaskbarPopupController implements TaskbarControllers.LoggableTaskba
private static final SystemShortcut.Factory<BaseTaskbarContext>
APP_INFO = SystemShortcut.AppInfo::new;
private static final SystemShortcut.Factory<BaseTaskbarContext>
BUBBLE = SystemShortcut.BubbleShortcut::new;
private final TaskbarActivityContext mContext;
private final PopupDataProvider mPopupDataProvider;
// Initialized in init.
private TaskbarControllers mControllers;
private boolean mAllowInitialSplitSelection;
private AppInfo[] mAppInfosList = AppInfo.EMPTY_ARRAY;
// Saves the ItemInfos in the hotseat without the predicted items.
private SparseArray<ItemInfo> mHotseatInfosList;
private ManageWindowsTaskbarShortcut<BaseTaskbarContext> mManageWindowsTaskbarShortcut;
public TaskbarPopupController(TaskbarActivityContext context) {
mContext = context;
mPopupDataProvider = new PopupDataProvider(mContext);
mPopupDataProvider = new PopupDataProvider(this::updateNotificationDots);
}
public void init(TaskbarControllers controllers) {
@@ -113,23 +100,43 @@ public class TaskbarPopupController implements TaskbarControllers.LoggableTaskba
mPopupDataProvider.setDeepShortcutMap(deepShortcutMapCopy);
}
/** Closes the multi-instance menu if it is enabled and currently open. */
public void maybeCloseMultiInstanceMenu() {
if (Flags.enableMultiInstanceMenuTaskbar() && mManageWindowsTaskbarShortcut != null) {
mManageWindowsTaskbarShortcut.closeMultiInstanceMenu();
cleanUpMultiInstanceMenuReference();
}
}
/** Releases the reference to the Taskbar multi-instance menu */
public void cleanUpMultiInstanceMenuReference() {
mManageWindowsTaskbarShortcut = null;
}
public void setAllowInitialSplitSelection(boolean allowInitialSplitSelection) {
mAllowInitialSplitSelection = allowInitialSplitSelection;
}
private void updateNotificationDots(Predicate<PackageUserKey> updatedDots) {
final PackageUserKey packageUserKey = new PackageUserKey(null, null);
Predicate<ItemInfo> matcher = info -> !packageUserKey.updateFromItemInfo(info)
|| updatedDots.test(packageUserKey);
LauncherBindableItemsContainer.ItemOperator op = (info, v) -> {
if (info instanceof WorkspaceItemInfo && v instanceof BubbleTextView) {
if (matcher.test(info)) {
((BubbleTextView) v).applyDotState(info, true /* animate */);
}
} else if (info instanceof FolderInfo && v instanceof FolderIcon) {
FolderInfo fi = (FolderInfo) info;
if (fi.anyMatch(matcher)) {
FolderDotInfo folderDotInfo = new FolderDotInfo();
for (ItemInfo si : fi.getContents()) {
folderDotInfo.addDotInfo(mPopupDataProvider.getDotInfoForItem(si));
}
((FolderIcon) v).setDotInfo(folderDotInfo);
}
}
// process all the shortcuts
return false;
};
mControllers.taskbarViewController.mapOverItems(op);
Folder folder = Folder.getOpen(mContext);
if (folder != null) {
folder.iterateOverItems(op);
}
mControllers.taskbarAllAppsController.updateNotificationDots(updatedDots);
}
/**
* Shows the notifications and deep shortcuts associated with a Taskbar {@param icon}.
* @return the container if shown or null.
@@ -141,35 +148,22 @@ public class TaskbarPopupController implements TaskbarControllers.LoggableTaskba
icon.clearFocus();
return null;
}
ItemInfo itemInfo;
if (icon.getTag() instanceof ItemInfo item && ShortcutUtil.supportsShortcuts(item)) {
itemInfo = item;
} else if (icon.getTag() instanceof SingleTask task) {
itemInfo = SingleTask.Companion.createTaskItemInfo(task);
} else {
ItemInfo item = (ItemInfo) icon.getTag();
if (!ShortcutUtil.supportsShortcuts(item)) {
return null;
}
PopupContainerWithArrow<BaseTaskbarContext> container;
int deepShortcutCount = mPopupDataProvider.getShortcutCountForItem(itemInfo);
int deepShortcutCount = mPopupDataProvider.getShortcutCountForItem(item);
// TODO(b/198438631): add support for INSTALL shortcut factory
List<SystemShortcut> systemShortcuts = getSystemShortcuts()
.map(s -> s.getShortcut(context, itemInfo, icon))
.map(s -> s.getShortcut(context, item, icon))
.filter(Objects::nonNull)
.collect(Collectors.toList());
// TODO(b/375648361): Revisit to see if this can be implemented within getSystemShortcuts().
if (Flags.enablePinningAppWithContextMenu()) {
SystemShortcut shortcut = createPinShortcut(context, itemInfo, icon);
if (shortcut != null) {
systemShortcuts.add(0, shortcut);
}
}
container = (PopupContainerWithArrow) context.getLayoutInflater().inflate(
R.layout.popup_container, context.getDragLayer(), false);
container.populateAndShowRows(icon, itemInfo, deepShortcutCount, systemShortcuts);
container.populateAndShowRows(icon, deepShortcutCount, systemShortcuts);
// TODO (b/198438631): configure for taskbar/context
container.setPopupItemDragHandler(new TaskbarPopupItemDragHandler());
@@ -187,45 +181,11 @@ public class TaskbarPopupController implements TaskbarControllers.LoggableTaskba
// Create a Stream of all applicable system shortcuts
private Stream<SystemShortcut.Factory> getSystemShortcuts() {
// append split options to APP_INFO shortcut if not in Desktop Windowing mode, the order
// here will reflect in the popup
ArrayList<SystemShortcut.Factory> shortcuts = new ArrayList<>();
shortcuts.add(APP_INFO);
if (!mControllers.taskbarDesktopModeController
.isInDesktopModeAndNotInOverview(mContext.getDisplayId())) {
shortcuts.addAll(mControllers.uiController.getSplitMenuOptions().toList());
}
if (BubbleAnythingFlagHelper.enableCreateAnyBubble()) {
shortcuts.add(BUBBLE);
}
if (Flags.enableMultiInstanceMenuTaskbar()
&& DesktopModeStatus.canEnterDesktopMode(mContext)
&& !mControllers.taskbarStashController.isInOverview()) {
maybeCloseMultiInstanceMenu();
shortcuts.addAll(getMultiInstanceMenuOptions().toList());
}
return shortcuts.stream();
}
@Nullable
private SystemShortcut createPinShortcut(BaseTaskbarContext target, ItemInfo itemInfo,
BubbleTextView originalView) {
// Predicted items use {@code HotseatPredictionController.PinPrediction} shortcut to pin.
if (itemInfo.isPredictedItem()) {
return null;
}
if (itemInfo.container == CONTAINER_HOTSEAT) {
return new PinToTaskbarShortcut<>(target, itemInfo, originalView, false,
mHotseatInfosList);
}
if (mHotseatInfosList.size()
< mContext.getTaskbarSpecsEvaluator().getNumShownHotseatIcons()) {
return new PinToTaskbarShortcut<>(target, itemInfo, originalView, true,
mHotseatInfosList);
}
return null;
// append split options to APP_INFO shortcut, the order here will reflect in the popup
return Stream.concat(
Stream.of(APP_INFO),
mControllers.uiController.getSplitMenuOptions()
);
}
@Override
@@ -288,83 +248,7 @@ public class TaskbarPopupController implements TaskbarControllers.LoggableTaskba
originalView, position, mAllowInitialSplitSelection);
}
/**
* Set the list of AppInfos to be able to pull from later
*/
public void setApps(AppInfo[] apps) {
mAppInfosList = apps;
}
/**
* Finds and returns an AppInfo object from a list, using its ComponentKey for identification.
* Based off of {@link com.android.launcher3.allapps.AllAppsStore#getApp(ComponentKey)}
* since we cannot access AllAppsStore from here.
*/
public AppInfo getApp(ComponentKey key) {
if (key == null) {
return null;
}
AppInfo tempInfo = new AppInfo();
tempInfo.componentName = key.componentName;
tempInfo.user = key.user;
int index = Arrays.binarySearch(mAppInfosList, tempInfo, COMPONENT_KEY_COMPARATOR);
return index < 0 ? null : mAppInfosList[index];
}
public void setHotseatInfosList(SparseArray<ItemInfo> info) {
mHotseatInfosList = info;
}
/**
* Returns a stream of Multi Instance menu options if an app supports it.
*/
Stream<SystemShortcut.Factory<BaseTaskbarContext>> getMultiInstanceMenuOptions() {
SystemShortcut.Factory<BaseTaskbarContext> f1 = createNewWindowShortcutFactory();
SystemShortcut.Factory<BaseTaskbarContext> f2 = createManageWindowsShortcutFactory();
return f1 != null ? Stream.of(f1, f2) : Stream.empty();
}
/**
* Creates a factory function representing a "New Window" menu item only if the calling app
* supports multi-instance.
* @return A factory function to be used in populating the long-press menu.
*/
SystemShortcut.Factory<BaseTaskbarContext> createNewWindowShortcutFactory() {
return (context, itemInfo, originalView) -> {
if (shouldShowMultiInstanceOptions(itemInfo)) {
return new NewWindowTaskbarShortcut<>(context, itemInfo, originalView);
}
return null;
};
}
/**
* Creates a factory function representing a "Manage Windows" menu item only if the calling app
* supports multi-instance. This menu item shows the open instances of the calling app.
* @return A factory function to be used in populating the long-press menu.
*/
public SystemShortcut.Factory<BaseTaskbarContext> createManageWindowsShortcutFactory() {
return (context, itemInfo, originalView) -> {
if (shouldShowMultiInstanceOptions(itemInfo)) {
mManageWindowsTaskbarShortcut = new ManageWindowsTaskbarShortcut<>(
context, itemInfo, originalView, mControllers);
return mManageWindowsTaskbarShortcut;
}
return null;
};
}
/**
* Determines whether to show multi-instance options for a given item.
*/
private boolean shouldShowMultiInstanceOptions(ItemInfo itemInfo) {
ComponentKey key = itemInfo.getComponentKey();
AppInfo app = getApp(key);
return app != null && app.supportsMultiInstance()
&& itemInfo.container != CONTAINER_ALL_APPS;
}
/**
/**
* A single menu item ("Split left," "Split right," or "Split top") that executes a split
* from the taskbar, as if the user performed a drag and drop split.
* Includes an onClick method that initiates the actual split.