Loading quickstep/res/layout/taskbar_divider.xml 0 → 100644 +23 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- 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. --> <View xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="@dimen/taskbar_divider_thickness" android:layout_height="@dimen/taskbar_divider_height" android:layout_marginStart="@dimen/taskbar_icon_spacing" android:layout_marginEnd="@dimen/taskbar_icon_spacing" android:background="@color/taskbar_divider" /> No newline at end of file quickstep/res/values/colors.xml +1 −0 Original line number Diff line number Diff line Loading @@ -27,4 +27,5 @@ <!-- Taskbar --> <color name="taskbar_background">#101010</color> <color name="taskbar_divider">#C0C0C0</color> </resources> No newline at end of file quickstep/res/values/dimens.xml +2 −0 Original line number Diff line number Diff line Loading @@ -127,4 +127,6 @@ <dimen name="taskbar_icon_drag_icon_size">54dp</dimen> <!-- Note that this applies to both sides of all icons, so visible space is double this. --> <dimen name="taskbar_icon_spacing">14dp</dimen> <dimen name="taskbar_divider_thickness">1dp</dimen> <dimen name="taskbar_divider_height">24dp</dimen> </resources> quickstep/src/com/android/launcher3/taskbar/TaskbarController.java +100 −2 Original line number Diff line number Diff line Loading @@ -23,6 +23,8 @@ import static com.android.systemui.shared.system.WindowManagerWrapper.ITYPE_BOTT import static com.android.systemui.shared.system.WindowManagerWrapper.ITYPE_EXTRA_NAVIGATION_BAR; import android.animation.Animator; import android.app.ActivityOptions; import android.content.ComponentName; import android.graphics.PixelFormat; import android.graphics.Point; import android.view.Gravity; Loading @@ -42,8 +44,13 @@ import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.states.StateAnimationConfig; import com.android.launcher3.touch.ItemClickHandler; import com.android.quickstep.AnimatedFloat; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.WindowManagerWrapper; import java.util.ArrayList; import java.util.List; /** * Interfaces with Launcher/WindowManager/SystemUI to determine what to show in TaskbarView. */ Loading @@ -60,11 +67,17 @@ public class TaskbarController { private final TaskbarStateHandler mTaskbarStateHandler; private final TaskbarVisibilityController mTaskbarVisibilityController; private final TaskbarHotseatController mHotseatController; private final TaskbarRecentsController mRecentsController; private final TaskbarDragController mDragController; // Initialized in init(). private WindowManager.LayoutParams mWindowLayoutParams; // Contains all loaded Tasks, not yet deduped from Hotseat items. private List<Task> mLatestLoadedRecentTasks; // Contains all loaded Hotseat items. private ItemInfo[] mLatestLoadedHotseatItems; public TaskbarController(BaseQuickstepLauncher launcher, TaskbarContainerView taskbarContainerView) { mLauncher = launcher; Loading @@ -79,6 +92,8 @@ public class TaskbarController { createTaskbarVisibilityControllerCallbacks()); mHotseatController = new TaskbarHotseatController(mLauncher, createTaskbarHotseatControllerCallbacks()); mRecentsController = new TaskbarRecentsController(mLauncher, createTaskbarRecentsControllerCallbacks()); mDragController = new TaskbarDragController(mLauncher); } Loading @@ -101,7 +116,16 @@ public class TaskbarController { return new TaskbarViewCallbacks() { @Override public View.OnClickListener getItemOnClickListener() { return ItemClickHandler.INSTANCE; return view -> { Object tag = view.getTag(); if (tag instanceof Task) { Task task = (Task) tag; ActivityManagerWrapper.getInstance().startActivityFromRecents(task.key, ActivityOptions.makeBasic()); } else { ItemClickHandler.INSTANCE.onClick(view); } }; } @Override Loading @@ -116,6 +140,23 @@ public class TaskbarController { @Override public void updateHotseatItems(ItemInfo[] hotseatItemInfos) { mTaskbarView.updateHotseatItems(hotseatItemInfos); mLatestLoadedHotseatItems = hotseatItemInfos; dedupeAndUpdateRecentItems(); } }; } private TaskbarRecentsControllerCallbacks createTaskbarRecentsControllerCallbacks() { return new TaskbarRecentsControllerCallbacks() { @Override public void updateRecentItems(ArrayList<Task> recentTasks) { mLatestLoadedRecentTasks = recentTasks; dedupeAndUpdateRecentItems(); } @Override public void updateRecentTaskAtIndex(int taskIndex, Task task) { mTaskbarView.updateRecentTaskAtIndex(taskIndex, task); } }; } Loading @@ -124,11 +165,13 @@ public class TaskbarController { * Initializes the Taskbar, including adding it to the screen. */ public void init() { mTaskbarView.init(mHotseatController.getNumHotseatIcons()); mTaskbarView.init(mHotseatController.getNumHotseatIcons(), mRecentsController.getNumRecentIcons()); addToWindowManager(); mTaskbarStateHandler.setTaskbarCallbacks(createTaskbarStateHandlerCallbacks()); mTaskbarVisibilityController.init(); mHotseatController.init(); mRecentsController.init(); } private TaskbarStateHandlerCallbacks createTaskbarStateHandlerCallbacks() { Loading @@ -149,6 +192,7 @@ public class TaskbarController { mTaskbarStateHandler.setTaskbarCallbacks(null); mTaskbarVisibilityController.cleanup(); mHotseatController.cleanup(); mRecentsController.cleanup(); } private void removeFromWindowManager() { Loading Loading @@ -246,6 +290,52 @@ public class TaskbarController { return mTaskbarView.isDraggingItem(); } private void dedupeAndUpdateRecentItems() { if (mLatestLoadedRecentTasks == null || mLatestLoadedHotseatItems == null) { return; } final int numRecentIcons = mRecentsController.getNumRecentIcons(); // From most recent to least recently opened. List<Task> dedupedTasksInDescendingOrder = new ArrayList<>(); for (int i = mLatestLoadedRecentTasks.size() - 1; i >= 0; i--) { Task task = mLatestLoadedRecentTasks.get(i); boolean isTaskInHotseat = false; for (ItemInfo hotseatItem : mLatestLoadedHotseatItems) { if (hotseatItem == null) { continue; } ComponentName hotseatActivity = hotseatItem.getTargetComponent(); if (hotseatActivity != null && task.key.sourceComponent.getPackageName() .equals(hotseatActivity.getPackageName())) { isTaskInHotseat = true; break; } } if (!isTaskInHotseat) { dedupedTasksInDescendingOrder.add(task); if (dedupedTasksInDescendingOrder.size() == numRecentIcons) { break; } } } // TaskbarView expects an array of all the recent tasks to show, in the order to show them. // So we create an array of the proper size, then fill it in such that the most recent items // are at the end. If there aren't enough elements to fill the array, leave them null. Task[] tasksArray = new Task[numRecentIcons]; for (int i = 0; i < tasksArray.length; i++) { Task task = i >= dedupedTasksInDescendingOrder.size() ? null : dedupedTasksInDescendingOrder.get(i); tasksArray[tasksArray.length - 1 - i] = task; } mTaskbarView.updateRecentTasks(tasksArray); mRecentsController.loadIconsForTasks(tasksArray); } /** * @return Whether the given View is in the same window as Taskbar. */ Loading Loading @@ -283,4 +373,12 @@ public class TaskbarController { protected interface TaskbarHotseatControllerCallbacks { void updateHotseatItems(ItemInfo[] hotseatItemInfos); } /** * Contains methods that TaskbarRecentsController can call to interface with TaskbarController. */ protected interface TaskbarRecentsControllerCallbacks { void updateRecentItems(ArrayList<Task> recentTasks); void updateRecentTaskAtIndex(int taskIndex, Task task); } } quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java +11 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.content.pm.LauncherApps; import android.content.res.Resources; import android.graphics.Canvas; import android.graphics.Point; import android.os.UserHandle; import android.view.DragEvent; import android.view.View; Loading @@ -33,6 +34,7 @@ import com.android.launcher3.BubbleTextView; import com.android.launcher3.LauncherSettings; import com.android.launcher3.R; import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.system.ClipDescriptionCompat; import com.android.systemui.shared.system.LauncherAppsCompat; Loading Loading @@ -102,6 +104,15 @@ public class TaskbarDragController { item.getIntent().getComponent(), null, item.user)); } intent.putExtra(Intent.EXTRA_USER, item.user); } else if (tag instanceof Task) { Task task = (Task) tag; clipDescription = new ClipDescription(task.titleDescription, new String[] { ClipDescriptionCompat.MIMETYPE_APPLICATION_TASK }); intent = new Intent(); intent.putExtra(ClipDescriptionCompat.EXTRA_TASK_ID, task.key.id); intent.putExtra(Intent.EXTRA_USER, UserHandle.of(task.key.userId)); } if (clipDescription != null && intent != null) { Loading Loading
quickstep/res/layout/taskbar_divider.xml 0 → 100644 +23 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- 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. --> <View xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="@dimen/taskbar_divider_thickness" android:layout_height="@dimen/taskbar_divider_height" android:layout_marginStart="@dimen/taskbar_icon_spacing" android:layout_marginEnd="@dimen/taskbar_icon_spacing" android:background="@color/taskbar_divider" /> No newline at end of file
quickstep/res/values/colors.xml +1 −0 Original line number Diff line number Diff line Loading @@ -27,4 +27,5 @@ <!-- Taskbar --> <color name="taskbar_background">#101010</color> <color name="taskbar_divider">#C0C0C0</color> </resources> No newline at end of file
quickstep/res/values/dimens.xml +2 −0 Original line number Diff line number Diff line Loading @@ -127,4 +127,6 @@ <dimen name="taskbar_icon_drag_icon_size">54dp</dimen> <!-- Note that this applies to both sides of all icons, so visible space is double this. --> <dimen name="taskbar_icon_spacing">14dp</dimen> <dimen name="taskbar_divider_thickness">1dp</dimen> <dimen name="taskbar_divider_height">24dp</dimen> </resources>
quickstep/src/com/android/launcher3/taskbar/TaskbarController.java +100 −2 Original line number Diff line number Diff line Loading @@ -23,6 +23,8 @@ import static com.android.systemui.shared.system.WindowManagerWrapper.ITYPE_BOTT import static com.android.systemui.shared.system.WindowManagerWrapper.ITYPE_EXTRA_NAVIGATION_BAR; import android.animation.Animator; import android.app.ActivityOptions; import android.content.ComponentName; import android.graphics.PixelFormat; import android.graphics.Point; import android.view.Gravity; Loading @@ -42,8 +44,13 @@ import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.states.StateAnimationConfig; import com.android.launcher3.touch.ItemClickHandler; import com.android.quickstep.AnimatedFloat; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.WindowManagerWrapper; import java.util.ArrayList; import java.util.List; /** * Interfaces with Launcher/WindowManager/SystemUI to determine what to show in TaskbarView. */ Loading @@ -60,11 +67,17 @@ public class TaskbarController { private final TaskbarStateHandler mTaskbarStateHandler; private final TaskbarVisibilityController mTaskbarVisibilityController; private final TaskbarHotseatController mHotseatController; private final TaskbarRecentsController mRecentsController; private final TaskbarDragController mDragController; // Initialized in init(). private WindowManager.LayoutParams mWindowLayoutParams; // Contains all loaded Tasks, not yet deduped from Hotseat items. private List<Task> mLatestLoadedRecentTasks; // Contains all loaded Hotseat items. private ItemInfo[] mLatestLoadedHotseatItems; public TaskbarController(BaseQuickstepLauncher launcher, TaskbarContainerView taskbarContainerView) { mLauncher = launcher; Loading @@ -79,6 +92,8 @@ public class TaskbarController { createTaskbarVisibilityControllerCallbacks()); mHotseatController = new TaskbarHotseatController(mLauncher, createTaskbarHotseatControllerCallbacks()); mRecentsController = new TaskbarRecentsController(mLauncher, createTaskbarRecentsControllerCallbacks()); mDragController = new TaskbarDragController(mLauncher); } Loading @@ -101,7 +116,16 @@ public class TaskbarController { return new TaskbarViewCallbacks() { @Override public View.OnClickListener getItemOnClickListener() { return ItemClickHandler.INSTANCE; return view -> { Object tag = view.getTag(); if (tag instanceof Task) { Task task = (Task) tag; ActivityManagerWrapper.getInstance().startActivityFromRecents(task.key, ActivityOptions.makeBasic()); } else { ItemClickHandler.INSTANCE.onClick(view); } }; } @Override Loading @@ -116,6 +140,23 @@ public class TaskbarController { @Override public void updateHotseatItems(ItemInfo[] hotseatItemInfos) { mTaskbarView.updateHotseatItems(hotseatItemInfos); mLatestLoadedHotseatItems = hotseatItemInfos; dedupeAndUpdateRecentItems(); } }; } private TaskbarRecentsControllerCallbacks createTaskbarRecentsControllerCallbacks() { return new TaskbarRecentsControllerCallbacks() { @Override public void updateRecentItems(ArrayList<Task> recentTasks) { mLatestLoadedRecentTasks = recentTasks; dedupeAndUpdateRecentItems(); } @Override public void updateRecentTaskAtIndex(int taskIndex, Task task) { mTaskbarView.updateRecentTaskAtIndex(taskIndex, task); } }; } Loading @@ -124,11 +165,13 @@ public class TaskbarController { * Initializes the Taskbar, including adding it to the screen. */ public void init() { mTaskbarView.init(mHotseatController.getNumHotseatIcons()); mTaskbarView.init(mHotseatController.getNumHotseatIcons(), mRecentsController.getNumRecentIcons()); addToWindowManager(); mTaskbarStateHandler.setTaskbarCallbacks(createTaskbarStateHandlerCallbacks()); mTaskbarVisibilityController.init(); mHotseatController.init(); mRecentsController.init(); } private TaskbarStateHandlerCallbacks createTaskbarStateHandlerCallbacks() { Loading @@ -149,6 +192,7 @@ public class TaskbarController { mTaskbarStateHandler.setTaskbarCallbacks(null); mTaskbarVisibilityController.cleanup(); mHotseatController.cleanup(); mRecentsController.cleanup(); } private void removeFromWindowManager() { Loading Loading @@ -246,6 +290,52 @@ public class TaskbarController { return mTaskbarView.isDraggingItem(); } private void dedupeAndUpdateRecentItems() { if (mLatestLoadedRecentTasks == null || mLatestLoadedHotseatItems == null) { return; } final int numRecentIcons = mRecentsController.getNumRecentIcons(); // From most recent to least recently opened. List<Task> dedupedTasksInDescendingOrder = new ArrayList<>(); for (int i = mLatestLoadedRecentTasks.size() - 1; i >= 0; i--) { Task task = mLatestLoadedRecentTasks.get(i); boolean isTaskInHotseat = false; for (ItemInfo hotseatItem : mLatestLoadedHotseatItems) { if (hotseatItem == null) { continue; } ComponentName hotseatActivity = hotseatItem.getTargetComponent(); if (hotseatActivity != null && task.key.sourceComponent.getPackageName() .equals(hotseatActivity.getPackageName())) { isTaskInHotseat = true; break; } } if (!isTaskInHotseat) { dedupedTasksInDescendingOrder.add(task); if (dedupedTasksInDescendingOrder.size() == numRecentIcons) { break; } } } // TaskbarView expects an array of all the recent tasks to show, in the order to show them. // So we create an array of the proper size, then fill it in such that the most recent items // are at the end. If there aren't enough elements to fill the array, leave them null. Task[] tasksArray = new Task[numRecentIcons]; for (int i = 0; i < tasksArray.length; i++) { Task task = i >= dedupedTasksInDescendingOrder.size() ? null : dedupedTasksInDescendingOrder.get(i); tasksArray[tasksArray.length - 1 - i] = task; } mTaskbarView.updateRecentTasks(tasksArray); mRecentsController.loadIconsForTasks(tasksArray); } /** * @return Whether the given View is in the same window as Taskbar. */ Loading Loading @@ -283,4 +373,12 @@ public class TaskbarController { protected interface TaskbarHotseatControllerCallbacks { void updateHotseatItems(ItemInfo[] hotseatItemInfos); } /** * Contains methods that TaskbarRecentsController can call to interface with TaskbarController. */ protected interface TaskbarRecentsControllerCallbacks { void updateRecentItems(ArrayList<Task> recentTasks); void updateRecentTaskAtIndex(int taskIndex, Task task); } }
quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java +11 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.content.pm.LauncherApps; import android.content.res.Resources; import android.graphics.Canvas; import android.graphics.Point; import android.os.UserHandle; import android.view.DragEvent; import android.view.View; Loading @@ -33,6 +34,7 @@ import com.android.launcher3.BubbleTextView; import com.android.launcher3.LauncherSettings; import com.android.launcher3.R; import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.system.ClipDescriptionCompat; import com.android.systemui.shared.system.LauncherAppsCompat; Loading Loading @@ -102,6 +104,15 @@ public class TaskbarDragController { item.getIntent().getComponent(), null, item.user)); } intent.putExtra(Intent.EXTRA_USER, item.user); } else if (tag instanceof Task) { Task task = (Task) tag; clipDescription = new ClipDescription(task.titleDescription, new String[] { ClipDescriptionCompat.MIMETYPE_APPLICATION_TASK }); intent = new Intent(); intent.putExtra(ClipDescriptionCompat.EXTRA_TASK_ID, task.key.id); intent.putExtra(Intent.EXTRA_USER, UserHandle.of(task.key.userId)); } if (clipDescription != null && intent != null) { Loading