diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java index 7a510ac95f..a2e4c225d9 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java @@ -166,7 +166,8 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ new StashedHandleViewController(this, stashedHandleView), new TaskbarStashController(this), new TaskbarEduController(this), - new TaskbarAutohideSuspendController(this)); + new TaskbarAutohideSuspendController(this), + new TaskbarPopupController()); } public void init(TaskbarSharedState sharedState) { @@ -255,6 +256,11 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ return false; } + @Override + public View.OnClickListener getItemOnClickListener() { + return this::onTaskbarIconClicked; + } + /** * Change from hotseat/predicted hotseat to taskbar container. */ diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java index 08a79c064d..56730dbd70 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java @@ -38,6 +38,7 @@ public class TaskbarControllers { public final TaskbarStashController taskbarStashController; public final TaskbarEduController taskbarEduController; public final TaskbarAutohideSuspendController taskbarAutohideSuspendController; + public final TaskbarPopupController taskbarPopupController; /** Do not store this controller, as it may change at runtime. */ @NonNull public TaskbarUIController uiController = TaskbarUIController.DEFAULT; @@ -55,7 +56,8 @@ public class TaskbarControllers { StashedHandleViewController stashedHandleViewController, TaskbarStashController taskbarStashController, TaskbarEduController taskbarEduController, - TaskbarAutohideSuspendController taskbarAutoHideSuspendController) { + TaskbarAutohideSuspendController taskbarAutoHideSuspendController, + TaskbarPopupController taskbarPopupController) { this.taskbarActivityContext = taskbarActivityContext; this.taskbarDragController = taskbarDragController; this.navButtonController = navButtonController; @@ -70,6 +72,7 @@ public class TaskbarControllers { this.taskbarStashController = taskbarStashController; this.taskbarEduController = taskbarEduController; this.taskbarAutohideSuspendController = taskbarAutoHideSuspendController; + this.taskbarPopupController = taskbarPopupController; } /** diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java index 3bcacb6c8a..b3a9f8db7c 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java @@ -40,6 +40,7 @@ import com.android.launcher3.DropTarget; import com.android.launcher3.LauncherSettings; import com.android.launcher3.R; import com.android.launcher3.accessibility.DragViewStateAnnouncer; +import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.dragndrop.DragController; import com.android.launcher3.dragndrop.DragDriver; import com.android.launcher3.dragndrop.DragOptions; @@ -49,6 +50,7 @@ import com.android.launcher3.graphics.DragPreviewProvider; import com.android.launcher3.logging.StatsLogManager; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.WorkspaceItemInfo; +import com.android.launcher3.popup.PopupContainerWithArrow; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.system.ClipDescriptionCompat; import com.android.systemui.shared.system.LauncherAppsCompat; @@ -139,11 +141,13 @@ public class TaskbarDragController extends DragController popupContainer = + mControllers.taskbarPopupController.showForIcon(btv); + if (popupContainer != null) { + dragOptions.preDragCondition = popupContainer.createPreDragCondition(); + } + } startDrag( drawable, diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarModelCallbacks.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarModelCallbacks.java index 5e76b960fd..6dcfe564a6 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarModelCallbacks.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarModelCallbacks.java @@ -23,6 +23,7 @@ import com.android.launcher3.model.BgDataModel; import com.android.launcher3.model.BgDataModel.FixedContainerItems; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.WorkspaceItemInfo; +import com.android.launcher3.util.ComponentKey; import com.android.launcher3.util.IntArray; import com.android.launcher3.util.IntSet; import com.android.launcher3.util.ItemInfoMatcher; @@ -30,6 +31,7 @@ import com.android.launcher3.util.LauncherBindableItemsContainer; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -186,4 +188,9 @@ public class TaskbarModelCallbacks implements TaskbarStashController.FLAG_STASHED_IN_APP_EMPTY, isHotseatEmpty); mControllers.taskbarStashController.applyState(); } + + @Override + public void bindDeepShortcutMap(HashMap deepShortcutMapCopy) { + mControllers.taskbarPopupController.setDeepShortcutMap(deepShortcutMapCopy); + } } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java new file mode 100644 index 0000000000..952f597f72 --- /dev/null +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.launcher3.taskbar; + +import androidx.annotation.NonNull; + +import com.android.launcher3.BubbleTextView; +import com.android.launcher3.R; +import com.android.launcher3.model.data.ItemInfo; +import com.android.launcher3.popup.PopupContainerWithArrow; +import com.android.launcher3.popup.PopupDataProvider; +import com.android.launcher3.popup.SystemShortcut; +import com.android.launcher3.util.ComponentKey; +import com.android.launcher3.views.ActivityContext; + +import java.util.HashMap; +import java.util.Objects; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * Implements interfaces required to show and allow interacting with a PopupContainerWithArrow. + */ +public class TaskbarPopupController { + + private static final SystemShortcut.Factory + APP_INFO = SystemShortcut.AppInfo::new; + + private final PopupDataProvider mPopupDataProvider; + + public TaskbarPopupController() { + // TODO (b/198438631): add notifications dots change listener + mPopupDataProvider = new PopupDataProvider(packageUserKey -> {}); + } + + @NonNull + public PopupDataProvider getPopupDataProvider() { + return mPopupDataProvider; + } + + public void setDeepShortcutMap(HashMap deepShortcutMapCopy) { + mPopupDataProvider.setDeepShortcutMap(deepShortcutMapCopy); + } + + /** + * Shows the notifications and deep shortcuts associated with a Taskbar {@param icon}. + * @return the container if shown or null. + */ + public PopupContainerWithArrow showForIcon(BubbleTextView icon) { + TaskbarActivityContext context = ActivityContext.lookupContext(icon.getContext()); + if (PopupContainerWithArrow.getOpen(context) != null) { + // There is already an items container open, so don't open this one. + icon.clearFocus(); + return null; + } + ItemInfo item = (ItemInfo) icon.getTag(); + if (!PopupContainerWithArrow.canShow(icon, item)) { + return null; + } + + final PopupContainerWithArrow container = + (PopupContainerWithArrow) context.getLayoutInflater().inflate( + R.layout.popup_container, context.getDragLayer(), false); + // TODO (b/198438631): configure for taskbar/context + + container.populateAndShow(icon, + mPopupDataProvider.getShortcutCountForItem(item), + mPopupDataProvider.getNotificationKeysForItem(item), + // TODO (b/198438631): add support for INSTALL shortcut factory + Stream.of(APP_INFO) + .map(s -> s.getShortcut(context, item)) + .filter(Objects::nonNull) + .collect(Collectors.toList())); + container.requestFocus(); + return container; + } +} diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java index 09197c3240..c47bde9dcd 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java @@ -261,7 +261,7 @@ public class TaskbarViewController { private boolean mCanceledStashHint; public View.OnClickListener getIconOnClickListener() { - return mActivity::onTaskbarIconClicked; + return mActivity.getItemOnClickListener(); } public View.OnLongClickListener getIconOnLongClickListener() { diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java index 13583874b9..d3629947c8 100644 --- a/src/com/android/launcher3/config/FeatureFlags.java +++ b/src/com/android/launcher3/config/FeatureFlags.java @@ -204,6 +204,10 @@ public final class FeatureFlags { public static final BooleanFlag ENABLE_TASKBAR_EDU = getDebugFlag("ENABLE_TASKBAR_EDU", true, "Enables showing taskbar education the first time an app is opened."); + public static final BooleanFlag ENABLE_TASKBAR_POPUP_MENU = getDebugFlag( + "ENABLE_TASKBAR_POPUP_MENU", false, "Enables long pressing taskbar icons to show the" + + " popup menu."); + public static final BooleanFlag ENABLE_OVERVIEW_GRID = getDebugFlag( "ENABLE_OVERVIEW_GRID", true, "Uses grid overview layout. " + "Only applicable on large screen devices.");