blob: c653b8eecffa5f7ffa1fd3b8c67d3aeeb3165cb9 [file] [log] [blame]
Amin Shaikh972e2362016-12-07 14:08:09 -08001/*
2 * Copyright (C) 2012 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;
18
Jeremy Joslin145c3432016-12-09 13:11:51 -080019import static android.net.NetworkRecommendationProvider.EXTRA_RECOMMENDATION_RESULT;
20import static android.net.NetworkRecommendationProvider.EXTRA_SEQUENCE;
Jeremy Joslinc5ac5872016-11-30 15:05:40 -080021import static android.net.NetworkScoreManager.CACHE_FILTER_NONE;
Jeremy Joslin145c3432016-12-09 13:11:51 -080022
Amin Shaikh972e2362016-12-07 14:08:09 -080023import static junit.framework.Assert.assertEquals;
24import static junit.framework.Assert.assertFalse;
Jeremy Joslin145c3432016-12-09 13:11:51 -080025import static junit.framework.Assert.assertNotNull;
26import static junit.framework.Assert.assertTrue;
Amin Shaikh972e2362016-12-07 14:08:09 -080027import static junit.framework.Assert.fail;
Jeremy Joslin145c3432016-12-09 13:11:51 -080028
Amin Shaikh972e2362016-12-07 14:08:09 -080029import static org.mockito.Matchers.any;
30import static org.mockito.Matchers.anyInt;
31import static org.mockito.Matchers.anyListOf;
32import static org.mockito.Matchers.anyString;
33import static org.mockito.Matchers.eq;
Jeremy Joslin145c3432016-12-09 13:11:51 -080034import static org.mockito.Matchers.isA;
Jeremy Joslinc5ac5872016-11-30 15:05:40 -080035import static org.mockito.Mockito.atLeastOnce;
Jeremy Joslin145c3432016-12-09 13:11:51 -080036import static org.mockito.Mockito.doAnswer;
Amin Shaikh972e2362016-12-07 14:08:09 -080037import static org.mockito.Mockito.doThrow;
Jeremy Joslin145c3432016-12-09 13:11:51 -080038import static org.mockito.Mockito.mock;
Amin Shaikh972e2362016-12-07 14:08:09 -080039import static org.mockito.Mockito.times;
40import static org.mockito.Mockito.verify;
41import static org.mockito.Mockito.verifyNoMoreInteractions;
Jeremy Joslin145c3432016-12-09 13:11:51 -080042import static org.mockito.Mockito.verifyZeroInteractions;
Amin Shaikh972e2362016-12-07 14:08:09 -080043import static org.mockito.Mockito.when;
44
45import android.Manifest.permission;
46import android.content.ComponentName;
47import android.content.ContentResolver;
48import android.content.Context;
49import android.content.Intent;
50import android.content.ServiceConnection;
51import android.content.pm.PackageManager;
52import android.content.res.Resources;
Jeremy Joslin145c3432016-12-09 13:11:51 -080053import android.net.INetworkRecommendationProvider;
Amin Shaikh972e2362016-12-07 14:08:09 -080054import android.net.INetworkScoreCache;
55import android.net.NetworkKey;
Amin Shaikh972e2362016-12-07 14:08:09 -080056import android.net.NetworkScorerAppManager;
57import android.net.NetworkScorerAppManager.NetworkScorerAppData;
Jeremy Joslin145c3432016-12-09 13:11:51 -080058import android.net.RecommendationRequest;
59import android.net.RecommendationResult;
Amin Shaikh972e2362016-12-07 14:08:09 -080060import android.net.ScoredNetwork;
61import android.net.WifiKey;
Jeremy Joslin145c3432016-12-09 13:11:51 -080062import android.net.wifi.WifiConfiguration;
63import android.os.Bundle;
Amin Shaikh972e2362016-12-07 14:08:09 -080064import android.os.IBinder;
Jeremy Joslin145c3432016-12-09 13:11:51 -080065import android.os.IRemoteCallback;
66import android.os.Looper;
Amin Shaikh972e2362016-12-07 14:08:09 -080067import android.os.RemoteException;
68import android.os.UserHandle;
Amin Shaikh972e2362016-12-07 14:08:09 -080069import android.support.test.InstrumentationRegistry;
70import android.support.test.filters.MediumTest;
71import android.support.test.runner.AndroidJUnit4;
Jeremy Joslin145c3432016-12-09 13:11:51 -080072
Amin Shaikh972e2362016-12-07 14:08:09 -080073import com.android.server.devicepolicy.MockUtils;
Jeremy Joslin145c3432016-12-09 13:11:51 -080074
Amin Shaikh972e2362016-12-07 14:08:09 -080075import org.junit.Before;
76import org.junit.Test;
77import org.junit.runner.RunWith;
78import org.mockito.ArgumentCaptor;
79import org.mockito.Captor;
80import org.mockito.Mock;
81import org.mockito.MockitoAnnotations;
Jeremy Joslin145c3432016-12-09 13:11:51 -080082import org.mockito.invocation.InvocationOnMock;
83import org.mockito.stubbing.Answer;
84
85import java.io.FileDescriptor;
86import java.io.PrintWriter;
87import java.io.StringWriter;
88import java.util.List;
Amin Shaikh972e2362016-12-07 14:08:09 -080089
90/**
91 * Tests for {@link NetworkScoreService}.
92 */
93@RunWith(AndroidJUnit4.class)
94@MediumTest
95public class NetworkScoreServiceTest {
96 private static final ScoredNetwork SCORED_NETWORK =
97 new ScoredNetwork(new NetworkKey(new WifiKey("\"ssid\"", "00:00:00:00:00:00")),
98 null /* rssiCurve*/);
Jeremy Joslinfa4f08e2016-12-06 07:42:38 -080099 private static final NetworkScorerAppData NEW_SCORER =
100 new NetworkScorerAppData("newPackageName", 1, "newScoringServiceClass");
Amin Shaikh972e2362016-12-07 14:08:09 -0800101
102 @Mock private PackageManager mPackageManager;
103 @Mock private NetworkScorerAppManager mNetworkScorerAppManager;
104 @Mock private Context mContext;
105 @Mock private Resources mResources;
106 @Mock private INetworkScoreCache.Stub mNetworkScoreCache, mNetworkScoreCache2;
107 @Mock private IBinder mIBinder, mIBinder2;
Jeremy Joslin145c3432016-12-09 13:11:51 -0800108 @Mock private INetworkRecommendationProvider mRecommendationProvider;
Amin Shaikh972e2362016-12-07 14:08:09 -0800109 @Captor private ArgumentCaptor<List<ScoredNetwork>> mScoredNetworkCaptor;
110
111 private ContentResolver mContentResolver;
112 private NetworkScoreService mNetworkScoreService;
Jeremy Joslin145c3432016-12-09 13:11:51 -0800113 private RecommendationRequest mRecommendationRequest;
Amin Shaikh972e2362016-12-07 14:08:09 -0800114
115 @Before
116 public void setUp() throws Exception {
117 MockitoAnnotations.initMocks(this);
118 when(mNetworkScoreCache.asBinder()).thenReturn(mIBinder);
119 when(mNetworkScoreCache2.asBinder()).thenReturn(mIBinder2);
120 mContentResolver = InstrumentationRegistry.getContext().getContentResolver();
121 when(mContext.getContentResolver()).thenReturn(mContentResolver);
122 when(mContext.getResources()).thenReturn(mResources);
123 mNetworkScoreService = new NetworkScoreService(mContext, mNetworkScorerAppManager);
Jeremy Joslin145c3432016-12-09 13:11:51 -0800124 WifiConfiguration configuration = new WifiConfiguration();
125 mRecommendationRequest = new RecommendationRequest.Builder()
126 .setCurrentRecommendedWifiConfig(configuration).build();
Amin Shaikh972e2362016-12-07 14:08:09 -0800127 }
128
129 @Test
Amin Shaikh972e2362016-12-07 14:08:09 -0800130 public void testSystemRunning() {
131 when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(NEW_SCORER);
132
133 mNetworkScoreService.systemRunning();
134
135 verify(mContext).bindServiceAsUser(MockUtils.checkIntent(new Intent().setComponent(
Jeremy Joslinfa4f08e2016-12-06 07:42:38 -0800136 new ComponentName(NEW_SCORER.packageName,
137 NEW_SCORER.recommendationServiceClassName))),
Amin Shaikh972e2362016-12-07 14:08:09 -0800138 any(ServiceConnection.class),
139 eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
140 eq(UserHandle.SYSTEM));
141 }
142
143 @Test
Jeremy Joslin145c3432016-12-09 13:11:51 -0800144 public void testRequestScores_noPermission() throws Exception {
145 doThrow(new SecurityException()).when(mContext)
146 .enforceCallingOrSelfPermission(eq(permission.BROADCAST_NETWORK_PRIVILEGED),
147 anyString());
148 try {
149 mNetworkScoreService.requestScores(null);
150 fail("BROADCAST_NETWORK_PRIVILEGED not enforced.");
151 } catch (SecurityException e) {
152 // expected
153 }
154 }
155
156 @Test
157 public void testRequestScores_providerNotConnected() throws Exception {
158 assertFalse(mNetworkScoreService.requestScores(new NetworkKey[0]));
159 verifyZeroInteractions(mRecommendationProvider);
160 }
161
162 @Test
163 public void testRequestScores_providerThrowsRemoteException() throws Exception {
164 injectProvider();
165 doThrow(new RemoteException()).when(mRecommendationProvider)
166 .requestScores(any(NetworkKey[].class));
167
168 assertFalse(mNetworkScoreService.requestScores(new NetworkKey[0]));
169 }
170
171 @Test
172 public void testRequestScores_providerAvailable() throws Exception {
173 injectProvider();
174
175 final NetworkKey[] networks = new NetworkKey[0];
176 assertTrue(mNetworkScoreService.requestScores(networks));
177 verify(mRecommendationProvider).requestScores(networks);
178 }
179
180 @Test
181 public void testRequestRecommendation_noPermission() throws Exception {
182 doThrow(new SecurityException()).when(mContext)
183 .enforceCallingOrSelfPermission(eq(permission.BROADCAST_NETWORK_PRIVILEGED),
184 anyString());
185 try {
186 mNetworkScoreService.requestRecommendation(mRecommendationRequest);
187 fail("BROADCAST_NETWORK_PRIVILEGED not enforced.");
188 } catch (SecurityException e) {
189 // expected
190 }
191 }
192
193 @Test
194 public void testRequestRecommendation_mainThread() throws Exception {
195 when(mContext.getMainLooper()).thenReturn(Looper.myLooper());
196 try {
197 mNetworkScoreService.requestRecommendation(mRecommendationRequest);
198 fail("requestRecommendation run on main thread.");
199 } catch (RuntimeException e) {
200 // expected
201 }
202 }
203
204 @Test
205 public void testRequestRecommendation_providerNotConnected() throws Exception {
206 when(mContext.getMainLooper()).thenReturn(Looper.getMainLooper());
207
208 final RecommendationResult result =
209 mNetworkScoreService.requestRecommendation(mRecommendationRequest);
210 assertNotNull(result);
211 assertEquals(mRecommendationRequest.getCurrentSelectedConfig(),
212 result.getWifiConfiguration());
213 }
214
215 @Test
216 public void testRequestRecommendation_providerThrowsRemoteException() throws Exception {
217 injectProvider();
218 when(mContext.getMainLooper()).thenReturn(Looper.getMainLooper());
219 doThrow(new RemoteException()).when(mRecommendationProvider)
220 .requestRecommendation(eq(mRecommendationRequest), isA(IRemoteCallback.class),
221 anyInt());
222
223 final RecommendationResult result =
224 mNetworkScoreService.requestRecommendation(mRecommendationRequest);
225 assertNotNull(result);
226 assertEquals(mRecommendationRequest.getCurrentSelectedConfig(),
227 result.getWifiConfiguration());
228 }
229
230 @Test
231 public void testRequestRecommendation_resultReturned() throws Exception {
232 injectProvider();
233 when(mContext.getMainLooper()).thenReturn(Looper.getMainLooper());
234 final WifiConfiguration wifiConfiguration = new WifiConfiguration();
235 wifiConfiguration.SSID = "testRequestRecommendation_resultReturned";
236 final RecommendationResult providerResult =
237 new RecommendationResult(wifiConfiguration);
238 final Bundle bundle = new Bundle();
239 bundle.putParcelable(EXTRA_RECOMMENDATION_RESULT, providerResult);
240 doAnswer(invocation -> {
241 bundle.putInt(EXTRA_SEQUENCE, invocation.getArgumentAt(2, int.class));
242 invocation.getArgumentAt(1, IRemoteCallback.class).sendResult(bundle);
243 return null;
244 }).when(mRecommendationProvider)
245 .requestRecommendation(eq(mRecommendationRequest), isA(IRemoteCallback.class),
246 anyInt());
247
248 final RecommendationResult result =
249 mNetworkScoreService.requestRecommendation(mRecommendationRequest);
250 assertNotNull(result);
251 assertEquals(providerResult.getWifiConfiguration().SSID,
252 result.getWifiConfiguration().SSID);
253 }
254
255 @Test
Amin Shaikh972e2362016-12-07 14:08:09 -0800256 public void testUpdateScores_notActiveScorer() {
257 when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(false);
258
259 try {
260 mNetworkScoreService.updateScores(new ScoredNetwork[0]);
261 fail("SecurityException expected");
262 } catch (SecurityException e) {
263 // expected
264 }
265 }
266
267 @Test
268 public void testUpdateScores_oneRegisteredCache() throws RemoteException {
269 when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(true);
270
Jeremy Joslinc5ac5872016-11-30 15:05:40 -0800271 mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI,
272 mNetworkScoreCache, CACHE_FILTER_NONE);
Amin Shaikh972e2362016-12-07 14:08:09 -0800273
274 mNetworkScoreService.updateScores(new ScoredNetwork[]{SCORED_NETWORK});
275
276 verify(mNetworkScoreCache).updateScores(mScoredNetworkCaptor.capture());
277
278 assertEquals(1, mScoredNetworkCaptor.getValue().size());
279 assertEquals(SCORED_NETWORK, mScoredNetworkCaptor.getValue().get(0));
280 }
281
282 @Test
283 public void testUpdateScores_twoRegisteredCaches() throws RemoteException {
284 when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(true);
285
Jeremy Joslinc5ac5872016-11-30 15:05:40 -0800286 mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI,
287 mNetworkScoreCache, CACHE_FILTER_NONE);
Amin Shaikh972e2362016-12-07 14:08:09 -0800288 mNetworkScoreService.registerNetworkScoreCache(
Jeremy Joslinc5ac5872016-11-30 15:05:40 -0800289 NetworkKey.TYPE_WIFI, mNetworkScoreCache2, CACHE_FILTER_NONE);
Amin Shaikh972e2362016-12-07 14:08:09 -0800290
291 // updateScores should update both caches
292 mNetworkScoreService.updateScores(new ScoredNetwork[]{SCORED_NETWORK});
293
294 verify(mNetworkScoreCache).updateScores(anyListOf(ScoredNetwork.class));
295 verify(mNetworkScoreCache2).updateScores(anyListOf(ScoredNetwork.class));
296
297 mNetworkScoreService.unregisterNetworkScoreCache(
298 NetworkKey.TYPE_WIFI, mNetworkScoreCache2);
299
300 // updateScores should only update the first cache since the 2nd has been unregistered
301 mNetworkScoreService.updateScores(new ScoredNetwork[]{SCORED_NETWORK});
302
303 verify(mNetworkScoreCache, times(2)).updateScores(anyListOf(ScoredNetwork.class));
304
305 mNetworkScoreService.unregisterNetworkScoreCache(
306 NetworkKey.TYPE_WIFI, mNetworkScoreCache);
307
308 // updateScores should not update any caches since they are both unregistered
309 mNetworkScoreService.updateScores(new ScoredNetwork[]{SCORED_NETWORK});
310
Jeremy Joslinc5ac5872016-11-30 15:05:40 -0800311 // The register and unregister calls grab the binder from the score cache.
312 verify(mNetworkScoreCache, atLeastOnce()).asBinder();
313 verify(mNetworkScoreCache2, atLeastOnce()).asBinder();
Amin Shaikh972e2362016-12-07 14:08:09 -0800314 verifyNoMoreInteractions(mNetworkScoreCache, mNetworkScoreCache2);
315 }
316
317 @Test
318 public void testClearScores_notActiveScorer_noBroadcastNetworkPermission() {
319 when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(false);
320 when(mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED))
321 .thenReturn(PackageManager.PERMISSION_DENIED);
322 try {
323 mNetworkScoreService.clearScores();
324 fail("SecurityException expected");
325 } catch (SecurityException e) {
326 // expected
327 }
328 }
329
330 @Test
331 public void testClearScores_activeScorer_noBroadcastNetworkPermission() {
332 when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(true);
333 when(mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED))
334 .thenReturn(PackageManager.PERMISSION_DENIED);
335
336 mNetworkScoreService.clearScores();
337 }
338
339 @Test
340 public void testClearScores_activeScorer() throws RemoteException {
341 when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(true);
342
Jeremy Joslinc5ac5872016-11-30 15:05:40 -0800343 mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache,
344 CACHE_FILTER_NONE);
Amin Shaikh972e2362016-12-07 14:08:09 -0800345 mNetworkScoreService.clearScores();
346
347 verify(mNetworkScoreCache).clearScores();
348 }
349
350 @Test
351 public void testClearScores_notActiveScorer_hasBroadcastNetworkPermission()
352 throws RemoteException {
353 when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(false);
354 when(mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED))
355 .thenReturn(PackageManager.PERMISSION_GRANTED);
356
Jeremy Joslinc5ac5872016-11-30 15:05:40 -0800357 mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache,
358 CACHE_FILTER_NONE);
Amin Shaikh972e2362016-12-07 14:08:09 -0800359 mNetworkScoreService.clearScores();
360
361 verify(mNetworkScoreCache).clearScores();
362 }
363
364 @Test
365 public void testSetActiveScorer_noScoreNetworksPermission() {
366 doThrow(new SecurityException()).when(mContext)
367 .enforceCallingOrSelfPermission(eq(permission.SCORE_NETWORKS), anyString());
368
369 try {
370 mNetworkScoreService.setActiveScorer(null);
371 fail("SecurityException expected");
372 } catch (SecurityException e) {
373 // expected
374 }
375 }
376
377 @Test
Amin Shaikh972e2362016-12-07 14:08:09 -0800378 public void testDisableScoring_notActiveScorer_noBroadcastNetworkPermission() {
379 when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(false);
380 when(mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED))
381 .thenReturn(PackageManager.PERMISSION_DENIED);
382
383 try {
384 mNetworkScoreService.disableScoring();
385 fail("SecurityException expected");
386 } catch (SecurityException e) {
387 // expected
388 }
Amin Shaikh972e2362016-12-07 14:08:09 -0800389 }
390
391 @Test
392 public void testRegisterNetworkScoreCache_noBroadcastNetworkPermission() {
393 doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
394 eq(permission.BROADCAST_NETWORK_PRIVILEGED), anyString());
395
396 try {
397 mNetworkScoreService.registerNetworkScoreCache(
Jeremy Joslinc5ac5872016-11-30 15:05:40 -0800398 NetworkKey.TYPE_WIFI, mNetworkScoreCache, CACHE_FILTER_NONE);
Amin Shaikh972e2362016-12-07 14:08:09 -0800399 fail("SecurityException expected");
400 } catch (SecurityException e) {
401 // expected
402 }
403 }
404
405 @Test
406 public void testUnregisterNetworkScoreCache_noBroadcastNetworkPermission() {
407 doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
408 eq(permission.BROADCAST_NETWORK_PRIVILEGED), anyString());
409
410 try {
411 mNetworkScoreService.unregisterNetworkScoreCache(
412 NetworkKey.TYPE_WIFI, mNetworkScoreCache);
413 fail("SecurityException expected");
414 } catch (SecurityException e) {
415 // expected
416 }
417 }
418
419 @Test
420 public void testDump_noDumpPermission() {
421 doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
422 eq(permission.DUMP), anyString());
423
424 try {
425 mNetworkScoreService.dump(
426 new FileDescriptor(), new PrintWriter(new StringWriter()), new String[0]);
427 fail("SecurityException expected");
428 } catch (SecurityException e) {
429 // expected
430 }
431 }
432
433 @Test
434 public void testDump_doesNotCrash() {
435 when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(NEW_SCORER);
436 StringWriter stringWriter = new StringWriter();
437
438 mNetworkScoreService.dump(
439 new FileDescriptor(), new PrintWriter(stringWriter), new String[0]);
440
441 assertFalse(stringWriter.toString().isEmpty());
442 }
Jeremy Joslin145c3432016-12-09 13:11:51 -0800443
444 // "injects" the mock INetworkRecommendationProvider into the NetworkScoreService.
445 private void injectProvider() {
446 final ComponentName componentName = new ComponentName(NEW_SCORER.packageName,
447 NEW_SCORER.recommendationServiceClassName);
448 when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(NEW_SCORER);
449 when(mContext.bindServiceAsUser(isA(Intent.class), isA(ServiceConnection.class), anyInt(),
450 isA(UserHandle.class))).thenAnswer(new Answer<Boolean>() {
451 @Override
452 public Boolean answer(InvocationOnMock invocation) throws Throwable {
453 IBinder mockBinder = mock(IBinder.class);
454 when(mockBinder.queryLocalInterface(anyString()))
455 .thenReturn(mRecommendationProvider);
456 invocation.getArgumentAt(1, ServiceConnection.class)
457 .onServiceConnected(componentName, mockBinder);
458 return true;
459 }
460 });
461 mNetworkScoreService.systemRunning();
462 }
Amin Shaikh972e2362016-12-07 14:08:09 -0800463}