Merge "Add ImpressionLogger to StatsLogManager" into tm-qpr-dev am: c2f03ae080

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Launcher3/+/20445919

Change-Id: I0b74a4469f7c401c9fa04989e5f82048407960a8
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
index dac5a31..0ef4597 100644
--- a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
+++ b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
@@ -62,11 +62,14 @@
 import com.android.launcher3.model.data.FolderInfo;
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.util.Executors;
+import com.android.launcher3.util.IntArray;
 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;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Optional;
 import java.util.OptionalInt;
 import java.util.concurrent.CopyOnWriteArrayList;
@@ -85,6 +88,7 @@
 
     private static final String TAG = "StatsLog";
     private static final String LATENCY_TAG = "StatsLatencyLog";
+    private static final String IMPRESSION_TAG = "StatsImpressionLog";
     private static final boolean IS_VERBOSE = Utilities.isPropertyEnabled(LogConfig.STATSLOG);
     private static final InstanceId DEFAULT_INSTANCE_ID = InstanceId.fakeInstanceId(0);
     // LauncherAtom.ItemInfo.getDefaultInstance() should be used but until launcher proto migrates
@@ -119,7 +123,12 @@
 
     @Override
     protected StatsLatencyLogger createLatencyLogger() {
-        return new StatsCompatLatencyLogger(mContext, mActivityContext);
+        return new StatsCompatLatencyLogger();
+    }
+
+    @Override
+    protected StatsImpressionLogger createImpressionLogger() {
+        return new StatsCompatImpressionLogger();
     }
 
     /**
@@ -466,8 +475,6 @@
      * Helps to construct and log statsd compatible latency events.
      */
     private static class StatsCompatLatencyLogger implements StatsLatencyLogger {
-        private final Context mContext;
-        private final Optional<ActivityContext> mActivityContext;
         private InstanceId mInstanceId = DEFAULT_INSTANCE_ID;
         private LatencyType mType = LatencyType.UNKNOWN;
         private int mPackageId = 0;
@@ -475,11 +482,6 @@
         private int mQueryLength = -1;
         private int mSubEventType = 0;
 
-        StatsCompatLatencyLogger(Context context, ActivityContext activityContext) {
-            mContext = context;
-            mActivityContext = Optional.ofNullable(activityContext);
-        }
-
         @Override
         public StatsLatencyLogger withInstanceId(InstanceId instanceId) {
             this.mInstanceId = instanceId;
@@ -539,6 +541,96 @@
         }
     }
 
+    /**
+     * Helps to construct and log statsd compatible impression events.
+     */
+    private static class StatsCompatImpressionLogger implements StatsImpressionLogger {
+        private final IntArray mResultTypeList = new IntArray();
+        private final IntArray mResultCountList = new IntArray();
+        private final List<Boolean> mAboveKeyboardList = new ArrayList<>();
+        private InstanceId mInstanceId = DEFAULT_INSTANCE_ID;
+        private State mLauncherState = State.UNKNOWN;
+        private int mQueryLength = -1;
+
+        @Override
+        public StatsImpressionLogger withInstanceId(InstanceId instanceId) {
+            this.mInstanceId = instanceId;
+            return this;
+        }
+
+        @Override
+        public StatsImpressionLogger withState(State state) {
+            this.mLauncherState = state;
+            return this;
+        }
+
+        @Override
+        public StatsImpressionLogger withQueryLength(int queryLength) {
+            this.mQueryLength = queryLength;
+            return this;
+        }
+
+        @Override
+        public StatsImpressionLogger withResultType(IntArray resultType) {
+            this.mResultTypeList.clear();
+            this.mResultTypeList.addAll(resultType);
+            return this;
+        }
+
+        @Override
+        public StatsImpressionLogger withResultCount(IntArray resultCount) {
+            this.mResultCountList.clear();
+            this.mResultCountList.addAll(resultCount);
+            return this;
+        }
+
+        @Override
+        public StatsImpressionLogger withAboveKeyboard(List<Boolean> aboveKeyboard) {
+            this.mAboveKeyboardList.clear();
+            this.mAboveKeyboardList.addAll(aboveKeyboard);
+            return this;
+        }
+
+        @Override
+        public void log(EventEnum event) {
+            boolean [] mAboveKeyboard = new boolean[mAboveKeyboardList.size()];
+            for (int i = 0; i < mAboveKeyboardList.size(); i++) {
+                mAboveKeyboard[i] = mAboveKeyboardList.get(i);
+            }
+            if (IS_VERBOSE) {
+                String name = (event instanceof Enum) ? ((Enum) event).name() :
+                        event.getId() + "";
+                StringBuilder logStringBuilder = new StringBuilder("\n");
+                logStringBuilder.append(String.format("InstanceId:%s ", mInstanceId));
+                logStringBuilder.append(String.format("ImpressionEvent:%s ", name));
+                logStringBuilder.append(String.format("LauncherState = %s ", mLauncherState));
+                logStringBuilder.append(String.format("QueryLength = %s ", mQueryLength));
+                for (int i = 0; i < mResultTypeList.size(); i++) {
+                    logStringBuilder.append(String.format(
+                            "\n ResultType = %s with ResultCount = %s with is_above_keyboard = %s",
+                            mResultTypeList.get(i), mResultCountList.get(i),
+                            mAboveKeyboard[i]));
+                }
+                Log.d(IMPRESSION_TAG, logStringBuilder.toString());
+            }
+
+
+
+            SysUiStatsLog.write(SysUiStatsLog.LAUNCHER_IMPRESSION_EVENT,
+                    event.getId(), // event_id
+                    mInstanceId.getId(), // instance_id
+                    mLauncherState.getLauncherState(), // state
+                    mQueryLength, // query_length
+                    //result type list
+                    mResultTypeList.toArray(),
+                    // result count list
+                    mResultCountList.toArray(),
+                    // above keyboard list
+                    mAboveKeyboard
+            );
+        }
+    }
+
     private static int getCardinality(LauncherAtom.ItemInfo info) {
         if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
             return 0;
diff --git a/src/com/android/launcher3/logging/InstanceId.java b/src/com/android/launcher3/logging/InstanceId.java
index 3c4a644..5bbe07c 100644
--- a/src/com/android/launcher3/logging/InstanceId.java
+++ b/src/com/android/launcher3/logging/InstanceId.java
@@ -47,7 +47,6 @@
         this(in.readInt());
     }
 
