From 794fe4f58ea5dfa7f1e8e4e245f00ff9e951168d Mon Sep 17 00:00:00 2001 From: Tony Wickham Date: Mon, 11 Jan 2021 14:54:23 -0600 Subject: [PATCH] Add Hotseat items to Taskbar - Currently supports WorkspaceItemInfo (e.g. normal app icons including hotseat predictions and pinned deep shortcuts). - Currently doesn't support Folders, Notification dots, or long press. Some technical details: - Always allow HotseatPredictionController updates given the Hotseat is always showing even when Launcher is stopped. - Represent Taskbar Hotseat items as BubbleTextViews, to allow for normal click handling etc. When the hotseat is updated, we reuse the same BubbleTextViews that were initially inflated, and just reapply the new info. - Add new BubbleTextView iconDisplay for Taskbar, to allow for different treatment such as icon size. Bug: 171917176 Change-Id: I325eb39051f2dc69228b39b5c40ed0cbdad8e200 --- quickstep/res/layout/taskbar.xml | 4 +- quickstep/res/layout/taskbar_app_icon.xml | 17 ++++ .../res/layout/taskbar_predicted_app_icon.xml | 17 ++++ quickstep/res/values/dimens.xml | 3 + quickstep/res/values/styles.xml | 6 ++ .../launcher3/BaseQuickstepLauncher.java | 9 ++ .../QuickstepAppTransitionManagerImpl.java | 8 +- .../HotseatPredictionController.java | 13 ++- .../launcher3/taskbar/TaskbarController.java | 57 ++++++++++++ .../taskbar/TaskbarHotseatController.java | 90 +++++++++++++++++++ .../launcher3/taskbar/TaskbarView.java | 76 ++++++++++++++++ .../uioverrides/PredictedAppIcon.java | 5 +- res/values/attrs.xml | 1 + src/com/android/launcher3/BubbleTextView.java | 9 +- src/com/android/launcher3/Launcher.java | 14 +++ .../LauncherAppTransitionManager.java | 2 +- .../launcher3/touch/ItemClickHandler.java | 2 +- 17 files changed, 323 insertions(+), 10 deletions(-) create mode 100644 quickstep/res/layout/taskbar_app_icon.xml create mode 100644 quickstep/res/layout/taskbar_predicted_app_icon.xml create mode 100644 quickstep/src/com/android/launcher3/taskbar/TaskbarHotseatController.java diff --git a/quickstep/res/layout/taskbar.xml b/quickstep/res/layout/taskbar.xml index 5f1046df4e..b124b33290 100644 --- a/quickstep/res/layout/taskbar.xml +++ b/quickstep/res/layout/taskbar.xml @@ -24,6 +24,8 @@ android:id="@+id/taskbar_view" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:background="@color/taskbar_background"/> + android:background="@color/taskbar_background" + android:gravity="center" + android:animateLayoutChanges="true"/> \ No newline at end of file diff --git a/quickstep/res/layout/taskbar_app_icon.xml b/quickstep/res/layout/taskbar_app_icon.xml new file mode 100644 index 0000000000..6fefdb69dc --- /dev/null +++ b/quickstep/res/layout/taskbar_app_icon.xml @@ -0,0 +1,17 @@ + + + + diff --git a/quickstep/res/layout/taskbar_predicted_app_icon.xml b/quickstep/res/layout/taskbar_predicted_app_icon.xml new file mode 100644 index 0000000000..211ebc80cd --- /dev/null +++ b/quickstep/res/layout/taskbar_predicted_app_icon.xml @@ -0,0 +1,17 @@ + + + + diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml index 4272f50b56..f082b83c4a 100644 --- a/quickstep/res/values/dimens.xml +++ b/quickstep/res/values/dimens.xml @@ -122,4 +122,7 @@ 48dp + 32dp + + 14dp diff --git a/quickstep/res/values/styles.xml b/quickstep/res/values/styles.xml index 8d054b4be5..5a353f0a59 100644 --- a/quickstep/res/values/styles.xml +++ b/quickstep/res/values/styles.xml @@ -85,4 +85,10 @@ 8dp false + + + \ No newline at end of file diff --git a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java index 09a3cfd184..cbe0eb0795 100644 --- a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java +++ b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java @@ -264,6 +264,11 @@ public abstract class BaseQuickstepLauncher extends Launcher return mTaskbarStateHandler; } + @Override + public boolean isViewInTaskbar(View v) { + return mTaskbarController != null && mTaskbarController.isViewInTaskbar(v); + } + @Override public void useFadeOutAnimationForLauncherStart(CancellationSignal signal) { QuickstepAppTransitionManagerImpl appTransitionManager = @@ -350,6 +355,10 @@ public abstract class BaseQuickstepLauncher extends Launcher // populating workspace. // TODO: Find a better place for this WellbeingModel.INSTANCE.get(this); + + if (mTaskbarController != null) { + mTaskbarController.onHotseatUpdated(); + } } @Override diff --git a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java index 36c8bb8b99..876cabc61b 100644 --- a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java +++ b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java @@ -202,9 +202,10 @@ public abstract class QuickstepAppTransitionManagerImpl extends LauncherAppTrans } @Override - public boolean supportsAdaptiveIconAnimation() { + public boolean supportsAdaptiveIconAnimation(View clickedView) { return hasControlRemoteAppTransitionPermission() - && FeatureFlags.ADAPTIVE_ICON_WINDOW_ANIM.get(); + && FeatureFlags.ADAPTIVE_ICON_WINDOW_ANIM.get() + && !mLauncher.isViewInTaskbar(clickedView); } /** @@ -972,9 +973,12 @@ public abstract class QuickstepAppTransitionManagerImpl extends LauncherAppTrans launcherIsATargetWithMode(appTargets, MODE_CLOSING); final boolean launchingFromRecents = isLaunchingFromRecents(mV, appTargets); + final boolean launchingFromTaskbar = mLauncher.isViewInTaskbar(mV); if (launchingFromRecents) { composeRecentsLaunchAnimator(anim, mV, appTargets, wallpaperTargets, launcherClosing); + } else if (launchingFromTaskbar) { + // TODO } else { composeIconLaunchAnimator(anim, mV, appTargets, wallpaperTargets, launcherClosing); diff --git a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java index b2de4c95ad..aa6601b8c8 100644 --- a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java +++ b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java @@ -37,7 +37,6 @@ import com.android.launcher3.DragSource; import com.android.launcher3.DropTarget; import com.android.launcher3.Hotseat; import com.android.launcher3.InvariantDeviceProfile; -import com.android.launcher3.Launcher; import com.android.launcher3.LauncherSettings; import com.android.launcher3.R; import com.android.launcher3.Utilities; @@ -75,7 +74,7 @@ public class HotseatPredictionController implements DragController.DragListener, private int mHotSeatItemsCount; - private Launcher mLauncher; + private QuickstepLauncher mLauncher; private final Hotseat mHotseat; private List mPredictedItems = Collections.emptyList(); @@ -108,7 +107,7 @@ public class HotseatPredictionController implements DragController.DragListener, return true; }; - public HotseatPredictionController(Launcher launcher) { + public HotseatPredictionController(QuickstepLauncher launcher) { mLauncher = launcher; mHotseat = launcher.getHotseat(); mHotSeatItemsCount = mLauncher.getDeviceProfile().inv.numHotseatIcons; @@ -229,6 +228,10 @@ public class HotseatPredictionController implements DragController.DragListener, } else { if (callback != null) callback.run(); } + + if (mLauncher.getTaskbarController() != null) { + mLauncher.getTaskbarController().onHotseatUpdated(); + } } /** @@ -242,6 +245,10 @@ public class HotseatPredictionController implements DragController.DragListener, * start and pauses predicted apps update on the hotseat */ public void setPauseUIUpdate(boolean paused) { + if (mLauncher.getTaskbarController() != null) { + // Taskbar is present, always allow updates since hotseat is still visible. + return; + } mUIUpdatePaused = paused; if (!paused) { fillGapsWithPrediction(); diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java index bdf7f8ad08..f91bfb78fc 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java @@ -26,6 +26,7 @@ import android.animation.Animator; import android.graphics.PixelFormat; import android.graphics.Point; import android.view.Gravity; +import android.view.View; import android.view.WindowManager; import androidx.annotation.Nullable; @@ -36,7 +37,9 @@ import com.android.launcher3.QuickstepAppTransitionManagerImpl; import com.android.launcher3.R; import com.android.launcher3.anim.AlphaUpdateListener; import com.android.launcher3.anim.PendingAnimation; +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.system.WindowManagerWrapper; @@ -55,6 +58,7 @@ public class TaskbarController { private final Point mTaskbarSize; private final TaskbarStateHandler mTaskbarStateHandler; private final TaskbarVisibilityController mTaskbarVisibilityController; + private final TaskbarHotseatController mHotseatController; // Initialized in init(). private WindowManager.LayoutParams mWindowLayoutParams; @@ -64,12 +68,15 @@ public class TaskbarController { mLauncher = launcher; mTaskbarContainerView = taskbarContainerView; mTaskbarView = mTaskbarContainerView.findViewById(R.id.taskbar_view); + mTaskbarView.setCallbacks(createTaskbarViewCallbacks()); mWindowManager = mLauncher.getWindowManager(); mTaskbarSize = new Point(MATCH_PARENT, mLauncher.getResources().getDimensionPixelSize(R.dimen.taskbar_size)); mTaskbarStateHandler = mLauncher.getTaskbarStateHandler(); mTaskbarVisibilityController = new TaskbarVisibilityController(mLauncher, createTaskbarVisibilityControllerCallbacks()); + mHotseatController = new TaskbarHotseatController(mLauncher, + createTaskbarHotseatControllerCallbacks()); } private TaskbarVisibilityControllerCallbacks createTaskbarVisibilityControllerCallbacks() { @@ -87,13 +94,33 @@ public class TaskbarController { }; } + private TaskbarViewCallbacks createTaskbarViewCallbacks() { + return new TaskbarViewCallbacks() { + @Override + public View.OnClickListener getItemOnClickListener() { + return ItemClickHandler.INSTANCE; + } + }; + } + + private TaskbarHotseatControllerCallbacks createTaskbarHotseatControllerCallbacks() { + return new TaskbarHotseatControllerCallbacks() { + @Override + public void updateHotseatItems(ItemInfo[] hotseatItemInfos) { + mTaskbarView.updateHotseatItems(hotseatItemInfos); + } + }; + } + /** * Initializes the Taskbar, including adding it to the screen. */ public void init() { + mTaskbarView.init(mHotseatController.getNumHotseatIcons()); addToWindowManager(); mTaskbarStateHandler.setTaskbarCallbacks(createTaskbarStateHandlerCallbacks()); mTaskbarVisibilityController.init(); + mHotseatController.init(); } private TaskbarStateHandlerCallbacks createTaskbarStateHandlerCallbacks() { @@ -109,9 +136,11 @@ public class TaskbarController { * Removes the Taskbar from the screen, and removes any obsolete listeners etc. */ public void cleanup() { + mTaskbarView.cleanup(); removeFromWindowManager(); mTaskbarStateHandler.setTaskbarCallbacks(null); mTaskbarVisibilityController.cleanup(); + mHotseatController.cleanup(); } private void removeFromWindowManager() { @@ -190,6 +219,20 @@ public class TaskbarController { mTaskbarVisibilityController.animateToVisibilityForIme(isImeVisible ? 0 : 1); } + /** + * Should be called when one or more items in the Hotseat have changed. + */ + public void onHotseatUpdated() { + mHotseatController.onHotseatUpdated(); + } + + /** + * @return Whether the given View is in the same window as Taskbar. + */ + public boolean isViewInTaskbar(View v) { + return mTaskbarContainerView.getWindowId().equals(v.getWindowId()); + } + /** * Contains methods that TaskbarStateHandler can call to interface with TaskbarController. */ @@ -205,4 +248,18 @@ public class TaskbarController { void updateTaskbarBackgroundAlpha(float alpha); void updateTaskbarVisibilityAlpha(float alpha); } + + /** + * Contains methods that TaskbarView can call to interface with TaskbarController. + */ + protected interface TaskbarViewCallbacks { + View.OnClickListener getItemOnClickListener(); + } + + /** + * Contains methods that TaskbarHotseatController can call to interface with TaskbarController. + */ + protected interface TaskbarHotseatControllerCallbacks { + void updateHotseatItems(ItemInfo[] hotseatItemInfos); + } } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarHotseatController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarHotseatController.java new file mode 100644 index 0000000000..4dc051aaa9 --- /dev/null +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarHotseatController.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 android.view.View; + +import com.android.launcher3.BaseQuickstepLauncher; +import com.android.launcher3.CellLayout; +import com.android.launcher3.DropTarget; +import com.android.launcher3.Hotseat; +import com.android.launcher3.ShortcutAndWidgetContainer; +import com.android.launcher3.dragndrop.DragController; +import com.android.launcher3.dragndrop.DragOptions; +import com.android.launcher3.model.data.ItemInfo; + +/** + * Works with TaskbarController to update the TaskbarView's Hotseat items. + */ +public class TaskbarHotseatController { + + private final BaseQuickstepLauncher mLauncher; + private final Hotseat mHotseat; + private final TaskbarController.TaskbarHotseatControllerCallbacks mTaskbarCallbacks; + private final int mNumHotseatIcons; + + private final DragController.DragListener mDragListener = new DragController.DragListener() { + @Override + public void onDragStart(DropTarget.DragObject dragObject, DragOptions options) { + } + + @Override + public void onDragEnd() { + onHotseatUpdated(); + } + }; + + public TaskbarHotseatController(BaseQuickstepLauncher launcher, + TaskbarController.TaskbarHotseatControllerCallbacks taskbarCallbacks) { + mLauncher = launcher; + mHotseat = mLauncher.getHotseat(); + mTaskbarCallbacks = taskbarCallbacks; + mNumHotseatIcons = mLauncher.getDeviceProfile().inv.numHotseatIcons; + } + + protected void init() { + mLauncher.getDragController().addDragListener(mDragListener); + } + + protected void cleanup() { + mLauncher.getDragController().removeDragListener(mDragListener); + } + + /** + * Called when any Hotseat item changes, and reports the new list of items to TaskbarController. + */ + protected void onHotseatUpdated() { + ShortcutAndWidgetContainer shortcutsAndWidgets = mHotseat.getShortcutsAndWidgets(); + ItemInfo[] hotseatItemInfos = new ItemInfo[mNumHotseatIcons]; + for (int i = 0; i < shortcutsAndWidgets.getChildCount(); i++) { + View child = shortcutsAndWidgets.getChildAt(i); + Object tag = shortcutsAndWidgets.getChildAt(i).getTag(); + if (tag instanceof ItemInfo) { + ItemInfo itemInfo = (ItemInfo) tag; + CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams(); + // Since the hotseat might be laid out vertically or horizontally, use whichever + // index is higher. + hotseatItemInfos[Math.max(lp.cellX, lp.cellY)] = itemInfo; + } + } + + mTaskbarCallbacks.updateHotseatItems(hotseatItemInfos); + } + + protected int getNumHotseatIcons() { + return mNumHotseatIcons; + } +} diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java index bf6e946f0d..0d82810935 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java @@ -16,19 +16,35 @@ package com.android.launcher3.taskbar; import android.content.Context; +import android.content.res.Resources; import android.graphics.drawable.ColorDrawable; import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.view.View; import android.widget.LinearLayout; +import androidx.annotation.LayoutRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import com.android.launcher3.BubbleTextView; +import com.android.launcher3.R; +import com.android.launcher3.model.data.ItemInfo; +import com.android.launcher3.model.data.WorkspaceItemInfo; + /** * Hosts the Taskbar content such as Hotseat and Recent Apps. Drawn on top of other apps. */ public class TaskbarView extends LinearLayout { private final ColorDrawable mBackgroundDrawable; + private final int mItemMarginLeftRight; + + // Initialized in init(). + private int mHotseatStartIndex; + private int mHotseatEndIndex; + + private TaskbarController.TaskbarViewCallbacks mControllerCallbacks; public TaskbarView(@NonNull Context context) { this(context, null); @@ -46,7 +62,24 @@ public class TaskbarView extends LinearLayout { public TaskbarView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); + + Resources resources = getResources(); mBackgroundDrawable = (ColorDrawable) getBackground(); + mItemMarginLeftRight = resources.getDimensionPixelSize(R.dimen.taskbar_icon_spacing); + } + + protected void setCallbacks(TaskbarController.TaskbarViewCallbacks taskbarViewCallbacks) { + mControllerCallbacks = taskbarViewCallbacks; + } + + protected void init(int numHotseatIcons) { + mHotseatStartIndex = 0; + mHotseatEndIndex = mHotseatStartIndex + numHotseatIcons - 1; + updateHotseatItems(new ItemInfo[numHotseatIcons]); + } + + protected void cleanup() { + removeAllViews(); } /** @@ -56,4 +89,47 @@ public class TaskbarView extends LinearLayout { public void setBackgroundAlpha(float alpha) { mBackgroundDrawable.setAlpha((int) (alpha * 255)); } + + /** + * Inflates/binds the Hotseat views to show in the Taskbar given their ItemInfos. + */ + protected void updateHotseatItems(ItemInfo[] hotseatItemInfos) { + for (int i = 0; i < hotseatItemInfos.length; i++) { + ItemInfo hotseatItemInfo = hotseatItemInfos[i]; + int hotseatIndex = mHotseatStartIndex + i; + View hotseatView = getChildAt(hotseatIndex); + + // Replace any Hotseat views with the appropriate type if it's not already that type. + final int expectedLayoutResId; + if (hotseatItemInfo != null && hotseatItemInfo.isPredictedItem()) { + expectedLayoutResId = R.layout.taskbar_predicted_app_icon; + } else { + expectedLayoutResId = R.layout.taskbar_app_icon; + } + if (hotseatView == null || hotseatView.getSourceLayoutResId() != expectedLayoutResId) { + removeView(hotseatView); + BubbleTextView btv = (BubbleTextView) inflate(expectedLayoutResId); + LayoutParams lp = new LayoutParams(btv.getIconSize(), btv.getIconSize()); + lp.setMargins(mItemMarginLeftRight, 0, mItemMarginLeftRight, 0); + hotseatView = btv; + addView(hotseatView, hotseatIndex, lp); + } + + // Apply the Hotseat ItemInfos, or hide the view if there is none for a given index. + if (hotseatView instanceof BubbleTextView + && hotseatItemInfo instanceof WorkspaceItemInfo) { + ((BubbleTextView) hotseatView).applyFromWorkspaceItem( + (WorkspaceItemInfo) hotseatItemInfo); + hotseatView.setVisibility(VISIBLE); + hotseatView.setOnClickListener(mControllerCallbacks.getItemOnClickListener()); + } else { + hotseatView.setVisibility(GONE); + hotseatView.setOnClickListener(null); + } + } + } + + private View inflate(@LayoutRes int layoutResId) { + return LayoutInflater.from(getContext()).inflate(layoutResId, this, false); + } } diff --git a/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java b/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java index 597c17b4e2..22c4a7eba3 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java +++ b/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java @@ -184,7 +184,10 @@ public class PredictedAppIcon extends DoubleShadowBubbleTextView implements } private int getOutlineOffsetY() { - return getPaddingTop() + mDeviceProfile.folderIconOffsetYPx; + if (mDisplay != DISPLAY_TASKBAR) { + return getPaddingTop() + mDeviceProfile.folderIconOffsetYPx; + } + return (getMeasuredHeight() / 2) - mNormalizedIconRadius; } private void drawEffect(Canvas canvas, boolean isBadged) { diff --git a/res/values/attrs.xml b/res/values/attrs.xml index 96c30b5f03..e593fb497d 100644 --- a/res/values/attrs.xml +++ b/res/values/attrs.xml @@ -57,6 +57,7 @@ + diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java index ecda501f1f..140340af62 100644 --- a/src/com/android/launcher3/BubbleTextView.java +++ b/src/com/android/launcher3/BubbleTextView.java @@ -92,6 +92,7 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, private static final int DISPLAY_ALL_APPS = 1; private static final int DISPLAY_FOLDER = 2; private static final int DISPLAY_HERO_APP = 5; + protected static final int DISPLAY_TASKBAR = 6; private static final int[] STATE_PRESSED = new int[]{android.R.attr.state_pressed}; private static final float HIGHLIGHT_SCALE = 1.16f; @@ -140,7 +141,7 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, private Drawable mIcon; private boolean mCenterVertically; - private final int mDisplay; + protected final int mDisplay; private final CheckLongPressHelper mLongPressHelper; @@ -206,6 +207,8 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, defaultIconSize = grid.folderChildIconSizePx; } else if (mDisplay == DISPLAY_HERO_APP) { defaultIconSize = grid.allAppsIconSizePx; + } else if (mDisplay == DISPLAY_TASKBAR) { + defaultIconSize = grid.iconSizePx; } else { // widget_selection or shortcut_popup defaultIconSize = grid.iconSizePx; @@ -487,6 +490,10 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, * @param canvas The canvas to draw to. */ protected void drawDotIfNecessary(Canvas canvas) { + if (mDisplay == DISPLAY_TASKBAR) { + // TODO: support notification dots in Taskbar + return; + } if (!mForceHideDot && (hasDot() || mDotParams.scale > 0)) { getIconBounds(mDotParams.iconBounds); Utilities.scaleRectAboutCenter(mDotParams.iconBounds, diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 0274775244..2334267fd9 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -1917,6 +1917,13 @@ public class Launcher extends StatefulActivity implements Launche @Override public boolean startActivitySafely(View v, Intent intent, ItemInfo item) { + if (isViewInTaskbar(v)) { + // Start the activity without the hacky workarounds below, which assume the View was + // clicked when Launcher was resumed and will be hidden until Launcher is re-resumed + // (this isn't the case for Taskbar). + return super.startActivitySafely(v, intent, item); + } + if (!hasBeenResumed()) { // Workaround an issue where the WM launch animation is clobbered when finishing the // recents animation into launcher. Defer launching the activity until Launcher is @@ -2818,6 +2825,13 @@ public class Launcher extends StatefulActivity implements Launche .start(); } + /** + * @return Whether the View is in the same window as the Taskbar window. + */ + public boolean isViewInTaskbar(View v) { + return false; + } + private static class NonConfigInstance { public Configuration config; public Bitmap snapshot; diff --git a/src/com/android/launcher3/LauncherAppTransitionManager.java b/src/com/android/launcher3/LauncherAppTransitionManager.java index ac3ad9f8fd..0fa441a279 100644 --- a/src/com/android/launcher3/LauncherAppTransitionManager.java +++ b/src/com/android/launcher3/LauncherAppTransitionManager.java @@ -50,7 +50,7 @@ public class LauncherAppTransitionManager implements ResourceBasedOverride { return ActivityOptions.makeClipRevealAnimation(v, left, top, width, height); } - public boolean supportsAdaptiveIconAnimation() { + public boolean supportsAdaptiveIconAnimation(View clickedView) { return false; } diff --git a/src/com/android/launcher3/touch/ItemClickHandler.java b/src/com/android/launcher3/touch/ItemClickHandler.java index 3122c68304..2647d6fec4 100644 --- a/src/com/android/launcher3/touch/ItemClickHandler.java +++ b/src/com/android/launcher3/touch/ItemClickHandler.java @@ -302,7 +302,7 @@ public class ItemClickHandler { intent.setPackage(null); } } - if (v != null && launcher.getAppTransitionManager().supportsAdaptiveIconAnimation()) { + if (v != null && launcher.getAppTransitionManager().supportsAdaptiveIconAnimation(v)) { // Preload the icon to reduce latency b/w swapping the floating view with the original. FloatingIconView.fetchIcon(launcher, v, item, true /* isOpening */); }