Log Launcher transitions to WW
- ONRESUME / ONSTOP
- HOME_GESTURE
- OVERVIEW_GESTURE
- QUICKSWITCH
- SWIPELEFT/SWIPERIGHT
Bug: 156875719
Bug: 148822714
Bug: 137777105
Debug log: go/launcher-log-parity
Change-Id: I64a0deab4996b5be36320fbe0339f320891c53e0
diff --git a/src/com/android/launcher3/BaseActivity.java b/src/com/android/launcher3/BaseActivity.java
index 7d80d81..310c306 100644
--- a/src/com/android/launcher3/BaseActivity.java
+++ b/src/com/android/launcher3/BaseActivity.java
@@ -37,8 +37,6 @@
import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
import com.android.launcher3.logging.StatsLogManager;
-import com.android.launcher3.logging.StatsLogUtils;
-import com.android.launcher3.logging.StatsLogUtils.LogStateProvider;
import com.android.launcher3.logging.UserEventDispatcher;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.util.SystemUiController;
@@ -52,7 +50,7 @@
/**
* Launcher BaseActivity
*/
-public abstract class BaseActivity extends Activity implements LogStateProvider, ActivityContext {
+public abstract class BaseActivity extends Activity implements ActivityContext {
private static final String TAG = "BaseActivity";
@@ -146,13 +144,11 @@
return mDeviceProfile;
}
- public int getCurrentState() { return StatsLogUtils.LAUNCHER_STATE_BACKGROUND; }
-
public void modifyUserEvent(LauncherLogProto.LauncherEvent event) {}
public final StatsLogManager getStatsLogManager() {
if (mStatsLogManager == null) {
- mStatsLogManager = StatsLogManager.newInstance(this, this);
+ mStatsLogManager = StatsLogManager.newInstance(this);
}
return mStatsLogManager;
}
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 7fc64ea..0970dae 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -38,6 +38,10 @@
import static com.android.launcher3.Utilities.postAsyncCallback;
import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_LAUNCHER_LOAD;
import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
+import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_BACKGROUND;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ONRESUME;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ONSTOP;
+import static com.android.launcher3.logging.StatsLogManager.containerTypeToAtomState;
import static com.android.launcher3.popup.SystemShortcut.APP_INFO;
import static com.android.launcher3.popup.SystemShortcut.INSTALL;
import static com.android.launcher3.popup.SystemShortcut.WIDGETS;
@@ -110,8 +114,9 @@
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.keyboard.CustomActionsPopup;
import com.android.launcher3.keyboard.ViewGroupFocusHelper;
+import com.android.launcher3.logger.LauncherAtom;
import com.android.launcher3.logging.FileLog;
-import com.android.launcher3.logging.StatsLogUtils;
+import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.logging.UserEventDispatcher;
import com.android.launcher3.model.AppLaunchTracker;
import com.android.launcher3.model.BgDataModel.Callbacks;
@@ -920,13 +925,32 @@
private void logStopAndResume(int command) {
+ int pageIndex = mWorkspace.isOverlayShown() ? -1 : mWorkspace.getCurrentPage();
int containerType = mStateManager.getState().containerType;
+
+ StatsLogManager.EventEnum event;
+ StatsLogManager.StatsLogger logger = getStatsLogManager().logger();
+ if (command == Action.Command.RESUME) {
+ logger.withSrcState(LAUNCHER_STATE_BACKGROUND)
+ .withDstState(containerTypeToAtomState(mStateManager.getState().containerType));
+ event = LAUNCHER_ONRESUME;
+ } else { /* command == Action.Command.STOP */
+ logger.withSrcState(containerTypeToAtomState(mStateManager.getState().containerType))
+ .withDstState(LAUNCHER_STATE_BACKGROUND);
+ event = LAUNCHER_ONSTOP;
+ }
+
if (containerType == ContainerType.WORKSPACE && mWorkspace != null) {
getUserEventDispatcher().logActionCommand(command,
- containerType, -1, mWorkspace.isOverlayShown() ? -1 : 0);
+ containerType, -1, pageIndex);
+ logger.withContainerInfo(LauncherAtom.ContainerInfo.newBuilder()
+ .setWorkspace(
+ LauncherAtom.WorkspaceContainer.newBuilder()
+ .setPageIndex(pageIndex)).build());
} else {
getUserEventDispatcher().logActionCommand(command, containerType, -1);
}
+ logger.log(event);
}
private void scheduleDeferredCheck() {
@@ -1836,16 +1860,6 @@
}
@Override
- public int getCurrentState() {
- if (mStateManager.getState() == LauncherState.ALL_APPS) {
- return StatsLogUtils.LAUNCHER_STATE_ALLAPPS;
- } else if (mStateManager.getState() == OVERVIEW) {
- return StatsLogUtils.LAUNCHER_STATE_OVERVIEW;
- }
- return StatsLogUtils.LAUNCHER_STATE_HOME;
- }
-
- @Override
public boolean startActivitySafely(View v, Intent intent, ItemInfo item,
@Nullable String sourceContainer) {
if (!hasBeenResumed()) {
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index a8dca12..1441e0b 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -28,6 +28,9 @@
import static com.android.launcher3.config.FeatureFlags.ADAPTIVE_ICON_WINDOW_ANIM;
import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_OVERLAY;
import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
+import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_HOME;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SWIPELEFT;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SWIPERIGHT;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -79,6 +82,7 @@
import com.android.launcher3.graphics.DragPreviewProvider;
import com.android.launcher3.graphics.PreloadIconDrawable;
import com.android.launcher3.icons.BitmapRenderer;
+import com.android.launcher3.logger.LauncherAtom;
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.logging.StatsLogManager.LauncherEvent;
import com.android.launcher3.logging.UserEventDispatcher;
@@ -999,6 +1003,15 @@
if (!mOverlayShown) {
mLauncher.getUserEventDispatcher().logActionOnContainer(Action.Touch.SWIPE,
Action.Direction.LEFT, ContainerType.WORKSPACE, 0);
+ mLauncher.getStatsLogManager().logger()
+ .withSrcState(LAUNCHER_STATE_HOME)
+ .withDstState(LAUNCHER_STATE_HOME)
+ .withContainerInfo(LauncherAtom.ContainerInfo.newBuilder()
+ .setWorkspace(
+ LauncherAtom.WorkspaceContainer.newBuilder()
+ .setPageIndex(0))
+ .build())
+ .log(LAUNCHER_SWIPELEFT);
}
mOverlayShown = true;
// Not announcing the overlay page for accessibility since it announces itself.
@@ -1008,6 +1021,15 @@
if (!ued.isPreviousHomeGesture()) {
mLauncher.getUserEventDispatcher().logActionOnContainer(Action.Touch.SWIPE,
Action.Direction.RIGHT, ContainerType.WORKSPACE, -1);
+ mLauncher.getStatsLogManager().logger()
+ .withSrcState(LAUNCHER_STATE_HOME)
+ .withDstState(LAUNCHER_STATE_HOME)
+ .withContainerInfo(LauncherAtom.ContainerInfo.newBuilder()
+ .setWorkspace(
+ LauncherAtom.WorkspaceContainer.newBuilder()
+ .setPageIndex(-1))
+ .build())
+ .log(LAUNCHER_SWIPERIGHT);
}
} else if (Float.compare(mOverlayTranslation, 0f) != 0) {
// When arriving to 0 overscroll from non-zero overscroll, announce page for
@@ -1099,9 +1121,20 @@
protected void notifyPageSwitchListener(int prevPage) {
super.notifyPageSwitchListener(prevPage);
if (prevPage != mCurrentPage) {
- int swipeDirection = (prevPage < mCurrentPage) ? Action.Direction.RIGHT : Action.Direction.LEFT;
+ int swipeDirection = (prevPage < mCurrentPage)
+ ? Action.Direction.RIGHT : Action.Direction.LEFT;
+ StatsLogManager.EventEnum event = (prevPage < mCurrentPage)
+ ? LAUNCHER_SWIPERIGHT : LAUNCHER_SWIPELEFT;
mLauncher.getUserEventDispatcher().logActionOnContainer(Action.Touch.SWIPE,
swipeDirection, ContainerType.WORKSPACE, prevPage);
+ mLauncher.getStatsLogManager().logger()
+ .withSrcState(LAUNCHER_STATE_HOME)
+ .withDstState(LAUNCHER_STATE_HOME)
+ .withContainerInfo(LauncherAtom.ContainerInfo.newBuilder()
+ .setWorkspace(
+ LauncherAtom.WorkspaceContainer.newBuilder()
+ .setPageIndex(prevPage)).build())
+ .log(event);
}
}
diff --git a/src/com/android/launcher3/logging/StatsLogManager.java b/src/com/android/launcher3/logging/StatsLogManager.java
index 3edfa8d..8e23b65 100644
--- a/src/com/android/launcher3/logging/StatsLogManager.java
+++ b/src/com/android/launcher3/logging/StatsLogManager.java
@@ -15,6 +15,12 @@
*/
package com.android.launcher3.logging;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.IGNORE;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_CLOSE_DOWN;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_OPEN_UP;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOME_GESTURE;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_OVERVIEW_GESTURE;
+
import android.content.Context;
import androidx.annotation.Nullable;
@@ -23,8 +29,8 @@
import com.android.launcher3.logger.LauncherAtom.ContainerInfo;
import com.android.launcher3.logger.LauncherAtom.FromState;
import com.android.launcher3.logger.LauncherAtom.ToState;
-import com.android.launcher3.logging.StatsLogUtils.LogStateProvider;
import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.userevent.LauncherLogProto;
import com.android.launcher3.util.ResourceBasedOverride;
/**
@@ -35,6 +41,54 @@
*/
public class StatsLogManager implements ResourceBasedOverride {
+ public static final int LAUNCHER_STATE_UNSPECIFIED = 0;
+ public static final int LAUNCHER_STATE_BACKGROUND = 1;
+ public static final int LAUNCHER_STATE_HOME = 2;
+ public static final int LAUNCHER_STATE_OVERVIEW = 3;
+ public static final int LAUNCHER_STATE_ALLAPPS = 4;
+ public static final int LAUNCHER_STATE_UNCHANGED = 5;
+
+ /**
+ * Returns proper launcher state enum for {@link StatsLogManager}
+ * (to be removed during UserEventDispatcher cleanup)
+ */
+ public static int containerTypeToAtomState(int containerType) {
+ switch (containerType) {
+ case LauncherLogProto.ContainerType.ALLAPPS_VALUE:
+ return LAUNCHER_STATE_ALLAPPS;
+ case LauncherLogProto.ContainerType.OVERVIEW_VALUE:
+ return LAUNCHER_STATE_OVERVIEW;
+ case LauncherLogProto.ContainerType.WORKSPACE_VALUE:
+ return LAUNCHER_STATE_HOME;
+ case LauncherLogProto.ContainerType.APP_VALUE:
+ return LAUNCHER_STATE_BACKGROUND;
+ }
+ return LAUNCHER_STATE_UNSPECIFIED;
+ }
+
+ /**
+ * Returns event enum based on the two {@link ContainerType} transition information when
+ * swipe gesture happens.
+ * (to be removed during UserEventDispatcher cleanup)
+ */
+ public static EventEnum getLauncherAtomEvent(int startContainerType,
+ int targetContainerType, EventEnum fallbackEvent) {
+ if (startContainerType == LauncherLogProto.ContainerType.WORKSPACE.getNumber()
+ && targetContainerType == LauncherLogProto.ContainerType.WORKSPACE.getNumber()) {
+ return LAUNCHER_HOME_GESTURE;
+ } else if (startContainerType != LauncherLogProto.ContainerType.TASKSWITCHER.getNumber()
+ && targetContainerType == LauncherLogProto.ContainerType.TASKSWITCHER.getNumber()) {
+ return LAUNCHER_OVERVIEW_GESTURE;
+ } else if (startContainerType != LauncherLogProto.ContainerType.ALLAPPS.getNumber()
+ && targetContainerType == LauncherLogProto.ContainerType.ALLAPPS.getNumber()) {
+ return LAUNCHER_ALLAPPS_OPEN_UP;
+ } else if (startContainerType == LauncherLogProto.ContainerType.ALLAPPS.getNumber()
+ && targetContainerType != LauncherLogProto.ContainerType.ALLAPPS.getNumber()) {
+ return LAUNCHER_ALLAPPS_CLOSE_DOWN;
+ }
+ return fallbackEvent; // TODO fix
+ }
+
public interface EventEnum {
int getId();
}
@@ -164,6 +218,44 @@
@UiEvent(doc = "App launch ranking logged for hotseat predictions)")
LAUNCHER_HOTSEAT_RANKED(553),
+ @UiEvent(doc = "Launcher is now in background. e.g., Screen off event")
+ LAUNCHER_ONSTOP(562),
+
+ @UiEvent(doc = "Launcher is now in foreground. e.g., Screen on event, back button")
+ LAUNCHER_ONRESUME(563),
+
+ @UiEvent(doc = "User swipes or fling in LEFT direction on workspace.")
+ LAUNCHER_SWIPELEFT(564),
+
+ @UiEvent(doc = "User swipes or fling in RIGHT direction on workspace.")
+ LAUNCHER_SWIPERIGHT(565),
+
+ @UiEvent(doc = "User swipes or fling in UP direction in unknown way.")
+ LAUNCHER_UNKNOWN_SWIPEUP(566),
+
+ @UiEvent(doc = "User swipes or fling in DOWN direction in unknown way.")
+ LAUNCHER_UNKNOWN_SWIPEDOWN(567),
+
+ @UiEvent(doc = "User swipes or fling in UP direction to open apps drawer.")
+ LAUNCHER_ALLAPPS_OPEN_UP(568),
+
+ @UiEvent(doc = "User swipes or fling in DOWN direction to close apps drawer.")
+ LAUNCHER_ALLAPPS_CLOSE_DOWN(569),
+
+ @UiEvent(doc = "User swipes or fling in UP direction and hold from the bottom bazel area")
+ LAUNCHER_OVERVIEW_GESTURE(570),
+
+ @UiEvent(doc = "User swipes or fling in LEFT direction on the bottom bazel area.")
+ LAUNCHER_QUICKSWITCH_LEFT(571),
+
+ @UiEvent(doc = "User swipes or fling in RIGHT direction on the bottom bazel area.")
+ LAUNCHER_QUICKSWITCH_RIGHT(572),
+
+ @UiEvent(doc = "User swipes or fling in DOWN direction on the bottom bazel area.")
+ LAUNCHER_SWIPEDOWN_NAVBAR(573),
+
+ @UiEvent(doc = "User swipes or fling in UP direction from bottom bazel area.")
+ LAUNCHER_HOME_GESTURE(574),
@UiEvent(doc = "User's workspace layout information is snapshot in the background.")
LAUNCHER_WORKSPACE_SNAPSHOT(579),
@@ -184,6 +276,7 @@
LAUNCHER_SELECT_MODE_ITEM(584);
// ADD MORE
+
private final int mId;
LauncherEvent(int id) {
@@ -301,19 +394,12 @@
};
}
- protected LogStateProvider mStateProvider;
-
/**
* Creates a new instance of {@link StatsLogManager} based on provided context.
*/
public static StatsLogManager newInstance(Context context) {
- return newInstance(context, null);
- }
-
- public static StatsLogManager newInstance(Context context, LogStateProvider stateProvider) {
StatsLogManager mgr = Overrides.getObject(StatsLogManager.class,
context.getApplicationContext(), R.string.stats_log_manager_class);
- mgr.mStateProvider = stateProvider;
return mgr;
}
diff --git a/src/com/android/launcher3/logging/StatsLogUtils.java b/src/com/android/launcher3/logging/StatsLogUtils.java
index 10d88e5..a5cc7ea 100644
--- a/src/com/android/launcher3/logging/StatsLogUtils.java
+++ b/src/com/android/launcher3/logging/StatsLogUtils.java
@@ -6,28 +6,13 @@
import androidx.annotation.Nullable;
import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
import java.util.ArrayList;
-import static com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType.DEFAULT_CONTAINERTYPE;
-
public class StatsLogUtils {
-
- // Defined in android.stats.launcher.nano
- // As they cannot be linked in this file, defining again.
- public final static int LAUNCHER_STATE_BACKGROUND = 0;
- public final static int LAUNCHER_STATE_HOME = 1;
- public final static int LAUNCHER_STATE_OVERVIEW = 2;
- public final static int LAUNCHER_STATE_ALLAPPS = 3;
-
private final static int MAXIMUM_VIEW_HIERARCHY_LEVEL = 5;
- public interface LogStateProvider {
- int getCurrentState();
- }
-
/**
* Implemented by containers to provide a container source for a given child.
*/
@@ -61,20 +46,4 @@
}
return null;
}
-
- public static int getContainerTypeFromState(int state) {
- int containerType = DEFAULT_CONTAINERTYPE;
- switch (state) {
- case StatsLogUtils.LAUNCHER_STATE_ALLAPPS:
- containerType = ContainerType.ALLAPPS;
- break;
- case StatsLogUtils.LAUNCHER_STATE_HOME:
- containerType = ContainerType.WORKSPACE;
- break;
- case StatsLogUtils.LAUNCHER_STATE_OVERVIEW:
- containerType = ContainerType.OVERVIEW;
- break;
- }
- return containerType;
- }
}
diff --git a/src/com/android/launcher3/states/SpringLoadedState.java b/src/com/android/launcher3/states/SpringLoadedState.java
index f0e0557..2a4f887 100644
--- a/src/com/android/launcher3/states/SpringLoadedState.java
+++ b/src/com/android/launcher3/states/SpringLoadedState.java
@@ -35,7 +35,7 @@
| FLAG_HIDE_BACK_BUTTON;
public SpringLoadedState(int id) {
- super(id, ContainerType.OVERVIEW, STATE_FLAGS);
+ super(id, ContainerType.WORKSPACE, STATE_FLAGS);
}
@Override
diff --git a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
index 171c5ee..3c78b08 100644
--- a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
+++ b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
@@ -21,6 +21,8 @@
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.anim.Interpolators.scrollInterpolatorForVelocity;
import static com.android.launcher3.config.FeatureFlags.UNSTABLE_SPRINGS;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_UNKNOWN_SWIPEDOWN;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_UNKNOWN_SWIPEUP;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_COMPONENTS;
import static com.android.launcher3.states.StateAnimationConfig.PLAY_ATOMIC_OVERVIEW_SCALE;
import static com.android.launcher3.states.StateAnimationConfig.PLAY_NON_ATOMIC;
@@ -42,12 +44,14 @@
import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.PendingAnimation;
+import com.android.launcher3.logger.LauncherAtom;
+import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.states.StateAnimationConfig;
import com.android.launcher3.states.StateAnimationConfig.AnimationFlags;
import com.android.launcher3.testing.TestProtocol;
-import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
+import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
import com.android.launcher3.util.FlingBlockCheck;
import com.android.launcher3.util.TouchController;
@@ -298,11 +302,11 @@
public boolean onDrag(float displacement, MotionEvent ev) {
if (!mIsLogContainerSet) {
if (mStartState == ALL_APPS) {
- mStartContainerType = LauncherLogProto.ContainerType.ALLAPPS;
+ mStartContainerType = ContainerType.ALLAPPS;
} else if (mStartState == NORMAL) {
mStartContainerType = getLogContainerTypeForNormalState(ev);
} else if (mStartState == OVERVIEW) {
- mStartContainerType = LauncherLogProto.ContainerType.TASKSWITCHER;
+ mStartContainerType = ContainerType.TASKSWITCHER;
}
mIsLogContainerSet = true;
}
@@ -559,10 +563,22 @@
// Transition complete. log the action
mLauncher.getUserEventDispatcher().logStateChangeAction(logAction,
getDirectionForLog(), mDetector.getDownX(), mDetector.getDownY(),
- mStartContainerType,
- mStartState.containerType,
+ mStartContainerType /* e.g., hotseat */,
+ mStartState.containerType /* e.g., workspace */,
targetState.containerType,
mLauncher.getWorkspace().getCurrentPage());
+ mLauncher.getStatsLogManager().logger()
+ .withSrcState(StatsLogManager.containerTypeToAtomState(mStartState.containerType))
+ .withDstState(StatsLogManager.containerTypeToAtomState(targetState.containerType))
+ .withContainerInfo(LauncherAtom.ContainerInfo.newBuilder()
+ .setWorkspace(
+ LauncherAtom.WorkspaceContainer.newBuilder()
+ .setPageIndex(mLauncher.getWorkspace().getCurrentPage()))
+ .build())
+ .log(StatsLogManager.getLauncherAtomEvent(mStartState.containerType,
+ targetState.containerType, mToState.ordinal > mFromState.ordinal
+ ? LAUNCHER_UNKNOWN_SWIPEUP
+ : LAUNCHER_UNKNOWN_SWIPEDOWN));
}
protected void clearState() {