From d45a973781ee47ed87afe7178cacafbe4c84cc49 Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Tue, 28 May 2019 14:27:25 -0700 Subject: [PATCH 1/3] Merge branch 'ub-launcher3-qt-dev' into merge_5609112 Test: Manual Bug:112282235 P3 Starting an app from Launcher very rarely takes > 10 sec Bug:121279417 P2 Why LauncherInstrumentation.WAIT_TIME_MS == 60000? Bug:123900446 P1 App to home animation should zoom into the app icon Bug:131360075 P1 [Gesture Nav] Polish/finish landscape Bug:131854153 P1 Lots of Cuttlefish (and not only) tests are broken Bug:132687470 P1 Swiping home from forced landscape app creates cutoff task thumbnail Bug:132756514 P1 Sometimes (when quick switching?) user gets stuck in full-screen recents view Bug:132917885 P1 Reduce swipe-up gesture region height in landscape Bug:132975416 P1 Flake in NexusPredictionAppTracker.getAppPredictionContextExtras Bug:132993129 P1 If predictions disabled, app predictions loading bar appears briefly on device restart Change-Id: Ibfa1ed3ab6241fdb9412df2a80c11e83032008d9 (cherry picked from commit c3b21dd0480be4c64df6ac854ccb6d4923a992b2) --- Android.bp | 2 +- AndroidManifest-common.xml | 7 + OWNERS | 12 +- quickstep/AndroidManifest.xml | 8 -- .../res/layout/prediction_load_progress.xml | 11 -- .../appprediction/PredictionAppTracker.java | 2 +- .../appprediction/PredictionRowView.java | 25 +--- .../PredictionUiStateManager.java | 11 -- .../quickstep/TouchInteractionService.java | 14 +- .../WindowTransformSwipeHandler.java | 32 +++-- .../quickstep/fallback/RecentsRootView.java | 9 +- .../quickstep/util/RectFSpringAnim.java | 59 ++++---- quickstep/res/values/config.xml | 2 + .../QuickstepTestInformationHandler.java | 36 +++++ .../quickstep/TestInformationProvider.java | 127 ------------------ .../quickstep/util/MotionPauseDetector.java | 4 + quickstep/tests/OWNERS | 1 + .../quickstep/AppPredictionsUITests.java | 1 - .../android/quickstep/TaplTestsQuickstep.java | 2 +- res/values/config.xml | 1 + .../launcher3/BaseDraggingActivity.java | 9 +- src/com/android/launcher3/Launcher.java | 11 +- .../android/launcher3/LauncherRootView.java | 9 +- src/com/android/launcher3/LauncherState.java | 14 +- .../launcher3/LauncherStateManager.java | 9 +- src/com/android/launcher3/ResourceUtils.java | 5 +- src/com/android/launcher3/Workspace.java | 11 +- .../allapps/AllAppsContainerView.java | 14 +- .../allapps/AllAppsRecyclerView.java | 2 +- .../compat/AccessibilityManagerCompat.java | 9 +- .../android/launcher3/config/BaseFlags.java | 2 +- .../launcher3/dragndrop/DragController.java | 13 +- .../android/launcher3/dragndrop/DragView.java | 4 +- .../launcher3/states/RotationHelper.java | 14 ++ .../testing/TestInformationHandler.java | 83 ++++++++++++ .../testing/TestInformationProvider.java | 67 +++++++++ .../launcher3/{ => testing}/TestProtocol.java | 3 +- .../launcher3/touch/ItemClickHandler.java | 21 +-- .../launcher3/views/BaseDragLayer.java | 13 +- .../launcher3/views/FloatingIconView.java | 6 +- tests/Android.mk | 2 +- tests/AndroidManifest-common.xml | 8 ++ tests/OWNERS | 1 + .../launcher3/ui/AbstractLauncherUiTest.java | 11 +- .../com/android/launcher3/tapl/AllApps.java | 4 +- .../launcher3/tapl/AllAppsFromOverview.java | 4 +- .../android/launcher3/tapl/Background.java | 19 ++- .../tapl/com/android/launcher3/tapl/Home.java | 2 +- .../android/launcher3/tapl/Launchable.java | 5 +- .../tapl/LauncherInstrumentation.java | 56 +++++--- .../com/android/launcher3/tapl/Overview.java | 7 +- .../com/android/launcher3/tapl/Widgets.java | 2 +- .../com/android/launcher3/tapl/Workspace.java | 4 +- 53 files changed, 450 insertions(+), 360 deletions(-) delete mode 100644 quickstep/recents_ui_overrides/res/layout/prediction_load_progress.xml create mode 100644 quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java delete mode 100644 quickstep/src/com/android/quickstep/TestInformationProvider.java create mode 100644 quickstep/tests/OWNERS create mode 100644 src/com/android/launcher3/testing/TestInformationHandler.java create mode 100644 src/com/android/launcher3/testing/TestInformationProvider.java rename src/com/android/launcher3/{ => testing}/TestProtocol.java (96%) create mode 100644 tests/OWNERS diff --git a/Android.bp b/Android.bp index b80282eb54..4c38205979 100644 --- a/Android.bp +++ b/Android.bp @@ -25,7 +25,7 @@ android_library { "tests/tapl/**/*.java", "src/com/android/launcher3/util/SecureSettingsObserver.java", "src/com/android/launcher3/ResourceUtils.java", - "src/com/android/launcher3/TestProtocol.java", + "src/com/android/launcher3/testing/TestProtocol.java", ], manifest: "tests/tapl/AndroidManifest.xml", platform_apis: true, diff --git a/AndroidManifest-common.xml b/AndroidManifest-common.xml index ef5bb2672f..5318a12edd 100644 --- a/AndroidManifest-common.xml +++ b/AndroidManifest-common.xml @@ -176,5 +176,12 @@ + diff --git a/OWNERS b/OWNERS index 98dfb8a72c..8b3df48b2f 100644 --- a/OWNERS +++ b/OWNERS @@ -2,13 +2,11 @@ # gnl-eng@google.com (Googlers only) # People who can approve changes for submission +# + adamcohen@google.com hyunyoungs@google.com +mrcasey@google.com sunnygoyal@google.com -winsonc@google.com - -# Source of truth of this directory is actually in launcher team's -# unbundled branch ub-launcher3-[release variant] (e.g., master, edmonton). -# Pls try to wait for one of the owner's review if you have to force -# submit (e.g., for large refactor, breakage, etc) as we may want to -# cherry pick the change to our active developmental branch. +twickham@google.com +winsonc@google.com \ No newline at end of file diff --git a/quickstep/AndroidManifest.xml b/quickstep/AndroidManifest.xml index be275e0e8a..a38979d41d 100644 --- a/quickstep/AndroidManifest.xml +++ b/quickstep/AndroidManifest.xml @@ -73,14 +73,6 @@ - - - diff --git a/quickstep/recents_ui_overrides/res/layout/prediction_load_progress.xml b/quickstep/recents_ui_overrides/res/layout/prediction_load_progress.xml deleted file mode 100644 index 20c400441a..0000000000 --- a/quickstep/recents_ui_overrides/res/layout/prediction_load_progress.xml +++ /dev/null @@ -1,11 +0,0 @@ - - diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionAppTracker.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionAppTracker.java index af67e1bbbc..8f1282dedc 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionAppTracker.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionAppTracker.java @@ -56,7 +56,7 @@ public class PredictionAppTracker extends AppLaunchTracker { private static final int MSG_LAUNCH = 2; private static final int MSG_PREDICT = 3; - private final Context mContext; + protected final Context mContext; private final Handler mMessageHandler; // Accessed only on worker thread diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionRowView.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionRowView.java index 55f4c98e9a..4a486f8e5c 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionRowView.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionRowView.java @@ -28,7 +28,6 @@ import android.os.Build; import android.util.AttributeSet; import android.util.IntProperty; import android.util.Log; -import android.view.LayoutInflater; import android.view.View; import android.view.animation.Interpolator; import android.widget.LinearLayout; @@ -115,8 +114,6 @@ public class PredictionRowView extends LinearLayout implements private final AnimatedFloat mOverviewScrollFactor = new AnimatedFloat(this::updateTranslationAndAlpha); - private View mLoadingProgress; - private boolean mPredictionsEnabled = false; public PredictionRowView(@NonNull Context context) { @@ -165,7 +162,6 @@ public class PredictionRowView extends LinearLayout implements public void setup(FloatingHeaderView parent, FloatingHeaderRow[] rows, boolean tabsHidden) { mParent = parent; - setPredictionsEnabled(mPredictionUiStateManager.arePredictionsEnabled()); } private void setPredictionsEnabled(boolean predictionsEnabled) { @@ -205,7 +201,7 @@ public class PredictionRowView extends LinearLayout implements @Override public boolean hasVisibleContent() { - return mPredictionUiStateManager.arePredictionsEnabled(); + return mPredictionsEnabled; } /** @@ -241,9 +237,6 @@ public class PredictionRowView extends LinearLayout implements } private void applyPredictionApps() { - if (mLoadingProgress != null) { - removeView(mLoadingProgress); - } if (!mPredictionsEnabled) { mParent.onHeightUpdated(); return; @@ -290,15 +283,8 @@ public class PredictionRowView extends LinearLayout implements } if (predictionCount == 0) { - if (mLoadingProgress == null) { - mLoadingProgress = LayoutInflater.from(getContext()) - .inflate(R.layout.prediction_load_progress, this, false); - } - addView(mLoadingProgress); - } else { - mLoadingProgress = null; + setPredictionsEnabled(false); } - mParent.onHeightUpdated(); } @@ -342,11 +328,8 @@ public class PredictionRowView extends LinearLayout implements public void setTextAlpha(int alpha) { mIconCurrentTextAlpha = alpha; int iconColor = setColorAlphaBound(mIconTextColor, mIconCurrentTextAlpha); - - if (mLoadingProgress == null) { - for (int i = 0; i < getChildCount(); i++) { - ((BubbleTextView) getChildAt(i)).setTextColor(iconColor); - } + for (int i = 0; i < getChildCount(); i++) { + ((BubbleTextView) getChildAt(i)).setTextColor(iconColor); } } diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionUiStateManager.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionUiStateManager.java index 6dad9afe57..64cb4b465f 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionUiStateManager.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionUiStateManager.java @@ -24,7 +24,6 @@ import android.app.prediction.AppPredictor; import android.app.prediction.AppTarget; import android.content.ComponentName; import android.content.Context; -import android.os.Handler; import android.view.ViewTreeObserver.OnGlobalLayoutListener; import com.android.launcher3.AppInfo; @@ -63,7 +62,6 @@ public class PredictionUiStateManager implements OnGlobalLayoutListener, ItemInf OnIDPChangeListener, OnUpdateListener { public static final String LAST_PREDICTION_ENABLED_STATE = "last_prediction_enabled_state"; - private static final long INITIAL_CALLBACK_WAIT_TIMEOUT_MS = 5000; // TODO (b/129421797): Update the client constants public enum Client { @@ -110,13 +108,8 @@ public class PredictionUiStateManager implements OnGlobalLayoutListener, ItemInf for (int i = 0; i < mPredictionServicePredictions.length; i++) { mPredictionServicePredictions[i] = Collections.emptyList(); } - mGettingValidPredictionResults = Utilities.getDevicePrefs(context) .getBoolean(LAST_PREDICTION_ENABLED_STATE, true); - if (mGettingValidPredictionResults) { - new Handler().postDelayed( - this::updatePredictionStateAfterCallback, INITIAL_CALLBACK_WAIT_TIMEOUT_MS); - } // Call this last mCurrentState = parseLastState(); @@ -293,10 +286,6 @@ public class PredictionUiStateManager implements OnGlobalLayoutListener, ItemInf dispatchOnChange(false); } - public boolean arePredictionsEnabled() { - return mCurrentState.isEnabled; - } - private boolean canApplyPredictions(PredictionState newState) { if (mAppsView == null) { // If there is no apps view, no need to schedule. diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java index 0c997dd598..6ba1bf5c55 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java @@ -331,16 +331,8 @@ public class TouchInteractionService extends Service implements defaultDisplay.getRealSize(realSize); mSwipeTouchRegion.set(0, 0, realSize.x, realSize.y); if (mMode == Mode.NO_BUTTON) { - switch (defaultDisplay.getRotation()) { - case Surface.ROTATION_90: - case Surface.ROTATION_270: - mSwipeTouchRegion.top = mSwipeTouchRegion.bottom - getNavbarSize( - ResourceUtils.NAVBAR_LANDSCAPE_BOTTOM_SIZE); - break; - default: - mSwipeTouchRegion.top = mSwipeTouchRegion.bottom - getNavbarSize( - ResourceUtils.NAVBAR_PORTRAIT_BOTTOM_SIZE); - } + mSwipeTouchRegion.top = mSwipeTouchRegion.bottom - + getNavbarSize(ResourceUtils.NAVBAR_BOTTOM_GESTURE_SIZE); } else { switch (defaultDisplay.getRotation()) { case Surface.ROTATION_90: @@ -353,7 +345,7 @@ public class TouchInteractionService extends Service implements break; default: mSwipeTouchRegion.top = mSwipeTouchRegion.bottom - - getNavbarSize(ResourceUtils.NAVBAR_PORTRAIT_BOTTOM_SIZE); + - getNavbarSize(ResourceUtils.NAVBAR_BOTTOM_GESTURE_SIZE); } } } 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 2ff5c0c6a5..ffef1cf325 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java @@ -170,7 +170,8 @@ public class WindowTransformSwipeHandler STATE_LAUNCHER_PRESENT | STATE_LAUNCHER_DRAWN | STATE_LAUNCHER_STARTED; public enum GestureEndTarget { - HOME(1, STATE_SCALED_CONTROLLER_HOME, true, false, ContainerType.WORKSPACE, false), + HOME(1, STATE_SCALED_CONTROLLER_HOME | STATE_CAPTURE_SCREENSHOT, true, false, + ContainerType.WORKSPACE, false), RECENTS(1, STATE_SCALED_CONTROLLER_RECENTS | STATE_CAPTURE_SCREENSHOT | STATE_SCREENSHOT_VIEW_SHOWN, true, false, ContainerType.TASKSWITCHER, true), @@ -331,9 +332,8 @@ public class WindowTransformSwipeHandler | STATE_SCALED_CONTROLLER_RECENTS, this::finishCurrentTransitionToRecents); - mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_GESTURE_COMPLETED - | STATE_SCALED_CONTROLLER_HOME | STATE_APP_CONTROLLER_RECEIVED - | STATE_LAUNCHER_DRAWN, + mStateCallback.addCallback(STATE_SCREENSHOT_CAPTURED | STATE_GESTURE_COMPLETED + | STATE_SCALED_CONTROLLER_HOME, this::finishCurrentTransitionToHome); mStateCallback.addCallback(STATE_SCALED_CONTROLLER_HOME | STATE_CURRENT_TASK_FINISHED, this::reset); @@ -936,8 +936,10 @@ public class WindowTransformSwipeHandler } else if (endTarget == RECENTS) { mLiveTileOverlay.startIconAnimation(); if (mRecentsView != null) { - duration = Utilities.boundToRange(mRecentsView.getScroller().getDuration(), - duration, MAX_SWIPE_DURATION); + if (mRecentsView.getScroller().getDuration() > MAX_SWIPE_DURATION) { + mRecentsView.snapToPage(mRecentsView.getNextPage(), (int) MAX_SWIPE_DURATION); + } + duration = Math.max(duration, mRecentsView.getScroller().getDuration()); } if (mMode == Mode.NO_BUTTON) { setShelfState(ShelfAnimState.OVERVIEW, interpolator, duration); @@ -1251,8 +1253,15 @@ public class WindowTransformSwipeHandler if (mTaskSnapshot == null) { mTaskSnapshot = controller.screenshotTask(mRunningTaskId); } - TaskView taskView = mRecentsView.updateThumbnail(mRunningTaskId, mTaskSnapshot); - if (taskView != null) { + final TaskView taskView; + if (mGestureEndTarget == HOME) { + // Capture the screenshot before finishing the transition to home to ensure it's + // taken in the correct orientation, but no need to update the thumbnail. + taskView = null; + } else { + taskView = mRecentsView.updateThumbnail(mRunningTaskId, mTaskSnapshot); + } + if (taskView != null && !mCanceled) { // Defer finishing the animation until the next launcher frame with the // new thumbnail finishTransitionPosted = new WindowCallbacksCompat(taskView) { @@ -1262,6 +1271,13 @@ public class WindowTransformSwipeHandler @Override public void onPostDraw(Canvas canvas) { + // If we were cancelled after this was attached, do not update + // the state. + if (mCanceled) { + detach(); + return; + } + if (mDeferFrameCount > 0) { mDeferFrameCount--; // Workaround, detach and reattach to invalidate the root node for diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/RecentsRootView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/RecentsRootView.java index 09d323ee69..1820729576 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/RecentsRootView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/RecentsRootView.java @@ -20,7 +20,6 @@ import android.content.Context; import android.graphics.Point; import android.graphics.Rect; import android.util.AttributeSet; -import android.view.WindowInsets; import com.android.launcher3.BaseActivity; import com.android.launcher3.R; @@ -71,7 +70,7 @@ public class RecentsRootView extends BaseDragLayer { // Update device profile before notifying the children. mActivity.getDeviceProfile().updateInsets(insets); setInsets(insets); - return true; // I'll take it from here + return false; // Let children get the full insets } @Override @@ -89,10 +88,4 @@ public class RecentsRootView extends BaseDragLayer { mActivity.getDeviceProfile().updateInsets(mInsets); super.setInsets(mInsets); } - - @Override - public WindowInsets dispatchApplyWindowInsets(WindowInsets insets) { - updateTouchExcludeRegion(insets); - return super.dispatchApplyWindowInsets(insets); - } } \ No newline at end of file diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java index 3f4ad58ab8..77dc6f32e7 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java @@ -16,26 +16,22 @@ package com.android.quickstep.util; import android.animation.Animator; -import android.animation.ObjectAnimator; -import android.animation.PropertyValuesHolder; -import android.animation.ValueAnimator; import android.content.res.Resources; import android.graphics.PointF; import android.graphics.RectF; -import android.util.FloatProperty; import androidx.dynamicanimation.animation.DynamicAnimation.OnAnimationEndListener; import androidx.dynamicanimation.animation.FloatPropertyCompat; +import androidx.dynamicanimation.animation.SpringAnimation; +import androidx.dynamicanimation.animation.SpringForce; import com.android.launcher3.R; import com.android.launcher3.Utilities; -import com.android.launcher3.anim.AnimationSuccessListener; import com.android.launcher3.anim.FlingSpringAnim; import java.util.ArrayList; import java.util.List; -import static com.android.launcher3.anim.Interpolators.DEACCEL; /** * Applies spring forces to animate from a starting rect to a target rect, @@ -43,14 +39,6 @@ import static com.android.launcher3.anim.Interpolators.DEACCEL; */ public class RectFSpringAnim { - /** - * Although the rect position animation takes an indefinite amount of time since it depends on - * the initial velocity and applied forces, scaling from the starting rect to the target rect - * can be done in parallel at a fixed duration. Update callbacks are sent based on the progress - * of this animation, while the end callback is sent after all animations finish. - */ - private static final long RECT_SCALE_DURATION = 250; - private static final FloatPropertyCompat RECT_CENTER_X = new FloatPropertyCompat("rectCenterXSpring") { @Override @@ -79,17 +67,17 @@ public class RectFSpringAnim { } }; - private static final FloatProperty RECT_SCALE_PROGRESS = - new FloatProperty("rectScaleProgress") { + private static final FloatPropertyCompat RECT_SCALE_PROGRESS = + new FloatPropertyCompat("rectScaleProgress") { @Override - public Float get(RectFSpringAnim anim) { - return anim.mCurrentScaleProgress; + public float getValue(RectFSpringAnim object) { + return object.mCurrentScaleProgress; } @Override - public void setValue(RectFSpringAnim anim, float currentScaleProgress) { - anim.mCurrentScaleProgress = currentScaleProgress; - anim.onUpdate(); + public void setValue(RectFSpringAnim object, float value) { + object.mCurrentScaleProgress = value; + object.onUpdate(); } }; @@ -106,7 +94,7 @@ public class RectFSpringAnim { private float mCurrentScaleProgress; private FlingSpringAnim mRectXAnim; private FlingSpringAnim mRectYAnim; - private ValueAnimator mRectScaleAnim; + private SpringAnimation mRectScaleAnim; private boolean mAnimsStarted; private boolean mRectXAnimEnded; private boolean mRectYAnimEnded; @@ -177,17 +165,18 @@ public class RectFSpringAnim { mRectYAnim = new FlingSpringAnim(this, RECT_Y, startY, endY, startVelocityY, mMinVisChange, minYValue, maxYValue, springVelocityFactor, onYEndListener); - mRectScaleAnim = ObjectAnimator.ofPropertyValuesHolder(this, - PropertyValuesHolder.ofFloat(RECT_SCALE_PROGRESS, 1)) - .setDuration(RECT_SCALE_DURATION); - mRectScaleAnim.setInterpolator(DEACCEL); - mRectScaleAnim.addListener(new AnimationSuccessListener() { - @Override - public void onAnimationSuccess(Animator animator) { - mRectScaleAnimEnded = true; - maybeOnEnd(); - } - }); + float minVisibleChange = 1f / mStartRect.height(); + mRectScaleAnim = new SpringAnimation(this, RECT_SCALE_PROGRESS) + .setSpring(new SpringForce(1f) + .setDampingRatio(SpringForce.DAMPING_RATIO_LOW_BOUNCY) + .setStiffness(SpringForce.STIFFNESS_LOW)) + .setStartVelocity(velocityPxPerMs.y * minVisibleChange) + .setMaxValue(1f) + .setMinimumVisibleChange(minVisibleChange) + .addEndListener((animation, canceled, value, velocity) -> { + mRectScaleAnimEnded = true; + maybeOnEnd(); + }); mRectXAnim.start(); mRectYAnim.start(); @@ -202,7 +191,9 @@ public class RectFSpringAnim { if (mAnimsStarted) { mRectXAnim.end(); mRectYAnim.end(); - mRectScaleAnim.end(); + if (mRectScaleAnim.canSkipToEnd()) { + mRectScaleAnim.skipToEnd(); + } } } diff --git a/quickstep/res/values/config.xml b/quickstep/res/values/config.xml index e84543b378..5c4d6d869f 100644 --- a/quickstep/res/values/config.xml +++ b/quickstep/res/values/config.xml @@ -25,6 +25,8 @@ com.android.quickstep.logging.StatsLogCompatManager + com.android.quickstep.QuickstepTestInformationHandler + 3 diff --git a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java new file mode 100644 index 0000000000..89513634fe --- /dev/null +++ b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java @@ -0,0 +1,36 @@ +package com.android.quickstep; + +import android.content.Context; +import android.os.Bundle; + +import com.android.launcher3.testing.TestInformationHandler; +import com.android.launcher3.testing.TestProtocol; +import com.android.launcher3.uioverrides.states.OverviewState; +import com.android.quickstep.util.LayoutUtils; + +public class QuickstepTestInformationHandler extends TestInformationHandler { + + public QuickstepTestInformationHandler(Context context) { } + + @Override + public Bundle call(String method) { + final Bundle response = new Bundle(); + switch (method) { + case TestProtocol.REQUEST_HOME_TO_OVERVIEW_SWIPE_HEIGHT: { + final float swipeHeight = + OverviewState.getDefaultSwipeHeight(mDeviceProfile); + response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, (int) swipeHeight); + return response; + } + + case TestProtocol.REQUEST_BACKGROUND_TO_OVERVIEW_SWIPE_HEIGHT: { + final float swipeHeight = + LayoutUtils.getShelfTrackingDistance(mContext, mDeviceProfile); + response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, (int) swipeHeight); + return response; + } + } + + return super.call(method); + } +} diff --git a/quickstep/src/com/android/quickstep/TestInformationProvider.java b/quickstep/src/com/android/quickstep/TestInformationProvider.java deleted file mode 100644 index d96f9af6fe..0000000000 --- a/quickstep/src/com/android/quickstep/TestInformationProvider.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (C) 2019 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; - -import android.content.ContentProvider; -import android.content.ContentValues; -import android.content.Context; -import android.database.Cursor; -import android.net.Uri; -import android.os.Bundle; - -import com.android.launcher3.DeviceProfile; -import com.android.launcher3.InvariantDeviceProfile; -import com.android.launcher3.Launcher; -import com.android.launcher3.LauncherAppState; -import com.android.launcher3.LauncherState; -import com.android.launcher3.TestProtocol; -import com.android.launcher3.Utilities; -import com.android.launcher3.uioverrides.states.OverviewState; -import com.android.quickstep.util.LayoutUtils; - -public class TestInformationProvider extends ContentProvider { - @Override - public boolean onCreate() { - return true; - } - - @Override - public int update(Uri uri, ContentValues contentValues, String s, String[] strings) { - return 0; - } - - @Override - public int delete(Uri uri, String s, String[] strings) { - return 0; - } - - @Override - public Uri insert(Uri uri, ContentValues contentValues) { - return null; - } - - @Override - public String getType(Uri uri) { - return null; - } - - @Override - public Cursor query(Uri uri, String[] strings, String s, String[] strings1, String s1) { - return null; - } - - @Override - public Bundle call(String method, String arg, Bundle extras) { - if (Utilities.IS_RUNNING_IN_TEST_HARNESS) { - final Bundle response = new Bundle(); - final Context context = getContext(); - final DeviceProfile deviceProfile = InvariantDeviceProfile.INSTANCE. - get(context).getDeviceProfile(context); - final LauncherAppState launcherAppState = LauncherAppState.getInstanceNoCreate(); - final Launcher launcher = launcherAppState != null ? - (Launcher) launcherAppState.getModel().getCallback() : null; - - switch (method) { - case TestProtocol.REQUEST_HOME_TO_OVERVIEW_SWIPE_HEIGHT: { - final float swipeHeight = - OverviewState.getDefaultSwipeHeight(deviceProfile); - response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, (int) swipeHeight); - break; - } - - case TestProtocol.REQUEST_BACKGROUND_TO_OVERVIEW_SWIPE_HEIGHT: { - final float swipeHeight = - LayoutUtils.getShelfTrackingDistance(context, deviceProfile); - response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, (int) swipeHeight); - break; - } - - case TestProtocol.REQUEST_ALL_APPS_TO_OVERVIEW_SWIPE_HEIGHT: { - if (launcher == null) return null; - - final float progress = LauncherState.OVERVIEW.getVerticalProgress(launcher) - - LauncherState.ALL_APPS.getVerticalProgress(launcher); - final float distance = - launcher.getAllAppsController().getShiftRange() * progress; - response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, (int) distance); - break; - } - - case TestProtocol.REQUEST_HOME_TO_ALL_APPS_SWIPE_HEIGHT: { - if (launcher == null) return null; - - final float progress = LauncherState.NORMAL.getVerticalProgress(launcher) - - LauncherState.ALL_APPS.getVerticalProgress(launcher); - final float distance = - launcher.getAllAppsController().getShiftRange() * progress; - response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, (int) distance); - break; - } - - case TestProtocol.REQUEST_ENABLE_DEBUG_TRACING: - TestProtocol.sDebugTracing = true; - break; - - case TestProtocol.REQUEST_DISABLE_DEBUG_TRACING: - TestProtocol.sDebugTracing = false; - break; - } - return response; - } - return null; - } -} diff --git a/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java b/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java index 893c053565..801a5604f5 100644 --- a/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java +++ b/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java @@ -21,6 +21,7 @@ import android.view.MotionEvent; import com.android.launcher3.Alarm; import com.android.launcher3.R; +import com.android.launcher3.compat.AccessibilityManagerCompat; /** * Given positions along x- or y-axis, tracks velocity and acceleration and determines when there is @@ -47,6 +48,7 @@ public class MotionPauseDetector { private final float mSpeedFast; private final Alarm mForcePauseTimeout; private final boolean mMakePauseHarderToTrigger; + private final Context mContext; private Long mPreviousTime = null; private Float mPreviousPosition = null; @@ -71,6 +73,7 @@ public class MotionPauseDetector { * @param makePauseHarderToTrigger Used for gestures that require a more explicit pause. */ public MotionPauseDetector(Context context, boolean makePauseHarderToTrigger) { + mContext = context; Resources res = context.getResources(); mSpeedVerySlow = res.getDimension(R.dimen.motion_pause_detector_speed_very_slow); mSpeedSlow = res.getDimension(R.dimen.motion_pause_detector_speed_slow); @@ -165,6 +168,7 @@ public class MotionPauseDetector { if (mIsPaused != isPaused) { mIsPaused = isPaused; if (mIsPaused) { + AccessibilityManagerCompat.sendPauseDetectedEventToTest(mContext); mHasEverBeenPaused = true; } if (mOnMotionPauseListener != null) { diff --git a/quickstep/tests/OWNERS b/quickstep/tests/OWNERS new file mode 100644 index 0000000000..046d871163 --- /dev/null +++ b/quickstep/tests/OWNERS @@ -0,0 +1 @@ +vadimt@google.com diff --git a/quickstep/tests/src/com/android/quickstep/AppPredictionsUITests.java b/quickstep/tests/src/com/android/quickstep/AppPredictionsUITests.java index 5e20e5643c..d9fcf4d97a 100644 --- a/quickstep/tests/src/com/android/quickstep/AppPredictionsUITests.java +++ b/quickstep/tests/src/com/android/quickstep/AppPredictionsUITests.java @@ -68,7 +68,6 @@ public class AppPredictionsUITests extends AbstractQuickStepTest { // Disable app tracker AppLaunchTracker.INSTANCE.initializeForTesting(new AppLaunchTracker()); - PredictionUiStateManager.INSTANCE.initializeForTesting(null); mCallback = PredictionUiStateManager.INSTANCE.get(mTargetContext).appPredictorCallback( diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java index 43d6311843..f02859f462 100644 --- a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java +++ b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java @@ -127,7 +127,7 @@ public class TaplTestsQuickstep extends AbstractQuickStepTest { assertNotNull("OverviewTask.open returned null", task.open()); assertTrue("Test activity didn't open from Overview", mDevice.wait(Until.hasObject( By.pkg(getAppPackageName()).text("TestActivity2")), - LONG_WAIT_TIME_MS)); + DEFAULT_UI_TIMEOUT)); executeOnLauncher(launcher -> assertTrue( "Launcher activity is the top activity; expecting another activity to be the top " + "one", diff --git a/res/values/config.xml b/res/values/config.xml index 984729b20f..638a411be6 100644 --- a/res/values/config.xml +++ b/res/values/config.xml @@ -71,6 +71,7 @@ + diff --git a/src/com/android/launcher3/BaseDraggingActivity.java b/src/com/android/launcher3/BaseDraggingActivity.java index bd6ac90f39..f69b172480 100644 --- a/src/com/android/launcher3/BaseDraggingActivity.java +++ b/src/com/android/launcher3/BaseDraggingActivity.java @@ -34,6 +34,7 @@ import com.android.launcher3.LauncherSettings.Favorites; import com.android.launcher3.compat.LauncherAppsCompat; import com.android.launcher3.model.AppLaunchTracker; import com.android.launcher3.shortcuts.DeepShortcutManager; +import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.uioverrides.DisplayRotationListener; import com.android.launcher3.uioverrides.WallpaperColorInfo; import com.android.launcher3.util.Themes; @@ -134,8 +135,8 @@ public abstract class BaseDraggingActivity extends BaseActivity public boolean startActivitySafely(View v, Intent intent, @Nullable ItemInfo item, @Nullable String sourceContainer) { - if (com.android.launcher3.TestProtocol.sDebugTracing) { - android.util.Log.d(com.android.launcher3.TestProtocol.NO_START_TAG, + if (TestProtocol.sDebugTracing) { + android.util.Log.d(TestProtocol.NO_START_TAG, "startActivitySafely 1"); } if (mIsSafeModeEnabled && !Utilities.isSystemApp(this, intent)) { @@ -161,8 +162,8 @@ public abstract class BaseDraggingActivity extends BaseActivity startShortcutIntentSafely(intent, optsBundle, item, sourceContainer); } else if (user == null || user.equals(Process.myUserHandle())) { // Could be launching some bookkeeping activity - if (com.android.launcher3.TestProtocol.sDebugTracing) { - android.util.Log.d(com.android.launcher3.TestProtocol.NO_START_TAG, + if (TestProtocol.sDebugTracing) { + android.util.Log.d(TestProtocol.NO_START_TAG, "startActivitySafely 2"); } startActivity(intent, optsBundle); diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index a59189beaa..711cfd2885 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -29,6 +29,7 @@ import static com.android.launcher3.LauncherState.OVERVIEW_PEEK; import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_LAUNCHER_LOAD; import static com.android.launcher3.logging.LoggerUtils.newContainerTarget; import static com.android.launcher3.logging.LoggerUtils.newTarget; +import static com.android.launcher3.states.RotationHelper.REQUEST_NONE; import static com.android.launcher3.util.RaceConditionTracker.ENTER; import static com.android.launcher3.util.RaceConditionTracker.EXIT; @@ -76,8 +77,6 @@ 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; @@ -110,6 +109,7 @@ import com.android.launcher3.popup.PopupDataProvider; import com.android.launcher3.shortcuts.DeepShortcutManager; import com.android.launcher3.states.InternalStateHandler; import com.android.launcher3.states.RotationHelper; +import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.touch.ItemClickHandler; import com.android.launcher3.uioverrides.UiFactory; import com.android.launcher3.userevent.nano.LauncherLogProto; @@ -154,6 +154,8 @@ import java.util.HashSet; import java.util.List; import java.util.function.Predicate; +import androidx.annotation.Nullable; + /** * Default launcher application. */ @@ -406,6 +408,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, super.onEnterAnimationComplete(); UiFactory.onEnterAnimationComplete(this); mAllAppsController.highlightWorkTabIfNecessary(); + mRotationHelper.setCurrentTransitionRequest(REQUEST_NONE); } @Override @@ -1782,8 +1785,8 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, public boolean startActivitySafely(View v, Intent intent, ItemInfo item, @Nullable String sourceContainer) { - if (com.android.launcher3.TestProtocol.sDebugTracing) { - android.util.Log.d(com.android.launcher3.TestProtocol.NO_START_TAG, + if (TestProtocol.sDebugTracing) { + android.util.Log.d(TestProtocol.NO_START_TAG, "startActivitySafely outer"); } boolean success = super.startActivitySafely(v, intent, item, sourceContainer); diff --git a/src/com/android/launcher3/LauncherRootView.java b/src/com/android/launcher3/LauncherRootView.java index 20eec05d44..49b380b41f 100644 --- a/src/com/android/launcher3/LauncherRootView.java +++ b/src/com/android/launcher3/LauncherRootView.java @@ -14,7 +14,6 @@ import android.os.Build; import android.util.AttributeSet; import android.view.View; import android.view.ViewDebug; -import android.view.WindowInsets; import java.util.Collections; import java.util.List; @@ -101,7 +100,7 @@ public class LauncherRootView extends InsettableFrameLayout { mLauncher.getStateManager().reapplyState(true /* cancelCurrentAnimation */); } - return true; // I'll take it from here + return false; // Let children get the full insets } @Override @@ -156,12 +155,6 @@ public class LauncherRootView extends InsettableFrameLayout { } } - @Override - public WindowInsets dispatchApplyWindowInsets(WindowInsets insets) { - mLauncher.getDragLayer().updateTouchExcludeRegion(insets); - return super.dispatchApplyWindowInsets(insets); - } - @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); diff --git a/src/com/android/launcher3/LauncherState.java b/src/com/android/launcher3/LauncherState.java index eff58a7013..3a92dfb961 100644 --- a/src/com/android/launcher3/LauncherState.java +++ b/src/com/android/launcher3/LauncherState.java @@ -18,13 +18,13 @@ package com.android.launcher3; import static android.view.View.IMPORTANT_FOR_ACCESSIBILITY_AUTO; import static android.view.View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS; import static android.view.accessibility.AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED; -import static com.android.launcher3.TestProtocol.ALL_APPS_STATE_ORDINAL; -import static com.android.launcher3.TestProtocol.BACKGROUND_APP_STATE_ORDINAL; -import static com.android.launcher3.TestProtocol.NORMAL_STATE_ORDINAL; -import static com.android.launcher3.TestProtocol.OVERVIEW_PEEK_STATE_ORDINAL; -import static com.android.launcher3.TestProtocol.OVERVIEW_STATE_ORDINAL; -import static com.android.launcher3.TestProtocol.QUICK_SWITCH_STATE_ORDINAL; -import static com.android.launcher3.TestProtocol.SPRING_LOADED_STATE_ORDINAL; +import static com.android.launcher3.testing.TestProtocol.ALL_APPS_STATE_ORDINAL; +import static com.android.launcher3.testing.TestProtocol.BACKGROUND_APP_STATE_ORDINAL; +import static com.android.launcher3.testing.TestProtocol.NORMAL_STATE_ORDINAL; +import static com.android.launcher3.testing.TestProtocol.OVERVIEW_PEEK_STATE_ORDINAL; +import static com.android.launcher3.testing.TestProtocol.OVERVIEW_STATE_ORDINAL; +import static com.android.launcher3.testing.TestProtocol.QUICK_SWITCH_STATE_ORDINAL; +import static com.android.launcher3.testing.TestProtocol.SPRING_LOADED_STATE_ORDINAL; import static com.android.launcher3.anim.Interpolators.ACCEL_2; import static com.android.launcher3.states.RotationHelper.REQUEST_NONE; diff --git a/src/com/android/launcher3/LauncherStateManager.java b/src/com/android/launcher3/LauncherStateManager.java index 49ae33894a..3edd8385ab 100644 --- a/src/com/android/launcher3/LauncherStateManager.java +++ b/src/com/android/launcher3/LauncherStateManager.java @@ -48,6 +48,7 @@ import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.AnimatorSetBuilder; import com.android.launcher3.anim.PropertySetter; import com.android.launcher3.anim.PropertySetter.AnimatedPropertySetter; +import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.uioverrides.UiFactory; import java.io.PrintWriter; @@ -447,8 +448,8 @@ public class LauncherStateManager { } private void onStateTransitionStart(LauncherState state) { - if (com.android.launcher3.TestProtocol.sDebugTracing) { - android.util.Log.d(com.android.launcher3.TestProtocol.NO_DRAG_TAG, + if (TestProtocol.sDebugTracing) { + android.util.Log.d(TestProtocol.NO_DRAG_TAG, "onStateTransitionStart"); } if (mState != state) { @@ -576,8 +577,8 @@ public class LauncherStateManager { private final AnimatorSet mAnim; public StartAnimRunnable(AnimatorSet anim) { - if (com.android.launcher3.TestProtocol.sDebugTracing) { - android.util.Log.d(com.android.launcher3.TestProtocol.NO_DRAG_TAG, + if (TestProtocol.sDebugTracing) { + android.util.Log.d(TestProtocol.NO_DRAG_TAG, "StartAnimRunnable"); } mAnim = anim; diff --git a/src/com/android/launcher3/ResourceUtils.java b/src/com/android/launcher3/ResourceUtils.java index 0c80d130ea..73e705b586 100644 --- a/src/com/android/launcher3/ResourceUtils.java +++ b/src/com/android/launcher3/ResourceUtils.java @@ -21,10 +21,9 @@ import android.util.DisplayMetrics; import android.util.TypedValue; public class ResourceUtils { - public static final String NAVBAR_PORTRAIT_BOTTOM_SIZE = "navigation_bar_frame_height"; public static final String NAVBAR_LANDSCAPE_LEFT_RIGHT_SIZE = "navigation_bar_width"; - public static final String NAVBAR_LANDSCAPE_BOTTOM_SIZE - = "navigation_bar_frame_height_landscape"; + public static final String NAVBAR_BOTTOM_GESTURE_SIZE = "navigation_bar_gesture_height"; + public static int getNavbarSize(String resName, Resources res) { return getDimenByName(resName, res, 48); diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index d19f9cd73f..f784226a51 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -20,8 +20,6 @@ import static com.android.launcher3.LauncherAnimUtils.OVERVIEW_TRANSITION_MS; import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_EXIT_DELAY; import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_TRANSITION_MS; import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPLICATION; -import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT; -import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT; import static com.android.launcher3.LauncherState.ALL_APPS; import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.LauncherState.SPRING_LOADED; @@ -86,6 +84,7 @@ import com.android.launcher3.graphics.RotationMode; import com.android.launcher3.pageindicators.WorkspacePageIndicator; import com.android.launcher3.popup.PopupContainerWithArrow; import com.android.launcher3.shortcuts.ShortcutDragPreviewProvider; +import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.touch.WorkspaceTouchListener; import com.android.launcher3.userevent.nano.LauncherLogProto.Action; import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; @@ -371,8 +370,8 @@ public class Workspace extends PagedView @Override public void onDragStart(DropTarget.DragObject dragObject, DragOptions options) { - if (com.android.launcher3.TestProtocol.sDebugTracing) { - android.util.Log.d(com.android.launcher3.TestProtocol.NO_DRAG_TAG, + if (TestProtocol.sDebugTracing) { + android.util.Log.d(TestProtocol.NO_DRAG_TAG, "onDragStart 1"); } if (ENFORCE_DRAG_EVENT_ORDER) { @@ -425,8 +424,8 @@ public class Workspace extends PagedView } // Always enter the spring loaded mode - if (com.android.launcher3.TestProtocol.sDebugTracing) { - android.util.Log.d(com.android.launcher3.TestProtocol.NO_DRAG_TAG, + if (TestProtocol.sDebugTracing) { + android.util.Log.d(TestProtocol.NO_DRAG_TAG, "onDragStart 2"); } mLauncher.getStateManager().goToState(SPRING_LOADED); diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java index 63682c73ac..053c570045 100644 --- a/src/com/android/launcher3/allapps/AllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java @@ -31,6 +31,7 @@ import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; +import android.view.WindowInsets; import com.android.launcher3.AppInfo; import com.android.launcher3.DeviceProfile; @@ -43,7 +44,7 @@ import com.android.launcher3.ItemInfo; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherState; import com.android.launcher3.R; -import com.android.launcher3.TestProtocol; +import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.Utilities; import com.android.launcher3.compat.AccessibilityManagerCompat; import com.android.launcher3.config.FeatureFlags; @@ -321,12 +322,21 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo } setLayoutParams(mlp); - mNavBarScrimHeight = insets.bottom; InsettableFrameLayout.dispatchInsets(this, insets); mLauncher.getAllAppsController() .setScrollRangeDelta(mSearchUiManager.getScrollRangeDelta(insets)); } + @Override + public WindowInsets dispatchApplyWindowInsets(WindowInsets insets) { + if (Utilities.ATLEAST_Q) { + mNavBarScrimHeight = insets.getTappableElementInsets().bottom; + } else { + mNavBarScrimHeight = insets.getStableInsetBottom(); + } + return super.dispatchApplyWindowInsets(insets); + } + @Override protected void dispatchDraw(Canvas canvas) { super.dispatchDraw(canvas); diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java index 548d5de0e0..a0e9dc5d8e 100644 --- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java +++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java @@ -425,7 +425,7 @@ public class AllAppsRecyclerView extends BaseRecyclerView implements LogContaine public void onScrollStateChanged(int state) { super.onScrollStateChanged(state); - if (state == SCROLL_STATE_IDLE && Utilities.IS_RUNNING_IN_TEST_HARNESS) { + if (state == SCROLL_STATE_IDLE) { AccessibilityManagerCompat.sendScrollFinishedEventToTest(getContext()); } } diff --git a/src/com/android/launcher3/compat/AccessibilityManagerCompat.java b/src/com/android/launcher3/compat/AccessibilityManagerCompat.java index 86f773fa31..81c95cbdd4 100644 --- a/src/com/android/launcher3/compat/AccessibilityManagerCompat.java +++ b/src/com/android/launcher3/compat/AccessibilityManagerCompat.java @@ -23,7 +23,7 @@ import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityNodeInfo; -import com.android.launcher3.TestProtocol; +import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.Utilities; import java.util.function.Consumer; @@ -69,6 +69,13 @@ public class AccessibilityManagerCompat { sendEventToTest(accessibilityManager, TestProtocol.SCROLL_FINISHED_MESSAGE, null); } + public static void sendPauseDetectedEventToTest(Context context) { + final AccessibilityManager accessibilityManager = getAccessibilityManagerForTest(context); + if (accessibilityManager == null) return; + + sendEventToTest(accessibilityManager, TestProtocol.PAUSE_DETECTED_MESSAGE, null); + } + private static void sendEventToTest( AccessibilityManager accessibilityManager, String eventTag, Bundle data) { final AccessibilityEvent e = AccessibilityEvent.obtain( diff --git a/src/com/android/launcher3/config/BaseFlags.java b/src/com/android/launcher3/config/BaseFlags.java index 7e20d11c2b..54d0db1006 100644 --- a/src/com/android/launcher3/config/BaseFlags.java +++ b/src/com/android/launcher3/config/BaseFlags.java @@ -105,7 +105,7 @@ abstract class BaseFlags { "ENABLE_QUICKSTEP_LIVE_TILE", false, "Enable live tile in Quickstep overview"); public static final TogglableFlag ENABLE_HINTS_IN_OVERVIEW = new TogglableFlag( - "ENABLE_HINTS_IN_OVERVIEW", false, + "ENABLE_HINTS_IN_OVERVIEW", true, "Show chip hints and gleams on the overview screen"); public static final TogglableFlag FAKE_LANDSCAPE_UI = new TogglableFlag( diff --git a/src/com/android/launcher3/dragndrop/DragController.java b/src/com/android/launcher3/dragndrop/DragController.java index bf692fe472..9d3c8f75dc 100644 --- a/src/com/android/launcher3/dragndrop/DragController.java +++ b/src/com/android/launcher3/dragndrop/DragController.java @@ -41,6 +41,7 @@ import com.android.launcher3.Launcher; import com.android.launcher3.R; import com.android.launcher3.WorkspaceItemInfo; import com.android.launcher3.accessibility.DragViewStateAnnouncer; +import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.util.ItemInfoMatcher; import com.android.launcher3.util.Thunk; import com.android.launcher3.util.TouchController; @@ -472,8 +473,8 @@ public class DragController implements DragDriver.EventListener, TouchController } private void handleMoveEvent(int x, int y) { - if (com.android.launcher3.TestProtocol.sDebugTracing) { - android.util.Log.d(com.android.launcher3.TestProtocol.NO_DRAG_TAG, + if (TestProtocol.sDebugTracing) { + android.util.Log.d(TestProtocol.NO_DRAG_TAG, "handleMoveEvent 1"); } mDragObject.dragView.move(x, y); @@ -492,8 +493,8 @@ public class DragController implements DragDriver.EventListener, TouchController if (mIsInPreDrag && mOptions.preDragCondition != null && mOptions.preDragCondition.shouldStartDrag(mDistanceSinceScroll)) { - if (com.android.launcher3.TestProtocol.sDebugTracing) { - android.util.Log.d(com.android.launcher3.TestProtocol.NO_DRAG_TAG, + if (TestProtocol.sDebugTracing) { + android.util.Log.d(TestProtocol.NO_DRAG_TAG, "handleMoveEvent 2"); } callOnDragStart(); @@ -533,8 +534,8 @@ public class DragController implements DragDriver.EventListener, TouchController * Call this from a drag source view. */ public boolean onControllerTouchEvent(MotionEvent ev) { - if (com.android.launcher3.TestProtocol.sDebugTracing) { - android.util.Log.d(com.android.launcher3.TestProtocol.NO_DRAG_TAG, + if (TestProtocol.sDebugTracing) { + android.util.Log.d(TestProtocol.NO_DRAG_TAG, "onControllerTouchEvent"); } if (mDragDriver == null || mOptions == null || mOptions.isAccessibleDrag) { diff --git a/src/com/android/launcher3/dragndrop/DragView.java b/src/com/android/launcher3/dragndrop/DragView.java index 9d46cf2abf..d1bd2db134 100644 --- a/src/com/android/launcher3/dragndrop/DragView.java +++ b/src/com/android/launcher3/dragndrop/DragView.java @@ -44,6 +44,7 @@ import android.view.View; import com.android.launcher3.FastBitmapDrawable; import com.android.launcher3.ItemInfo; import com.android.launcher3.Launcher; +import com.android.launcher3.LauncherModel; import com.android.launcher3.LauncherSettings; import com.android.launcher3.LauncherState; import com.android.launcher3.LauncherStateManager; @@ -54,7 +55,6 @@ import com.android.launcher3.anim.Interpolators; import com.android.launcher3.icons.LauncherIcons; import com.android.launcher3.util.Themes; import com.android.launcher3.util.Thunk; -import com.android.launcher3.util.UiThreadHelper; import java.util.Arrays; @@ -210,7 +210,7 @@ public class DragView extends View implements LauncherStateManager.StateListener return; } // Load the adaptive icon on a background thread and add the view in ui thread. - new Handler(UiThreadHelper.getBackgroundLooper()).postAtFrontOfQueue(new Runnable() { + new Handler(LauncherModel.getWorkerLooper()).postAtFrontOfQueue(new Runnable() { @Override public void run() { Object[] outObj = new Object[1]; diff --git a/src/com/android/launcher3/states/RotationHelper.java b/src/com/android/launcher3/states/RotationHelper.java index 3727fa6632..b6c3c35b89 100644 --- a/src/com/android/launcher3/states/RotationHelper.java +++ b/src/com/android/launcher3/states/RotationHelper.java @@ -62,6 +62,10 @@ public class RotationHelper implements OnSharedPreferenceChangeListener { * Rotation request made by {@link InternalStateHandler}. This supersedes any other request. */ private int mStateHandlerRequest = REQUEST_NONE; + /** + * Rotation request made by an app transition + */ + private int mCurrentTransitionRequest = REQUEST_NONE; /** * Rotation request made by a Launcher State */ @@ -123,6 +127,13 @@ public class RotationHelper implements OnSharedPreferenceChangeListener { } } + public void setCurrentTransitionRequest(int request) { + if (mCurrentTransitionRequest != request) { + mCurrentTransitionRequest = request; + notifyChange(); + } + } + public void setCurrentStateRequest(int request) { if (mCurrentStateRequest != request) { mCurrentStateRequest = request; @@ -163,6 +174,9 @@ public class RotationHelper implements OnSharedPreferenceChangeListener { if (mStateHandlerRequest != REQUEST_NONE) { activityFlags = mStateHandlerRequest == REQUEST_LOCK ? SCREEN_ORIENTATION_LOCKED : SCREEN_ORIENTATION_UNSPECIFIED; + } else if (mCurrentTransitionRequest != REQUEST_NONE) { + activityFlags = mCurrentTransitionRequest == REQUEST_LOCK ? + SCREEN_ORIENTATION_LOCKED : SCREEN_ORIENTATION_UNSPECIFIED; } else if (mCurrentStateRequest == REQUEST_LOCK) { activityFlags = SCREEN_ORIENTATION_LOCKED; } else if (mIgnoreAutoRotateSettings || mCurrentStateRequest == REQUEST_ROTATE diff --git a/src/com/android/launcher3/testing/TestInformationHandler.java b/src/com/android/launcher3/testing/TestInformationHandler.java new file mode 100644 index 0000000000..b8476aa1da --- /dev/null +++ b/src/com/android/launcher3/testing/TestInformationHandler.java @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.launcher3.testing; + +import android.content.Context; +import android.os.Bundle; + +import com.android.launcher3.DeviceProfile; +import com.android.launcher3.InvariantDeviceProfile; +import com.android.launcher3.Launcher; +import com.android.launcher3.LauncherAppState; +import com.android.launcher3.LauncherState; +import com.android.launcher3.R; +import com.android.launcher3.util.ResourceBasedOverride; + +public class TestInformationHandler implements ResourceBasedOverride { + + public static TestInformationHandler newInstance(Context context) { + return Overrides.getObject(TestInformationHandler.class, + context, R.string.test_information_handler_class); + } + + protected Context mContext; + protected DeviceProfile mDeviceProfile; + protected LauncherAppState mLauncherAppState; + protected Launcher mLauncher; + + public void init(Context context) { + mContext = context; + mDeviceProfile = InvariantDeviceProfile.INSTANCE. + get(context).getDeviceProfile(context); + mLauncherAppState = LauncherAppState.getInstanceNoCreate(); + mLauncher = mLauncherAppState != null ? + (Launcher) mLauncherAppState.getModel().getCallback() : null; + } + + public Bundle call(String method) { + final Bundle response = new Bundle(); + switch (method) { + case TestProtocol.REQUEST_ALL_APPS_TO_OVERVIEW_SWIPE_HEIGHT: { + if (mLauncher == null) return null; + + final float progress = LauncherState.OVERVIEW.getVerticalProgress(mLauncher) + - LauncherState.ALL_APPS.getVerticalProgress(mLauncher); + final float distance = mLauncher.getAllAppsController().getShiftRange() * progress; + response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, (int) distance); + break; + } + + case TestProtocol.REQUEST_HOME_TO_ALL_APPS_SWIPE_HEIGHT: { + if (mLauncher == null) return null; + + final float progress = LauncherState.NORMAL.getVerticalProgress(mLauncher) + - LauncherState.ALL_APPS.getVerticalProgress(mLauncher); + final float distance = mLauncher.getAllAppsController().getShiftRange() * progress; + response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, (int) distance); + break; + } + + case TestProtocol.REQUEST_ENABLE_DEBUG_TRACING: + TestProtocol.sDebugTracing = true; + break; + + case TestProtocol.REQUEST_DISABLE_DEBUG_TRACING: + TestProtocol.sDebugTracing = false; + break; + } + return response; + } +} diff --git a/src/com/android/launcher3/testing/TestInformationProvider.java b/src/com/android/launcher3/testing/TestInformationProvider.java new file mode 100644 index 0000000000..bd177c0031 --- /dev/null +++ b/src/com/android/launcher3/testing/TestInformationProvider.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.launcher3.testing; + +import android.content.ContentProvider; +import android.content.ContentValues; +import android.database.Cursor; +import android.net.Uri; +import android.os.Bundle; + +import com.android.launcher3.Utilities; + +public class TestInformationProvider extends ContentProvider { + @Override + public boolean onCreate() { + return true; + } + + @Override + public int update(Uri uri, ContentValues contentValues, String s, String[] strings) { + return 0; + } + + @Override + public int delete(Uri uri, String s, String[] strings) { + return 0; + } + + @Override + public Uri insert(Uri uri, ContentValues contentValues) { + return null; + } + + @Override + public String getType(Uri uri) { + return null; + } + + @Override + public Cursor query(Uri uri, String[] strings, String s, String[] strings1, String s1) { + return null; + } + + @Override + public Bundle call(String method, String arg, Bundle extras) { + if (Utilities.IS_RUNNING_IN_TEST_HARNESS) { + TestInformationHandler handler = TestInformationHandler.newInstance(getContext()); + handler.init(getContext()); + return handler.call(method); + } + return null; + } +} diff --git a/src/com/android/launcher3/TestProtocol.java b/src/com/android/launcher3/testing/TestProtocol.java similarity index 96% rename from src/com/android/launcher3/TestProtocol.java rename to src/com/android/launcher3/testing/TestProtocol.java index a0440e877e..a678ef248d 100644 --- a/src/com/android/launcher3/TestProtocol.java +++ b/src/com/android/launcher3/testing/TestProtocol.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.launcher3; +package com.android.launcher3.testing; /** * Protocol for custom accessibility events for communication with UI Automation tests. @@ -25,6 +25,7 @@ public final class TestProtocol { public static final String STATE_FIELD = "state"; public static final String SWITCHED_TO_STATE_MESSAGE = "TAPL_SWITCHED_TO_STATE"; public static final String SCROLL_FINISHED_MESSAGE = "TAPL_SCROLL_FINISHED"; + public static final String PAUSE_DETECTED_MESSAGE = "TAPL_PAUSE_DETECTED"; public static final String RESPONSE_MESSAGE_POSTFIX = "_RESPONSE"; public static final int NORMAL_STATE_ORDINAL = 0; public static final int SPRING_LOADED_STATE_ORDINAL = 1; diff --git a/src/com/android/launcher3/touch/ItemClickHandler.java b/src/com/android/launcher3/touch/ItemClickHandler.java index 99b9f25b18..f858dc4c69 100644 --- a/src/com/android/launcher3/touch/ItemClickHandler.java +++ b/src/com/android/launcher3/touch/ItemClickHandler.java @@ -47,6 +47,7 @@ import com.android.launcher3.WorkspaceItemInfo; import com.android.launcher3.compat.AppWidgetManagerCompat; import com.android.launcher3.folder.Folder; import com.android.launcher3.folder.FolderIcon; +import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.util.PackageManagerHelper; import com.android.launcher3.widget.PendingAppWidgetHostView; import com.android.launcher3.widget.WidgetAddFlowHandler; @@ -66,15 +67,15 @@ public class ItemClickHandler { } private static void onClick(View v, String sourceContainer) { - if (com.android.launcher3.TestProtocol.sDebugTracing) { - android.util.Log.d(com.android.launcher3.TestProtocol.NO_START_TAG, + if (TestProtocol.sDebugTracing) { + android.util.Log.d(TestProtocol.NO_START_TAG, "onClick 1"); } // Make sure that rogue clicks don't get through while allapps is launching, or after the // view has detached (it's possible for this to happen if the view is removed mid touch). if (v.getWindowToken() == null) { - if (com.android.launcher3.TestProtocol.sDebugTracing) { - android.util.Log.d(com.android.launcher3.TestProtocol.NO_START_TAG, + if (TestProtocol.sDebugTracing) { + android.util.Log.d(TestProtocol.NO_START_TAG, "onClick 2"); } return; @@ -82,8 +83,8 @@ public class ItemClickHandler { Launcher launcher = Launcher.getLauncher(v.getContext()); if (!launcher.getWorkspace().isFinishedSwitchingState()) { - if (com.android.launcher3.TestProtocol.sDebugTracing) { - android.util.Log.d(com.android.launcher3.TestProtocol.NO_START_TAG, + if (TestProtocol.sDebugTracing) { + android.util.Log.d(TestProtocol.NO_START_TAG, "onClick 3"); } return; @@ -97,8 +98,8 @@ public class ItemClickHandler { onClickFolderIcon(v); } } else if (tag instanceof AppInfo) { - if (com.android.launcher3.TestProtocol.sDebugTracing) { - android.util.Log.d(com.android.launcher3.TestProtocol.NO_START_TAG, + if (TestProtocol.sDebugTracing) { + android.util.Log.d(TestProtocol.NO_START_TAG, "onClick 4"); } startAppShortcutOrInfoActivity(v, (AppInfo) tag, launcher, @@ -232,8 +233,8 @@ public class ItemClickHandler { private static void startAppShortcutOrInfoActivity(View v, ItemInfo item, Launcher launcher, @Nullable String sourceContainer) { - if (com.android.launcher3.TestProtocol.sDebugTracing) { - android.util.Log.d(com.android.launcher3.TestProtocol.NO_START_TAG, + if (TestProtocol.sDebugTracing) { + android.util.Log.d(TestProtocol.NO_START_TAG, "startAppShortcutOrInfoActivity"); } Intent intent; diff --git a/src/com/android/launcher3/views/BaseDragLayer.java b/src/com/android/launcher3/views/BaseDragLayer.java index 4964182409..939b0f2b9f 100644 --- a/src/com/android/launcher3/views/BaseDragLayer.java +++ b/src/com/android/launcher3/views/BaseDragLayer.java @@ -41,6 +41,7 @@ import android.widget.FrameLayout; import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.InsettableFrameLayout; import com.android.launcher3.Utilities; +import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.util.MultiValueAlpha; import com.android.launcher3.util.MultiValueAlpha.AlphaProperty; import com.android.launcher3.util.TouchController; @@ -213,8 +214,8 @@ public abstract class BaseDragLayer @Override public boolean onTouchEvent(MotionEvent ev) { - if (com.android.launcher3.TestProtocol.sDebugTracing) { - android.util.Log.d(com.android.launcher3.TestProtocol.NO_DRAG_TAG, + if (TestProtocol.sDebugTracing) { + android.util.Log.d(TestProtocol.NO_DRAG_TAG, "onTouchEvent " + ev); } int action = ev.getAction(); @@ -226,8 +227,8 @@ public abstract class BaseDragLayer } if (mActiveController != null) { - if (com.android.launcher3.TestProtocol.sDebugTracing) { - android.util.Log.d(com.android.launcher3.TestProtocol.NO_DRAG_TAG, + if (TestProtocol.sDebugTracing) { + android.util.Log.d(TestProtocol.NO_DRAG_TAG, "onTouchEvent 1"); } return mActiveController.onControllerTouchEvent(ev); @@ -495,12 +496,14 @@ public abstract class BaseDragLayer } } + @Override @TargetApi(Build.VERSION_CODES.Q) - public void updateTouchExcludeRegion(WindowInsets insets) { + public WindowInsets dispatchApplyWindowInsets(WindowInsets insets) { if (Utilities.ATLEAST_Q) { Insets gestureInsets = insets.getMandatorySystemGestureInsets(); mSystemGestureRegion.set(gestureInsets.left, gestureInsets.top, gestureInsets.right, gestureInsets.bottom); } + return super.dispatchApplyWindowInsets(insets); } } diff --git a/src/com/android/launcher3/views/FloatingIconView.java b/src/com/android/launcher3/views/FloatingIconView.java index f63bcddf0d..03cbb21437 100644 --- a/src/com/android/launcher3/views/FloatingIconView.java +++ b/src/com/android/launcher3/views/FloatingIconView.java @@ -20,6 +20,7 @@ import static com.android.launcher3.Utilities.getBadge; import static com.android.launcher3.Utilities.mapToRange; import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.launcher3.config.FeatureFlags.ADAPTIVE_ICON_WINDOW_ANIM; +import static com.android.launcher3.states.RotationHelper.REQUEST_LOCK; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; @@ -40,7 +41,6 @@ import android.graphics.drawable.Drawable; import android.os.Build; import android.os.CancellationSignal; import android.os.Handler; -import android.os.Looper; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; @@ -63,7 +63,6 @@ import com.android.launcher3.graphics.ShiftedBitmapDrawable; import com.android.launcher3.icons.LauncherIcons; import com.android.launcher3.popup.SystemShortcut; import com.android.launcher3.shortcuts.DeepShortcutView; -import com.android.launcher3.util.UiThreadHelper; import androidx.annotation.Nullable; import androidx.annotation.WorkerThread; @@ -180,6 +179,7 @@ public class FloatingIconView extends View implements protected void onAttachedToWindow() { super.onAttachedToWindow(); getViewTreeObserver().addOnGlobalLayoutListener(this); + mLauncher.getRotationHelper().setCurrentTransitionRequest(REQUEST_LOCK); } @Override @@ -642,7 +642,7 @@ public class FloatingIconView extends View implements originalView.setVisibility(INVISIBLE); }; CancellationSignal loadIconSignal = view.mLoadIconSignal; - new Handler(UiThreadHelper.getBackgroundLooper()).postAtFrontOfQueue(() -> { + new Handler(LauncherModel.getWorkerLooper()).postAtFrontOfQueue(() -> { view.getIcon(originalView, (ItemInfo) originalView.getTag(), isOpening, onIconLoaded, loadIconSignal); }); diff --git a/tests/Android.mk b/tests/Android.mk index 0991a0439d..978209febf 100644 --- a/tests/Android.mk +++ b/tests/Android.mk @@ -32,7 +32,7 @@ else LOCAL_SRC_FILES := $(call all-java-files-under, tapl) \ ../src/com/android/launcher3/ResourceUtils.java \ ../src/com/android/launcher3/util/SecureSettingsObserver.java \ - ../src/com/android/launcher3/TestProtocol.java + ../src/com/android/launcher3/testing/TestProtocol.java endif LOCAL_MODULE := ub-launcher-aosp-tapl diff --git a/tests/AndroidManifest-common.xml b/tests/AndroidManifest-common.xml index 75ff66e6ea..61c7306e57 100644 --- a/tests/AndroidManifest-common.xml +++ b/tests/AndroidManifest-common.xml @@ -184,5 +184,13 @@ + + + + + + diff --git a/tests/OWNERS b/tests/OWNERS new file mode 100644 index 0000000000..046d871163 --- /dev/null +++ b/tests/OWNERS @@ -0,0 +1 @@ +vadimt@google.com diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java index 74cece836c..44401c73c2 100644 --- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java +++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java @@ -54,6 +54,7 @@ import com.android.launcher3.MainThreadExecutor; import com.android.launcher3.ResourceUtils; import com.android.launcher3.Utilities; import com.android.launcher3.compat.LauncherAppsCompat; +import com.android.launcher3.model.AppLaunchTracker; import com.android.launcher3.tapl.LauncherInstrumentation; import com.android.launcher3.tapl.TestHelpers; import com.android.launcher3.util.Wait; @@ -91,7 +92,6 @@ public abstract class AbstractLauncherUiTest { public static final long SHORT_UI_TIMEOUT = 300; public static final long DEFAULT_UI_TIMEOUT = 10000; - protected static final int LONG_WAIT_TIME_MS = 60000; private static final String TAG = "AbstractLauncherUiTest"; private static int sScreenshotCount = 0; @@ -198,6 +198,9 @@ public abstract class AbstractLauncherUiTest { @Before public void setUp() throws Exception { + // Disable app tracker + AppLaunchTracker.INSTANCE.initializeForTesting(new AppLaunchTracker()); + mTargetContext = InstrumentationRegistry.getTargetContext(); mTargetPackage = mTargetContext.getPackageName(); // Unlock the phone @@ -243,7 +246,7 @@ public abstract class AbstractLauncherUiTest { */ protected UiObject2 scrollAndFind(UiObject2 container, BySelector condition) { final int margin = ResourceUtils.getNavbarSize( - ResourceUtils.NAVBAR_PORTRAIT_BOTTOM_SIZE, mLauncher.getResources()) + 1; + ResourceUtils.NAVBAR_BOTTOM_GESTURE_SIZE, mLauncher.getResources()) + 1; container.setGestureMargins(0, 0, 0, margin); int i = 0; @@ -394,7 +397,7 @@ public abstract class AbstractLauncherUiTest { intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); instrumentation.getTargetContext().startActivity(intent); assertTrue(packageName + " didn't start", - mDevice.wait(Until.hasObject(By.pkg(packageName).depth(0)), LONG_WAIT_TIME_MS)); + mDevice.wait(Until.hasObject(By.pkg(packageName).depth(0)), DEFAULT_UI_TIMEOUT)); } protected void startTestActivity(int activityNumber) { @@ -410,7 +413,7 @@ public abstract class AbstractLauncherUiTest { assertTrue(packageName + " didn't start", mDevice.wait( Until.hasObject(By.pkg(packageName).text("TestActivity" + activityNumber)), - LONG_WAIT_TIME_MS)); + DEFAULT_UI_TIMEOUT)); } protected static String resolveSystemApp(String category) { diff --git a/tests/tapl/com/android/launcher3/tapl/AllApps.java b/tests/tapl/com/android/launcher3/tapl/AllApps.java index 70405fed8a..18a8f2755a 100644 --- a/tests/tapl/com/android/launcher3/tapl/AllApps.java +++ b/tests/tapl/com/android/launcher3/tapl/AllApps.java @@ -27,7 +27,7 @@ import androidx.test.uiautomator.Direction; import androidx.test.uiautomator.UiObject2; import com.android.launcher3.ResourceUtils; -import com.android.launcher3.TestProtocol; +import com.android.launcher3.testing.TestProtocol; /** * Operations on AllApps opened from Home. Also a parent for All Apps opened from Overview. @@ -97,7 +97,7 @@ public class AllApps extends LauncherInstrumentation.VisibleContainer { 0, getSearchBox(allAppsContainer).getVisibleBounds().bottom + 1, 0, - ResourceUtils.getNavbarSize(ResourceUtils.NAVBAR_PORTRAIT_BOTTOM_SIZE, + ResourceUtils.getNavbarSize(ResourceUtils.NAVBAR_BOTTOM_GESTURE_SIZE, mLauncher.getResources()) + 1); final BySelector appIconSelector = AppIcon.getAppIconSelector(appName, mLauncher); if (!hasClickableIcon(allAppsContainer, appListRecycler, appIconSelector)) { diff --git a/tests/tapl/com/android/launcher3/tapl/AllAppsFromOverview.java b/tests/tapl/com/android/launcher3/tapl/AllAppsFromOverview.java index a472d31344..f48d4dd4c7 100644 --- a/tests/tapl/com/android/launcher3/tapl/AllAppsFromOverview.java +++ b/tests/tapl/com/android/launcher3/tapl/AllAppsFromOverview.java @@ -16,14 +16,14 @@ package com.android.launcher3.tapl; -import static com.android.launcher3.TestProtocol.OVERVIEW_STATE_ORDINAL; +import static com.android.launcher3.testing.TestProtocol.OVERVIEW_STATE_ORDINAL; import android.graphics.Point; import androidx.annotation.NonNull; import androidx.test.uiautomator.UiObject2; -import com.android.launcher3.TestProtocol; +import com.android.launcher3.testing.TestProtocol; /** * Operations on AllApps opened from Overview. diff --git a/tests/tapl/com/android/launcher3/tapl/Background.java b/tests/tapl/com/android/launcher3/tapl/Background.java index 55e14cc80c..ce952983f9 100644 --- a/tests/tapl/com/android/launcher3/tapl/Background.java +++ b/tests/tapl/com/android/launcher3/tapl/Background.java @@ -16,7 +16,7 @@ package com.android.launcher3.tapl; -import static com.android.launcher3.TestProtocol.BACKGROUND_APP_STATE_ORDINAL; +import static com.android.launcher3.testing.TestProtocol.BACKGROUND_APP_STATE_ORDINAL; import android.graphics.Point; import android.os.SystemClock; @@ -24,7 +24,7 @@ import android.view.MotionEvent; import androidx.annotation.NonNull; -import com.android.launcher3.TestProtocol; +import com.android.launcher3.testing.TestProtocol; /** * Indicates the base state with a UI other than Overview running as foreground. It can also @@ -32,7 +32,6 @@ import com.android.launcher3.TestProtocol; */ public class Background extends LauncherInstrumentation.VisibleContainer { private static final int ZERO_BUTTON_SWIPE_UP_GESTURE_DURATION = 500; - private static final int ZERO_BUTTON_SWIPE_UP_HOLD_DURATION = 400; Background(LauncherInstrumentation launcher) { super(launcher); @@ -72,9 +71,15 @@ public class Background extends LauncherInstrumentation.VisibleContainer { final long downTime = SystemClock.uptimeMillis(); mLauncher.sendPointer(downTime, downTime, MotionEvent.ACTION_DOWN, start); - mLauncher.movePointer( - downTime, downTime, ZERO_BUTTON_SWIPE_UP_GESTURE_DURATION, start, end); - LauncherInstrumentation.sleep(ZERO_BUTTON_SWIPE_UP_HOLD_DURATION); + mLauncher.executeAndWaitForEvent( + () -> mLauncher.movePointer( + downTime, + downTime, + ZERO_BUTTON_SWIPE_UP_GESTURE_DURATION, + start, + end), + event -> TestProtocol.PAUSE_DETECTED_MESSAGE.equals(event.getClassName()), + "Pause wasn't detected"); mLauncher.sendPointer( downTime, SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, end); break; @@ -89,7 +94,7 @@ public class Background extends LauncherInstrumentation.VisibleContainer { mLauncher.swipeToState( centerX, startY, centerX, startY - swipeHeight - mLauncher.getTouchSlop(), - 60, + 10, expectedState); break; } diff --git a/tests/tapl/com/android/launcher3/tapl/Home.java b/tests/tapl/com/android/launcher3/tapl/Home.java index 20c116ce21..cfc43749d1 100644 --- a/tests/tapl/com/android/launcher3/tapl/Home.java +++ b/tests/tapl/com/android/launcher3/tapl/Home.java @@ -16,7 +16,7 @@ package com.android.launcher3.tapl; -import static com.android.launcher3.TestProtocol.OVERVIEW_STATE_ORDINAL; +import static com.android.launcher3.testing.TestProtocol.OVERVIEW_STATE_ORDINAL; import androidx.annotation.NonNull; diff --git a/tests/tapl/com/android/launcher3/tapl/Launchable.java b/tests/tapl/com/android/launcher3/tapl/Launchable.java index 3295ddbef4..4261988409 100644 --- a/tests/tapl/com/android/launcher3/tapl/Launchable.java +++ b/tests/tapl/com/android/launcher3/tapl/Launchable.java @@ -24,12 +24,13 @@ import androidx.test.uiautomator.UiDevice; import androidx.test.uiautomator.UiObject2; import androidx.test.uiautomator.Until; -import com.android.launcher3.TestProtocol; +import com.android.launcher3.testing.TestProtocol; /** * Ancestor for AppIcon and AppMenuItem. */ abstract class Launchable { + private static final int WAIT_TIME_MS = 60000; protected final LauncherInstrumentation mLauncher; protected final UiObject2 mObject; @@ -56,7 +57,7 @@ abstract class Launchable { mLauncher.getTestInfo(TestProtocol.REQUEST_ENABLE_DEBUG_TRACING); mLauncher.assertTrue( "Launching an app didn't open a new window: " + mObject.getText(), - mObject.clickAndWait(Until.newWindow(), LauncherInstrumentation.WAIT_TIME_MS)); + mObject.clickAndWait(Until.newWindow(), WAIT_TIME_MS)); mLauncher.getTestInfo(TestProtocol.REQUEST_DISABLE_DEBUG_TRACING); mLauncher.assertTrue( "App didn't start: " + selector, diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index a4711f5f19..a442e2b020 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -16,16 +16,23 @@ package com.android.launcher3.tapl; -import static com.android.launcher3.TestProtocol.BACKGROUND_APP_STATE_ORDINAL; -import static com.android.launcher3.TestProtocol.NORMAL_STATE_ORDINAL; +import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED; +import static android.content.pm.PackageManager.DONT_KILL_APP; +import static android.content.pm.PackageManager.MATCH_ALL; +import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS; + +import static com.android.launcher3.testing.TestProtocol.BACKGROUND_APP_STATE_ORDINAL; +import static com.android.launcher3.testing.TestProtocol.NORMAL_STATE_ORDINAL; import static com.android.launcher3.tapl.TestHelpers.getOverviewPackageName; import android.app.ActivityManager; import android.app.Instrumentation; import android.app.UiAutomation; +import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; import android.content.pm.PackageManager; +import android.content.pm.ProviderInfo; import android.content.res.Resources; import android.graphics.Point; import android.graphics.Rect; @@ -53,7 +60,7 @@ import androidx.test.uiautomator.UiDevice; import androidx.test.uiautomator.UiObject2; import androidx.test.uiautomator.Until; -import com.android.launcher3.TestProtocol; +import com.android.launcher3.testing.TestProtocol; import com.android.systemui.shared.system.QuickStepContract; import org.junit.Assert; @@ -115,7 +122,7 @@ public final class LauncherInstrumentation { private static final String APPS_RES_ID = "apps_view"; private static final String OVERVIEW_RES_ID = "overview_panel"; private static final String WIDGETS_RES_ID = "widgets_list_view"; - public static final int WAIT_TIME_MS = 60000; + public static final int WAIT_TIME_MS = 10000; private static final String SYSTEMUI_PACKAGE = "com.android.systemui"; private static WeakReference sActiveContainer = new WeakReference<>(null); @@ -149,9 +156,10 @@ public final class LauncherInstrumentation { getLauncherPackageName() : targetPackage; + String testProviderAuthority = authorityPackage + ".TestInfo"; mTestProviderUri = new Uri.Builder() .scheme(ContentResolver.SCHEME_CONTENT) - .authority(authorityPackage + ".TestInfo") + .authority(testProviderAuthority) .build(); try { @@ -160,6 +168,25 @@ public final class LauncherInstrumentation { } catch (IOException e) { fail(e.toString()); } + + + PackageManager pm = getContext().getPackageManager(); + ProviderInfo pi = pm.resolveContentProvider( + testProviderAuthority, MATCH_ALL | MATCH_DISABLED_COMPONENTS); + ComponentName cn = new ComponentName(pi.packageName, pi.name); + + if (pm.getComponentEnabledSetting(cn) != COMPONENT_ENABLED_STATE_ENABLED) { + if (TestHelpers.isInLauncherProcess()) { + getContext().getPackageManager().setComponentEnabledSetting( + cn, COMPONENT_ENABLED_STATE_ENABLED, DONT_KILL_APP); + } else { + try { + mDevice.executeShellCommand("pm enable " + cn.flattenToString()); + } catch (IOException e) { + fail(e.toString()); + } + } + } } Context getContext() { @@ -337,7 +364,7 @@ public final class LauncherInstrumentation { } } - private Parcelable executeAndWaitForEvent(Runnable command, + Parcelable executeAndWaitForEvent(Runnable command, UiAutomation.AccessibilityEventFilter eventFilter, String message) { try { final AccessibilityEvent event = @@ -541,25 +568,22 @@ public final class LauncherInstrumentation { @NonNull UiObject2 waitForLauncherObject(String resName) { - final BySelector selector = getLauncherObjectSelector(resName); - final UiObject2 object = mDevice.wait(Until.findObject(selector), WAIT_TIME_MS); - assertNotNull("Can't find a launcher object; selector: " + selector, object); - return object; + return waitForObjectBySelector(getLauncherObjectSelector(resName)); } @NonNull UiObject2 waitForLauncherObjectByClass(String clazz) { - final BySelector selector = getLauncherObjectSelectorByClass(clazz); - final UiObject2 object = mDevice.wait(Until.findObject(selector), WAIT_TIME_MS); - assertNotNull("Can't find a launcher object; selector: " + selector, object); - return object; + return waitForObjectBySelector(getLauncherObjectSelectorByClass(clazz)); } @NonNull UiObject2 waitForFallbackLauncherObject(String resName) { - final BySelector selector = getFallbackLauncherObjectSelector(resName); + return waitForObjectBySelector(getFallbackLauncherObjectSelector(resName)); + } + + private UiObject2 waitForObjectBySelector(BySelector selector) { final UiObject2 object = mDevice.wait(Until.findObject(selector), WAIT_TIME_MS); - assertNotNull("Can't find a fallback launcher object; selector: " + selector, object); + assertNotNull("Can't find a launcher object; selector: " + selector, object); return object; } diff --git a/tests/tapl/com/android/launcher3/tapl/Overview.java b/tests/tapl/com/android/launcher3/tapl/Overview.java index ec99d26c19..058831f180 100644 --- a/tests/tapl/com/android/launcher3/tapl/Overview.java +++ b/tests/tapl/com/android/launcher3/tapl/Overview.java @@ -16,7 +16,7 @@ package com.android.launcher3.tapl; -import static com.android.launcher3.TestProtocol.ALL_APPS_STATE_ORDINAL; +import static com.android.launcher3.testing.TestProtocol.ALL_APPS_STATE_ORDINAL; import androidx.annotation.NonNull; import androidx.test.uiautomator.UiObject2; @@ -51,10 +51,9 @@ public final class Overview extends BaseOverview { // Swipe from an app icon to the top. LauncherInstrumentation.log("Overview.switchToAllApps before swipe"); - final UiObject2 appIcon = mLauncher.waitForLauncherObjectByClass( - "android.widget.TextView"); + final UiObject2 allApps = mLauncher.waitForLauncherObject("apps_view"); mLauncher.swipeToState(mLauncher.getDevice().getDisplayWidth() / 2, - appIcon.getVisibleBounds().centerY(), + allApps.getVisibleBounds().top, mLauncher.getDevice().getDisplayWidth() / 2, 0, 50, ALL_APPS_STATE_ORDINAL); diff --git a/tests/tapl/com/android/launcher3/tapl/Widgets.java b/tests/tapl/com/android/launcher3/tapl/Widgets.java index b780df4adb..94003be919 100644 --- a/tests/tapl/com/android/launcher3/tapl/Widgets.java +++ b/tests/tapl/com/android/launcher3/tapl/Widgets.java @@ -41,7 +41,7 @@ public final class Widgets extends LauncherInstrumentation.VisibleContainer { LauncherInstrumentation.log("Widgets.flingForward enter"); final UiObject2 widgetsContainer = verifyActiveContainer(); widgetsContainer.setGestureMargins(0, 0, 0, - ResourceUtils.getNavbarSize(ResourceUtils.NAVBAR_PORTRAIT_BOTTOM_SIZE, + ResourceUtils.getNavbarSize(ResourceUtils.NAVBAR_BOTTOM_GESTURE_SIZE, mLauncher.getResources()) + 1); widgetsContainer.fling(Direction.DOWN, (int) (FLING_SPEED * mLauncher.getDisplayDensity())); diff --git a/tests/tapl/com/android/launcher3/tapl/Workspace.java b/tests/tapl/com/android/launcher3/tapl/Workspace.java index 10b253d443..7dcc426b9d 100644 --- a/tests/tapl/com/android/launcher3/tapl/Workspace.java +++ b/tests/tapl/com/android/launcher3/tapl/Workspace.java @@ -16,7 +16,7 @@ package com.android.launcher3.tapl; -import static com.android.launcher3.TestProtocol.ALL_APPS_STATE_ORDINAL; +import static com.android.launcher3.testing.TestProtocol.ALL_APPS_STATE_ORDINAL; import static junit.framework.TestCase.assertTrue; @@ -30,7 +30,7 @@ import androidx.annotation.Nullable; import androidx.test.uiautomator.Direction; import androidx.test.uiautomator.UiObject2; -import com.android.launcher3.TestProtocol; +import com.android.launcher3.testing.TestProtocol; /** * Operations on the workspace screen. From 3a91804a2a75e9e07c0a633cec61f09dc422c827 Mon Sep 17 00:00:00 2001 From: Samuel Fufa Date: Wed, 14 Aug 2019 14:26:05 -0700 Subject: [PATCH 2/3] Sorting people by key crashes launcher Approch: approach: filter out people with null getKey before sorting. Bug:139436782 Change-Id: I6510a12374ff4fec02c879ff76ba42b1fcdb8281 (cherry picked from commit 8628eb9353462b66e3120bf9a79b8c6c56d9e481) (cherry picked from commit b6c569171a5287f8228d93298932e60aeb57ceca) --- .../notification/NotificationKeyData.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/com/android/launcher3/notification/NotificationKeyData.java b/src/com/android/launcher3/notification/NotificationKeyData.java index bfa4ba9ab3..a1917ecb00 100644 --- a/src/com/android/launcher3/notification/NotificationKeyData.java +++ b/src/com/android/launcher3/notification/NotificationKeyData.java @@ -20,16 +20,14 @@ import android.app.Notification; import android.app.Person; import android.service.notification.StatusBarNotification; -import com.android.launcher3.Utilities; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import com.android.launcher3.Utilities; + +import java.util.ArrayList; +import java.util.List; + /** * The key data associated with the notification, used to determine what to include * in dots and dummy popup views before they are populated. @@ -39,8 +37,9 @@ import androidx.annotation.Nullable; public class NotificationKeyData { public final String notificationKey; public final String shortcutId; + @NonNull + public final String[] personKeysFromNotification; public int count; - @NonNull public final String[] personKeysFromNotification; private NotificationKeyData(String notificationKey, String shortcutId, int count, String[] personKeysFromNotification) { @@ -70,7 +69,8 @@ public class NotificationKeyData { if (people == null || people.isEmpty()) { return Utilities.EMPTY_STRING_ARRAY; } - return people.stream().map(Person::getKey).sorted().toArray(String[]::new); + return people.stream().filter(person -> person.getKey() != null) + .map(Person::getKey).sorted().toArray(String[]::new); } @Override From 9b82a4141190e9a227111a5edc84d1cd2bf63af4 Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Thu, 29 Aug 2019 11:41:53 -0700 Subject: [PATCH 3/3] [DO NOT MERGE] Fix NumberFormatException for launcher. Fix is already in ub-launcher3-master: I5094b22ddc77c45590cea1a5f5dead0dc7580abf Bug: 140076379 Change-Id: I01948cf71ef2e058dc1ef8c506f174856ee09e0d (cherry picked from commit d49fe3130ed2460022ba98b376543e1a7aa30605) (cherry picked from commit 241cd902035d05d9d7300c2f63b4f01af833d275) --- src/com/android/launcher3/Utilities.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java index 3bef5986d7..ba122f9441 100644 --- a/src/com/android/launcher3/Utilities.java +++ b/src/com/android/launcher3/Utilities.java @@ -732,7 +732,7 @@ public final class Utilities { int[] array = new int[tokenizer.countTokens()]; int count = 0; while (tokenizer.hasMoreTokens()) { - array[count] = Integer.parseInt(tokenizer.nextToken()); + array[count] = Integer.parseInt(tokenizer.nextToken().trim()); count++; } return array;