blob: 004ff29f7eac1e67af3a828d5f6aa23302f0a898 [file] [log] [blame]
Jason Monk8c09ac72017-03-16 11:53:40 -04001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5 * except in compliance with the License. You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software distributed under the
10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
11 * KIND, either express or implied. See the License for the specific language governing
12 * permissions and limitations under the License.
13 */
14
15package com.android.systemui.qs.tileimpl;
16
17import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_QS_CLICK;
18import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_QS_LONG_PRESS;
19import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_QS_SECONDARY_CLICK;
20import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_QS_POSITION;
21import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_QS_VALUE;
22import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_ACTION;
23
Jason Monk2ef8ed62017-09-07 14:51:41 -040024import static org.mockito.ArgumentMatchers.any;
Jason Monk8c09ac72017-03-16 11:53:40 -040025import static org.mockito.ArgumentMatchers.anyInt;
26import static org.mockito.ArgumentMatchers.eq;
27import static org.mockito.Matchers.argThat;
Jason Monk1c6116c2017-09-06 17:33:01 -040028import static org.mockito.Mockito.clearInvocations;
Jason Monk8c09ac72017-03-16 11:53:40 -040029import static org.mockito.Mockito.mock;
Jason Monk1c6116c2017-09-06 17:33:01 -040030import static org.mockito.Mockito.never;
31import static org.mockito.Mockito.spy;
Jason Monk8c09ac72017-03-16 11:53:40 -040032import static org.mockito.Mockito.verify;
33import static org.mockito.Mockito.when;
34
Jason Monk1c6116c2017-09-06 17:33:01 -040035import static java.lang.Thread.sleep;
36
Jason Monk8c09ac72017-03-16 11:53:40 -040037import android.content.Intent;
38import android.metrics.LogMaker;
Jason Monkfba8faf2017-05-23 10:42:59 -040039import android.support.test.filters.SmallTest;
Jason Monk8c09ac72017-03-16 11:53:40 -040040import android.testing.AndroidTestingRunner;
41import android.testing.TestableLooper;
42import android.testing.TestableLooper.RunWithLooper;
43
44import com.android.internal.logging.MetricsLogger;
45import com.android.systemui.Dependency;
46import com.android.systemui.SysuiTestCase;
47import com.android.systemui.plugins.qs.QSTile;
48import com.android.systemui.qs.QSHost;
49import com.android.systemui.qs.QSTileHost;
50
51import org.junit.Before;
52import org.junit.Test;
53import org.junit.runner.RunWith;
54import org.mockito.ArgumentMatcher;
55
56@RunWith(AndroidTestingRunner.class)
57@RunWithLooper
Jason Monkfba8faf2017-05-23 10:42:59 -040058@SmallTest
Jason Monk8c09ac72017-03-16 11:53:40 -040059public class QSTileImplTest extends SysuiTestCase {
60
61 public static final int POSITION = 14;
62 private TestableLooper mTestableLooper;
63 private TileImpl mTile;
64 private QSTileHost mHost;
65 private MetricsLogger mMetricsLogger;
66
67 @Before
68 public void setup() throws Exception {
69 String spec = "spec";
70 mTestableLooper = TestableLooper.get(this);
71 mDependency.injectTestDependency(Dependency.BG_LOOPER, mTestableLooper.getLooper());
72 mMetricsLogger = mDependency.injectMockDependency(MetricsLogger.class);
73 mHost = mock(QSTileHost.class);
74 when(mHost.indexOf(spec)).thenReturn(POSITION);
Jason Monk1c6116c2017-09-06 17:33:01 -040075
76 mTile = spy(new TileImpl(mHost));
77 mTile.mHandler = mTile.new H(mTestableLooper.getLooper());
78 mTile.setTileSpec(spec);
Jason Monk8c09ac72017-03-16 11:53:40 -040079 }
80
81 @Test
82 public void testClick_Metrics() {
83 mTile.click();
84 verify(mMetricsLogger).write(argThat(new TileLogMatcher(ACTION_QS_CLICK)));
85 }
86
87 @Test
88 public void testSecondaryClick_Metrics() {
89 mTile.secondaryClick();
90 verify(mMetricsLogger).write(argThat(new TileLogMatcher(ACTION_QS_SECONDARY_CLICK)));
91 }
92
93 @Test
94 public void testLongClick_Metrics() {
95 mTile.longClick();
96 verify(mMetricsLogger).write(argThat(new TileLogMatcher(ACTION_QS_LONG_PRESS)));
97 }
98
99 @Test
100 public void testPopulate() {
101 LogMaker maker = mock(LogMaker.class);
102 when(maker.setSubtype(anyInt())).thenReturn(maker);
Jason Monk2ef8ed62017-09-07 14:51:41 -0400103 when(maker.addTaggedData(anyInt(), any())).thenReturn(maker);
Jason Monk8c09ac72017-03-16 11:53:40 -0400104 mTile.getState().value = true;
105 mTile.populate(maker);
106 verify(maker).addTaggedData(eq(FIELD_QS_VALUE), eq(1));
107 verify(maker).addTaggedData(eq(FIELD_QS_POSITION), eq(POSITION));
108 }
109
Jason Monk1c6116c2017-09-06 17:33:01 -0400110 @Test
111 public void testStaleTimeout() throws InterruptedException {
112 when(mTile.getStaleTimeout()).thenReturn(5l);
113 clearInvocations(mTile);
114
115 mTile.handleRefreshState(null);
116 mTestableLooper.processAllMessages();
117 verify(mTile, never()).handleStale();
118
119 sleep(10);
120 mTestableLooper.processAllMessages();
121 verify(mTile).handleStale();
122 }
123
124 @Test
125 public void testStaleListening() {
126 mTile.handleStale();
127 mTestableLooper.processAllMessages();
128 verify(mTile).handleSetListening(eq(true));
129
130 mTile.handleRefreshState(null);
131 mTestableLooper.processAllMessages();
132 verify(mTile).handleSetListening(eq(false));
133 }
134
Jason Monk8c09ac72017-03-16 11:53:40 -0400135 private class TileLogMatcher implements ArgumentMatcher<LogMaker> {
136
137 private final int mCategory;
138 public String mInvalid;
139
140 public TileLogMatcher(int category) {
141 mCategory = category;
142 }
143
144 @Override
145 public boolean matches(LogMaker arg) {
146 if (arg.getCategory() != mCategory) {
147 mInvalid = "Expected category " + mCategory + " but was " + arg.getCategory();
148 return false;
149 }
150 if (arg.getType() != TYPE_ACTION) {
151 mInvalid = "Expected type " + TYPE_ACTION + " but was " + arg.getType();
152 return false;
153 }
154 if (arg.getSubtype() != mTile.getMetricsCategory()) {
155 mInvalid = "Expected subtype " + mTile.getMetricsCategory() + " but was "
156 + arg.getSubtype();
157 return false;
158 }
159 return true;
160 }
161
162 @Override
163 public String toString() {
164 return mInvalid;
165 }
166 }
167
168 private static class TileImpl extends QSTileImpl<QSTile.BooleanState> {
169 protected TileImpl(QSHost host) {
170 super(host);
171 }
172
173 @Override
174 public BooleanState newTileState() {
175 return new BooleanState();
176 }
177
178 @Override
179 protected void handleClick() {
180
181 }
182
183 @Override
184 protected void handleUpdateState(BooleanState state, Object arg) {
185
186 }
187
188 @Override
189 public int getMetricsCategory() {
190 return 42;
191 }
192
193 @Override
194 public Intent getLongClickIntent() {
195 return null;
196 }
197
198 @Override
Jason Monk1c6116c2017-09-06 17:33:01 -0400199 protected void handleSetListening(boolean listening) {
Jason Monk8c09ac72017-03-16 11:53:40 -0400200
201 }
202
203 @Override
204 public CharSequence getTileLabel() {
205 return null;
206 }
207 }
208}