diff options
author | Hyunyoung Song <hyunyoungs@google.com> | 2016-02-19 21:02:55 +0000 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2016-02-19 21:02:55 +0000 |
commit | 61ecb3b20dbf1226dfe6d923ebcafe898a050681 (patch) | |
tree | d789a2e8e527c7e156fdb89e93a6fcc963191669 | |
parent | e70d30bc1864c0087425357e0ff0f497ef97b079 (diff) | |
parent | fbf19cccd293ca23cbed38eaa25abc6ea72be83e (diff) | |
download | android_packages_apps_Trebuchet-61ecb3b20dbf1226dfe6d923ebcafe898a050681.tar.gz android_packages_apps_Trebuchet-61ecb3b20dbf1226dfe6d923ebcafe898a050681.tar.bz2 android_packages_apps_Trebuchet-61ecb3b20dbf1226dfe6d923ebcafe898a050681.zip |
<UserEventLogging> Log app launches b/26494415
am: fbf19cccd2
* commit 'fbf19cccd293ca23cbed38eaa25abc6ea72be83e':
<UserEventLogging> Log app launches b/26494415
-rw-r--r-- | src/com/android/launcher3/Launcher.java | 7 | ||||
-rw-r--r-- | src/com/android/launcher3/LauncherCallbacks.java | 19 | ||||
-rw-r--r-- | src/com/android/launcher3/Stats.java | 2 | ||||
-rw-r--r-- | src/com/android/launcher3/allapps/AllAppsContainerView.java | 2 | ||||
-rw-r--r-- | src/com/android/launcher3/config/FeatureFlags.java | 1 | ||||
-rw-r--r-- | src/com/android/launcher3/userevent/Logger.java | 208 |
6 files changed, 236 insertions, 3 deletions
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index ce962616f..7b53f9f8d 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -108,6 +108,7 @@ import com.android.launcher3.dragndrop.DragController; import com.android.launcher3.dragndrop.DragLayer; import com.android.launcher3.dragndrop.DragView; import com.android.launcher3.model.WidgetsModel; +import com.android.launcher3.userevent.Logger; import com.android.launcher3.util.ComponentKey; import com.android.launcher3.util.LongArrayMap; import com.android.launcher3.util.TestingUtils; @@ -367,6 +368,8 @@ public class Launcher extends Activity } private Stats mStats; + private Logger mUserEventLogger; + public FocusIndicatorView mFocusHandler; private boolean mRotationEnabled = false; @@ -424,6 +427,7 @@ public class Launcher extends Activity mDragController = new DragController(this); mStateTransitionAnimation = new LauncherStateTransitionAnimation(this); + mUserEventLogger = new Logger(this); mStats = new Stats(this); mAppWidgetManager = AppWidgetManagerCompat.getInstance(this); @@ -627,6 +631,7 @@ public class Launcher extends Activity public Stats getStats() { return mStats; } + public Logger getLogger() {return mUserEventLogger; } public boolean isDraggingEnabled() { // We prevent dragging when we are loading the workspace as it is possible to pick up a view @@ -950,6 +955,7 @@ public class Launcher extends Activity } super.onResume(); + mUserEventLogger.resetElapsedSessionMillis(); // Restore the previous launcher state if (mOnResumeState == State.WORKSPACE) { @@ -3331,6 +3337,7 @@ public class Launcher extends Activity getWindow().getDecorView() .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); } + mUserEventLogger.resetElapsedContainerMillis(); return changed; } diff --git a/src/com/android/launcher3/LauncherCallbacks.java b/src/com/android/launcher3/LauncherCallbacks.java index 772fbf358..1d7575253 100644 --- a/src/com/android/launcher3/LauncherCallbacks.java +++ b/src/com/android/launcher3/LauncherCallbacks.java @@ -54,20 +54,33 @@ public interface LauncherCallbacks { */ public void onLauncherProviderChange(); public void finishBindingItems(final boolean upgradePath); - public void onClickAllAppsButton(View v); public void bindAllApplications(ArrayList<AppInfo> apps); + public void onInteractionBegin(); + public void onInteractionEnd(); + + /** + * Extension points for Gel Logging. + */ + @Deprecated + public void onClickAllAppsButton(View v); + @Deprecated public void onClickFolderIcon(View v); + @Deprecated public void onClickAppShortcut(View v); @Deprecated public void onClickPagedViewIcon(View v); + @Deprecated public void onClickWallpaperPicker(View v); + @Deprecated public void onClickSettingsButton(View v); + @Deprecated public void onClickAddWidgetButton(View v); + @Deprecated public void onPageSwitch(View newPage, int newPageIndex); + @Deprecated public void onWorkspaceLockedChanged(); + @Deprecated public void onDragStarted(View view); - public void onInteractionBegin(); - public void onInteractionEnd(); /* * Extension points for replacing the search experience diff --git a/src/com/android/launcher3/Stats.java b/src/com/android/launcher3/Stats.java index 59feeb7e2..287382869 100644 --- a/src/com/android/launcher3/Stats.java +++ b/src/com/android/launcher3/Stats.java @@ -26,6 +26,7 @@ import android.view.View; import android.view.ViewParent; import com.android.launcher3.config.ProviderConfig; +import com.android.launcher3.userevent.Logger; public class Stats { @@ -145,5 +146,6 @@ public class Stats { LaunchSourceUtils.populateSourceDataFromAncestorProvider(v, sourceExtras); broadcastIntent.putExtra(EXTRA_SOURCE, sourceExtras); mLauncher.sendBroadcast(broadcastIntent, mLaunchBroadcastPermission); + mLauncher.getLogger().logAppLaunch(intent.getComponent().getPackageName(), shortcut, sourceExtras); } } diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java index 6bcbb61aa..22af94c74 100644 --- a/src/com/android/launcher3/allapps/AllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java @@ -47,6 +47,7 @@ import com.android.launcher3.LauncherTransitionable; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.Workspace; +import com.android.launcher3.userevent.Logger; import com.android.launcher3.util.ComponentKey; import java.nio.charset.Charset; @@ -312,6 +313,7 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc icon.getMeasuredHeight()); updateBackgroundAndPaddings(); + mLauncher.getLogger().resetElapsedContainerMillis(); } @Override diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java index e8e15c207..1988c2d81 100644 --- a/src/com/android/launcher3/config/FeatureFlags.java +++ b/src/com/android/launcher3/config/FeatureFlags.java @@ -35,4 +35,5 @@ public final class FeatureFlags { public static boolean LAUNCHER3_LEGACY_WORKSPACE_DND = false; public static boolean LAUNCHER3_ICON_NORMALIZATION = true; public static boolean LAUNCHER3_CLIPPED_FOLDER_ICON = false; + public static boolean LAUNCHER3_LEGACY_LOGGING = false; } diff --git a/src/com/android/launcher3/userevent/Logger.java b/src/com/android/launcher3/userevent/Logger.java new file mode 100644 index 000000000..ae9041a4b --- /dev/null +++ b/src/com/android/launcher3/userevent/Logger.java @@ -0,0 +1,208 @@ +package com.android.launcher3.userevent; + +import com.android.launcher3.ShortcutInfo; +import com.android.launcher3.LauncherSettings; +import com.android.launcher3.Stats; +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.Target; +import com.android.launcher3.userevent.nano.LauncherLogProto.LauncherEvent; + +import android.content.Context; +import android.os.Bundle; +import android.util.Log; + +import java.util.Locale; + +/** + * Creates {@LauncherLogProto} nano protobuf object that can be used for user event + * metrics analysis. + */ +public class Logger { + + private static final String TAG = "UserEventLogger"; + private static final boolean DEBUG = false; + + private long mActionDurationMillis; + private long mElapsedContainerMillis; + private long mElapsedSessionMillis; + + private Context mContext; + + public Logger(Context context) { + mContext = context; + } + + public void logAppLaunch(String provider, ShortcutInfo shortcut, Bundle bundle) { + LauncherEvent event = new LauncherEvent(); + event.action = new Action(); + event.action.type = Action.TOUCH; + event.action.touch = Action.TAP; + + event.srcTarget = new Target(); + event.srcTarget.type = Target.ITEM; + event.srcTarget.itemType = LauncherLogProto.APP_ICON; + // TODO: package hash name should be different per device. + event.srcTarget.packageNameHash = provider.hashCode(); + + event.srcTarget.parent = new Target(); + String subContainer = bundle.getString(Stats.SOURCE_EXTRA_SUB_CONTAINER); + + if (shortcut != null) { + event.srcTarget.parent.containerType = getContainerType(shortcut); + event.srcTarget.pageIndex = (int) shortcut.screenId; + event.srcTarget.gridX = shortcut.cellX; + event.srcTarget.gridX = shortcut.cellY; + } + if (subContainer != null) { + event.srcTarget.parent.type = Target.CONTAINER; + if (subContainer.equals(Stats.SUB_CONTAINER_FOLDER)) { + event.srcTarget.parent.containerType = LauncherLogProto.FOLDER; + } else if (subContainer.equals(Stats.SUB_CONTAINER_ALL_APPS_A_Z)) { + event.srcTarget.parent.containerType = LauncherLogProto.ALLAPPS; + } else if (subContainer.equals(Stats.CONTAINER_HOTSEAT)) { + event.srcTarget.parent.containerType = LauncherLogProto.HOTSEAT; + } else if (subContainer.equals(Stats.SUB_CONTAINER_ALL_APPS_PREDICTION)) { + event.srcTarget.parent.containerType = LauncherLogProto.PREDICTION; + } + + if (DEBUG) { + Log.d(TAG, String.format("parent bundle: %s %s %s %s", + bundle.getString(Stats.SOURCE_EXTRA_CONTAINER), + bundle.getString(Stats.SOURCE_EXTRA_CONTAINER_PAGE), + bundle.getString(Stats.SOURCE_EXTRA_SUB_CONTAINER), + bundle.getString(Stats.SOURCE_EXTRA_SUB_CONTAINER_PAGE))); + } + } + + + // Assign timeToAction + event.elapsedContainerMillis = System.currentTimeMillis() - mElapsedContainerMillis; + event.elapsedSessionMillis = System.currentTimeMillis() - mElapsedSessionMillis; + + // Debug + processLauncherEvent(event); + } + + public void resetElapsedContainerMillis() { + mElapsedContainerMillis = System.currentTimeMillis(); + } + + public void resetElapsedSessionMillis() { + mElapsedSessionMillis = System.currentTimeMillis(); + } + + // + // Debugging helper methods. + // toString() cannot be overriden inside auto generated {@link LauncherLogProto}. + // Note: switch statement cannot be replaced with reflection as proguard strips the constants + + private static void processLauncherEvent(LauncherEvent ev) { + if (DEBUG) { + if (ev.action.touch == Action.TAP && ev.srcTarget.itemType == LauncherLogProto.APP_ICON) { + Log.d(TAG, String.format(Locale.US, "action:%s target:%s\n\telapsed container %d ms session %d ms", + getActionStr(ev.action), + getTargetStr(ev.srcTarget), + ev.elapsedContainerMillis, + ev.elapsedSessionMillis)); + } + } + } + + private static int getContainerType(ShortcutInfo shortcut) { + switch ((int) shortcut.container) { + case LauncherSettings.Favorites.CONTAINER_DESKTOP: return LauncherLogProto.WORKSPACE; + case LauncherSettings.Favorites.CONTAINER_HOTSEAT: return LauncherLogProto.HOTSEAT; + default: + return (int) shortcut.container; + } + } + + private static String getActionStr(Action action) { + switch(action.touch) { + case Action.TAP: return "TAP"; + case Action.LONGPRESS: return "LONGPRESS"; + case Action.DRAGDROP: return "DRAGDROP"; + case Action.PINCH: return "PINCH"; + default: return "UNKNOWN"; + } + } + + private static String getTargetStr(Target t) { + String typeStr; + switch (t.type) { + case LauncherLogProto.Target.ITEM: + return getItemStr(t); + case LauncherLogProto.Target.CONTROL: + return getControlStr(t); + case LauncherLogProto.Target.CONTAINER: + return getContainerStr(t); + default: + return "UNKNOWN TARGET TYPE"; + } + } + + private static String getItemStr(Target t) { + String typeStr = ""; + switch(t.itemType){ + case LauncherLogProto.APP_ICON: typeStr = "ICON"; break; + case LauncherLogProto.SHORTCUT: typeStr = "SHORTCUT"; break; + case LauncherLogProto.WIDGET: typeStr = "WIDGET"; break; + default: typeStr = "UNKNOWN"; + } + + return typeStr + " " + t.packageNameHash + " grid=(" + t.gridX + "," + t.gridY + ") " + + getContainerStr(t.parent); + } + + private static String getControlStr(Target t) { + switch(t.controlType) { + case LauncherLogProto.ALL_APPS_BUTTON: return "ALL_APPS_BUTTON"; + case LauncherLogProto.WIDGETS_BUTTON: return "WIDGETS_BUTTON"; + case LauncherLogProto.WALLPAPER_BUTTON: return "WALLPAPER_BUTTON"; + case LauncherLogProto.SETTINGS_BUTTON: return "SETTINGS_BUTTON"; + case LauncherLogProto.REMOVE_TARGET: return "REMOVE_TARGET"; + case LauncherLogProto.UNINSTALL_TARGET: return "UNINSTALL_TARGET"; + case LauncherLogProto.APPINFO_TARGET: return "APPINFO_TARGET"; + case LauncherLogProto.RESIZE_HANDLE: return "RESIZE_HANDLE"; + case LauncherLogProto.FAST_SCROLL_HANDLE: return "FAST_SCROLL_HANDLE"; + default: return "UNKNOWN"; + } + } + + private static String getContainerStr(Target t) { + String str; + Log.d(TAG, "t.containerType" + t.containerType); + switch (t.containerType) { + case LauncherLogProto.WORKSPACE: + str = "WORKSPACE"; + break; + case LauncherLogProto.HOTSEAT: + str = "HOTSEAT"; + break; + case LauncherLogProto.FOLDER: + str = "FOLDER"; + break; + case LauncherLogProto.ALLAPPS: + str = "ALLAPPS"; + break; + case LauncherLogProto.WIDGETS: + str = "WIDGETS"; + break; + case LauncherLogProto.OVERVIEW: + str = "OVERVIEW"; + break; + case LauncherLogProto.PREDICTION: + str = "PREDICTION"; + break; + case LauncherLogProto.SEARCHRESULT: + str = "SEARCHRESULT"; + break; + default: + str = "UNKNOWN"; + } + return str + " id=" + t.pageIndex; + } +} + |