ItemInfo supports lite proto builder (1/n)
Bug: 144953948
Bug: 137777105
The new lite proto builder is used to send two types of logging to statsd
1) Snapshot logging
2) App launch, task launch, task dismiss
Statsd will be connected once platform CL is submitted
Change-Id: If606cee5288fe4bd6c522605ae84eb0f24174f5b
diff --git a/src/com/android/launcher3/BaseDraggingActivity.java b/src/com/android/launcher3/BaseDraggingActivity.java
index 9f3b48f..6fa3c28 100644
--- a/src/com/android/launcher3/BaseDraggingActivity.java
+++ b/src/com/android/launcher3/BaseDraggingActivity.java
@@ -16,6 +16,7 @@
package com.android.launcher3;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.APP_LAUNCH_TAP;
import static com.android.launcher3.util.DefaultDisplay.CHANGE_ROTATION;
import android.app.ActivityOptions;
@@ -181,7 +182,7 @@
sourceContainer);
}
getUserEventDispatcher().logAppLaunch(v, intent, user);
- getStatsLogManager().logAppLaunch(v, intent, user);
+ getStatsLogManager().log(APP_LAUNCH_TAP, item.buildProto(null, null));
return true;
} catch (NullPointerException|ActivityNotFoundException|SecurityException e) {
Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
diff --git a/src/com/android/launcher3/ItemInfo.java b/src/com/android/launcher3/ItemInfo.java
index c99465c..8c4e4a0 100644
--- a/src/com/android/launcher3/ItemInfo.java
+++ b/src/com/android/launcher3/ItemInfo.java
@@ -16,6 +16,13 @@
package com.android.launcher3;
+import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_DESKTOP;
+import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT;
+import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
+import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET;
+import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT;
+import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
+
import android.content.ComponentName;
import android.content.ContentValues;
import android.content.Intent;
@@ -24,13 +31,17 @@
import androidx.annotation.Nullable;
+import com.android.launcher3.logger.LauncherAtom;
import com.android.launcher3.util.ContentWriter;
+
+
/**
* Represents an item in the launcher.
*/
public class ItemInfo {
+ public static final boolean DEBUG = true;
public static final int NO_ID = -1;
/**
@@ -190,6 +201,7 @@
return "id=" + id
+ " type=" + LauncherSettings.Favorites.itemTypeToString(itemType)
+ " container=" + LauncherSettings.Favorites.containerToString((int)container)
+ + " targetComponent=" + getTargetComponent()
+ " screen=" + screenId
+ " cell(" + cellX + "," + cellY + ")"
+ " span(" + spanX + "," + spanY + ")"
@@ -221,4 +233,70 @@
return container == LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION
|| container == LauncherSettings.Favorites.CONTAINER_PREDICTION;
}
+
+ /**
+ * Can be overridden by inherited classes to fill in {@link LauncherAtom.ItemInfo}
+ */
+ public void setItemBuilder(LauncherAtom.ItemInfo.Builder builder) {
+ }
+
+ /**
+ * Creates {@link LauncherAtom.ItemInfo} with important fields and parent container info.
+ */
+ public LauncherAtom.ItemInfo buildProto(Intent intent, FolderInfo fInfo) {
+
+ LauncherAtom.ItemInfo.Builder itemBuilder = LauncherAtom.ItemInfo.newBuilder();
+ itemBuilder.setIsWork(user != Process.myUserHandle());
+ ComponentName cn = getTargetComponent();
+ switch (itemType) {
+ case ITEM_TYPE_APPLICATION:
+ itemBuilder.setApplication(LauncherAtom.Application.newBuilder()
+ .setComponentName(cn.flattenToShortString())
+ .setPackageName(cn.getPackageName()));
+ break;
+ case ITEM_TYPE_DEEP_SHORTCUT:
+ case ITEM_TYPE_SHORTCUT:
+ itemBuilder.setShortcut(LauncherAtom.Shortcut.newBuilder()
+ .setShortcutName(cn.flattenToShortString()));
+ break;
+ case ITEM_TYPE_APPWIDGET:
+ setItemBuilder(itemBuilder);
+ break;
+ default:
+ break;
+
+ }
+ if (fInfo != null) {
+ LauncherAtom.FolderContainer.Builder folderBuilder =
+ LauncherAtom.FolderContainer.newBuilder();
+ folderBuilder.setGridX(cellX).setGridY(cellY).setPageIndex(screenId);
+
+ switch (fInfo.container) {
+ case CONTAINER_HOTSEAT:
+ folderBuilder.setHotseat(LauncherAtom.HotseatContainer.newBuilder()
+ .setIndex(fInfo.screenId));
+ break;
+ case CONTAINER_DESKTOP:
+ folderBuilder.setWorkspace(LauncherAtom.WorkspaceContainer.newBuilder()
+ .setPageIndex(fInfo.screenId)
+ .setGridX(fInfo.cellX).setGridY(fInfo.cellY));
+ break;
+ }
+ itemBuilder.setFolder(folderBuilder);
+ } else {
+ switch (container) {
+ case CONTAINER_HOTSEAT:
+ itemBuilder.setHotseat(LauncherAtom.HotseatContainer.newBuilder()
+ .setIndex(screenId));
+ break;
+ case CONTAINER_DESKTOP:
+ itemBuilder.setWorkspace(LauncherAtom.WorkspaceContainer.newBuilder()
+ .setGridX(cellX)
+ .setGridY(cellY)
+ .setPageIndex(screenId));
+ break;
+ }
+ }
+ return itemBuilder.build();
+ }
}
diff --git a/src/com/android/launcher3/LauncherAppWidgetInfo.java b/src/com/android/launcher3/LauncherAppWidgetInfo.java
index b824301..3a478dd 100644
--- a/src/com/android/launcher3/LauncherAppWidgetInfo.java
+++ b/src/com/android/launcher3/LauncherAppWidgetInfo.java
@@ -21,6 +21,7 @@
import android.content.Intent;
import android.os.Process;
+import com.android.launcher3.logger.LauncherAtom;
import com.android.launcher3.model.PackageItemInfo;
import com.android.launcher3.util.ContentWriter;
@@ -162,7 +163,9 @@
@Override
protected String dumpProperties() {
- return super.dumpProperties() + " appWidgetId=" + appWidgetId;
+ return super.dumpProperties()
+ + " providerName=" + providerName
+ + " appWidgetId=" + appWidgetId;
}
public final boolean isWidgetIdAllocated() {
@@ -182,4 +185,13 @@
public final boolean hasOptionFlag(int option) {
return (options & option) != 0;
}
+
+ @Override
+ public void setItemBuilder(LauncherAtom.ItemInfo.Builder builder) {
+ builder.setWidget(LauncherAtom.Widget.newBuilder()
+ .setSpanX(spanX)
+ .setSpanY(spanY)
+ .setComponentName(providerName.toString())
+ .setPackageName(providerName.getPackageName()));
+ }
}
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index ee9c099..8bc0242 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -991,7 +991,6 @@
if (!mOverlayShown) {
mLauncher.getUserEventDispatcher().logActionOnContainer(Action.Touch.SWIPE,
Action.Direction.LEFT, ContainerType.WORKSPACE, 0);
- mLauncher.getStatsLogManager().logSwipeOnContainer(true, 0);
}
mOverlayShown = true;
// Not announcing the overlay page for accessibility since it announces itself.
@@ -1001,7 +1000,6 @@
if (!ued.isPreviousHomeGesture()) {
mLauncher.getUserEventDispatcher().logActionOnContainer(Action.Touch.SWIPE,
Action.Direction.RIGHT, ContainerType.WORKSPACE, -1);
- mLauncher.getStatsLogManager().logSwipeOnContainer(false, -1);
}
} else if (Float.compare(mOverlayTranslation, 0f) != 0) {
// When arriving to 0 overscroll from non-zero overscroll, announce page for
diff --git a/src/com/android/launcher3/logging/LauncherUiEvent.java b/src/com/android/launcher3/logging/LauncherUiEvent.java
new file mode 100644
index 0000000..4507ff7
--- /dev/null
+++ b/src/com/android/launcher3/logging/LauncherUiEvent.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.logging;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+@Retention(SOURCE)
+@Target(FIELD)
+public @interface LauncherUiEvent {
+ /** An explanation, suitable for Android analysts, of the UI event that this log represents. */
+ String doc();
+}
+
diff --git a/src/com/android/launcher3/logging/StatsLogManager.java b/src/com/android/launcher3/logging/StatsLogManager.java
index 9dfd7ab..2829951 100644
--- a/src/com/android/launcher3/logging/StatsLogManager.java
+++ b/src/com/android/launcher3/logging/StatsLogManager.java
@@ -16,23 +16,44 @@
package com.android.launcher3.logging;
import android.content.Context;
-import android.content.Intent;
-import android.os.UserHandle;
-import android.view.View;
-
-import androidx.annotation.Nullable;
import com.android.launcher3.R;
+import com.android.launcher3.logger.LauncherAtom;
+import com.android.launcher3.logger.LauncherAtom.ItemInfo;
import com.android.launcher3.logging.StatsLogUtils.LogStateProvider;
-import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.ResourceBasedOverride;
/**
- * Handles the user event logging in Q.
+ * Handles the user event logging in R+.
*/
public class StatsLogManager implements ResourceBasedOverride {
+ interface EventEnum {
+ int getId();
+ }
+
+ public enum LauncherEvent implements EventEnum {
+ @LauncherUiEvent(doc = "App launched from workspace, hotseat or folder in launcher")
+ APP_LAUNCH_TAP(1),
+ @LauncherUiEvent(doc = "Task launched from overview using TAP")
+ TASK_LAUNCH_TAP(2),
+ @LauncherUiEvent(doc = "Task launched from overview using SWIPE DOWN")
+ TASK_LAUNCH_SWIPE_DOWN(2),
+ @LauncherUiEvent(doc = "TASK dismissed from overview using SWIPE UP")
+ TASK_DISMISS_SWIPE_UP(3);
+ // ADD MORE
+
+ private final int mId;
+ LauncherEvent(int id) {
+ mId = id;
+ }
+ public int getId() {
+ return mId;
+ }
+ }
+
protected LogStateProvider mStateProvider;
+
public static StatsLogManager newInstance(Context context, LogStateProvider stateProvider) {
StatsLogManager mgr = Overrides.getObject(StatsLogManager.class,
context.getApplicationContext(), R.string.stats_log_manager_class);
@@ -42,11 +63,14 @@
}
/**
- * Logs app launches
+ * Logs an event and accompanying {@link ItemInfo}
*/
- public void logAppLaunch(View v, Intent intent, @Nullable UserHandle userHandle) { }
- public void logTaskLaunch(View v, ComponentKey key) { }
- public void logTaskDismiss(View v, ComponentKey key) { }
- public void logSwipeOnContainer(boolean isSwipingToLeft, int pageId) { }
+ public void log(LauncherEvent eventId, LauncherAtom.ItemInfo itemInfo) { }
+
+ /**
+ * Logs snapshot, or impression of the current workspace.
+ */
+ public void logSnapshot() { }
+
public void verify() {} // TODO: should move into robo tests
}
diff --git a/src/com/android/launcher3/model/LoaderCursor.java b/src/com/android/launcher3/model/LoaderCursor.java
index 2311dcc..695d2a6 100644
--- a/src/com/android/launcher3/model/LoaderCursor.java
+++ b/src/com/android/launcher3/model/LoaderCursor.java
@@ -35,6 +35,8 @@
import android.util.Log;
import android.util.LongSparseArray;
+import androidx.annotation.VisibleForTesting;
+
import com.android.launcher3.AppInfo;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.ItemInfo;
@@ -150,8 +152,10 @@
}
}
+ @VisibleForTesting
public WorkspaceItemInfo loadSimpleWorkspaceItem() {
final WorkspaceItemInfo info = new WorkspaceItemInfo();
+ info.intent = new Intent();
// Non-app shortcuts are only supported for current user.
info.user = user;
info.itemType = itemType;