diff --git a/go/quickstep/res/layout/clear_all_button.xml b/go/quickstep/res/layout/clear_all_button.xml index 2f7c8ae208..eef66add45 100644 --- a/go/quickstep/res/layout/clear_all_button.xml +++ b/go/quickstep/res/layout/clear_all_button.xml @@ -29,5 +29,6 @@ android:text="@string/recents_clear_all" android:textAllCaps="false" android:textColor="@color/clear_all_button_text" - android:textSize="14sp"/> + android:textSize="14sp" + style="@style/TextTitle"/> diff --git a/go/quickstep/res/layout/icon_recents_root_view.xml b/go/quickstep/res/layout/icon_recents_root_view.xml index 595a380bd8..8381ebc631 100644 --- a/go/quickstep/res/layout/icon_recents_root_view.xml +++ b/go/quickstep/res/layout/icon_recents_root_view.xml @@ -36,5 +36,6 @@ android:text="@string/recents_empty_message" android:textColor="@android:color/white" android:textSize="25sp" + style="@style/TextTitle" android:visibility="gone"/> \ No newline at end of file diff --git a/go/quickstep/res/layout/task_item_view.xml b/go/quickstep/res/layout/task_item_view.xml index ab2cf2804b..aeac47786a 100644 --- a/go/quickstep/res/layout/task_item_view.xml +++ b/go/quickstep/res/layout/task_item_view.xml @@ -41,5 +41,6 @@ android:layout_gravity="center_vertical" android:singleLine="true" android:textColor="@android:color/white" - android:textSize="24sp"/> + android:textSize="24sp" + style="@style/TextTitle"/> diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsUiFactory.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsUiFactory.java index ebae1cd968..336cdc93fe 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsUiFactory.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsUiFactory.java @@ -76,8 +76,13 @@ public abstract class RecentsUiFactory { @Override public void mapInsets(Context context, Rect insets, Rect out) { + // If there is a display cutout, the top insets in portrait would also include the + // cutout, which we will get as the left inset in landscape. Using the max of left and + // top allows us to cover both cases (with or without cutout). if (SysUINavigationMode.getMode(context) == NO_BUTTON) { - out.set(insets); + out.top = Math.max(insets.top, insets.left); + out.bottom = Math.max(insets.right, insets.bottom); + out.left = out.right = 0; } else { out.top = Math.max(insets.top, insets.left); out.bottom = insets.right; @@ -99,7 +104,9 @@ public abstract class RecentsUiFactory { @Override public void mapInsets(Context context, Rect insets, Rect out) { if (SysUINavigationMode.getMode(context) == NO_BUTTON) { - out.set(insets); + out.top = Math.max(insets.top, insets.right); + out.bottom = Math.max(insets.left, insets.bottom); + out.left = out.right = 0; } else { out.top = Math.max(insets.top, insets.right); out.bottom = insets.left; diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java index f429ce5b04..a662d7433e 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java @@ -17,6 +17,7 @@ package com.android.launcher3.uioverrides.states; import static com.android.launcher3.LauncherAnimUtils.OVERVIEW_TRANSITION_MS; +import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.Launcher; import com.android.launcher3.allapps.AllAppsTransitionController; import com.android.launcher3.userevent.nano.LauncherLogProto; @@ -41,6 +42,13 @@ public class BackgroundAppState extends OverviewState { super(id, logContainer, OVERVIEW_TRANSITION_MS, STATE_FLAGS); } + @Override + public void onStateEnabled(Launcher launcher) { + RecentsView rv = launcher.getOverviewPanel(); + rv.setOverviewStateEnabled(true); + AbstractFloatingView.closeAllOpenViews(launcher, false); + } + @Override public float getVerticalProgress(Launcher launcher) { if (launcher.getDeviceProfile().isVerticalBarLayout()) { 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 90b55360ef..4b2e487da9 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java @@ -118,7 +118,8 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe final RectF iconLocation = new RectF(); boolean canUseWorkspaceView = workspaceView != null && workspaceView.isAttachedToWindow(); FloatingIconView floatingIconView = canUseWorkspaceView - ? recentsView.getFloatingIconView(activity, workspaceView, iconLocation) + ? FloatingIconView.getFloatingIconView(activity, workspaceView, + true /* hideOriginal */, iconLocation, false /* isOpening */) : null; return new HomeAnimationFactory() { 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 0fd74bb26e..0c997dd598 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java @@ -331,21 +331,29 @@ public class TouchInteractionService extends Service implements defaultDisplay.getRealSize(realSize); mSwipeTouchRegion.set(0, 0, realSize.x, realSize.y); if (mMode == Mode.NO_BUTTON) { - mSwipeTouchRegion.top = mSwipeTouchRegion.bottom - getNavbarSize( - ResourceUtils.NAVBAR_VERTICAL_SIZE); + 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); + } } else { switch (defaultDisplay.getRotation()) { case Surface.ROTATION_90: mSwipeTouchRegion.left = mSwipeTouchRegion.right - - getNavbarSize(ResourceUtils.NAVBAR_HORIZONTAL_SIZE); + - getNavbarSize(ResourceUtils.NAVBAR_LANDSCAPE_LEFT_RIGHT_SIZE); break; case Surface.ROTATION_270: mSwipeTouchRegion.right = mSwipeTouchRegion.left - + getNavbarSize(ResourceUtils.NAVBAR_HORIZONTAL_SIZE); + + getNavbarSize(ResourceUtils.NAVBAR_LANDSCAPE_LEFT_RIGHT_SIZE); break; default: mSwipeTouchRegion.top = mSwipeTouchRegion.bottom - - getNavbarSize(ResourceUtils.NAVBAR_VERTICAL_SIZE); + - getNavbarSize(ResourceUtils.NAVBAR_PORTRAIT_BOTTOM_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 d69262e2c6..2ff5c0c6a5 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java @@ -902,7 +902,7 @@ public class WindowTransformSwipeHandler float minFlingVelocity = mContext.getResources() .getDimension(R.dimen.quickstep_fling_min_velocity); if (Math.abs(endVelocity) > minFlingVelocity && mTransitionDragLength > 0) { - if (endTarget == RECENTS) { + if (endTarget == RECENTS && mMode != Mode.NO_BUTTON) { Interpolators.OvershootParams overshoot = new Interpolators.OvershootParams( startShift, endShift, endShift, velocityPxPerMs.y, mTransitionDragLength); @@ -918,6 +918,10 @@ public class WindowTransformSwipeHandler // derivative of the scroll interpolator at zero, ie. 2. long baseDuration = Math.round(Math.abs(distanceToTravel / velocityPxPerMs.y)); duration = Math.min(MAX_SWIPE_DURATION, 2 * baseDuration); + + if (endTarget == RECENTS) { + interpolator = OVERSHOOT_1_2; + } } } } @@ -932,7 +936,8 @@ public class WindowTransformSwipeHandler } else if (endTarget == RECENTS) { mLiveTileOverlay.startIconAnimation(); if (mRecentsView != null) { - duration = Math.max(duration, mRecentsView.getScroller().getDuration()); + duration = Utilities.boundToRange(mRecentsView.getScroller().getDuration(), + duration, MAX_SWIPE_DURATION); } if (mMode == Mode.NO_BUTTON) { setShelfState(ShelfAnimState.OVERVIEW, interpolator, duration); diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AssistantTouchConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AssistantTouchConsumer.java index 20ea3a1694..bf276e1e16 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AssistantTouchConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AssistantTouchConsumer.java @@ -23,6 +23,7 @@ import static android.view.MotionEvent.ACTION_POINTER_DOWN; import static android.view.MotionEvent.ACTION_POINTER_UP; import static android.view.MotionEvent.ACTION_UP; +import static com.android.launcher3.Utilities.squaredHypot; import static com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction.UPLEFT; import static com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction.UPRIGHT; import static com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch.FLING; @@ -40,6 +41,7 @@ import android.os.SystemClock; import android.util.Log; import android.view.HapticFeedbackConstants; import android.view.MotionEvent; +import android.view.ViewConfiguration; import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.R; @@ -81,7 +83,7 @@ public class AssistantTouchConsumer extends DelegateInputConsumer private final float mDistThreshold; private final long mTimeThreshold; private final int mAngleThreshold; - private final float mSlop; + private final float mSquaredSlop; private final ISystemUiProxy mSysUiProxy; private final Context mContext; private final SwipeDetector mSwipeDetector; @@ -96,7 +98,10 @@ public class AssistantTouchConsumer extends DelegateInputConsumer 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 = QuickStepContract.getQuickStepDragSlopPx(); + + float slop = ViewConfiguration.get(context).getScaledTouchSlop(); + + mSquaredSlop = slop * slop; mActivityControlHelper = activityControlHelper; mSwipeDetector = new SwipeDetector(mContext, this, SwipeDetector.VERTICAL); mSwipeDetector.setDetectableScrollConditions(SwipeDetector.DIRECTION_POSITIVE, false); @@ -155,7 +160,8 @@ public class AssistantTouchConsumer extends DelegateInputConsumer if (!mPassedSlop) { // Normal gesture, ensure we pass the slop before we start tracking the gesture - if (Math.hypot(mLastPos.x - mDownPos.x, mLastPos.y - mDownPos.y) > mSlop) { + if (squaredHypot(mLastPos.x - mDownPos.x, mLastPos.y - mDownPos.y) + > mSquaredSlop) { mPassedSlop = true; mStartDragPos.set(mLastPos.x, mLastPos.y); @@ -218,31 +224,35 @@ public class AssistantTouchConsumer extends DelegateInputConsumer private void updateAssistantProgress() { if (!mLaunchedAssistant) { mLastProgress = Math.min(mDistance * 1f / mDistThreshold, 1) * mTimeFraction; - updateAssistant(SWIPE); + try { + if (mDistance >= mDistThreshold && mTimeFraction >= 1) { + mSysUiProxy.onAssistantGestureCompletion(0); + startAssistantInternal(SWIPE); + + Bundle args = new Bundle(); + args.putInt(INVOCATION_TYPE_KEY, INVOCATION_TYPE_GESTURE); + mSysUiProxy.startAssistant(args); + mLaunchedAssistant = true; + } else { + mSysUiProxy.onAssistantProgress(mLastProgress); + } + } catch (RemoteException e) { + Log.w(TAG, "Failed to send SysUI start/send assistant progress: " + mLastProgress, + e); + } } } - private void updateAssistant(int gestureType) { - try { - mSysUiProxy.onAssistantProgress(mLastProgress); - if (gestureType == FLING || (mDistance >= mDistThreshold && mTimeFraction >= 1)) { - UserEventDispatcher.newInstance(mContext) - .logActionOnContainer(gestureType, mDirection, NAVBAR); - Bundle args = new Bundle(); - args.putInt(INVOCATION_TYPE_KEY, INVOCATION_TYPE_GESTURE); + private void startAssistantInternal(int gestureType) { + UserEventDispatcher.newInstance(mContext) + .logActionOnContainer(gestureType, mDirection, NAVBAR); - BaseDraggingActivity launcherActivity = mActivityControlHelper.getCreatedActivity(); - if (launcherActivity != null) { - launcherActivity.getRootView().performHapticFeedback( - 13, // HapticFeedbackConstants.GESTURE_END - HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING); - } - - mSysUiProxy.startAssistant(args); - mLaunchedAssistant = true; - } - } catch (RemoteException e) { - Log.w(TAG, "Failed to send SysUI start/send assistant progress: " + mLastProgress, e); + BaseDraggingActivity launcherActivity = mActivityControlHelper + .getCreatedActivity(); + if (launcherActivity != null) { + launcherActivity.getRootView().performHapticFeedback( + 13, // HapticFeedbackConstants.GESTURE_END + HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING); } } @@ -266,9 +276,20 @@ public class AssistantTouchConsumer extends DelegateInputConsumer @Override public void onDragEnd(float velocity, boolean fling) { - if (fling && !mLaunchedAssistant) { + if (fling && !mLaunchedAssistant && mState != STATE_DELEGATE_ACTIVE) { mLastProgress = 1; - updateAssistant(FLING); + try { + mSysUiProxy.onAssistantGestureCompletion(velocity); + startAssistantInternal(FLING); + + Bundle args = new Bundle(); + args.putInt(INVOCATION_TYPE_KEY, INVOCATION_TYPE_GESTURE); + mSysUiProxy.startAssistant(args); + mLaunchedAssistant = true; + } catch (RemoteException e) { + Log.w(TAG, "Failed to send SysUI start/send assistant progress: " + mLastProgress, + e); + } } } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java index b1d175df85..d01b5ec19d 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java @@ -15,11 +15,13 @@ */ package com.android.quickstep.inputconsumers; +import static com.android.launcher3.Utilities.squaredHypot; +import static com.android.launcher3.Utilities.squaredTouchSlop; + import android.content.Context; import android.content.Intent; import android.graphics.PointF; import android.view.MotionEvent; -import android.view.ViewConfiguration; /** * A dummy input consumer used when the device is still locked, e.g. from secure camera. @@ -32,8 +34,7 @@ public class DeviceLockedInputConsumer implements InputConsumer { public DeviceLockedInputConsumer(Context context) { mContext = context; - float touchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); - mTouchSlopSquared = touchSlop * touchSlop; + mTouchSlopSquared = squaredTouchSlop(context); } @Override @@ -48,9 +49,7 @@ public class DeviceLockedInputConsumer implements InputConsumer { if (ev.getAction() == MotionEvent.ACTION_DOWN) { mTouchDown.set(x, y); } else if (ev.getAction() == MotionEvent.ACTION_MOVE) { - float xSquared = (x - mTouchDown.x) * (x - mTouchDown.x); - float ySquared = (y - mTouchDown.y) * (y - mTouchDown.y); - if (xSquared + ySquared > mTouchSlopSquared) { + if (squaredHypot(x - mTouchDown.x, y - mTouchDown.y) > mTouchSlopSquared) { // For now, just start the home intent so user is prompted to unlock the device. mContext.startActivity(new Intent(Intent.ACTION_MAIN) .addCategory(Intent.CATEGORY_HOME) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java index eb5366ca0f..b0acffa398 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java @@ -23,6 +23,7 @@ import static android.view.MotionEvent.ACTION_POINTER_UP; import static android.view.MotionEvent.ACTION_UP; import static android.view.MotionEvent.INVALID_POINTER_ID; import static com.android.launcher3.Utilities.EDGE_NAV_BAR; +import static com.android.launcher3.Utilities.squaredHypot; import static com.android.launcher3.uioverrides.RecentsUiFactory.ROTATION_LANDSCAPE; import static com.android.launcher3.uioverrides.RecentsUiFactory.ROTATION_SEASCAPE; import static com.android.launcher3.util.RaceConditionTracker.ENTER; @@ -109,7 +110,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC private int mActivePointerId = INVALID_POINTER_ID; private final float mDragSlop; - private final float mTouchSlop; + private final float mSquaredTouchSlop; // Slop used to check when we start moving window. private boolean mPassedDragSlop; @@ -157,7 +158,8 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC mDisplayRotation = getSystemService(WindowManager.class).getDefaultDisplay().getRotation(); mDragSlop = QuickStepContract.getQuickStepDragSlopPx(); - mTouchSlop = QuickStepContract.getQuickStepTouchSlopPx(); + float slop = QuickStepContract.getQuickStepTouchSlopPx(); + mSquaredTouchSlop = slop * slop; mPassedTouchSlop = mPassedDragSlop = continuingPreviousGesture; } @@ -256,7 +258,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC } if (!mPassedTouchSlop) { - if (Math.hypot(displacementX, mLastPos.y - mDownPos.y) >= mTouchSlop) { + if (squaredHypot(displacementX, mLastPos.y - mDownPos.y) >= mSquaredTouchSlop) { mPassedTouchSlop = true; if (mIsDeferredDownTarget) { diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java index a835680c2b..1e1007e686 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java @@ -20,6 +20,8 @@ import static com.android.launcher3.BaseActivity.STATE_HANDLER_INVISIBILITY_FLAG import static com.android.launcher3.InvariantDeviceProfile.CHANGE_FLAG_ICON_PARAMS; import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY; import static com.android.launcher3.Utilities.EDGE_NAV_BAR; +import static com.android.launcher3.Utilities.squaredHypot; +import static com.android.launcher3.Utilities.squaredTouchSlop; import static com.android.launcher3.anim.Interpolators.ACCEL; import static com.android.launcher3.anim.Interpolators.ACCEL_2; import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN; @@ -64,7 +66,6 @@ import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; -import android.view.ViewConfiguration; import android.view.ViewDebug; import android.view.ViewGroup; import android.view.accessibility.AccessibilityEvent; @@ -75,7 +76,6 @@ import com.android.launcher3.BaseActivity; import com.android.launcher3.DeviceProfile; import com.android.launcher3.Insettable; import com.android.launcher3.InvariantDeviceProfile; -import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAnimUtils.ViewProgressProperty; import com.android.launcher3.LauncherState; import com.android.launcher3.PagedView; @@ -93,7 +93,6 @@ import com.android.launcher3.util.OverScroller; import com.android.launcher3.util.PendingAnimation; import com.android.launcher3.util.Themes; import com.android.launcher3.util.ViewPool; -import com.android.launcher3.views.FloatingIconView; import com.android.quickstep.RecentsAnimationWrapper; import com.android.quickstep.RecentsModel; import com.android.quickstep.RecentsModel.TaskThumbnailChangeListener; @@ -281,7 +280,7 @@ public abstract class RecentsView extends PagedView impl private boolean mHandleTaskStackChanges; private boolean mSwipeDownShouldLaunchApp; private boolean mTouchDownToStartHome; - private final int mTouchSlop; + private final float mSquaredTouchSlop; private int mDownX; private int mDownY; @@ -306,8 +305,6 @@ public abstract class RecentsView extends PagedView impl private Layout mEmptyTextLayout; private LiveTileOverlay mLiveTileOverlay; - private FloatingIconView mFloatingIconView; - private BaseActivity.MultiWindowModeChangedListener mMultiWindowModeChangedListener = (inMultiWindowMode) -> { if (!inMultiWindowMode && mOverviewStateEnabled) { @@ -339,7 +336,7 @@ public abstract class RecentsView extends PagedView impl setLayoutDirection(mIsRtl ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR); mTaskTopMargin = getResources() .getDimensionPixelSize(R.dimen.task_thumbnail_top_margin); - mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); + mSquaredTouchSlop = squaredTouchSlop(context); mEmptyIcon = context.getDrawable(R.drawable.ic_empty_recents); mEmptyIcon.setCallback(this); @@ -496,7 +493,8 @@ public abstract class RecentsView extends PagedView impl case MotionEvent.ACTION_MOVE: // Passing the touch slop will not allow dismiss to home if (mTouchDownToStartHome && - (isHandlingTouch() || Math.hypot(mDownX - x, mDownY - y) > mTouchSlop)) { + (isHandlingTouch() || + squaredHypot(mDownX - x, mDownY - y) > mSquaredTouchSlop)) { mTouchDownToStartHome = false; } break; @@ -1684,12 +1682,6 @@ public abstract class RecentsView extends PagedView impl } } - public FloatingIconView getFloatingIconView(Launcher launcher, View view, RectF iconLocation) { - mFloatingIconView = FloatingIconView.getFloatingIconView(launcher, view, - true /* hideOriginal */, iconLocation, false /* isOpening */, mFloatingIconView); - return mFloatingIconView; - } - public ClipAnimationHelper getTempClipAnimationHelper() { return mTempClipAnimationHelper; } diff --git a/quickstep/res/layout/task.xml b/quickstep/res/layout/task.xml index ecf1b0a19b..ba4ea8bc6d 100644 --- a/quickstep/res/layout/task.xml +++ b/quickstep/res/layout/task.xml @@ -36,6 +36,7 @@ android:importantForAccessibility="no" /> diff --git a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java index 91c460148d..95ae312891 100644 --- a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java +++ b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java @@ -142,7 +142,6 @@ public abstract class QuickstepAppTransitionManagerImpl extends LauncherAppTrans private final float mClosingWindowTransY; private DeviceProfile mDeviceProfile; - private FloatingIconView mFloatingView; private RemoteAnimationProvider mRemoteAnimationProvider; @@ -411,15 +410,15 @@ public abstract class QuickstepAppTransitionManagerImpl extends LauncherAppTrans private ValueAnimator getOpeningWindowAnimators(View v, RemoteAnimationTargetCompat[] targets, Rect windowTargetBounds, boolean toggleVisibility) { RectF bounds = new RectF(); - mFloatingView = FloatingIconView.getFloatingIconView(mLauncher, v, toggleVisibility, - bounds, true /* isOpening */, mFloatingView); + FloatingIconView floatingView = FloatingIconView.getFloatingIconView(mLauncher, v, + toggleVisibility, bounds, true /* isOpening */); Rect crop = new Rect(); Matrix matrix = new Matrix(); RemoteAnimationTargetSet openingTargets = new RemoteAnimationTargetSet(targets, MODE_OPENING); SyncRtSurfaceTransactionApplierCompat surfaceApplier = - new SyncRtSurfaceTransactionApplierCompat(mFloatingView); + new SyncRtSurfaceTransactionApplierCompat(floatingView); openingTargets.addDependentTransactionApplier(surfaceApplier); // Scale the app icon to take up the entire screen. This simplifies the math when @@ -463,7 +462,7 @@ public abstract class QuickstepAppTransitionManagerImpl extends LauncherAppTrans ValueAnimator appAnimator = ValueAnimator.ofFloat(0, 1); appAnimator.setDuration(APP_LAUNCH_DURATION); appAnimator.setInterpolator(LINEAR); - appAnimator.addListener(mFloatingView); + appAnimator.addListener(floatingView); appAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { @@ -557,7 +556,7 @@ public abstract class QuickstepAppTransitionManagerImpl extends LauncherAppTrans } else { currentBounds.bottom -= croppedHeight; } - mFloatingView.update(currentBounds, mIconAlpha.value, percent, 0f, + floatingView.update(currentBounds, mIconAlpha.value, percent, 0f, cornerRadius * scale, true /* isOpening */); } else { matrix.setTranslate(target.position.x, target.position.y); diff --git a/quickstep/src/com/android/quickstep/TestInformationProvider.java b/quickstep/src/com/android/quickstep/TestInformationProvider.java index b37ddda097..d96f9af6fe 100644 --- a/quickstep/src/com/android/quickstep/TestInformationProvider.java +++ b/quickstep/src/com/android/quickstep/TestInformationProvider.java @@ -111,6 +111,14 @@ public class TestInformationProvider extends ContentProvider { 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/res/layout/floating_icon_view.xml b/res/layout/floating_icon_view.xml new file mode 100644 index 0000000000..240c486b19 --- /dev/null +++ b/res/layout/floating_icon_view.xml @@ -0,0 +1,19 @@ + + + diff --git a/res/values/config.xml b/res/values/config.xml index 83aea8b1f0..984729b20f 100644 --- a/res/values/config.xml +++ b/res/values/config.xml @@ -86,7 +86,6 @@ - diff --git a/src/com/android/launcher3/BaseActivity.java b/src/com/android/launcher3/BaseActivity.java index 7f7224241b..424ffde1ff 100644 --- a/src/com/android/launcher3/BaseActivity.java +++ b/src/com/android/launcher3/BaseActivity.java @@ -36,6 +36,7 @@ import com.android.launcher3.logging.UserEventDispatcher.UserEventDelegate; import com.android.launcher3.uioverrides.UiFactory; import com.android.launcher3.userevent.nano.LauncherLogProto; import com.android.launcher3.util.SystemUiController; +import com.android.launcher3.util.ViewCache; import com.android.launcher3.views.ActivityContext; import java.io.FileDescriptor; @@ -102,6 +103,12 @@ public abstract class BaseActivity extends Activity // animation @InvisibilityFlags private int mForceInvisible; + private final ViewCache mViewCache = new ViewCache(); + + public ViewCache getViewCache() { + return mViewCache; + } + @Override public DeviceProfile getDeviceProfile() { return mDeviceProfile; diff --git a/src/com/android/launcher3/BaseDraggingActivity.java b/src/com/android/launcher3/BaseDraggingActivity.java index ccd9e2529e..bd6ac90f39 100644 --- a/src/com/android/launcher3/BaseDraggingActivity.java +++ b/src/com/android/launcher3/BaseDraggingActivity.java @@ -134,6 +134,10 @@ 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, + "startActivitySafely 1"); + } if (mIsSafeModeEnabled && !Utilities.isSystemApp(this, intent)) { Toast.makeText(this, R.string.safemode_shortcut_error, Toast.LENGTH_SHORT).show(); return false; @@ -157,6 +161,10 @@ 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, + "startActivitySafely 2"); + } startActivity(intent, optsBundle); AppLaunchTracker.INSTANCE.get(this).onStartApp(intent.getComponent(), Process.myUserHandle(), sourceContainer); diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java index bff7f42131..2f801e04b9 100644 --- a/src/com/android/launcher3/BubbleTextView.java +++ b/src/com/android/launcher3/BubbleTextView.java @@ -51,7 +51,6 @@ import com.android.launcher3.graphics.PreloadIconDrawable; import com.android.launcher3.icons.DotRenderer; import com.android.launcher3.icons.IconCache.IconLoadRequest; import com.android.launcher3.icons.IconCache.ItemInfoUpdateReceiver; -import com.android.launcher3.icons.LauncherIcons; import com.android.launcher3.model.PackageItemInfo; import com.android.launcher3.views.ActivityContext; @@ -561,7 +560,10 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, } } if (itemInfo.contentDescription != null) { - if (hasDot()) { + if (itemInfo.isDisabled()) { + setContentDescription(getContext().getString(R.string.disabled_app_label, + itemInfo.contentDescription)); + } else if (hasDot()) { int count = mDotInfo.getNotificationCount(); setContentDescription(getContext().getResources().getQuantityString( R.plurals.dotted_app_label, count, itemInfo.contentDescription, count)); diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 40eb912df5..a59189beaa 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -1782,6 +1782,10 @@ 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, + "startActivitySafely outer"); + } boolean success = super.startActivitySafely(v, intent, item, sourceContainer); if (success && v instanceof BubbleTextView) { // This is set to the view that launched the activity that navigated the user away diff --git a/src/com/android/launcher3/LauncherStateManager.java b/src/com/android/launcher3/LauncherStateManager.java index b1a3fc992e..49ae33894a 100644 --- a/src/com/android/launcher3/LauncherStateManager.java +++ b/src/com/android/launcher3/LauncherStateManager.java @@ -447,6 +447,10 @@ 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, + "onStateTransitionStart"); + } if (mState != state) { mState.onStateDisabled(mLauncher); } @@ -572,6 +576,10 @@ 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, + "StartAnimRunnable"); + } mAnim = anim; } diff --git a/src/com/android/launcher3/ResourceUtils.java b/src/com/android/launcher3/ResourceUtils.java index 8df3290fd0..0c80d130ea 100644 --- a/src/com/android/launcher3/ResourceUtils.java +++ b/src/com/android/launcher3/ResourceUtils.java @@ -21,8 +21,10 @@ import android.util.DisplayMetrics; import android.util.TypedValue; public class ResourceUtils { - public static final String NAVBAR_VERTICAL_SIZE = "navigation_bar_frame_height"; - public static final String NAVBAR_HORIZONTAL_SIZE = "navigation_bar_width"; + 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 int getNavbarSize(String resName, Resources res) { return getDimenByName(resName, res, 48); diff --git a/src/com/android/launcher3/TestProtocol.java b/src/com/android/launcher3/TestProtocol.java index eefecda5d7..a0440e877e 100644 --- a/src/com/android/launcher3/TestProtocol.java +++ b/src/com/android/launcher3/TestProtocol.java @@ -64,4 +64,9 @@ public final class TestProtocol { "all-apps-to-overview-swipe-height"; public static final String REQUEST_HOME_TO_ALL_APPS_SWIPE_HEIGHT = "home-to-all-apps-swipe-height"; + public static boolean sDebugTracing = false; + public static final String REQUEST_ENABLE_DEBUG_TRACING = "enable-debug-tracing"; + public static final String REQUEST_DISABLE_DEBUG_TRACING = "disable-debug-tracing"; + public static final String NO_DRAG_TAG = "b/133009122"; + public static final String NO_START_TAG = "b/132900132"; } diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java index 796fd25057..cc9bda7106 100644 --- a/src/com/android/launcher3/Utilities.java +++ b/src/com/android/launcher3/Utilities.java @@ -61,6 +61,7 @@ import android.util.Pair; import android.util.TypedValue; import android.view.MotionEvent; import android.view.View; +import android.view.ViewConfiguration; import android.view.animation.Interpolator; import com.android.launcher3.compat.LauncherAppsCompat; @@ -726,6 +727,15 @@ public final class Utilities { return str.toString(); } + public static float squaredHypot(float x, float y) { + return x * x + y * y; + } + + public static float squaredTouchSlop(Context context) { + float slop = ViewConfiguration.get(context).getScaledTouchSlop(); + return slop * slop; + } + private static class FixedSizeEmptyDrawable extends ColorDrawable { private final int mSize; diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index a508ce52bd..d19f9cd73f 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -371,6 +371,10 @@ 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, + "onDragStart 1"); + } if (ENFORCE_DRAG_EVENT_ORDER) { enforceDragParity("onDragStart", 0, 0); } @@ -421,6 +425,10 @@ 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, + "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 41252aab54..63682c73ac 100644 --- a/src/com/android/launcher3/allapps/AllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java @@ -41,6 +41,7 @@ import com.android.launcher3.Insettable; import com.android.launcher3.InsettableFrameLayout; 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.Utilities; @@ -193,11 +194,18 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo @Override public boolean onInterceptTouchEvent(MotionEvent ev) { + + // The AllAppsContainerView houses the QSB and is hence visible from the Workspace + // Overview states. We shouldn't intercept for the scrubber in these cases. + if (!mLauncher.isInState(LauncherState.ALL_APPS)) return false; + if (ev.getAction() == MotionEvent.ACTION_DOWN) { AllAppsRecyclerView rv = getActiveRecyclerView(); if (rv != null && rv.getScrollbar().isHitInParent(ev.getX(), ev.getY(), mFastScrollerOffset)) { mTouchHandler = rv.getScrollbar(); + } else { + mTouchHandler = null; } } if (mTouchHandler != null) { diff --git a/src/com/android/launcher3/dragndrop/DragController.java b/src/com/android/launcher3/dragndrop/DragController.java index f92e00acba..bf692fe472 100644 --- a/src/com/android/launcher3/dragndrop/DragController.java +++ b/src/com/android/launcher3/dragndrop/DragController.java @@ -472,6 +472,10 @@ 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, + "handleMoveEvent 1"); + } mDragObject.dragView.move(x, y); // Drop on someone? @@ -488,6 +492,10 @@ 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, + "handleMoveEvent 2"); + } callOnDragStart(); } } @@ -525,6 +533,10 @@ 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, + "onControllerTouchEvent"); + } if (mDragDriver == null || mOptions == null || mOptions.isAccessibleDrag) { return false; } diff --git a/src/com/android/launcher3/dragndrop/DragView.java b/src/com/android/launcher3/dragndrop/DragView.java index 7af12c57d4..9d46cf2abf 100644 --- a/src/com/android/launcher3/dragndrop/DragView.java +++ b/src/com/android/launcher3/dragndrop/DragView.java @@ -44,7 +44,6 @@ 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; @@ -55,6 +54,7 @@ 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,8 +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. - final Looper workerLooper = LauncherModel.getWorkerLooper(); - new Handler(workerLooper).postAtFrontOfQueue(new Runnable() { + new Handler(UiThreadHelper.getBackgroundLooper()).postAtFrontOfQueue(new Runnable() { @Override public void run() { Object[] outObj = new Object[1]; diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java index 389e85269b..2ef6d707e3 100644 --- a/src/com/android/launcher3/folder/Folder.java +++ b/src/com/android/launcher3/folder/Folder.java @@ -593,6 +593,10 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo protected void handleClose(boolean animate) { mIsOpen = false; + if (!animate && mCurrentAnimator != null && mCurrentAnimator.isRunning()) { + mCurrentAnimator.cancel(); + } + if (isEditingName()) { mFolderName.dispatchBackKey(); } diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java index 8d9c52065b..250169cdb2 100644 --- a/src/com/android/launcher3/folder/FolderIcon.java +++ b/src/com/android/launcher3/folder/FolderIcon.java @@ -102,7 +102,6 @@ public class FolderIcon extends FrameLayout implements FolderListener { private List mCurrentPreviewItems = new ArrayList<>(); boolean mAnimating = false; - private Rect mTempBounds = new Rect(); private float mSlop; @@ -203,6 +202,10 @@ public class FolderIcon extends FrameLayout implements FolderListener { mBackground.getBounds(outBounds); } + public float getBackgroundStrokeWidth() { + return mBackground.getStrokeWidth(); + } + public Folder getFolder() { return mFolder; } diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java index 047f4862b6..7b14fa2491 100644 --- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java +++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java @@ -16,6 +16,8 @@ package com.android.launcher3.popup; +import static com.android.launcher3.Utilities.squaredHypot; +import static com.android.launcher3.Utilities.squaredTouchSlop; import static com.android.launcher3.notification.NotificationMainView.NOTIFICATION_ITEM_INFO; import static com.android.launcher3.popup.PopupPopulator.MAX_SHORTCUTS; import static com.android.launcher3.popup.PopupPopulator.MAX_SHORTCUTS_IF_NOTIFICATIONS; @@ -37,7 +39,6 @@ import android.util.AttributeSet; import android.util.Pair; import android.view.MotionEvent; import android.view.View; -import android.view.ViewConfiguration; import android.view.ViewGroup; import android.widget.ImageView; @@ -51,6 +52,7 @@ import com.android.launcher3.ItemInfoWithIcon; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherModel; import com.android.launcher3.R; +import com.android.launcher3.Utilities; import com.android.launcher3.accessibility.LauncherAccessibilityDelegate; import com.android.launcher3.accessibility.ShortcutMenuAccessibilityDelegate; import com.android.launcher3.dot.DotInfo; @@ -136,8 +138,8 @@ public class PopupContainerWithArrow extends ArrowPopup implements DragSource, return true; } // Stop sending touch events to deep shortcut views if user moved beyond touch slop. - return Math.hypot(mInterceptTouchDown.x - ev.getX(), mInterceptTouchDown.y - ev.getY()) - > ViewConfiguration.get(getContext()).getScaledTouchSlop(); + return squaredHypot(mInterceptTouchDown.x - ev.getX(), mInterceptTouchDown.y - ev.getY()) + > squaredTouchSlop(getContext()); } @Override diff --git a/src/com/android/launcher3/touch/ItemClickHandler.java b/src/com/android/launcher3/touch/ItemClickHandler.java index 06500018d5..99b9f25b18 100644 --- a/src/com/android/launcher3/touch/ItemClickHandler.java +++ b/src/com/android/launcher3/touch/ItemClickHandler.java @@ -66,14 +66,26 @@ 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, + "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, + "onClick 2"); + } return; } 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, + "onClick 3"); + } return; } @@ -85,6 +97,10 @@ 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, + "onClick 4"); + } startAppShortcutOrInfoActivity(v, (AppInfo) tag, launcher, sourceContainer == null ? CONTAINER_ALL_APPS: sourceContainer); } else if (tag instanceof LauncherAppWidgetInfo) { @@ -216,6 +232,10 @@ 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, + "startAppShortcutOrInfoActivity"); + } Intent intent; if (item instanceof PromiseAppInfo) { PromiseAppInfo promiseAppInfo = (PromiseAppInfo) item; diff --git a/src/com/android/launcher3/util/ViewCache.java b/src/com/android/launcher3/util/ViewCache.java new file mode 100644 index 0000000000..08b8744167 --- /dev/null +++ b/src/com/android/launcher3/util/ViewCache.java @@ -0,0 +1,73 @@ +/* + * 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.util; + +import android.content.Context; +import android.util.SparseArray; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +/** + * Utility class to cache views at an activity level + */ +public class ViewCache { + + protected final SparseArray mCache = new SparseArray(); + + public void setCacheSize(int layoutId, int size) { + mCache.put(layoutId, new CacheEntry(size)); + } + + public T getView(int layoutId, Context context, ViewGroup parent) { + CacheEntry entry = mCache.get(layoutId); + if (entry == null) { + entry = new CacheEntry(1); + mCache.put(layoutId, entry); + } + + if (entry.mCurrentSize > 0) { + entry.mCurrentSize --; + T result = (T) entry.mViews[entry.mCurrentSize]; + entry.mViews[entry.mCurrentSize] = null; + return result; + } + + return (T) LayoutInflater.from(context).inflate(layoutId, parent, false); + } + + public void recycleView(int layoutId, View view) { + CacheEntry entry = mCache.get(layoutId); + if (entry != null && entry.mCurrentSize < entry.mMaxSize) { + entry.mViews[entry.mCurrentSize] = view; + entry.mCurrentSize++; + } + } + + private static class CacheEntry { + + final int mMaxSize; + final View[] mViews; + + int mCurrentSize; + + public CacheEntry(int maxSize) { + mMaxSize = maxSize; + mViews = new View[maxSize]; + mCurrentSize = 0; + } + } +} diff --git a/src/com/android/launcher3/views/BaseDragLayer.java b/src/com/android/launcher3/views/BaseDragLayer.java index 3c81bcf399..4964182409 100644 --- a/src/com/android/launcher3/views/BaseDragLayer.java +++ b/src/com/android/launcher3/views/BaseDragLayer.java @@ -213,6 +213,10 @@ 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, + "onTouchEvent " + ev); + } int action = ev.getAction(); if (action == ACTION_UP || action == ACTION_CANCEL) { if (mTouchCompleteListener != null) { @@ -222,6 +226,10 @@ public abstract class BaseDragLayer } if (mActiveController != null) { + if (com.android.launcher3.TestProtocol.sDebugTracing) { + android.util.Log.d(com.android.launcher3.TestProtocol.NO_DRAG_TAG, + "onTouchEvent 1"); + } return mActiveController.onControllerTouchEvent(ev); } else { // In case no child view handled the touch event, we may not get onIntercept anymore diff --git a/src/com/android/launcher3/views/FloatingIconView.java b/src/com/android/launcher3/views/FloatingIconView.java index e5c75c3fca..f63bcddf0d 100644 --- a/src/com/android/launcher3/views/FloatingIconView.java +++ b/src/com/android/launcher3/views/FloatingIconView.java @@ -27,6 +27,7 @@ import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.annotation.TargetApi; +import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Outline; @@ -40,6 +41,7 @@ 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; import android.view.ViewOutlineProvider; @@ -61,6 +63,7 @@ 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; @@ -148,12 +151,20 @@ public class FloatingIconView extends View implements private final SpringAnimation mFgSpringX; private float mFgTransX; - private FloatingIconView(Launcher launcher) { - super(launcher); - mLauncher = launcher; + public FloatingIconView(Context context) { + this(context, null); + } + + public FloatingIconView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public FloatingIconView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + mLauncher = Launcher.getLauncher(context); mBlurSizeOutline = getResources().getDimensionPixelSize( R.dimen.blur_size_medium_outline); - mListenerView = new ListenerView(launcher, null); + mListenerView = new ListenerView(context, attrs); mFgSpringX = new SpringAnimation(this, mFgTransXProperty) .setSpring(new SpringForce() @@ -259,8 +270,6 @@ public class FloatingIconView extends View implements mFgSpringX.animateToFinalPosition(diffX); mFgSpringY.animateToFinalPosition(diffY); } - - } invalidate(); invalidateOutline(); @@ -352,6 +361,7 @@ public class FloatingIconView extends View implements } @WorkerThread + @SuppressWarnings("WrongThread") private void getIcon(View v, ItemInfo info, boolean isOpening, Runnable onIconLoadedRunnable, CancellationSignal loadIconSignal) { final LayoutParams lp = (LayoutParams) getLayoutParams(); @@ -368,10 +378,13 @@ public class FloatingIconView extends View implements drawable = v.getBackground(); } } else { + boolean isFolderIcon = v instanceof FolderIcon; + int width = isFolderIcon ? v.getWidth() : lp.width; + int height = isFolderIcon ? v.getHeight() : lp.height; if (supportsAdaptiveIcons) { - drawable = Utilities.getFullDrawable(mLauncher, info, lp.width, lp.height, - false, sTmpObjArray); - if ((drawable instanceof AdaptiveIconDrawable)) { + drawable = Utilities.getFullDrawable(mLauncher, info, width, height, false, + sTmpObjArray); + if (drawable instanceof AdaptiveIconDrawable) { mBadge = getBadge(mLauncher, info, sTmpObjArray[0]); } else { // The drawable we get back is not an adaptive icon, so we need to use the @@ -383,8 +396,8 @@ public class FloatingIconView extends View implements // Similar to DragView, we simply use the BubbleTextView icon here. drawable = btvIcon; } else { - drawable = Utilities.getFullDrawable(mLauncher, info, lp.width, lp.height, - false, sTmpObjArray); + drawable = Utilities.getFullDrawable(mLauncher, info, width, height, false, + sTmpObjArray); } } } @@ -395,7 +408,7 @@ public class FloatingIconView extends View implements && finalDrawable instanceof AdaptiveIconDrawable; int iconOffset = getOffsetForIconBounds(finalDrawable); - new Handler(Looper.getMainLooper()).post(() -> { + mLauncher.getMainExecutor().execute(() -> { if (isAdaptiveIcon) { mIsAdaptiveIcon = true; boolean isFolderIcon = finalDrawable instanceof FolderAdaptiveIcon; @@ -412,13 +425,6 @@ public class FloatingIconView extends View implements } mForeground = foreground; - if (mForeground instanceof ShiftedBitmapDrawable && v instanceof FolderIcon) { - ShiftedBitmapDrawable sbd = (ShiftedBitmapDrawable) mForeground; - ((FolderIcon) v).getPreviewBounds(sTmpRect); - sbd.setShiftX(sbd.getShiftX() - sTmpRect.left); - sbd.setShiftY(sbd.getShiftY() - sTmpRect.top); - } - final int originalHeight = lp.height; final int originalWidth = lp.width; @@ -434,13 +440,25 @@ public class FloatingIconView extends View implements if (mBadge != null) { mBadge.setBounds(mStartRevealRect); - if (!isOpening) { + if (!isOpening && !isFolderIcon) { DRAWABLE_ALPHA.set(mBadge, 0); } - } - if (!isFolderIcon) { + if (isFolderIcon) { + ((FolderIcon) v).getPreviewBounds(sTmpRect); + float bgStroke = ((FolderIcon) v).getBackgroundStrokeWidth(); + if (mForeground instanceof ShiftedBitmapDrawable) { + ShiftedBitmapDrawable sbd = (ShiftedBitmapDrawable) mForeground; + sbd.setShiftX(sbd.getShiftX() - sTmpRect.left - bgStroke); + sbd.setShiftY(sbd.getShiftY() - sTmpRect.top - bgStroke); + } + if (mBadge instanceof ShiftedBitmapDrawable) { + ShiftedBitmapDrawable sbd = (ShiftedBitmapDrawable) mBadge; + sbd.setShiftX(sbd.getShiftX() - sTmpRect.left - bgStroke); + sbd.setShiftY(sbd.getShiftY() - sTmpRect.top - bgStroke); + } + } else { Utilities.scaleRectAboutCenter(mStartRevealRect, IconShape.getNormalizationScale()); } @@ -475,6 +493,7 @@ public class FloatingIconView extends View implements setClipToOutline(true); } else { setBackground(finalDrawable); + setClipToOutline(false); } if (!loadIconSignal.isCanceled()) { @@ -498,6 +517,7 @@ public class FloatingIconView extends View implements } @WorkerThread + @SuppressWarnings("WrongThread") private int getOffsetForIconBounds(Drawable drawable) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O || !(drawable instanceof AdaptiveIconDrawable)) { @@ -508,7 +528,7 @@ public class FloatingIconView extends View implements Rect bounds = new Rect(0, 0, lp.width + mBlurSizeOutline, lp.height + mBlurSizeOutline); bounds.inset(mBlurSizeOutline / 2, mBlurSizeOutline / 2); - try (LauncherIcons li = LauncherIcons.obtain(getContext())) { + try (LauncherIcons li = LauncherIcons.obtain(mLauncher)) { Utilities.scaleRectAboutCenter(bounds, li.getNormalizer().getScale(drawable, null)); } @@ -597,11 +617,14 @@ public class FloatingIconView extends View implements * @param isOpening True if this view replaces the icon for app open animation. */ public static FloatingIconView getFloatingIconView(Launcher launcher, View originalView, - boolean hideOriginal, RectF positionOut, boolean isOpening, FloatingIconView recycle) { - if (recycle != null) { - recycle.recycle(); - } - FloatingIconView view = recycle != null ? recycle : new FloatingIconView(launcher); + boolean hideOriginal, RectF positionOut, boolean isOpening) { + final DragLayer dragLayer = launcher.getDragLayer(); + ViewGroup parent = (ViewGroup) dragLayer.getParent(); + + FloatingIconView view = launcher.getViewCache().getView(R.layout.floating_icon_view, + launcher, parent); + view.recycle(); + view.mIsVerticalBarLayout = launcher.getDeviceProfile().isVerticalBarLayout(); view.mOriginalIcon = originalView; @@ -619,16 +642,15 @@ public class FloatingIconView extends View implements originalView.setVisibility(INVISIBLE); }; CancellationSignal loadIconSignal = view.mLoadIconSignal; - new Handler(LauncherModel.getWorkerLooper()).postAtFrontOfQueue(() -> { + new Handler(UiThreadHelper.getBackgroundLooper()).postAtFrontOfQueue(() -> { view.getIcon(originalView, (ItemInfo) originalView.getTag(), isOpening, onIconLoaded, loadIconSignal); }); } // We need to add it to the overlay, but keep it invisible until animation starts.. - final DragLayer dragLayer = launcher.getDragLayer(); view.setVisibility(INVISIBLE); - ((ViewGroup) dragLayer.getParent()).addView(view); + parent.addView(view); dragLayer.addView(view.mListenerView); view.mListenerView.setListener(view::onListenerViewClosed); @@ -665,7 +687,7 @@ public class FloatingIconView extends View implements } }); - if (mBadge != null) { + if (mBadge != null && !(mOriginalIcon instanceof FolderIcon)) { ObjectAnimator badgeFade = ObjectAnimator.ofInt(mBadge, DRAWABLE_ALPHA, 255); badgeFade.addUpdateListener(valueAnimator -> invalidate()); fade.play(badgeFade); @@ -691,7 +713,6 @@ public class FloatingIconView extends View implements @Override public void onAnimationEnd(Animator animation) { folderIcon.setBackgroundVisible(true); - folderIcon.animateBgShadowAndStroke(); if (folderIcon.hasDot()) { folderIcon.animateDotScale(0, 1f); } @@ -708,6 +729,7 @@ public class FloatingIconView extends View implements ((ViewGroup) dragLayer.getParent()).removeView(this); dragLayer.removeView(mListenerView); recycle(); + mLauncher.getViewCache().recycleView(R.layout.floating_icon_view, this); } private void recycle() { @@ -746,5 +768,6 @@ public class FloatingIconView extends View implements mFgTransX = 0; mFgSpringY.cancel(); mBadge = null; + sTmpObjArray[0] = null; } } diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java index ca6d968cc1..74cece836c 100644 --- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java +++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java @@ -243,7 +243,7 @@ public abstract class AbstractLauncherUiTest { */ protected UiObject2 scrollAndFind(UiObject2 container, BySelector condition) { final int margin = ResourceUtils.getNavbarSize( - ResourceUtils.NAVBAR_VERTICAL_SIZE, mLauncher.getResources()) + 1; + ResourceUtils.NAVBAR_PORTRAIT_BOTTOM_SIZE, mLauncher.getResources()) + 1; container.setGestureMargins(0, 0, 0, margin); int i = 0; diff --git a/tests/tapl/com/android/launcher3/tapl/AllApps.java b/tests/tapl/com/android/launcher3/tapl/AllApps.java index a296975c3c..70405fed8a 100644 --- a/tests/tapl/com/android/launcher3/tapl/AllApps.java +++ b/tests/tapl/com/android/launcher3/tapl/AllApps.java @@ -18,6 +18,7 @@ package com.android.launcher3.tapl; import static com.android.launcher3.tapl.LauncherInstrumentation.NavigationModel.ZERO_BUTTON; +import android.graphics.Point; import android.graphics.Rect; import androidx.annotation.NonNull; @@ -48,12 +49,34 @@ public class AllApps extends LauncherInstrumentation.VisibleContainer { return LauncherInstrumentation.ContainerType.ALL_APPS; } - private boolean hasClickableIcon(UiObject2 allAppsContainer, BySelector appIconSelector) { - final UiObject2 icon = allAppsContainer.findObject(appIconSelector); - if (icon == null) return false; - if (mLauncher.getNavigationModel() == ZERO_BUTTON) return true; - final UiObject2 navBar = mLauncher.waitForSystemUiObject("navigation_bar_frame"); - return icon.getVisibleBounds().bottom < navBar.getVisibleBounds().top; + private boolean hasClickableIcon( + UiObject2 allAppsContainer, UiObject2 appListRecycler, BySelector appIconSelector) { + final UiObject2 icon = appListRecycler.findObject(appIconSelector); + if (icon == null) { + LauncherInstrumentation.log("hasClickableIcon: icon not visible"); + return false; + } + final Rect iconBounds = icon.getVisibleBounds(); + LauncherInstrumentation.log("hasClickableIcon: icon bounds: " + iconBounds); + if (mLauncher.getNavigationModel() != ZERO_BUTTON) { + final UiObject2 navBar = mLauncher.waitForSystemUiObject("navigation_bar_frame"); + if (iconBounds.bottom >= navBar.getVisibleBounds().top) { + LauncherInstrumentation.log("hasClickableIcon: icon intersects with nav bar"); + return false; + } + } + if (iconCenterInSearchBox(allAppsContainer, icon)) { + LauncherInstrumentation.log("hasClickableIcon: icon center is under search box"); + return false; + } + LauncherInstrumentation.log("hasClickableIcon: icon is clickable"); + return true; + } + + private boolean iconCenterInSearchBox(UiObject2 allAppsContainer, UiObject2 icon) { + final Point iconCenter = icon.getVisibleCenter(); + return getSearchBox(allAppsContainer).getVisibleBounds().contains( + iconCenter.x, iconCenter.y); } /** @@ -66,17 +89,22 @@ public class AllApps extends LauncherInstrumentation.VisibleContainer { @NonNull public AppIcon getAppIcon(String appName) { try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer( - "want to get app icon on all apps")) { + "want to get app icon " + appName + " on all apps")) { final UiObject2 allAppsContainer = verifyActiveContainer(); - allAppsContainer.setGestureMargins(0, 0, 0, - ResourceUtils.getNavbarSize(ResourceUtils.NAVBAR_VERTICAL_SIZE, + final UiObject2 appListRecycler = mLauncher.waitForObjectInContainer(allAppsContainer, + "apps_list_view"); + allAppsContainer.setGestureMargins( + 0, + getSearchBox(allAppsContainer).getVisibleBounds().bottom + 1, + 0, + ResourceUtils.getNavbarSize(ResourceUtils.NAVBAR_PORTRAIT_BOTTOM_SIZE, mLauncher.getResources()) + 1); final BySelector appIconSelector = AppIcon.getAppIconSelector(appName, mLauncher); - if (!hasClickableIcon(allAppsContainer, appIconSelector)) { + if (!hasClickableIcon(allAppsContainer, appListRecycler, appIconSelector)) { scrollBackToBeginning(); int attempts = 0; try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer("scrolled")) { - while (!hasClickableIcon(allAppsContainer, appIconSelector) && + while (!hasClickableIcon(allAppsContainer, appListRecycler, appIconSelector) && allAppsContainer.scroll(Direction.DOWN, 0.8f)) { mLauncher.assertTrue( "Exceeded max scroll attempts: " + MAX_SCROLL_ATTEMPTS, @@ -89,7 +117,7 @@ public class AllApps extends LauncherInstrumentation.VisibleContainer { final UiObject2 appIcon = mLauncher.getObjectInContainer(allAppsContainer, appIconSelector); - ensureIconVisible(appIcon, allAppsContainer); + ensureIconVisible(appIcon, allAppsContainer, appListRecycler); return new AppIcon(mLauncher, appIcon); } } @@ -97,10 +125,9 @@ public class AllApps extends LauncherInstrumentation.VisibleContainer { private void scrollBackToBeginning() { try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer( "want to scroll back in all apps")) { + LauncherInstrumentation.log("Scrolling to the beginning"); final UiObject2 allAppsContainer = verifyActiveContainer(); - final UiObject2 searchBox = - mLauncher.waitForObjectInContainer(allAppsContainer, - "search_container_all_apps"); + final UiObject2 searchBox = getSearchBox(allAppsContainer); int attempts = 0; final Rect margins = new Rect(0, searchBox.getVisibleBounds().bottom + 1, 0, 5); @@ -128,19 +155,26 @@ public class AllApps extends LauncherInstrumentation.VisibleContainer { getInt(TestProtocol.SCROLL_Y_FIELD, -1); } - private void ensureIconVisible(UiObject2 appIcon, UiObject2 allAppsContainer) { + private void ensureIconVisible( + UiObject2 appIcon, UiObject2 allAppsContainer, UiObject2 appListRecycler) { final int appHeight = appIcon.getVisibleBounds().height(); if (appHeight < MIN_INTERACT_SIZE) { // Try to figure out how much percentage of the container needs to be scrolled in order // to reveal the app icon to have the MIN_INTERACT_SIZE final float pct = Math.max(((float) (MIN_INTERACT_SIZE - appHeight)) / mHeight, 0.2f); - mLauncher.scroll(allAppsContainer, Direction.DOWN, pct, null, 10); + mLauncher.scroll(appListRecycler, Direction.DOWN, pct, null, 10); try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer( "scrolled an icon in all apps to make it visible - and then")) { mLauncher.waitForIdle(); verifyActiveContainer(); } } + mLauncher.assertTrue("Couldn't scroll app icon to not intersect with the search box", + !iconCenterInSearchBox(allAppsContainer, appIcon)); + } + + private UiObject2 getSearchBox(UiObject2 allAppsContainer) { + return mLauncher.waitForObjectInContainer(allAppsContainer, "search_container_all_apps"); } /** diff --git a/tests/tapl/com/android/launcher3/tapl/AllAppsFromOverview.java b/tests/tapl/com/android/launcher3/tapl/AllAppsFromOverview.java index c3b671bcc2..a472d31344 100644 --- a/tests/tapl/com/android/launcher3/tapl/AllAppsFromOverview.java +++ b/tests/tapl/com/android/launcher3/tapl/AllAppsFromOverview.java @@ -53,9 +53,9 @@ public final class AllAppsFromOverview extends AllApps { TestProtocol.REQUEST_ALL_APPS_TO_OVERVIEW_SWIPE_HEIGHT). getInt(TestProtocol.TEST_INFO_RESPONSE_FIELD); - final int endY = start.y + swipeHeight + mLauncher.getTouchSlop(); + final int endY = start.y + swipeHeight; LauncherInstrumentation.log("AllAppsFromOverview.switchBackToOverview before swipe"); - mLauncher.swipe(start.x, start.y, start.x, endY, OVERVIEW_STATE_ORDINAL); + mLauncher.swipeToState(start.x, start.y, start.x, endY, 60, OVERVIEW_STATE_ORDINAL); try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer("swiped down")) { return new Overview(mLauncher); diff --git a/tests/tapl/com/android/launcher3/tapl/Background.java b/tests/tapl/com/android/launcher3/tapl/Background.java index 8f5e7fed0d..55e14cc80c 100644 --- a/tests/tapl/com/android/launcher3/tapl/Background.java +++ b/tests/tapl/com/android/launcher3/tapl/Background.java @@ -86,9 +86,10 @@ public class Background extends LauncherInstrumentation.VisibleContainer { final int swipeHeight = mLauncher.getTestInfo(getSwipeHeightRequestName()). getInt(TestProtocol.TEST_INFO_RESPONSE_FIELD); - mLauncher.swipe( + mLauncher.swipeToState( centerX, startY, centerX, startY - swipeHeight - mLauncher.getTouchSlop(), + 60, expectedState); break; } diff --git a/tests/tapl/com/android/launcher3/tapl/Launchable.java b/tests/tapl/com/android/launcher3/tapl/Launchable.java index 1b372ec134..3295ddbef4 100644 --- a/tests/tapl/com/android/launcher3/tapl/Launchable.java +++ b/tests/tapl/com/android/launcher3/tapl/Launchable.java @@ -24,6 +24,8 @@ import androidx.test.uiautomator.UiDevice; import androidx.test.uiautomator.UiObject2; import androidx.test.uiautomator.Until; +import com.android.launcher3.TestProtocol; + /** * Ancestor for AppIcon and AppMenuItem. */ @@ -51,9 +53,11 @@ abstract class Launchable { private Background launch(BySelector selector) { LauncherInstrumentation.log("Launchable.launch before click " + mObject.getVisibleCenter()); + 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)); + mLauncher.getTestInfo(TestProtocol.REQUEST_DISABLE_DEBUG_TRACING); mLauncher.assertTrue( "App didn't start: " + selector, mLauncher.getDevice().wait(Until.hasObject(selector), diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index 57fd4b9216..a4711f5f19 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -584,18 +584,15 @@ public final class LauncherInstrumentation { return mDevice; } - void swipe(int startX, int startY, int endX, int endY, int expectedState) { - swipe(startX, startY, endX, endY, expectedState, 60); - } - - void swipe(int startX, int startY, int endX, int endY, int expectedState, int steps) { - changeStateViaGesture(startX, startY, endX, endY, expectedState, - () -> mDevice.swipe(startX, startY, endX, endY, steps)); - } - void swipeToState(int startX, int startY, int endX, int endY, int steps, int expectedState) { - changeStateViaGesture(startX, startY, endX, endY, expectedState, - () -> linearGesture(startX, startY, endX, endY, steps)); + final Bundle parcel = (Bundle) executeAndWaitForEvent( + () -> linearGesture(startX, startY, endX, endY, steps), + event -> TestProtocol.SWITCHED_TO_STATE_MESSAGE.equals(event.getClassName()), + "Swipe failed to receive an event for the swipe end: " + startX + ", " + startY + + ", " + endX + ", " + endY); + assertEquals("Swipe switched launcher to a wrong state;", + TestProtocol.stateOrdinalToString(expectedState), + TestProtocol.stateOrdinalToString(parcel.getInt(TestProtocol.STATE_FIELD))); } void scroll(UiObject2 container, Direction direction, float percent, Rect margins, int steps) { @@ -652,18 +649,6 @@ public final class LauncherInstrumentation { sendPointer(downTime, endTime, MotionEvent.ACTION_UP, end); } - private void changeStateViaGesture(int startX, int startY, int endX, int endY, - int expectedState, Runnable gesture) { - final Bundle parcel = (Bundle) executeAndWaitForEvent( - gesture, - event -> TestProtocol.SWITCHED_TO_STATE_MESSAGE.equals(event.getClassName()), - "Swipe failed to receive an event for the swipe end: " + startX + ", " + startY - + ", " + endX + ", " + endY); - assertEquals("Swipe switched launcher to a wrong state;", - TestProtocol.stateOrdinalToString(expectedState), - TestProtocol.stateOrdinalToString(parcel.getInt(TestProtocol.STATE_FIELD))); - } - void waitForIdle() { mDevice.waitForIdle(); } diff --git a/tests/tapl/com/android/launcher3/tapl/Widgets.java b/tests/tapl/com/android/launcher3/tapl/Widgets.java index f7e0b6c4e8..b780df4adb 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_VERTICAL_SIZE, + ResourceUtils.getNavbarSize(ResourceUtils.NAVBAR_PORTRAIT_BOTTOM_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 11c07943fe..10b253d443 100644 --- a/tests/tapl/com/android/launcher3/tapl/Workspace.java +++ b/tests/tapl/com/android/launcher3/tapl/Workspace.java @@ -148,6 +148,7 @@ public final class Workspace extends Home { static void dragIconToWorkspace( LauncherInstrumentation launcher, Launchable launchable, Point dest, String longPressIndicator) { + launcher.getTestInfo(TestProtocol.REQUEST_ENABLE_DEBUG_TRACING); LauncherInstrumentation.log("dragIconToWorkspace: begin"); final Point launchableCenter = launchable.getObject().getVisibleCenter(); final long downTime = SystemClock.uptimeMillis(); @@ -162,6 +163,7 @@ public final class Workspace extends Home { downTime, SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, dest); LauncherInstrumentation.log("dragIconToWorkspace: end"); launcher.waitUntilGone("drop_target_bar"); + launcher.getTestInfo(TestProtocol.REQUEST_DISABLE_DEBUG_TRACING); } /**