Clean up and cover more QS metrics
Change-Id: I4ab5e54398024c8b16ca8223f0639aadcdef4377
Fixes: 34801532
Test: runtest systemui
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java
new file mode 100644
index 0000000..c67cccc
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java
@@ -0,0 +1,103 @@
+/*
+ * 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.qs;
+
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_QS_MORE_SETTINGS;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.testing.TestableLooper.RunWithLooper;
+import android.testing.ViewUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.systemui.R;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.plugins.qs.DetailAdapter;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper
+public class QSDetailTest extends SysuiTestCase {
+
+ private MetricsLogger mMetricsLogger;
+ private QSDetail mQsDetail;
+ private QSPanel mQsPanel;
+ private QuickStatusBarHeader mQuickHeader;
+ private ActivityStarter mActivityStarter;
+ private DetailAdapter mMockDetailAdapter;
+ private TestableLooper mTestableLooper;
+
+ @Before
+ public void setup() throws Exception {
+ mTestableLooper = TestableLooper.get(this);
+ mTestableLooper.runWithLooper(() -> {
+ mMetricsLogger = mDependency.injectMockDependency(MetricsLogger.class);
+ mActivityStarter = mDependency.injectMockDependency(ActivityStarter.class);
+ mQsDetail = (QSDetail) LayoutInflater.from(mContext).inflate(R.layout.qs_detail, null);
+ mQsPanel = mock(QSPanel.class);
+ mQuickHeader = mock(QuickStatusBarHeader.class);
+ mQsDetail.setQsPanel(mQsPanel, mQuickHeader);
+
+ mMockDetailAdapter = mock(DetailAdapter.class);
+ when(mMockDetailAdapter.createDetailView(any(), any(), any()))
+ .thenReturn(mock(View.class));
+ });
+ }
+
+ @Test
+ public void testShowDetail_Metrics() {
+ ViewUtils.attachView(mQsDetail);
+ mTestableLooper.processAllMessages();
+
+ mQsDetail.handleShowingDetail(mMockDetailAdapter, 0, 0, false);
+ verify(mMetricsLogger).visible(eq(mMockDetailAdapter.getMetricsCategory()));
+ mQsDetail.handleShowingDetail(null, 0, 0, false);
+ verify(mMetricsLogger).hidden(eq(mMockDetailAdapter.getMetricsCategory()));
+
+ ViewUtils.detachView(mQsDetail);
+ mTestableLooper.processAllMessages();
+ }
+
+ @Test
+ public void testMoreSettingsButton() {
+ ViewUtils.attachView(mQsDetail);
+ mTestableLooper.processAllMessages();
+
+ mQsDetail.handleShowingDetail(mMockDetailAdapter, 0, 0, false);
+ mQsDetail.findViewById(android.R.id.button2).performClick();
+
+ int metricsCategory = mMockDetailAdapter.getMetricsCategory();
+ verify(mMetricsLogger).action(eq(ACTION_QS_MORE_SETTINGS), eq(metricsCategory));
+
+ verify(mActivityStarter).postStartActivityDismissingKeyguard(any(), anyInt());
+
+ ViewUtils.detachView(mQsDetail);
+ mTestableLooper.processAllMessages();
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
index deb31da..d77ed3d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
@@ -19,6 +19,7 @@
import android.os.Looper;
+import com.android.internal.logging.MetricsLogger;
import com.android.keyguard.CarrierText;
import com.android.systemui.Dependency;
import com.android.systemui.R;
@@ -44,12 +45,15 @@
@RunWithLooper(setAsMainLooper = true)
public class QSFragmentTest extends SysuiBaseFragmentTest {
+ private MetricsLogger mMockMetricsLogger;
+
public QSFragmentTest() {
super(QSFragment.class);
}
@Before
public void addLeakCheckDependencies() {
+ mMockMetricsLogger = mDependency.injectMockDependency(MetricsLogger.class);
mContext.addMockSystemService(Context.LAYOUT_INFLATER_SERVICE,
new LayoutInflaterBuilder(mContext)
.replace("com.android.systemui.statusbar.policy.SplitClockView",
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java
new file mode 100644
index 0000000..4979684
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java
@@ -0,0 +1,65 @@
+/*
+ * 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.qs;
+
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.verify;
+
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.testing.TestableLooper.RunWithLooper;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.qs.customize.QSCustomizer;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Collections;
+
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper
+public class QSPanelTest extends SysuiTestCase {
+
+ private MetricsLogger mMetricsLogger;
+ private QSPanel mQsPanel;
+ private QSTileHost mHost;
+ private QSCustomizer mCustomizer;
+
+ @Before
+ public void setup() throws Exception {
+ TestableLooper.get(this).runWithLooper(() -> {
+ mMetricsLogger = mDependency.injectMockDependency(MetricsLogger.class);
+ mQsPanel = new QSPanel(mContext, null);
+ mHost = mock(QSTileHost.class);
+ when(mHost.getTiles()).thenReturn(Collections.emptyList());
+ mCustomizer = mock(QSCustomizer.class);
+ mQsPanel.setHost(mHost, mCustomizer);
+ });
+ }
+
+ @Test
+ public void testSetExpanded_Metrics() {
+ mQsPanel.setExpanded(true);
+ verify(mMetricsLogger).visibility(eq(MetricsEvent.QS_PANEL), eq(true));
+ mQsPanel.setExpanded(false);
+ verify(mMetricsLogger).visibility(eq(MetricsEvent.QS_PANEL), eq(false));
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java
new file mode 100644
index 0000000..9ed9d28
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java
@@ -0,0 +1,174 @@
+/*
+ * 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.qs.tileimpl;
+
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_QS_CLICK;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_QS_LONG_PRESS;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_QS_SECONDARY_CLICK;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_QS_POSITION;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_QS_VALUE;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_ACTION;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Matchers.argThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Intent;
+import android.metrics.LogMaker;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.testing.TestableLooper.RunWithLooper;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.systemui.Dependency;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.plugins.qs.QSTile;
+import com.android.systemui.qs.QSHost;
+import com.android.systemui.qs.QSTileHost;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentMatcher;
+
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper
+public class QSTileImplTest extends SysuiTestCase {
+
+ public static final int POSITION = 14;
+ private TestableLooper mTestableLooper;
+ private TileImpl mTile;
+ private QSTileHost mHost;
+ private MetricsLogger mMetricsLogger;
+
+ @Before
+ public void setup() throws Exception {
+ String spec = "spec";
+ mTestableLooper = TestableLooper.get(this);
+ mDependency.injectTestDependency(Dependency.BG_LOOPER, mTestableLooper.getLooper());
+ mMetricsLogger = mDependency.injectMockDependency(MetricsLogger.class);
+ mHost = mock(QSTileHost.class);
+ when(mHost.indexOf(spec)).thenReturn(POSITION);
+ mTestableLooper.runWithLooper(() -> {
+ mTile = new TileImpl(mHost);
+ mTile.setTileSpec(spec);
+ });
+ }
+
+ @Test
+ public void testClick_Metrics() {
+ mTile.click();
+ verify(mMetricsLogger).write(argThat(new TileLogMatcher(ACTION_QS_CLICK)));
+ }
+
+ @Test
+ public void testSecondaryClick_Metrics() {
+ mTile.secondaryClick();
+ verify(mMetricsLogger).write(argThat(new TileLogMatcher(ACTION_QS_SECONDARY_CLICK)));
+ }
+
+ @Test
+ public void testLongClick_Metrics() {
+ mTile.longClick();
+ verify(mMetricsLogger).write(argThat(new TileLogMatcher(ACTION_QS_LONG_PRESS)));
+ }
+
+ @Test
+ public void testPopulate() {
+ LogMaker maker = mock(LogMaker.class);
+ when(maker.setSubtype(anyInt())).thenReturn(maker);
+ mTile.getState().value = true;
+ mTile.populate(maker);
+ verify(maker).addTaggedData(eq(FIELD_QS_VALUE), eq(1));
+ verify(maker).addTaggedData(eq(FIELD_QS_POSITION), eq(POSITION));
+ }
+
+ private class TileLogMatcher implements ArgumentMatcher<LogMaker> {
+
+ private final int mCategory;
+ public String mInvalid;
+
+ public TileLogMatcher(int category) {
+ mCategory = category;
+ }
+
+ @Override
+ public boolean matches(LogMaker arg) {
+ if (arg.getCategory() != mCategory) {
+ mInvalid = "Expected category " + mCategory + " but was " + arg.getCategory();
+ return false;
+ }
+ if (arg.getType() != TYPE_ACTION) {
+ mInvalid = "Expected type " + TYPE_ACTION + " but was " + arg.getType();
+ return false;
+ }
+ if (arg.getSubtype() != mTile.getMetricsCategory()) {
+ mInvalid = "Expected subtype " + mTile.getMetricsCategory() + " but was "
+ + arg.getSubtype();
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return mInvalid;
+ }
+ }
+
+ private static class TileImpl extends QSTileImpl<QSTile.BooleanState> {
+ protected TileImpl(QSHost host) {
+ super(host);
+ }
+
+ @Override
+ public BooleanState newTileState() {
+ return new BooleanState();
+ }
+
+ @Override
+ protected void handleClick() {
+
+ }
+
+ @Override
+ protected void handleUpdateState(BooleanState state, Object arg) {
+
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return 42;
+ }
+
+ @Override
+ public Intent getLongClickIntent() {
+ return null;
+ }
+
+ @Override
+ protected void setListening(boolean listening) {
+
+ }
+
+ @Override
+ public CharSequence getTileLabel() {
+ return null;
+ }
+ }
+}
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 f48af75..bf6b394 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
@@ -62,9 +62,9 @@
mKeyguardIndicationController = mock(KeyguardIndicationController.class);
mStackScroller = mock(NotificationStackScrollLayout.class);
mMetricsLogger = new FakeMetricsLogger();
+ mDependency.injectTestDependency(MetricsLogger.class, mMetricsLogger);
mStatusBar = new TestableStatusBar(mStatusBarKeyguardViewManager, mUnlockMethodCache,
mKeyguardIndicationController, mStackScroller);
- mStatusBar.setMetricsLogger(mMetricsLogger);
doAnswer(invocation -> {
OnDismissAction onDismissAction = (OnDismissAction) invocation.getArguments()[0];