From b3fbc0ba8f94a6a0f60822dc7fc209c45d7501d9 Mon Sep 17 00:00:00 2001 From: Hyunyoung Song Date: Wed, 14 Feb 2018 13:40:25 -0800 Subject: [PATCH] Quick step/scrub/switch logging - state transition happening due to Home and back is handled by specifying src target as 'from' container and dst target as the 'to' container - Source and Destination container shows FROM and TO state for SWIPE/FLING - event.isStateChange = true indicates that an action resulted in state transition - Elapsed container millis is the screen time on the source container Bug: 70181187 - logcat printout with setprop log.tag.UserEvent VERBOSE 1) State: WORKSPACE -> ALLAPPS action:FLING direction=UP Source child:HOTSEAT id=0 parent:WORKSPACE id=0 Destination child:ALLAPPS Elapsed container 1225 ms, session 1225 ms, action 0 ms 2) ALLAPPS -> HOMESCREEN action:FLING direction=DOWN Source child:ALLAPPS parent:ALLAPPS Destination child:WORKSPACE id=0 Elapsed container 971 ms, session 2197 ms, action 0 ms 3) HOMESCREEN -> OVERVIEW action:FLING direction=UP Source child:NAVBAR parent:WORKSPACE id=0 Destination child:TASKSWITCHER Elapsed container 4834 ms, session 4834 ms, action 0 ms 4) OVERVIEW-> ALLAPPS action:FLING direction=UP Source child:TASK parent:TASKSWITCHER Destination child:ALLAPPS Elapsed container 2176 ms, session 7010 ms, action 0 ms 5) ALLAPPS->OVERVIEW action:FLING direction=DOWN Source child:ALLAPPS parent:ALLAPPS Destination child:TASKSWITCHER Elapsed container 3683 ms, session 10693 ms, action 0 ms 6) OVERVIEW-> HOMESCREEN action:FLING direction=DOWN Source child:TASK parent:TASKSWITCHER Destination child:WORKSPACE id=0 Elapsed container 2108 ms, session 12801 ms, action 0 ms 7) APPS-> OVERVIEW action:FLING direction=UP Source child:NAVBAR parent:APP Destination child:TASKSWITCHER Elapsed container 104 ms, session 104 ms, action 0 ms 8) Quickscrub: action:DRAGANDDROP Source child: QUICK 9) Quickswitch: action:FLING Source child: QUICK Change-Id: I5898230859ff600f48a2a873a40b670fe4d39a0d --- protos/launcher_log.proto | 9 +- .../uioverrides/EdgeSwipeController.java | 23 +++- .../launcher3/uioverrides/OverviewState.java | 2 +- .../uioverrides/OverviewSwipeController.java | 28 ++++- .../OverviewSwipeUpController.java | 6 +- .../uioverrides/TwoStepSwipeController.java | 10 +- .../quickstep/QuickScrubController.java | 16 ++- .../com/android/quickstep/RecentsView.java | 2 +- .../WindowTransformSwipeHandler.java | 28 +++++ .../launcher3/AbstractFloatingView.java | 3 +- src/com/android/launcher3/Launcher.java | 12 +- .../launcher3/LauncherStateManager.java | 1 - src/com/android/launcher3/Workspace.java | 2 +- src/com/android/launcher3/folder/Folder.java | 2 +- .../launcher3/logging/LoggerUtils.java | 19 +++- .../logging/UserEventDispatcher.java | 103 +++++++++++++++--- 16 files changed, 219 insertions(+), 47 deletions(-) diff --git a/protos/launcher_log.proto b/protos/launcher_log.proto index de74fcec5f..3b983d254f 100644 --- a/protos/launcher_log.proto +++ b/protos/launcher_log.proto @@ -68,6 +68,7 @@ enum ItemType { SEARCHBOX = 6; EDITTEXT = 7; NOTIFICATION = 8; + TASK = 9; // Each page of Recents UI (QuickStep) } // Used to define what type of container a Target would represent. @@ -78,11 +79,14 @@ enum ContainerType { FOLDER = 3; ALLAPPS = 4; WIDGETS = 5; - OVERVIEW = 6; + OVERVIEW = 6; // Zoomed out workspace (without QuickStep) PREDICTION = 7; SEARCHRESULT = 8; DEEPSHORTCUTS = 9; PINITEM = 10; // confirmation screen + NAVBAR = 11; + TASKSWITCHER = 12; // Recents UI Container (QuickStep) + APP = 13; // Foreground activity is another app (QuickStep) } // Used to define what type of control a Target would represent. @@ -100,6 +104,7 @@ enum ControlType { HOME_INTENT = 10; // Deprecated, use enum Command instead BACK_BUTTON = 11; // Deprecated, use enum Command instead // GO_TO_PLAYSTORE + QUICK_SCRUB_BUTTON = 12; } // Used to define the action component of the LauncherEvent. @@ -141,6 +146,7 @@ message Action { optional Command command = 4; // Log if the action was performed on outside of the container optional bool is_outside = 5; + optional bool is_state_change = 6; } // @@ -150,7 +156,6 @@ message Action { // message LauncherEvent { required Action action = 1; - // List of targets that touch actions can be operated on. repeated Target src_target = 2; repeated Target dest_target = 3; diff --git a/quickstep/src/com/android/launcher3/uioverrides/EdgeSwipeController.java b/quickstep/src/com/android/launcher3/uioverrides/EdgeSwipeController.java index bf55bd6f52..3d2830d191 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/EdgeSwipeController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/EdgeSwipeController.java @@ -30,8 +30,12 @@ import android.view.MotionEvent; import com.android.launcher3.DeviceProfile; import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener; import com.android.launcher3.Launcher; +import com.android.launcher3.LauncherState; import com.android.launcher3.anim.SpringAnimationHandler; import com.android.launcher3.dragndrop.DragLayer; +import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch; +import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction; +import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; import com.android.launcher3.util.VerticalSwipeController; import com.android.quickstep.RecentsView; @@ -100,6 +104,10 @@ public class EdgeSwipeController extends VerticalSwipeController implements return isTransitionFlipped() ? DIRECTION_NEGATIVE : DIRECTION_POSITIVE; } + public EdgeSwipeController(Launcher l, LauncherState baseState) { + super(l, baseState); + } + @Override protected boolean isTransitionFlipped() { return mLauncher.getDeviceProfile().isSeascape(); @@ -117,8 +125,21 @@ public class EdgeSwipeController extends VerticalSwipeController implements builder.addTaggedData(319/*APP_TRANSITION_DELAY_MS*/, 0/* zero time */); mMetricsLogger.write(builder); + + // Add user event logging for launcher pipeline + int direction = Direction.UP; + if (mLauncher.getDeviceProfile().isLandscape) { + direction = Direction.LEFT; + if (mLauncher.getDeviceProfile().isSeascape()) { + direction = Direction.RIGHT; + } + } + mLauncher.getUserEventDispatcher().logStateChangeAction( + wasFling ? Touch.FLING : Touch.SWIPE, direction, + ContainerType.NAVBAR, ContainerType.WORKSPACE, // src target + ContainerType.TASKSWITCHER, // dst target + mLauncher.getWorkspace().getCurrentPage()); } - // TODO: Log something } @Override diff --git a/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java b/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java index 5706d32eb4..9ba2308c62 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java +++ b/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java @@ -40,7 +40,7 @@ public class OverviewState extends LauncherState { | FLAG_DISABLE_RESTORE; public OverviewState(int id) { - super(id, ContainerType.WORKSPACE, OVERVIEW_TRANSITION_MS, STATE_FLAGS); + super(id, ContainerType.TASKSWITCHER, OVERVIEW_TRANSITION_MS, STATE_FLAGS); } @Override diff --git a/quickstep/src/com/android/launcher3/uioverrides/OverviewSwipeController.java b/quickstep/src/com/android/launcher3/uioverrides/OverviewSwipeController.java index 1fd541a490..468a5617cb 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/OverviewSwipeController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/OverviewSwipeController.java @@ -31,6 +31,10 @@ import com.android.launcher3.Utilities; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.dragndrop.DragLayer; import com.android.launcher3.touch.SwipeDetector; +import com.android.launcher3.userevent.nano.LauncherLogProto; +import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; +import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction; +import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch; import com.android.launcher3.util.TouchController; import com.android.quickstep.RecentsView; import com.android.quickstep.TaskView; @@ -70,6 +74,7 @@ public class OverviewSwipeController extends AnimatorListenerAdapter private float mDisplacementShift; private float mProgressMultiplier; private float mEndDisplacement; + private int mStartingTarget; private TaskView mTaskBeingDragged; @@ -120,7 +125,6 @@ public class OverviewSwipeController extends AnimatorListenerAdapter // calling the callbacks. final int directionsToDetectScroll; boolean ignoreSlopWhenSettling = false; - if (mCurrentAnimation != null) { directionsToDetectScroll = SwipeDetector.DIRECTION_BOTH; ignoreSlopWhenSettling = true; @@ -139,12 +143,15 @@ public class OverviewSwipeController extends AnimatorListenerAdapter // The tile can be dragged down to open the task. mTaskBeingDragged = (TaskView) view; directionsToDetectScroll = SwipeDetector.DIRECTION_BOTH; + mStartingTarget = LauncherLogProto.ItemType.TASK; } else if (isEventOverHotseat(ev)) { // The hotseat is being dragged directionsToDetectScroll = SwipeDetector.DIRECTION_POSITIVE; mSwipeDownEnabled = false; + mStartingTarget = ContainerType.HOTSEAT; } else { mNoIntercept = true; + mStartingTarget = ContainerType.WORKSPACE; return false; } } @@ -249,8 +256,9 @@ public class OverviewSwipeController extends AnimatorListenerAdapter @Override public void onDragEnd(float velocity, boolean fling) { final boolean goingToEnd; - + final int logAction; if (fling) { + logAction = Touch.FLING; boolean goingUp = velocity < 0; if (!goingUp && !mSwipeDownEnabled) { goingToEnd = false; @@ -269,6 +277,7 @@ public class OverviewSwipeController extends AnimatorListenerAdapter goingToEnd = true; } } else { + logAction = Touch.SWIPE; goingToEnd = mCurrentAnimation.getProgressFraction() > SUCCESS_TRANSITION_PROGRESS; } @@ -280,7 +289,7 @@ public class OverviewSwipeController extends AnimatorListenerAdapter progress + velocity * SINGLE_FRAME_MS / Math.abs(mEndDisplacement), 0f, 1f); - mCurrentAnimation.setEndAction(() -> onCurrentAnimationEnd(goingToEnd)); + mCurrentAnimation.setEndAction(() -> onCurrentAnimationEnd(goingToEnd, logAction)); ValueAnimator anim = mCurrentAnimation.getAnimationPlayer(); anim.setFloatValues(nextFrameProgress, goingToEnd ? 1f : 0f); @@ -289,19 +298,28 @@ public class OverviewSwipeController extends AnimatorListenerAdapter anim.start(); } - private void onCurrentAnimationEnd(boolean wasSuccess) { - // TODO: Might be a good time to log something. + private void onCurrentAnimationEnd(boolean wasSuccess, int logAction) { if (mTaskBeingDragged == null) { LauncherState state = wasSuccess ? (mCurrentAnimationIsGoingUp ? ALL_APPS : NORMAL) : OVERVIEW; mLauncher.getStateManager().goToState(state, false); + } else if (wasSuccess) { if (mCurrentAnimationIsGoingUp) { mRecentsView.onTaskDismissed(mTaskBeingDragged); } else { mTaskBeingDragged.launchTask(false); + mLauncher.getUserEventDispatcher().logTaskLaunch(logAction, + Direction.DOWN, mTaskBeingDragged.getTask().getTopComponent()); } } + if (mTaskBeingDragged == null || (wasSuccess && mCurrentAnimationIsGoingUp)) { + mLauncher.getUserEventDispatcher().logStateChangeAction(logAction, + mCurrentAnimationIsGoingUp ? Direction.UP : Direction.DOWN, + mStartingTarget, ContainerType.TASKSWITCHER, + mLauncher.getStateManager().getState().containerType, + mRecentsView.getCurrentPage()); + } mDetector.finishedScrolling(); mTaskBeingDragged = null; mCurrentAnimation = null; diff --git a/quickstep/src/com/android/launcher3/uioverrides/OverviewSwipeUpController.java b/quickstep/src/com/android/launcher3/uioverrides/OverviewSwipeUpController.java index 3ae8f410df..4fb388613e 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/OverviewSwipeUpController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/OverviewSwipeUpController.java @@ -58,10 +58,12 @@ public class OverviewSwipeUpController extends VerticalSwipeController { protected void onTransitionComplete(boolean wasFling, boolean stateChanged) { if (stateChanged) { // Transition complete. log the action - mLauncher.getUserEventDispatcher().logActionOnContainer( + mLauncher.getUserEventDispatcher().logStateChangeAction( wasFling ? Touch.FLING : Touch.SWIPE, Direction.UP, - ContainerType.OVERVIEW, + ContainerType.HOTSEAT, + ContainerType.TASKSWITCHER, + ContainerType.ALLAPPS, mLauncher.getWorkspace().getCurrentPage()); } diff --git a/quickstep/src/com/android/launcher3/uioverrides/TwoStepSwipeController.java b/quickstep/src/com/android/launcher3/uioverrides/TwoStepSwipeController.java index fb59946abd..2695054c23 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/TwoStepSwipeController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/TwoStepSwipeController.java @@ -50,10 +50,7 @@ import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch; import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; import com.android.launcher3.util.FloatRange; import com.android.launcher3.util.TouchController; -import com.android.quickstep.RecentsModel; -import com.android.quickstep.RecentsView; import com.android.quickstep.TouchInteractionService; -import com.android.systemui.shared.recents.model.RecentsTaskLoadPlan; import java.util.ArrayList; @@ -371,9 +368,12 @@ public class TwoStepSwipeController extends AnimatorListenerAdapter private void onSwipeInteractionCompleted(LauncherState targetState, int logAction) { if (targetState != mFromState) { // Transition complete. log the action - mLauncher.getUserEventDispatcher().logActionOnContainer(logAction, + mLauncher.getUserEventDispatcher().logStateChangeAction(logAction, mToState == ALL_APPS ? Direction.UP : Direction.DOWN, - mStartContainerType, mLauncher.getWorkspace().getCurrentPage()); + mStartContainerType, + mFromState.containerType, + mToState.containerType, + mLauncher.getWorkspace().getCurrentPage()); } clearState(); diff --git a/quickstep/src/com/android/quickstep/QuickScrubController.java b/quickstep/src/com/android/quickstep/QuickScrubController.java index bda9688485..f28d51c8ea 100644 --- a/quickstep/src/com/android/quickstep/QuickScrubController.java +++ b/quickstep/src/com/android/quickstep/QuickScrubController.java @@ -19,8 +19,13 @@ package com.android.quickstep; import android.view.HapticFeedbackConstants; import com.android.launcher3.Alarm; +import com.android.launcher3.Launcher; import com.android.launcher3.OnAlarmListener; import com.android.launcher3.Utilities; +import com.android.launcher3.userevent.nano.LauncherLogProto; +import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch; +import com.android.launcher3.userevent.nano.LauncherLogProto.ControlType; +import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; /** * Responds to quick scrub callbacks to page through and launch recent tasks. @@ -42,13 +47,15 @@ public class QuickScrubController implements OnAlarmListener { private final Alarm mAutoAdvanceAlarm; private final RecentsView mRecentsView; + private final Launcher mLauncher; private boolean mInQuickScrub; private int mQuickScrubSection; private int mStartPage; private boolean mHasAlarmRun; - public QuickScrubController(RecentsView recentsView) { + public QuickScrubController(Launcher launcher, RecentsView recentsView) { + mLauncher = launcher; mRecentsView = recentsView; if (ENABLE_AUTO_ADVANCE) { mAutoAdvanceAlarm = new Alarm(); @@ -61,6 +68,7 @@ public class QuickScrubController implements OnAlarmListener { mStartPage = startingFromHome ? 0 : mRecentsView.getFirstTaskIndex(); mQuickScrubSection = 0; mHasAlarmRun = false; + mLauncher.getUserEventDispatcher().resetActionDurationMillis(); } public void onQuickScrubEnd() { @@ -85,6 +93,9 @@ public class QuickScrubController implements OnAlarmListener { // No page move needed, just launch it launchTaskRunnable.run(); } + mLauncher.getUserEventDispatcher().logActionOnControl(Touch.DRAGDROP, + ControlType.QUICK_SCRUB_BUTTON, null, mStartPage == 0 ? + ContainerType.WORKSPACE : ContainerType.APP); } public void onQuickScrubProgress(float progress) { @@ -119,6 +130,9 @@ public class QuickScrubController implements OnAlarmListener { break; } } + mLauncher.getUserEventDispatcher().logActionOnControl(Touch.FLING, + ControlType.QUICK_SCRUB_BUTTON, null, mStartPage == 0 ? + ContainerType.WORKSPACE : ContainerType.APP); } public void snapToPageForCurrentQuickScrubSection() { diff --git a/quickstep/src/com/android/quickstep/RecentsView.java b/quickstep/src/com/android/quickstep/RecentsView.java index cb510c8f9f..8ff0a86ed0 100644 --- a/quickstep/src/com/android/quickstep/RecentsView.java +++ b/quickstep/src/com/android/quickstep/RecentsView.java @@ -124,7 +124,7 @@ public class RecentsView extends PagedView implements Insettable { setClipToOutline(true); mLauncher = Launcher.getLauncher(context); - mQuickScrubController = new QuickScrubController(this); + mQuickScrubController = new QuickScrubController(mLauncher, this); mModel = RecentsModel.getInstance(context); mScrollState.isRtl = mIsRtl; diff --git a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java index ddddbf67e0..0e8dea60ea 100644 --- a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java +++ b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java @@ -59,6 +59,10 @@ import com.android.launcher3.allapps.AllAppsTransitionController; import com.android.launcher3.anim.AnimationSuccessListener; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.Interpolators; + +import com.android.launcher3.userevent.nano.LauncherLogProto; +import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch; +import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction; import com.android.launcher3.util.TraceHelper; import com.android.quickstep.TouchConsumer.InteractionType; import com.android.systemui.shared.recents.model.ThumbnailData; @@ -603,6 +607,30 @@ public class WindowTransformSwipeHandler extends BaseSwipeInteractionHandler { } animateToProgress(endShift, duration); + int direction = Direction.UP; + if (mLauncher.getDeviceProfile().isLandscape) { + direction = Direction.LEFT; + if (mLauncher.getDeviceProfile().isSeascape()) { + direction = Direction.RIGHT; + } + } + int dstContainerType = LauncherLogProto.ContainerType.TASKSWITCHER; + if (Float.compare(endShift, 0) == 0) { + direction = Direction.DOWN; + if (mLauncher.getDeviceProfile().isLandscape) { + direction = Direction.RIGHT; + if (mLauncher.getDeviceProfile().isSeascape()) { + direction = Direction.LEFT; + } + } + dstContainerType = LauncherLogProto.ContainerType.APP; + } + mLauncher.getUserEventDispatcher().logStateChangeAction( + isFling ? Touch.FLING : Touch.SWIPE, direction, + LauncherLogProto.ContainerType.NAVBAR, + LauncherLogProto.ContainerType.APP, + dstContainerType, + 0); } /** Animates to the given progress, where 0 is the current app and 1 is overview. */ diff --git a/src/com/android/launcher3/AbstractFloatingView.java b/src/com/android/launcher3/AbstractFloatingView.java index 12f022faf7..fc5ce8f2b7 100644 --- a/src/com/android/launcher3/AbstractFloatingView.java +++ b/src/com/android/launcher3/AbstractFloatingView.java @@ -92,7 +92,8 @@ public abstract class AbstractFloatingView extends LinearLayout implements Touch public final void close(boolean animate) { animate &= !Utilities.isPowerSaverOn(getContext()); handleClose(animate); - Launcher.getLauncher(getContext()).getUserEventDispatcher().resetElapsedContainerMillis(); + Launcher.getLauncher(getContext()).getUserEventDispatcher() + .resetElapsedContainerMillis("container closed"); } protected abstract void handleClose(boolean animate); diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index b4093b7d1d..f76d4eb470 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -783,7 +783,7 @@ public class Launcher extends BaseActivity if (!mAppLaunchSuccess) { getUserEventDispatcher().logActionCommand(Action.Command.STOP, - mStateManager.getState().containerType); + mStateManager.getState().containerType, -1); } NotificationListener.removeNotificationsChangedListener(); getStateManager().moveToRestState(); @@ -1280,7 +1280,8 @@ public class Launcher extends BaseActivity } else if (alreadyOnHome) { Target target = newContainerTarget(mStateManager.getState().containerType); target.pageIndex = mWorkspace.getCurrentPage(); - ued.logActionCommand(Action.Command.HOME_INTENT, target); + ued.logActionCommand(Action.Command.HOME_INTENT, target, + newContainerTarget(ContainerType.WORKSPACE)); } // In all these cases, only animate if we're already on home @@ -1656,7 +1657,8 @@ public class Launcher extends BaseActivity topView.onBackPressed(); } else if (!isInState(NORMAL)) { LauncherState lastState = mStateManager.getLastState(); - ued.logActionCommand(Action.Command.BACK, mStateManager.getState().containerType); + ued.logActionCommand(Action.Command.BACK, mStateManager.getState().containerType, + lastState.containerType); mStateManager.goToState(lastState); } else { // Back button is a no-op here, but give at least some feedback for the button press @@ -1682,7 +1684,7 @@ public class Launcher extends BaseActivity if (v instanceof Workspace) { if (isInState(OVERVIEW)) { - getUserEventDispatcher().logActionOnContainer(LauncherLogProto.Action.Type.TOUCH, + getUserEventDispatcher().logActionOnContainer(LauncherLogProto.Action.Touch.TAP, LauncherLogProto.Action.Direction.NONE, LauncherLogProto.ContainerType.OVERVIEW, mWorkspace.getCurrentPage()); mStateManager.goToState(NORMAL); @@ -1693,7 +1695,7 @@ public class Launcher extends BaseActivity if (v instanceof CellLayout) { if (isInState(OVERVIEW)) { int page = mWorkspace.indexOfChild(v); - getUserEventDispatcher().logActionOnContainer(LauncherLogProto.Action.Type.TOUCH, + getUserEventDispatcher().logActionOnContainer(LauncherLogProto.Action.Touch.TAP, LauncherLogProto.Action.Direction.NONE, LauncherLogProto.ContainerType.OVERVIEW, page); mWorkspace.snapToPageFromOverView(page); diff --git a/src/com/android/launcher3/LauncherStateManager.java b/src/com/android/launcher3/LauncherStateManager.java index 170fcd7075..2f8687d7e1 100644 --- a/src/com/android/launcher3/LauncherStateManager.java +++ b/src/com/android/launcher3/LauncherStateManager.java @@ -302,7 +302,6 @@ public class LauncherStateManager { state.onStateTransitionEnd(mLauncher); mLauncher.getWorkspace().setClipChildren(!state.disablePageClipping); - mLauncher.getUserEventDispatcher().resetElapsedContainerMillis(); mLauncher.finishAutoCancelActionMode(); if (state == NORMAL) { diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index 11523a516f..141494614b 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -1679,7 +1679,7 @@ public class Workspace extends PagedView if (popupContainer != null) { dragOptions.preDragCondition = popupContainer.createPreDragCondition(); - mLauncher.getUserEventDispatcher().resetElapsedContainerMillis(); + mLauncher.getUserEventDispatcher().resetElapsedContainerMillis("dragging started"); } } diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java index 8abafb0ea9..993663ed41 100644 --- a/src/com/android/launcher3/folder/Folder.java +++ b/src/com/android/launcher3/folder/Folder.java @@ -522,7 +522,7 @@ public class Folder extends AbstractFloatingView implements DragSource, View.OnC onCompleteRunnable = new Runnable() { @Override public void run() { - mLauncher.getUserEventDispatcher().resetElapsedContainerMillis(); + mLauncher.getUserEventDispatcher().resetElapsedContainerMillis("folder opened"); } }; anim.addListener(new AnimatorListenerAdapter() { diff --git a/src/com/android/launcher3/logging/LoggerUtils.java b/src/com/android/launcher3/logging/LoggerUtils.java index 00ee0096ad..c608a233ff 100644 --- a/src/com/android/launcher3/logging/LoggerUtils.java +++ b/src/com/android/launcher3/logging/LoggerUtils.java @@ -71,7 +71,7 @@ public class LoggerUtils { switch (action.type) { case Action.Type.TOUCH: str += getFieldName(action.touch, Action.Touch.class); - if (action.touch == Action.Touch.SWIPE) { + if (action.touch == Action.Touch.SWIPE || action.touch == Action.Touch.FLING) { str += " direction=" + getFieldName(action.dir, Action.Direction.class); } return str; @@ -114,11 +114,20 @@ public class LoggerUtils { if (t.intentHash != 0) { typeStr += ", intentHash=" + t.intentHash; } - if (t.packageNameHash != 0 || t.componentHash != 0 || t.intentHash != 0) { - typeStr += ", predictiveRank=" + t.predictedRank; + if ((t.packageNameHash != 0 || t.componentHash != 0 || t.intentHash != 0) && + t.itemType != ItemType.TASK) { + typeStr += ", predictiveRank=" + t.predictedRank + ", grid(" + t.gridX + "," + t.gridY + + "), span(" + t.spanX + "," + t.spanY + + "), pageIdx=" + t.pageIndex; + } - return typeStr + ", grid(" + t.gridX + "," + t.gridY + "), span(" + t.spanX + "," + t.spanY - + "), pageIdx=" + t.pageIndex; + return typeStr; + } + + public static Target newItemTarget(int itemType) { + Target t = newTarget(Target.Type.ITEM); + t.itemType = itemType; + return t; } public static Target newItemTarget(View v) { diff --git a/src/com/android/launcher3/logging/UserEventDispatcher.java b/src/com/android/launcher3/logging/UserEventDispatcher.java index 243dbeae67..b7de400609 100644 --- a/src/com/android/launcher3/logging/UserEventDispatcher.java +++ b/src/com/android/launcher3/logging/UserEventDispatcher.java @@ -32,6 +32,7 @@ import com.android.launcher3.ItemInfo; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.config.FeatureFlags; +import com.android.launcher3.userevent.nano.LauncherLogProto; import com.android.launcher3.userevent.nano.LauncherLogProto.Action; import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; import com.android.launcher3.userevent.nano.LauncherLogProto.LauncherEvent; @@ -158,9 +159,23 @@ public class UserEventDispatcher { dispatchUserEvent(event, intent); } + public void logTaskLaunch(int action, int direction, ComponentName componentName){ + LauncherEvent event = newLauncherEvent(newTouchAction(action), // TAP or SWIPE + newTarget(Target.Type.ITEM)); + if (action == Action.Touch.SWIPE || action == Action.Touch.FLING) { + event.action.dir = direction; + } + event.srcTarget[0].itemType = LauncherLogProto.ItemType.TASK; + fillComponentInfo(event.srcTarget[0], componentName); + dispatchUserEvent(event, null); + } + protected void fillIntentInfo(Target target, Intent intent) { target.intentHash = intent.hashCode(); - ComponentName cn = intent.getComponent(); + fillComponentInfo(target, intent.getComponent()); + } + + private void fillComponentInfo(Target target, ComponentName cn) { if (cn != null) { target.packageNameHash = (mUuidStr + cn.getPackageName()).hashCode(); target.componentHash = (mUuidStr + cn.flattenToString()).hashCode(); @@ -176,19 +191,29 @@ public class UserEventDispatcher { dispatchUserEvent(event, null); } - public void logActionCommand(int command, int containerType) { - logActionCommand(command, newContainerTarget(containerType)); + public void logActionCommand(int command, Target srcTarget) { + logActionCommand(command, srcTarget, null); } - public void logActionCommand(int command, Target target) { - LauncherEvent event = newLauncherEvent(newCommandAction(command), target); + public void logActionCommand(int command, int srcContainerType, int dstContainerType) { + logActionCommand(command, newContainerTarget(srcContainerType), + dstContainerType >=0 ? newContainerTarget(dstContainerType) : null); + } + + public void logActionCommand(int command, Target srcTarget, Target dstTarget) { + LauncherEvent event = newLauncherEvent(newCommandAction(command), srcTarget); + if (dstTarget != null) { + event.destTarget = new Target[1]; + event.destTarget[0] = dstTarget; + event.action.isStateChange = true; + } dispatchUserEvent(event, null); } /** * TODO: Make this function work when a container view is passed as the 2nd param. */ - public void logActionCommand(int command, View itemView, int containerType) { + public void logActionCommand(int command, View itemView, int srcContainerType) { LauncherEvent event = newLauncherEvent(newCommandAction(command), newItemTarget(itemView), newTarget(Target.Type.CONTAINER)); @@ -196,22 +221,39 @@ public class UserEventDispatcher { // TODO: Remove the following two lines once fillInLogContainerData can take in a // container view. event.srcTarget[0].type = Target.Type.CONTAINER; - event.srcTarget[0].containerType = containerType; + event.srcTarget[0].containerType = srcContainerType; } dispatchUserEvent(event, null); } public void logActionOnControl(int action, int controlType) { - logActionOnControl(action, controlType, null); + logActionOnControl(action, controlType, null, -1); + } + + public void logActionOnControl(int action, int controlType, int parentContainerType) { + logActionOnControl(action, controlType, null, parentContainerType); } public void logActionOnControl(int action, int controlType, @Nullable View controlInContainer) { + logActionOnControl(action, controlType, controlInContainer, -1); + } + + public void logActionOnControl(int action, int controlType, @Nullable View controlInContainer, + int parentContainerType) { final LauncherEvent event = controlInContainer == null ? newLauncherEvent(newTouchAction(action), newTarget(Target.Type.CONTROL)) : newLauncherEvent(newTouchAction(action), newTarget(Target.Type.CONTROL), newTarget(Target.Type.CONTAINER)); event.srcTarget[0].controlType = controlType; - fillInLogContainerData(event, controlInContainer); + if (controlInContainer != null) { + fillInLogContainerData(event, controlInContainer); + } + if (parentContainerType >= 0) { + event.srcTarget[1].containerType = parentContainerType; + } + if (action == Action.Touch.DRAGDROP) { + event.actionDurationMillis = SystemClock.uptimeMillis() - mActionDurationMillis; + } dispatchUserEvent(event, null); } @@ -232,10 +274,35 @@ public class UserEventDispatcher { event.action.dir = dir; event.srcTarget[0].pageIndex = pageIndex; dispatchUserEvent(event, null); + } - if (action == Action.Touch.SWIPE) { - resetElapsedContainerMillis(); + /** + * Used primarily for swipe up and down when state changes when swipe up happens from the + * navbar bezel, the {@param srcChildContainerType} is NAVBAR and + * {@param srcParentContainerType} is either one of the two + * (1) WORKSPACE: if the launcher the foreground activity + * (2) APP: if another app was the foreground activity + */ + public void logStateChangeAction(int action, int dir, int srcChildTargetType, + int srcParentContainerType, int dstContainerType, + int pageIndex) { + LauncherEvent event; + if (srcChildTargetType == LauncherLogProto.ItemType.TASK) { + event = newLauncherEvent(newTouchAction(action), + newItemTarget(srcChildTargetType), + newContainerTarget(srcParentContainerType)); + } else { + event = newLauncherEvent(newTouchAction(action), + newContainerTarget(srcChildTargetType), + newContainerTarget(srcParentContainerType)); } + event.destTarget = new Target[1]; + event.destTarget[0] = newContainerTarget(dstContainerType); + event.action.dir = dir; + event.action.isStateChange = true; + event.srcTarget[0].pageIndex = pageIndex; + dispatchUserEvent(event, null); + resetElapsedContainerMillis("state changed"); } public void logActionOnItem(int action, int dir, int itemType) { @@ -257,7 +324,7 @@ public class UserEventDispatcher { provider.fillInLogContainerData(icon, info, event.srcTarget[0], event.srcTarget[1]); dispatchUserEvent(event, null); - resetElapsedContainerMillis(); + resetElapsedContainerMillis("deep shortcut open"); } /* Currently we are only interested in whether this event happens or not and don't @@ -290,9 +357,15 @@ public class UserEventDispatcher { /** * Currently logs following containers: workspace, allapps, widget tray. + * @param reason */ - public final void resetElapsedContainerMillis() { + public final void resetElapsedContainerMillis(String reason) { mElapsedContainerMillis = SystemClock.uptimeMillis(); + if (!IS_VERBOSE) { + return; + } + Log.d(TAG, "resetElapsedContainerMillis reason=" + reason); + } public final void resetElapsedSessionMillis() { @@ -321,13 +394,13 @@ public class UserEventDispatcher { log += "\n Destination " + getTargetsStr(ev.destTarget); } log += String.format(Locale.US, - "\n Elapsed container %d ms session %d ms action %d ms", + "\n Elapsed container %d ms, session %d ms, action %d ms", ev.elapsedContainerMillis, ev.elapsedSessionMillis, ev.actionDurationMillis); log += "\n isInLandscapeMode " + ev.isInLandscapeMode; log += "\n isInMultiWindowMode " + ev.isInMultiWindowMode; - log += "\n"; + log += "\n\n"; Log.d(TAG, log); }