From 5e58b447b0c19e646d11e0be45983cb71a043fc2 Mon Sep 17 00:00:00 2001 From: Tony Wickham Date: Wed, 24 Apr 2019 17:19:07 -0700 Subject: [PATCH 01/17] Call initTransitionEndpoints in constructor Before, the soonest we initTransitionEndpoints() is in onRecentsAnimationStart(), which might be too late if launcher was killed. (In that case, the gesture might end before we ever get onRecentsAnimationStart(), and thus will never consider the distance traveled great enough to trigger recents since we don't have endpoints.) Bug: 129723135 Change-Id: I349f62244aaba8369926b14f90acd994fd40a93a --- .../src/com/android/quickstep/WindowTransformSwipeHandler.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java index 365e171693..1577e840b8 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java @@ -276,6 +276,9 @@ public class WindowTransformSwipeHandler mMode = SysUINavigationMode.getMode(context); initStateCallbacks(); + + DeviceProfile dp = InvariantDeviceProfile.INSTANCE.get(mContext).getDeviceProfile(mContext); + initTransitionEndpoints(dp); } private void initStateCallbacks() { From 5c13972e11e5eae185b141e61749415551f4857d Mon Sep 17 00:00:00 2001 From: Tony Date: Mon, 22 Apr 2019 20:29:27 -0700 Subject: [PATCH 02/17] Decouple recents view from window while swiping up MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add setRecentsAttachedToWindow(boolean attached, boolean animate) with the following conditions: Conditions for attached - Motion is paused and shelf is peeking - xDisplacement > yDisplacement (to ensure seamless quick switch) - We are continuing the previous quick switch gesture - Gesture has ended and endTarget is RECENTS or NEW_TASK Conditions for animate - Recents is visible. Since the running task is invisible, this is true if either an adjacent TaskView is visible, or if we’re continuing the previous gesture Currently the attach/detatch animation is just fading recents in/out. Test: - Swipe up to go home does not show the recents list at all. Instead, all the visuals/motion focus on the app window animating into the home screen. - Recents appears when swiping and holding, to indicate that letting go will land in recents. The shelf also appears with haptic feedback in this case to reinforce this. - The next task is immediately visible when quick switching (swiping left to right on the nav bar). Bug: 129985827 Change-Id: Ib0c16f583bfd5b02d2f9f68c9688edc980a39d75 --- .../LauncherActivityControllerHelper.java | 27 +++++- .../quickstep/OtherActivityInputConsumer.java | 1 + .../WindowTransformSwipeHandler.java | 93 +++++++++++++++++-- .../quickstep/ActivityControlHelper.java | 15 ++- 4 files changed, 123 insertions(+), 13 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java index 35783b58a1..a033402ffe 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java @@ -16,14 +16,15 @@ package com.android.quickstep; import static android.view.View.TRANSLATION_Y; - import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY; import static com.android.launcher3.LauncherState.BACKGROUND_APP; import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.LauncherState.OVERVIEW; import static com.android.launcher3.allapps.AllAppsTransitionController.SPRING_DAMPING_RATIO; import static com.android.launcher3.allapps.AllAppsTransitionController.SPRING_STIFFNESS; +import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL; import static com.android.launcher3.anim.Interpolators.LINEAR; +import static com.android.quickstep.WindowTransformSwipeHandler.RECENTS_ATTACH_DURATION; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; @@ -177,6 +178,8 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe return new AnimationFactory() { private Animator mShelfAnim; private ShelfAnimState mShelfState; + private Animator mAttachToWindowAnim; + private boolean mIsAttachedToWindow; @Override public void createActivityController(long transitionLength) { @@ -221,6 +224,28 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe mShelfAnim.setDuration(duration); mShelfAnim.start(); } + + @Override + public void setRecentsAttachedToAppWindow(boolean attached, boolean animate) { + if (mIsAttachedToWindow == attached && animate) { + return; + } + mIsAttachedToWindow = attached; + if (mAttachToWindowAnim != null) { + mAttachToWindowAnim.cancel(); + } + mAttachToWindowAnim = ObjectAnimator.ofFloat(activity.getOverviewPanel(), + RecentsView.CONTENT_ALPHA, attached ? 1 : 0); + mAttachToWindowAnim.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + mAttachToWindowAnim = null; + } + }); + mAttachToWindowAnim.setInterpolator(ACCEL_DEACCEL); + mAttachToWindowAnim.setDuration(animate ? RECENTS_ATTACH_DURATION : 0); + mAttachToWindowAnim.start(); + } }; } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/OtherActivityInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/OtherActivityInputConsumer.java index 44ba515d76..e5b927d4c7 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/OtherActivityInputConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/OtherActivityInputConsumer.java @@ -267,6 +267,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC mMotionPauseDetector.setDisallowPause(upDist < mMotionPauseMinDisplacement || isLikelyToStartNewTask); mMotionPauseDetector.addPosition(displacement, ev.getEventTime()); + mInteractionHandler.setIsLikelyToStartNewTask(isLikelyToStartNewTask); } } break; diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java index e1b38b3336..2e76ec65c5 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java @@ -43,6 +43,7 @@ import android.animation.Animator; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.TimeInterpolator; +import android.animation.ValueAnimator; import android.annotation.TargetApi; import android.app.ActivityManager.RunningTaskInfo; import android.content.Context; @@ -111,6 +112,8 @@ public class WindowTransformSwipeHandler implements SwipeAnimationListener, OnApplyWindowInsetsListener { private static final String TAG = WindowTransformSwipeHandler.class.getSimpleName(); + private static final Rect TEMP_RECT = new Rect(); + private static final String[] STATE_NAMES = DEBUG_STATES ? new String[16] : null; private static int getFlagForIndex(int index, String name) { @@ -162,22 +165,23 @@ public class WindowTransformSwipeHandler STATE_LAUNCHER_PRESENT | STATE_LAUNCHER_DRAWN | STATE_LAUNCHER_STARTED; enum GestureEndTarget { - HOME(1, STATE_SCALED_CONTROLLER_HOME, true, false, ContainerType.WORKSPACE), + HOME(1, STATE_SCALED_CONTROLLER_HOME, true, false, ContainerType.WORKSPACE, false), RECENTS(1, STATE_SCALED_CONTROLLER_RECENTS | STATE_CAPTURE_SCREENSHOT - | STATE_SCREENSHOT_VIEW_SHOWN, true, false, ContainerType.TASKSWITCHER), + | STATE_SCREENSHOT_VIEW_SHOWN, true, false, ContainerType.TASKSWITCHER, true), - NEW_TASK(0, STATE_START_NEW_TASK, false, true, ContainerType.APP), + NEW_TASK(0, STATE_START_NEW_TASK, false, true, ContainerType.APP, true), - LAST_TASK(0, STATE_RESUME_LAST_TASK, false, true, ContainerType.APP); + LAST_TASK(0, STATE_RESUME_LAST_TASK, false, true, ContainerType.APP, false); GestureEndTarget(float endShift, int endState, boolean isLauncher, boolean canBeContinued, - int containerType) { + int containerType, boolean recentsAttachedToAppWindow) { this.endShift = endShift; this.endState = endState; this.isLauncher = isLauncher; this.canBeContinued = canBeContinued; this.containerType = containerType; + this.recentsAttachedToAppWindow = recentsAttachedToAppWindow; } /** 0 is app, 1 is overview */ @@ -190,6 +194,8 @@ public class WindowTransformSwipeHandler public final boolean canBeContinued; /** Used to log where the user ended up after the gesture ends */ public final int containerType; + /** Whether RecentsView should be attached to the window as we animate to this target */ + public final boolean recentsAttachedToAppWindow; } public static final long MAX_SWIPE_DURATION = 350; @@ -202,6 +208,7 @@ public class WindowTransformSwipeHandler private static final String SCREENSHOT_CAPTURED_EVT = "ScreenshotCaptured"; private static final long SHELF_ANIM_DURATION = 120; + public static final long RECENTS_ATTACH_DURATION = 300; /** * Used as the page index for logging when we return to the last task at the end of the gesture. @@ -254,6 +261,7 @@ public class WindowTransformSwipeHandler private int mLogAction = Touch.SWIPE; private int mLogDirection = Direction.UP; private PointF mDownPos; + private boolean mIsLikelyToStartNewTask; private final RecentsAnimationWrapper mRecentsAnimationWrapper; @@ -434,6 +442,7 @@ public class WindowTransformSwipeHandler mAnimationFactory = mActivityControlHelper.prepareRecentsUI(mActivity, mWasLauncherAlreadyVisible, true, this::onAnimatorPlaybackControllerCreated); + maybeUpdateRecentsAttachedState(false /* animate */); }; if (mWasLauncherAlreadyVisible) { // Launcher is visible, but might be about to stop. Thus, if we prepare recents @@ -538,10 +547,65 @@ public class WindowTransformSwipeHandler setShelfState(isPaused ? PEEK : HIDE, FAST_OUT_SLOW_IN, SHELF_ANIM_DURATION); } + public void maybeUpdateRecentsAttachedState() { + maybeUpdateRecentsAttachedState(true /* animate */); + } + + /** + * Determines whether to show or hide RecentsView. The window is always + * synchronized with its corresponding TaskView in RecentsView, so if + * RecentsView is shown, it will appear to be attached to the window. + * + * Note this method has no effect unless the navigation mode is NO_BUTTON. + */ + private void maybeUpdateRecentsAttachedState(boolean animate) { + if (mMode != Mode.NO_BUTTON || mRecentsView == null) { + return; + } + RemoteAnimationTargetCompat runningTaskTarget = mRecentsAnimationWrapper.targetSet == null + ? null + : mRecentsAnimationWrapper.targetSet.findTask(mRunningTaskId); + final boolean recentsAttachedToAppWindow; + int runningTaskIndex = mRecentsView.getRunningTaskIndex(); + if (mContinuingLastGesture) { + recentsAttachedToAppWindow = true; + animate = false; + } else if (runningTaskTarget != null && isNotInRecents(runningTaskTarget)) { + // The window is going away so make sure recents is always visible in this case. + recentsAttachedToAppWindow = true; + animate = false; + } else { + if (mGestureEndTarget != null) { + recentsAttachedToAppWindow = mGestureEndTarget.recentsAttachedToAppWindow; + } else { + recentsAttachedToAppWindow = mIsShelfPeeking || mIsLikelyToStartNewTask; + } + if (animate) { + // Only animate if an adjacent task view is visible on screen. + TaskView adjacentTask1 = mRecentsView.getTaskViewAt(runningTaskIndex + 1); + TaskView adjacentTask2 = mRecentsView.getTaskViewAt(runningTaskIndex - 1); + animate = (adjacentTask1 != null && adjacentTask1.getGlobalVisibleRect(TEMP_RECT)) + || (adjacentTask2 != null && adjacentTask2.getGlobalVisibleRect(TEMP_RECT)); + } + } + mAnimationFactory.setRecentsAttachedToAppWindow(recentsAttachedToAppWindow, animate); + } + + public void setIsLikelyToStartNewTask(boolean isLikelyToStartNewTask) { + if (mIsLikelyToStartNewTask != isLikelyToStartNewTask) { + mIsLikelyToStartNewTask = isLikelyToStartNewTask; + maybeUpdateRecentsAttachedState(); + } + } + @UiThread public void setShelfState(ShelfAnimState shelfState, Interpolator interpolator, long duration) { mAnimationFactory.setShelfState(shelfState, interpolator, duration); + boolean wasShelfPeeking = mIsShelfPeeking; mIsShelfPeeking = shelfState == PEEK; + if (mIsShelfPeeking != wasShelfPeeking) { + maybeUpdateRecentsAttachedState(); + } if (mRecentsView != null && shelfState.shouldPreformHaptic) { mRecentsView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY, HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING); @@ -869,6 +933,8 @@ public class WindowTransformSwipeHandler Interpolator interpolator, GestureEndTarget target, PointF velocityPxPerMs) { mGestureEndTarget = target; + maybeUpdateRecentsAttachedState(); + if (mGestureEndTarget == HOME) { HomeAnimationFactory homeAnimFactory; if (mActivity != null) { @@ -902,8 +968,15 @@ public class WindowTransformSwipeHandler windowAnim.start(velocityPxPerMs); mLauncherTransitionController = null; } else { - Animator windowAnim = mCurrentShift.animateToValue(start, end); + ValueAnimator windowAnim = mCurrentShift.animateToValue(start, end); windowAnim.setDuration(duration).setInterpolator(interpolator); + windowAnim.addUpdateListener(valueAnimator -> { + if (mRecentsView != null && mRecentsView.getVisibility() != View.VISIBLE) { + // Views typically don't compute scroll when invisible as an optimization, + // but in our case we need to since the window offset depends on the scroll. + mRecentsView.computeScroll(); + } + }); windowAnim.addListener(new AnimationSuccessListener() { @Override public void onAnimationSuccess(Animator animator) { @@ -1177,10 +1250,14 @@ public class WindowTransformSwipeHandler } public static float getHiddenTargetAlpha(RemoteAnimationTargetCompat app, Float expectedAlpha) { - if (!(app.isNotInRecents - || app.activityType == RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME)) { + if (!isNotInRecents(app)) { return 0; } return expectedAlpha; } + + private static boolean isNotInRecents(RemoteAnimationTargetCompat app) { + return app.isNotInRecents + || app.activityType == RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME; + } } diff --git a/quickstep/src/com/android/quickstep/ActivityControlHelper.java b/quickstep/src/com/android/quickstep/ActivityControlHelper.java index a71b7bb859..17f88c980e 100644 --- a/quickstep/src/com/android/quickstep/ActivityControlHelper.java +++ b/quickstep/src/com/android/quickstep/ActivityControlHelper.java @@ -27,6 +27,10 @@ import android.view.MotionEvent; import android.view.View; import android.view.animation.Interpolator; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.UiThread; + import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.DeviceProfile; import com.android.launcher3.anim.AnimatorPlaybackController; @@ -37,10 +41,6 @@ import com.android.systemui.shared.system.RemoteAnimationTargetCompat; import java.util.function.BiPredicate; import java.util.function.Consumer; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.annotation.UiThread; - /** * Utility class which abstracts out the logical differences between Launcher and RecentsActivity. */ @@ -122,6 +122,13 @@ public interface ActivityControlHelper { default void setShelfState(ShelfAnimState animState, Interpolator interpolator, long duration) { } + + /** + * @param attached Whether to show RecentsView alongside the app window. If false, recents + * will be hidden by some property we can animate, e.g. alpha. + * @param animate Whether to animate recents to/from its new attached state. + */ + default void setRecentsAttachedToAppWindow(boolean attached, boolean animate) { } } interface HomeAnimationFactory { From 2e4477accbe2d681a8d818088eaca9d2eb48c95b Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Thu, 25 Apr 2019 07:05:41 -0700 Subject: [PATCH 03/17] Filling in content values on the worker thread Writing to disk hapens on the worker thread, so if we create content values on UI thread, some values can change before it is written to disk. This happens in case of shortcuts, where the badge is applied after the icon is queued, but before it is written Bug: 131303610 Change-Id: Ic35b17071d4ed3e5c5fee9f003a225e4ffdc74f3 --- .../android/launcher3/model/ModelWriter.java | 62 ++++++++++--------- src/com/android/launcher3/util/IOUtils.java | 25 ++++++++ 2 files changed, 57 insertions(+), 30 deletions(-) diff --git a/src/com/android/launcher3/model/ModelWriter.java b/src/com/android/launcher3/model/ModelWriter.java index 40c914b216..4ce2f4ba99 100644 --- a/src/com/android/launcher3/model/ModelWriter.java +++ b/src/com/android/launcher3/model/ModelWriter.java @@ -47,6 +47,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.concurrent.Executor; +import java.util.function.Supplier; /** * Class for handling model updates. @@ -151,15 +152,13 @@ public class ModelWriter { public void moveItemInDatabase(final ItemInfo item, int container, int screenId, int cellX, int cellY) { updateItemInfoProps(item, container, screenId, cellX, cellY); - - final ContentWriter writer = new ContentWriter(mContext) - .put(Favorites.CONTAINER, item.container) - .put(Favorites.CELLX, item.cellX) - .put(Favorites.CELLY, item.cellY) - .put(Favorites.RANK, item.rank) - .put(Favorites.SCREEN, item.screenId); - - enqueueDeleteRunnable(new UpdateItemRunnable(item, writer)); + enqueueDeleteRunnable(new UpdateItemRunnable(item, () -> + new ContentWriter(mContext) + .put(Favorites.CONTAINER, item.container) + .put(Favorites.CELLX, item.cellX) + .put(Favorites.CELLY, item.cellY) + .put(Favorites.RANK, item.rank) + .put(Favorites.SCREEN, item.screenId))); } /** @@ -195,25 +194,26 @@ public class ModelWriter { item.spanX = spanX; item.spanY = spanY; - final ContentWriter writer = new ContentWriter(mContext) - .put(Favorites.CONTAINER, item.container) - .put(Favorites.CELLX, item.cellX) - .put(Favorites.CELLY, item.cellY) - .put(Favorites.RANK, item.rank) - .put(Favorites.SPANX, item.spanX) - .put(Favorites.SPANY, item.spanY) - .put(Favorites.SCREEN, item.screenId); - - mWorkerExecutor.execute(new UpdateItemRunnable(item, writer)); + mWorkerExecutor.execute(new UpdateItemRunnable(item, () -> + new ContentWriter(mContext) + .put(Favorites.CONTAINER, item.container) + .put(Favorites.CELLX, item.cellX) + .put(Favorites.CELLY, item.cellY) + .put(Favorites.RANK, item.rank) + .put(Favorites.SPANX, item.spanX) + .put(Favorites.SPANY, item.spanY) + .put(Favorites.SCREEN, item.screenId))); } /** * Update an item to the database in a specified container. */ public void updateItemInDatabase(ItemInfo item) { - ContentWriter writer = new ContentWriter(mContext); - item.onAddToDatabase(writer); - mWorkerExecutor.execute(new UpdateItemRunnable(item, writer)); + mWorkerExecutor.execute(new UpdateItemRunnable(item, () -> { + ContentWriter writer = new ContentWriter(mContext); + item.onAddToDatabase(writer); + return writer; + })); } /** @@ -224,17 +224,18 @@ public class ModelWriter { int container, int screenId, int cellX, int cellY) { updateItemInfoProps(item, container, screenId, cellX, cellY); - final ContentWriter writer = new ContentWriter(mContext); final ContentResolver cr = mContext.getContentResolver(); - item.onAddToDatabase(writer); - item.id = Settings.call(cr, Settings.METHOD_NEW_ITEM_ID).getInt(Settings.EXTRA_VALUE); - writer.put(Favorites._ID, item.id); ModelVerifier verifier = new ModelVerifier(); - final StackTraceElement[] stackTrace = new Throwable().getStackTrace(); mWorkerExecutor.execute(() -> { + // Write the item on background thread, as some properties might have been updated in + // the background. + final ContentWriter writer = new ContentWriter(mContext); + item.onAddToDatabase(writer); + writer.put(Favorites._ID, item.id); + cr.insert(Favorites.CONTENT_URI, writer.getValues(mContext)); synchronized (mBgDataModel) { @@ -354,10 +355,10 @@ public class ModelWriter { private class UpdateItemRunnable extends UpdateItemBaseRunnable { private final ItemInfo mItem; - private final ContentWriter mWriter; + private final Supplier mWriter; private final int mItemId; - UpdateItemRunnable(ItemInfo item, ContentWriter writer) { + UpdateItemRunnable(ItemInfo item, Supplier writer) { mItem = item; mWriter = writer; mItemId = item.id; @@ -366,7 +367,8 @@ public class ModelWriter { @Override public void run() { Uri uri = Favorites.getContentUri(mItemId); - mContext.getContentResolver().update(uri, mWriter.getValues(mContext), null, null); + mContext.getContentResolver().update(uri, mWriter.get().getValues(mContext), + null, null); updateItemArrays(mItem, mItemId); } } diff --git a/src/com/android/launcher3/util/IOUtils.java b/src/com/android/launcher3/util/IOUtils.java index 77c21fe925..f95f74d600 100644 --- a/src/com/android/launcher3/util/IOUtils.java +++ b/src/com/android/launcher3/util/IOUtils.java @@ -16,12 +16,18 @@ package com.android.launcher3.util; +import android.content.Context; + +import com.android.launcher3.config.FeatureFlags; + import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; +import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.util.UUID; /** * Supports various IO utility functions @@ -52,4 +58,23 @@ public class IOUtils { } return total; } + + /** + * Utility method to debug binary data + */ + public static String createTempFile(Context context, byte[] data) { + if (!FeatureFlags.IS_DOGFOOD_BUILD) { + throw new IllegalStateException("Method only allowed in development mode"); + } + + String name = UUID.randomUUID().toString(); + File file = new File(context.getCacheDir(), name); + try (FileOutputStream fo = new FileOutputStream(file)) { + fo.write(data); + fo.flush(); + } catch (Exception e) { + throw new RuntimeException(e); + } + return file.getAbsolutePath(); + } } From 5519a0f6a8d310b97ff03de654a02d4efeadd49c Mon Sep 17 00:00:00 2001 From: Tony Wickham Date: Wed, 24 Apr 2019 18:45:02 -0700 Subject: [PATCH 04/17] Use AccessibilityManager#getRecommendedTimeoutMillis for Snackbar Bug: 129806241 Change-Id: I4aabc3ee33560960f3117d82f9873fce60f1278a --- .../launcher3/compat/AccessibilityManagerCompat.java | 7 +++++++ src/com/android/launcher3/views/Snackbar.java | 10 ++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/com/android/launcher3/compat/AccessibilityManagerCompat.java b/src/com/android/launcher3/compat/AccessibilityManagerCompat.java index 51e914c441..b4d0c54fc6 100644 --- a/src/com/android/launcher3/compat/AccessibilityManagerCompat.java +++ b/src/com/android/launcher3/compat/AccessibilityManagerCompat.java @@ -106,4 +106,11 @@ public class AccessibilityManagerCompat { } return false; } + + public static int getRecommendedTimeoutMillis(Context context, int originalTimeout, int flags) { + if (Utilities.ATLEAST_Q) { + return getManager(context).getRecommendedTimeoutMillis(originalTimeout, flags); + } + return originalTimeout; + } } diff --git a/src/com/android/launcher3/views/Snackbar.java b/src/com/android/launcher3/views/Snackbar.java index 04b637bbf9..dc0e2e0dfc 100644 --- a/src/com/android/launcher3/views/Snackbar.java +++ b/src/com/android/launcher3/views/Snackbar.java @@ -16,6 +16,9 @@ package com.android.launcher3.views; +import static android.view.accessibility.AccessibilityManager.FLAG_CONTENT_CONTROLS; +import static android.view.accessibility.AccessibilityManager.FLAG_CONTENT_TEXT; + import android.content.Context; import android.content.res.Resources; import android.graphics.Rect; @@ -29,6 +32,7 @@ import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.Launcher; import com.android.launcher3.R; import com.android.launcher3.anim.Interpolators; +import com.android.launcher3.compat.AccessibilityManagerCompat; import com.android.launcher3.dragndrop.DragLayer; /** @@ -38,7 +42,7 @@ public class Snackbar extends AbstractFloatingView { private static final long SHOW_DURATION_MS = 180; private static final long HIDE_DURATION_MS = 180; - private static final long TIMEOUT_DURATION_MS = 4000; + private static final int TIMEOUT_DURATION_MS = 4000; private final Launcher mLauncher; private Runnable mOnDismissed; @@ -131,7 +135,9 @@ public class Snackbar extends AbstractFloatingView { .setDuration(SHOW_DURATION_MS) .setInterpolator(Interpolators.ACCEL_DEACCEL) .start(); - snackbar.postDelayed(() -> snackbar.close(true), TIMEOUT_DURATION_MS); + int timeout = AccessibilityManagerCompat.getRecommendedTimeoutMillis(launcher, + TIMEOUT_DURATION_MS, FLAG_CONTENT_TEXT | FLAG_CONTENT_CONTROLS); + snackbar.postDelayed(() -> snackbar.close(true), timeout); } @Override From fd94cd54987931499e7252d03a5ecf6e1056dba0 Mon Sep 17 00:00:00 2001 From: Hyunyoung Song Date: Thu, 25 Apr 2019 11:20:42 -0700 Subject: [PATCH 05/17] Add logging for Task Icon interaction Bug: 129279637 Change-Id: I135bad16015129b3b60bb13e86783d623e504b1b --- protos/launcher_log.proto | 2 ++ .../src/com/android/quickstep/views/TaskView.java | 10 +++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/protos/launcher_log.proto b/protos/launcher_log.proto index 4974dcbdc9..02c6b0f419 100644 --- a/protos/launcher_log.proto +++ b/protos/launcher_log.proto @@ -71,6 +71,7 @@ enum ItemType { NOTIFICATION = 8; TASK = 9; // Each page of Recents UI (QuickStep) WEB_APP = 10; + TASK_ICON = 11; } // Used to define what type of container a Target would represent. @@ -115,6 +116,7 @@ enum ControlType { REMOTE_ACTION_SHORTCUT = 17; APP_USAGE_SETTINGS = 18; BACK_GESTURE = 19; + UNDO = 20; } enum TipType { diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java index 05fe2d0d1e..848c2140fd 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java @@ -49,6 +49,8 @@ import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.R; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.Interpolators; +import com.android.launcher3.logging.UserEventDispatcher; +import com.android.launcher3.userevent.nano.LauncherLogProto; import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction; import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch; import com.android.launcher3.util.PendingAnimation; @@ -366,9 +368,11 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { } } - private boolean showTaskMenu() { + private boolean showTaskMenu(int action) { getRecentsView().snapToPage(getRecentsView().indexOfChild(this)); mMenuView = TaskMenuView.showForTask(this); + UserEventDispatcher.newInstance(getContext()).logActionOnItem(action, Direction.NONE, + LauncherLogProto.ItemType.TASK_ICON); if (mMenuView != null) { mMenuView.addOnAttachStateChangeListener(mTaskMenuStateListener); } @@ -378,10 +382,10 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { private void setIcon(Drawable icon) { if (icon != null) { mIconView.setDrawable(icon); - mIconView.setOnClickListener(v -> showTaskMenu()); + mIconView.setOnClickListener(v -> showTaskMenu(Touch.TAP)); mIconView.setOnLongClickListener(v -> { requestDisallowInterceptTouchEvent(true); - return showTaskMenu(); + return showTaskMenu(Touch.LONGPRESS); }); } else { mIconView.setDrawable(null); From ab03a7eb19b644fc7992f1dd2fd33e00466ee808 Mon Sep 17 00:00:00 2001 From: vadimt Date: Thu, 25 Apr 2019 11:57:41 -0700 Subject: [PATCH 06/17] Enable testStressSwipeToOverview() Underlying issue has been fixed. Bug: 129723135 Change-Id: I336de8bb38360ee83023caa17bc90a601db3b9e2 --- .../src/com/android/quickstep/StartLauncherViaGestureTests.java | 1 - 1 file changed, 1 deletion(-) diff --git a/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java b/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java index a47c8e7a99..8bdb90db79 100644 --- a/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java +++ b/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java @@ -88,7 +88,6 @@ public class StartLauncherViaGestureTests extends AbstractQuickStepTest { } @Test - @Ignore // b/129723135 @NavigationModeSwitch public void testStressSwipeToOverview() { for (int i = 0; i < STRESS_REPEAT_COUNT; ++i) { From 1335c36c15bbd92ee43b0f4a228b604422711b05 Mon Sep 17 00:00:00 2001 From: Kevin Date: Thu, 25 Apr 2019 12:53:20 -0700 Subject: [PATCH 07/17] Don't layout empty tasks in layout anim if we have the actual content. When we load the task content (icons, snapshots, etc), oftentimes, we are still in the middle of the layout animation where items are fading in from bottom to top. At this point, we start a second content-fill animation from bottom to top that fades from empty => filled after the first animation. However, we can improve this so that empty views aren't shown for a split second for some of the later laid out views. If the first animation has not finished and we would animate a content change from empty => filled but the view is currently still not visible, we should just complete the content transition on the spot so that the layout animation lays out the filled version instead. Bug: 131339235 Test: Go to recents, observe lay out animation does not continue to lay out the empty view first Change-Id: I936a81e6cf8b3552cdee90c183fc841f50ec9ea8 --- .../src/com/android/quickstep/ContentFillItemAnimator.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/go/quickstep/src/com/android/quickstep/ContentFillItemAnimator.java b/go/quickstep/src/com/android/quickstep/ContentFillItemAnimator.java index 1b6f2e34d9..9282345532 100644 --- a/go/quickstep/src/com/android/quickstep/ContentFillItemAnimator.java +++ b/go/quickstep/src/com/android/quickstep/ContentFillItemAnimator.java @@ -161,6 +161,13 @@ public final class ContentFillItemAnimator extends SimpleItemAnimator { private void animateChangeImpl(ViewHolder viewHolder, long startDelay) { TaskItemView itemView = (TaskItemView) viewHolder.itemView; + if (itemView.getAlpha() == 0) { + // View is still not visible, so we can finish the change immediately. + CONTENT_TRANSITION_PROGRESS.set(itemView, 1.0f); + dispatchChangeFinished(viewHolder, true /* oldItem */); + dispatchFinishedWhenDone(); + return; + } final ObjectAnimator anim = ObjectAnimator.ofFloat(itemView, CONTENT_TRANSITION_PROGRESS, 0.0f, 1.0f); anim.setDuration(ITEM_CHANGE_DURATION).setStartDelay(startDelay); From 03f27013bfcd30f697220b8e6315e76688dc0d3c Mon Sep 17 00:00:00 2001 From: Tony Wickham Date: Thu, 25 Apr 2019 14:22:54 -0700 Subject: [PATCH 08/17] Log undo button click Also fix a bug where we logged workspace swipe upon clicking undo, since rebinding the pages causes us to reset mCurrentPage = 0 followed by setCurrentPage(pageBoundFirst). Since the page isn't actually visibly changing, we shouldn't log in that case. Bug: 118758133 Change-Id: Ie87164a8c7c278680f67dee75657210bd33408a4 --- src/com/android/launcher3/DeleteDropTarget.java | 9 ++++++++- src/com/android/launcher3/Launcher.java | 9 +++++---- src/com/android/launcher3/PagedView.java | 8 ++++++-- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/com/android/launcher3/DeleteDropTarget.java b/src/com/android/launcher3/DeleteDropTarget.java index 8cbad20b57..3347b2aef0 100644 --- a/src/com/android/launcher3/DeleteDropTarget.java +++ b/src/com/android/launcher3/DeleteDropTarget.java @@ -16,6 +16,9 @@ package com.android.launcher3; +import static com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch.TAP; +import static com.android.launcher3.userevent.nano.LauncherLogProto.ControlType.UNDO; + import android.content.Context; import android.text.TextUtils; import android.util.AttributeSet; @@ -121,8 +124,12 @@ public class DeleteDropTarget extends ButtonDropTarget { int itemPage = mLauncher.getWorkspace().getCurrentPage(); onAccessibilityDrop(null, item); ModelWriter modelWriter = mLauncher.getModelWriter(); + Runnable onUndoClicked = () -> { + modelWriter.abortDelete(itemPage); + mLauncher.getUserEventDispatcher().logActionOnControl(TAP, UNDO); + }; Snackbar.show(mLauncher, R.string.item_removed, R.string.undo, - modelWriter::commitDelete, () -> modelWriter.abortDelete(itemPage)); + modelWriter::commitDelete, onUndoClicked); } } diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index d790c047ca..1223787bd0 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -75,6 +75,8 @@ import android.view.accessibility.AccessibilityEvent; import android.view.animation.OvershootInterpolator; import android.widget.Toast; +import androidx.annotation.Nullable; + import com.android.launcher3.DropTarget.DragObject; import com.android.launcher3.accessibility.LauncherAccessibilityDelegate; import com.android.launcher3.allapps.AllAppsContainerView; @@ -150,9 +152,6 @@ import java.util.HashSet; import java.util.List; import java.util.function.Predicate; -import androidx.annotation.IdRes; -import androidx.annotation.Nullable; - /** * Default launcher application. */ @@ -2198,7 +2197,9 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, InstallShortcutReceiver.FLAG_LOADER_RUNNING, this); // When undoing the removal of the last item on a page, return to that page. - mWorkspace.setCurrentPage(pageBoundFirst); + // Since we are just resetting the current page without user interaction, + // override the previous page so we don't log the page switch. + mWorkspace.setCurrentPage(pageBoundFirst, pageBoundFirst /* overridePrevPage */); TraceHelper.endSection("finishBindingItems"); } diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java index abb45e51dd..3a02b073e8 100644 --- a/src/com/android/launcher3/PagedView.java +++ b/src/com/android/launcher3/PagedView.java @@ -300,10 +300,14 @@ public abstract class PagedView extends ViewGrou return page; } + public void setCurrentPage(int currentPage) { + setCurrentPage(currentPage, INVALID_PAGE); + } + /** * Sets the current page. */ - public void setCurrentPage(int currentPage) { + public void setCurrentPage(int currentPage, int overridePrevPage) { if (!mScroller.isFinished()) { abortScrollerAnimation(true); } @@ -312,7 +316,7 @@ public abstract class PagedView extends ViewGrou if (getChildCount() == 0) { return; } - int prevPage = mCurrentPage; + int prevPage = overridePrevPage != INVALID_PAGE ? overridePrevPage : mCurrentPage; mCurrentPage = validateNewPage(currentPage); updateCurrentPageScroll(); notifyPageSwitchListener(prevPage); From a310a80c7b01057eaa89edca99085c24706c9e73 Mon Sep 17 00:00:00 2001 From: Hyunyoung Song Date: Thu, 25 Apr 2019 13:57:16 -0700 Subject: [PATCH 09/17] Add important dump logging Bug: 130851537 Bug: 119992316 Change-Id: I3de7c1d910d1aecd80b47a85284565c79fe0e2cc --- .../NavBarToHomeTouchController.java | 5 +++++ .../touchcontrollers/TaskViewTouchController.java | 5 +++++ .../touchcontrollers/StatusBarTouchController.java | 12 ++++++++++++ src/com/android/launcher3/AbstractFloatingView.java | 4 ++++ src/com/android/launcher3/Launcher.java | 3 ++- src/com/android/launcher3/LauncherStateManager.java | 10 ++++++++++ .../android/launcher3/dragndrop/DragController.java | 4 ++++ .../touch/AbstractStateChangeTouchController.java | 5 +++++ src/com/android/launcher3/util/TouchController.java | 4 ++++ src/com/android/launcher3/views/BaseDragLayer.java | 9 +++++++-- 10 files changed, 58 insertions(+), 3 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java index 8b1b51d43f..750495f7f2 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java @@ -52,6 +52,8 @@ import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch; import com.android.launcher3.util.TouchController; import com.android.quickstep.views.RecentsView; +import java.io.PrintWriter; + /** * Handles swiping up on the nav bar to go home from launcher, e.g. overview or all apps. */ @@ -224,4 +226,7 @@ public class NavBarToHomeTouchController implements TouchController, SwipeDetect mEndState.containerType, mLauncher.getWorkspace().getCurrentPage()); } + + @Override + public void dump(String prefix, PrintWriter writer) { } } diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java index 8b4aa07d79..87f1f7eb46 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java @@ -42,6 +42,8 @@ import com.android.quickstep.SysUINavigationMode; import com.android.quickstep.views.RecentsView; import com.android.quickstep.views.TaskView; +import java.io.PrintWriter; + /** * Touch controller for handling task view card swipes */ @@ -305,4 +307,7 @@ public abstract class TaskViewTouchController mPendingAnimation = null; } } + + @Override + public void dump(String prefix, PrintWriter writer) { } } diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java index 12e6f12bcc..fee18204ea 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java @@ -32,6 +32,8 @@ import com.android.launcher3.util.TouchController; import com.android.quickstep.RecentsModel; import com.android.systemui.shared.recents.ISystemUiProxy; +import java.io.PrintWriter; + /** * TouchController for handling touch events that get sent to the StatusBar. Once the * Once the event delta y passes the touch slop, the events start getting forwarded. @@ -45,6 +47,7 @@ public class StatusBarTouchController implements TouchController { protected final TouchEventTranslator mTranslator; private final float mTouchSlop; private ISystemUiProxy mSysUiProxy; + private int mLastAction; /* If {@code false}, this controller should not handle the input {@link MotionEvent}.*/ private boolean mCanIntercept; @@ -56,9 +59,18 @@ public class StatusBarTouchController implements TouchController { mTranslator = new TouchEventTranslator((MotionEvent ev)-> dispatchTouchEvent(ev)); } + @Override + public void dump(String prefix, PrintWriter writer) { + writer.println(prefix + "mCanIntercept:" + mCanIntercept); + writer.println(prefix + "mLastAction:" + MotionEvent.actionToString(mLastAction)); + writer.println(prefix + "mSysUiProxy available:" + (mSysUiProxy != null)); + + } + private void dispatchTouchEvent(MotionEvent ev) { try { if (mSysUiProxy != null) { + mLastAction = ev.getActionMasked(); mSysUiProxy.onStatusBarMotionEvent(ev); } } catch (RemoteException e) { diff --git a/src/com/android/launcher3/AbstractFloatingView.java b/src/com/android/launcher3/AbstractFloatingView.java index d6f992f516..bd584996cc 100644 --- a/src/com/android/launcher3/AbstractFloatingView.java +++ b/src/com/android/launcher3/AbstractFloatingView.java @@ -41,6 +41,7 @@ import com.android.launcher3.util.TouchController; import com.android.launcher3.views.ActivityContext; import com.android.launcher3.views.BaseDragLayer; +import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -251,4 +252,7 @@ public abstract class AbstractFloatingView extends LinearLayout implements Touch @FloatingViewType int type) { return getOpenView(activity, type); } + + @Override + public void dump(String prefix, PrintWriter writer) { } } diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index d790c047ca..bdb71d2785 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -2345,7 +2345,8 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, writer.println(" mPendingActivityResult=" + mPendingActivityResult); writer.println(" mRotationHelper: " + mRotationHelper); // Extra logging for b/116853349 - mDragLayer.dumpAlpha(writer); + mDragLayer.dump(prefix, writer); + mStateManager.dump(prefix, writer); dumpMisc(writer); try { diff --git a/src/com/android/launcher3/LauncherStateManager.java b/src/com/android/launcher3/LauncherStateManager.java index 209578d22a..b24f660e6b 100644 --- a/src/com/android/launcher3/LauncherStateManager.java +++ b/src/com/android/launcher3/LauncherStateManager.java @@ -50,6 +50,7 @@ import com.android.launcher3.anim.PropertySetter; import com.android.launcher3.anim.PropertySetter.AnimatedPropertySetter; import com.android.launcher3.uioverrides.UiFactory; +import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; @@ -144,6 +145,15 @@ public class LauncherStateManager { return mCurrentStableState; } + public void dump(String prefix, PrintWriter writer) { + writer.println(prefix + "LauncherState"); + writer.println(prefix + "\tmLastStableState:" + mLastStableState); + writer.println(prefix + "\tmCurrentStableState:" + mCurrentStableState); + writer.println(prefix + "\tmState:" + mState); + writer.println(prefix + "\tmRestState:" + mRestState); + writer.println(prefix + "\tisInTransition:" + (mConfig.mCurrentAnimation != null)); + } + public StateHandler[] getStateHandlers() { if (mStateHandlers == null) { mStateHandlers = UiFactory.getStateHandler(mLauncher); diff --git a/src/com/android/launcher3/dragndrop/DragController.java b/src/com/android/launcher3/dragndrop/DragController.java index 4d45ba9e68..5c3d4fbbf1 100644 --- a/src/com/android/launcher3/dragndrop/DragController.java +++ b/src/com/android/launcher3/dragndrop/DragController.java @@ -46,6 +46,7 @@ import com.android.launcher3.util.Thunk; import com.android.launcher3.util.TouchController; import com.android.launcher3.util.UiThreadHelper; +import java.io.PrintWriter; import java.util.ArrayList; /** @@ -697,4 +698,7 @@ public class DragController implements DragDriver.EventListener, TouchController mDropTargets.remove(target); } + @Override + public void dump(String prefix, PrintWriter writer) { } + } diff --git a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java index 0274de35cb..5f40dce9ce 100644 --- a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java +++ b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java @@ -50,6 +50,8 @@ import com.android.launcher3.util.FlingBlockCheck; import com.android.launcher3.util.PendingAnimation; import com.android.launcher3.util.TouchController; +import java.io.PrintWriter; + /** * TouchController for handling state changes */ @@ -581,4 +583,7 @@ public abstract class AbstractStateChangeTouchController this.endTime = duration + SystemClock.elapsedRealtime(); } } + + @Override + public void dump(String prefix, PrintWriter writer) { } } diff --git a/src/com/android/launcher3/util/TouchController.java b/src/com/android/launcher3/util/TouchController.java index 3cca215002..ac6a5bdcff 100644 --- a/src/com/android/launcher3/util/TouchController.java +++ b/src/com/android/launcher3/util/TouchController.java @@ -18,6 +18,8 @@ package com.android.launcher3.util; import android.view.MotionEvent; +import java.io.PrintWriter; + public interface TouchController { /** @@ -29,4 +31,6 @@ public interface TouchController { * Called when the draglayer receives a intercept touch event. */ boolean onControllerInterceptTouchEvent(MotionEvent ev); + + void dump(String prefix, PrintWriter writer); } diff --git a/src/com/android/launcher3/views/BaseDragLayer.java b/src/com/android/launcher3/views/BaseDragLayer.java index ab72bbe184..66cd536a54 100644 --- a/src/com/android/launcher3/views/BaseDragLayer.java +++ b/src/com/android/launcher3/views/BaseDragLayer.java @@ -383,8 +383,13 @@ public abstract class BaseDragLayer return mMultiValueAlpha.getProperty(index); } - public void dumpAlpha(PrintWriter writer) { - writer.println(" dragLayerAlpha : " + mMultiValueAlpha ); + public void dump(String prefix, PrintWriter writer) { + writer.println(prefix + "DragLayer"); + if (mActiveController != null) { + writer.println(prefix + "\tactiveController: " + mActiveController); + mActiveController.dump(prefix + "\t", writer); + } + writer.println(prefix + "\tdragLayerAlpha : " + mMultiValueAlpha ); } public static class LayoutParams extends InsettableFrameLayout.LayoutParams { From b60dce726884227e75b5b7788d9068bb3d736c32 Mon Sep 17 00:00:00 2001 From: Matthew Ng Date: Wed, 24 Apr 2019 11:54:44 -0700 Subject: [PATCH 10/17] Remove interaction flag code replaced by QuickStepContract (1/2) Test: manual Bug: 112934365 Fixes: 129497226 Change-Id: Id128eee4eaa620f0b9c461ef5adf0a16e9ea9a2c --- .../quickstep/AssistantTouchConsumer.java | 4 +- .../quickstep/OtherActivityInputConsumer.java | 6 +- .../quickstep/OverviewInteractionState.java | 60 +------------------ 3 files changed, 8 insertions(+), 62 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/AssistantTouchConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/AssistantTouchConsumer.java index a76ecd53b1..5e7faf7274 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/AssistantTouchConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/AssistantTouchConsumer.java @@ -45,7 +45,7 @@ import com.android.launcher3.anim.Interpolators; import com.android.launcher3.logging.UserEventDispatcher; import com.android.systemui.shared.recents.ISystemUiProxy; import com.android.systemui.shared.system.InputMonitorCompat; -import com.android.systemui.shared.system.NavigationBarCompat; +import com.android.systemui.shared.system.QuickStepContract; /** * Touch consumer for handling events to launch assistant from launcher @@ -103,7 +103,7 @@ public class AssistantTouchConsumer implements InputConsumer { mDistThreshold = res.getDimension(R.dimen.gestures_assistant_drag_threshold); mTimeThreshold = res.getInteger(R.integer.assistant_gesture_min_time_threshold); mAngleThreshold = res.getInteger(R.integer.assistant_gesture_corner_deg_threshold); - mSlop = NavigationBarCompat.getQuickStepDragSlopPx(); + mSlop = QuickStepContract.getQuickStepDragSlopPx(); mInputMonitorCompat = inputMonitorCompat; mActivityControlHelper = activityControlHelper; mState = STATE_INACTIVE; diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/OtherActivityInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/OtherActivityInputConsumer.java index 44ba515d76..bb320f2c55 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/OtherActivityInputConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/OtherActivityInputConsumer.java @@ -60,7 +60,7 @@ import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.BackgroundExecutor; import com.android.systemui.shared.system.InputConsumerController; import com.android.systemui.shared.system.InputMonitorCompat; -import com.android.systemui.shared.system.NavigationBarCompat; +import com.android.systemui.shared.system.QuickStepContract; import com.android.systemui.shared.system.WindowManagerWrapper; import java.util.function.Consumer; @@ -152,8 +152,8 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC mDisplayRotation = display.getRotation(); WindowManagerWrapper.getInstance().getStableInsets(mStableInsets); - mDragSlop = NavigationBarCompat.getQuickStepDragSlopPx(); - mTouchSlop = NavigationBarCompat.getQuickStepTouchSlopPx(); + mDragSlop = QuickStepContract.getQuickStepDragSlopPx(); + mTouchSlop = QuickStepContract.getQuickStepTouchSlopPx(); mPassedTouchSlop = mPassedDragSlop = continuingPreviousGesture; } diff --git a/quickstep/src/com/android/quickstep/OverviewInteractionState.java b/quickstep/src/com/android/quickstep/OverviewInteractionState.java index 286ddc043e..6c7bc776c0 100644 --- a/quickstep/src/com/android/quickstep/OverviewInteractionState.java +++ b/quickstep/src/com/android/quickstep/OverviewInteractionState.java @@ -15,46 +15,32 @@ */ package com.android.quickstep; -import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_DISABLE_QUICK_SCRUB; -import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_DISABLE_SWIPE_UP; -import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_SHOW_OVERVIEW_BUTTON; - import android.content.Context; import android.os.Handler; import android.os.Message; import android.os.RemoteException; import android.util.Log; -import com.android.launcher3.Utilities; -import com.android.launcher3.allapps.DiscoveryBounce; import com.android.launcher3.util.MainThreadInitializedObject; import com.android.launcher3.util.UiThreadHelper; import com.android.systemui.shared.recents.ISystemUiProxy; import androidx.annotation.WorkerThread; +import com.android.systemui.shared.system.QuickStepContract; /** - * Sets overview interaction flags, such as: - * - * - FLAG_DISABLE_QUICK_SCRUB - * - FLAG_DISABLE_SWIPE_UP - * - FLAG_SHOW_OVERVIEW_BUTTON - * - * @see com.android.systemui.shared.system.NavigationBarCompat.InteractionType and associated flags. + * Sets alpha for the back button */ public class OverviewInteractionState { private static final String TAG = "OverviewFlags"; - private static final String HAS_ENABLED_QUICKSTEP_ONCE = "launcher.has_enabled_quickstep_once"; - // We do not need any synchronization for this variable as its only written on UI thread. public static final MainThreadInitializedObject INSTANCE = new MainThreadInitializedObject<>((c) -> new OverviewInteractionState(c)); private static final int MSG_SET_PROXY = 200; private static final int MSG_SET_BACK_BUTTON_ALPHA = 201; - private static final int MSG_APPLY_FLAGS = 202; private final Context mContext; private final Handler mUiHandler; @@ -62,7 +48,6 @@ public class OverviewInteractionState { // These are updated on the background thread private ISystemUiProxy mISystemUiProxy; - private boolean mSwipeUpEnabled; private float mBackButtonAlpha = 1; private OverviewInteractionState(Context context) { @@ -73,9 +58,6 @@ public class OverviewInteractionState { // For example, send back alpha on uihandler to avoid flickering when setting its visibility mUiHandler = new Handler(this::handleUiMessage); mBgHandler = new Handler(UiThreadHelper.getBackgroundLooper(), this::handleBgMessage); - - onNavigationModeChanged(SysUINavigationMode.INSTANCE.get(context) - .addModeChangeListener(this::onNavigationModeChanged)); } public float getBackButtonAlpha() { @@ -83,7 +65,7 @@ public class OverviewInteractionState { } public void setBackButtonAlpha(float alpha, boolean animate) { - if (!mSwipeUpEnabled) { + if (QuickStepContract.isLegacyMode(SysUINavigationMode.getMode(mContext).resValue)) { alpha = 1; } mUiHandler.removeMessages(MSG_SET_BACK_BUTTON_ALPHA); @@ -111,30 +93,10 @@ public class OverviewInteractionState { case MSG_SET_BACK_BUTTON_ALPHA: applyBackButtonAlpha((float) msg.obj, msg.arg1 == 1); return true; - case MSG_APPLY_FLAGS: - break; } - applyFlags(); return true; } - @WorkerThread - private void applyFlags() { - if (mISystemUiProxy == null) { - return; - } - - int flags = FLAG_DISABLE_QUICK_SCRUB; - if (!mSwipeUpEnabled) { - flags = FLAG_DISABLE_SWIPE_UP | FLAG_DISABLE_QUICK_SCRUB | FLAG_SHOW_OVERVIEW_BUTTON; - } - try { - mISystemUiProxy.setInteractionState(flags); - } catch (RemoteException e) { - Log.w(TAG, "Unable to update overview interaction flags", e); - } - } - @WorkerThread private void applyBackButtonAlpha(float alpha, boolean animate) { if (mISystemUiProxy == null) { @@ -146,20 +108,4 @@ public class OverviewInteractionState { Log.w(TAG, "Unable to update overview back button alpha", e); } } - - private void onNavigationModeChanged(SysUINavigationMode.Mode mode) { - mSwipeUpEnabled = mode.hasGestures; - resetHomeBounceSeenOnQuickstepEnabledFirstTime(); - mBgHandler.obtainMessage(MSG_APPLY_FLAGS).sendToTarget(); - } - - private void resetHomeBounceSeenOnQuickstepEnabledFirstTime() { - if (mSwipeUpEnabled && !Utilities.getPrefs(mContext).getBoolean( - HAS_ENABLED_QUICKSTEP_ONCE, true)) { - Utilities.getPrefs(mContext).edit() - .putBoolean(HAS_ENABLED_QUICKSTEP_ONCE, true) - .putBoolean(DiscoveryBounce.HOME_BOUNCE_SEEN, false) - .apply(); - } - } } From 9e7d2acc22fdf76c8a1a55d7bb7c6eb5fc72b18d Mon Sep 17 00:00:00 2001 From: Hyunyoung Song Date: Thu, 25 Apr 2019 16:07:18 -0700 Subject: [PATCH 11/17] Cleanup unnecessary override dump method Change-Id: Ic2909a4d382362ddec9bcc2c738d13120e792fd8 --- .../touchcontrollers/NavBarToHomeTouchController.java | 5 ----- .../touchcontrollers/TaskViewTouchController.java | 5 ----- src/com/android/launcher3/AbstractFloatingView.java | 4 ---- src/com/android/launcher3/dragndrop/DragController.java | 5 ----- .../launcher3/touch/AbstractStateChangeTouchController.java | 5 ----- src/com/android/launcher3/util/TouchController.java | 2 +- 6 files changed, 1 insertion(+), 25 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java index 750495f7f2..8b1b51d43f 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java @@ -52,8 +52,6 @@ import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch; import com.android.launcher3.util.TouchController; import com.android.quickstep.views.RecentsView; -import java.io.PrintWriter; - /** * Handles swiping up on the nav bar to go home from launcher, e.g. overview or all apps. */ @@ -226,7 +224,4 @@ public class NavBarToHomeTouchController implements TouchController, SwipeDetect mEndState.containerType, mLauncher.getWorkspace().getCurrentPage()); } - - @Override - public void dump(String prefix, PrintWriter writer) { } } diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java index 87f1f7eb46..8b4aa07d79 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java @@ -42,8 +42,6 @@ import com.android.quickstep.SysUINavigationMode; import com.android.quickstep.views.RecentsView; import com.android.quickstep.views.TaskView; -import java.io.PrintWriter; - /** * Touch controller for handling task view card swipes */ @@ -307,7 +305,4 @@ public abstract class TaskViewTouchController mPendingAnimation = null; } } - - @Override - public void dump(String prefix, PrintWriter writer) { } } diff --git a/src/com/android/launcher3/AbstractFloatingView.java b/src/com/android/launcher3/AbstractFloatingView.java index bd584996cc..d6f992f516 100644 --- a/src/com/android/launcher3/AbstractFloatingView.java +++ b/src/com/android/launcher3/AbstractFloatingView.java @@ -41,7 +41,6 @@ import com.android.launcher3.util.TouchController; import com.android.launcher3.views.ActivityContext; import com.android.launcher3.views.BaseDragLayer; -import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -252,7 +251,4 @@ public abstract class AbstractFloatingView extends LinearLayout implements Touch @FloatingViewType int type) { return getOpenView(activity, type); } - - @Override - public void dump(String prefix, PrintWriter writer) { } } diff --git a/src/com/android/launcher3/dragndrop/DragController.java b/src/com/android/launcher3/dragndrop/DragController.java index 5c3d4fbbf1..72107596a6 100644 --- a/src/com/android/launcher3/dragndrop/DragController.java +++ b/src/com/android/launcher3/dragndrop/DragController.java @@ -46,7 +46,6 @@ import com.android.launcher3.util.Thunk; import com.android.launcher3.util.TouchController; import com.android.launcher3.util.UiThreadHelper; -import java.io.PrintWriter; import java.util.ArrayList; /** @@ -697,8 +696,4 @@ public class DragController implements DragDriver.EventListener, TouchController public void removeDropTarget(DropTarget target) { mDropTargets.remove(target); } - - @Override - public void dump(String prefix, PrintWriter writer) { } - } diff --git a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java index 5f40dce9ce..0274de35cb 100644 --- a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java +++ b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java @@ -50,8 +50,6 @@ import com.android.launcher3.util.FlingBlockCheck; import com.android.launcher3.util.PendingAnimation; import com.android.launcher3.util.TouchController; -import java.io.PrintWriter; - /** * TouchController for handling state changes */ @@ -583,7 +581,4 @@ public abstract class AbstractStateChangeTouchController this.endTime = duration + SystemClock.elapsedRealtime(); } } - - @Override - public void dump(String prefix, PrintWriter writer) { } } diff --git a/src/com/android/launcher3/util/TouchController.java b/src/com/android/launcher3/util/TouchController.java index ac6a5bdcff..fc1d819f78 100644 --- a/src/com/android/launcher3/util/TouchController.java +++ b/src/com/android/launcher3/util/TouchController.java @@ -32,5 +32,5 @@ public interface TouchController { */ boolean onControllerInterceptTouchEvent(MotionEvent ev); - void dump(String prefix, PrintWriter writer); + default void dump(String prefix, PrintWriter writer) { } } From 90bddf0cf8dc2be8ca02a5bb528a51bd8aa1cf7a Mon Sep 17 00:00:00 2001 From: Kevin Date: Thu, 25 Apr 2019 17:16:53 -0700 Subject: [PATCH 12/17] Round thumbnail corners Round the task thumbnail corners as per the mocks by setting the bitmap as a shader. Bug: 114136250 Test: See rounded thumbnails on recents Go Change-Id: I2bf8ebce34deb0d1cb6199cf8f6d5fa6ac746bb8 --- .../res/drawable/default_thumbnail.xml | 2 +- go/quickstep/res/values/dimens.xml | 19 +++++++++++++++++++ .../android/quickstep/ThumbnailDrawable.java | 19 +++++++++++++++++-- .../android/quickstep/views/TaskItemView.java | 3 ++- 4 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 go/quickstep/res/values/dimens.xml diff --git a/go/quickstep/res/drawable/default_thumbnail.xml b/go/quickstep/res/drawable/default_thumbnail.xml index 0a2dbf03de..ab22dcf827 100644 --- a/go/quickstep/res/drawable/default_thumbnail.xml +++ b/go/quickstep/res/drawable/default_thumbnail.xml @@ -18,5 +18,5 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> - + diff --git a/go/quickstep/res/values/dimens.xml b/go/quickstep/res/values/dimens.xml new file mode 100644 index 0000000000..ee154fcafc --- /dev/null +++ b/go/quickstep/res/values/dimens.xml @@ -0,0 +1,19 @@ + + + + 3dp + \ No newline at end of file diff --git a/go/quickstep/src/com/android/quickstep/ThumbnailDrawable.java b/go/quickstep/src/com/android/quickstep/ThumbnailDrawable.java index 6ef9039f68..a8cc0a1b83 100644 --- a/go/quickstep/src/com/android/quickstep/ThumbnailDrawable.java +++ b/go/quickstep/src/com/android/quickstep/ThumbnailDrawable.java @@ -16,17 +16,23 @@ package com.android.quickstep; +import static android.graphics.Shader.TileMode.CLAMP; + +import android.content.res.Resources; import android.graphics.Bitmap; +import android.graphics.BitmapShader; import android.graphics.Canvas; import android.graphics.ColorFilter; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.PixelFormat; import android.graphics.Rect; +import android.graphics.RectF; import android.graphics.drawable.Drawable; import androidx.annotation.NonNull; +import com.android.launcher3.R; import com.android.systemui.shared.recents.model.ThumbnailData; /** @@ -39,11 +45,18 @@ public final class ThumbnailDrawable extends Drawable { private final Paint mPaint = new Paint(); private final Matrix mMatrix = new Matrix(); private final ThumbnailData mThumbnailData; + private final BitmapShader mShader; + private final RectF mDestRect = new RectF(); + private final int mCornerRadius; private int mRequestedOrientation; - public ThumbnailDrawable(@NonNull ThumbnailData thumbnailData, int requestedOrientation) { + public ThumbnailDrawable(Resources res, @NonNull ThumbnailData thumbnailData, + int requestedOrientation) { mThumbnailData = thumbnailData; mRequestedOrientation = requestedOrientation; + mCornerRadius = (int) res.getDimension(R.dimen.task_thumbnail_corner_radius); + mShader = new BitmapShader(mThumbnailData.thumbnail, CLAMP, CLAMP); + mPaint.setShader(mShader); updateMatrix(); } @@ -64,12 +77,13 @@ public final class ThumbnailDrawable extends Drawable { if (mThumbnailData.thumbnail == null) { return; } - canvas.drawBitmap(mThumbnailData.thumbnail, mMatrix, mPaint); + canvas.drawRoundRect(mDestRect, mCornerRadius, mCornerRadius, mPaint); } @Override protected void onBoundsChange(Rect bounds) { super.onBoundsChange(bounds); + mDestRect.set(bounds); updateMatrix(); } @@ -125,5 +139,6 @@ public final class ThumbnailDrawable extends Drawable { } // Scale to fill. mMatrix.postScale(scaleX, scaleY); + mShader.setLocalMatrix(mMatrix); } } diff --git a/go/quickstep/src/com/android/quickstep/views/TaskItemView.java b/go/quickstep/src/com/android/quickstep/views/TaskItemView.java index 0b5ed569c8..90192057be 100644 --- a/go/quickstep/src/com/android/quickstep/views/TaskItemView.java +++ b/go/quickstep/src/com/android/quickstep/views/TaskItemView.java @@ -177,7 +177,8 @@ public final class TaskItemView extends LinearLayout { return mDefaultThumbnail; } int orientation = getResources().getConfiguration().orientation; - return new ThumbnailDrawable(thumbnailData, orientation /* requestedOrientation */); + return new ThumbnailDrawable(getResources(), thumbnailData, + orientation /* requestedOrientation */); } private @NonNull String getSafeLabel(@Nullable String label) { From 55fa21eb9562820e885143ef52c5ce76b204e0e4 Mon Sep 17 00:00:00 2001 From: vadimt Date: Thu, 25 Apr 2019 17:29:05 -0700 Subject: [PATCH 13/17] Annotating DigitalWellBeingToastTest so that it actually runs in lab :) And starting a test app :))))) Change-Id: I3b326a40651b0e4293dee26e4ef5f991cd7b7d0d --- .../com/android/quickstep/DigitalWellBeingToastTest.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/quickstep/tests/src/com/android/quickstep/DigitalWellBeingToastTest.java b/quickstep/tests/src/com/android/quickstep/DigitalWellBeingToastTest.java index 87981571bd..70f9c90dad 100644 --- a/quickstep/tests/src/com/android/quickstep/DigitalWellBeingToastTest.java +++ b/quickstep/tests/src/com/android/quickstep/DigitalWellBeingToastTest.java @@ -12,21 +12,29 @@ import android.app.PendingIntent; import android.app.usage.UsageStatsManager; import android.content.Intent; +import androidx.test.filters.LargeTest; +import androidx.test.runner.AndroidJUnit4; + import com.android.launcher3.Launcher; import com.android.quickstep.views.DigitalWellBeingToast; import com.android.quickstep.views.RecentsView; import com.android.quickstep.views.TaskView; import org.junit.Test; +import org.junit.runner.RunWith; import java.time.Duration; +@LargeTest +@RunWith(AndroidJUnit4.class) public class DigitalWellBeingToastTest extends AbstractQuickStepTest { private static final String CALCULATOR_PACKAGE = resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR); @Test public void testToast() throws Exception { + startAppFast(CALCULATOR_PACKAGE); + final UsageStatsManager usageStatsManager = mTargetContext.getSystemService(UsageStatsManager.class); final int observerId = 0; From a4949471bed4c6fc8bcedb35a3bcc99df2d8e149 Mon Sep 17 00:00:00 2001 From: Kevin Date: Tue, 23 Apr 2019 15:00:41 -0700 Subject: [PATCH 14/17] Rotate thumbnail view based off device orientation In landscape mode, recents thumbnails should be shown horizontally, so this CL modifies the custom view so that it resizes to display a horizontal snapshot. Bug: 114136250 Bug: 131095241 Test: Rotate recents, see view width change appropriately Change-Id: Ic3d8d039535c673567d19c372da211d177691a81 --- .../quickstep/views/TaskThumbnailIconView.java | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/go/quickstep/src/com/android/quickstep/views/TaskThumbnailIconView.java b/go/quickstep/src/com/android/quickstep/views/TaskThumbnailIconView.java index b1c60dd978..0bad77b607 100644 --- a/go/quickstep/src/com/android/quickstep/views/TaskThumbnailIconView.java +++ b/go/quickstep/src/com/android/quickstep/views/TaskThumbnailIconView.java @@ -16,6 +16,9 @@ package com.android.quickstep.views; +import static android.content.res.Configuration.ORIENTATION_PORTRAIT; +import static android.view.View.MeasureSpec.makeMeasureSpec; + import android.content.Context; import android.graphics.Rect; import android.util.AttributeSet; @@ -53,15 +56,20 @@ final class TaskThumbnailIconView extends ViewGroup { int width = height; setMeasuredDimension(width, height); + int subItemSize = (int) (SUBITEM_FRAME_RATIO * height); if (mThumbnailView.getVisibility() != GONE) { - int thumbnailHeightSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY); - int thumbnailWidthSpec = MeasureSpec.makeMeasureSpec(subItemSize, MeasureSpec.EXACTLY); + boolean isPortrait = + (getResources().getConfiguration().orientation == ORIENTATION_PORTRAIT); + int thumbnailHeightSpec = + makeMeasureSpec(isPortrait ? height : subItemSize, MeasureSpec.EXACTLY); + int thumbnailWidthSpec = + makeMeasureSpec(isPortrait ? subItemSize : width, MeasureSpec.EXACTLY); measureChild(mThumbnailView, thumbnailWidthSpec, thumbnailHeightSpec); } if (mIconView.getVisibility() != GONE) { - int iconHeightSpec = MeasureSpec.makeMeasureSpec(subItemSize, MeasureSpec.EXACTLY); - int iconWidthSpec = MeasureSpec.makeMeasureSpec(subItemSize, MeasureSpec.EXACTLY); + int iconHeightSpec = makeMeasureSpec(subItemSize, MeasureSpec.EXACTLY); + int iconWidthSpec = makeMeasureSpec(subItemSize, MeasureSpec.EXACTLY); measureChild(mIconView, iconWidthSpec, iconHeightSpec); } } From dd4d390f38c42c01998498029e572745078b8c6a Mon Sep 17 00:00:00 2001 From: vadimt Date: Thu, 25 Apr 2019 17:53:26 -0700 Subject: [PATCH 15/17] Set portrait orientation for FallbackRecentsTest Bug: 131364673 Change-Id: I77f3058e09eadc5bcbfe48c768f78883082a526d --- .../tests/src/com/android/quickstep/FallbackRecentsTest.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java index f43683118f..20fdff2c55 100644 --- a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java +++ b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java @@ -32,6 +32,7 @@ import android.app.Instrumentation; import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; +import android.os.RemoteException; import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; @@ -65,10 +66,11 @@ public class FallbackRecentsTest { @Rule public final TestRule mSetLauncherCommand; - public FallbackRecentsTest() { + public FallbackRecentsTest() throws RemoteException { Instrumentation instrumentation = getInstrumentation(); Context context = instrumentation.getContext(); mDevice = UiDevice.getInstance(instrumentation); + mDevice.setOrientationNatural(); mLauncher = new LauncherInstrumentation(instrumentation); mQuickstepOnOffExecutor = new NavigationModeSwitchRule(mLauncher); From 572c746f747586d65e2b820af98c2f58e345b402 Mon Sep 17 00:00:00 2001 From: Hyunyoung Song Date: Sat, 13 Apr 2019 02:40:31 -0700 Subject: [PATCH 16/17] Night accent color Bug: 128857973 Change-Id: If81e9684143967480259a01e59694676875b0df1 --- res/values/styles.xml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/res/values/styles.xml b/res/values/styles.xml index 9b84cc9a34..7932c6d608 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -19,12 +19,13 @@ -