Merge "Set remote animations duration based on animation being run" into ub-launcher3-master
diff --git a/quickstep/libs/sysui_shared.jar b/quickstep/libs/sysui_shared.jar
index 662069a..9006831 100644
--- a/quickstep/libs/sysui_shared.jar
+++ b/quickstep/libs/sysui_shared.jar
Binary files differ
diff --git a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
index 3fd1ba0..3b75001 100644
--- a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
+++ b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
@@ -671,7 +671,13 @@
*/
private ValueAnimator getWindowAnimators(View v, RemoteAnimationTargetCompat[] targets) {
Rect bounds = new Rect();
- if (v instanceof BubbleTextView) {
+ boolean isDeepShortcutTextView = v instanceof DeepShortcutTextView
+ && v.getParent() != null && v.getParent() instanceof DeepShortcutView;
+ if (isDeepShortcutTextView) {
+ // Deep shortcut views have their icon drawn in a sibling view.
+ DeepShortcutView view = (DeepShortcutView) v.getParent();
+ mDragLayer.getDescendantRectRelativeToSelf(view.getIconView(), bounds);
+ } else if (v instanceof BubbleTextView) {
((BubbleTextView) v).getIconBounds(bounds);
} else {
mDragLayer.getDescendantRectRelativeToSelf(v, bounds);
diff --git a/quickstep/src/com/android/launcher3/uioverrides/FastOverviewState.java b/quickstep/src/com/android/launcher3/uioverrides/FastOverviewState.java
index c86c5af..8a5c55a 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/FastOverviewState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/FastOverviewState.java
@@ -16,6 +16,8 @@
package com.android.launcher3.uioverrides;
import com.android.launcher3.Launcher;
+import com.android.quickstep.QuickScrubController;
+import com.android.quickstep.RecentsView;
/**
* Extension of overview state used for QuickScrub
@@ -28,7 +30,14 @@
private static final boolean DEBUG_DIFFERENT_UI = false;
public FastOverviewState(int id) {
- super(id, STATE_FLAGS);
+ super(id, QuickScrubController.QUICK_SWITCH_START_DURATION, STATE_FLAGS);
+ }
+
+ @Override
+ public void onStateTransitionEnd(Launcher launcher) {
+ super.onStateTransitionEnd(launcher);
+ RecentsView recentsView = launcher.getOverviewPanel();
+ recentsView.getQuickScrubController().onFinishedTransitionToQuickScrub();
}
@Override
diff --git a/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java b/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java
index 4dfbf8d..a88369d 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java
@@ -37,11 +37,11 @@
| FLAG_DISABLE_RESTORE | FLAG_OVERVIEW_UI;
public OverviewState(int id) {
- this(id, STATE_FLAGS);
+ this(id, OVERVIEW_TRANSITION_MS, STATE_FLAGS);
}
- protected OverviewState(int id, int stateFlags) {
- super(id, ContainerType.TASKSWITCHER, OVERVIEW_TRANSITION_MS, stateFlags);
+ protected OverviewState(int id, int transitionDuration, int stateFlags) {
+ super(id, ContainerType.TASKSWITCHER, transitionDuration, stateFlags);
}
@Override
diff --git a/quickstep/src/com/android/launcher3/uioverrides/OverviewSwipeController.java b/quickstep/src/com/android/launcher3/uioverrides/OverviewSwipeController.java
index 958091b..eb14d60 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/OverviewSwipeController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/OverviewSwipeController.java
@@ -133,8 +133,7 @@
mSwipeDownEnabled = true;
View view = mRecentsView.getChildAt(mRecentsView.getCurrentPage());
- if (mLauncher.getDragLayer().isEventOverView(view, ev) &&
- view instanceof TaskView) {
+ if (view instanceof TaskView && mLauncher.getDragLayer().isEventOverView(view, ev)) {
// The tile can be dragged down to open the task.
mTaskBeingDragged = (TaskView) view;
directionsToDetectScroll = SwipeDetector.DIRECTION_BOTH;
diff --git a/quickstep/src/com/android/quickstep/NormalizedIconLoader.java b/quickstep/src/com/android/quickstep/NormalizedIconLoader.java
index 3247312..f875bb7 100644
--- a/quickstep/src/com/android/quickstep/NormalizedIconLoader.java
+++ b/quickstep/src/com/android/quickstep/NormalizedIconLoader.java
@@ -16,13 +16,13 @@
package com.android.quickstep;
import android.annotation.TargetApi;
+import android.app.ActivityManager.TaskDescription;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Build;
-import android.os.Build.VERSION_CODES;
import android.os.UserHandle;
import android.util.LruCache;
import android.util.SparseArray;
@@ -56,7 +56,7 @@
BitmapInfo info = mDefaultIcons.get(userId);
if (info == null) {
info = getBitmapInfo(Resources.getSystem()
- .getDrawable(android.R.drawable.sym_def_app_icon), userId, false);
+ .getDrawable(android.R.drawable.sym_def_app_icon), userId, 0, false);
mDefaultIcons.put(userId, info);
}
@@ -65,26 +65,30 @@
}
@Override
- protected Drawable createBadgedDrawable(Drawable drawable, int userId) {
- return new FastBitmapDrawable(getBitmapInfo(drawable, userId, false));
+ protected Drawable createBadgedDrawable(Drawable drawable, int userId, TaskDescription desc) {
+ return new FastBitmapDrawable(getBitmapInfo(drawable, userId, desc.getPrimaryColor(),
+ false));
}
private synchronized BitmapInfo getBitmapInfo(Drawable drawable, int userId,
- boolean isInstantApp) {
+ int primaryColor, boolean isInstantApp) {
if (mLauncherIcons == null) {
mLauncherIcons = LauncherIcons.obtain(mContext);
}
+ mLauncherIcons.setWrapperBackgroundColor(primaryColor);
// User version code O, so that the icon is always wrapped in an adaptive icon container.
return mLauncherIcons.createBadgedIconBitmap(drawable, UserHandle.of(userId),
Build.VERSION_CODES.O, isInstantApp);
}
@Override
- protected synchronized Drawable getBadgedActivityIcon(ActivityInfo activityInfo, int userId) {
+ protected Drawable getBadgedActivityIcon(ActivityInfo activityInfo, int userId,
+ TaskDescription desc) {
BitmapInfo bitmapInfo = getBitmapInfo(
activityInfo.loadUnbadgedIcon(mContext.getPackageManager()),
userId,
+ desc.getPrimaryColor(),
activityInfo.applicationInfo.isInstantApp());
return mDrawableFactory.newIcon(bitmapInfo, activityInfo);
}
diff --git a/quickstep/src/com/android/quickstep/QuickScrubController.java b/quickstep/src/com/android/quickstep/QuickScrubController.java
index b9d96b9..0ccd7f2 100644
--- a/quickstep/src/com/android/quickstep/QuickScrubController.java
+++ b/quickstep/src/com/android/quickstep/QuickScrubController.java
@@ -34,8 +34,7 @@
*/
public class QuickScrubController implements OnAlarmListener {
- public static final int QUICK_SWITCH_START_DURATION = 133;
- public static final int QUICK_SWITCH_SNAP_DURATION = 120;
+ public static final int QUICK_SWITCH_START_DURATION = 210;
private static final boolean ENABLE_AUTO_ADVANCE = true;
private static final int NUM_QUICK_SCRUB_SECTIONS = 3;
@@ -52,6 +51,8 @@
private int mQuickScrubSection;
private boolean mStartedFromHome;
private boolean mHasAlarmRun;
+ private boolean mQuickSwitched;
+ private boolean mFinishedTransitionToQuickScrub;
public QuickScrubController(Launcher launcher, RecentsView recentsView) {
mLauncher = launcher;
@@ -67,6 +68,10 @@
mStartedFromHome = startingFromHome;
mQuickScrubSection = 0;
mHasAlarmRun = false;
+ mQuickSwitched = false;
+ mFinishedTransitionToQuickScrub = false;
+
+ snapToNextTaskIfAvailable();
mLauncher.getUserEventDispatcher().resetActionDurationMillis();
}
@@ -97,7 +102,9 @@
int quickScrubSection = Math.round(progress * NUM_QUICK_SCRUB_SECTIONS);
if (quickScrubSection != mQuickScrubSection) {
int pageToGoTo = mRecentsView.getNextPage() + quickScrubSection - mQuickScrubSection;
- goToPageWithHaptic(pageToGoTo);
+ if (mFinishedTransitionToQuickScrub) {
+ goToPageWithHaptic(pageToGoTo);
+ }
if (ENABLE_AUTO_ADVANCE) {
if (quickScrubSection == NUM_QUICK_SCRUB_SECTIONS || quickScrubSection == 0) {
mAutoAdvanceAlarm.setAlarm(mHasAlarmRun
@@ -111,36 +118,45 @@
}
public void onQuickSwitch() {
- for (int i = 0; i < mRecentsView.getPageCount(); i++) {
- TaskView taskView = (TaskView) mRecentsView.getPageAt(i);
- if (taskView.getTask().key.id != mRecentsView.getRunningTaskId()) {
- Runnable launchTaskRunnable = () -> taskView.launchTask(true);
- if (mRecentsView.snapToPage(i, QUICK_SWITCH_SNAP_DURATION)) {
- // Snap to the new page then launch it
- mRecentsView.setNextPageSwitchRunnable(launchTaskRunnable);
- } else {
- // No need to move page, just launch task directly
- launchTaskRunnable.run();
- }
- break;
- }
- }
- mLauncher.getUserEventDispatcher().logActionOnControl(Touch.FLING,
- ControlType.QUICK_SCRUB_BUTTON, null, mStartedFromHome ?
- ContainerType.WORKSPACE : ContainerType.APP);
+ mQuickSwitched = true;
+ quickSwitchIfReady();
}
- public void snapToPageForCurrentQuickScrubSection() {
- if (mInQuickScrub) {
- goToPageWithHaptic(mQuickScrubSection);
+ public void onFinishedTransitionToQuickScrub() {
+ mFinishedTransitionToQuickScrub = true;
+ quickSwitchIfReady();
+ }
+
+ /**
+ * Immediately launches the current task (which we snapped to in onQuickScrubStart) if we've
+ * gotten the onQuickSwitch callback and the transition to quick scrub has completed.
+ */
+ private void quickSwitchIfReady() {
+ if (mQuickSwitched && mFinishedTransitionToQuickScrub) {
+ onQuickScrubEnd();
+ mLauncher.getUserEventDispatcher().logActionOnControl(Touch.FLING,
+ ControlType.QUICK_SCRUB_BUTTON, null, mStartedFromHome ?
+ ContainerType.WORKSPACE : ContainerType.APP);
+ }
+ }
+
+ public void snapToNextTaskIfAvailable() {
+ if (mInQuickScrub && mRecentsView.getChildCount() > 0) {
+ int toPage = mStartedFromHome ? 0 : mRecentsView.getNextPage() + 1;
+ goToPageWithHaptic(toPage, QUICK_SWITCH_START_DURATION);
}
}
private void goToPageWithHaptic(int pageToGoTo) {
+ goToPageWithHaptic(pageToGoTo, -1);
+ }
+
+ private void goToPageWithHaptic(int pageToGoTo, int overrideDuration) {
pageToGoTo = Utilities.boundToRange(pageToGoTo, 0, mRecentsView.getPageCount() - 1);
if (pageToGoTo != mRecentsView.getNextPage()) {
- int duration = Math.abs(pageToGoTo - mRecentsView.getNextPage())
- * QUICKSCRUB_SNAP_DURATION_PER_PAGE;
+ int duration = overrideDuration > -1 ? overrideDuration
+ : Math.abs(pageToGoTo - mRecentsView.getNextPage())
+ * QUICKSCRUB_SNAP_DURATION_PER_PAGE;
mRecentsView.snapToPage(pageToGoTo, duration);
mRecentsView.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP,
HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
diff --git a/quickstep/src/com/android/quickstep/RecentsView.java b/quickstep/src/com/android/quickstep/RecentsView.java
index 9481390..3cd1179 100644
--- a/quickstep/src/com/android/quickstep/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/RecentsView.java
@@ -339,7 +339,7 @@
applyIconScale(false /* animate */);
if (oldChildCount != getChildCount()) {
- mQuickScrubController.snapToPageForCurrentQuickScrubSection();
+ mQuickScrubController.snapToNextTaskIfAvailable();
}
}
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 5d0bec9..04740d9 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -21,9 +21,8 @@
import static android.view.MotionEvent.ACTION_POINTER_DOWN;
import static android.view.MotionEvent.ACTION_POINTER_UP;
import static android.view.MotionEvent.ACTION_UP;
-
import static com.android.launcher3.LauncherState.FAST_OVERVIEW;
-import static com.android.quickstep.QuickScrubController.QUICK_SWITCH_START_DURATION;
+import static com.android.launcher3.LauncherState.NORMAL;
import android.annotation.TargetApi;
import android.app.ActivityManager.RunningTaskInfo;
@@ -45,6 +44,7 @@
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.LauncherState;
import com.android.launcher3.MainThreadExecutor;
import com.android.launcher3.R;
import com.android.launcher3.uioverrides.UiFactory;
@@ -316,13 +316,12 @@
if (TouchConsumer.isInteractionQuick(interactionType)) {
Runnable action = () -> {
Runnable onComplete = null;
- if (interactionType == INTERACTION_QUICK_SCRUB) {
- mQuickScrubController.onQuickScrubStart(true);
- } else if (interactionType == INTERACTION_QUICK_SWITCH) {
+ if (interactionType == INTERACTION_QUICK_SWITCH) {
onComplete = mQuickScrubController::onQuickSwitch;
}
- mLauncher.getStateManager().goToState(FAST_OVERVIEW, true, 0,
- QUICK_SWITCH_START_DURATION, onComplete);
+ LauncherState fromState = mLauncher.getStateManager().getState();
+ mLauncher.getStateManager().goToState(FAST_OVERVIEW, true, onComplete);
+ mQuickScrubController.onQuickScrubStart(fromState == NORMAL);
};
if (mLauncher.getWorkspace().runOnOverlayHidden(action)) {
diff --git a/src/com/android/launcher3/LauncherStateManager.java b/src/com/android/launcher3/LauncherStateManager.java
index 41b66a4..950a8ac 100644
--- a/src/com/android/launcher3/LauncherStateManager.java
+++ b/src/com/android/launcher3/LauncherStateManager.java
@@ -157,11 +157,6 @@
}
private void goToState(LauncherState state, boolean animated, long delay,
- Runnable onCompleteRunnable) {
- goToState(state, animated, delay, -1, onCompleteRunnable);
- }
-
- public void goToState(LauncherState state, boolean animated, long delay, long overrideDuration,
final Runnable onCompleteRunnable) {
if (mLauncher.isInState(state)) {
if (mConfig.mCurrentAnimation == null) {
@@ -208,9 +203,6 @@
// Since state NORMAL can be reached from multiple states, just assume that the
// transition plays in reverse and use the same duration as previous state.
mConfig.duration = state == NORMAL ? mState.transitionDuration : state.transitionDuration;
- if (overrideDuration > -1) {
- mConfig.duration = overrideDuration;
- }
AnimatorSet animation = createAnimationToNewWorkspaceInternal(
state, new AnimatorSetBuilder(), onCompleteRunnable);
diff --git a/src/com/android/launcher3/graphics/LauncherIcons.java b/src/com/android/launcher3/graphics/LauncherIcons.java
index 2e9ff23..3b5585b 100644
--- a/src/com/android/launcher3/graphics/LauncherIcons.java
+++ b/src/com/android/launcher3/graphics/LauncherIcons.java
@@ -29,11 +29,13 @@
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
+import android.graphics.Color;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.AdaptiveIconDrawable;
import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.PaintDrawable;
import android.os.Build;
@@ -60,6 +62,8 @@
*/
public class LauncherIcons implements AutoCloseable {
+ private static final int DEFAULT_WRAPPER_BACKGROUND = Color.WHITE;
+
public static final Object sPoolSync = new Object();
private static LauncherIcons sPool;
@@ -84,6 +88,9 @@
*/
public void recycle() {
synchronized (sPoolSync) {
+ // Clear any temporary state variables
+ mWrapperBackgroundColor = DEFAULT_WRAPPER_BACKGROUND;
+
next = sPool;
sPool = this;
}
@@ -104,7 +111,9 @@
private IconNormalizer mNormalizer;
private ShadowGenerator mShadowGenerator;
+
private Drawable mWrapperIcon;
+ private int mWrapperBackgroundColor = DEFAULT_WRAPPER_BACKGROUND;
// sometimes we store linked lists of these things
private LauncherIcons next;
@@ -222,6 +231,13 @@
Math.min(scale[0], ShadowGenerator.getScaleForBounds(iconBounds)));
}
+ /**
+ * Sets the background color used for wrapped adaptive icon
+ */
+ public void setWrapperBackgroundColor(int color) {
+ mWrapperBackgroundColor = (Color.alpha(color) < 255) ? DEFAULT_WRAPPER_BACKGROUND : color;
+ }
+
private Drawable normalizeAndWrapToAdaptiveIcon(Drawable icon, int iconAppTargetSdk,
RectF outIconBounds, float[] outScale) {
float scale = 1f;
@@ -240,6 +256,8 @@
fsd.setScale(scale);
icon = dr;
scale = getNormalizer().getScale(icon, outIconBounds, null, null);
+
+ ((ColorDrawable) dr.getBackground()).setColor(mWrapperBackgroundColor);
}
} else {
scale = getNormalizer().getScale(icon, outIconBounds, null, null);
diff --git a/src/com/android/launcher3/notification/NotificationListener.java b/src/com/android/launcher3/notification/NotificationListener.java
index cbdabf3..1fd7078 100644
--- a/src/com/android/launcher3/notification/NotificationListener.java
+++ b/src/com/android/launcher3/notification/NotificationListener.java
@@ -74,6 +74,9 @@
/** Maps keys to their corresponding current group key */
private final Map<String, String> mNotificationGroupKeyMap = new HashMap<>();
+ /** The last notification key that was dismissed from launcher UI */
+ private String mLastKeyDismissedByLauncher;
+
private SettingsObserver mNotificationBadgingObserver;
private final Handler.Callback mWorkerCallback = new Handler.Callback() {
@@ -251,13 +254,25 @@
}
NotificationGroup notificationGroup = mNotificationGroupMap.get(sbn.getGroupKey());
+ String key = sbn.getKey();
if (notificationGroup != null) {
- notificationGroup.removeChildKey(sbn.getKey());
+ notificationGroup.removeChildKey(key);
if (notificationGroup.isEmpty()) {
- cancelNotification(notificationGroup.getGroupSummaryKey());
+ if (key.equals(mLastKeyDismissedByLauncher)) {
+ // Only cancel the group notification if launcher dismissed the last child.
+ cancelNotification(notificationGroup.getGroupSummaryKey());
+ }
mNotificationGroupMap.remove(sbn.getGroupKey());
}
}
+ if (key.equals(mLastKeyDismissedByLauncher)) {
+ mLastKeyDismissedByLauncher = null;
+ }
+ }
+
+ public void cancelNotificationFromLauncher(String key) {
+ mLastKeyDismissedByLauncher = key;
+ cancelNotification(key);
}
@Override
diff --git a/src/com/android/launcher3/popup/PopupDataProvider.java b/src/com/android/launcher3/popup/PopupDataProvider.java
index 335426c..f1b8ec0 100644
--- a/src/com/android/launcher3/popup/PopupDataProvider.java
+++ b/src/com/android/launcher3/popup/PopupDataProvider.java
@@ -206,7 +206,7 @@
if (notificationListener == null) {
return;
}
- notificationListener.cancelNotification(notificationKey);
+ notificationListener.cancelNotificationFromLauncher(notificationKey);
}
public void setAllWidgets(ArrayList<WidgetListRowEntry> allWidgets) {