Add logs for taskbar and overview split action
Log:
- Taskbar app launch (also from foldeR)
- Taskbar app drag (also from folder)
- Taskbar folder open
- Long press to hide taskbar
- Long press to show taskbar
- Overview Split screen action
Also add support for ActivityContext to overwrite/add to LauncherAtom.ItemInfo, which TaskbarActivityContext does to change HotseatContainer and PredictedHotseatContainer to TaskBarContainer
Test: enable logcat locally
Bug: 193009817
Change-Id: Ia82c846a727fecb8cbfd0a069c8af1276083bf83
diff --git a/protos/launcher_atom.proto b/protos/launcher_atom.proto
index 6dfb84e..ca9f063 100644
--- a/protos/launcher_atom.proto
+++ b/protos/launcher_atom.proto
@@ -241,6 +241,7 @@
oneof ParentContainer {
WorkspaceContainer workspace = 4;
HotseatContainer hotseat = 5;
+ TaskBarContainer taskbar = 6;
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
index 764b0d3..3dd7f5d 100644
--- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
@@ -16,6 +16,8 @@
package com.android.launcher3.taskbar;
import static com.android.launcher3.LauncherState.HOTSEAT_ICONS;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_LONGPRESS_HIDE;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_LONGPRESS_SHOW;
import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_IN_APP;
import static com.android.launcher3.taskbar.TaskbarViewController.ALPHA_INDEX_HOME;
@@ -36,7 +38,10 @@
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimatorListeners;
import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.logging.InstanceId;
+import com.android.launcher3.logging.InstanceIdSequence;
import com.android.launcher3.model.data.ItemInfoWithIcon;
+import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.util.MultiValueAlpha;
import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
import com.android.launcher3.util.OnboardingPrefs;
@@ -262,6 +267,11 @@
@Override
protected void onStashedInAppChanged() {
onStashedInAppChanged(mLauncher.getDeviceProfile());
+ if (mControllers.taskbarStashController.isStashedInApp()) {
+ mContext.getStatsLogManager().logger().log(LAUNCHER_TASKBAR_LONGPRESS_HIDE);
+ } else {
+ mContext.getStatsLogManager().logger().log(LAUNCHER_TASKBAR_LONGPRESS_SHOW);
+ }
}
private void onStashedInAppChanged(DeviceProfile deviceProfile) {
@@ -306,6 +316,12 @@
mControllers.taskbarEduController.hideEdu();
}
+ @Override
+ public void onTaskbarIconLaunched(WorkspaceItemInfo item) {
+ InstanceId instanceId = new InstanceIdSequence().newInstanceId();
+ mLauncher.logAppLaunch(mContext.getStatsLogManager(), item, instanceId);
+ }
+
private final class TaskBarRecentsAnimationListener implements RecentsAnimationListener {
private final RecentsAnimationCallbacks mCallbacks;
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index 0d684a0..b93251e 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -19,6 +19,7 @@
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_OPEN;
import static com.android.systemui.shared.system.WindowManagerWrapper.ITYPE_BOTTOM_TAPPABLE_ELEMENT;
import static com.android.systemui.shared.system.WindowManagerWrapper.ITYPE_EXTRA_NAVIGATION_BAR;
@@ -52,6 +53,7 @@
import com.android.launcher3.R;
import com.android.launcher3.folder.Folder;
import com.android.launcher3.folder.FolderIcon;
+import com.android.launcher3.logger.LauncherAtom;
import com.android.launcher3.model.data.FolderInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.taskbar.contextual.RotationButtonController;
@@ -230,6 +232,60 @@
}
/**
+ * Change from hotseat/predicted hotseat to taskbar container.
+ */
+ @Override
+ public void applyOverwritesToLogItem(LauncherAtom.ItemInfo.Builder itemInfoBuilder) {
+ if (!itemInfoBuilder.hasContainerInfo()) {
+ return;
+ }
+ LauncherAtom.ContainerInfo oldContainer = itemInfoBuilder.getContainerInfo();
+
+ if (oldContainer.hasPredictedHotseatContainer()) {
+ LauncherAtom.PredictedHotseatContainer predictedHotseat =
+ oldContainer.getPredictedHotseatContainer();
+ LauncherAtom.TaskBarContainer.Builder taskbarBuilder =
+ LauncherAtom.TaskBarContainer.newBuilder();
+
+ if (predictedHotseat.hasIndex()) {
+ taskbarBuilder.setIndex(predictedHotseat.getIndex());
+ }
+ if (predictedHotseat.hasCardinality()) {
+ taskbarBuilder.setCardinality(predictedHotseat.getCardinality());
+ }
+
+ itemInfoBuilder.setContainerInfo(LauncherAtom.ContainerInfo.newBuilder()
+ .setTaskBarContainer(taskbarBuilder));
+ } else if (oldContainer.hasHotseat()) {
+ LauncherAtom.HotseatContainer hotseat = oldContainer.getHotseat();
+ LauncherAtom.TaskBarContainer.Builder taskbarBuilder =
+ LauncherAtom.TaskBarContainer.newBuilder();
+
+ if (hotseat.hasIndex()) {
+ taskbarBuilder.setIndex(hotseat.getIndex());
+ }
+
+ itemInfoBuilder.setContainerInfo(LauncherAtom.ContainerInfo.newBuilder()
+ .setTaskBarContainer(taskbarBuilder));
+ } else if (oldContainer.hasFolder() && oldContainer.getFolder().hasHotseat()) {
+ LauncherAtom.FolderContainer.Builder folderBuilder = oldContainer.getFolder()
+ .toBuilder();
+ LauncherAtom.HotseatContainer hotseat = folderBuilder.getHotseat();
+ LauncherAtom.TaskBarContainer.Builder taskbarBuilder =
+ LauncherAtom.TaskBarContainer.newBuilder();
+
+ if (hotseat.hasIndex()) {
+ taskbarBuilder.setIndex(hotseat.getIndex());
+ }
+
+ folderBuilder.setTaskbar(taskbarBuilder);
+ folderBuilder.clearHotseat();
+ itemInfoBuilder.setContainerInfo(LauncherAtom.ContainerInfo.newBuilder()
+ .setFolder(folderBuilder));
+ }
+ }
+
+ /**
* Sets a new data-source for this taskbar instance
*/
public void setUIController(@NonNull TaskbarUIController uiController) {
@@ -326,6 +382,7 @@
getDragLayer().post(() -> {
folder.animateOpen();
+ getStatsLogManager().logger().withItemInfo(folder.mInfo).log(LAUNCHER_FOLDER_OPEN);
folder.iterateOverItems((itemInfo, itemView) -> {
mControllers.taskbarViewController
@@ -363,6 +420,8 @@
getSystemService(LauncherApps.class).startMainActivity(
intent.getComponent(), info.user, intent.getSourceBounds(), null);
}
+
+ mControllers.uiController.onTaskbarIconLaunched(info);
} catch (NullPointerException | ActivityNotFoundException | SecurityException e) {
Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT)
.show();
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
index b89032e..1afbd17 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
@@ -34,6 +34,8 @@
import androidx.annotation.Nullable;
+import com.android.internal.logging.InstanceId;
+import com.android.internal.logging.InstanceIdSequence;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.DragSource;
@@ -48,6 +50,7 @@
import com.android.launcher3.dragndrop.DraggableView;
import com.android.launcher3.graphics.DragPreviewProvider;
import com.android.launcher3.icons.FastBitmapDrawable;
+import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.systemui.shared.recents.model.Task;
@@ -284,10 +287,22 @@
}
if (clipDescription != null && intent != null) {
+ // Need to share the same InstanceId between launcher3 and WM Shell (internal).
+ InstanceId internalInstanceId = new InstanceIdSequence(
+ com.android.launcher3.logging.InstanceId.INSTANCE_ID_MAX).newInstanceId();
+ com.android.launcher3.logging.InstanceId launcherInstanceId =
+ new com.android.launcher3.logging.InstanceId(internalInstanceId.getId());
+
+ intent.putExtra(ClipDescription.EXTRA_LOGGING_INSTANCE_ID, internalInstanceId);
+
ClipData clipData = new ClipData(clipDescription, new ClipData.Item(intent));
if (btv.startDragAndDrop(clipData, shadowBuilder, null /* localState */,
View.DRAG_FLAG_GLOBAL | View.DRAG_FLAG_OPAQUE)) {
onSystemDragStarted();
+
+ mActivity.getStatsLogManager().logger().withItemInfo(mDragObject.dragInfo)
+ .withInstanceId(launcherInstanceId)
+ .log(StatsLogManager.LauncherEvent.LAUNCHER_ITEM_DRAG_STARTED);
}
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
index c0312a0..d8360e0 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
@@ -18,6 +18,7 @@
import android.graphics.Rect;
import com.android.launcher3.model.data.ItemInfoWithIcon;
+import com.android.launcher3.model.data.WorkspaceItemInfo;
import java.util.stream.Stream;
@@ -43,4 +44,6 @@
public Stream<ItemInfoWithIcon> getAppIconsForEdu() {
return Stream.empty();
}
+
+ public void onTaskbarIconLaunched(WorkspaceItemInfo item) { }
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index 2009cd7..3738dce 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -51,6 +51,7 @@
import com.android.launcher3.appprediction.PredictionRowView;
import com.android.launcher3.hybridhotseat.HotseatPredictionController;
import com.android.launcher3.logging.InstanceId;
+import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.logging.StatsLogManager.StatsLogger;
import com.android.launcher3.model.BgDataModel.FixedContainerItems;
import com.android.launcher3.model.data.ItemInfo;
@@ -104,7 +105,8 @@
}
@Override
- protected void logAppLaunch(ItemInfo info, InstanceId instanceId) {
+ public void logAppLaunch(StatsLogManager statsLogManager, ItemInfo info,
+ InstanceId instanceId) {
// If the app launch is from any of the surfaces in AllApps then add the InstanceId from
// LiveSearchManager to recreate the AllApps session on the server side.
if (mAllAppsSessionLogId != null && ALL_APPS.equals(
@@ -112,8 +114,7 @@
instanceId = mAllAppsSessionLogId;
}
- StatsLogger logger = getStatsLogManager()
- .logger().withItemInfo(info).withInstanceId(instanceId);
+ StatsLogger logger = statsLogManager.logger().withItemInfo(info).withInstanceId(instanceId);
if (mAllAppsPredictions != null
&& (info.itemType == ITEM_TYPE_APPLICATION
diff --git a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
index 38c299e..09113d8 100644
--- a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
+++ b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
@@ -56,6 +56,7 @@
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.util.Executors;
import com.android.launcher3.util.LogConfig;
+import com.android.launcher3.views.ActivityContext;
import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
import com.android.systemui.shared.system.SysUiStatsLog;
@@ -97,7 +98,7 @@
@Override
protected StatsLogger createLogger() {
- return new StatsCompatLogger(mContext);
+ return new StatsCompatLogger(mContext, mActivityContext);
}
/**
@@ -141,7 +142,8 @@
private static final ItemInfo DEFAULT_ITEM_INFO = new ItemInfo();
- private Context mContext;
+ private final Context mContext;
+ private final Optional<ActivityContext> mActivityContext;
private ItemInfo mItemInfo = DEFAULT_ITEM_INFO;
private InstanceId mInstanceId = DEFAULT_INSTANCE_ID;
private OptionalInt mRank = OptionalInt.empty();
@@ -154,8 +156,9 @@
private SliceItem mSliceItem;
private LauncherAtom.Slice mSlice;
- StatsCompatLogger(Context context) {
+ StatsCompatLogger(Context context, ActivityContext activityContext) {
mContext = context;
+ mActivityContext = Optional.ofNullable(activityContext);
}
@Override
@@ -307,6 +310,9 @@
mRank.ifPresent(itemInfoBuilder::setRank);
mContainerInfo.ifPresent(itemInfoBuilder::setContainerInfo);
+ mActivityContext.ifPresent(activityContext ->
+ activityContext.applyOverwritesToLogItem(itemInfoBuilder));
+
if (mFromState.isPresent() || mToState.isPresent() || mEditText.isPresent()) {
FolderIcon.Builder folderIconBuilder = itemInfoBuilder
.getFolderIcon()
diff --git a/src/com/android/launcher3/BaseDraggingActivity.java b/src/com/android/launcher3/BaseDraggingActivity.java
index 2c76e52..7954011 100644
--- a/src/com/android/launcher3/BaseDraggingActivity.java
+++ b/src/com/android/launcher3/BaseDraggingActivity.java
@@ -55,6 +55,7 @@
import com.android.launcher3.allapps.search.SearchAdapterProvider;
import com.android.launcher3.logging.InstanceId;
import com.android.launcher3.logging.InstanceIdSequence;
+import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.touch.ItemClickHandler;
@@ -224,7 +225,7 @@
}
if (item != null) {
InstanceId instanceId = new InstanceIdSequence().newInstanceId();
- logAppLaunch(item, instanceId);
+ logAppLaunch(getStatsLogManager(), item, instanceId);
}
return true;
} catch (NullPointerException | ActivityNotFoundException | SecurityException e) {
@@ -234,8 +235,12 @@
return false;
}
- protected void logAppLaunch(ItemInfo info, InstanceId instanceId) {
- getStatsLogManager().logger().withItemInfo(info).withInstanceId(instanceId)
+ /**
+ * Creates and logs a new app launch event.
+ */
+ public void logAppLaunch(StatsLogManager statsLogManager, ItemInfo info,
+ InstanceId instanceId) {
+ statsLogManager.logger().withItemInfo(info).withInstanceId(instanceId)
.log(LAUNCHER_APP_LAUNCH_TAP);
}
diff --git a/src/com/android/launcher3/logging/InstanceId.java b/src/com/android/launcher3/logging/InstanceId.java
index e720d75..3c4a644 100644
--- a/src/com/android/launcher3/logging/InstanceId.java
+++ b/src/com/android/launcher3/logging/InstanceId.java
@@ -36,10 +36,10 @@
*/
public final class InstanceId implements Parcelable {
// At most 20 bits: ~1m possibilities, ~0.5% probability of collision in 100 values
- static final int INSTANCE_ID_MAX = 1 << 20;
+ public static final int INSTANCE_ID_MAX = 1 << 20;
private final int mId;
- InstanceId(int id) {
+ public InstanceId(int id) {
mId = min(max(0, id), INSTANCE_ID_MAX);
}
diff --git a/src/com/android/launcher3/logging/StatsLogManager.java b/src/com/android/launcher3/logging/StatsLogManager.java
index 5ed651f..d987212 100644
--- a/src/com/android/launcher3/logging/StatsLogManager.java
+++ b/src/com/android/launcher3/logging/StatsLogManager.java
@@ -33,6 +33,7 @@
import com.android.launcher3.logger.LauncherAtom.ToState;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.util.ResourceBasedOverride;
+import com.android.launcher3.views.ActivityContext;
/**
* Handles the user event logging in R+.
@@ -53,6 +54,9 @@
public static final int LAUNCHER_STATE_UNCHANGED = 5;
private InstanceId mInstanceId;
+
+ protected @Nullable ActivityContext mActivityContext = null;
+
/**
* Returns event enum based on the two state transition information when swipe
* gesture happens(to be removed during UserEventDispatcher cleanup).
@@ -281,6 +285,9 @@
@UiEvent(doc = "User tapped on the share button on overview")
LAUNCHER_OVERVIEW_ACTIONS_SHARE(582),
+ @UiEvent(doc = "User tapped on the split screen button on overview")
+ LAUNCHER_OVERVIEW_ACTIONS_SPLIT(895),
+
@UiEvent(doc = "User tapped on the close button in select mode")
LAUNCHER_SELECT_MODE_CLOSE(583),
@@ -505,7 +512,13 @@
LAUNCHER_TURN_OFF_WORK_APPS_TAP(839),
@UiEvent(doc = "Launcher item drop failed since there was not enough room on the screen.")
- LAUNCHER_ITEM_DROP_FAILED_INSUFFICIENT_SPACE(872);
+ LAUNCHER_ITEM_DROP_FAILED_INSUFFICIENT_SPACE(872),
+
+ @UiEvent(doc = "User long pressed on the taskbar background to hide the taskbar")
+ LAUNCHER_TASKBAR_LONGPRESS_HIDE(896),
+
+ @UiEvent(doc = "User long pressed on the taskbar gesture handle to show the taskbar")
+ LAUNCHER_TASKBAR_LONGPRESS_SHOW(897);
// ADD MORE
@@ -645,7 +658,7 @@
public StatsLogger logger() {
StatsLogger logger = createLogger();
if (mInstanceId != null) {
- return logger.withInstanceId(mInstanceId);
+ logger.withInstanceId(mInstanceId);
}
return logger;
}
@@ -668,7 +681,9 @@
* Creates a new instance of {@link StatsLogManager} based on provided context.
*/
public static StatsLogManager newInstance(Context context) {
- return Overrides.getObject(StatsLogManager.class,
+ StatsLogManager manager = Overrides.getObject(StatsLogManager.class,
context.getApplicationContext(), R.string.stats_log_manager_class);
+ manager.mActivityContext = ActivityContext.lookupContextNoThrow(context);
+ return manager;
}
}
diff --git a/src/com/android/launcher3/views/ActivityContext.java b/src/com/android/launcher3/views/ActivityContext.java
index dc5fe06..ebcd379 100644
--- a/src/com/android/launcher3/views/ActivityContext.java
+++ b/src/com/android/launcher3/views/ActivityContext.java
@@ -27,6 +27,7 @@
import com.android.launcher3.dot.DotInfo;
import com.android.launcher3.dragndrop.DragController;
import com.android.launcher3.folder.FolderIcon;
+import com.android.launcher3.logger.LauncherAtom;
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.util.ViewCache;
@@ -122,15 +123,33 @@
}
/**
- * Returns the ActivityContext associated with the given Context.
+ * Called just before logging the given item.
+ */
+ default void applyOverwritesToLogItem(LauncherAtom.ItemInfo.Builder itemInfoBuilder) { }
+
+ /**
+ * Returns the ActivityContext associated with the given Context, or throws an exception if
+ * the Context is not associated with any ActivityContext.
*/
static <T extends Context & ActivityContext> T lookupContext(Context context) {
+ T activityContext = lookupContextNoThrow(context);
+ if (activityContext == null) {
+ throw new IllegalArgumentException("Cannot find ActivityContext in parent tree");
+ }
+ return activityContext;
+ }
+
+ /**
+ * Returns the ActivityContext associated with the given Context, or null if
+ * the Context is not associated with any ActivityContext.
+ */
+ static <T extends Context & ActivityContext> T lookupContextNoThrow(Context context) {
if (context instanceof ActivityContext) {
return (T) context;
} else if (context instanceof ContextWrapper) {
- return lookupContext(((ContextWrapper) context).getBaseContext());
+ return lookupContextNoThrow(((ContextWrapper) context).getBaseContext());
} else {
- throw new IllegalArgumentException("Cannot find ActivityContext in parent tree");
+ return null;
}
}
}