NetworkScoreServiceTest.java revision b8418ac89aa9d8e904b848d92c1729b7c7d90a16
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.NetworkScoreManager.CACHE_FILTER_NONE;
20import static junit.framework.Assert.assertEquals;
21import static junit.framework.Assert.assertFalse;
22import static junit.framework.Assert.fail;
23import static org.mockito.Matchers.any;
24import static org.mockito.Matchers.anyInt;
25import static org.mockito.Matchers.anyListOf;
26import static org.mockito.Matchers.anyString;
27import static org.mockito.Matchers.eq;
28import static org.mockito.Mockito.atLeastOnce;
29import static org.mockito.Mockito.doThrow;
30import static org.mockito.Mockito.times;
31import static org.mockito.Mockito.verify;
32import static org.mockito.Mockito.verifyNoMoreInteractions;
33import static org.mockito.Mockito.when;
34
35import android.Manifest.permission;
36import android.content.ComponentName;
37import android.content.ContentResolver;
38import android.content.Context;
39import android.content.Intent;
40import android.content.ServiceConnection;
41import android.content.pm.PackageManager;
42import android.content.res.Resources;
43import android.net.INetworkScoreCache;
44import android.net.NetworkKey;
45import android.net.NetworkScorerAppManager;
46import android.net.NetworkScorerAppManager.NetworkScorerAppData;
47import android.net.ScoredNetwork;
48import android.net.WifiKey;
49import android.os.IBinder;
50import android.os.RemoteException;
51import android.os.UserHandle;
52import android.support.test.InstrumentationRegistry;
53import android.support.test.filters.MediumTest;
54import android.support.test.runner.AndroidJUnit4;
55import com.android.server.devicepolicy.MockUtils;
56import java.io.FileDescriptor;
57import java.io.PrintWriter;
58import java.io.StringWriter;
59import java.util.List;
60import org.junit.Before;
61import org.junit.Test;
62import org.junit.runner.RunWith;
63import org.mockito.ArgumentCaptor;
64import org.mockito.Captor;
65import org.mockito.Mock;
66import org.mockito.MockitoAnnotations;
67
68/**
69 * Tests for {@link NetworkScoreService}.
70 */
71@RunWith(AndroidJUnit4.class)
72@MediumTest
73public class NetworkScoreServiceTest {
74    private static final ScoredNetwork SCORED_NETWORK =
75            new ScoredNetwork(new NetworkKey(new WifiKey("\"ssid\"", "00:00:00:00:00:00")),
76                    null /* rssiCurve*/);
77    private static final NetworkScorerAppData NEW_SCORER =
78        new NetworkScorerAppData("newPackageName", 1, "newScoringServiceClass");
79
80    @Mock private PackageManager mPackageManager;
81    @Mock private NetworkScorerAppManager mNetworkScorerAppManager;
82    @Mock private Context mContext;
83    @Mock private Resources mResources;
84    @Mock private INetworkScoreCache.Stub mNetworkScoreCache, mNetworkScoreCache2;
85    @Mock private IBinder mIBinder, mIBinder2;
86    @Captor private ArgumentCaptor<List<ScoredNetwork>> mScoredNetworkCaptor;
87
88    private ContentResolver mContentResolver;
89    private NetworkScoreService mNetworkScoreService;
90
91    @Before
92    public void setUp() throws Exception {
93        MockitoAnnotations.initMocks(this);
94        when(mNetworkScoreCache.asBinder()).thenReturn(mIBinder);
95        when(mNetworkScoreCache2.asBinder()).thenReturn(mIBinder2);
96        mContentResolver = InstrumentationRegistry.getContext().getContentResolver();
97        when(mContext.getContentResolver()).thenReturn(mContentResolver);
98        when(mContext.getResources()).thenReturn(mResources);
99        mNetworkScoreService = new NetworkScoreService(mContext, mNetworkScorerAppManager);
100    }
101
102    @Test
103    public void testSystemRunning() {
104        when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(NEW_SCORER);
105
106        mNetworkScoreService.systemRunning();
107
108        verify(mContext).bindServiceAsUser(MockUtils.checkIntent(new Intent().setComponent(
109                new ComponentName(NEW_SCORER.packageName,
110                    NEW_SCORER.recommendationServiceClassName))),
111                any(ServiceConnection.class),
112                eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
113                eq(UserHandle.SYSTEM));
114    }
115
116    @Test
117    public void testUpdateScores_notActiveScorer() {
118        when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(false);
119
120        try {
121            mNetworkScoreService.updateScores(new ScoredNetwork[0]);
122            fail("SecurityException expected");
123        } catch (SecurityException e) {
124            // expected
125        }
126    }
127
128    @Test
129    public void testUpdateScores_oneRegisteredCache() throws RemoteException {
130        when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(true);
131
132        mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI,
133                mNetworkScoreCache, CACHE_FILTER_NONE);
134
135        mNetworkScoreService.updateScores(new ScoredNetwork[]{SCORED_NETWORK});
136
137        verify(mNetworkScoreCache).updateScores(mScoredNetworkCaptor.capture());
138
139        assertEquals(1, mScoredNetworkCaptor.getValue().size());
140        assertEquals(SCORED_NETWORK, mScoredNetworkCaptor.getValue().get(0));
141    }
142
143    @Test
144    public void testUpdateScores_twoRegisteredCaches() throws RemoteException {
145        when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(true);
146
147        mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI,
148                mNetworkScoreCache, CACHE_FILTER_NONE);
149        mNetworkScoreService.registerNetworkScoreCache(
150                NetworkKey.TYPE_WIFI, mNetworkScoreCache2, CACHE_FILTER_NONE);
151
152        // updateScores should update both caches
153        mNetworkScoreService.updateScores(new ScoredNetwork[]{SCORED_NETWORK});
154
155        verify(mNetworkScoreCache).updateScores(anyListOf(ScoredNetwork.class));
156        verify(mNetworkScoreCache2).updateScores(anyListOf(ScoredNetwork.class));
157
158        mNetworkScoreService.unregisterNetworkScoreCache(
159                NetworkKey.TYPE_WIFI, mNetworkScoreCache2);
160
161        // updateScores should only update the first cache since the 2nd has been unregistered
162        mNetworkScoreService.updateScores(new ScoredNetwork[]{SCORED_NETWORK});
163
164        verify(mNetworkScoreCache, times(2)).updateScores(anyListOf(ScoredNetwork.class));
165
166        mNetworkScoreService.unregisterNetworkScoreCache(
167                NetworkKey.TYPE_WIFI, mNetworkScoreCache);
168
169        // updateScores should not update any caches since they are both unregistered
170        mNetworkScoreService.updateScores(new ScoredNetwork[]{SCORED_NETWORK});
171
172        // The register and unregister calls grab the binder from the score cache.
173        verify(mNetworkScoreCache, atLeastOnce()).asBinder();
174        verify(mNetworkScoreCache2, atLeastOnce()).asBinder();
175        verifyNoMoreInteractions(mNetworkScoreCache, mNetworkScoreCache2);
176    }
177
178    @Test
179    public void testClearScores_notActiveScorer_noBroadcastNetworkPermission() {
180        when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(false);
181        when(mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED))
182            .thenReturn(PackageManager.PERMISSION_DENIED);
183        try {
184            mNetworkScoreService.clearScores();
185            fail("SecurityException expected");
186        } catch (SecurityException e) {
187            // expected
188        }
189    }
190
191    @Test
192    public void testClearScores_activeScorer_noBroadcastNetworkPermission() {
193        when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(true);
194        when(mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED))
195            .thenReturn(PackageManager.PERMISSION_DENIED);
196
197        mNetworkScoreService.clearScores();
198    }
199
200    @Test
201    public void testClearScores_activeScorer() throws RemoteException {
202        when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(true);
203
204        mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache,
205                CACHE_FILTER_NONE);
206        mNetworkScoreService.clearScores();
207
208        verify(mNetworkScoreCache).clearScores();
209    }
210
211    @Test
212    public void testClearScores_notActiveScorer_hasBroadcastNetworkPermission()
213            throws RemoteException {
214        when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(false);
215        when(mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED))
216                .thenReturn(PackageManager.PERMISSION_GRANTED);
217
218        mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache,
219                CACHE_FILTER_NONE);
220        mNetworkScoreService.clearScores();
221
222        verify(mNetworkScoreCache).clearScores();
223    }
224
225    @Test
226    public void testSetActiveScorer_noScoreNetworksPermission() {
227        doThrow(new SecurityException()).when(mContext)
228                .enforceCallingOrSelfPermission(eq(permission.SCORE_NETWORKS), anyString());
229
230        try {
231            mNetworkScoreService.setActiveScorer(null);
232            fail("SecurityException expected");
233        } catch (SecurityException e) {
234            // expected
235        }
236    }
237
238    @Test
239    public void testDisableScoring_notActiveScorer_noBroadcastNetworkPermission() {
240        when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(false);
241        when(mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED))
242                .thenReturn(PackageManager.PERMISSION_DENIED);
243
244        try {
245            mNetworkScoreService.disableScoring();
246            fail("SecurityException expected");
247        } catch (SecurityException e) {
248            // expected
249        }
250    }
251
252    @Test
253    public void testRegisterNetworkScoreCache_noBroadcastNetworkPermission() {
254        doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
255                eq(permission.BROADCAST_NETWORK_PRIVILEGED), anyString());
256
257        try {
258            mNetworkScoreService.registerNetworkScoreCache(
259                NetworkKey.TYPE_WIFI, mNetworkScoreCache, CACHE_FILTER_NONE);
260            fail("SecurityException expected");
261        } catch (SecurityException e) {
262            // expected
263        }
264    }
265
266    @Test
267    public void testUnregisterNetworkScoreCache_noBroadcastNetworkPermission() {
268        doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
269                eq(permission.BROADCAST_NETWORK_PRIVILEGED), anyString());
270
271        try {
272            mNetworkScoreService.unregisterNetworkScoreCache(
273                    NetworkKey.TYPE_WIFI, mNetworkScoreCache);
274            fail("SecurityException expected");
275        } catch (SecurityException e) {
276            // expected
277        }
278    }
279
280    @Test
281    public void testDump_noDumpPermission() {
282        doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
283                eq(permission.DUMP), anyString());
284
285        try {
286            mNetworkScoreService.dump(
287                    new FileDescriptor(), new PrintWriter(new StringWriter()), new String[0]);
288            fail("SecurityException expected");
289        } catch (SecurityException e) {
290            // expected
291        }
292    }
293
294    @Test
295    public void testDump_doesNotCrash() {
296        when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(NEW_SCORER);
297        StringWriter stringWriter = new StringWriter();
298
299        mNetworkScoreService.dump(
300                new FileDescriptor(), new PrintWriter(stringWriter), new String[0]);
301
302        assertFalse(stringWriter.toString().isEmpty());
303    }
304}
305