summaryrefslogtreecommitdiffstats
path: root/src/com/android/launcher3/logging
diff options
context:
space:
mode:
authorHyunyoung Song <hyunyoungs@google.com>2016-04-12 18:32:04 -0700
committerHyunyoung Song <hyunyoungs@google.com>2016-04-13 10:58:33 -0700
commitddec1c739ef37c3a042982b8943fe42e04b65f4c (patch)
tree565933d46552049c8af29e8615964e47919fd81c /src/com/android/launcher3/logging
parent30a716157b748258e5461fe783298ba7c740835f (diff)
downloadandroid_packages_apps_Trebuchet-ddec1c739ef37c3a042982b8943fe42e04b65f4c.tar.gz
android_packages_apps_Trebuchet-ddec1c739ef37c3a042982b8943fe42e04b65f4c.tar.bz2
android_packages_apps_Trebuchet-ddec1c739ef37c3a042982b8943fe42e04b65f4c.zip
Refactor UserEventLogging, Add predictedRank, replace Bundle with Proto
b/26494415 - Removed bundle object that became redundant now that we have LauncherEvent proto - Combined Stats and UserEventLogger as they are effectively doing same thing - Removed parent field inside Target - added predictedRank target inside Target b/27967359 - make com.android.launcher3.action.LAUNCH broadcast explicit Later CL: finish packageName/intent/componentHash/predictedRank fields Change-Id: I441fb46c834f73e58a4d2324e8da7971e8713ec8
Diffstat (limited to 'src/com/android/launcher3/logging')
-rw-r--r--src/com/android/launcher3/logging/LoggerUtils.java36
-rw-r--r--src/com/android/launcher3/logging/UserEventLogger.java216
2 files changed, 184 insertions, 68 deletions
diff --git a/src/com/android/launcher3/logging/LoggerUtils.java b/src/com/android/launcher3/logging/LoggerUtils.java
index 4b30384f2..584e38e9e 100644
--- a/src/com/android/launcher3/logging/LoggerUtils.java
+++ b/src/com/android/launcher3/logging/LoggerUtils.java
@@ -5,7 +5,6 @@ import android.util.Log;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.ShortcutInfo;
-import com.android.launcher3.Stats;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
@@ -18,16 +17,6 @@ import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
*/
public class LoggerUtils {
private static final String TAG = "LoggerUtils";
- private static final boolean DEBUG = false;
-
- 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;
- }
- }
public static String getActionStr(LauncherLogProto.Action action) {
switch(action.touch) {
@@ -62,8 +51,10 @@ public class LoggerUtils {
default: typeStr = "UNKNOWN";
}
- return typeStr + " " + t.packageNameHash + " grid=(" + t.gridX + "," + t.gridY + ") "
- + getContainerStr(t.parent);
+ return typeStr + ", packageHash=" + t.packageNameHash
+ + ", componentHash=" + t.componentHash
+ + ", intentHash=" + t.intentHash
+ + ", grid=(" + t.gridX + "," + t.gridY + "), id=" + t.pageIndex;
}
private static String getControlStr(Target t) {
@@ -76,7 +67,6 @@ public class LoggerUtils {
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";
}
}
@@ -114,4 +104,22 @@ public class LoggerUtils {
}
return str + " id=" + t.pageIndex;
}
+
+
+ public static LauncherLogProto.LauncherEvent initLauncherEvent(
+ int actionType,
+ int childTargetType,
+ int parentTargetType){
+ LauncherLogProto.LauncherEvent event = new LauncherLogProto.LauncherEvent();
+
+ event.srcTarget = new LauncherLogProto.Target[2];
+ event.srcTarget[0] = new LauncherLogProto.Target();
+ event.srcTarget[0].type = childTargetType;
+ event.srcTarget[1] = new LauncherLogProto.Target();
+ event.srcTarget[1].type = parentTargetType;
+
+ event.action = new LauncherLogProto.Action();
+ event.action.type = actionType;
+ return event;
+ }
}
diff --git a/src/com/android/launcher3/logging/UserEventLogger.java b/src/com/android/launcher3/logging/UserEventLogger.java
index 4e5b2c1b4..bc3afeb8a 100644
--- a/src/com/android/launcher3/logging/UserEventLogger.java
+++ b/src/com/android/launcher3/logging/UserEventLogger.java
@@ -1,71 +1,182 @@
+/*
+ * Copyright (C) 2012 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 android.os.Bundle;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
import android.util.Log;
+import android.view.View;
+import android.view.ViewParent;
-import com.android.launcher3.ShortcutInfo;
-import com.android.launcher3.Stats;
-import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.ItemInfo;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.R;
import com.android.launcher3.userevent.nano.LauncherLogProto;
+import com.android.launcher3.userevent.nano.LauncherLogProto.LauncherEvent;
+import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
+import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
+import com.android.launcher3.util.ComponentKey;
+
+import com.google.protobuf.nano.MessageNano;
-import java.util.Locale;
+import java.util.List;
public abstract class UserEventLogger {
+ private final static int MAXIMUM_VIEW_HIERARCHY_LEVEL = 5;
+ /**
+ * Implemented by containers to provide a launch source for a given child.
+ */
+ public interface LaunchSourceProvider {
+
+ /**
+ * Copies data from the source to the destination proto.
+ * @param v source of the data
+ * @param info source of the data
+ * @param target dest of the data
+ * @param targetParent dest of the data
+ */
+ void fillInLaunchSourceData(View v, ItemInfo info, Target target, Target targetParent);
+ }
+
+ /**
+ * Recursively finds the parent of the given child which implements IconLogInfoProvider
+ */
+ public static LaunchSourceProvider getLaunchProviderRecursive(View v) {
+ ViewParent parent = null;
+ if (v != null) {
+ parent = v.getParent();
+ } else {
+ return null;
+ }
+
+ // Optimization to only check up to 5 parents.
+ int count = MAXIMUM_VIEW_HIERARCHY_LEVEL;
+ while (parent != null && count-- > 0) {
+ if (parent instanceof LaunchSourceProvider) {
+ return (LaunchSourceProvider) parent;
+ } else {
+ parent = parent.getParent();
+ }
+ }
+ return null;
+ }
+
private String TAG = "UserEventLogger";
- private boolean DEBUG = false;
+ private static final boolean DEBUG_BROADCASTS = true;
+
+ public static final String ACTION_LAUNCH = "com.android.launcher3.action.LAUNCH";
+ public static final String EXTRA_INTENT = "intent";;
+ public static final String EXTRA_SOURCE = "source";
+
+ private final Launcher mLauncher;
+ private final String mLaunchBroadcastPermission;
private long mElapsedContainerMillis;
private long mElapsedSessionMillis;
private long mActionDurationMillis;
+ // Used for filling in predictedRank on {@link Target}s.
+ private List<ComponentKey> mPredictedApps;
+
+ public UserEventLogger(Launcher launcher) {
+ mLauncher = launcher;
+ mLaunchBroadcastPermission =
+ launcher.getResources().getString(R.string.receive_launch_broadcasts_permission);
+
+ if (DEBUG_BROADCASTS) {
+ launcher.registerReceiver(
+ new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Log.v(TAG, "got broadcast: " + intent + " for launched intent: "
+ + intent.getStringExtra(EXTRA_INTENT));
+ }
+ },
+ new IntentFilter(ACTION_LAUNCH),
+ mLaunchBroadcastPermission,
+ null
+ );
+ }
+ }
- public final void logAppLaunch(String provider, ShortcutInfo shortcut, Bundle bundle) {
- if (FeatureFlags.LAUNCHER3_LEGACY_LOGGING) return;
+ // APP_ICON SHORTCUT WIDGET
+ // --------------------------------------------------------------
+ // packageNameHash required optional required
+ // componentNameHash required required
+ // intentHash required
+ // --------------------------------------------------------------
- LauncherLogProto.LauncherEvent event = new LauncherLogProto.LauncherEvent();
- event.action = new LauncherLogProto.Action();
- event.action.type = LauncherLogProto.Action.TOUCH;
- event.action.touch = LauncherLogProto.Action.TAP;
+ /**
+ * Prepare {@link LauncherEvent} and {@link Intent} and then attach the event
+ * to the intent and then broadcast.
+ */
+ public final void broadcastEvent(LauncherEvent ev, Intent intent) {
+ intent = new Intent(intent);
+ intent.setSourceBounds(null);
+
+ final String flat = intent.toUri(0);
+ Intent broadcastIntent = new Intent(ACTION_LAUNCH).putExtra(EXTRA_INTENT, flat);
+
+ broadcastIntent.putExtra(EXTRA_SOURCE, MessageNano.toByteArray(ev));
+ String[] packages = ((Context)mLauncher).getResources().getStringArray(R.array.launch_broadcast_targets);
+ for(String p: packages) {
+ broadcastIntent.setPackage(p);
+ mLauncher.sendBroadcast(broadcastIntent, mLaunchBroadcastPermission);
+ }
+ }
- event.srcTarget = new LauncherLogProto.Target();
- event.srcTarget.type = LauncherLogProto.Target.ITEM;
- event.srcTarget.itemType = LauncherLogProto.APP_ICON;
- // TODO: package hash name should be different per device.
- event.srcTarget.packageNameHash = provider.hashCode();
+ public final void logLaunch(View v, Intent intent) {
+ LauncherEvent event = LoggerUtils.initLauncherEvent(
+ Action.TOUCH, Target.ITEM, Target.CONTAINER);
+ event.action.touch = Action.TAP;
- event.srcTarget.parent = new LauncherLogProto.Target();
- String subContainer = bundle.getString(Stats.SOURCE_EXTRA_SUB_CONTAINER);
+ // Fill in grid(x,y), pageIndex of the child and container type of the parent
+ // TODO: make this percolate up the view hierarchy if needed.
+ int idx = 0;
+ LaunchSourceProvider provider = getLaunchProviderRecursive(v);
+ provider.fillInLaunchSourceData(v, (ItemInfo) v.getTag(), event.srcTarget[idx], event.srcTarget[idx + 1]);
- if (shortcut != null) {
- event.srcTarget.parent.containerType = LoggerUtils.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 = LauncherLogProto.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;
- }
+ // TODO: Fill in all the hashes and the predictedRank
- 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)));
- }
- }
+ // Fill in the duration of time spent navigating in Launcher and the container.
event.elapsedContainerMillis = System.currentTimeMillis() - mElapsedContainerMillis;
event.elapsedSessionMillis = System.currentTimeMillis() - mElapsedSessionMillis;
processEvent(event);
+
+ broadcastEvent(event, intent);
+ }
+
+ public void logTap(View v) {
+ // TODO
+ }
+
+ public void logLongPress() {
+ // TODO
+ }
+
+ public void logDragNDrop() {
+ // TODO
+ }
+
+ public void setPredictedApps(List<ComponentKey> predictedApps) {
+ mPredictedApps = predictedApps;
}
/**
@@ -73,25 +184,22 @@ public abstract class UserEventLogger {
*/
public final void resetElapsedContainerMillis() {
mElapsedContainerMillis = System.currentTimeMillis();
- if(DEBUG) {
- Log.d(TAG, "resetElapsedContainerMillis " + mElapsedContainerMillis);
- }
}
public final void resetElapsedSessionMillis() {
mElapsedSessionMillis = System.currentTimeMillis();
mElapsedContainerMillis = System.currentTimeMillis();
- if(DEBUG) {
- Log.d(TAG, "resetElapsedSessionMillis " + mElapsedSessionMillis);
- }
+
}
public final void resetActionDurationMillis() {
mActionDurationMillis = System.currentTimeMillis();
- if(DEBUG) {
- Log.d(TAG, "resetElapsedContainerMillis " + mElapsedContainerMillis);
- }
}
public abstract void processEvent(LauncherLogProto.LauncherEvent ev);
-} \ No newline at end of file
+
+ public int getPredictedRank(ComponentKey key) {
+ if (mPredictedApps == null) return -1;
+ return mPredictedApps.indexOf(key);
+ }
+}