Add metrics for nav buttons through KeyButtonView

Doesn't cover home-long-press or overview, but those appear to be
covered by other events.

Test: runtest systemui
Change-Id: I590b52765aaef3c2bf573ce8ab980aa992b1d5b0
Fixes: 25931698
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
index b5d22b1..d777961 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
@@ -24,6 +24,7 @@
 import android.graphics.drawable.Icon;
 import android.hardware.input.InputManager;
 import android.media.AudioManager;
+import android.metrics.LogMaker;
 import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.SystemClock;
@@ -41,6 +42,9 @@
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.widget.ImageView;
 
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.plugins.statusbar.phone.NavBarButtonProvider.ButtonInterface;
 
@@ -60,6 +64,7 @@
     private boolean mLongClicked;
     private OnClickListener mOnClickListener;
     private final KeyButtonRipple mRipple;
+    private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class);
 
     private final Runnable mCheckLongPress = new Runnable() {
         public void run() {
@@ -252,6 +257,11 @@
     }
 
     void sendEvent(int action, int flags, long when) {
+        mMetricsLogger.write(new LogMaker(MetricsEvent.ACTION_NAV_BUTTON_EVENT)
+                .setType(MetricsEvent.TYPE_ACTION)
+                .setSubtype(mCode)
+                .addTaggedData(MetricsEvent.FIELD_NAV_ACTION, action)
+                .addTaggedData(MetricsEvent.FIELD_FLAGS, flags));
         final int repeatCount = (flags & KeyEvent.FLAG_LONG_PRESS) != 0 ? 1 : 0;
         final KeyEvent ev = new KeyEvent(mDownTime, when, action, mCode, repeatCount,
                 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyButtonViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyButtonViewTest.java
new file mode 100644
index 0000000..21fddf2
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyButtonViewTest.java
@@ -0,0 +1,91 @@
+/*
+ * 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.policy;
+
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_NAV_BUTTON_EVENT;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_FLAGS;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_NAV_ACTION;
+
+import static org.mockito.ArgumentMatchers.argThat;
+
+import android.metrics.LogMaker;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.testing.TestableLooper.RunWithLooper;
+import android.view.KeyEvent;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentMatcher;
+import org.mockito.Mockito;
+
+import java.util.Objects;
+
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper
+public class KeyButtonViewTest extends SysuiTestCase {
+
+    private KeyButtonView mKeyButtonView;
+    private MetricsLogger mMetricsLogger;
+
+    @Before
+    public void setup() throws Exception {
+        mMetricsLogger = mDependency.injectMockDependency(MetricsLogger.class);
+        TestableLooper.get(this).runWithLooper(() ->
+                mKeyButtonView = new KeyButtonView(mContext, null));
+    }
+
+    @Test
+    public void testMetrics() {
+        int action = 42;
+        int flags = 0x141;
+        int code = KeyEvent.KEYCODE_ENTER;
+        mKeyButtonView.setCode(code);
+        mKeyButtonView.sendEvent(action, flags);
+
+        Mockito.verify(mMetricsLogger).write(argThat(new ArgumentMatcher<LogMaker>() {
+            public String mReason;
+
+            @Override
+            public boolean matches(LogMaker argument) {
+                return checkField("category", argument.getCategory(), ACTION_NAV_BUTTON_EVENT)
+                        && checkField("type", argument.getType(), MetricsEvent.TYPE_ACTION)
+                        && checkField("subtype", argument.getSubtype(), code)
+                        && checkField("FIELD_FLAGS", argument.getTaggedData(FIELD_FLAGS), flags)
+                        && checkField("FIELD_NAV_ACTION", argument.getTaggedData(FIELD_NAV_ACTION),
+                                action);
+            }
+
+            private boolean checkField(String field, Object val, Object val2) {
+                if (!Objects.equals(val, val2)) {
+                    mReason = "Expected " + field + " " + val2 + " but was " + val;
+                    return false;
+                }
+                return true;
+            }
+
+            @Override
+            public String toString() {
+                return mReason;
+            }
+        }));
+    }
+
+}
\ No newline at end of file
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index 04b6091..d4d7672 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -3892,12 +3892,21 @@
     // ACTION: QS -> Click date
     ACTION_QS_DATE = 930;
 
+    // ACTION: Event on nav button
+    ACTION_NAV_BUTTON_EVENT = 931;
+
+    // FIELD: Flags for a nav button event
+    FIELD_FLAGS = 932;
+
+    // FIELD: Action for a nav button event
+    FIELD_NAV_ACTION = 933;
+
+    // ---- End O Constants, all O constants go above this line ----
+
     // OPEN: Settings > Storage > Movies & TV
     // CATEGORY: SETTINGS
     // OS: O
-    APPLICATIONS_STORAGE_MOVIES = 931;
-
-    // ---- End O Constants, all O constants go above this line ----
+    APPLICATIONS_STORAGE_MOVIES = 1000;
 
     // Add new aosp constants above this line.
     // END OF AOSP CONSTANTS