blob: 5057443eee07311917169a78dac178d166bd26d8 [file] [log] [blame]
Hugo Benichia43a0952016-08-30 10:01:15 +09001/*
2 * Copyright (C) 2016, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.connectivity;
18
Hugo Benichi4a0c5d72017-10-11 11:26:25 +090019import static org.junit.Assert.assertFalse;
20import static org.junit.Assert.assertTrue;
Hugo Benichia43a0952016-08-30 10:01:15 +090021import static org.mockito.Mockito.any;
22import static org.mockito.Mockito.anyBoolean;
23import static org.mockito.Mockito.anyInt;
24import static org.mockito.Mockito.eq;
25import static org.mockito.Mockito.never;
Remi NGUYEN VANe67b0c32018-12-27 16:43:56 +090026import static org.mockito.Mockito.reset;
Hugo Benichia43a0952016-08-30 10:01:15 +090027import static org.mockito.Mockito.times;
28import static org.mockito.Mockito.verify;
29import static org.mockito.Mockito.when;
30
Hugo Benichi4a0c5d72017-10-11 11:26:25 +090031import android.app.PendingIntent;
32import android.content.Context;
33import android.content.res.Resources;
34import android.net.ConnectivityManager;
Lorenzo Colitti9307ca22019-01-12 01:54:23 +090035import android.net.INetd;
Hugo Benichi4a0c5d72017-10-11 11:26:25 +090036import android.net.Network;
37import android.net.NetworkCapabilities;
Chalard Jean08577fc2018-05-02 21:14:54 +090038import android.net.NetworkFactory;
Hugo Benichi4a0c5d72017-10-11 11:26:25 +090039import android.net.NetworkInfo;
40import android.net.NetworkMisc;
Lorenzo Colitti9307ca22019-01-12 01:54:23 +090041import android.os.INetworkManagementService;
Hugo Benichi4a0c5d72017-10-11 11:26:25 +090042import android.support.test.filters.SmallTest;
Remi NGUYEN VANe67b0c32018-12-27 16:43:56 +090043import android.support.test.runner.AndroidJUnit4;
Hugo Benichi4a0c5d72017-10-11 11:26:25 +090044import android.text.format.DateUtils;
45
46import com.android.internal.R;
47import com.android.server.ConnectivityService;
Hugo Benichi4a0c5d72017-10-11 11:26:25 +090048import com.android.server.connectivity.NetworkNotificationManager.NotificationType;
49
Hugo Benichi4a0c5d72017-10-11 11:26:25 +090050import org.junit.Before;
51import org.junit.Test;
Remi NGUYEN VANe67b0c32018-12-27 16:43:56 +090052import org.junit.runner.RunWith;
Hugo Benichi4a0c5d72017-10-11 11:26:25 +090053import org.mockito.Mock;
54import org.mockito.MockitoAnnotations;
55
56@RunWith(AndroidJUnit4.class)
57@SmallTest
58public class LingerMonitorTest {
Hugo Benichia43a0952016-08-30 10:01:15 +090059 static final String CELLULAR = "CELLULAR";
60 static final String WIFI = "WIFI";
61
Lorenzo Colitti84e6f1232016-08-29 14:03:11 +090062 static final long LOW_RATE_LIMIT = DateUtils.MINUTE_IN_MILLIS;
63 static final long HIGH_RATE_LIMIT = 0;
64
65 static final int LOW_DAILY_LIMIT = 2;
66 static final int HIGH_DAILY_LIMIT = 1000;
67
Hugo Benichia43a0952016-08-30 10:01:15 +090068 LingerMonitor mMonitor;
69
70 @Mock ConnectivityService mConnService;
Lorenzo Colitti9307ca22019-01-12 01:54:23 +090071 @Mock INetd mNetd;
72 @Mock INetworkManagementService mNMS;
Hugo Benichia43a0952016-08-30 10:01:15 +090073 @Mock Context mCtx;
74 @Mock NetworkMisc mMisc;
75 @Mock NetworkNotificationManager mNotifier;
76 @Mock Resources mResources;
77
Hugo Benichi4a0c5d72017-10-11 11:26:25 +090078 @Before
Hugo Benichia43a0952016-08-30 10:01:15 +090079 public void setUp() {
80 MockitoAnnotations.initMocks(this);
81 when(mCtx.getResources()).thenReturn(mResources);
82 when(mCtx.getPackageName()).thenReturn("com.android.server.connectivity");
Hugo Benichia43a0952016-08-30 10:01:15 +090083
Lorenzo Colitti84e6f1232016-08-29 14:03:11 +090084 mMonitor = new TestableLingerMonitor(mCtx, mNotifier, HIGH_DAILY_LIMIT, HIGH_RATE_LIMIT);
Hugo Benichia43a0952016-08-30 10:01:15 +090085 }
86
Hugo Benichi4a0c5d72017-10-11 11:26:25 +090087 @Test
Hugo Benichia43a0952016-08-30 10:01:15 +090088 public void testTransitions() {
89 setNotificationSwitch(transition(WIFI, CELLULAR));
90 NetworkAgentInfo nai1 = wifiNai(100);
91 NetworkAgentInfo nai2 = cellNai(101);
92
93 assertTrue(mMonitor.isNotificationEnabled(nai1, nai2));
94 assertFalse(mMonitor.isNotificationEnabled(nai2, nai1));
95 }
96
Hugo Benichi4a0c5d72017-10-11 11:26:25 +090097 @Test
Hugo Benichia43a0952016-08-30 10:01:15 +090098 public void testNotificationOnLinger() {
99 setNotificationSwitch(transition(WIFI, CELLULAR));
100 setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION);
101 NetworkAgentInfo from = wifiNai(100);
102 NetworkAgentInfo to = cellNai(101);
103
104 mMonitor.noteLingerDefaultNetwork(from, to);
105 verifyNotification(from, to);
106 }
107
Hugo Benichi4a0c5d72017-10-11 11:26:25 +0900108 @Test
Hugo Benichia43a0952016-08-30 10:01:15 +0900109 public void testToastOnLinger() {
110 setNotificationSwitch(transition(WIFI, CELLULAR));
111 setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST);
112 NetworkAgentInfo from = wifiNai(100);
113 NetworkAgentInfo to = cellNai(101);
114
115 mMonitor.noteLingerDefaultNetwork(from, to);
116 verifyToast(from, to);
117 }
118
Hugo Benichi4a0c5d72017-10-11 11:26:25 +0900119 @Test
Hugo Benichia43a0952016-08-30 10:01:15 +0900120 public void testNotificationClearedAfterDisconnect() {
121 setNotificationSwitch(transition(WIFI, CELLULAR));
122 setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION);
123 NetworkAgentInfo from = wifiNai(100);
124 NetworkAgentInfo to = cellNai(101);
125
126 mMonitor.noteLingerDefaultNetwork(from, to);
127 verifyNotification(from, to);
128
129 mMonitor.noteDisconnect(to);
130 verify(mNotifier, times(1)).clearNotification(100);
131 }
132
Hugo Benichi4a0c5d72017-10-11 11:26:25 +0900133 @Test
Hugo Benichia43a0952016-08-30 10:01:15 +0900134 public void testNotificationClearedAfterSwitchingBack() {
135 setNotificationSwitch(transition(WIFI, CELLULAR));
136 setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION);
137 NetworkAgentInfo from = wifiNai(100);
138 NetworkAgentInfo to = cellNai(101);
139
140 mMonitor.noteLingerDefaultNetwork(from, to);
141 verifyNotification(from, to);
142
143 mMonitor.noteLingerDefaultNetwork(to, from);
144 verify(mNotifier, times(1)).clearNotification(100);
145 }
146
Hugo Benichi4a0c5d72017-10-11 11:26:25 +0900147 @Test
Hugo Benichia43a0952016-08-30 10:01:15 +0900148 public void testUniqueToast() {
149 setNotificationSwitch(transition(WIFI, CELLULAR));
150 setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST);
151 NetworkAgentInfo from = wifiNai(100);
152 NetworkAgentInfo to = cellNai(101);
153
154 mMonitor.noteLingerDefaultNetwork(from, to);
155 verifyToast(from, to);
156
157 mMonitor.noteLingerDefaultNetwork(to, from);
158 verify(mNotifier, times(1)).clearNotification(100);
159
Lorenzo Colitti84e6f1232016-08-29 14:03:11 +0900160 reset(mNotifier);
Hugo Benichia43a0952016-08-30 10:01:15 +0900161 mMonitor.noteLingerDefaultNetwork(from, to);
Lorenzo Colitti84e6f1232016-08-29 14:03:11 +0900162 verifyNoNotifications();
163 }
164
Hugo Benichi4a0c5d72017-10-11 11:26:25 +0900165 @Test
Lorenzo Colitti84e6f1232016-08-29 14:03:11 +0900166 public void testMultipleNotifications() {
167 setNotificationSwitch(transition(WIFI, CELLULAR));
168 setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION);
169 NetworkAgentInfo wifi1 = wifiNai(100);
170 NetworkAgentInfo wifi2 = wifiNai(101);
171 NetworkAgentInfo cell = cellNai(102);
172
173 mMonitor.noteLingerDefaultNetwork(wifi1, cell);
174 verifyNotification(wifi1, cell);
175
176 mMonitor.noteLingerDefaultNetwork(cell, wifi2);
177 verify(mNotifier, times(1)).clearNotification(100);
178
179 reset(mNotifier);
180 mMonitor.noteLingerDefaultNetwork(wifi2, cell);
181 verifyNotification(wifi2, cell);
182 }
183
Hugo Benichi4a0c5d72017-10-11 11:26:25 +0900184 @Test
Lorenzo Colitti84e6f1232016-08-29 14:03:11 +0900185 public void testRateLimiting() throws InterruptedException {
186 mMonitor = new TestableLingerMonitor(mCtx, mNotifier, HIGH_DAILY_LIMIT, LOW_RATE_LIMIT);
187
188 setNotificationSwitch(transition(WIFI, CELLULAR));
189 setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION);
190 NetworkAgentInfo wifi1 = wifiNai(100);
191 NetworkAgentInfo wifi2 = wifiNai(101);
192 NetworkAgentInfo wifi3 = wifiNai(102);
193 NetworkAgentInfo cell = cellNai(103);
194
195 mMonitor.noteLingerDefaultNetwork(wifi1, cell);
196 verifyNotification(wifi1, cell);
197 reset(mNotifier);
198
199 Thread.sleep(50);
200 mMonitor.noteLingerDefaultNetwork(cell, wifi2);
201 mMonitor.noteLingerDefaultNetwork(wifi2, cell);
202 verifyNoNotifications();
203
204 Thread.sleep(50);
205 mMonitor.noteLingerDefaultNetwork(cell, wifi3);
206 mMonitor.noteLingerDefaultNetwork(wifi3, cell);
207 verifyNoNotifications();
208 }
209
Hugo Benichi4a0c5d72017-10-11 11:26:25 +0900210 @Test
Lorenzo Colitti84e6f1232016-08-29 14:03:11 +0900211 public void testDailyLimiting() throws InterruptedException {
212 mMonitor = new TestableLingerMonitor(mCtx, mNotifier, LOW_DAILY_LIMIT, HIGH_RATE_LIMIT);
213
214 setNotificationSwitch(transition(WIFI, CELLULAR));
215 setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION);
216 NetworkAgentInfo wifi1 = wifiNai(100);
217 NetworkAgentInfo wifi2 = wifiNai(101);
218 NetworkAgentInfo wifi3 = wifiNai(102);
219 NetworkAgentInfo cell = cellNai(103);
220
221 mMonitor.noteLingerDefaultNetwork(wifi1, cell);
222 verifyNotification(wifi1, cell);
223 reset(mNotifier);
224
225 Thread.sleep(50);
226 mMonitor.noteLingerDefaultNetwork(cell, wifi2);
227 mMonitor.noteLingerDefaultNetwork(wifi2, cell);
228 verifyNotification(wifi2, cell);
229 reset(mNotifier);
230
231 Thread.sleep(50);
232 mMonitor.noteLingerDefaultNetwork(cell, wifi3);
233 mMonitor.noteLingerDefaultNetwork(wifi3, cell);
234 verifyNoNotifications();
Hugo Benichia43a0952016-08-30 10:01:15 +0900235 }
236
Hugo Benichi4a0c5d72017-10-11 11:26:25 +0900237 @Test
Hugo Benichia43a0952016-08-30 10:01:15 +0900238 public void testUniqueNotification() {
239 setNotificationSwitch(transition(WIFI, CELLULAR));
240 setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION);
241 NetworkAgentInfo from = wifiNai(100);
242 NetworkAgentInfo to = cellNai(101);
243
244 mMonitor.noteLingerDefaultNetwork(from, to);
245 verifyNotification(from, to);
246
247 mMonitor.noteLingerDefaultNetwork(to, from);
248 verify(mNotifier, times(1)).clearNotification(100);
249
250 mMonitor.noteLingerDefaultNetwork(from, to);
251 verifyNotification(from, to);
252 }
253
Hugo Benichi4a0c5d72017-10-11 11:26:25 +0900254 @Test
Lorenzo Colitti84e6f1232016-08-29 14:03:11 +0900255 public void testIgnoreNeverValidatedNetworks() {
Hugo Benichia43a0952016-08-30 10:01:15 +0900256 setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST);
257 setNotificationSwitch(transition(WIFI, CELLULAR));
258 NetworkAgentInfo from = wifiNai(100);
259 NetworkAgentInfo to = cellNai(101);
260 from.everValidated = false;
261
262 mMonitor.noteLingerDefaultNetwork(from, to);
263 verifyNoNotifications();
264 }
265
Hugo Benichi4a0c5d72017-10-11 11:26:25 +0900266 @Test
Lorenzo Colitti84e6f1232016-08-29 14:03:11 +0900267 public void testIgnoreCurrentlyValidatedNetworks() {
268 setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST);
269 setNotificationSwitch(transition(WIFI, CELLULAR));
270 NetworkAgentInfo from = wifiNai(100);
271 NetworkAgentInfo to = cellNai(101);
272 from.lastValidated = true;
273
274 mMonitor.noteLingerDefaultNetwork(from, to);
275 verifyNoNotifications();
276 }
277
Hugo Benichi4a0c5d72017-10-11 11:26:25 +0900278 @Test
Hugo Benichia43a0952016-08-30 10:01:15 +0900279 public void testNoNotificationType() {
280 setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST);
281 setNotificationSwitch();
282 NetworkAgentInfo from = wifiNai(100);
283 NetworkAgentInfo to = cellNai(101);
284
285 mMonitor.noteLingerDefaultNetwork(from, to);
286 verifyNoNotifications();
287 }
288
Hugo Benichi4a0c5d72017-10-11 11:26:25 +0900289 @Test
Hugo Benichia43a0952016-08-30 10:01:15 +0900290 public void testNoTransitionToNotify() {
291 setNotificationType(LingerMonitor.NOTIFY_TYPE_NONE);
292 setNotificationSwitch(transition(WIFI, CELLULAR));
293 NetworkAgentInfo from = wifiNai(100);
294 NetworkAgentInfo to = cellNai(101);
295
296 mMonitor.noteLingerDefaultNetwork(from, to);
297 verifyNoNotifications();
298 }
299
Hugo Benichi4a0c5d72017-10-11 11:26:25 +0900300 @Test
Hugo Benichia43a0952016-08-30 10:01:15 +0900301 public void testDifferentTransitionToNotify() {
302 setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST);
303 setNotificationSwitch(transition(CELLULAR, WIFI));
304 NetworkAgentInfo from = wifiNai(100);
305 NetworkAgentInfo to = cellNai(101);
306
307 mMonitor.noteLingerDefaultNetwork(from, to);
308 verifyNoNotifications();
309 }
310
311 void setNotificationSwitch(String... transitions) {
312 when(mResources.getStringArray(R.array.config_networkNotifySwitches))
313 .thenReturn(transitions);
314 }
315
316 String transition(String from, String to) {
317 return from + "-" + to;
318 }
319
320 void setNotificationType(int type) {
321 when(mResources.getInteger(R.integer.config_networkNotifySwitchType)).thenReturn(type);
322 }
323
324 void verifyNoToast() {
325 verify(mNotifier, never()).showToast(any(), any());
326 }
327
328 void verifyNoNotification() {
329 verify(mNotifier, never())
330 .showNotification(anyInt(), any(), any(), any(), any(), anyBoolean());
331 }
332
333 void verifyNoNotifications() {
334 verifyNoToast();
335 verifyNoNotification();
Hugo Benichia43a0952016-08-30 10:01:15 +0900336 }
337
338 void verifyToast(NetworkAgentInfo from, NetworkAgentInfo to) {
339 verifyNoNotification();
340 verify(mNotifier, times(1)).showToast(from, to);
341 }
342
343 void verifyNotification(NetworkAgentInfo from, NetworkAgentInfo to) {
344 verifyNoToast();
345 verify(mNotifier, times(1)).showNotification(eq(from.network.netId),
346 eq(NotificationType.NETWORK_SWITCH), eq(from), eq(to), any(), eq(true));
347 }
348
349 NetworkAgentInfo nai(int netId, int transport, int networkType, String networkTypeName) {
350 NetworkInfo info = new NetworkInfo(networkType, 0, networkTypeName, "");
351 NetworkCapabilities caps = new NetworkCapabilities();
352 caps.addCapability(0);
353 caps.addTransportType(transport);
354 NetworkAgentInfo nai = new NetworkAgentInfo(null, null, new Network(netId), info, null,
Chalard Jean08577fc2018-05-02 21:14:54 +0900355 caps, 50, mCtx, null, mMisc, mConnService, mNetd, mNMS,
356 NetworkFactory.SerialNumber.NONE);
Hugo Benichia43a0952016-08-30 10:01:15 +0900357 nai.everValidated = true;
358 return nai;
359 }
360
361 NetworkAgentInfo wifiNai(int netId) {
362 return nai(netId, NetworkCapabilities.TRANSPORT_WIFI,
363 ConnectivityManager.TYPE_WIFI, WIFI);
364 }
365
366 NetworkAgentInfo cellNai(int netId) {
367 return nai(netId, NetworkCapabilities.TRANSPORT_CELLULAR,
368 ConnectivityManager.TYPE_MOBILE, CELLULAR);
369 }
370
371 public static class TestableLingerMonitor extends LingerMonitor {
Lorenzo Colitti84e6f1232016-08-29 14:03:11 +0900372 public TestableLingerMonitor(Context c, NetworkNotificationManager n, int l, long r) {
373 super(c, n, l, r);
Hugo Benichia43a0952016-08-30 10:01:15 +0900374 }
375 @Override protected PendingIntent createNotificationIntent() {
376 return null;
377 }
378 }
379}