-    @VisibleForTesting
     public int getId() {
         return mId;
     }
diff --git a/src/com/android/launcher3/logging/StatsLogManager.java b/src/com/android/launcher3/logging/StatsLogManager.java
index fcc5d86..0e42d58 100644
--- a/src/com/android/launcher3/logging/StatsLogManager.java
+++ b/src/com/android/launcher3/logging/StatsLogManager.java
@@ -32,9 +32,12 @@
 import com.android.launcher3.logger.LauncherAtom.FromState;
 import com.android.launcher3.logger.LauncherAtom.ToState;
 import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.util.IntArray;
 import com.android.launcher3.util.ResourceBasedOverride;
 import com.android.launcher3.views.ActivityContext;
 
+import java.util.List;
+
 /**
  * Handles the user event logging in R+.
  *
@@ -839,6 +842,77 @@
     }
 
     /**
+     * Helps to construct and log impression event.
+     */
+    public interface StatsImpressionLogger {
+
+        enum State {
+            UNKNOWN(0),
+            ALLAPPS(1),
+            SEARCHBOX_WIDGET(2);
+            private final int mLauncherState;
+
+            State(int id) {
+                this.mLauncherState = id;
+            }
+
+            public int getLauncherState() {
+                return mLauncherState;
+            }
+        }
+
+        /**
+         * Sets {@link InstanceId} of log message.
+         */
+        default StatsImpressionLogger withInstanceId(InstanceId instanceId) {
+            return this;
+        }
+
+        /**
+         * Sets {@link State} of impression event.
+         */
+        default StatsImpressionLogger withState(State state) {
+            return this;
+        }
+
+        /**
+         * Sets query length of the event.
+         */
+        default StatsImpressionLogger withQueryLength(int queryLength) {
+            return this;
+        }
+
+        /**
+         * Sets list of {@link com.android.app.search.ResultType} for the impression event.
+         */
+        default StatsImpressionLogger withResultType(IntArray resultType) {
+            return this;
+        }
+
+        /**
+         * Sets list of count for each of {@link com.android.app.search.ResultType} for the
+         * impression event.
+         */
+        default StatsImpressionLogger withResultCount(IntArray resultCount) {
+            return this;
+        }
+
+        /**
+         * Sets list of boolean for each of {@link com.android.app.search.ResultType} that indicates
+         * if this result is above keyboard or not for the impression event.
+         */
+        default StatsImpressionLogger withAboveKeyboard(List<Boolean> aboveKeyboard) {
+            return this;
+        }
+
+        /**
+         * Builds the final message and logs it as {@link EventEnum}.
+         */
+        default void log(EventEnum event) {
+        }
+    }
+
+    /**
      * Returns new logger object.
      */
     public StatsLogger logger() {
@@ -861,6 +935,17 @@
     }
 
     /**
+     * Returns new impression logger object.
+     */
+    public StatsImpressionLogger impressionLogger() {
+        StatsImpressionLogger logger = createImpressionLogger();
+        if (mInstanceId != null) {
+            logger.withInstanceId(mInstanceId);
+        }
+        return logger;
+    }
+
+    /**
      * Returns a singleton KeyboardStateManager.
      */
     public KeyboardStateManager keyboardStateManager() {
@@ -880,6 +965,11 @@
         };
     }
 
+    protected StatsImpressionLogger createImpressionLogger() {
+        return new StatsImpressionLogger() {
+        };
+    }
+
     /**
      * Sets InstanceId to every new {@link StatsLogger} object returned by {@link #logger()} when
      * not-null.