blob: 676463407f3ff5d2da7bc4d0c9ac976edcf0fa39 [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;
Rohan Shahdb2cfa32018-02-20 11:27:22 -080040import android.support.test.InstrumentationRegistry;
Jason Monk8c09ac72017-03-16 11:53:40 -040041import android.testing.AndroidTestingRunner;
42import android.testing.TestableLooper;
43import android.testing.TestableLooper.RunWithLooper;
44
45import com.android.internal.logging.MetricsLogger;
46import com.android.systemui.Dependency;
47import com.android.systemui.SysuiTestCase;
48import com.android.systemui.plugins.qs.QSTile;
49import com.android.systemui.qs.QSHost;
50import com.android.systemui.qs.QSTileHost;
51
52import org.junit.Before;
Geoffrey Pitsch659a91b2017-11-28 13:33:13 -050053import org.junit.Ignore;
Jason Monk8c09ac72017-03-16 11:53:40 -040054import org.junit.Test;
55import org.junit.runner.RunWith;
56import org.mockito.ArgumentMatcher;
57
58@RunWith(AndroidTestingRunner.class)
59@RunWithLooper
Jason Monkfba8faf2017-05-23 10:42:59 -040060@SmallTest
Jason Monk8c09ac72017-03-16 11:53:40 -040061public class QSTileImplTest extends SysuiTestCase {
62
63 public static final int POSITION = 14;
64 private TestableLooper mTestableLooper;
65 private TileImpl mTile;
66 private QSTileHost mHost;
67 private MetricsLogger mMetricsLogger;
68
69 @Before
70 public void setup() throws Exception {
71 String spec = "spec";
72 mTestableLooper = TestableLooper.get(this);
73 mDependency.injectTestDependency(Dependency.BG_LOOPER, mTestableLooper.getLooper());
74 mMetricsLogger = mDependency.injectMockDependency(MetricsLogger.class);
75 mHost = mock(QSTileHost.class);
76 when(mHost.indexOf(spec)).thenReturn(POSITION);
Rohan Shahdb2cfa32018-02-20 11:27:22 -080077 when(mHost.getContext()).thenReturn(mContext.getBaseContext());
Jason Monk1c6116c2017-09-06 17:33:01 -040078
79 mTile = spy(new TileImpl(mHost));
80 mTile.mHandler = mTile.new H(mTestableLooper.getLooper());
81 mTile.setTileSpec(spec);
Jason Monk8c09ac72017-03-16 11:53:40 -040082 }
83
84 @Test
85 public void testClick_Metrics() {
86 mTile.click();
87 verify(mMetricsLogger).write(argThat(new TileLogMatcher(ACTION_QS_CLICK)));
88 }
89
90 @Test
91 public void testSecondaryClick_Metrics() {
92 mTile.secondaryClick();
93 verify(mMetricsLogger).write(argThat(new TileLogMatcher(ACTION_QS_SECONDARY_CLICK)));
94 }
95
96 @Test
97 public void testLongClick_Metrics() {
98 mTile.longClick();
99 verify(mMetricsLogger).write(argThat(new TileLogMatcher(ACTION_QS_LONG_PRESS)));
100 }
101
102 @Test
103 public void testPopulate() {
104 LogMaker maker = mock(LogMaker.class);
105 when(maker.setSubtype(anyInt())).thenReturn(maker);
Jason Monk2ef8ed62017-09-07 14:51:41 -0400106 when(maker.addTaggedData(anyInt(), any())).thenReturn(maker);
Jason Monk8c09ac72017-03-16 11:53:40 -0400107 mTile.getState().value = true;
108 mTile.populate(maker);
109 verify(maker).addTaggedData(eq(FIELD_QS_VALUE), eq(1));
110 verify(maker).addTaggedData(eq(FIELD_QS_POSITION), eq(POSITION));
111 }
112
Jason Monk1c6116c2017-09-06 17:33:01 -0400113 @Test
Geoffrey Pitsch659a91b2017-11-28 13:33:13 -0500114 @Ignore("flaky")
Jason Monk1c6116c2017-09-06 17:33:01 -0400115 public void testStaleTimeout() throws InterruptedException {
116 when(mTile.getStaleTimeout()).thenReturn(5l);
117 clearInvocations(mTile);
118
119 mTile.handleRefreshState(null);
120 mTestableLooper.processAllMessages();
121 verify(mTile, never()).handleStale();
122
123 sleep(10);
124 mTestableLooper.processAllMessages();
125 verify(mTile).handleStale();
126 }
127
128 @Test
129 public void testStaleListening() {
130 mTile.handleStale();
131 mTestableLooper.processAllMessages();
132 verify(mTile).handleSetListening(eq(true));
133
134 mTile.handleRefreshState(null);
135 mTestableLooper.processAllMessages();
136 verify(mTile).handleSetListening(eq(false));
137 }
138
Jason Monk8c09ac72017-03-16 11:53:40 -0400139 private class TileLogMatcher implements ArgumentMatcher<LogMaker> {
140
141 private final int mCategory;
142 public String mInvalid;
143
144 public TileLogMatcher(int category) {
145 mCategory = category;
146 }
147
148 @Override
149 public boolean matches(LogMaker arg) {
150 if (arg.getCategory() != mCategory) {
151 mInvalid = "Expected category " + mCategory + " but was " + arg.getCategory();
152 return false;
153 }
154 if (arg.getType() != TYPE_ACTION) {
155 mInvalid = "Expected type " + TYPE_ACTION + " but was " + arg.getType();
156 return false;
157 }
158 if (arg.getSubtype() != mTile.getMetricsCategory()) {
159 mInvalid = "Expected subtype " + mTile.getMetricsCategory() + " but was "
160 + arg.getSubtype();
161 return false;
162 }
163 return true;
164 }
165
166 @Override
167 public String toString() {
168 return mInvalid;
169 }
170 }
171
172 private static class TileImpl extends QSTileImpl<QSTile.BooleanState> {
173 protected TileImpl(QSHost host) {
174 super(host);
175 }
176
177 @Override
178 public BooleanState newTileState() {
179 return new BooleanState();
180 }
181
182 @Override
183 protected void handleClick() {
184
185 }
186
187 @Override
188 protected void handleUpdateState(BooleanState state, Object arg) {
189
190 }
191
192 @Override
193 public int getMetricsCategory() {
194 return 42;
195 }
196
197 @Override
198 public Intent getLongClickIntent() {
199 return null;
200 }
201
202 @Override
Jason Monk1c6116c2017-09-06 17:33:01 -0400203 protected void handleSetListening(boolean listening) {
Jason Monk8c09ac72017-03-16 11:53:40 -0400204
205 }
206
207 @Override
208 public CharSequence getTileLabel() {
209 return null;
210 }
211 }
212}