blob: 1c9c7949a971f9f5f31024410fa16d414f41d51b [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;
Geoffrey Pitsch659a91b2017-11-28 13:33:13 -050052import org.junit.Ignore;
Jason Monk8c09ac72017-03-16 11:53:40 -040053import org.junit.Test;
54import org.junit.runner.RunWith;
55import org.mockito.ArgumentMatcher;
56
57@RunWith(AndroidTestingRunner.class)
58@RunWithLooper
Jason Monkfba8faf2017-05-23 10:42:59 -040059@SmallTest
Jason Monk8c09ac72017-03-16 11:53:40 -040060public class QSTileImplTest extends SysuiTestCase {
61
62 public static final int POSITION = 14;
63 private TestableLooper mTestableLooper;
64 private TileImpl mTile;
65 private QSTileHost mHost;
66 private MetricsLogger mMetricsLogger;
67
68 @Before
69 public void setup() throws Exception {
70 String spec = "spec";
71 mTestableLooper = TestableLooper.get(this);
72 mDependency.injectTestDependency(Dependency.BG_LOOPER, mTestableLooper.getLooper());
73 mMetricsLogger = mDependency.injectMockDependency(MetricsLogger.class);
74 mHost = mock(QSTileHost.class);
75 when(mHost.indexOf(spec)).thenReturn(POSITION);
Jason Monk1c6116c2017-09-06 17:33:01 -040076
77 mTile = spy(new TileImpl(mHost));
78 mTile.mHandler = mTile.new H(mTestableLooper.getLooper());
79 mTile.setTileSpec(spec);
Jason Monk8c09ac72017-03-16 11:53:40 -040080 }
81
82 @Test
83 public void testClick_Metrics() {
84 mTile.click();
85 verify(mMetricsLogger).write(argThat(new TileLogMatcher(ACTION_QS_CLICK)));
86 }
87
88 @Test
89 public void testSecondaryClick_Metrics() {
90 mTile.secondaryClick();
91 verify(mMetricsLogger).write(argThat(new TileLogMatcher(ACTION_QS_SECONDARY_CLICK)));
92 }
93
94 @Test
95 public void testLongClick_Metrics() {
96 mTile.longClick();
97 verify(mMetricsLogger).write(argThat(new TileLogMatcher(ACTION_QS_LONG_PRESS)));
98 }
99
100 @Test
101 public void testPopulate() {
102 LogMaker maker = mock(LogMaker.class);
103 when(maker.setSubtype(anyInt())).thenReturn(maker);
Jason Monk2ef8ed62017-09-07 14:51:41 -0400104 when(maker.addTaggedData(anyInt(), any())).thenReturn(maker);
Jason Monk8c09ac72017-03-16 11:53:40 -0400105 mTile.getState().value = true;
106 mTile.populate(maker);
107 verify(maker).addTaggedData(eq(FIELD_QS_VALUE), eq(1));
108 verify(maker).addTaggedData(eq(FIELD_QS_POSITION), eq(POSITION));
109 }
110
Jason Monk1c6116c2017-09-06 17:33:01 -0400111 @Test
Geoffrey Pitsch659a91b2017-11-28 13:33:13 -0500112 @Ignore("flaky")
Jason Monk1c6116c2017-09-06 17:33:01 -0400113 public void testStaleTimeout() throws InterruptedException {
114 when(mTile.getStaleTimeout()).thenReturn(5l);
115 clearInvocations(mTile);
116
117 mTile.handleRefreshState(null);
118 mTestableLooper.processAllMessages();
119 verify(mTile, never()).handleStale();
120
121 sleep(10);
122 mTestableLooper.processAllMessages();
123 verify(mTile).handleStale();
124 }
125
126 @Test
127 public void testStaleListening() {
128 mTile.handleStale();
129 mTestableLooper.processAllMessages();
130 verify(mTile).handleSetListening(eq(true));
131
132 mTile.handleRefreshState(null);
133 mTestableLooper.processAllMessages();
134 verify(mTile).handleSetListening(eq(false));
135 }
136
Jason Monk8c09ac72017-03-16 11:53:40 -0400137 private class TileLogMatcher implements ArgumentMatcher<LogMaker> {
138
139 private final int mCategory;
140 public String mInvalid;
141
142 public TileLogMatcher(int category) {
143 mCategory = category;
144 }
145
146 @Override
147 public boolean matches(LogMaker arg) {
148 if (arg.getCategory() != mCategory) {
149 mInvalid = "Expected category " + mCategory + " but was " + arg.getCategory();
150 return false;
151 }
152 if (arg.getType() != TYPE_ACTION) {
153 mInvalid = "Expected type " + TYPE_ACTION + " but was " + arg.getType();
154 return false;
155 }
156 if (arg.getSubtype() != mTile.getMetricsCategory()) {
157 mInvalid = "Expected subtype " + mTile.getMetricsCategory() + " but was "
158 + arg.getSubtype();
159 return false;
160 }
161 return true;
162 }
163
164 @Override
165 public String toString() {
166 return mInvalid;
167 }
168 }
169
170 private static class TileImpl extends QSTileImpl<QSTile.BooleanState> {
171 protected TileImpl(QSHost host) {
172 super(host);
173 }
174
175 @Override
176 public BooleanState newTileState() {
177 return new BooleanState();
178 }
179
180 @Override
181 protected void handleClick() {
182
183 }
184
185 @Override
186 protected void handleUpdateState(BooleanState state, Object arg) {
187
188 }
189
190 @Override
191 public int getMetricsCategory() {
192 return 42;
193 }
194
195 @Override
196 public Intent getLongClickIntent() {
197 return null;
198 }
199
200 @Override
Jason Monk1c6116c2017-09-06 17:33:01 -0400201 protected void handleSetListening(boolean listening) {
Jason Monk8c09ac72017-03-16 11:53:40 -0400202
203 }
204
205 @Override
206 public CharSequence getTileLabel() {
207 return null;
208 }
209 }
210}