port status bar logs to Tron V2

Bug: 33303260
Test: runtest --path frameworks/base/core/tests/coretests/src/com/android/internal/logging/legacy/ && runtest --path frameworks/base/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone
Change-Id: I7746b846247e930617f0b440217635e71ed58bb5
diff --git a/core/java/com/android/internal/logging/legacy/EventLogCollector.java b/core/java/com/android/internal/logging/legacy/EventLogCollector.java
index 46e70ea..598f0d5 100644
--- a/core/java/com/android/internal/logging/legacy/EventLogCollector.java
+++ b/core/java/com/android/internal/logging/legacy/EventLogCollector.java
@@ -45,8 +45,6 @@
 
     private EventLogCollector() {
         mTagParsers = new ArrayMap<>();
-        addParser(new LockscreenGestureParser());
-        addParser(new StatusBarStateParser());
         addParser(new PowerScreenStateParser());
         addParser(new SysuiMultiActionParser());
 
diff --git a/core/java/com/android/internal/logging/legacy/LegacyConversionLogger.java b/core/java/com/android/internal/logging/legacy/LegacyConversionLogger.java
index 91e968b..1209e4d 100644
--- a/core/java/com/android/internal/logging/legacy/LegacyConversionLogger.java
+++ b/core/java/com/android/internal/logging/legacy/LegacyConversionLogger.java
@@ -24,14 +24,6 @@
 
 /** @hide */
 public class LegacyConversionLogger implements TronLogger {
-    public static final String VIEW_KEY = "view";
-    public static final String TYPE_KEY = "type";
-    public static final String EVENT_KEY = "data";
-
-    public static final int TYPE_COUNTER = 1;
-    public static final int TYPE_HISTOGRAM = 2;
-    public static final int TYPE_EVENT = 3;
-
     private final Queue<LogMaker> mQueue;
     private HashMap<String, Boolean> mConfig;
 
diff --git a/core/java/com/android/internal/logging/legacy/LockscreenGestureParser.java b/core/java/com/android/internal/logging/legacy/LockscreenGestureParser.java
deleted file mode 100644
index df08ee0..0000000
--- a/core/java/com/android/internal/logging/legacy/LockscreenGestureParser.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2017 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.internal.logging.legacy;
-
-import android.util.Log;
-
-import android.metrics.LogMaker;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-
-/**
- * Parse the Android lockscreen gesture logs.
- * @hide
- */
-public class LockscreenGestureParser extends TagParser {
-    private static final String TAG = "LockscreenGestureParser";
-    private static final int EVENTLOG_TAG = 36021;
-
-    // source of truth is com.android.systemui.EventLogConstants
-    public static final int[] GESTURE_TYPE_MAP = {
-            MetricsEvent.VIEW_UNKNOWN,  // there is no type 0
-            MetricsEvent.ACTION_LS_UNLOCK,  // SYSUI_LOCKSCREEN_GESTURE_SWIPE_UP_UNLOCK = 1
-            MetricsEvent.ACTION_LS_SHADE,  // SYSUI_LOCKSCREEN_GESTURE_SWIPE_DOWN_FULL_SHADE = 2
-            MetricsEvent.ACTION_LS_HINT,  // SYSUI_LOCKSCREEN_GESTURE_TAP_UNLOCK_HINT = 3
-            MetricsEvent.ACTION_LS_CAMERA,  // SYSUI_LOCKSCREEN_GESTURE_SWIPE_CAMERA = 4
-            MetricsEvent.ACTION_LS_DIALER,  // SYSUI_LOCKSCREEN_GESTURE_SWIPE_DIALER = 5
-            MetricsEvent.ACTION_LS_LOCK,  // SYSUI_LOCKSCREEN_GESTURE_TAP_LOCK = 6
-            MetricsEvent.ACTION_LS_NOTE,  // SYSUI_LOCKSCREEN_GESTURE_TAP_NOTIFICATION_ACTIVATE = 7
-            MetricsEvent.ACTION_LS_QS,  // SYSUI_LOCKSCREEN_GESTURE_SWIPE_DOWN_QS = 8
-            MetricsEvent.ACTION_SHADE_QS_PULL,  // SYSUI_SHADE_GESTURE_SWIPE_DOWN_QS = 9
-            MetricsEvent.ACTION_SHADE_QS_TAP  // SYSUI_TAP_TO_OPEN_QS = 10
-    };
-
-    @Override
-    public int getTag() {
-        return EVENTLOG_TAG;
-    }
-
-    @Override
-    public void parseEvent(TronLogger logger, long eventTimeMs, Object[] operands) {
-        final boolean debug = Util.debug();
-        if (operands.length >= 1) {
-            try {
-                int type = ((Integer) operands[0]).intValue();
-                // ignore gesture length in operands[1]
-                // ignore gesture velocity in operands[2]
-
-                int category = MetricsEvent.VIEW_UNKNOWN;
-                if (type < GESTURE_TYPE_MAP.length) {
-                    category = GESTURE_TYPE_MAP[type];
-                }
-                if (category != MetricsEvent.VIEW_UNKNOWN) {
-                    LogMaker proto = logger.obtain();
-                    proto.setCategory(category);
-                    proto.setType(MetricsEvent.TYPE_ACTION);
-                    proto.setTimestamp(eventTimeMs);
-                    logger.addEvent(proto);
-                }
-            } catch (ClassCastException e) {
-                if (debug) {
-                    Log.e(TAG, "unexpected operand type: ", e);
-                }
-            }
-        } else if (debug) {
-            Log.w(TAG, "wrong number of operands: " + operands.length);
-        }
-    }
-}
diff --git a/core/java/com/android/internal/logging/legacy/StatusBarStateParser.java b/core/java/com/android/internal/logging/legacy/StatusBarStateParser.java
deleted file mode 100644
index 226253f..0000000
--- a/core/java/com/android/internal/logging/legacy/StatusBarStateParser.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2017 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.internal.logging.legacy;
-
-import android.util.Log;
-
-import android.metrics.LogMaker;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-
-/**
- * Parse the Android lockscreen gesture logs.
- * @hide
- */
-public class StatusBarStateParser extends TagParser {
-    private static final String TAG = "StatusBarStateParser";
-    private static final int EVENTLOG_TAG = 36004;
-
-    // source of truth is com.android.systemui.statusbar.StatusBarState
-    public static final int SHADE = 0;
-    public static final int KEYGUARD = 1;
-    public static final int SHADE_LOCKED = 2;
-
-    @Override
-    public int getTag() {
-        return EVENTLOG_TAG;
-    }
-
-    @Override
-    public void parseEvent(TronLogger logger, long eventTimeMs, Object[] operands) {
-        final boolean debug = Util.debug();
-        if (operands.length >= 6) {
-            try {
-                // [state, isShowing, isOccluded, isBouncerShowing, isSecure, isCurrentlyInsecure]
-                int state = ((Integer) operands[0]).intValue();
-                boolean isBouncerShowing = (((Integer) operands[3]).intValue()) == 1;
-                int isSecure = ((Integer) operands[4]).intValue();
-
-                int view = MetricsEvent.LOCKSCREEN;
-                int type = MetricsEvent.TYPE_OPEN;
-                if (state == SHADE) {
-                    type = MetricsEvent.TYPE_CLOSE;
-                } else if (isBouncerShowing) {
-                    view = MetricsEvent.BOUNCER;
-                }
-
-                LogMaker proto = logger.obtain();
-                proto.setCategory(view);
-                proto.setType(type);
-                proto.setTimestamp(eventTimeMs);
-                proto.setSubtype(isSecure);
-                logger.addEvent(proto);
-            } catch (ClassCastException e) {
-                if (debug) {
-                    Log.e(TAG, "unexpected operand type: ", e);
-                }
-            }
-        } else if (debug) {
-            Log.w(TAG, "wrong number of operands: " + operands.length);
-        }
-    }
-}
diff --git a/core/tests/coretests/src/com/android/internal/logging/legacy/LockscreenGestureParserTest.java b/core/tests/coretests/src/com/android/internal/logging/legacy/LockscreenGestureParserTest.java
deleted file mode 100644
index c023b57..0000000
--- a/core/tests/coretests/src/com/android/internal/logging/legacy/LockscreenGestureParserTest.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2017 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.internal.logging.legacy;
-
-import static org.mockito.Matchers.anyObject;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import android.metrics.LogMaker;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-
-public class LockscreenGestureParserTest extends ParserTest {
-
-    public LockscreenGestureParserTest() {
-        mParser = new LockscreenGestureParser();
-    }
-
-    public void testSwipeUpUnlock() throws Throwable {
-        validate(MetricsEvent.ACTION_LS_UNLOCK, 1, 359, 6382);
-    }
-
-    public void testSwipeToShade() throws Throwable {
-        validate(MetricsEvent.ACTION_LS_SHADE, 2, 324, 0);
-    }
-
-    public void testTapLockHint() throws Throwable {
-        validate(MetricsEvent.ACTION_LS_HINT, 3, 0, 0);
-    }
-
-    public void testCamera() throws Throwable {
-        validate(MetricsEvent.ACTION_LS_CAMERA, 4, 223, 1756);
-    }
-
-    public void testDialer() throws Throwable {
-        validate(MetricsEvent.ACTION_LS_DIALER, 5, 163, 861);
-    }
-
-    public void testTapToLock() throws Throwable {
-        validate(MetricsEvent.ACTION_LS_LOCK, 6, 0, 0);
-    }
-
-    public void testTapOnNotification() throws Throwable {
-        validate(MetricsEvent.ACTION_LS_NOTE, 7, 0, 0);
-    }
-
-    public void testLockscreenQuickSettings() throws Throwable {
-        validate(MetricsEvent.ACTION_LS_QS, 8, 284, 3824);
-    }
-
-    public void testShadePullQuickSettings() throws Throwable {
-        validate(MetricsEvent.ACTION_SHADE_QS_PULL, 9, 175, 3444);
-    }
-
-    public void testShadeTapQuickSettings() throws Throwable {
-        validate(MetricsEvent.ACTION_SHADE_QS_TAP, 10, 0, 0);
-    }
-
-    private void validate(int view, int type, int len, int vel) {
-        int t = 1000;
-        Object[] objects = new Object[3];
-        objects[0] = type;
-        objects[1] = len;
-        objects[2] = vel;
-
-        mParser.parseEvent(mLogger, t, objects);
-
-        verify(mLogger, times(1)).addEvent(mProtoCaptor.capture());
-
-        LogMaker proto = mProtoCaptor.getValue();
-        assertEquals(t, proto.getTimestamp());
-        assertEquals(view, proto.getCategory());
-        assertEquals(MetricsEvent.TYPE_ACTION, proto.getType());
-    }
-
-    public void testIgnoreUnexpectedData() throws Throwable {
-        int t = 1000;
-        Object[] objects = new Object[4];
-        objects[0] = 1;
-        objects[1] = 0;
-        objects[2] = 0;
-        objects[3] = "foo";
-
-        mParser.parseEvent(mLogger, t, objects);
-
-        verify(mLogger, times(1)).addEvent((LogMaker) anyObject());
-    }
-}
diff --git a/core/tests/coretests/src/com/android/internal/logging/legacy/StatusBarStateParserTest.java b/core/tests/coretests/src/com/android/internal/logging/legacy/StatusBarStateParserTest.java
deleted file mode 100644
index def9628..0000000
--- a/core/tests/coretests/src/com/android/internal/logging/legacy/StatusBarStateParserTest.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2017 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.internal.logging.legacy;
-
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-
-import android.metrics.LogMaker;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-
-public class StatusBarStateParserTest extends ParserTest {
-
-    public StatusBarStateParserTest() {
-        mParser = new StatusBarStateParser();
-    }
-
-    public void testLockScreen() throws Throwable {
-        validate(MetricsEvent.LOCKSCREEN, MetricsEvent.TYPE_OPEN, 1, "1,1,0,0,1,0");
-    }
-
-    public void testBounce() throws Throwable {
-        validate(MetricsEvent.BOUNCER, MetricsEvent.TYPE_OPEN, 1, "1,1,0,1,1,0");
-    }
-
-    public void testUnlock() throws Throwable {
-        validate(MetricsEvent.LOCKSCREEN, MetricsEvent.TYPE_CLOSE, 1, "0,0,0,0,1,0");
-    }
-
-    public void testSecure() throws Throwable {
-        validate(MetricsEvent.BOUNCER, MetricsEvent.TYPE_OPEN, 1, "2,1,0,1,1,0");
-    }
-
-    public void testInsecure() throws Throwable {
-        validate(MetricsEvent.LOCKSCREEN, MetricsEvent.TYPE_OPEN, 0, "1,1,0,0,0,0");
-    }
-
-    public void testIgnoreUnexpectedData() throws Throwable {
-        validate(MetricsEvent.LOCKSCREEN, MetricsEvent.TYPE_OPEN, 0, "1,1,0,0,0,0,5");
-    }
-
-    private void validate(int view, int type, int subType, String log) {
-        String[] parts = log.split(",");
-        int t = 1000;
-        Object[] objects = new Object[parts.length];
-        for (int i = 0; i < parts.length; i++) {
-            objects[i] = Integer.valueOf(parts[i]);
-        }
-
-        mParser.parseEvent(mLogger, t, objects);
-
-        verify(mLogger, times(1)).addEvent(mProtoCaptor.capture());
-
-        LogMaker proto = mProtoCaptor.getValue();
-        assertEquals(t, proto.getTimestamp());
-        assertEquals(view, proto.getCategory());
-        assertEquals(type, proto.getType());
-        assertEquals(subType, proto.getSubtype());
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/EventLogConstants.java b/packages/SystemUI/src/com/android/systemui/EventLogConstants.java
index 9238928..def3c40 100644
--- a/packages/SystemUI/src/com/android/systemui/EventLogConstants.java
+++ b/packages/SystemUI/src/com/android/systemui/EventLogConstants.java
@@ -16,30 +16,46 @@
 
 package com.android.systemui;
 
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+
 /**
  * Constants to be passed as sysui_* eventlog parameters.
  */
 public class EventLogConstants {
     /** The user swiped up on the lockscreen, unlocking the device. */
-    public static final int SYSUI_LOCKSCREEN_GESTURE_SWIPE_UP_UNLOCK = 1;
+    private static final int SYSUI_LOCKSCREEN_GESTURE_SWIPE_UP_UNLOCK = 1;
     /** The user swiped down on the lockscreen, going to the full shade. */
-    public static final int SYSUI_LOCKSCREEN_GESTURE_SWIPE_DOWN_FULL_SHADE = 2;
+    private static final int SYSUI_LOCKSCREEN_GESTURE_SWIPE_DOWN_FULL_SHADE = 2;
     /** The user tapped in an empty area, causing the unlock hint to be shown. */
-    public static final int SYSUI_LOCKSCREEN_GESTURE_TAP_UNLOCK_HINT = 3;
+    private static final int SYSUI_LOCKSCREEN_GESTURE_TAP_UNLOCK_HINT = 3;
     /** The user swiped inward on the camera icon, launching the camera. */
-    public static final int SYSUI_LOCKSCREEN_GESTURE_SWIPE_CAMERA = 4;
+    private static final int SYSUI_LOCKSCREEN_GESTURE_SWIPE_CAMERA = 4;
     /** The user swiped inward on the dialer icon, launching the dialer. */
-    public static final int SYSUI_LOCKSCREEN_GESTURE_SWIPE_DIALER = 5;
+    private static final int SYSUI_LOCKSCREEN_GESTURE_SWIPE_DIALER = 5;
     /** The user tapped the lock, locking the device. */
-    public static final int SYSUI_LOCKSCREEN_GESTURE_TAP_LOCK = 6;
+    private static final int SYSUI_LOCKSCREEN_GESTURE_TAP_LOCK = 6;
     /** The user tapped a notification, needs to tap again to launch. */
-    public static final int SYSUI_LOCKSCREEN_GESTURE_TAP_NOTIFICATION_ACTIVATE = 7;
+    private static final int SYSUI_LOCKSCREEN_GESTURE_TAP_NOTIFICATION_ACTIVATE = 7;
     /** The user swiped down to open quick settings, from keyguard. */
-    public static final int SYSUI_LOCKSCREEN_GESTURE_SWIPE_DOWN_QS = 8;
+    private static final int SYSUI_LOCKSCREEN_GESTURE_SWIPE_DOWN_QS = 8;
     /** The user swiped down to open quick settings, from shade. */
-    public static final int SYSUI_SHADE_GESTURE_SWIPE_DOWN_QS = 9;
+    private static final int SYSUI_SHADE_GESTURE_SWIPE_DOWN_QS = 9;
     /** The user tapped on the status bar to open quick settings, from shade. */
-    public static final int SYSUI_TAP_TO_OPEN_QS = 10;
+    private static final int SYSUI_TAP_TO_OPEN_QS = 10;
+
+    public static final int[] METRICS_GESTURE_TYPE_MAP = {
+            MetricsEvent.VIEW_UNKNOWN,         // there is no type 0
+            MetricsEvent.ACTION_LS_UNLOCK,     // SYSUI_LOCKSCREEN_GESTURE_SWIPE_UP_UNLOCK
+            MetricsEvent.ACTION_LS_SHADE,      // SYSUI_LOCKSCREEN_GESTURE_SWIPE_DOWN_FULL_SHADE
+            MetricsEvent.ACTION_LS_HINT,       // SYSUI_LOCKSCREEN_GESTURE_TAP_UNLOCK_HINT
+            MetricsEvent.ACTION_LS_CAMERA,     // SYSUI_LOCKSCREEN_GESTURE_SWIPE_CAMERA
+            MetricsEvent.ACTION_LS_DIALER,     // SYSUI_LOCKSCREEN_GESTURE_SWIPE_DIALER
+            MetricsEvent.ACTION_LS_LOCK,       // SYSUI_LOCKSCREEN_GESTURE_TAP_LOCK
+            MetricsEvent.ACTION_LS_NOTE,       // SYSUI_LOCKSCREEN_GESTURE_TAP_NOTIFICATION_ACTIVATE
+            MetricsEvent.ACTION_LS_QS,         // SYSUI_LOCKSCREEN_GESTURE_SWIPE_DOWN_QS
+            MetricsEvent.ACTION_SHADE_QS_PULL, // SYSUI_SHADE_GESTURE_SWIPE_DOWN_QS
+            MetricsEvent.ACTION_SHADE_QS_TAP   // SYSUI_TAP_TO_OPEN_QS
+    };
 
     /** Secondary user tries binding to the system sysui service */
     public static final int SYSUI_RECENTS_CONNECTION_USER_BIND_SERVICE = 1;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index bfc0a80..d27f38e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -35,6 +35,7 @@
 import android.content.pm.ActivityInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
+import android.content.res.AssetFileDescriptor.AutoCloseOutputStream;
 import android.content.res.Configuration;
 import android.graphics.drawable.Drawable;
 import android.os.AsyncTask;
@@ -58,6 +59,7 @@
 import android.widget.FrameLayout;
 import android.widget.TextView;
 
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
@@ -164,6 +166,7 @@
     private IntentButton mLeftDefault = mLeftButton;
     private IntentButton mLeftPlugin;
     private String mLeftButtonStr;
+    private LockscreenGestureLogger mLockscreenGestureLogger = new LockscreenGestureLogger();
 
     public KeyguardBottomAreaView(Context context) {
         this(context, null);
@@ -445,8 +448,7 @@
     }
 
     private void handleTrustCircleClick() {
-        EventLogTags.writeSysuiLockscreenGesture(
-                EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_TAP_LOCK, 0 /* lengthDp - N/A */,
+        mLockscreenGestureLogger.write(MetricsEvent.ACTION_LS_LOCK, 0 /* lengthDp - N/A */,
                 0 /* velocityDp - N/A */);
         mIndicationController.showTransientIndication(
                 R.string.keyguard_indication_trust_disabled);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenGestureLogger.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenGestureLogger.java
new file mode 100644
index 0000000..83b96bf
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenGestureLogger.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2017 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.systemui.statusbar.phone;
+
+import android.metrics.LogMaker;
+import android.util.ArrayMap;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.systemui.EventLogConstants;
+import com.android.systemui.EventLogTags;
+
+/**
+ * Wrapper that emits both new- and old-style gesture logs.
+ * TODO: delete this once the old logs are no longer needed.
+ */
+public class LockscreenGestureLogger {
+    private ArrayMap<Integer, Integer> mLegacyMap;
+    private LogMaker mLogMaker = new LogMaker(MetricsEvent.VIEW_UNKNOWN)
+            .setType(MetricsEvent.TYPE_ACTION);
+
+    public LockscreenGestureLogger() {
+        mLegacyMap = new ArrayMap<>(EventLogConstants.METRICS_GESTURE_TYPE_MAP.length);
+        for (int i = 0; i < EventLogConstants.METRICS_GESTURE_TYPE_MAP.length ; i++) {
+            mLegacyMap.put(EventLogConstants.METRICS_GESTURE_TYPE_MAP[i], i);
+        }
+    }
+
+    public void write(int gesture, int length, int velocity) {
+        MetricsLogger.action(mLogMaker.setCategory(gesture)
+                .setType(MetricsEvent.TYPE_ACTION)
+                .addTaggedData(MetricsEvent.FIELD_GESTURE_LENGTH, length)
+                .addTaggedData(MetricsEvent.FIELD_GESTURE_VELOCITY, velocity));
+        // also write old-style logs for backward-0compatibility
+        EventLogTags.writeSysuiLockscreenGesture(safeLookup(gesture), length, velocity);
+    }
+
+    private int safeLookup(int gesture) {
+        Integer value = mLegacyMap.get(gesture);
+        if (value == null) {
+            return MetricsEvent.VIEW_UNKNOWN;
+        }
+        return value;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index fe7e915..ffd1d80 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -43,6 +43,7 @@
 import android.widget.TextView;
 
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.keyguard.KeyguardStatusView;
 import com.android.systemui.DejankUtils;
 import com.android.systemui.EventLogConstants;
@@ -212,6 +213,7 @@
     private int mIndicationBottomPadding;
     private boolean mIsFullWidth;
     private boolean mDark;
+    private LockscreenGestureLogger mLockscreenGestureLogger = new LockscreenGestureLogger();
 
     public NotificationPanelView(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -710,10 +712,9 @@
     private void logQsSwipeDown(float y) {
         float vel = getCurrentQSVelocity();
         final int gesture = mStatusBarState == StatusBarState.KEYGUARD
-                ? EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_SWIPE_DOWN_QS
-                : EventLogConstants.SYSUI_SHADE_GESTURE_SWIPE_DOWN_QS;
-        EventLogTags.writeSysuiLockscreenGesture(
-                gesture,
+                ? MetricsEvent.ACTION_LS_QS
+                : MetricsEvent.ACTION_SHADE_QS_PULL;
+        mLockscreenGestureLogger.write(gesture,
                 (int) ((y - mInitialTouchY) / mStatusBar.getDisplayDensity()),
                 (int) (vel / mStatusBar.getDisplayDensity()));
     }
@@ -1819,9 +1820,7 @@
             if (mQsExpanded) {
                 flingSettings(0 /* vel */, false /* expand */, null, true /* isClick */);
             } else if (mQsExpansionEnabled) {
-                EventLogTags.writeSysuiLockscreenGesture(
-                        EventLogConstants.SYSUI_TAP_TO_OPEN_QS,
-                        0, 0);
+                mLockscreenGestureLogger.write(MetricsEvent.ACTION_SHADE_QS_TAP, 0, 0);
                 flingSettings(0 /* vel */, true /* expand */, null, true /* isClick */);
             }
         }
@@ -1836,8 +1835,7 @@
         int lengthDp = Math.abs((int) (translation / displayDensity));
         int velocityDp = Math.abs((int) (vel / displayDensity));
         if (start) {
-            EventLogTags.writeSysuiLockscreenGesture(
-                    EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_SWIPE_DIALER, lengthDp, velocityDp);
+            mLockscreenGestureLogger.write(MetricsEvent.ACTION_LS_DIALER, lengthDp, velocityDp);
 
             mFalsingManager.onLeftAffordanceOn();
             if (mFalsingManager.shouldEnforceBouncer()) {
@@ -1855,9 +1853,7 @@
         } else {
             if (KeyguardBottomAreaView.CAMERA_LAUNCH_SOURCE_AFFORDANCE.equals(
                     mLastCameraLaunchSource)) {
-                EventLogTags.writeSysuiLockscreenGesture(
-                        EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_SWIPE_CAMERA,
-                        lengthDp, velocityDp);
+                mLockscreenGestureLogger.write(MetricsEvent.ACTION_LS_CAMERA, lengthDp, velocityDp);
             }
             mFalsingManager.onCameraOn();
             if (mFalsingManager.shouldEnforceBouncer()) {
@@ -2152,8 +2148,8 @@
         switch (mStatusBar.getBarState()) {
             case StatusBarState.KEYGUARD:
                 if (!mDozingOnDown) {
-                    EventLogTags.writeSysuiLockscreenGesture(
-                            EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_TAP_UNLOCK_HINT,
+                    mLockscreenGestureLogger.write(
+                            MetricsEvent.ACTION_LS_HINT,
                             0 /* lengthDp - N/A */, 0 /* velocityDp - N/A */);
                     startUnlockHintAnimation();
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index 5f67468..fa74cc1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -33,6 +33,7 @@
 import android.view.animation.Interpolator;
 import android.widget.FrameLayout;
 
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.systemui.DejankUtils;
 import com.android.systemui.EventLogConstants;
 import com.android.systemui.EventLogTags;
@@ -55,6 +56,7 @@
     private static final int PEEK_ANIMATION_DURATION = 360;
     private long mDownTime;
     private float mMinExpandHeight;
+    private LockscreenGestureLogger mLockscreenGestureLogger = new LockscreenGestureLogger();
 
     private final void logf(String fmt, Object... args) {
         Log.v(TAG, (mViewName != null ? (mViewName + ": ") : "") + String.format(fmt, args));
@@ -423,8 +425,8 @@
                         float displayDensity = mStatusBar.getDisplayDensity();
                         int heightDp = (int) Math.abs((y - mInitialTouchY) / displayDensity);
                         int velocityDp = (int) Math.abs(vel / displayDensity);
-                        EventLogTags.writeSysuiLockscreenGesture(
-                                EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_SWIPE_UP_UNLOCK,
+                        mLockscreenGestureLogger.write(
+                                MetricsEvent.ACTION_LS_UNLOCK,
                                 heightDp, velocityDp);
                     }
             fling(vel, expand, isFalseTouch(x, y));
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 270476e..b385835 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -69,6 +69,7 @@
 import android.media.session.MediaSession;
 import android.media.session.MediaSessionManager;
 import android.media.session.PlaybackState;
+import android.metrics.LogMaker;
 import android.net.Uri;
 import android.os.AsyncTask;
 import android.os.Bundle;
@@ -406,7 +407,7 @@
     protected PhoneStatusBarView mStatusBarView;
     private int mStatusBarWindowState = WINDOW_STATE_SHOWING;
     protected StatusBarWindowManager mStatusBarWindowManager;
-    private UnlockMethodCache mUnlockMethodCache;
+    protected UnlockMethodCache mUnlockMethodCache;
     private DozeServiceHost mDozeServiceHost;
     private boolean mWakeUpComingFromTouch;
     private PointF mWakeUpTouchLocation;
@@ -706,6 +707,8 @@
     private NetworkController mNetworkController;
     private KeyguardMonitorImpl mKeyguardMonitor;
     private BatteryController mBatteryController;
+    private LogMaker mStatusBarStateLog;
+    private LockscreenGestureLogger mLockscreenGestureLogger = new LockscreenGestureLogger();
 
     private void recycleAllVisibilityObjects(ArraySet<NotificationVisibility> array) {
         final int N = array.size();
@@ -3828,6 +3831,13 @@
                 isSecure,
                 canSkipBouncer);
         if (stateFingerprint != mLastLoggedStateFingerprint) {
+            if (mStatusBarStateLog == null) {
+                mStatusBarStateLog = new LogMaker(MetricsEvent.VIEW_UNKNOWN);
+            }
+            MetricsLogger.action(mStatusBarStateLog
+                    .setCategory(isBouncerShowing ? MetricsEvent.BOUNCER : MetricsEvent.LOCKSCREEN)
+                    .setType(isShowing ? MetricsEvent.TYPE_OPEN : MetricsEvent.TYPE_CLOSE)
+                    .setSubtype(isSecure ? 1 : 0));
             EventLogTags.writeSysuiStatusBarState(mState,
                     isShowing ? 1 : 0,
                     isOccluded ? 1 : 0,
@@ -4508,8 +4518,8 @@
 
     @Override
     public void onActivated(ActivatableNotificationView view) {
-        EventLogTags.writeSysuiLockscreenGesture(
-                EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_TAP_NOTIFICATION_ACTIVATE,
+        mLockscreenGestureLogger.write(
+                MetricsEvent.ACTION_LS_NOTE,
                 0 /* lengthDp - N/A */, 0 /* velocityDp - N/A */);
         mKeyguardIndicationController.showTransientIndication(R.string.notification_tap_again);
         ActivatableNotificationView previousView = mStackScroller.getActivatedChild();
@@ -4626,8 +4636,8 @@
     @Override
     public boolean onDraggedDown(View startingChild, int dragLengthY) {
         if (hasActiveNotifications() && (!isDozing() || isPulsing())) {
-            EventLogTags.writeSysuiLockscreenGesture(
-                    EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_SWIPE_DOWN_FULL_SHADE,
+            mLockscreenGestureLogger.write(
+                    MetricsEvent.ACTION_LS_SHADE,
                     (int) (dragLengthY / mDisplayMetrics.density),
                     0 /* velocityDp - N/A */);
 
diff --git a/packages/SystemUI/tests/Android.mk b/packages/SystemUI/tests/Android.mk
index c627e22..cefade0 100644
--- a/packages/SystemUI/tests/Android.mk
+++ b/packages/SystemUI/tests/Android.mk
@@ -43,6 +43,7 @@
     android-support-v17-leanback
 
 LOCAL_STATIC_JAVA_LIBRARIES := \
+    metrics-helper-lib \
     android-support-test \
     mockito-updated-target-minus-junit4 \
     SystemUI-proto \
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index 309559b..21c7fce 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -22,11 +22,20 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
+import android.metrics.LogMaker;
+import android.metrics.MetricsReader;
 import android.support.test.filters.SmallTest;
+import android.support.test.metricshelper.MetricsAsserts;
 import android.support.test.runner.AndroidJUnit4;
+import android.util.DisplayMetrics;
 
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.keyguard.KeyguardHostView.OnDismissAction;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.statusbar.ActivatableNotificationView;
+import com.android.systemui.statusbar.KeyguardIndicationController;
+import com.android.systemui.statusbar.NotificationData;
+import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -37,12 +46,22 @@
 public class StatusBarTest extends SysuiTestCase {
 
     StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
+    UnlockMethodCache mUnlockMethodCache;
+    KeyguardIndicationController mKeyguardIndicationController;
+    NotificationStackScrollLayout mStackScroller;
     StatusBar mStatusBar;
 
+    private MetricsReader mMetricsReader;
+    private DisplayMetrics mDisplayMetrics = new DisplayMetrics();
+
     @Before
     public void setup() {
         mStatusBarKeyguardViewManager = mock(StatusBarKeyguardViewManager.class);
-        mStatusBar = new TestableStatusBar(mStatusBarKeyguardViewManager);
+        mUnlockMethodCache = mock(UnlockMethodCache.class);
+        mKeyguardIndicationController = mock(KeyguardIndicationController.class);
+        mStackScroller = mock(NotificationStackScrollLayout.class);
+        mStatusBar = new TestableStatusBar(mStatusBarKeyguardViewManager, mUnlockMethodCache,
+                mKeyguardIndicationController, mStackScroller);
 
         doAnswer(invocation -> {
             OnDismissAction onDismissAction = (OnDismissAction) invocation.getArguments()[0];
@@ -55,6 +74,11 @@
             runnable.run();
             return null;
         }).when(mStatusBarKeyguardViewManager).addAfterKeyguardGoneRunnable(any());
+
+        when(mStackScroller.getActivatedChild()).thenReturn(null);
+
+        mMetricsReader = new MetricsReader();
+        mMetricsReader.checkpoint(); // clear out old logs
     }
 
     @Test
@@ -81,9 +105,114 @@
         mStatusBar.executeRunnableDismissingKeyguard(null, null, false, false, false);
     }
 
+    @Test
+    public void lockscreenStateMetrics_notShowing() {
+        // uninteresting state, except that fingerprint must be non-zero
+        when(mStatusBarKeyguardViewManager.isOccluded()).thenReturn(false);
+        when(mUnlockMethodCache.canSkipBouncer()).thenReturn(true);
+        // interesting state
+        when(mStatusBarKeyguardViewManager.isShowing()).thenReturn(false);
+        when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
+        when(mUnlockMethodCache.isMethodSecure()).thenReturn(false);
+
+        mStatusBar.onKeyguardViewManagerStatesUpdated();
+
+        MetricsAsserts.assertHasLog("missing hidden insecure lockscreen log", mMetricsReader,
+                new LogMaker(MetricsEvent.LOCKSCREEN)
+                        .setType(MetricsEvent.TYPE_CLOSE)
+                        .setSubtype(0));
+    }
+
+    @Test
+    public void lockscreenStateMetrics_notShowing_secure() {
+        // uninteresting state, except that fingerprint must be non-zero
+        when(mStatusBarKeyguardViewManager.isOccluded()).thenReturn(false);
+        when(mUnlockMethodCache.canSkipBouncer()).thenReturn(true);
+        // interesting state
+        when(mStatusBarKeyguardViewManager.isShowing()).thenReturn(false);
+        when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
+        when(mUnlockMethodCache.isMethodSecure()).thenReturn(true);
+
+        mStatusBar.onKeyguardViewManagerStatesUpdated();
+
+        MetricsAsserts.assertHasLog("missing hidden secure lockscreen log", mMetricsReader,
+                new LogMaker(MetricsEvent.LOCKSCREEN)
+                        .setType(MetricsEvent.TYPE_CLOSE)
+                        .setSubtype(1));
+    }
+
+    @Test
+    public void lockscreenStateMetrics_isShowing() {
+        // uninteresting state, except that fingerprint must be non-zero
+        when(mStatusBarKeyguardViewManager.isOccluded()).thenReturn(false);
+        when(mUnlockMethodCache.canSkipBouncer()).thenReturn(true);
+        // interesting state
+        when(mStatusBarKeyguardViewManager.isShowing()).thenReturn(true);
+        when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
+        when(mUnlockMethodCache.isMethodSecure()).thenReturn(false);
+
+        mStatusBar.onKeyguardViewManagerStatesUpdated();
+
+        MetricsAsserts.assertHasLog("missing insecure lockscreen showing", mMetricsReader,
+                new LogMaker(MetricsEvent.LOCKSCREEN)
+                        .setType(MetricsEvent.TYPE_OPEN)
+                        .setSubtype(0));
+    }
+
+    @Test
+    public void lockscreenStateMetrics_isShowing_secure() {
+        // uninteresting state, except that fingerprint must be non-zero
+        when(mStatusBarKeyguardViewManager.isOccluded()).thenReturn(false);
+        when(mUnlockMethodCache.canSkipBouncer()).thenReturn(true);
+        // interesting state
+        when(mStatusBarKeyguardViewManager.isShowing()).thenReturn(true);
+        when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
+        when(mUnlockMethodCache.isMethodSecure()).thenReturn(true);
+
+        mStatusBar.onKeyguardViewManagerStatesUpdated();
+
+        MetricsAsserts.assertHasLog("missing secure lockscreen showing log", mMetricsReader,
+                new LogMaker(MetricsEvent.LOCKSCREEN)
+                        .setType(MetricsEvent.TYPE_OPEN)
+                        .setSubtype(1));
+    }
+
+    @Test
+    public void lockscreenStateMetrics_isShowingBouncer() {
+        // uninteresting state, except that fingerprint must be non-zero
+        when(mStatusBarKeyguardViewManager.isOccluded()).thenReturn(false);
+        when(mUnlockMethodCache.canSkipBouncer()).thenReturn(true);
+        // interesting state
+        when(mStatusBarKeyguardViewManager.isShowing()).thenReturn(true);
+        when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(true);
+        when(mUnlockMethodCache.isMethodSecure()).thenReturn(true);
+
+        mStatusBar.onKeyguardViewManagerStatesUpdated();
+
+        MetricsAsserts.assertHasLog("missing bouncer log", mMetricsReader,
+                new LogMaker(MetricsEvent.BOUNCER)
+                        .setType(MetricsEvent.TYPE_OPEN)
+                        .setSubtype(1));
+    }
+
+    @Test
+    public void onActivatedMetrics() {
+        ActivatableNotificationView view =  mock(ActivatableNotificationView.class);
+        mStatusBar.onActivated(view);
+
+        MetricsAsserts.assertHasLog("missing lockscreen note tap log", mMetricsReader,
+                new LogMaker(MetricsEvent.ACTION_LS_NOTE)
+                        .setType(MetricsEvent.TYPE_ACTION));
+    }
+
     static class TestableStatusBar extends StatusBar {
-        public TestableStatusBar(StatusBarKeyguardViewManager man) {
+        public TestableStatusBar(StatusBarKeyguardViewManager man,
+                UnlockMethodCache unlock, KeyguardIndicationController key,
+                NotificationStackScrollLayout stack) {
             mStatusBarKeyguardViewManager = man;
+            mUnlockMethodCache = unlock;
+            mKeyguardIndicationController = key;
+            mStackScroller = stack;
         }
 
         @Override
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index 59d982a..a590805 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -3275,7 +3275,6 @@
     // OPEN: Settings > Apps > Default Apps > Warning dialog to confirm selection
     DEFAULT_APP_PICKER_CONFIRMATION_DIALOG = 791;
 
-
     // OPEN: Settings > Apps > Default Apps > Default autofill app
     DEFAULT_AUTOFILL_PICKER = 792;
 
@@ -3352,7 +3351,8 @@
     BACKUP_SETTINGS = 818;
 
     // ACTION: Picture-in-picture was explicitly entered for an activity
-    // VALUE: true if it was entered while hiding as a result of moving to another task, false otherwise
+    // VALUE: true if it was entered while hiding as a result of moving to
+    // another task, false otherwise
     ACTION_PICTURE_IN_PICTURE_ENTERED = 819;
 
     // ACTION: The activity currently in picture-in-picture was expanded back to fullscreen
@@ -3378,6 +3378,16 @@
     // The current aspect ratio of the PiP, logged when it changes.
     PICTURE_IN_PICTURE_ASPECT_RATIO = 825;
 
+    // FIELD - length in dp of ACTION_LS_* gestures, or zero if not applicable
+    // CATEGORY: GLOBAL_SYSTEM_UI
+    // OS: O
+    FIELD_GESTURE_LENGTH = 826;
+
+    // FIELD - velocity in dp (per second?) of ACTION_LS_* gestures, or zero if not applicable
+    // CATEGORY: GLOBAL_SYSTEM_UI
+    // OS: O
+    FIELD_GESTURE_VELOCITY = 827;
+
     // ---- End O Constants, all O constants go above this line ----
 
     // Add new aosp constants above this line.