From 619daaf82a65cbd1190a676b8582f1a7eb1cb774 Mon Sep 17 00:00:00 2001 From: Tony Wickham Date: Fri, 7 Feb 2020 12:29:06 -0800 Subject: [PATCH 01/52] Give current TaskView accessibility focus Send TYPE_VIEW_FOCUSED in the following places: - When page transition ends on a task - When finishing state transition to overview - When un-hiding the current running task view Bug: 145647019 Change-Id: I7bb357ea60e1dea79daf2ad50efa51071e064da8 --- .../launcher3/uioverrides/states/OverviewState.java | 6 ++++++ .../src/com/android/quickstep/views/RecentsView.java | 5 +++++ src/com/android/launcher3/PagedView.java | 2 ++ .../launcher3/compat/AccessibilityManagerCompat.java | 9 +++++++-- 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java index a1c837861d..7895bac4d2 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java @@ -37,6 +37,7 @@ import static com.android.quickstep.SysUINavigationMode.removeShelfFromOverview; import android.graphics.Rect; import android.view.View; +import android.view.accessibility.AccessibilityEvent; import android.view.animation.Interpolator; import com.android.launcher3.AbstractFloatingView; @@ -47,6 +48,7 @@ import com.android.launcher3.R; import com.android.launcher3.Workspace; import com.android.launcher3.allapps.DiscoveryBounce; import com.android.launcher3.anim.AnimatorSetBuilder; +import com.android.launcher3.compat.AccessibilityManagerCompat; import com.android.launcher3.userevent.nano.LauncherLogProto.Action; import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; import com.android.quickstep.SysUINavigationMode; @@ -143,6 +145,10 @@ public class OverviewState extends LauncherState { public void onStateTransitionEnd(Launcher launcher) { launcher.getRotationHelper().setCurrentStateRequest(REQUEST_ROTATE); DiscoveryBounce.showForOverviewIfNeeded(launcher); + RecentsView recentsView = launcher.getOverviewPanel(); + AccessibilityManagerCompat.sendCustomAccessibilityEvent( + recentsView.getPageAt(recentsView.getCurrentPage()), + AccessibilityEvent.TYPE_VIEW_FOCUSED, null); } @Override 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 aaba308c0e..3f48751c88 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 @@ -93,6 +93,7 @@ import com.android.launcher3.Utilities; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.PropertyListBuilder; import com.android.launcher3.anim.SpringObjectAnimator; +import com.android.launcher3.compat.AccessibilityManagerCompat; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.graphics.RotationMode; import com.android.launcher3.userevent.nano.LauncherLogProto; @@ -973,6 +974,10 @@ public abstract class RecentsView extends PagedView impl TaskView runningTask = getRunningTaskView(); if (runningTask != null) { runningTask.setStableAlpha(isHidden ? 0 : mContentAlpha); + if (!isHidden) { + AccessibilityManagerCompat.sendCustomAccessibilityEvent(runningTask, + AccessibilityEvent.TYPE_VIEW_FOCUSED, null); + } } } diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java index ae4eae9179..71a35e280d 100644 --- a/src/com/android/launcher3/PagedView.java +++ b/src/com/android/launcher3/PagedView.java @@ -374,6 +374,8 @@ public abstract class PagedView extends ViewGrou protected void onPageEndTransition() { mWasInOverscroll = false; AccessibilityManagerCompat.sendScrollFinishedEventToTest(getContext()); + AccessibilityManagerCompat.sendCustomAccessibilityEvent(getPageAt(mCurrentPage), + AccessibilityEvent.TYPE_VIEW_FOCUSED, null); } protected int getUnboundedScrollX() { diff --git a/src/com/android/launcher3/compat/AccessibilityManagerCompat.java b/src/com/android/launcher3/compat/AccessibilityManagerCompat.java index 28579c1cfc..db4bef0948 100644 --- a/src/com/android/launcher3/compat/AccessibilityManagerCompat.java +++ b/src/com/android/launcher3/compat/AccessibilityManagerCompat.java @@ -18,11 +18,14 @@ package com.android.launcher3.compat; import android.content.Context; import android.os.Bundle; +import android.text.TextUtils; import android.util.Log; import android.view.View; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; +import androidx.annotation.Nullable; + import com.android.launcher3.Utilities; import com.android.launcher3.testing.TestProtocol; @@ -37,11 +40,13 @@ public class AccessibilityManagerCompat { return isAccessibilityEnabled(context); } - public static void sendCustomAccessibilityEvent(View target, int type, String text) { + public static void sendCustomAccessibilityEvent(View target, int type, @Nullable String text) { if (isObservedEventType(target.getContext(), type)) { AccessibilityEvent event = AccessibilityEvent.obtain(type); target.onInitializeAccessibilityEvent(event); - event.getText().add(text); + if (!TextUtils.isEmpty(text)) { + event.getText().add(text); + } getManager(target.getContext()).sendAccessibilityEvent(event); } } From 3b0c1f3acaea80c332da2b49b35a58f1d5a1f53c Mon Sep 17 00:00:00 2001 From: Andy Wickham Date: Fri, 14 Feb 2020 00:31:54 +0000 Subject: [PATCH 02/52] Allows multiple gesture blocking activities to be specified. Bug: 148542211 Change-Id: Ie299359eb2df60f5f08d156dc6882fa133fab27c --- .../quickstep/TouchInteractionService.java | 6 ++-- quickstep/res/values/config.xml | 12 ++++--- .../RecentsAnimationDeviceState.java | 33 ++++++++++++------- 3 files changed, 32 insertions(+), 19 deletions(-) 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 3364b66248..a597458944 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java @@ -753,7 +753,7 @@ public class TouchInteractionService extends Service implements PluginListener 0 && - mDeviceState.getGestureBlockedActivityPackage() != null; + !mDeviceState.getGestureBlockedActivityPackages().isEmpty(); } @WorkerThread @@ -762,8 +762,8 @@ public class TouchInteractionService extends Service implements PluginListener + sendBroadcast(new Intent(NOTIFY_ACTION_BACK).setPackage(blockedPackage))); } } diff --git a/quickstep/res/values/config.xml b/quickstep/res/values/config.xml index 327bb14e75..304963f82a 100644 --- a/quickstep/res/values/config.xml +++ b/quickstep/res/values/config.xml @@ -13,11 +13,13 @@ See the License for the specific language governing permissions and limitations under the License. --> - - + + - - + + + com.android.launcher3/com.android.quickstep.interaction.BackGestureTutorialActivity + com.android.quickstep.logging.StatsLogCompatManager @@ -32,5 +34,5 @@ 200 20 - + diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java index 4b33d21cba..abe15927d4 100644 --- a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java +++ b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java @@ -66,6 +66,8 @@ import com.android.systemui.shared.system.SystemGestureExclusionListenerCompat; import java.io.PrintWriter; import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; /** * Manages the state of the system during a swipe up gesture. @@ -107,7 +109,7 @@ public class RecentsAnimationDeviceState implements private Region mExclusionRegion; private SystemGestureExclusionListenerCompat mExclusionListener; - private ComponentName mGestureBlockedActivity; + private final List mGestureBlockedActivities; public RecentsAnimationDeviceState(Context context) { final ContentResolver resolver = context.getContentResolver(); @@ -142,9 +144,19 @@ public class RecentsAnimationDeviceState implements runOnDestroy(() -> mSysUiNavMode.removeModeChangeListener(this)); // Add any blocked activities - String blockingActivity = context.getString(R.string.gesture_blocking_activity); - if (!TextUtils.isEmpty(blockingActivity)) { - mGestureBlockedActivity = ComponentName.unflattenFromString(blockingActivity); + String[] blockingActivities; + try { + blockingActivities = + context.getResources().getStringArray(R.array.gesture_blocking_activities); + } catch (Resources.NotFoundException e) { + blockingActivities = new String[0]; + } + mGestureBlockedActivities = new ArrayList<>(blockingActivities.length); + for (String blockingActivity : blockingActivities) { + if (!TextUtils.isEmpty(blockingActivity)) { + mGestureBlockedActivities.add( + ComponentName.unflattenFromString(blockingActivity)); + } } } @@ -272,17 +284,16 @@ public class RecentsAnimationDeviceState implements * @return whether the given running task info matches the gesture-blocked activity. */ public boolean isGestureBlockedActivity(ActivityManager.RunningTaskInfo runningTaskInfo) { - return runningTaskInfo != null && mGestureBlockedActivity != null - && mGestureBlockedActivity.equals(runningTaskInfo.topActivity); + return runningTaskInfo != null + && mGestureBlockedActivities.contains(runningTaskInfo.topActivity); } /** - * @return the package of the gesture-blocked activity or {@code null} if there is none. + * @return the packages of gesture-blocked activities. */ - public String getGestureBlockedActivityPackage() { - return (mGestureBlockedActivity != null) - ? mGestureBlockedActivity.getPackageName() - : null; + public List getGestureBlockedActivityPackages() { + return mGestureBlockedActivities.stream().map(ComponentName::getPackageName) + .collect(Collectors.toList()); } /** From c3bd4d0e75e150a44169551eba27db48bc66a462 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Tue, 18 Feb 2020 17:32:57 -0800 Subject: [PATCH 03/52] Updating Pause detection to use motion events directly Bug: 139750033 Change-Id: Ib261b203fec941f3c5303eafc1d435efdf3dbcaf --- .../FlingAndHoldTouchController.java | 2 +- .../NoButtonQuickSwitchTouchController.java | 2 +- .../AccessibilityInputConsumer.java | 6 +- .../OtherActivityInputConsumer.java | 19 ++-- .../ScreenPinnedInputConsumer.java | 4 +- .../quickstep/util/MotionPauseDetector.java | 101 +++++++++++++----- 6 files changed, 95 insertions(+), 39 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/FlingAndHoldTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/FlingAndHoldTouchController.java index b80830a441..519939e8d0 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/FlingAndHoldTouchController.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/FlingAndHoldTouchController.java @@ -172,7 +172,7 @@ public class FlingAndHoldTouchController extends PortraitStatesTouchController { mMotionPauseDetector.setDisallowPause(!handlingOverviewAnim() || upDisplacement < mMotionPauseMinDisplacement || upDisplacement > mMotionPauseMaxDisplacement); - mMotionPauseDetector.addPosition(displacement, event.getEventTime()); + mMotionPauseDetector.addPosition(event); return super.onDrag(displacement, event); } diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java index 8628db0107..799f1ad182 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java @@ -317,7 +317,7 @@ public class NoButtonQuickSwitchTouchController implements TouchController, // home screen elements will appear in the shelf on motion pause. mMotionPauseDetector.setDisallowPause(mIsHomeScreenVisible || -displacement.y < mMotionPauseMinDisplacement); - mMotionPauseDetector.addPosition(displacement.y, ev.getEventTime()); + mMotionPauseDetector.addPosition(ev); if (mIsHomeScreenVisible) { // Cancel the shelf anim so it doesn't clobber mNonOverviewAnim. diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AccessibilityInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AccessibilityInputConsumer.java index d3765c5334..5ad48ebabc 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AccessibilityInputConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AccessibilityInputConsumer.java @@ -31,8 +31,8 @@ import android.view.ViewConfiguration; import com.android.launcher3.R; import com.android.quickstep.InputConsumer; import com.android.quickstep.RecentsAnimationDeviceState; -import com.android.quickstep.util.MotionPauseDetector; import com.android.quickstep.SystemUiProxy; +import com.android.quickstep.util.MotionPauseDetector; import com.android.systemui.shared.system.InputMonitorCompat; /** @@ -117,9 +117,7 @@ public class AccessibilityInputConsumer extends DelegateInputConsumer { if (pointerIndex == -1) { break; } - - mMotionPauseDetector.addPosition(ev.getY(pointerIndex) - mDownY, - ev.getEventTime()); + mMotionPauseDetector.addPosition(ev, pointerIndex); } break; } 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 3ee3c2d3b4..8e7074d237 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 @@ -59,6 +59,7 @@ import com.android.quickstep.TaskAnimationManager; import com.android.quickstep.util.ActiveGestureLog; import com.android.quickstep.util.CachedEventDispatcher; import com.android.quickstep.util.MotionPauseDetector; +import com.android.quickstep.util.NavBarPosition; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.InputMonitorCompat; @@ -77,6 +78,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC public static final float QUICKSTEP_TOUCH_SLOP_RATIO = 3; private final RecentsAnimationDeviceState mDeviceState; + private final NavBarPosition mNavBarPosition; private final TaskAnimationManager mTaskAnimationManager; private final GestureState mGestureState; private RecentsAnimationCallbacks mActiveCallbacks; @@ -126,13 +128,16 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC Factory handlerFactory) { super(base); mDeviceState = deviceState; + mNavBarPosition = mDeviceState.getNavBarPosition(); mTaskAnimationManager = taskAnimationManager; mGestureState = gestureState; mMainThreadHandler = new Handler(Looper.getMainLooper()); mHandlerFactory = handlerFactory; mActivityInterface = mGestureState.getActivityInterface(); - mMotionPauseDetector = new MotionPauseDetector(base); + mMotionPauseDetector = new MotionPauseDetector(base, false, + mNavBarPosition.isLeftEdge() || mNavBarPosition.isRightEdge() + ? MotionEvent.AXIS_X : MotionEvent.AXIS_Y); mMotionPauseMinDisplacement = base.getResources().getDimension( R.dimen.motion_pause_detector_min_displacement_from_app); mOnCompleteCallback = onCompleteCallback; @@ -172,7 +177,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC if (mPassedWindowMoveSlop && mInteractionHandler != null && !mRecentsViewDispatcher.hasConsumer()) { mRecentsViewDispatcher.setConsumer(mInteractionHandler.getRecentsViewDispatcher( - mDeviceState.getNavBarPosition().getRotationMode())); + mNavBarPosition.getRotationMode())); } int edgeFlags = ev.getEdgeFlags(); ev.setEdgeFlags(edgeFlags | EDGE_NAV_BAR); @@ -285,7 +290,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC if (mDeviceState.isFullyGesturalNavMode()) { mMotionPauseDetector.setDisallowPause(upDist < mMotionPauseMinDisplacement || isLikelyToStartNewTask); - mMotionPauseDetector.addPosition(displacement, ev.getEventTime()); + mMotionPauseDetector.addPosition(ev); mInteractionHandler.setIsLikelyToStartNewTask(isLikelyToStartNewTask); } } @@ -354,9 +359,9 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC ViewConfiguration.get(this).getScaledMaximumFlingVelocity()); float velocityX = mVelocityTracker.getXVelocity(mActivePointerId); float velocityY = mVelocityTracker.getYVelocity(mActivePointerId); - float velocity = mDeviceState.getNavBarPosition().isRightEdge() + float velocity = mNavBarPosition.isRightEdge() ? velocityX - : mDeviceState.getNavBarPosition().isLeftEdge() + : mNavBarPosition.isLeftEdge() ? -velocityX : velocityY; @@ -410,9 +415,9 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC } private float getDisplacement(MotionEvent ev) { - if (mDeviceState.getNavBarPosition().isRightEdge()) { + if (mNavBarPosition.isRightEdge()) { return ev.getX() - mDownPos.x; - } else if (mDeviceState.getNavBarPosition().isLeftEdge()) { + } else if (mNavBarPosition.isLeftEdge()) { return mDownPos.x - ev.getX(); } else { return ev.getY() - mDownPos.y; diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/ScreenPinnedInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/ScreenPinnedInputConsumer.java index d5ed321e08..b9827fff1d 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/ScreenPinnedInputConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/ScreenPinnedInputConsumer.java @@ -23,8 +23,8 @@ import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.R; import com.android.quickstep.GestureState; import com.android.quickstep.InputConsumer; -import com.android.quickstep.util.MotionPauseDetector; import com.android.quickstep.SystemUiProxy; +import com.android.quickstep.util.MotionPauseDetector; /** * An input consumer that detects swipe up and hold to exit screen pinning mode. @@ -72,7 +72,7 @@ public class ScreenPinnedInputConsumer implements InputConsumer { case MotionEvent.ACTION_MOVE: float displacement = mTouchDownY - y; mMotionPauseDetector.setDisallowPause(displacement < mMotionPauseMinDisplacement); - mMotionPauseDetector.addPosition(y, ev.getEventTime()); + mMotionPauseDetector.addPosition(ev); break; case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: diff --git a/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java b/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java index 801a5604f5..d8b10b6cbc 100644 --- a/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java +++ b/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java @@ -37,8 +37,7 @@ public class MotionPauseDetector { private static final long FORCE_PAUSE_TIMEOUT = 300; /** - * After {@link #makePauseHarderToTrigger()}, must - * move slowly for this long to trigger a pause. + * After {@link #mMakePauseHarderToTrigger}, must move slowly for this long to trigger a pause. */ private static final long HARDER_TRIGGER_TIMEOUT = 400; @@ -49,13 +48,10 @@ public class MotionPauseDetector { private final Alarm mForcePauseTimeout; private final boolean mMakePauseHarderToTrigger; private final Context mContext; + private final VelocityProvider mVelocityProvider; - private Long mPreviousTime = null; - private Float mPreviousPosition = null; private Float mPreviousVelocity = null; - private Float mFirstPosition = null; - private OnMotionPauseListener mOnMotionPauseListener; private boolean mIsPaused; // Bias more for the first pause to make it feel extra responsive. @@ -73,6 +69,13 @@ public class MotionPauseDetector { * @param makePauseHarderToTrigger Used for gestures that require a more explicit pause. */ public MotionPauseDetector(Context context, boolean makePauseHarderToTrigger) { + this(context, makePauseHarderToTrigger, MotionEvent.AXIS_Y); + } + + /** + * @param makePauseHarderToTrigger Used for gestures that require a more explicit pause. + */ + public MotionPauseDetector(Context context, boolean makePauseHarderToTrigger, int axis) { mContext = context; Resources res = context.getResources(); mSpeedVerySlow = res.getDimension(R.dimen.motion_pause_detector_speed_very_slow); @@ -82,6 +85,7 @@ public class MotionPauseDetector { mForcePauseTimeout = new Alarm(); mForcePauseTimeout.setOnAlarmListener(alarm -> updatePaused(true /* isPaused */)); mMakePauseHarderToTrigger = makePauseHarderToTrigger; + mVelocityProvider = new LinearVelocityProvider(axis); } /** @@ -101,28 +105,28 @@ public class MotionPauseDetector { /** * Computes velocity and acceleration to determine whether the motion is paused. - * @param position The x or y component of the motion being tracked. + * @param ev The motion being tracked. * * TODO: Use historical positions as well, e.g. {@link MotionEvent#getHistoricalY(int, int)}. */ - public void addPosition(float position, long time) { - if (mFirstPosition == null) { - mFirstPosition = position; - } + public void addPosition(MotionEvent ev) { + addPosition(ev, 0); + } + + /** + * Computes velocity and acceleration to determine whether the motion is paused. + * @param ev The motion being tracked. + * @param pointerIndex Index for the pointer being tracked in the motion event + */ + public void addPosition(MotionEvent ev, int pointerIndex) { mForcePauseTimeout.setAlarm(mMakePauseHarderToTrigger ? HARDER_TRIGGER_TIMEOUT : FORCE_PAUSE_TIMEOUT); - if (mPreviousTime != null && mPreviousPosition != null) { - long changeInTime = Math.max(1, time - mPreviousTime); - float changeInPosition = position - mPreviousPosition; - float velocity = changeInPosition / changeInTime; - if (mPreviousVelocity != null) { - checkMotionPaused(velocity, mPreviousVelocity, time); - } - mPreviousVelocity = velocity; + Float newVelocity = mVelocityProvider.addMotionEvent(ev, pointerIndex); + if (newVelocity != null && mPreviousVelocity != null) { + checkMotionPaused(newVelocity, mPreviousVelocity, ev.getEventTime()); } - mPreviousTime = time; - mPreviousPosition = position; + mPreviousVelocity = newVelocity; } private void checkMotionPaused(float velocity, float prevVelocity, long time) { @@ -178,10 +182,8 @@ public class MotionPauseDetector { } public void clear() { - mPreviousTime = null; - mPreviousPosition = null; + mVelocityProvider.clear(); mPreviousVelocity = null; - mFirstPosition = null; setOnMotionPauseListener(null); mIsPaused = mHasEverBeenPaused = false; mSlowStartTime = 0; @@ -195,4 +197,55 @@ public class MotionPauseDetector { public interface OnMotionPauseListener { void onMotionPauseChanged(boolean isPaused); } + + /** + * Interface to abstract out velocity calculations + */ + protected interface VelocityProvider { + + /** + * Adds a new motion events, and returns the velocity at this point, or null if + * the velocity is not available + */ + Float addMotionEvent(MotionEvent ev, int pointer); + + /** + * Clears all stored motion event records + */ + void clear(); + } + + private static class LinearVelocityProvider implements VelocityProvider { + + private Long mPreviousTime = null; + private Float mPreviousPosition = null; + + private final int mAxis; + + LinearVelocityProvider(int axis) { + mAxis = axis; + } + + @Override + public Float addMotionEvent(MotionEvent ev, int pointer) { + long time = ev.getEventTime(); + float position = ev.getAxisValue(mAxis, pointer); + Float velocity = null; + + if (mPreviousTime != null && mPreviousPosition != null) { + long changeInTime = Math.max(1, time - mPreviousTime); + float changeInPosition = position - mPreviousPosition; + velocity = changeInPosition / changeInTime; + } + mPreviousTime = time; + mPreviousPosition = position; + return velocity; + } + + @Override + public void clear() { + mPreviousTime = null; + mPreviousPosition = null; + } + } } From ccebfbe2733e6570d3af0622262a1eb2e5633478 Mon Sep 17 00:00:00 2001 From: Samuel Fufa Date: Mon, 10 Feb 2020 09:26:20 -0800 Subject: [PATCH 04/52] Clean up work profile This includes - Dismiss work edu on launcher state change - Remove work tab flash on first setup - Make edu bottom sheet adopt theme color - Fix Work toggle bottom inset Bug: 149200572 Bug: 149197172 Bug: 149199058 Bug: 149215103 Bug: 149198955 Bug: 145595763 Bug:149481723 Test: Manual Change-Id: I39a30782b80fd3a66bede55754fa30a940d2caee --- .../hotseat_edu_notification_icon.xml | 2 +- .../res/layout/predicted_hotseat_edu.xml | 4 +- .../hybridhotseat/HotseatEduController.java | 3 +- .../hybridhotseat/HotseatEduDialog.java | 2 +- .../uioverrides/states/AllAppsState.java | 6 +++ res/layout/work_apps_paused.xml | 4 +- res/layout/work_profile_edu.xml | 9 ++-- res/values/colors.xml | 1 - res/values/strings.xml | 2 +- src/com/android/launcher3/Launcher.java | 1 - .../allapps/AllAppsContainerView.java | 21 ++++------ .../allapps/AllAppsTransitionController.java | 12 ------ .../launcher3/allapps/DiscoveryBounce.java | 13 +----- .../allapps/LauncherAllAppsContainerView.java | 8 ++++ .../allapps/PersonalWorkSlidingTabStrip.java | 24 ----------- .../launcher3/views/AbstractSlideInView.java | 41 ++++++++++++++++++- .../android/launcher3/views/WorkEduView.java | 11 ++++- .../launcher3/widget/BaseWidgetSheet.java | 38 +++-------------- 18 files changed, 92 insertions(+), 110 deletions(-) diff --git a/quickstep/recents_ui_overrides/res/drawable/hotseat_edu_notification_icon.xml b/quickstep/recents_ui_overrides/res/drawable/hotseat_edu_notification_icon.xml index fa3a0f856a..4fda2a9b9b 100644 --- a/quickstep/recents_ui_overrides/res/drawable/hotseat_edu_notification_icon.xml +++ b/quickstep/recents_ui_overrides/res/drawable/hotseat_edu_notification_icon.xml @@ -15,5 +15,5 @@ --> - + diff --git a/quickstep/recents_ui_overrides/res/layout/predicted_hotseat_edu.xml b/quickstep/recents_ui_overrides/res/layout/predicted_hotseat_edu.xml index d94c665e86..fe99037ccf 100644 --- a/quickstep/recents_ui_overrides/res/layout/predicted_hotseat_edu.xml +++ b/quickstep/recents_ui_overrides/res/layout/predicted_hotseat_edu.xml @@ -24,13 +24,13 @@ + android:textSize="20sp" /> + android:background="@drawable/bottom_sheet_top_border" + android:backgroundTint="?android:attr/colorAccent" /> - \ No newline at end of file diff --git a/res/values/colors.xml b/res/values/colors.xml index 36f8468977..194ef2ce67 100644 --- a/res/values/colors.xml +++ b/res/values/colors.xml @@ -45,5 +45,4 @@ #1A73E8 - #f01A73E8 diff --git a/res/values/strings.xml b/res/values/strings.xml index bde3c3127e..5faa4297f3 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -330,7 +330,7 @@ Personal apps are private & can\'t be seen by IT - Work apps are badged and monitored by IT + Work apps are badged & visible to IT Next diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 397a38bbe3..94aadb2b4b 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -482,7 +482,6 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, @Override public void onEnterAnimationComplete() { super.onEnterAnimationComplete(); - mAllAppsController.highlightWorkTabIfNecessary(); mRotationHelper.setCurrentTransitionRequest(REQUEST_NONE); } diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java index 56bd1b63f8..e66cf3921e 100644 --- a/src/com/android/launcher3/allapps/AllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java @@ -103,6 +103,8 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo private final MultiValueAlpha mMultiValueAlpha; + Rect mInsets = new Rect(); + public AllAppsContainerView(Context context) { this(context, null); } @@ -320,6 +322,7 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo @Override public void setInsets(Rect insets) { + mInsets.set(insets); DeviceProfile grid = mLauncher.getDeviceProfile(); int leftRightPadding = grid.desiredWorkspaceLeftRightMarginPx + grid.cellLayoutPaddingLeftRightPx; @@ -411,6 +414,7 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); this.addView(mWorkFooterContainer); + mWorkFooterContainer.setInsets(mInsets); mWorkFooterContainer.post(() -> mAH[AdapterHolder.WORK].applyPadding()); } @@ -548,17 +552,6 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo return mHeader != null && mHeader.getVisibility() == View.VISIBLE; } - public void onScrollUpEnd() { - highlightWorkTabIfNecessary(); - } - - void highlightWorkTabIfNecessary() { - if (mUsingTabs) { - ((PersonalWorkSlidingTabStrip) findViewById(R.id.tabs)) - .highlightWorkTabIfNecessary(); - } - } - /** * Adds an update listener to {@param animator} that adds springs to the animation. */ @@ -643,9 +636,9 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo R.layout.work_apps_paused, null); recyclerView.post(() -> { int width = recyclerView.getWidth(); - int height = recyclerView.getHeight(); - pausedOverlay.measure(makeMeasureSpec(width, EXACTLY), - makeMeasureSpec(height, EXACTLY)); + int height = recyclerView.getHeight() - mWorkFooterContainer.getHeight(); + pausedOverlay.measure(makeMeasureSpec(recyclerView.getWidth(), EXACTLY), + makeMeasureSpec(recyclerView.getHeight(), EXACTLY)); pausedOverlay.layout(0, 0, width, height); applyPadding(); }); diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java index 93bdac91f7..6aa3efc277 100644 --- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java +++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java @@ -248,18 +248,6 @@ public class AllAppsTransitionController implements StateHandler, OnDeviceProfil private void onProgressAnimationEnd() { if (Float.compare(mProgress, 1f) == 0) { mAppsView.reset(false /* animate */); - } else if (isAllAppsExpanded()) { - mAppsView.onScrollUpEnd(); - } - } - - private boolean isAllAppsExpanded() { - return Float.compare(mProgress, 0f) == 0; - } - - public void highlightWorkTabIfNecessary() { - if (isAllAppsExpanded()) { - mAppsView.highlightWorkTabIfNecessary(); } } } diff --git a/src/com/android/launcher3/allapps/DiscoveryBounce.java b/src/com/android/launcher3/allapps/DiscoveryBounce.java index e8035eb87a..0f0fc3a249 100644 --- a/src/com/android/launcher3/allapps/DiscoveryBounce.java +++ b/src/com/android/launcher3/allapps/DiscoveryBounce.java @@ -35,7 +35,6 @@ import com.android.launcher3.LauncherState; import com.android.launcher3.LauncherStateManager.StateListener; import com.android.launcher3.R; import com.android.launcher3.Utilities; -import com.android.launcher3.pm.UserCache; /** * Abstract base class of floating view responsible for showing discovery bounce animation @@ -144,8 +143,7 @@ public class DiscoveryBounce extends AbstractFloatingView { private static void showForHomeIfNeeded(Launcher launcher, boolean withDelay) { if (!launcher.isInState(NORMAL) - || (launcher.getSharedPrefs().getBoolean(HOME_BOUNCE_SEEN, false) - && !shouldShowForWorkProfile(launcher)) + || launcher.getSharedPrefs().getBoolean(HOME_BOUNCE_SEEN, false) || AbstractFloatingView.getTopOpenView(launcher) != null || launcher.getSystemService(UserManager.class).isDemoUser() || Utilities.IS_RUNNING_IN_TEST_HARNESS) { @@ -170,8 +168,7 @@ public class DiscoveryBounce extends AbstractFloatingView { || !launcher.hasBeenResumed() || launcher.isForceInvisible() || launcher.getDeviceProfile().isVerticalBarLayout() - || (launcher.getSharedPrefs().getBoolean(SHELF_BOUNCE_SEEN, false) - && !shouldShowForWorkProfile(launcher)) + || launcher.getSharedPrefs().getBoolean(SHELF_BOUNCE_SEEN, false) || launcher.getSystemService(UserManager.class).isDemoUser() || Utilities.IS_RUNNING_IN_TEST_HARNESS) { return; @@ -213,12 +210,6 @@ public class DiscoveryBounce extends AbstractFloatingView { } } - private static boolean shouldShowForWorkProfile(Launcher launcher) { - return !launcher.getSharedPrefs().getBoolean( - PersonalWorkSlidingTabStrip.KEY_SHOWED_PEEK_WORK_TAB, false) - && UserCache.INSTANCE.get(launcher).hasWorkProfile(); - } - private static void incrementShelfBounceCount(Launcher launcher) { SharedPreferences sharedPrefs = launcher.getSharedPrefs(); int count = sharedPrefs.getInt(SHELF_BOUNCE_COUNT, 0); diff --git a/src/com/android/launcher3/allapps/LauncherAllAppsContainerView.java b/src/com/android/launcher3/allapps/LauncherAllAppsContainerView.java index 9d0ecd3a6c..25db0e7f1d 100644 --- a/src/com/android/launcher3/allapps/LauncherAllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/LauncherAllAppsContainerView.java @@ -63,6 +63,14 @@ public class LauncherAllAppsContainerView extends AllAppsContainerView { .setScrollRangeDelta(mSearchUiManager.getScrollRangeDelta(insets)); } + @Override + public void setupHeader() { + super.setupHeader(); + if (mWorkTabListener != null && !mUsingTabs) { + mLauncher.getStateManager().removeStateListener(mWorkTabListener); + } + } + @Override public void onTabChanged(int pos) { super.onTabChanged(pos); diff --git a/src/com/android/launcher3/allapps/PersonalWorkSlidingTabStrip.java b/src/com/android/launcher3/allapps/PersonalWorkSlidingTabStrip.java index 6204f31900..0e39bbe40f 100644 --- a/src/com/android/launcher3/allapps/PersonalWorkSlidingTabStrip.java +++ b/src/com/android/launcher3/allapps/PersonalWorkSlidingTabStrip.java @@ -16,7 +16,6 @@ package com.android.launcher3.allapps; import android.content.Context; -import android.content.SharedPreferences; import android.graphics.Canvas; import android.graphics.Paint; import android.util.AttributeSet; @@ -39,11 +38,8 @@ public class PersonalWorkSlidingTabStrip extends LinearLayout implements PageInd private static final int POSITION_PERSONAL = 0; private static final int POSITION_WORK = 1; - public static final String KEY_SHOWED_PEEK_WORK_TAB = "showed_peek_work_tab"; - private final Paint mSelectedIndicatorPaint; private final Paint mDividerPaint; - private final SharedPreferences mSharedPreferences; private int mSelectedIndicatorHeight; private int mIndicatorLeft = -1; @@ -72,7 +68,6 @@ public class PersonalWorkSlidingTabStrip extends LinearLayout implements PageInd mDividerPaint.setStrokeWidth( getResources().getDimensionPixelSize(R.dimen.all_apps_divider_height)); - mSharedPreferences = Utilities.getPrefs(context); mIsRtl = Utilities.isRtl(getResources()); } @@ -128,25 +123,6 @@ public class PersonalWorkSlidingTabStrip extends LinearLayout implements PageInd mIndicatorRight, getHeight(), mSelectedIndicatorPaint); } - public void highlightWorkTabIfNecessary() { - if (mSharedPreferences.getBoolean(KEY_SHOWED_PEEK_WORK_TAB, false)) { - return; - } - if (mLastActivePage != POSITION_PERSONAL) { - return; - } - highlightWorkTab(); - mSharedPreferences.edit().putBoolean(KEY_SHOWED_PEEK_WORK_TAB, true).apply(); - } - - private void highlightWorkTab() { - View v = getChildAt(POSITION_WORK); - v.post(() -> { - v.setPressed(true); - v.setPressed(false); - }); - } - @Override public void setScroll(int currentScroll, int totalScroll) { float scrollOffset = ((float) currentScroll) / totalScroll; diff --git a/src/com/android/launcher3/views/AbstractSlideInView.java b/src/com/android/launcher3/views/AbstractSlideInView.java index 9334c46a41..bdba39c371 100644 --- a/src/com/android/launcher3/views/AbstractSlideInView.java +++ b/src/com/android/launcher3/views/AbstractSlideInView.java @@ -15,6 +15,8 @@ */ package com.android.launcher3.views; +import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; + import static com.android.launcher3.anim.Interpolators.scrollInterpolatorForVelocity; import android.animation.Animator; @@ -62,6 +64,7 @@ public abstract class AbstractSlideInView extends AbstractFloatingView protected final ObjectAnimator mOpenCloseAnimator; protected View mContent; + private final View mColorScrim; protected Interpolator mScrollInterpolator; // range [0, 1], 0=> completely open, 1=> completely closed @@ -85,11 +88,30 @@ public abstract class AbstractSlideInView extends AbstractFloatingView announceAccessibilityChanges(); } }); + int scrimColor = getScrimColor(mLauncher); + mColorScrim = scrimColor != -1 ? createColorScrim(mLauncher, scrimColor) : null; + } + + protected void attachToContainer() { + if (mColorScrim != null) { + getPopupContainer().addView(mColorScrim); + } + getPopupContainer().addView(this); + } + + /** + * Returns a scrim color for a sliding view. if returned value is -1, no scrim is added. + */ + protected int getScrimColor(Context context) { + return -1; } protected void setTranslationShift(float translationShift) { mTranslationShift = translationShift; mContent.setTranslationY(mTranslationShift * mContent.getHeight()); + if (mColorScrim != null) { + mColorScrim.setAlpha(1 - mTranslationShift); + } } @Override @@ -127,7 +149,8 @@ public abstract class AbstractSlideInView extends AbstractFloatingView /* SingleAxisSwipeDetector.Listener */ @Override - public void onDragStart(boolean start) { } + public void onDragStart(boolean start) { + } @Override public boolean onDrag(float displacement) { @@ -185,9 +208,25 @@ public abstract class AbstractSlideInView extends AbstractFloatingView protected void onCloseComplete() { mIsOpen = false; getPopupContainer().removeView(this); + if (mColorScrim != null) { + getPopupContainer().removeView(mColorScrim); + } } protected BaseDragLayer getPopupContainer() { return mLauncher.getDragLayer(); } + + + protected static View createColorScrim(Context context, int bgColor) { + View view = new View(context); + view.forceHasOverlappingRendering(false); + view.setBackgroundColor(bgColor); + + BaseDragLayer.LayoutParams lp = new BaseDragLayer.LayoutParams(MATCH_PARENT, MATCH_PARENT); + lp.ignoreInsets = true; + view.setLayoutParams(lp); + + return view; + } } diff --git a/src/com/android/launcher3/views/WorkEduView.java b/src/com/android/launcher3/views/WorkEduView.java index b6c81ae4f9..81f8327dc5 100644 --- a/src/com/android/launcher3/views/WorkEduView.java +++ b/src/com/android/launcher3/views/WorkEduView.java @@ -52,11 +52,15 @@ public class WorkEduView extends AbstractSlideInView implements Insettable { private static final int WORK_EDU_PERSONAL_APPS = 1; private static final int WORK_EDU_WORK_APPS = 2; + protected static final int FINAL_SCRIM_BG_COLOR = 0x88000000; + + private Rect mInsets = new Rect(); private View mViewWrapper; private Button mProceedButton; private TextView mContentText; private AllAppsPagedView mAllAppsPagedView; + private int mNextWorkEduStep = WORK_EDU_PERSONAL_APPS; @@ -141,10 +145,15 @@ public class WorkEduView extends AbstractSlideInView implements Insettable { } private void show() { - mLauncher.getDragLayer().addView(this); + attachToContainer(); animateOpen(); } + @Override + protected int getScrimColor(Context context) { + return FINAL_SCRIM_BG_COLOR; + } + private void goToFirstPage() { if (mAllAppsPagedView != null) { mAllAppsPagedView.snapToPageImmediately(AllAppsContainerView.AdapterHolder.MAIN); diff --git a/src/com/android/launcher3/widget/BaseWidgetSheet.java b/src/com/android/launcher3/widget/BaseWidgetSheet.java index 6cae43da9e..df1a4696db 100644 --- a/src/com/android/launcher3/widget/BaseWidgetSheet.java +++ b/src/com/android/launcher3/widget/BaseWidgetSheet.java @@ -15,8 +15,6 @@ */ package com.android.launcher3.widget; -import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; - import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound; import static com.android.launcher3.logging.LoggerUtils.newContainerTarget; @@ -42,7 +40,6 @@ import com.android.launcher3.userevent.nano.LauncherLogProto.Target; import com.android.launcher3.util.SystemUiController; import com.android.launcher3.util.Themes; import com.android.launcher3.views.AbstractSlideInView; -import com.android.launcher3.views.BaseDragLayer; /** * Base class for various widgets popup @@ -55,11 +52,14 @@ abstract class BaseWidgetSheet extends AbstractSlideInView /* Touch handling related member variables. */ private Toast mWidgetInstructionToast; - protected final View mColorScrim; - public BaseWidgetSheet(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); - mColorScrim = createColorScrim(context); + } + + protected int getScrimColor(Context context) { + WallpaperColorInfo colors = WallpaperColorInfo.INSTANCE.get(context); + int alpha = context.getResources().getInteger(R.integer.extracted_color_gradient_alpha); + return setColorAlphaBound(colors.getSecondaryColor(), alpha); } @Override @@ -98,16 +98,6 @@ abstract class BaseWidgetSheet extends AbstractSlideInView return true; } - protected void attachToContainer() { - getPopupContainer().addView(mColorScrim); - getPopupContainer().addView(this); - } - - protected void setTranslationShift(float translationShift) { - super.setTranslationShift(translationShift); - mColorScrim.setAlpha(1 - mTranslationShift); - } - private boolean beginDraggingWidget(WidgetCell v) { // Get the widget preview as the drag representation WidgetImageView image = v.getWidgetView(); @@ -138,7 +128,6 @@ abstract class BaseWidgetSheet extends AbstractSlideInView protected void onCloseComplete() { super.onCloseComplete(); - getPopupContainer().removeView(mColorScrim); clearNavBarColor(); } @@ -177,19 +166,4 @@ abstract class BaseWidgetSheet extends AbstractSlideInView protected SystemUiController getSystemUiController() { return mLauncher.getSystemUiController(); } - - private static View createColorScrim(Context context) { - View view = new View(context); - view.forceHasOverlappingRendering(false); - - WallpaperColorInfo colors = WallpaperColorInfo.INSTANCE.get(context); - int alpha = context.getResources().getInteger(R.integer.extracted_color_gradient_alpha); - view.setBackgroundColor(setColorAlphaBound(colors.getSecondaryColor(), alpha)); - - BaseDragLayer.LayoutParams lp = new BaseDragLayer.LayoutParams(MATCH_PARENT, MATCH_PARENT); - lp.ignoreInsets = true; - view.setLayoutParams(lp); - - return view; - } } From 9ac4b580a1a5caabab15cb5b1eafa584da5f9504 Mon Sep 17 00:00:00 2001 From: jayaprakashs Date: Wed, 19 Feb 2020 12:38:05 -0800 Subject: [PATCH 05/52] null check in showLableSuggestion(). It throws NPE when the data is missing for all the packages and all the suggestions are null. Change-Id: I4aa36969e1aee00bcfc577a839d6da01d4e67a75 --- src/com/android/launcher3/folder/Folder.java | 2 +- src/com/android/launcher3/folder/FolderNameInfo.java | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java index 1d79e011ff..c72509edac 100644 --- a/src/com/android/launcher3/folder/Folder.java +++ b/src/com/android/launcher3/folder/Folder.java @@ -487,9 +487,9 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo nameInfos[0].getLabel()) || nameInfos.length > 1 && nameInfos[1] != null && !isEmpty( nameInfos[1].getLabel()); - CharSequence firstLabel = nameInfos[0].getLabel(); if (shouldOpen) { + CharSequence firstLabel = nameInfos[0] == null ? "" : nameInfos[0].getLabel(); if (!isEmpty(firstLabel)) { mFolderName.setHint(""); mFolderName.setText(firstLabel); diff --git a/src/com/android/launcher3/folder/FolderNameInfo.java b/src/com/android/launcher3/folder/FolderNameInfo.java index eb9da90ac4..ecbe46c70a 100644 --- a/src/com/android/launcher3/folder/FolderNameInfo.java +++ b/src/com/android/launcher3/folder/FolderNameInfo.java @@ -80,4 +80,10 @@ public final class FolderNameInfo implements Parcelable { public int describeContents() { return 0; } + + @Override + @NonNull + public String toString() { + return mLabel.toString() + ":" + mScore; + } } From 63b7f36338c5ccce05b97d8fa16e740142360d4a Mon Sep 17 00:00:00 2001 From: Andy Wickham Date: Tue, 18 Feb 2020 23:19:42 +0000 Subject: [PATCH 06/52] Renames BackGestureTutorialActivity to GestureSandboxActivity. Bug: 148542211 Change-Id: Iaac537380b02f1c52f967748c30fe49ac36bb91e --- quickstep/AndroidManifest.xml | 4 ++-- quickstep/res/values/config.xml | 2 +- ...stureTutorialActivity.java => GestureSandboxActivity.java} | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) rename quickstep/src/com/android/quickstep/interaction/{BackGestureTutorialActivity.java => GestureSandboxActivity.java} (95%) diff --git a/quickstep/AndroidManifest.xml b/quickstep/AndroidManifest.xml index d3cec28dd3..7ce4d7440c 100644 --- a/quickstep/AndroidManifest.xml +++ b/quickstep/AndroidManifest.xml @@ -93,12 +93,12 @@ android:directBootAware="true" /> - + diff --git a/quickstep/res/values/config.xml b/quickstep/res/values/config.xml index 304963f82a..a688f9a575 100644 --- a/quickstep/res/values/config.xml +++ b/quickstep/res/values/config.xml @@ -18,7 +18,7 @@ - com.android.launcher3/com.android.quickstep.interaction.BackGestureTutorialActivity + com.android.launcher3/com.android.quickstep.interaction.GestureSandboxActivity com.android.quickstep.logging.StatsLogCompatManager diff --git a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialActivity.java b/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java similarity index 95% rename from quickstep/src/com/android/quickstep/interaction/BackGestureTutorialActivity.java rename to quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java index d2a0951c62..8081ad7ce1 100644 --- a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialActivity.java +++ b/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java @@ -32,8 +32,8 @@ import com.android.quickstep.interaction.BackGestureTutorialFragment.TutorialTyp import java.util.List; import java.util.Optional; -/** Shows the Back gesture interactive tutorial in full screen mode. */ -public class BackGestureTutorialActivity extends FragmentActivity { +/** Shows the gesture interactive sandbox in full screen mode. */ +public class GestureSandboxActivity extends FragmentActivity { Optional mFragment = Optional.empty(); From 9fb7d28b638d70be07337ce2c73038bdcfaf8b5d Mon Sep 17 00:00:00 2001 From: Andy Wickham Date: Thu, 20 Feb 2020 00:07:06 +0000 Subject: [PATCH 07/52] Removes exported="true" for RecentsActivity. Change-Id: Iea9ad04886c3221cefa709c14b6501b2af83af06 --- quickstep/AndroidManifest.xml | 3 --- 1 file changed, 3 deletions(-) diff --git a/quickstep/AndroidManifest.xml b/quickstep/AndroidManifest.xml index 7ce4d7440c..a06a2dd208 100644 --- a/quickstep/AndroidManifest.xml +++ b/quickstep/AndroidManifest.xml @@ -47,10 +47,7 @@ - Date: Tue, 18 Feb 2020 11:52:53 -0800 Subject: [PATCH 08/52] Render user's actual workspace in ThemePicker preview (Part 5) This change takes care of rendering widgets using widget provider's layout info. Test: manual Bug: 144052839 Change-Id: I7002d8bf653513cdd317736d550a47f61f0ee474 --- .../android/launcher3/model/WidgetsModel.java | 6 ++ .../graphics/LauncherPreviewRenderer.java | 63 ++++++++++++++++--- .../launcher3/model/PackageItemInfo.java | 15 +++++ .../android/launcher3/model/WidgetsModel.java | 13 ++++ 4 files changed, 88 insertions(+), 9 deletions(-) diff --git a/go/src/com/android/launcher3/model/WidgetsModel.java b/go/src/com/android/launcher3/model/WidgetsModel.java index 7690b9d57c..3b3dc0196c 100644 --- a/go/src/com/android/launcher3/model/WidgetsModel.java +++ b/go/src/com/android/launcher3/model/WidgetsModel.java @@ -16,6 +16,7 @@ package com.android.launcher3.model; +import android.content.ComponentName; import android.content.Context; import android.os.UserHandle; @@ -68,4 +69,9 @@ public class WidgetsModel { public void onPackageIconsUpdated(Set packageNames, UserHandle user, LauncherAppState app) { } + + public WidgetItem getWidgetProviderInfoByProviderName( + ComponentName providerName) { + return null; + } } \ No newline at end of file diff --git a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java index def76e8d30..a429af22d4 100644 --- a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java +++ b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java @@ -25,6 +25,7 @@ import static com.android.launcher3.model.ModelUtils.sortWorkspaceItemsSpatially import android.annotation.TargetApi; import android.app.Fragment; +import android.appwidget.AppWidgetHostView; import android.content.Context; import android.content.Intent; import android.content.res.TypedArray; @@ -55,6 +56,7 @@ import com.android.launcher3.InsettableFrameLayout; import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.ItemInfo; import com.android.launcher3.LauncherAppState; +import com.android.launcher3.LauncherAppWidgetInfo; import com.android.launcher3.LauncherModel; import com.android.launcher3.LauncherSettings; import com.android.launcher3.LauncherSettings.Favorites; @@ -72,6 +74,8 @@ import com.android.launcher3.model.AllAppsList; import com.android.launcher3.model.BgDataModel; import com.android.launcher3.model.BgDataModel.Callbacks; import com.android.launcher3.model.LoaderResults; +import com.android.launcher3.model.WidgetItem; +import com.android.launcher3.model.WidgetsModel; import com.android.launcher3.views.ActivityContext; import com.android.launcher3.views.BaseDragLayer; @@ -248,6 +252,16 @@ public class LauncherPreviewRenderer implements Callable { addInScreenFromBind(folderIcon, info); } + private void inflateAndAddWidgets(LauncherAppWidgetInfo info, WidgetsModel widgetsModel) { + WidgetItem widgetItem = widgetsModel.getWidgetProviderInfoByProviderName( + info.providerName); + AppWidgetHostView view = new AppWidgetHostView(mContext); + view.setAppWidget(-1, widgetItem.widgetInfo); + view.updateAppWidget(null); + view.setTag(info); + addInScreenFromBind(view, info); + } + private void dispatchVisibilityAggregated(View view, boolean isVisible) { // Similar to View.dispatchVisibilityAggregated implementation. final boolean thisVisible = view.getVisibility() == VISIBLE; @@ -272,9 +286,9 @@ public class LauncherPreviewRenderer implements Callable { mContext).getModel(); final WorkspaceItemsInfoFetcher fetcher = new WorkspaceItemsInfoFetcher(); launcherModel.enqueueModelUpdateTask(fetcher); - ArrayList workspaceItems; + WorkspaceResult workspaceResult; try { - workspaceItems = fetcher.mTask.get(5, TimeUnit.SECONDS); + workspaceResult = fetcher.mTask.get(5, TimeUnit.SECONDS); } catch (InterruptedException | ExecutionException | TimeoutException e) { Log.d(TAG, "Error fetching workspace items info", e); return; @@ -284,9 +298,14 @@ public class LauncherPreviewRenderer implements Callable { // items ArrayList currentWorkspaceItems = new ArrayList<>(); ArrayList otherWorkspaceItems = new ArrayList<>(); + ArrayList currentAppWidgets = new ArrayList<>(); + ArrayList otherAppWidgets = new ArrayList<>(); - filterCurrentWorkspaceItems(0 /* currentScreenId */, workspaceItems, - currentWorkspaceItems, otherWorkspaceItems); + filterCurrentWorkspaceItems(0 /* currentScreenId */, + workspaceResult.mWorkspaceItems, currentWorkspaceItems, + otherWorkspaceItems); + filterCurrentWorkspaceItems(0 /* currentScreenId */, workspaceResult.mAppWidgets, + currentAppWidgets, otherAppWidgets); sortWorkspaceItemsSpatially(mIdp, currentWorkspaceItems); for (ItemInfo itemInfo : currentWorkspaceItems) { @@ -303,6 +322,17 @@ public class LauncherPreviewRenderer implements Callable { break; } } + for (ItemInfo itemInfo : currentAppWidgets) { + switch (itemInfo.itemType) { + case Favorites.ITEM_TYPE_APPWIDGET: + case Favorites.ITEM_TYPE_CUSTOM_APPWIDGET: + inflateAndAddWidgets((LauncherAppWidgetInfo) itemInfo, + workspaceResult.mWidgetsModel); + break; + default: + break; + } + } } else { // Add hotseat icons for (int i = 0; i < mIdp.numHotseatIcons; i++) { @@ -349,10 +379,10 @@ public class LauncherPreviewRenderer implements Callable { } } - private static class WorkspaceItemsInfoFetcher implements Callable>, + private static class WorkspaceItemsInfoFetcher implements Callable, LauncherModel.ModelUpdateTask { - private final FutureTask> mTask = new FutureTask<>(this); + private final FutureTask mTask = new FutureTask<>(this); private LauncherAppState mApp; private LauncherModel mModel; @@ -374,14 +404,16 @@ public class LauncherPreviewRenderer implements Callable { } @Override - public ArrayList call() throws Exception { + public WorkspaceResult call() throws Exception { if (!mModel.isModelLoaded()) { Log.d(TAG, "Workspace not loaded, loading now"); mModel.startLoaderForResults( new LoaderResults(mApp, mBgDataModel, mAllAppsList, new Callbacks[0])); - return new ArrayList<>(); + return null; } - return mBgDataModel.workspaceItems; + + return new WorkspaceResult(mBgDataModel.workspaceItems, mBgDataModel.appWidgets, + mBgDataModel.widgetsModel); } } @@ -389,4 +421,17 @@ public class LauncherPreviewRenderer implements Callable { view.measure(makeMeasureSpec(width, EXACTLY), makeMeasureSpec(height, EXACTLY)); view.layout(0, 0, width, height); } + + private static class WorkspaceResult { + private final ArrayList mWorkspaceItems; + private final ArrayList mAppWidgets; + private final WidgetsModel mWidgetsModel; + + private WorkspaceResult(ArrayList workspaceItems, + ArrayList appWidgets, WidgetsModel widgetsModel) { + mWorkspaceItems = workspaceItems; + mAppWidgets = appWidgets; + mWidgetsModel = widgetsModel; + } + } } diff --git a/src/com/android/launcher3/model/PackageItemInfo.java b/src/com/android/launcher3/model/PackageItemInfo.java index 3ef48cd8fd..2fc064c422 100644 --- a/src/com/android/launcher3/model/PackageItemInfo.java +++ b/src/com/android/launcher3/model/PackageItemInfo.java @@ -19,6 +19,8 @@ package com.android.launcher3.model; import com.android.launcher3.ItemInfoWithIcon; import com.android.launcher3.LauncherSettings; +import java.util.Objects; + /** * Represents a {@link Package} in the widget tray section. */ @@ -48,4 +50,17 @@ public class PackageItemInfo extends ItemInfoWithIcon { public PackageItemInfo clone() { return new PackageItemInfo(this); } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + PackageItemInfo that = (PackageItemInfo) o; + return Objects.equals(packageName, that.packageName); + } + + @Override + public int hashCode() { + return Objects.hash(packageName); + } } diff --git a/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java b/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java index 5ebf8d397f..2c6dce4ccb 100644 --- a/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java +++ b/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java @@ -6,6 +6,7 @@ import static android.appwidget.AppWidgetProviderInfo.WIDGET_FEATURE_HIDE_FROM_P import static com.android.launcher3.pm.ShortcutConfigActivityInfo.queryList; import android.appwidget.AppWidgetProviderInfo; +import android.content.ComponentName; import android.content.Context; import android.content.pm.PackageManager; import android.os.Process; @@ -243,4 +244,16 @@ public class WidgetsModel { } } } + + public WidgetItem getWidgetProviderInfoByProviderName( + ComponentName providerName) { + ArrayList widgetsList = mWidgetsList.get( + new PackageItemInfo(providerName.getPackageName())); + for (WidgetItem item : widgetsList) { + if (item.componentName.equals(providerName)) { + return item; + } + } + return null; + } } \ No newline at end of file From d1c07797269afc77608809b72088f89fad71acf9 Mon Sep 17 00:00:00 2001 From: Samuel Fufa Date: Wed, 19 Feb 2020 17:07:00 -0800 Subject: [PATCH 09/52] Increase timeout for flaky work test Bug:149867607 Change-Id: Ic746a4857a47fc29372d19419ddfa6eaebd06f87 --- tests/src/com/android/launcher3/ui/WorkTabTest.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/src/com/android/launcher3/ui/WorkTabTest.java b/tests/src/com/android/launcher3/ui/WorkTabTest.java index 5aa009006b..810c91a4a5 100644 --- a/tests/src/com/android/launcher3/ui/WorkTabTest.java +++ b/tests/src/com/android/launcher3/ui/WorkTabTest.java @@ -73,11 +73,10 @@ public class WorkTabTest extends AbstractLauncherUiTest { mDevice.pressHome(); waitForLauncherCondition("Launcher didn't start", Objects::nonNull); executeOnLauncher(launcher -> launcher.getStateManager().goToState(ALL_APPS)); - waitForLauncherCondition("Personal tab is missing", - launcher -> launcher.getAppsView().isPersonalTabVisible()); + launcher -> launcher.getAppsView().isPersonalTabVisible(), 60000); waitForLauncherCondition("Work tab is missing", - launcher -> launcher.getAppsView().isWorkTabVisible()); + launcher -> launcher.getAppsView().isWorkTabVisible(), 60000); } @Test From 4e3eaa5a71d127f30927e07cc42ddfa7afcb4887 Mon Sep 17 00:00:00 2001 From: Becky Qiu Date: Wed, 19 Feb 2020 17:37:22 -0800 Subject: [PATCH 10/52] [Overview Actions] Add ControlType for overview action buttons. Design: go/logging_for_overview_actions Test:local, logging result: https://paste.googleplex.com/6489148393259008 Bug:139828243 Change-Id: I61fa66f8ec6edae43f6242599f8d4ea8e28d735d --- protos/launcher_log.proto | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/protos/launcher_log.proto b/protos/launcher_log.proto index ec1d55b753..d08d851e15 100644 --- a/protos/launcher_log.proto +++ b/protos/launcher_log.proto @@ -151,6 +151,10 @@ enum ControlType { DISMISS_PREDICTION = 21; HYBRID_HOTSEAT_ACCEPTED = 22; HYBRID_HOTSEAT_CANCELED = 23; + OVERVIEW_ACTIONS_SHARE_BUTTON = 24; + OVERVIEW_ACTIONS_SCREENSHOT_BUTTON = 25; + OVERVIEW_ACTIONS_SELECT_BUTTON = 26; + SELECT_MODE_CLOSE_BUTTON = 27; } enum TipType { From f3b7246bf273b69a1a7390b4fbb7794ed57168ee Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Wed, 20 Nov 2019 12:27:06 -0800 Subject: [PATCH 11/52] Adding new tracing call from SysUI Bug: 144854916 Test: This change is only to ensure the changes build Change-Id: I62b247b45454861328b6062ed571c854a374aa34 --- protos/launcher_trace.proto | 31 +++++ protos/launcher_trace_file.proto | 49 +++++++ .../quickstep/TouchInteractionService.java | 30 ++++- .../android/quickstep/util/ProtoTracer.java | 127 ++++++++++++++++++ 4 files changed, 236 insertions(+), 1 deletion(-) create mode 100644 protos/launcher_trace.proto create mode 100644 protos/launcher_trace_file.proto create mode 100644 quickstep/recents_ui_overrides/src/com/android/quickstep/util/ProtoTracer.java diff --git a/protos/launcher_trace.proto b/protos/launcher_trace.proto new file mode 100644 index 0000000000..c6f3543c09 --- /dev/null +++ b/protos/launcher_trace.proto @@ -0,0 +1,31 @@ +/* + * 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. + */ + +syntax = "proto2"; + +package com.android.launcher3.tracing; + +option java_multiple_files = true; + +message LauncherTraceProto { + + optional TouchInteractionServiceProto touch_interaction_service = 1; +} + +message TouchInteractionServiceProto { + + optional bool service_connected = 1; +} diff --git a/protos/launcher_trace_file.proto b/protos/launcher_trace_file.proto new file mode 100644 index 0000000000..6ce182a2ad --- /dev/null +++ b/protos/launcher_trace_file.proto @@ -0,0 +1,49 @@ +/* + * 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. + */ + +syntax = "proto2"; + +import "launcher_trace.proto"; + +package com.android.launcher3.tracing; + +option java_multiple_files = true; + +/* represents a file full of launcher trace entries. + Encoded, it should start with 0x9 0x4C 0x4E 0x43 0x48 0x52 0x54 0x52 0x43 (.LNCHRTRC), such + that they can be easily identified. */ +message LauncherTraceFileProto { + + /* constant; MAGIC_NUMBER = (long) MAGIC_NUMBER_H << 32 | MagicNumber.MAGIC_NUMBER_L + (this is needed because enums have to be 32 bits and there's no nice way to put 64bit + constants into .proto files. */ + enum MagicNumber { + INVALID = 0; + MAGIC_NUMBER_L = 0x48434E4C; /* LNCH (little-endian ASCII) */ + MAGIC_NUMBER_H = 0x43525452; /* RTRC (little-endian ASCII) */ + } + + optional fixed64 magic_number = 1; /* Must be the first field, set to value in MagicNumber */ + repeated LauncherTraceEntryProto entry = 2; +} + +/* one launcher trace entry. */ +message LauncherTraceEntryProto { + /* required: elapsed realtime in nanos since boot of when this entry was logged */ + optional fixed64 elapsed_realtime_nanos = 1; + + optional LauncherTraceProto launcher = 3; +} 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 e62f571736..70a2f9b4f5 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java @@ -28,6 +28,7 @@ import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_INPUT_MONITOR; import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SYSUI_PROXY; +import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_TRACING_ENABLED; import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.ACTIVITY_TYPE_ASSISTANT; import android.annotation.TargetApi; @@ -63,6 +64,8 @@ import com.android.launcher3.model.AppLaunchTracker; import com.android.launcher3.provider.RestoreDbTask; import com.android.launcher3.testing.TestLogging; import com.android.launcher3.testing.TestProtocol; +import com.android.launcher3.tracing.nano.LauncherTraceProto; +import com.android.launcher3.tracing.nano.TouchInteractionServiceProto; import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper; import com.android.launcher3.util.TraceHelper; import com.android.quickstep.inputconsumers.AccessibilityInputConsumer; @@ -76,6 +79,7 @@ import com.android.quickstep.inputconsumers.ResetGestureInputConsumer; import com.android.quickstep.inputconsumers.ScreenPinnedInputConsumer; import com.android.quickstep.util.ActiveGestureLog; import com.android.quickstep.util.AssistantUtilities; +import com.android.quickstep.util.ProtoTracer; import com.android.systemui.plugins.OverscrollPlugin; import com.android.systemui.plugins.PluginListener; import com.android.systemui.shared.recents.IOverviewProxy; @@ -85,6 +89,7 @@ import com.android.systemui.shared.system.InputChannelCompat.InputEventReceiver; import com.android.systemui.shared.system.InputConsumerController; import com.android.systemui.shared.system.InputMonitorCompat; import com.android.systemui.shared.system.RecentsAnimationListener; +import com.android.systemui.shared.tracing.ProtoTraceable; import java.io.FileDescriptor; import java.io.PrintWriter; @@ -113,7 +118,8 @@ class ArgList extends LinkedList { * Service connected by system-UI for handling touch interaction. */ @TargetApi(Build.VERSION_CODES.Q) -public class TouchInteractionService extends Service implements PluginListener { +public class TouchInteractionService extends Service implements PluginListener, + ProtoTraceable { private static final String TAG = "TouchInteractionService"; @@ -275,6 +281,7 @@ public class TouchInteractionService extends Service implements PluginListener { + + public static final MainThreadInitializedObject INSTANCE = + new MainThreadInitializedObject<>(ProtoTracer::new); + + private static final String TAG = "ProtoTracer"; + private static final long MAGIC_NUMBER_VALUE = ((long) MAGIC_NUMBER_H << 32) | MAGIC_NUMBER_L; + + private final Context mContext; + private final FrameProtoTracer mProtoTracer; + + public ProtoTracer(Context context) { + mContext = context; + mProtoTracer = new FrameProtoTracer<>(this); + } + + @Override + public File getTraceFile() { + return new File(mContext.getFilesDir(), "launcher_trace.pb"); + } + + @Override + public LauncherTraceFileProto getEncapsulatingTraceProto() { + return new LauncherTraceFileProto(); + } + + @Override + public LauncherTraceEntryProto updateBufferProto(LauncherTraceEntryProto reuseObj, + ArrayList> traceables) { + LauncherTraceEntryProto proto = reuseObj != null + ? reuseObj + : new LauncherTraceEntryProto(); + proto.elapsedRealtimeNanos = SystemClock.elapsedRealtimeNanos(); + proto.launcher = proto.launcher != null ? proto.launcher : new LauncherTraceProto(); + for (ProtoTraceable t : traceables) { + t.writeToProto(proto.launcher); + } + return proto; + } + + @Override + public byte[] serializeEncapsulatingProto(LauncherTraceFileProto encapsulatingProto, + Queue buffer) { + encapsulatingProto.magicNumber = MAGIC_NUMBER_VALUE; + encapsulatingProto.entry = buffer.toArray(new LauncherTraceEntryProto[0]); + return MessageNano.toByteArray(encapsulatingProto); + } + + @Override + public byte[] getProtoBytes(MessageNano proto) { + return MessageNano.toByteArray(proto); + } + + @Override + public int getProtoSize(MessageNano proto) { + return proto.getCachedSize(); + } + + public void start() { + mProtoTracer.start(); + } + + public void stop() { + mProtoTracer.stop(); + } + + public void add(ProtoTraceable traceable) { + mProtoTracer.add(traceable); + } + + public void remove(ProtoTraceable traceable) { + mProtoTracer.remove(traceable); + } + + public void scheduleFrameUpdate() { + mProtoTracer.scheduleFrameUpdate(); + } + + public void update() { + mProtoTracer.update(); + } +} From aeaad97eb7ac5610491c35d2bc7bd15758d22966 Mon Sep 17 00:00:00 2001 From: Samuel Fufa Date: Thu, 20 Feb 2020 11:21:26 -0800 Subject: [PATCH 12/52] Increase timeout for WorkTabTest.toggleWorks test Bug: 149927292 Change-Id: I6dcd0bfa2fe584be9e46f653992f9c748e795614 --- tests/src/com/android/launcher3/ui/WorkTabTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/src/com/android/launcher3/ui/WorkTabTest.java b/tests/src/com/android/launcher3/ui/WorkTabTest.java index 810c91a4a5..6fe6739072 100644 --- a/tests/src/com/android/launcher3/ui/WorkTabTest.java +++ b/tests/src/com/android/launcher3/ui/WorkTabTest.java @@ -88,7 +88,7 @@ public class WorkTabTest extends AbstractLauncherUiTest { executeOnLauncher(launcher -> launcher.getStateManager().goToState(ALL_APPS)); waitForState("Launcher internal state didn't switch to All Apps", () -> ALL_APPS); getOnceNotNull("Apps view did not bind", - launcher -> launcher.getAppsView().getWorkFooterContainer()); + launcher -> launcher.getAppsView().getWorkFooterContainer(), 60000); UserManager userManager = getFromLauncher(l -> l.getSystemService(UserManager.class)); assertEquals(2, userManager.getUserProfiles().size()); From 27d3c595cfd3c462b93364c357253c2f4b686f37 Mon Sep 17 00:00:00 2001 From: Andy Wickham Date: Thu, 20 Feb 2020 20:32:07 +0000 Subject: [PATCH 13/52] Makes all ArrowPopups AccessibilityTargets. This currently includes the menu that pops up when long pressing an app icon in Launcher or Search, or long pressing Smartspace. Previously, only the menu for Launcher apps grabbed accessibility focus after the open animation completed, and now all three do. Fixes: 145253300 Change-Id: I147b45d38a04ab9a55eee9b5bd5551b4c7185fcf --- src/com/android/launcher3/popup/ArrowPopup.java | 6 ++++++ .../android/launcher3/popup/PopupContainerWithArrow.java | 6 ------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/com/android/launcher3/popup/ArrowPopup.java b/src/com/android/launcher3/popup/ArrowPopup.java index d9bd7144c5..065eb37470 100644 --- a/src/com/android/launcher3/popup/ArrowPopup.java +++ b/src/com/android/launcher3/popup/ArrowPopup.java @@ -32,6 +32,7 @@ import android.graphics.Paint; import android.graphics.Rect; import android.graphics.drawable.ShapeDrawable; import android.util.AttributeSet; +import android.util.Pair; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; @@ -358,6 +359,11 @@ public abstract class ArrowPopup extends Abstrac } } + @Override + protected Pair getAccessibilityTarget() { + return Pair.create(this, ""); + } + private void animateOpen() { setVisibility(View.VISIBLE); diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java index 05ea694d6f..445acca5c9 100644 --- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java +++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java @@ -37,7 +37,6 @@ import android.os.Build; import android.os.Handler; import android.os.Looper; import android.util.AttributeSet; -import android.util.Pair; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; @@ -329,11 +328,6 @@ public class PopupContainerWithArrow extends Arr R.string.shortcuts_menu_with_notifications_description); } - @Override - protected Pair getAccessibilityTarget() { - return Pair.create(this, ""); - } - @Override protected void getTargetObjectLocation(Rect outPos) { getPopupContainer().getDescendantRectRelativeToSelf(mOriginalIcon, outPos); From 2f41808e9b7e361341c70c6978301f90bbacfc03 Mon Sep 17 00:00:00 2001 From: vadimt Date: Wed, 19 Feb 2020 14:19:17 -0800 Subject: [PATCH 14/52] Updating logcat reading logic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Start a thread to read logcat synchronusly instead of back-tracking at the end of the test Also: * Reusing the same logcat process for all checks. This eliminates reading the log from its start for every gesture. We don’t kill that process at the end, and don’t stop the thread. I’ve verified that “am instrument” doesn’t hang, and the logcat process gets automatically killed after the test process exits. * Not using mStarted latch, as there is no need to wait until the reader reaches the start mark. Bug: 149422395 Change-Id: Ide4ed19ad8d099c41918f38c2b073b8b2e143b69 --- .../tapl/LauncherInstrumentation.java | 233 ++---------------- .../launcher3/tapl/LogEventChecker.java | 233 ++++++++++++++++++ 2 files changed, 258 insertions(+), 208 deletions(-) create mode 100644 tests/tapl/com/android/launcher3/tapl/LogEventChecker.java diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index c5fbd7c330..b3b887db22 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -69,22 +69,16 @@ import org.junit.Assert; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.lang.ref.WeakReference; -import java.text.ParseException; -import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.Date; import java.util.Deque; -import java.util.HashMap; import java.util.LinkedList; import java.util.List; -import java.util.Map; import java.util.concurrent.TimeoutException; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; -import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -97,16 +91,8 @@ public final class LauncherInstrumentation { private static final String TAG = "Tapl"; private static final int ZERO_BUTTON_STEPS_FROM_BACKGROUND_TO_HOME = 20; private static final int GESTURE_STEP_MS = 16; - private static final SimpleDateFormat DATE_TIME_FORMAT = - new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); private static long START_TIME = System.currentTimeMillis(); - static final Pattern EVENT_LOG_ENTRY = Pattern.compile( - "(?