NetworkScoreServiceTest.java revision ce73c6f296f583223cee4385e20c640ead3ae4de
1/*
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
19import static android.net.NetworkRecommendationProvider.EXTRA_RECOMMENDATION_RESULT;
20import static android.net.NetworkRecommendationProvider.EXTRA_SEQUENCE;
21import static android.net.NetworkScoreManager.CACHE_FILTER_NONE;
22
23import static junit.framework.Assert.assertEquals;
24import static junit.framework.Assert.assertFalse;
25import static junit.framework.Assert.assertNotNull;
26import static junit.framework.Assert.assertNull;
27import static junit.framework.Assert.assertSame;
28import static junit.framework.Assert.assertTrue;
29import static junit.framework.Assert.fail;
30
31import static org.mockito.Matchers.any;
32import static org.mockito.Matchers.anyInt;
33import static org.mockito.Matchers.anyListOf;
34import static org.mockito.Matchers.anyString;
35import static org.mockito.Matchers.eq;
36import static org.mockito.Matchers.isA;
37import static org.mockito.Mockito.atLeastOnce;
38import static org.mockito.Mockito.doAnswer;
39import static org.mockito.Mockito.doThrow;
40import static org.mockito.Mockito.mock;
41import static org.mockito.Mockito.times;
42import static org.mockito.Mockito.verify;
43import static org.mockito.Mockito.verifyNoMoreInteractions;
44import static org.mockito.Mockito.verifyZeroInteractions;
45import static org.mockito.Mockito.when;
46
47import android.Manifest.permission;
48import android.content.ComponentName;
49import android.content.ContentResolver;
50import android.content.Context;
51import android.content.Intent;
52import android.content.ServiceConnection;
53import android.content.pm.PackageManager;
54import android.content.res.Resources;
55import android.net.INetworkRecommendationProvider;
56import android.net.INetworkScoreCache;
57import android.net.NetworkKey;
58import android.net.NetworkScoreManager;
59import android.net.NetworkScorerAppManager;
60import android.net.NetworkScorerAppManager.NetworkScorerAppData;
61import android.net.RecommendationRequest;
62import android.net.RecommendationResult;
63import android.net.ScoredNetwork;
64import android.net.WifiKey;
65import android.net.wifi.WifiConfiguration;
66import android.os.Binder;
67import android.os.Bundle;
68import android.os.HandlerThread;
69import android.os.IBinder;
70import android.os.IRemoteCallback;
71import android.os.Looper;
72import android.os.RemoteCallback;
73import android.os.RemoteException;
74import android.os.UserHandle;
75import android.support.test.InstrumentationRegistry;
76import android.support.test.filters.MediumTest;
77import android.support.test.runner.AndroidJUnit4;
78import android.util.Pair;
79
80import com.android.server.devicepolicy.MockUtils;
81
82import org.junit.After;
83import org.junit.Before;
84import org.junit.Test;
85import org.junit.runner.RunWith;
86import org.mockito.ArgumentCaptor;
87import org.mockito.Captor;
88import org.mockito.Mock;
89import org.mockito.MockitoAnnotations;
90import org.mockito.invocation.InvocationOnMock;
91import org.mockito.stubbing.Answer;
92
93import java.io.FileDescriptor;
94import java.io.PrintWriter;
95import java.io.StringWriter;
96import java.util.List;
97import java.util.concurrent.CountDownLatch;
98import java.util.concurrent.TimeUnit;
99
100/**
101 * Tests for {@link NetworkScoreService}.
102 */
103@RunWith(AndroidJUnit4.class)
104@MediumTest
105public class NetworkScoreServiceTest {
106    private static final ScoredNetwork SCORED_NETWORK =
107            new ScoredNetwork(new NetworkKey(new WifiKey("\"ssid\"", "00:00:00:00:00:00")),
108                    null /* rssiCurve*/);
109    private static final NetworkScorerAppData NEW_SCORER =
110        new NetworkScorerAppData("newPackageName", 1, "newScoringServiceClass");
111
112    @Mock private PackageManager mPackageManager;
113    @Mock private NetworkScorerAppManager mNetworkScorerAppManager;
114    @Mock private Context mContext;
115    @Mock private Resources mResources;
116    @Mock private INetworkScoreCache.Stub mNetworkScoreCache, mNetworkScoreCache2;
117    @Mock private IBinder mIBinder, mIBinder2;
118    @Mock private INetworkRecommendationProvider mRecommendationProvider;
119    @Captor private ArgumentCaptor<List<ScoredNetwork>> mScoredNetworkCaptor;
120
121    private ContentResolver mContentResolver;
122    private NetworkScoreService mNetworkScoreService;
123    private RecommendationRequest mRecommendationRequest;
124    private RemoteCallback mRemoteCallback;
125    private OnResultListener mOnResultListener;
126    private HandlerThread mHandlerThread;
127
128    @Before
129    public void setUp() throws Exception {
130        MockitoAnnotations.initMocks(this);
131        when(mNetworkScoreCache.asBinder()).thenReturn(mIBinder);
132        when(mNetworkScoreCache2.asBinder()).thenReturn(mIBinder2);
133        mContentResolver = InstrumentationRegistry.getContext().getContentResolver();
134        when(mContext.getContentResolver()).thenReturn(mContentResolver);
135        when(mContext.getResources()).thenReturn(mResources);
136        mHandlerThread = new HandlerThread("NetworkScoreServiceTest");
137        mHandlerThread.start();
138        mNetworkScoreService = new NetworkScoreService(mContext, mNetworkScorerAppManager,
139                mHandlerThread.getLooper());
140        WifiConfiguration configuration = new WifiConfiguration();
141        configuration.SSID = "NetworkScoreServiceTest_SSID";
142        configuration.BSSID = "NetworkScoreServiceTest_BSSID";
143        mRecommendationRequest = new RecommendationRequest.Builder()
144            .setCurrentRecommendedWifiConfig(configuration).build();
145        mOnResultListener = new OnResultListener();
146        mRemoteCallback = new RemoteCallback(mOnResultListener);
147    }
148
149    @After
150    public void tearDown() throws Exception {
151        mHandlerThread.quitSafely();
152    }
153
154    @Test
155    public void testSystemRunning() {
156        when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(NEW_SCORER);
157
158        mNetworkScoreService.systemRunning();
159
160        verify(mContext).bindServiceAsUser(MockUtils.checkIntent(
161                new Intent(NetworkScoreManager.ACTION_RECOMMEND_NETWORKS)
162                        .setComponent(new ComponentName(NEW_SCORER.packageName,
163                                NEW_SCORER.recommendationServiceClassName))),
164                any(ServiceConnection.class),
165                eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
166                eq(UserHandle.SYSTEM));
167    }
168
169    @Test
170    public void testRequestScores_noPermission() throws Exception {
171        doThrow(new SecurityException()).when(mContext)
172            .enforceCallingOrSelfPermission(eq(permission.REQUEST_NETWORK_SCORES),
173                anyString());
174        try {
175            mNetworkScoreService.requestScores(null);
176            fail("REQUEST_NETWORK_SCORES not enforced.");
177        } catch (SecurityException e) {
178            // expected
179        }
180    }
181
182    @Test
183    public void testRequestScores_providerNotConnected() throws Exception {
184        assertFalse(mNetworkScoreService.requestScores(new NetworkKey[0]));
185        verifyZeroInteractions(mRecommendationProvider);
186    }
187
188    @Test
189    public void testRequestScores_providerThrowsRemoteException() throws Exception {
190        injectProvider();
191        doThrow(new RemoteException()).when(mRecommendationProvider)
192            .requestScores(any(NetworkKey[].class));
193
194        assertFalse(mNetworkScoreService.requestScores(new NetworkKey[0]));
195    }
196
197    @Test
198    public void testRequestScores_providerAvailable() throws Exception {
199        injectProvider();
200
201        final NetworkKey[] networks = new NetworkKey[0];
202        assertTrue(mNetworkScoreService.requestScores(networks));
203        verify(mRecommendationProvider).requestScores(networks);
204    }
205
206    @Test
207    public void testRequestRecommendation_noPermission() throws Exception {
208        doThrow(new SecurityException()).when(mContext)
209            .enforceCallingOrSelfPermission(eq(permission.REQUEST_NETWORK_SCORES),
210                anyString());
211        try {
212            mNetworkScoreService.requestRecommendation(mRecommendationRequest);
213            fail("REQUEST_NETWORK_SCORES not enforced.");
214        } catch (SecurityException e) {
215            // expected
216        }
217    }
218
219    @Test
220    public void testRequestRecommendation_mainThread() throws Exception {
221        when(mContext.getMainLooper()).thenReturn(Looper.myLooper());
222        try {
223            mNetworkScoreService.requestRecommendation(mRecommendationRequest);
224            fail("requestRecommendation run on main thread.");
225        } catch (RuntimeException e) {
226            // expected
227        }
228    }
229
230    @Test
231    public void testRequestRecommendation_providerNotConnected() throws Exception {
232        when(mContext.getMainLooper()).thenReturn(Looper.getMainLooper());
233
234        final RecommendationResult result =
235                mNetworkScoreService.requestRecommendation(mRecommendationRequest);
236        assertNotNull(result);
237        assertEquals(mRecommendationRequest.getCurrentSelectedConfig(),
238                result.getWifiConfiguration());
239    }
240
241    @Test
242    public void testRequestRecommendation_providerThrowsRemoteException() throws Exception {
243        injectProvider();
244        when(mContext.getMainLooper()).thenReturn(Looper.getMainLooper());
245        doThrow(new RemoteException()).when(mRecommendationProvider)
246                .requestRecommendation(eq(mRecommendationRequest), isA(IRemoteCallback.class),
247                        anyInt());
248
249        final RecommendationResult result =
250                mNetworkScoreService.requestRecommendation(mRecommendationRequest);
251        assertNotNull(result);
252        assertEquals(mRecommendationRequest.getCurrentSelectedConfig(),
253                result.getWifiConfiguration());
254    }
255
256    @Test
257    public void testRequestRecommendation_resultReturned() throws Exception {
258        injectProvider();
259        when(mContext.getMainLooper()).thenReturn(Looper.getMainLooper());
260        final WifiConfiguration wifiConfiguration = new WifiConfiguration();
261        wifiConfiguration.SSID = "testRequestRecommendation_resultReturned_SSID";
262        wifiConfiguration.BSSID = "testRequestRecommendation_resultReturned_BSSID";
263        final RecommendationResult providerResult = RecommendationResult
264                .createConnectRecommendation(wifiConfiguration);
265        final Bundle bundle = new Bundle();
266        bundle.putParcelable(EXTRA_RECOMMENDATION_RESULT, providerResult);
267        doAnswer(invocation -> {
268            bundle.putInt(EXTRA_SEQUENCE, invocation.getArgumentAt(2, int.class));
269            invocation.getArgumentAt(1, IRemoteCallback.class).sendResult(bundle);
270            return null;
271        }).when(mRecommendationProvider)
272                .requestRecommendation(eq(mRecommendationRequest), isA(IRemoteCallback.class),
273                        anyInt());
274
275        final RecommendationResult result =
276                mNetworkScoreService.requestRecommendation(mRecommendationRequest);
277        assertNotNull(result);
278        assertEquals(providerResult.getWifiConfiguration().SSID,
279                result.getWifiConfiguration().SSID);
280        assertEquals(providerResult.getWifiConfiguration().BSSID,
281                result.getWifiConfiguration().BSSID);
282    }
283
284    @Test
285    public void testRequestRecommendationAsync_noPermission() throws Exception {
286        doThrow(new SecurityException()).when(mContext)
287                .enforceCallingOrSelfPermission(eq(permission.BROADCAST_NETWORK_PRIVILEGED),
288                        anyString());
289        try {
290            mNetworkScoreService.requestRecommendationAsync(mRecommendationRequest,
291                    mRemoteCallback);
292            fail("BROADCAST_NETWORK_PRIVILEGED not enforced.");
293        } catch (SecurityException e) {
294            // expected
295        }
296    }
297
298    @Test
299    public void testRequestRecommendationAsync_providerNotConnected() throws Exception {
300        mNetworkScoreService.requestRecommendationAsync(mRecommendationRequest,
301                mRemoteCallback);
302        boolean callbackRan = mOnResultListener.countDownLatch.await(3, TimeUnit.SECONDS);
303        assertTrue(callbackRan);
304        verifyZeroInteractions(mRecommendationProvider);
305    }
306
307    @Test
308    public void testRequestRecommendationAsync_requestTimesOut() throws Exception {
309        injectProvider();
310        mNetworkScoreService.setRecommendationRequestTimeoutMs(0L);
311        mNetworkScoreService.requestRecommendationAsync(mRecommendationRequest,
312                mRemoteCallback);
313        boolean callbackRan = mOnResultListener.countDownLatch.await(3, TimeUnit.SECONDS);
314        assertTrue(callbackRan);
315        verify(mRecommendationProvider).requestRecommendation(eq(mRecommendationRequest),
316                isA(IRemoteCallback.Stub.class), anyInt());
317    }
318
319    @Test
320    public void testRequestRecommendationAsync_requestSucceeds() throws Exception {
321        injectProvider();
322        final Bundle bundle = new Bundle();
323        doAnswer(invocation -> {
324            invocation.getArgumentAt(1, IRemoteCallback.class).sendResult(bundle);
325            return null;
326        }).when(mRecommendationProvider)
327                .requestRecommendation(eq(mRecommendationRequest), isA(IRemoteCallback.class),
328                        anyInt());
329
330        mNetworkScoreService.requestRecommendationAsync(mRecommendationRequest,
331                mRemoteCallback);
332        boolean callbackRan = mOnResultListener.countDownLatch.await(3, TimeUnit.SECONDS);
333        assertTrue(callbackRan);
334        // If it's not the same instance then something else ran the callback.
335        assertSame(bundle, mOnResultListener.receivedBundle);
336    }
337
338    @Test
339    public void testRequestRecommendationAsync_requestThrowsRemoteException() throws Exception {
340        injectProvider();
341        doThrow(new RemoteException()).when(mRecommendationProvider)
342                .requestRecommendation(eq(mRecommendationRequest), isA(IRemoteCallback.class),
343                        anyInt());
344
345        mNetworkScoreService.requestRecommendationAsync(mRecommendationRequest,
346                mRemoteCallback);
347        boolean callbackRan = mOnResultListener.countDownLatch.await(3, TimeUnit.SECONDS);
348        assertTrue(callbackRan);
349    }
350
351    @Test
352    public void oneTimeCallback_multipleCallbacks() throws Exception {
353        NetworkScoreService.OneTimeCallback callback =
354                new NetworkScoreService.OneTimeCallback(mRemoteCallback);
355        callback.sendResult(null);
356        callback.sendResult(null);
357        assertEquals(1, mOnResultListener.resultCount);
358    }
359
360    @Test
361    public void serviceHandler_timeoutMsg() throws Exception {
362        NetworkScoreService.ServiceHandler handler =
363                new NetworkScoreService.ServiceHandler(mHandlerThread.getLooper());
364        NetworkScoreService.OneTimeCallback callback =
365                new NetworkScoreService.OneTimeCallback(mRemoteCallback);
366        final Pair<RecommendationRequest, NetworkScoreService.OneTimeCallback> pair =
367                Pair.create(mRecommendationRequest, callback);
368        handler.obtainMessage(
369                NetworkScoreService.ServiceHandler.MSG_RECOMMENDATION_REQUEST_TIMEOUT, pair)
370                .sendToTarget();
371
372        boolean callbackRan = mOnResultListener.countDownLatch.await(3, TimeUnit.SECONDS);
373        assertTrue(callbackRan);
374        assertTrue(mOnResultListener.receivedBundle.containsKey(EXTRA_RECOMMENDATION_RESULT));
375        RecommendationResult result =
376                mOnResultListener.receivedBundle.getParcelable(EXTRA_RECOMMENDATION_RESULT);
377        assertTrue(result.hasRecommendation());
378        assertEquals(mRecommendationRequest.getCurrentSelectedConfig().SSID,
379                result.getWifiConfiguration().SSID);
380    }
381
382    @Test
383    public void testUpdateScores_notActiveScorer() {
384        bindToScorer(false /*callerIsScorer*/);
385
386        try {
387            mNetworkScoreService.updateScores(new ScoredNetwork[0]);
388            fail("SecurityException expected");
389        } catch (SecurityException e) {
390            // expected
391        }
392    }
393
394    @Test
395    public void testUpdateScores_oneRegisteredCache() throws RemoteException {
396        bindToScorer(true /*callerIsScorer*/);
397
398        mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI,
399                mNetworkScoreCache, CACHE_FILTER_NONE);
400
401        mNetworkScoreService.updateScores(new ScoredNetwork[]{SCORED_NETWORK});
402
403        verify(mNetworkScoreCache).updateScores(mScoredNetworkCaptor.capture());
404
405        assertEquals(1, mScoredNetworkCaptor.getValue().size());
406        assertEquals(SCORED_NETWORK, mScoredNetworkCaptor.getValue().get(0));
407    }
408
409    @Test
410    public void testUpdateScores_twoRegisteredCaches() throws RemoteException {
411        bindToScorer(true /*callerIsScorer*/);
412
413        mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI,
414                mNetworkScoreCache, CACHE_FILTER_NONE);
415        mNetworkScoreService.registerNetworkScoreCache(
416                NetworkKey.TYPE_WIFI, mNetworkScoreCache2, CACHE_FILTER_NONE);
417
418        // updateScores should update both caches
419        mNetworkScoreService.updateScores(new ScoredNetwork[]{SCORED_NETWORK});
420
421        verify(mNetworkScoreCache).updateScores(anyListOf(ScoredNetwork.class));
422        verify(mNetworkScoreCache2).updateScores(anyListOf(ScoredNetwork.class));
423
424        mNetworkScoreService.unregisterNetworkScoreCache(
425                NetworkKey.TYPE_WIFI, mNetworkScoreCache2);
426
427        // updateScores should only update the first cache since the 2nd has been unregistered
428        mNetworkScoreService.updateScores(new ScoredNetwork[]{SCORED_NETWORK});
429
430        verify(mNetworkScoreCache, times(2)).updateScores(anyListOf(ScoredNetwork.class));
431
432        mNetworkScoreService.unregisterNetworkScoreCache(
433                NetworkKey.TYPE_WIFI, mNetworkScoreCache);
434
435        // updateScores should not update any caches since they are both unregistered
436        mNetworkScoreService.updateScores(new ScoredNetwork[]{SCORED_NETWORK});
437
438        // The register and unregister calls grab the binder from the score cache.
439        verify(mNetworkScoreCache, atLeastOnce()).asBinder();
440        verify(mNetworkScoreCache2, atLeastOnce()).asBinder();
441        verifyNoMoreInteractions(mNetworkScoreCache, mNetworkScoreCache2);
442    }
443
444    @Test
445    public void testClearScores_notActiveScorer_noRequestNetworkScoresPermission() {
446        bindToScorer(false /*callerIsScorer*/);
447        when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES))
448            .thenReturn(PackageManager.PERMISSION_DENIED);
449        try {
450            mNetworkScoreService.clearScores();
451            fail("SecurityException expected");
452        } catch (SecurityException e) {
453            // expected
454        }
455    }
456
457    @Test
458    public void testClearScores_activeScorer_noRequestNetworkScoresPermission() {
459        bindToScorer(true /*callerIsScorer*/);
460        when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES))
461            .thenReturn(PackageManager.PERMISSION_DENIED);
462
463        mNetworkScoreService.clearScores();
464    }
465
466    @Test
467    public void testClearScores_activeScorer() throws RemoteException {
468        bindToScorer(true /*callerIsScorer*/);
469
470        mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache,
471                CACHE_FILTER_NONE);
472        mNetworkScoreService.clearScores();
473
474        verify(mNetworkScoreCache).clearScores();
475    }
476
477    @Test
478    public void testClearScores_notActiveScorer_hasRequestNetworkScoresPermission()
479            throws RemoteException {
480        bindToScorer(false /*callerIsScorer*/);
481        when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES))
482                .thenReturn(PackageManager.PERMISSION_GRANTED);
483
484        mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache,
485                CACHE_FILTER_NONE);
486        mNetworkScoreService.clearScores();
487
488        verify(mNetworkScoreCache).clearScores();
489    }
490
491    @Test
492    public void testSetActiveScorer_noScoreNetworksPermission() {
493        doThrow(new SecurityException()).when(mContext)
494                .enforceCallingOrSelfPermission(eq(permission.SCORE_NETWORKS), anyString());
495
496        try {
497            mNetworkScoreService.setActiveScorer(null);
498            fail("SecurityException expected");
499        } catch (SecurityException e) {
500            // expected
501        }
502    }
503
504    @Test
505    public void testDisableScoring_notActiveScorer_noRequestNetworkScoresPermission() {
506        bindToScorer(false /*callerIsScorer*/);
507        when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES))
508                .thenReturn(PackageManager.PERMISSION_DENIED);
509
510        try {
511            mNetworkScoreService.disableScoring();
512            fail("SecurityException expected");
513        } catch (SecurityException e) {
514            // expected
515        }
516    }
517
518    @Test
519    public void testRegisterNetworkScoreCache_noRequestNetworkScoresPermission() {
520        doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
521                eq(permission.REQUEST_NETWORK_SCORES), anyString());
522
523        try {
524            mNetworkScoreService.registerNetworkScoreCache(
525                NetworkKey.TYPE_WIFI, mNetworkScoreCache, CACHE_FILTER_NONE);
526            fail("SecurityException expected");
527        } catch (SecurityException e) {
528            // expected
529        }
530    }
531
532    @Test
533    public void testUnregisterNetworkScoreCache_noRequestNetworkScoresPermission() {
534        doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
535                eq(permission.REQUEST_NETWORK_SCORES), anyString());
536
537        try {
538            mNetworkScoreService.unregisterNetworkScoreCache(
539                    NetworkKey.TYPE_WIFI, mNetworkScoreCache);
540            fail("SecurityException expected");
541        } catch (SecurityException e) {
542            // expected
543        }
544    }
545
546    @Test
547    public void testDump_noDumpPermission() {
548        doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
549                eq(permission.DUMP), anyString());
550
551        try {
552            mNetworkScoreService.dump(
553                    new FileDescriptor(), new PrintWriter(new StringWriter()), new String[0]);
554            fail("SecurityException expected");
555        } catch (SecurityException e) {
556            // expected
557        }
558    }
559
560    @Test
561    public void testDump_doesNotCrash() {
562        when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(NEW_SCORER);
563        StringWriter stringWriter = new StringWriter();
564
565        mNetworkScoreService.dump(
566                new FileDescriptor(), new PrintWriter(stringWriter), new String[0]);
567
568        assertFalse(stringWriter.toString().isEmpty());
569    }
570
571    @Test
572    public void testIsCallerActiveScorer_noBoundService() throws Exception {
573        mNetworkScoreService.systemRunning();
574
575        assertFalse(mNetworkScoreService.isCallerActiveScorer(Binder.getCallingUid()));
576    }
577
578    @Test
579    public void testIsCallerActiveScorer_boundServiceIsNotCaller() throws Exception {
580        bindToScorer(false /*callerIsScorer*/);
581
582        assertFalse(mNetworkScoreService.isCallerActiveScorer(Binder.getCallingUid()));
583    }
584
585    @Test
586    public void testIsCallerActiveScorer_boundServiceIsCaller() throws Exception {
587        bindToScorer(true /*callerIsScorer*/);
588
589        assertTrue(mNetworkScoreService.isCallerActiveScorer(Binder.getCallingUid()));
590    }
591
592    @Test
593    public void testGetActiveScorerPackage_notActive() throws Exception {
594        mNetworkScoreService.systemRunning();
595
596        assertNull(mNetworkScoreService.getActiveScorerPackage());
597    }
598
599    @Test
600    public void testGetActiveScorerPackage_active() throws Exception {
601        when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(NEW_SCORER);
602        mNetworkScoreService.systemRunning();
603
604        assertEquals(NEW_SCORER.packageName, mNetworkScoreService.getActiveScorerPackage());
605    }
606
607    // "injects" the mock INetworkRecommendationProvider into the NetworkScoreService.
608    private void injectProvider() {
609        final ComponentName componentName = new ComponentName(NEW_SCORER.packageName,
610                NEW_SCORER.recommendationServiceClassName);
611        when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(NEW_SCORER);
612        when(mContext.bindServiceAsUser(isA(Intent.class), isA(ServiceConnection.class), anyInt(),
613                isA(UserHandle.class))).thenAnswer(new Answer<Boolean>() {
614            @Override
615            public Boolean answer(InvocationOnMock invocation) throws Throwable {
616                IBinder mockBinder = mock(IBinder.class);
617                when(mockBinder.queryLocalInterface(anyString()))
618                        .thenReturn(mRecommendationProvider);
619                invocation.getArgumentAt(1, ServiceConnection.class)
620                        .onServiceConnected(componentName, mockBinder);
621                return true;
622            }
623        });
624        mNetworkScoreService.systemRunning();
625    }
626
627    private void bindToScorer(boolean callerIsScorer) {
628        final int callingUid = callerIsScorer ? Binder.getCallingUid() : 0;
629        NetworkScorerAppData appData = new NetworkScorerAppData(NEW_SCORER.packageName,
630                callingUid, NEW_SCORER.recommendationServiceClassName);
631        when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(appData);
632        when(mContext.bindServiceAsUser(isA(Intent.class), isA(ServiceConnection.class), anyInt(),
633                isA(UserHandle.class))).thenReturn(true);
634        mNetworkScoreService.systemRunning();
635    }
636
637    private static class OnResultListener implements RemoteCallback.OnResultListener {
638        private final CountDownLatch countDownLatch = new CountDownLatch(1);
639        private int resultCount;
640        private Bundle receivedBundle;
641
642        @Override
643        public void onResult(Bundle result) {
644            countDownLatch.countDown();
645            resultCount++;
646            receivedBundle = result;
647        }
648    }
649}
650