summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--proguard.flags5
-rw-r--r--protos/launcher_log.proto2
-rw-r--r--quickstep/res/layout/fallback_recents_activity.xml2
-rw-r--r--quickstep/res/layout/overview_panel.xml2
-rw-r--r--quickstep/res/values/config.xml2
-rw-r--r--quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java32
-rw-r--r--quickstep/src/com/android/launcher3/LauncherInitListener.java6
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/FastOverviewState.java8
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java13
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/UiFactory.java24
-rw-r--r--quickstep/src/com/android/quickstep/ActivityControlHelper.java20
-rw-r--r--quickstep/src/com/android/quickstep/AnimatedFloat.java4
-rw-r--r--quickstep/src/com/android/quickstep/DeferredTouchConsumer.java15
-rw-r--r--quickstep/src/com/android/quickstep/MotionEventQueue.java11
-rw-r--r--quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java96
-rw-r--r--quickstep/src/com/android/quickstep/QuickScrubController.java17
-rw-r--r--quickstep/src/com/android/quickstep/QuickstepProcessInitializer.java1
-rw-r--r--quickstep/src/com/android/quickstep/RecentsAnimationWrapper.java21
-rw-r--r--quickstep/src/com/android/quickstep/TaskSystemShortcut.java6
-rw-r--r--quickstep/src/com/android/quickstep/TouchConsumer.java2
-rw-r--r--quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java90
-rw-r--r--quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java19
-rw-r--r--quickstep/src/com/android/quickstep/logging/UserEventDispatcherExtension.java9
-rw-r--r--quickstep/src/com/android/quickstep/util/RemoteFadeOutAnimationListener.java53
-rw-r--r--quickstep/src/com/android/quickstep/views/ClearAllButton.java13
-rw-r--r--quickstep/src/com/android/quickstep/views/RecentsView.java57
-rw-r--r--quickstep/src/com/android/quickstep/views/RecentsViewContainer.java5
-rw-r--r--quickstep/src/com/android/quickstep/views/ShelfScrimView.java55
-rw-r--r--quickstep/src/com/android/quickstep/views/TaskThumbnailView.java35
-rw-r--r--quickstep/src/com/android/quickstep/views/TaskView.java6
-rw-r--r--res/layout/longpress_options_menu.xml1
-rw-r--r--res/values/attrs.xml1
-rw-r--r--res/values/styles.xml4
-rw-r--r--src/com/android/launcher3/LauncherStateManager.java15
-rw-r--r--src/com/android/launcher3/PagedView.java35
-rw-r--r--src/com/android/launcher3/Workspace.java25
-rw-r--r--src/com/android/launcher3/allapps/AllAppsContainerView.java7
-rw-r--r--src/com/android/launcher3/dragndrop/BaseItemDragListener.java2
-rw-r--r--src/com/android/launcher3/dragndrop/PinItemDragListener.java20
-rw-r--r--src/com/android/launcher3/graphics/LauncherIcons.java4
-rw-r--r--src/com/android/launcher3/keyboard/ViewGroupFocusHelper.java23
-rw-r--r--src/com/android/launcher3/popup/PopupContainerWithArrow.java1
-rw-r--r--src/com/android/launcher3/provider/ImportDataTask.java2
-rw-r--r--src/com/android/launcher3/qsb/QsbContainerView.java13
-rw-r--r--src/com/android/launcher3/util/Themes.java7
-rw-r--r--src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java4
46 files changed, 537 insertions, 258 deletions
diff --git a/proguard.flags b/proguard.flags
index 555d13e44..e4011165e 100644
--- a/proguard.flags
+++ b/proguard.flags
@@ -112,6 +112,11 @@
public <init>(...);
}
+# UserEventDispatcherExtension
+-keep class com.android.quickstep.logging.UserEventDispatcherExtension {
+ public <init>(...);
+}
+
-keep interface com.android.launcher3.userevent.nano.LauncherLogProto.** {
*;
}
diff --git a/protos/launcher_log.proto b/protos/launcher_log.proto
index cab20a3be..06e6a923d 100644
--- a/protos/launcher_log.proto
+++ b/protos/launcher_log.proto
@@ -110,6 +110,8 @@ enum ControlType {
QUICK_SCRUB_BUTTON = 12;
CLEAR_ALL_BUTTON = 13;
CANCEL_TARGET = 14;
+ TASK_PREVIEW = 15;
+ SPLIT_SCREEN_TARGET = 16;
}
enum TipType {
diff --git a/quickstep/res/layout/fallback_recents_activity.xml b/quickstep/res/layout/fallback_recents_activity.xml
index 7ecab3201..84e13add5 100644
--- a/quickstep/res/layout/fallback_recents_activity.xml
+++ b/quickstep/res/layout/fallback_recents_activity.xml
@@ -24,6 +24,7 @@
android:id="@+id/overview_panel_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:clipChildren="false"
>
<include layout="@layout/overview_clear_all_button"/>
@@ -33,6 +34,7 @@
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false"
+ android:outlineProvider="none"
android:focusableInTouchMode="true"
android:theme="@style/HomeScreenElementTheme"
>
diff --git a/quickstep/res/layout/overview_panel.xml b/quickstep/res/layout/overview_panel.xml
index 919afdb37..840b040ac 100644
--- a/quickstep/res/layout/overview_panel.xml
+++ b/quickstep/res/layout/overview_panel.xml
@@ -18,6 +18,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:clipChildren="false"
android:visibility="invisible"
>
<include layout="@layout/overview_clear_all_button"/>
@@ -28,6 +29,7 @@
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false"
+ android:outlineProvider="none"
android:focusableInTouchMode="true"
android:accessibilityPaneTitle="@string/accessibility_recent_apps"
android:theme="@style/HomeScreenElementTheme"
diff --git a/quickstep/res/values/config.xml b/quickstep/res/values/config.xml
index 7673f6994..c29437634 100644
--- a/quickstep/res/values/config.xml
+++ b/quickstep/res/values/config.xml
@@ -18,5 +18,5 @@
<string name="overview_callbacks_class" translatable="false"></string>
- <string name="user_event_dispatcher_class" translatable="false">com.google.quickstep.logging.UserEventDispatcherExtension</string>
+ <string name="user_event_dispatcher_class" translatable="false">com.android.quickstep.logging.UserEventDispatcherExtension</string>
</resources>
diff --git a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
index 6703bb546..2630edb3d 100644
--- a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
+++ b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
@@ -50,6 +50,7 @@ import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Build;
+import android.os.CancellationSignal;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
@@ -105,6 +106,7 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
private static final int APP_LAUNCH_ALPHA_DURATION = 50;
public static final int RECENTS_LAUNCH_DURATION = 336;
+ public static final int RECENTS_QUICKSCRUB_LAUNCH_DURATION = 300;
private static final int LAUNCHER_RESUME_START_DELAY = 100;
private static final int CLOSING_TRANSITION_DURATION_MS = 250;
@@ -236,8 +238,14 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
return bounds;
}
- public void setRemoteAnimationProvider(RemoteAnimationProvider animationProvider) {
+ public void setRemoteAnimationProvider(final RemoteAnimationProvider animationProvider,
+ CancellationSignal cancellationSignal) {
mRemoteAnimationProvider = animationProvider;
+ cancellationSignal.setOnCancelListener(() -> {
+ if (animationProvider == mRemoteAnimationProvider) {
+ mRemoteAnimationProvider = null;
+ }
+ });
}
/**
@@ -253,15 +261,21 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
RecentsView recentsView = mLauncher.getOverviewPanel();
boolean launcherClosing = launcherIsATargetWithMode(targets, MODE_CLOSING);
boolean skipLauncherChanges = !launcherClosing;
+ boolean isLaunchingFromQuickscrub =
+ recentsView.getQuickScrubController().isWaitingForTaskLaunch();
TaskView taskView = findTaskViewToLaunch(mLauncher, v, targets);
if (taskView == null) {
return false;
}
+ int duration = isLaunchingFromQuickscrub
+ ? RECENTS_QUICKSCRUB_LAUNCH_DURATION
+ : RECENTS_LAUNCH_DURATION;
+
ClipAnimationHelper helper = new ClipAnimationHelper();
target.play(getRecentsWindowAnimator(taskView, skipLauncherChanges, targets, helper)
- .setDuration(RECENTS_LAUNCH_DURATION));
+ .setDuration(duration));
Animator childStateAnimation = null;
// Found a visible recents task that matches the opening app, lets launch the app from there
@@ -270,7 +284,7 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
if (launcherClosing) {
launcherAnim = recentsView.createAdjacentPageAnimForTaskLaunch(taskView, helper);
launcherAnim.setInterpolator(Interpolators.TOUCH_RESPONSE_INTERPOLATOR);
- launcherAnim.setDuration(RECENTS_LAUNCH_DURATION);
+ launcherAnim.setDuration(duration);
// Make sure recents gets fixed up by resetting task alphas and scales, etc.
windowAnimEndListener = new AnimatorListenerAdapter() {
@@ -282,11 +296,10 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
};
} else {
AnimatorPlaybackController controller =
- mLauncher.getStateManager()
- .createAnimationToNewWorkspace(NORMAL, RECENTS_LAUNCH_DURATION);
+ mLauncher.getStateManager().createAnimationToNewWorkspace(NORMAL, duration);
controller.dispatchOnStart();
childStateAnimation = controller.getTarget();
- launcherAnim = controller.getAnimationPlayer().setDuration(RECENTS_LAUNCH_DURATION);
+ launcherAnim = controller.getAnimationPlayer().setDuration(duration);
windowAnimEndListener = new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
@@ -581,11 +594,8 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
float offsetX = (scaledWindowWidth - iconWidth) / 2;
float offsetY = (scaledWindowHeight - iconHeight) / 2;
- if (mLauncher.isInMultiWindowModeCompat()) {
- mFloatingView.getLocationOnScreen(floatingViewBounds);
- } else {
- mFloatingView.getLocationInWindow(floatingViewBounds);
- }
+ mFloatingView.getLocationOnScreen(floatingViewBounds);
+
float transX0 = floatingViewBounds[0] - offsetX;
float transY0 = floatingViewBounds[1] - offsetY;
matrix.postTranslate(transX0, transY0);
diff --git a/quickstep/src/com/android/launcher3/LauncherInitListener.java b/quickstep/src/com/android/launcher3/LauncherInitListener.java
index e5e377f83..08b6bfc6a 100644
--- a/quickstep/src/com/android/launcher3/LauncherInitListener.java
+++ b/quickstep/src/com/android/launcher3/LauncherInitListener.java
@@ -20,6 +20,7 @@ import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
+import android.os.CancellationSignal;
import android.os.Handler;
import com.android.launcher3.states.InternalStateHandler;
@@ -48,10 +49,11 @@ public class LauncherInitListener extends InternalStateHandler implements Activi
// Set a one-time animation provider. After the first call, this will get cleared.
// TODO: Probably also check the intended target id.
+ CancellationSignal cancellationSignal = new CancellationSignal();
appTransitionManager.setRemoteAnimationProvider((targets) -> {
// On the first call clear the reference.
- appTransitionManager.setRemoteAnimationProvider(null);
+ cancellationSignal.cancel();
RemoteAnimationProvider provider = mRemoteAnimationProvider;
mRemoteAnimationProvider = null;
@@ -59,7 +61,7 @@ public class LauncherInitListener extends InternalStateHandler implements Activi
return provider.createWindowAnimation(targets);
}
return null;
- });
+ }, cancellationSignal);
}
OverviewCallbacks.get(launcher).onInitOverviewTransition();
return mOnInitListener.test(launcher, alreadyOnHome);
diff --git a/quickstep/src/com/android/launcher3/uioverrides/FastOverviewState.java b/quickstep/src/com/android/launcher3/uioverrides/FastOverviewState.java
index 43d982230..26453022f 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/FastOverviewState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/FastOverviewState.java
@@ -34,7 +34,7 @@ public class FastOverviewState extends OverviewState {
/**
* Vertical transition of the task previews relative to the full container.
*/
- public static final float OVERVIEW_TRANSLATION_FACTOR = 0.5f;
+ public static final float OVERVIEW_TRANSLATION_FACTOR = 0.4f;
private static final int STATE_FLAGS = FLAG_DISABLE_RESTORE | FLAG_DISABLE_INTERACTION
| FLAG_OVERVIEW_UI | FLAG_HIDE_BACK_BUTTON | FLAG_DISABLE_ACCESSIBILITY;
@@ -76,4 +76,10 @@ public class FastOverviewState extends OverviewState {
return Math.min(Math.min(dp.availableHeightPx / usedHeight,
dp.availableWidthPx / usedWidth), MAX_PREVIEW_SCALE_UP);
}
+
+ @Override
+ public void onStateDisabled(Launcher launcher) {
+ super.onStateDisabled(launcher);
+ launcher.<RecentsView>getOverviewPanel().getQuickScrubController().cancelActiveQuickscrub();
+ }
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
index e3aabd6c8..ea27eb25b 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
@@ -76,15 +76,16 @@ public class RecentsViewStateController implements StateHandler {
}
PropertySetter setter = config.getPropertySetter(builder);
float[] scaleTranslationYFactor = toState.getOverviewScaleAndTranslationYFactor(mLauncher);
- Interpolator scaleInterpolator = builder.getInterpolator(ANIM_OVERVIEW_SCALE, LINEAR);
- setter.setFloat(mRecentsView, SCALE_PROPERTY, scaleTranslationYFactor[0], scaleInterpolator);
- Interpolator transYInterpolator = scaleInterpolator;
+ Interpolator scaleAndTransYInterpolator = builder.getInterpolator(
+ ANIM_OVERVIEW_SCALE, LINEAR);
if (mLauncher.getStateManager().getState() == OVERVIEW && toState == FAST_OVERVIEW) {
- transYInterpolator = Interpolators.clampToProgress(QUICK_SCRUB_START_INTERPOLATOR, 0,
- QUICK_SCRUB_TRANSLATION_Y_FACTOR);
+ scaleAndTransYInterpolator = Interpolators.clampToProgress(
+ QUICK_SCRUB_START_INTERPOLATOR, 0, QUICK_SCRUB_TRANSLATION_Y_FACTOR);
}
+ setter.setFloat(mRecentsView, SCALE_PROPERTY, scaleTranslationYFactor[0],
+ scaleAndTransYInterpolator);
setter.setFloat(mRecentsView, TRANSLATION_Y_FACTOR, scaleTranslationYFactor[1],
- transYInterpolator);
+ scaleAndTransYInterpolator);
setter.setFloat(mRecentsViewContainer, CONTENT_ALPHA, toState.overviewUi ? 1 : 0,
builder.getInterpolator(ANIM_OVERVIEW_FADE, AGGRESSIVE_EASE_IN_OUT));
diff --git a/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java b/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
index d0c7b2117..dd5dcbeaf 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
@@ -25,14 +25,19 @@ import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.allapps.DiscoveryBounce.HOME_BOUNCE_SEEN;
import static com.android.launcher3.allapps.DiscoveryBounce.SHELF_BOUNCE_SEEN;
+import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
+import android.animation.AnimatorSet;
+import android.animation.ValueAnimator;
import android.app.Activity;
import android.content.Context;
+import android.os.CancellationSignal;
import android.util.Base64;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherAppTransitionManagerImpl;
import com.android.launcher3.LauncherState;
import com.android.launcher3.LauncherStateManager;
import com.android.launcher3.LauncherStateManager.StateHandler;
@@ -41,6 +46,8 @@ import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.util.TouchController;
import com.android.quickstep.OverviewInteractionState;
import com.android.quickstep.RecentsModel;
+import com.android.quickstep.util.RemoteAnimationTargetSet;
+import com.android.quickstep.util.RemoteFadeOutAnimationListener;
import com.android.quickstep.views.RecentsView;
import com.android.systemui.shared.system.ActivityCompat;
import com.android.systemui.shared.system.WindowManagerWrapper;
@@ -179,6 +186,23 @@ public class UiFactory {
}
}
+ public static void useFadeOutAnimationForLauncherStart(Launcher launcher,
+ CancellationSignal cancellationSignal) {
+ LauncherAppTransitionManagerImpl appTransitionManager =
+ (LauncherAppTransitionManagerImpl) launcher.getAppTransitionManager();
+ appTransitionManager.setRemoteAnimationProvider((targets) -> {
+
+ // On the first call clear the reference.
+ cancellationSignal.cancel();
+
+ ValueAnimator fadeAnimation = ValueAnimator.ofFloat(1, 0);
+ fadeAnimation.addUpdateListener(new RemoteFadeOutAnimationListener(targets));
+ AnimatorSet anim = new AnimatorSet();
+ anim.play(fadeAnimation);
+ return anim;
+ }, cancellationSignal);
+ }
+
public static boolean dumpActivity(Activity activity, PrintWriter writer) {
if (!Utilities.IS_DEBUG_DEVICE) {
return false;
diff --git a/quickstep/src/com/android/quickstep/ActivityControlHelper.java b/quickstep/src/com/android/quickstep/ActivityControlHelper.java
index e202c574a..52a6dd5fe 100644
--- a/quickstep/src/com/android/quickstep/ActivityControlHelper.java
+++ b/quickstep/src/com/android/quickstep/ActivityControlHelper.java
@@ -46,6 +46,7 @@ import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherInitListener;
import com.android.launcher3.LauncherState;
+import com.android.launcher3.R;
import com.android.launcher3.allapps.AllAppsTransitionController;
import com.android.launcher3.allapps.DiscoveryBounce;
import com.android.launcher3.anim.AnimatorPlaybackController;
@@ -82,7 +83,8 @@ public interface ActivityControlHelper<T extends BaseDraggingActivity> {
void onQuickInteractionStart(T activity, @Nullable RunningTaskInfo taskInfo,
boolean activityVisible);
- float getTranslationYForQuickScrub(T activity);
+ float getTranslationYForQuickScrub(TransformedRect targetRect, DeviceProfile dp,
+ Context context);
void executeOnWindowAvailable(T activity, Runnable action);
@@ -151,10 +153,15 @@ public interface ActivityControlHelper<T extends BaseDraggingActivity> {
}
@Override
- public float getTranslationYForQuickScrub(Launcher activity) {
- LauncherRecentsView recentsView = activity.getOverviewPanel();
- return recentsView.computeTranslationYForFactor(
- FastOverviewState.OVERVIEW_TRANSLATION_FACTOR);
+ public float getTranslationYForQuickScrub(TransformedRect targetRect, DeviceProfile dp,
+ Context context) {
+ // The padding calculations are exactly same as that of RecentsView.setInsets
+ int topMargin = context.getResources()
+ .getDimensionPixelSize(R.dimen.task_thumbnail_top_margin);
+ int paddingTop = targetRect.rect.top - topMargin - dp.getInsets().top;
+ int paddingBottom = dp.availableHeightPx + dp.getInsets().top - targetRect.rect.bottom;
+
+ return FastOverviewState.OVERVIEW_TRANSLATION_FACTOR * (paddingBottom - paddingTop);
}
@Override
@@ -380,7 +387,8 @@ public interface ActivityControlHelper<T extends BaseDraggingActivity> {
}
@Override
- public float getTranslationYForQuickScrub(RecentsActivity activity) {
+ public float getTranslationYForQuickScrub(TransformedRect targetRect, DeviceProfile dp,
+ Context context) {
return 0;
}
diff --git a/quickstep/src/com/android/quickstep/AnimatedFloat.java b/quickstep/src/com/android/quickstep/AnimatedFloat.java
index 84dfa457e..84dfdbd1d 100644
--- a/quickstep/src/com/android/quickstep/AnimatedFloat.java
+++ b/quickstep/src/com/android/quickstep/AnimatedFloat.java
@@ -46,9 +46,9 @@ public class AnimatedFloat {
mUpdateCallback = updateCallback;
}
- public ObjectAnimator animateToValue(float v) {
+ public ObjectAnimator animateToValue(float start, float end) {
cancelAnimation();
- mValueAnimator = ObjectAnimator.ofFloat(this, VALUE, v);
+ mValueAnimator = ObjectAnimator.ofFloat(this, VALUE, start, end);
mValueAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animator) {
diff --git a/quickstep/src/com/android/quickstep/DeferredTouchConsumer.java b/quickstep/src/com/android/quickstep/DeferredTouchConsumer.java
index b92678a2e..8e83bd079 100644
--- a/quickstep/src/com/android/quickstep/DeferredTouchConsumer.java
+++ b/quickstep/src/com/android/quickstep/DeferredTouchConsumer.java
@@ -64,6 +64,16 @@ public class DeferredTouchConsumer implements TouchConsumer {
}
@Override
+ public void onQuickStep(MotionEvent ev) {
+ mTarget.onQuickStep(ev);
+ }
+
+ @Override
+ public void onCommand(int command) {
+ mTarget.onCommand(command);
+ }
+
+ @Override
public void preProcessMotionEvent(MotionEvent ev) {
mVelocityTracker.addMovement(ev);
}
@@ -92,6 +102,11 @@ public class DeferredTouchConsumer implements TouchConsumer {
return target == null ? true : target.deferNextEventToMainThread();
}
+ @Override
+ public void onShowOverviewFromAltTab() {
+ mTarget.onShowOverviewFromAltTab();
+ }
+
public interface DeferredTouchProvider {
TouchConsumer createTouchConsumer(VelocityTracker tracker);
diff --git a/quickstep/src/com/android/quickstep/MotionEventQueue.java b/quickstep/src/com/android/quickstep/MotionEventQueue.java
index 15f5aa524..f73be6cba 100644
--- a/quickstep/src/com/android/quickstep/MotionEventQueue.java
+++ b/quickstep/src/com/android/quickstep/MotionEventQueue.java
@@ -55,6 +55,8 @@ public class MotionEventQueue {
ACTION_VIRTUAL | (6 << ACTION_POINTER_INDEX_SHIFT);
private static final int ACTION_QUICK_STEP =
ACTION_VIRTUAL | (7 << ACTION_POINTER_INDEX_SHIFT);
+ private static final int ACTION_COMMAND =
+ ACTION_VIRTUAL | (8 << ACTION_POINTER_INDEX_SHIFT);
private final EventArray mEmptyArray = new EventArray();
private final Object mExecutionLock = new Object();
@@ -165,6 +167,9 @@ public class MotionEventQueue {
case ACTION_QUICK_STEP:
mConsumer.onQuickStep(event);
break;
+ case ACTION_COMMAND:
+ mConsumer.onCommand(event.getSource());
+ break;
default:
Log.e(TAG, "Invalid virtual event: " + event.getAction());
}
@@ -222,6 +227,12 @@ public class MotionEventQueue {
queueVirtualAction(ACTION_DEFER_INIT, 0);
}
+ public void onCommand(int command) {
+ MotionEvent ev = MotionEvent.obtain(0, 0, ACTION_COMMAND, 0, 0, 0);
+ ev.setSource(command);
+ queueNoPreProcess(ev);
+ }
+
public TouchConsumer getConsumer() {
return mConsumer;
}
diff --git a/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java b/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
index 9ba332831..c85628263 100644
--- a/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
+++ b/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
@@ -37,6 +37,7 @@ import android.os.Build;
import android.os.Bundle;
import android.os.Looper;
import android.os.SystemClock;
+import android.util.SparseArray;
import android.view.Choreographer;
import android.view.Display;
import android.view.MotionEvent;
@@ -69,6 +70,7 @@ public class OtherActivityTouchConsumer extends ContextWrapper implements TouchC
private static final long LAUNCHER_DRAW_TIMEOUT_MS = 150;
+ private final SparseArray<RecentsAnimationState> mAnimationStates = new SparseArray<>();
private final RunningTaskInfo mRunningTask;
private final RecentsModel mRecentsModel;
private final Intent mHomeIntent;
@@ -183,7 +185,7 @@ public class OtherActivityTouchConsumer extends ContextWrapper implements TouchC
case ACTION_UP: {
TraceHelper.endSection("TouchInt");
- finishTouchTracking();
+ finishTouchTracking(ev);
break;
}
}
@@ -212,8 +214,9 @@ public class OtherActivityTouchConsumer extends ContextWrapper implements TouchC
private void startTouchTrackingForWindowAnimation(long touchTimeMs) {
// Create the shared handler
+ RecentsAnimationState animationState = new RecentsAnimationState();
final WindowTransformSwipeHandler handler = new WindowTransformSwipeHandler(
- mRunningTask, this, touchTimeMs, mActivityControlHelper);
+ animationState.id, mRunningTask, this, touchTimeMs, mActivityControlHelper);
// Preload the plan
mRecentsModel.loadTasks(mRunningTask.id, null);
@@ -237,31 +240,7 @@ public class OtherActivityTouchConsumer extends ContextWrapper implements TouchC
public void onHandleAssistData(Bundle bundle) {
mRecentsModel.preloadAssistData(mRunningTask.id, bundle);
}
- },
- new RecentsAnimationListener() {
- public void onAnimationStart(
- RecentsAnimationControllerCompat controller,
- RemoteAnimationTargetCompat[] apps, Rect homeContentInsets,
- Rect minimizedHomeBounds) {
- if (mInteractionHandler == handler) {
- TraceHelper.partitionSection("RecentsController", "Received");
- handler.onRecentsAnimationStart(controller,
- new RemoteAnimationTargetSet(apps, MODE_CLOSING),
- homeContentInsets, minimizedHomeBounds);
- } else {
- TraceHelper.endSection("RecentsController", "Finishing no handler");
- controller.finish(false /* toHome */);
- }
- }
-
- public void onAnimationCanceled() {
- TraceHelper.endSection("RecentsController",
- "Cancelled: " + mInteractionHandler);
- if (mInteractionHandler == handler) {
- handler.onRecentsAnimationCanceled();
- }
- }
- }, null, null);
+ }, animationState, null, null);
if (Looper.myLooper() != Looper.getMainLooper()) {
startActivity.run();
@@ -277,12 +256,22 @@ public class OtherActivityTouchConsumer extends ContextWrapper implements TouchC
}
}
+ @Override
+ public void onCommand(int command) {
+ RecentsAnimationState state = mAnimationStates.get(command);
+ if (state != null) {
+ state.execute();
+ }
+ }
+
/**
* Called when the gesture has ended. Does not correlate to the completion of the interaction as
* the animation can still be running.
*/
- private void finishTouchTracking() {
+ private void finishTouchTracking(MotionEvent ev) {
if (mPassedInitialSlop && mInteractionHandler != null) {
+ mInteractionHandler.updateDisplacement(getDisplacement(ev) - mStartDisplacement);
+
mVelocityTracker.computeCurrentVelocity(1000,
ViewConfiguration.get(this).getScaledMaximumFlingVelocity());
@@ -398,4 +387,55 @@ public class OtherActivityTouchConsumer extends ContextWrapper implements TouchC
// TODO: Consider also check if the eventQueue is using mainThread of not.
return mInteractionHandler != null;
}
+
+ private class RecentsAnimationState implements RecentsAnimationListener {
+
+ private final int id;
+
+ private RecentsAnimationControllerCompat mController;
+ private RemoteAnimationTargetSet mTargets;
+ private Rect mHomeContentInsets;
+ private Rect mMinimizedHomeBounds;
+ private boolean mCancelled;
+
+ public RecentsAnimationState() {
+ id = mAnimationStates.size();
+ mAnimationStates.put(id, this);
+ }
+
+ @Override
+ public void onAnimationStart(
+ RecentsAnimationControllerCompat controller,
+ RemoteAnimationTargetCompat[] apps, Rect homeContentInsets,
+ Rect minimizedHomeBounds) {
+ mController = controller;
+ mTargets = new RemoteAnimationTargetSet(apps, MODE_CLOSING);
+ mHomeContentInsets = homeContentInsets;
+ mMinimizedHomeBounds = minimizedHomeBounds;
+ mEventQueue.onCommand(id);
+ }
+
+ @Override
+ public void onAnimationCanceled() {
+ mCancelled = true;
+ mEventQueue.onCommand(id);
+ }
+
+ public void execute() {
+ if (mInteractionHandler == null || mInteractionHandler.id != id) {
+ if (!mCancelled && mController != null) {
+ TraceHelper.endSection("RecentsController", "Finishing no handler");
+ mController.finish(false /* toHome */);
+ }
+ } else if (mCancelled) {
+ TraceHelper.endSection("RecentsController",
+ "Cancelled: " + mInteractionHandler);
+ mInteractionHandler.onRecentsAnimationCanceled();
+ } else {
+ TraceHelper.partitionSection("RecentsController", "Received");
+ mInteractionHandler.onRecentsAnimationStart(mController, mTargets,
+ mHomeContentInsets, mMinimizedHomeBounds);
+ }
+ }
+ }
}
diff --git a/quickstep/src/com/android/quickstep/QuickScrubController.java b/quickstep/src/com/android/quickstep/QuickScrubController.java
index 8e1a3d5d8..7a79c6f4d 100644
--- a/quickstep/src/com/android/quickstep/QuickScrubController.java
+++ b/quickstep/src/com/android/quickstep/QuickScrubController.java
@@ -40,7 +40,7 @@ import com.android.quickstep.views.TaskView;
public class QuickScrubController implements OnAlarmListener {
public static final int QUICK_SCRUB_FROM_APP_START_DURATION = 240;
- public static final int QUICK_SCRUB_FROM_HOME_START_DURATION = 150;
+ public static final int QUICK_SCRUB_FROM_HOME_START_DURATION = 200;
// We want the translation y to finish faster than the rest of the animation.
public static final float QUICK_SCRUB_TRANSLATION_Y_FACTOR = 5f / 6;
public static final Interpolator QUICK_SCRUB_START_INTERPOLATOR = FAST_OUT_SLOW_IN;
@@ -132,6 +132,17 @@ public class QuickScrubController implements OnAlarmListener {
}
}
+ public void cancelActiveQuickscrub() {
+ if (!mInQuickScrub) {
+ return;
+ }
+ Log.d(TAG, "Quickscrub was active, cancelling");
+ mInQuickScrub = false;
+ mActivityControlHelper = null;
+ mOnFinishedTransitionToQuickScrubRunnable = null;
+ mRecentsView.setNextPageSwitchRunnable(null);
+ }
+
/**
* Initializes the UI for quick scrub, returns true if success.
*/
@@ -145,6 +156,10 @@ public class QuickScrubController implements OnAlarmListener {
return true;
}
+ public boolean isWaitingForTaskLaunch() {
+ return mWaitingForTaskLaunch;
+ }
+
/**
* Attempts to go to normal overview or back to home, so UI doesn't prevent user interaction.
*/
diff --git a/quickstep/src/com/android/quickstep/QuickstepProcessInitializer.java b/quickstep/src/com/android/quickstep/QuickstepProcessInitializer.java
index aed995957..2c3f77f21 100644
--- a/quickstep/src/com/android/quickstep/QuickstepProcessInitializer.java
+++ b/quickstep/src/com/android/quickstep/QuickstepProcessInitializer.java
@@ -20,6 +20,7 @@ import android.content.Context;
import com.android.launcher3.MainProcessInitializer;
import com.android.systemui.shared.system.ThreadedRendererCompat;
+@SuppressWarnings("unused")
public class QuickstepProcessInitializer extends MainProcessInitializer {
public QuickstepProcessInitializer(Context context) { }
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationWrapper.java b/quickstep/src/com/android/quickstep/RecentsAnimationWrapper.java
index 30b10b0ea..34d42ac92 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationWrapper.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationWrapper.java
@@ -20,6 +20,8 @@ import com.android.launcher3.util.TraceHelper;
import com.android.launcher3.util.UiThreadHelper;
import com.android.quickstep.util.RemoteAnimationTargetSet;
import com.android.systemui.shared.system.RecentsAnimationControllerCompat;
+
+import java.util.ArrayList;
import java.util.concurrent.ExecutorService;
/**
@@ -27,6 +29,10 @@ import java.util.concurrent.ExecutorService;
*/
public class RecentsAnimationWrapper {
+ // A list of callbacks to run when we receive the recents animation target. There are different
+ // than the state callbacks as these run on the current worker thread.
+ private final ArrayList<Runnable> mCallbacks = new ArrayList<>();
+
public RemoteAnimationTargetSet targetSet;
private RecentsAnimationControllerCompat mController;
@@ -46,6 +52,21 @@ public class RecentsAnimationWrapper {
if (mInputConsumerEnabled) {
enableInputConsumer();
}
+
+ if (!mCallbacks.isEmpty()) {
+ for (Runnable action : new ArrayList<>(mCallbacks)) {
+ action.run();
+ }
+ mCallbacks.clear();
+ }
+ }
+
+ public synchronized void runOnInit(Runnable action) {
+ if (targetSet == null) {
+ mCallbacks.add(action);
+ } else {
+ action.run();
+ }
}
/**
diff --git a/quickstep/src/com/android/quickstep/TaskSystemShortcut.java b/quickstep/src/com/android/quickstep/TaskSystemShortcut.java
index 228af8e90..f82ff8c53 100644
--- a/quickstep/src/com/android/quickstep/TaskSystemShortcut.java
+++ b/quickstep/src/com/android/quickstep/TaskSystemShortcut.java
@@ -16,6 +16,8 @@
package com.android.quickstep;
+import static com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch.TAP;
+
import android.content.ComponentName;
import android.content.Intent;
import android.graphics.Bitmap;
@@ -35,6 +37,7 @@ import com.android.launcher3.ItemInfo;
import com.android.launcher3.R;
import com.android.launcher3.ShortcutInfo;
import com.android.launcher3.popup.SystemShortcut;
+import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.util.InstantAppResolver;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskThumbnailView;
@@ -166,7 +169,8 @@ public class TaskSystemShortcut<T extends SystemShortcut> extends SystemShortcut
Log.w(TAG, "Failed to notify SysUI of split screen: ", e);
return;
}
-
+ activity.getUserEventDispatcher().logActionOnControl(TAP,
+ LauncherLogProto.ControlType.SPLIT_SCREEN_TARGET);
// Add a device profile change listener to kick off animating the side tasks
// once we enter multiwindow mode and relayout
activity.addOnDeviceProfileChangeListener(onDeviceProfileChangeListener);
diff --git a/quickstep/src/com/android/quickstep/TouchConsumer.java b/quickstep/src/com/android/quickstep/TouchConsumer.java
index aa844d80d..4cecffa2b 100644
--- a/quickstep/src/com/android/quickstep/TouchConsumer.java
+++ b/quickstep/src/com/android/quickstep/TouchConsumer.java
@@ -48,6 +48,8 @@ public interface TouchConsumer extends Consumer<MotionEvent> {
default void onQuickStep(MotionEvent ev) { }
+ default void onCommand(int command) { }
+
/**
* Called on the binder thread to allow the consumer to process the motion event before it is
* posted on a handler thread.
diff --git a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
index 191c237f6..b1663b169 100644
--- a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
+++ b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
@@ -16,6 +16,7 @@
package com.android.quickstep;
import static com.android.launcher3.BaseActivity.INVISIBLE_BY_STATE_HANDLER;
+import static com.android.launcher3.Utilities.SINGLE_FRAME_MS;
import static com.android.launcher3.Utilities.postAsyncCallback;
import static com.android.launcher3.anim.Interpolators.DEACCEL;
import static com.android.launcher3.anim.Interpolators.LINEAR;
@@ -29,6 +30,7 @@ import android.animation.ObjectAnimator;
import android.annotation.TargetApi;
import android.app.ActivityManager.RunningTaskInfo;
import android.content.Context;
+import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Point;
import android.graphics.Rect;
@@ -36,6 +38,7 @@ import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.os.SystemClock;
+import android.os.UserHandle;
import android.support.annotation.AnyThread;
import android.support.annotation.UiThread;
import android.support.annotation.WorkerThread;
@@ -51,6 +54,7 @@ import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.logging.UserEventDispatcher;
@@ -65,11 +69,12 @@ import com.android.quickstep.ActivityControlHelper.AnimationFactory;
import com.android.quickstep.ActivityControlHelper.LayoutListener;
import com.android.quickstep.TouchConsumer.InteractionType;
import com.android.quickstep.util.ClipAnimationHelper;
-import com.android.quickstep.util.TransformedRect;
import com.android.quickstep.util.RemoteAnimationTargetSet;
+import com.android.quickstep.util.TransformedRect;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.recents.model.ThumbnailData;
+import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.InputConsumerController;
import com.android.systemui.shared.system.LatencyTrackerCompat;
import com.android.systemui.shared.system.RecentsAnimationControllerCompat;
@@ -167,6 +172,12 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> {
private final Handler mMainThreadHandler = new Handler(Looper.getMainLooper());
+ // An increasing identifier per single instance of OtherActivityTouchConsumer. Generally one
+ // instance of OtherActivityTouchConsumer will only have one swipe handle, but sometimes we can
+ // end up with multiple handlers if we get recents command in the middle of a swipe gesture.
+ // This is used to match the corresponding activity manager callbacks in
+ // OtherActivityTouchConsumer
+ public final int id;
private final Context mContext;
private final ActivityControlHelper<T> mActivityControlHelper;
private final ActivityInitListener mActivityInitListener;
@@ -199,6 +210,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> {
InputConsumerController.getRecentsAnimationInputConsumer();
private final RecentsAnimationWrapper mRecentsAnimationWrapper = new RecentsAnimationWrapper();
+
private final long mTouchTimeMs;
private long mLauncherFrameDrawnTime;
@@ -207,8 +219,9 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> {
private float mLongSwipeDisplacement = 0;
private LongSwipeHelper mLongSwipeController;
- WindowTransformSwipeHandler(RunningTaskInfo runningTaskInfo, Context context, long touchTimeMs,
- ActivityControlHelper<T> controller) {
+ WindowTransformSwipeHandler(int id, RunningTaskInfo runningTaskInfo, Context context,
+ long touchTimeMs, ActivityControlHelper<T> controller) {
+ this.id = id;
mContext = context;
mRunningTaskInfo = runningTaskInfo;
mRunningTaskId = runningTaskInfo.id;
@@ -453,11 +466,40 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> {
"Can't change interaction type to " + interactionType);
}
mInteractionType = interactionType;
+ mRecentsAnimationWrapper.runOnInit(this::shiftAnimationDestinationForQuickscrub);
setStateOnUiThread(STATE_QUICK_SCRUB_START | STATE_GESTURE_COMPLETED);
// Start the window animation without waiting for launcher.
- animateToProgress(1f, QUICK_SCRUB_FROM_APP_START_DURATION, LINEAR);
+ animateToProgress(mCurrentShift.value, 1f, QUICK_SCRUB_FROM_APP_START_DURATION, LINEAR);
+ }
+
+ private void shiftAnimationDestinationForQuickscrub() {
+ TransformedRect tempRect = new TransformedRect();
+ mActivityControlHelper
+ .getSwipeUpDestinationAndLength(mDp, mContext, mInteractionType, tempRect);
+ mClipAnimationHelper.updateTargetRect(tempRect);
+
+ float offsetY =
+ mActivityControlHelper.getTranslationYForQuickScrub(tempRect, mDp, mContext);
+ float scale, offsetX;
+ Resources res = mContext.getResources();
+
+ if (ActivityManagerWrapper.getInstance().getRecentTasks(2, UserHandle.myUserId()).size()
+ < 2) {
+ // There are not enough tasks, we don't need to shift
+ offsetX = 0;
+ scale = 1;
+ } else {
+ offsetX = res.getDimensionPixelSize(R.dimen.recents_page_spacing)
+ + tempRect.rect.width();
+ float distanceToReachEdge = mDp.widthPx / 2 + tempRect.rect.width() / 2 +
+ res.getDimensionPixelSize(R.dimen.recents_page_spacing);
+ float interpolation = Math.min(1, offsetX / distanceToReachEdge);
+ scale = TaskView.getCurveScaleForInterpolation(interpolation);
+ }
+ mClipAnimationHelper.offsetTarget(scale, Utilities.isRtl(res) ? -offsetX : offsetX, offsetY,
+ QuickScrubController.QUICK_SCRUB_START_INTERPOLATOR);
}
@WorkerThread
@@ -606,11 +648,13 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> {
private void handleNormalGestureEnd(float endVelocity, boolean isFling) {
long duration = MAX_SWIPE_DURATION;
final float endShift;
+ final float startShift;
if (!isFling) {
endShift = mCurrentShift.value >= MIN_PROGRESS_FOR_OVERVIEW && mGestureStarted ? 1 : 0;
long expectedDuration = Math.abs(Math.round((endShift - mCurrentShift.value)
* MAX_SWIPE_DURATION * SWIPE_DURATION_MULTIPLIER));
duration = Math.min(MAX_SWIPE_DURATION, expectedDuration);
+ startShift = mCurrentShift.value;
} else {
endShift = endVelocity < 0 ? 1 : 0;
float minFlingVelocity = mContext.getResources()
@@ -624,9 +668,11 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> {
long baseDuration = Math.round(1000 * Math.abs(distanceToTravel / endVelocity));
duration = Math.min(MAX_SWIPE_DURATION, 2 * baseDuration);
}
+ startShift = Utilities.boundToRange(mCurrentShift.value - endVelocity * SINGLE_FRAME_MS
+ / (mTransitionDragLength * 1000), 0, 1);
}
- animateToProgress(endShift, duration, DEACCEL);
+ animateToProgress(startShift, endShift, duration, DEACCEL);
}
private void doLogGesture(boolean toLauncher) {
@@ -646,9 +692,10 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> {
}
/** Animates to the given progress, where 0 is the current app and 1 is overview. */
- private void animateToProgress(float progress, long duration, Interpolator interpolator) {
- mIsGoingToHome = Float.compare(progress, 1) == 0;
- ObjectAnimator anim = mCurrentShift.animateToValue(progress).setDuration(duration);
+ private void animateToProgress(float start, float end, long duration,
+ Interpolator interpolator) {
+ mIsGoingToHome = Float.compare(end, 1) == 0;
+ ObjectAnimator anim = mCurrentShift.animateToValue(start, end).setDuration(duration);
anim.setInterpolator(interpolator);
anim.addListener(new AnimationSuccessListener() {
@Override
@@ -658,7 +705,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> {
: STATE_SCALED_CONTROLLER_APP);
}
});
- anim.start();
+ mRecentsAnimationWrapper.runOnInit(anim::start);
}
@UiThread
@@ -700,6 +747,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> {
mRecentsView.setRunningTaskHidden(false);
mRecentsView.setRunningTaskIconScaledDown(false /* isScaledDown */, false /* animate */);
+ mQuickScrubController.cancelActiveQuickscrub();
}
private void notifyTransitionCancelled() {
@@ -785,30 +833,6 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> {
// Inform the last progress in case we skipped before.
mQuickScrubController.onQuickScrubProgress(mCurrentQuickScrubProgress);
-
- // Make sure the window follows the first task if it moves, e.g. during quick scrub.
- TaskView firstTask = mRecentsView.getPageAt(0);
- // The first task may be null if we are swiping up from a task that does not
- // appear in the list (i.e. the assistant)
- if (firstTask != null) {
- int scrollForFirstTask = mRecentsView.getScrollForPage(0);
- int scrollForSecondTask = mRecentsView.getChildCount() > 1
- ? mRecentsView.getScrollForPage(1) : scrollForFirstTask;
- float offsetFromFirstTask = scrollForFirstTask - scrollForSecondTask;
-
- TransformedRect tempRect = new TransformedRect();
- mActivityControlHelper
- .getSwipeUpDestinationAndLength(mDp, mContext, mInteractionType, tempRect);
- float distanceToReachEdge = mDp.widthPx / 2 + tempRect.rect.width() / 2 +
- mContext.getResources().getDimensionPixelSize(R.dimen.recents_page_spacing);
- float interpolation = Math.min(1,
- Math.abs(offsetFromFirstTask) / distanceToReachEdge);
-
- mClipAnimationHelper.offsetTarget(
- firstTask.getCurveScaleForInterpolation(interpolation), offsetFromFirstTask,
- mActivityControlHelper.getTranslationYForQuickScrub(mActivity),
- QuickScrubController.QUICK_SCRUB_START_INTERPOLATOR);
- }
}
private void onFinishedTransitionToQuickScrub() {
diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
index c5d74c7d9..9e2de3395 100644
--- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
+++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
@@ -20,10 +20,8 @@ import android.graphics.Canvas;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;
-import android.view.accessibility.AccessibilityNodeInfo;
import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.R;
import com.android.quickstep.RecentsActivity;
import com.android.quickstep.util.LayoutUtils;
import com.android.quickstep.views.RecentsView;
@@ -73,21 +71,4 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity> {
// Just use the activity task size for multi-window as well.
return false;
}
-
- @Override
- public void addTaskAccessibilityActionsExtra(AccessibilityNodeInfo info) {
- info.addAction(
- new AccessibilityNodeInfo.AccessibilityAction(
- R.string.recents_clear_all,
- getContext().getText(R.string.recents_clear_all)));
- }
-
- @Override
- public boolean performTaskAccessibilityActionExtra(int action) {
- if (action == R.string.recents_clear_all) {
- dismissAllTasks();
- return true;
- }
- return false;
- }
}
diff --git a/quickstep/src/com/android/quickstep/logging/UserEventDispatcherExtension.java b/quickstep/src/com/android/quickstep/logging/UserEventDispatcherExtension.java
index 04153cc99..6dff187ea 100644
--- a/quickstep/src/com/android/quickstep/logging/UserEventDispatcherExtension.java
+++ b/quickstep/src/com/android/quickstep/logging/UserEventDispatcherExtension.java
@@ -15,10 +15,9 @@
*/
package com.android.quickstep.logging;
+import android.content.Context;
import android.util.Log;
-import static com.android.launcher3.logging.LoggerUtils.newAction;
-import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
import static com.android.launcher3.logging.LoggerUtils.newLauncherEvent;
import static com.android.launcher3.userevent.nano.LauncherLogProto.ControlType.CANCEL_TARGET;
import static com.android.systemui.shared.system.LauncherEventUtil.VISIBLE;
@@ -27,20 +26,20 @@ import static com.android.systemui.shared.system.LauncherEventUtil.RECENTS_QUICK
import static com.android.systemui.shared.system.LauncherEventUtil.RECENTS_SWIPE_UP_ONBOARDING_TIP;
import com.android.launcher3.logging.UserEventDispatcher;
-import com.android.launcher3.model.nano.LauncherDumpProto;
-import com.android.launcher3.userevent.nano.LauncherLogExtensions;
import com.android.launcher3.userevent.nano.LauncherLogProto;
-import com.android.systemui.shared.system.LauncherEventUtil;
import com.android.systemui.shared.system.MetricsLoggerCompat;
/**
* This class handles AOSP MetricsLogger function calls and logging around
* quickstep interactions.
*/
+@SuppressWarnings("unused")
public class UserEventDispatcherExtension extends UserEventDispatcher {
private static final String TAG = "UserEventDispatcher";
+ public UserEventDispatcherExtension(Context context) { }
+
public void logStateChangeAction(int action, int dir, int srcChildTargetType,
int srcParentContainerType, int dstContainerType,
int pageIndex) {
diff --git a/quickstep/src/com/android/quickstep/util/RemoteFadeOutAnimationListener.java b/quickstep/src/com/android/quickstep/util/RemoteFadeOutAnimationListener.java
new file mode 100644
index 000000000..40dd74bbb
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/util/RemoteFadeOutAnimationListener.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2018 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.quickstep.util;
+
+import static com.android.quickstep.util.RemoteAnimationProvider.prepareTargetsForFirstFrame;
+import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
+
+import android.animation.ValueAnimator;
+import android.animation.ValueAnimator.AnimatorUpdateListener;
+
+import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
+import com.android.systemui.shared.system.TransactionCompat;
+
+/**
+ * Animation listener which fades out the closing targets
+ */
+public class RemoteFadeOutAnimationListener implements AnimatorUpdateListener {
+
+ private final RemoteAnimationTargetSet mTarget;
+ private boolean mFirstFrame = true;
+
+ public RemoteFadeOutAnimationListener(RemoteAnimationTargetCompat[] targets) {
+ mTarget = new RemoteAnimationTargetSet(targets, MODE_CLOSING);
+ }
+
+ @Override
+ public void onAnimationUpdate(ValueAnimator valueAnimator) {
+ TransactionCompat t = new TransactionCompat();
+ if (mFirstFrame) {
+ prepareTargetsForFirstFrame(mTarget.unfilteredApps, t, MODE_CLOSING);
+ mFirstFrame = false;
+ }
+
+ float alpha = 1 - valueAnimator.getAnimatedFraction();
+ for (RemoteAnimationTargetCompat app : mTarget.apps) {
+ t.setAlpha(app.leash, alpha);
+ }
+ t.apply();
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/views/ClearAllButton.java b/quickstep/src/com/android/quickstep/views/ClearAllButton.java
index 25e3dc6c1..0025df136 100644
--- a/quickstep/src/com/android/quickstep/views/ClearAllButton.java
+++ b/quickstep/src/com/android/quickstep/views/ClearAllButton.java
@@ -16,13 +16,11 @@
package com.android.quickstep.views;
-import static android.view.accessibility.AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS;
-
import android.content.Context;
import android.graphics.Rect;
-import android.os.Bundle;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
+import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.Button;
public class ClearAllButton extends Button {
@@ -37,12 +35,9 @@ public class ClearAllButton extends Button {
}
@Override
- public boolean performAccessibilityAction(int action, Bundle arguments) {
- final boolean res = super.performAccessibilityAction(action, arguments);
- if (action == ACTION_ACCESSIBILITY_FOCUS) {
- mRecentsView.revealClearAllButton();
- }
- return res;
+ public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+ super.onInitializeAccessibilityNodeInfo(info);
+ info.setParent(mRecentsView); // Pretend we are a part of the task carousel.
}
@Override
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index dee15d0d7..d550edcd3 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -39,6 +39,7 @@ import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Build;
+import android.os.Bundle;
import android.os.Handler;
import android.os.UserHandle;
import android.support.annotation.Nullable;
@@ -386,7 +387,13 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
private void updateClearAllButtonAlpha() {
if (mClearAllButton != null) {
final float alpha = calculateClearAllButtonAlpha();
- mIsClearAllButtonFullyRevealed = alpha == 1;
+ final boolean revealed = alpha == 1;
+ if (mIsClearAllButtonFullyRevealed != revealed) {
+ mIsClearAllButtonFullyRevealed = revealed;
+ mClearAllButton.setImportantForAccessibility(revealed ?
+ IMPORTANT_FOR_ACCESSIBILITY_YES :
+ IMPORTANT_FOR_ACCESSIBILITY_NO);
+ }
mClearAllButton.setAlpha(alpha * mContentAlpha);
}
}
@@ -507,6 +514,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
DeviceProfile dp = mActivity.getDeviceProfile();
getTaskSize(dp, mTempRect);
+ // Keep this logic in sync with ActivityControlHelper.getTranslationYForQuickScrub.
mTempRect.top -= mTaskTopMargin;
setPadding(mTempRect.left - mInsets.left, mTempRect.top - mInsets.top,
dp.availableWidthPx + mInsets.left - mTempRect.right,
@@ -1285,7 +1293,30 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
}
@Override
+ public boolean performAccessibilityAction(int action, Bundle arguments) {
+ if (getChildCount() > 0) {
+ switch (action) {
+ case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: {
+ if (!mIsClearAllButtonFullyRevealed && getCurrentPage() == getPageCount() - 1) {
+ revealClearAllButton();
+ return true;
+ }
+ }
+ case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: {
+ if (mIsClearAllButtonFullyRevealed) {
+ setCurrentPage(getChildCount() - 1);
+ return true;
+ }
+ }
+ break;
+ }
+ }
+ return super.performAccessibilityAction(action, arguments);
+ }
+
+ @Override
public void addChildrenForAccessibility(ArrayList<View> outChildren) {
+ outChildren.add(mClearAllButton);
for (int i = getChildCount() - 1; i >= 0; --i) {
outChildren.add(getChildAt(i));
}
@@ -1295,6 +1326,13 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(info);
+ if (getChildCount() > 0) {
+ info.addAction(mIsClearAllButtonFullyRevealed ?
+ AccessibilityNodeInfo.ACTION_SCROLL_FORWARD :
+ AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
+ info.setScrollable(true);
+ }
+
final AccessibilityNodeInfo.CollectionInfo
collectionInfo = AccessibilityNodeInfo.CollectionInfo.obtain(
1, getChildCount(), false,
@@ -1306,11 +1344,15 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
super.onInitializeAccessibilityEvent(event);
- if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_SCROLLED) {
- final int visiblePageNumber = getChildCount() - getCurrentPage() - 1;
- event.setFromIndex(visiblePageNumber);
- event.setToIndex(visiblePageNumber);
- event.setItemCount(getChildCount());
+ event.setScrollable(getPageCount() > 0);
+
+ if (!mIsClearAllButtonFullyRevealed
+ && event.getEventType() == AccessibilityEvent.TYPE_VIEW_SCROLLED) {
+ final int childCount = getChildCount();
+ final int[] visibleTasks = getVisibleChildrenRange();
+ event.setFromIndex(childCount - visibleTasks[1] - 1);
+ event.setToIndex(childCount - visibleTasks[0] - 1);
+ event.setItemCount(childCount);
}
}
@@ -1325,9 +1367,6 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
return true;
}
- public void addTaskAccessibilityActionsExtra(AccessibilityNodeInfo info) {
- }
-
public boolean performTaskAccessibilityActionExtra(int action) {
return false;
}
diff --git a/quickstep/src/com/android/quickstep/views/RecentsViewContainer.java b/quickstep/src/com/android/quickstep/views/RecentsViewContainer.java
index 31c8b6448..c6cd52769 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsViewContainer.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsViewContainer.java
@@ -124,4 +124,9 @@ public class RecentsViewContainer extends InsettableFrameLayout {
return mRecentsView.requestFocus(direction, previouslyFocusedRect) ||
super.requestFocus(direction, previouslyFocusedRect);
}
+
+ @Override
+ public void addChildrenForAccessibility(ArrayList<View> outChildren) {
+ outChildren.add(mRecentsView);
+ }
} \ No newline at end of file
diff --git a/quickstep/src/com/android/quickstep/views/ShelfScrimView.java b/quickstep/src/com/android/quickstep/views/ShelfScrimView.java
index aca8351a0..c780b6234 100644
--- a/quickstep/src/com/android/quickstep/views/ShelfScrimView.java
+++ b/quickstep/src/com/android/quickstep/views/ShelfScrimView.java
@@ -28,9 +28,6 @@ import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Path.Direction;
import android.graphics.Path.Op;
-import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
import android.util.AttributeSet;
import com.android.launcher3.DeviceProfile;
@@ -48,11 +45,6 @@ import com.android.launcher3.views.ScrimView;
*/
public class ShelfScrimView extends ScrimView {
- private static final int THRESHOLD_ALPHA_DARK = 102;
- private static final int THRESHOLD_ALPHA_LIGHT = 46;
- private static final int THRESHOLD_ALPHA_SUPER_LIGHT = 128;
- private static final int CLEAR_ALL_TASKS = R.string.recents_clear_all;
-
// In transposed layout, we simply draw a flat color.
private boolean mDrawingFlatColor;
@@ -81,13 +73,7 @@ public class ShelfScrimView extends ScrimView {
mMaxScrimAlpha = OVERVIEW.getWorkspaceScrimAlpha(mLauncher);
mEndAlpha = Color.alpha(mEndScrim);
- if (Themes.getAttrBoolean(mLauncher, R.attr.isMainColorDark)) {
- mThresholdAlpha = THRESHOLD_ALPHA_DARK;
- } else if (Themes.getAttrBoolean(mLauncher, R.attr.isWorkspaceDarkText)) {
- mThresholdAlpha = THRESHOLD_ALPHA_SUPER_LIGHT;
- } else {
- mThresholdAlpha = THRESHOLD_ALPHA_LIGHT;
- }
+ mThresholdAlpha = Themes.getAttrInteger(context, R.attr.allAppsInterimScrimAlpha);
mRadius = mLauncher.getResources().getDimension(R.dimen.shelf_surface_radius);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
@@ -208,43 +194,4 @@ public class ShelfScrimView extends ScrimView {
mRadius, mRadius, mPaint);
return minTop - mDragHandleSize - top;
}
-
- @NonNull
- @Override
- protected AccessibilityHelper createAccessibilityHelper() {
- return new ShelfScrimAccessibilityHelper();
- }
-
- protected class ShelfScrimAccessibilityHelper extends AccessibilityHelper {
- @Override
- protected void onPopulateNodeForVirtualView(int virtualViewId,
- AccessibilityNodeInfoCompat node) {
- super.onPopulateNodeForVirtualView(virtualViewId, node);
-
- if (mLauncher.isInState(OVERVIEW)) {
- final RecentsView overviewPanel = mLauncher.getOverviewPanel();
- if (overviewPanel.getChildCount() != 0) {
- node.addAction(
- new AccessibilityNodeInfoCompat.AccessibilityActionCompat(
- CLEAR_ALL_TASKS,
- getContext().getText(CLEAR_ALL_TASKS)));
- }
- }
- }
-
- @Override
- protected boolean onPerformActionForVirtualView(
- int virtualViewId, int action, Bundle arguments) {
- if (super.onPerformActionForVirtualView(virtualViewId, action, arguments)) return true;
-
- if (action == CLEAR_ALL_TASKS) {
- if (mLauncher.isInState(OVERVIEW)) {
- mLauncher.<RecentsView>getOverviewPanel().dismissAllTasks();
- }
- return true;
- }
-
- return false;
- }
- }
}
diff --git a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
index 128a19e06..d9dfd1815 100644
--- a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
@@ -29,6 +29,7 @@ import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Shader;
+import android.support.v4.graphics.ColorUtils;
import android.util.AttributeSet;
import android.util.FloatProperty;
import android.util.Property;
@@ -37,8 +38,10 @@ import android.view.View;
import com.android.launcher3.BaseActivity;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.util.SystemUiController;
+import com.android.launcher3.util.Themes;
import com.android.quickstep.TaskOverlayFactory;
import com.android.quickstep.TaskOverlayFactory.TaskOverlay;
import com.android.systemui.shared.recents.model.Task;
@@ -50,6 +53,7 @@ import com.android.systemui.shared.recents.model.ThumbnailData;
public class TaskThumbnailView extends View {
private static final LightingColorFilter[] sDimFilterCache = new LightingColorFilter[256];
+ private static final LightingColorFilter[] sHighlightFilterCache = new LightingColorFilter[256];
public static final Property<TaskThumbnailView, Float> DIM_ALPHA_MULTIPLIER =
new FloatProperty<TaskThumbnailView>("dimAlphaMultiplier") {
@@ -68,6 +72,7 @@ public class TaskThumbnailView extends View {
private final BaseActivity mActivity;
private final TaskOverlay mOverlay;
+ private final boolean mIsDarkTextTheme;
private final Paint mPaint = new Paint();
private final Paint mBackgroundPaint = new Paint();
@@ -97,6 +102,7 @@ public class TaskThumbnailView extends View {
mPaint.setFilterBitmap(true);
mBackgroundPaint.setColor(Color.WHITE);
mActivity = BaseActivity.fromContext(context);
+ mIsDarkTextTheme = Themes.getAttrBoolean(mActivity, R.attr.isWorkspaceDarkText);
}
public void bind() {
@@ -198,7 +204,7 @@ public class TaskThumbnailView extends View {
private void updateThumbnailPaintFilter() {
int mul = (int) ((1 - mDimAlpha * mDimAlphaMultiplier) * 255);
if (mBitmapShader != null) {
- LightingColorFilter filter = getLightingColorFilter(mul);
+ LightingColorFilter filter = getDimmingColorFilter(mul, mIsDarkTextTheme);
mPaint.setColorFilter(filter);
mBackgroundPaint.setColorFilter(filter);
} else {
@@ -287,16 +293,25 @@ public class TaskThumbnailView extends View {
updateThumbnailMatrix();
}
- private static LightingColorFilter getLightingColorFilter(int dimColor) {
- if (dimColor < 0) {
- dimColor = 0;
- } else if (dimColor > 255) {
- dimColor = 255;
+ private static LightingColorFilter getDimmingColorFilter(int intensity, boolean shouldLighten) {
+ intensity = Utilities.boundToRange(intensity, 0, 255);
+ if (intensity == 255) {
+ return null;
}
- if (sDimFilterCache[dimColor] == null) {
- sDimFilterCache[dimColor] =
- new LightingColorFilter(Color.argb(255, dimColor, dimColor, dimColor), 0);
+ if (shouldLighten) {
+ if (sHighlightFilterCache[intensity] == null) {
+ int colorAdd = 255 - intensity;
+ sHighlightFilterCache[intensity] = new LightingColorFilter(
+ Color.argb(255, intensity, intensity, intensity),
+ Color.argb(255, colorAdd, colorAdd, colorAdd));
+ }
+ return sHighlightFilterCache[intensity];
+ } else {
+ if (sDimFilterCache[intensity] == null) {
+ sDimFilterCache[intensity] = new LightingColorFilter(
+ Color.argb(255, intensity, intensity, intensity), 0);
+ }
+ return sDimFilterCache[intensity];
}
- return sDimFilterCache[dimColor];
}
}
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index 5413a1319..b5f31b8e2 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -250,12 +250,12 @@ public class TaskView extends FrameLayout implements TaskCallbacks, PageCallback
setPivotY(mSnapshotView.getTop() + mSnapshotView.getHeight() * 0.5f);
}
- public float getCurveScaleForInterpolation(float linearInterpolation) {
+ public static float getCurveScaleForInterpolation(float linearInterpolation) {
float curveInterpolation = CURVE_INTERPOLATOR.getInterpolation(linearInterpolation);
return getCurveScaleForCurveInterpolation(curveInterpolation);
}
- private float getCurveScaleForCurveInterpolation(float curveInterpolation) {
+ private static float getCurveScaleForCurveInterpolation(float curveInterpolation) {
return 1 - curveInterpolation * EDGE_SCALE_DOWN_FACTOR;
}
@@ -321,8 +321,6 @@ public class TaskView extends FrameLayout implements TaskCallbacks, PageCallback
}
final RecentsView recentsView = getRecentsView();
- recentsView.addTaskAccessibilityActionsExtra(info);
-
final AccessibilityNodeInfo.CollectionItemInfo itemInfo =
AccessibilityNodeInfo.CollectionItemInfo.obtain(
0, 1, recentsView.getChildCount() - recentsView.indexOfChild(this) - 1, 1,
diff --git a/res/layout/longpress_options_menu.xml b/res/layout/longpress_options_menu.xml
index 168dbc3a2..20bb5b81b 100644
--- a/res/layout/longpress_options_menu.xml
+++ b/res/layout/longpress_options_menu.xml
@@ -22,4 +22,5 @@
android:clipToPadding="false"
android:clipChildren="false"
android:elevation="@dimen/deep_shortcuts_elevation"
+ android:importantForAccessibility="yes"
android:orientation="vertical" />
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 64ca05e3c..30091a5f7 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -20,6 +20,7 @@
<!-- Attributes used for launcher theme -->
<attr name="allAppsScrimColor" format="color" />
+ <attr name="allAppsInterimScrimAlpha" format="integer" />
<attr name="allAppsNavBarScrimColor" format="color" />
<attr name="popupColorPrimary" format="color" />
<attr name="popupColorSecondary" format="color" />
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 2b760f349..31cbaa11a 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -29,6 +29,7 @@
<style name="BaseLauncherThemeWithCustomAttrs" parent="@style/BaseLauncherTheme">
<item name="allAppsScrimColor">#EAFFFFFF</item>
+ <item name="allAppsInterimScrimAlpha">46</item>
<item name="allAppsNavBarScrimColor">#66FFFFFF</item>
<item name="popupColorPrimary">#FFF</item>
<item name="popupColorSecondary">#F5F5F5</item> <!-- Gray 100 -->
@@ -47,6 +48,7 @@
<style name="LauncherTheme.DarkText" parent="@style/LauncherTheme">
<item name="workspaceTextColor">#FF212121</item>
+ <item name="allAppsInterimScrimAlpha">128</item>
<item name="workspaceShadowColor">@android:color/transparent</item>
<item name="workspaceAmbientShadowColor">@android:color/transparent</item>
<item name="workspaceKeyShadowColor">@android:color/transparent</item>
@@ -62,6 +64,7 @@
<item name="android:colorControlHighlight">#A0FFFFFF</item>
<item name="android:colorPrimary">#FF212121</item>
<item name="allAppsScrimColor">#EA212121</item>
+ <item name="allAppsInterimScrimAlpha">102</item>
<item name="allAppsNavBarScrimColor">#80000000</item>
<item name="popupColorPrimary">?android:attr/colorPrimary</item>
<item name="popupColorSecondary">#424242</item> <!-- Gray 800 -->
@@ -71,6 +74,7 @@
</style>
<style name="LauncherThemeDark.DarKText" parent="@style/LauncherThemeDark">
+ <item name="allAppsInterimScrimAlpha">25</item>
<item name="workspaceTextColor">#FF212121</item>
<item name="workspaceShadowColor">@android:color/transparent</item>
<item name="workspaceAmbientShadowColor">@android:color/transparent</item>
diff --git a/src/com/android/launcher3/LauncherStateManager.java b/src/com/android/launcher3/LauncherStateManager.java
index b5eef8bd3..05c515bf4 100644
--- a/src/com/android/launcher3/LauncherStateManager.java
+++ b/src/com/android/launcher3/LauncherStateManager.java
@@ -17,7 +17,6 @@
package com.android.launcher3;
import static android.view.View.VISIBLE;
-
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_OVERVIEW_FADE;
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_OVERVIEW_SCALE;
@@ -222,7 +221,8 @@ public class LauncherStateManager {
}
}
- // Cancel the current animation
+ // Cancel the current animation. This will reset mState to mCurrentStableState, so store it.
+ LauncherState fromState = mState;
mConfig.reset();
if (!animated) {
@@ -245,10 +245,10 @@ public class LauncherStateManager {
// 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;
+ mConfig.duration = state == NORMAL ? fromState.transitionDuration : state.transitionDuration;
AnimatorSetBuilder builder = new AnimatorSetBuilder();
- prepareForAtomicAnimation(mState, state, builder);
+ prepareForAtomicAnimation(fromState, state, builder);
AnimatorSet animation = createAnimationToNewWorkspaceInternal(
state, builder, onCompleteRunnable);
Runnable runnable = new StartAnimRunnable(animation);
@@ -348,6 +348,12 @@ public class LauncherStateManager {
}
@Override
+ public void onAnimationCancel(Animator animation) {
+ super.onAnimationCancel(animation);
+ mState = mCurrentStableState;
+ }
+
+ @Override
public void onAnimationSuccess(Animator animator) {
// Run any queued runnables
if (onCompleteRunnable != null) {
@@ -432,7 +438,6 @@ public class LauncherStateManager {
}
public void setCurrentUserControlledAnimation(AnimatorPlaybackController controller) {
- clearCurrentAnimation();
setCurrentAnimation(controller.getTarget());
mConfig.userControlled = true;
mConfig.playbackController = controller;
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index 5cc2e8fc5..de9cd986f 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -152,6 +152,8 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
// Similar to the platform implementation of isLayoutValid();
protected boolean mIsLayoutValid;
+ private int[] mTmpIntPair = new int[2];
+
public PagedView(Context context) {
this(context, null);
}
@@ -1448,6 +1450,10 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
protected boolean snapToPage(int whichPage, int delta, int duration, boolean immediate,
TimeInterpolator interpolator) {
+ if (mFirstLayout) {
+ setCurrentPage(whichPage);
+ return false;
+ }
if (FeatureFlags.IS_DOGFOOD_BUILD) {
duration *= Settings.System.getFloat(getContext().getContentResolver(),
@@ -1600,4 +1606,33 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
boolean shouldIncludeView(View view);
}
+
+ public int[] getVisibleChildrenRange() {
+ float visibleLeft = 0;
+ float visibleRight = visibleLeft + getMeasuredWidth();
+ float scaleX = getScaleX();
+ if (scaleX < 1 && scaleX > 0) {
+ float mid = getMeasuredWidth() / 2;
+ visibleLeft = mid - ((mid - visibleLeft) / scaleX);
+ visibleRight = mid + ((visibleRight - mid) / scaleX);
+ }
+
+ int leftChild = -1;
+ int rightChild = -1;
+ final int childCount = getChildCount();
+ for (int i = 0; i < childCount; i++) {
+ final View child = getPageAt(i);
+
+ float left = child.getLeft() + child.getTranslationX() - getScrollX();
+ if (left <= visibleRight && (left + child.getMeasuredWidth()) >= visibleLeft) {
+ if (leftChild == -1) {
+ leftChild = i;
+ }
+ rightChild = i;
+ }
+ }
+ mTmpIntPair[0] = leftChild;
+ mTmpIntPair[1] = rightChild;
+ return mTmpIntPair;
+ }
}
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 06eb82e3e..66fb3c6b3 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -1381,28 +1381,9 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
if (mChildrenLayersEnabled) {
final int screenCount = getChildCount();
- float visibleLeft = 0;
- float visibleRight = visibleLeft + getMeasuredWidth();
- float scaleX = getScaleX();
- if (scaleX < 1 && scaleX > 0) {
- float mid = getMeasuredWidth() / 2;
- visibleLeft = mid - ((mid - visibleLeft) / scaleX);
- visibleRight = mid + ((visibleRight - mid) / scaleX);
- }
-
- int leftScreen = -1;
- int rightScreen = -1;
- for (int i = 0; i < screenCount; i++) {
- final View child = getPageAt(i);
-
- float left = child.getLeft() + child.getTranslationX() - getScrollX();
- if (left <= visibleRight && (left + child.getMeasuredWidth()) >= visibleLeft) {
- if (leftScreen == -1) {
- leftScreen = i;
- }
- rightScreen = i;
- }
- }
+ final int[] visibleScreens = getVisibleChildrenRange();
+ int leftScreen = visibleScreens[0];
+ int rightScreen = visibleScreens[1];
if (mForceDrawAdjacentPages) {
// In overview mode, make sure that the two side pages are visible.
leftScreen = Utilities.boundToRange(getCurrentPage() - 1, 0, rightScreen);
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index 68ad6e346..72ba418b2 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -466,9 +466,12 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo
*/
public void addSpringFromFlingUpdateListener(ValueAnimator animator, float velocity) {
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ boolean shouldSpring = true;
+
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
- if (valueAnimator.getAnimatedFraction() >= FLING_ANIMATION_THRESHOLD) {
+ if (shouldSpring
+ && valueAnimator.getAnimatedFraction() >= FLING_ANIMATION_THRESHOLD) {
int searchViewId = getSearchView().getId();
addSpringView(searchViewId);
@@ -481,7 +484,7 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo
}
});
- animator.removeUpdateListener(this);
+ shouldSpring = false;
}
}
});
diff --git a/src/com/android/launcher3/dragndrop/BaseItemDragListener.java b/src/com/android/launcher3/dragndrop/BaseItemDragListener.java
index df4a7c1f5..1e84b416b 100644
--- a/src/com/android/launcher3/dragndrop/BaseItemDragListener.java
+++ b/src/com/android/launcher3/dragndrop/BaseItemDragListener.java
@@ -159,7 +159,7 @@ public abstract class BaseItemDragListener extends InternalStateHandler implemen
postCleanup();
}
- private void postCleanup() {
+ protected void postCleanup() {
clearReference();
if (mLauncher != null) {
// Remove any drag params from the launcher intent since the drag operation is complete.
diff --git a/src/com/android/launcher3/dragndrop/PinItemDragListener.java b/src/com/android/launcher3/dragndrop/PinItemDragListener.java
index 924bb4c25..07eb0d60b 100644
--- a/src/com/android/launcher3/dragndrop/PinItemDragListener.java
+++ b/src/com/android/launcher3/dragndrop/PinItemDragListener.java
@@ -22,14 +22,17 @@ import android.content.pm.LauncherApps.PinItemRequest;
import android.graphics.Rect;
import android.os.Build;
import android.os.Bundle;
+import android.os.CancellationSignal;
import android.view.DragEvent;
import android.view.View;
import android.widget.RemoteViews;
import com.android.launcher3.DragSource;
import com.android.launcher3.ItemInfo;
+import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppWidgetProviderInfo;
import com.android.launcher3.PendingAddItemInfo;
+import com.android.launcher3.uioverrides.UiFactory;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.widget.PendingAddShortcutInfo;
import com.android.launcher3.widget.PendingAddWidgetInfo;
@@ -44,11 +47,13 @@ import com.android.launcher3.widget.WidgetAddFlowHandler;
public class PinItemDragListener extends BaseItemDragListener {
private final PinItemRequest mRequest;
+ private final CancellationSignal mCancelSignal;
public PinItemDragListener(PinItemRequest request, Rect previewRect,
int previewBitmapWidth, int previewViewWidth) {
super(previewRect, previewBitmapWidth, previewViewWidth);
mRequest = request;
+ mCancelSignal = new CancellationSignal();
}
@Override
@@ -60,6 +65,15 @@ public class PinItemDragListener extends BaseItemDragListener {
}
@Override
+ public boolean init(Launcher launcher, boolean alreadyOnHome) {
+ super.init(launcher, alreadyOnHome);
+ if (!alreadyOnHome) {
+ UiFactory.useFadeOutAnimationForLauncherStart(launcher, mCancelSignal);
+ }
+ return false;
+ }
+
+ @Override
protected PendingItemDragHelper createDragHelper() {
final PendingAddItemInfo item;
if (mRequest.getRequestType() == PinItemRequest.REQUEST_TYPE_SHORTCUT) {
@@ -95,6 +109,12 @@ public class PinItemDragListener extends BaseItemDragListener {
targetParent.containerType = LauncherLogProto.ContainerType.PINITEM;
}
+ @Override
+ protected void postCleanup() {
+ super.postCleanup();
+ mCancelSignal.cancel();
+ }
+
public static RemoteViews getPreview(PinItemRequest request) {
Bundle extras = request.getExtras();
if (extras != null &&
diff --git a/src/com/android/launcher3/graphics/LauncherIcons.java b/src/com/android/launcher3/graphics/LauncherIcons.java
index f020d2d7c..89ba72abf 100644
--- a/src/com/android/launcher3/graphics/LauncherIcons.java
+++ b/src/com/android/launcher3/graphics/LauncherIcons.java
@@ -330,9 +330,9 @@ public class LauncherIcons implements AutoCloseable {
mOldBounds.set(icon.getBounds());
if (Utilities.ATLEAST_OREO && icon instanceof AdaptiveIconDrawable) {
- int offset = Math.max((int)(BLUR_FACTOR * textureWidth), Math.min(left, top));
+ int offset = Math.max((int) Math.ceil(BLUR_FACTOR * textureWidth), Math.max(left, top));
int size = Math.max(width, height);
- icon.setBounds(offset, offset, size, size);
+ icon.setBounds(offset, offset, offset + size, offset + size);
} else {
icon.setBounds(left, top, left+width, top+height);
}
diff --git a/src/com/android/launcher3/keyboard/ViewGroupFocusHelper.java b/src/com/android/launcher3/keyboard/ViewGroupFocusHelper.java
index bd5c06e5b..fde220cbf 100644
--- a/src/com/android/launcher3/keyboard/ViewGroupFocusHelper.java
+++ b/src/com/android/launcher3/keyboard/ViewGroupFocusHelper.java
@@ -18,7 +18,6 @@ package com.android.launcher3.keyboard;
import android.graphics.Rect;
import android.view.View;
-import android.view.View.OnFocusChangeListener;
import com.android.launcher3.PagedView;
@@ -52,8 +51,8 @@ public class ViewGroupFocusHelper extends FocusIndicatorHelper {
private void computeLocationRelativeToContainer(View child, Rect outRect) {
View parent = (View) child.getParent();
- outRect.left += child.getLeft();
- outRect.top += child.getTop();
+ outRect.left += child.getX();
+ outRect.top += child.getY();
if (parent != mContainer) {
if (parent instanceof PagedView) {
@@ -64,22 +63,4 @@ public class ViewGroupFocusHelper extends FocusIndicatorHelper {
computeLocationRelativeToContainer(parent, outRect);
}
}
-
- /**
- * Sets the alpha of this FocusIndicatorHelper to 0 when a view with this listener
- * receives focus.
- */
- public View.OnFocusChangeListener getHideIndicatorOnFocusListener() {
- return new OnFocusChangeListener() {
- @Override
- public void onFocusChange(View v, boolean hasFocus) {
- if (hasFocus) {
- endCurrentAnimation();
- setCurrentView(null);
- setAlpha(0);
- invalidateDirty();
- }
- }
- };
- }
}
diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
index f276fbfea..172cf41e0 100644
--- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java
+++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
@@ -527,6 +527,7 @@ public class PopupContainerWithArrow extends ArrowPopup implements DragSource,
protected void closeComplete() {
super.closeComplete();
mOriginalIcon.setTextVisibility(mOriginalIcon.shouldTextBeVisible());
+ mOriginalIcon.forceHideBadge(false);
}
@Override
diff --git a/src/com/android/launcher3/provider/ImportDataTask.java b/src/com/android/launcher3/provider/ImportDataTask.java
index b83d3c0cd..b1dd003f8 100644
--- a/src/com/android/launcher3/provider/ImportDataTask.java
+++ b/src/com/android/launcher3/provider/ImportDataTask.java
@@ -142,6 +142,8 @@ public class ImportDataTask {
// First row of first screen is not empty
createEmptyRowOnFirstScreen = c.moveToNext();
}
+ } else {
+ createEmptyRowOnFirstScreen = false;
}
ArrayList<ContentProviderOperation> insertOperations = new ArrayList<>(BATCH_INSERT_SIZE);
diff --git a/src/com/android/launcher3/qsb/QsbContainerView.java b/src/com/android/launcher3/qsb/QsbContainerView.java
index 65acaa973..b26d39fda 100644
--- a/src/com/android/launcher3/qsb/QsbContainerView.java
+++ b/src/com/android/launcher3/qsb/QsbContainerView.java
@@ -36,7 +36,6 @@ import android.widget.FrameLayout;
import com.android.launcher3.AppWidgetResizeFrame;
import com.android.launcher3.InvariantDeviceProfile;
-import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
@@ -68,6 +67,10 @@ public class QsbContainerView extends FrameLayout {
super.setPadding(0, 0, 0, 0);
}
+ protected void setPaddingUnchecked(int left, int top, int right, int bottom) {
+ super.setPadding(left, top, right, bottom);
+ }
+
/**
* A fragment to display the QSB.
*/
@@ -100,7 +103,7 @@ public class QsbContainerView extends FrameLayout {
mWrapper = new FrameLayout(getActivity());
// Only add the view when enabled
- if (FeatureFlags.QSB_ON_FIRST_SCREEN) {
+ if (isQsbEnabled()) {
mWrapper.addView(createQsb(mWrapper));
}
return mWrapper;
@@ -212,7 +215,7 @@ public class QsbContainerView extends FrameLayout {
private void rebindFragment() {
// Exit if the embedded qsb is disabled
- if (!FeatureFlags.QSB_ON_FIRST_SCREEN) {
+ if (!isQsbEnabled()) {
return;
}
@@ -221,6 +224,10 @@ public class QsbContainerView extends FrameLayout {
mWrapper.addView(createQsb(mWrapper));
}
}
+
+ public boolean isQsbEnabled() {
+ return FeatureFlags.QSB_ON_FIRST_SCREEN;
+ }
}
/**
diff --git a/src/com/android/launcher3/util/Themes.java b/src/com/android/launcher3/util/Themes.java
index d22509344..5f965a341 100644
--- a/src/com/android/launcher3/util/Themes.java
+++ b/src/com/android/launcher3/util/Themes.java
@@ -52,6 +52,13 @@ public class Themes {
return value;
}
+ public static int getAttrInteger(Context context, int attr) {
+ TypedArray ta = context.obtainStyledAttributes(new int[]{attr});
+ int value = ta.getInteger(0, 0);
+ ta.recycle();
+ return value;
+ }
+
/**
* Returns the alpha corresponding to the theme attribute {@param attr}, in the range [0, 255].
*/
diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java b/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java
index db98f9a80..5a7e50fae 100644
--- a/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java
+++ b/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java
@@ -18,6 +18,7 @@ package com.android.launcher3.uioverrides;
import android.app.Activity;
import android.content.Context;
+import android.os.CancellationSignal;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherStateManager.StateHandler;
@@ -51,6 +52,9 @@ public class UiFactory {
public static void onTrimMemory(Launcher launcher, int level) { }
+ public static void useFadeOutAnimationForLauncherStart(Launcher launcher,
+ CancellationSignal cancellationSignal) { }
+
public static boolean dumpActivity(Activity activity, PrintWriter writer) {
return false;
}