WifiLockManagerTest.java revision 9563500603c158373e2ee512c4d451783c104660
1/*
2 * Copyright (C) 2010 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.wifi;
18
19import static org.hamcrest.CoreMatchers.not;
20import static org.junit.Assert.*;
21import static org.mockito.Matchers.*;
22import static org.mockito.Mockito.*;
23
24import android.content.Context;
25import android.net.wifi.WifiManager;
26import android.os.Binder;
27import android.os.IBinder;
28import android.os.WorkSource;
29import android.test.suitebuilder.annotation.SmallTest;
30
31import com.android.internal.app.IBatteryStats;
32
33import org.junit.Before;
34import org.junit.Test;
35
36import org.mockito.ArgumentCaptor;
37import org.mockito.InOrder;
38import org.mockito.Mock;
39import org.mockito.MockitoAnnotations;
40
41import java.io.PrintWriter;
42import java.io.StringWriter;
43
44/** Unit tests for {@link WifiLockManager}. */
45@SmallTest
46public class WifiLockManagerTest {
47
48    private static final int DEFAULT_TEST_UID_1 = 35;
49    private static final int DEFAULT_TEST_UID_2 = 53;
50    private static final int WIFI_LOCK_MODE_INVALID = -1;
51    private static final String TEST_WIFI_LOCK_TAG = "TestTag";
52
53    WifiLockManager mWifiLockManager;
54    @Mock IBatteryStats mBatteryStats;
55    @Mock IBinder mBinder;
56    WorkSource mWorkSource;
57    @Mock Context mContext;
58
59    /**
60     * Method to setup a WifiLockManager for the tests.
61     * The WifiLockManager uses mocks for BatteryStats and Context.
62     */
63    @Before
64    public void setUp() {
65        mWorkSource = new WorkSource(DEFAULT_TEST_UID_1);
66        MockitoAnnotations.initMocks(this);
67        mWifiLockManager = new WifiLockManager(mContext, mBatteryStats);
68    }
69
70    private void acquireWifiLockSuccessful(int lockMode, String tag, IBinder binder, WorkSource ws)
71            throws Exception {
72        ArgumentCaptor<IBinder.DeathRecipient> deathRecipient =
73                ArgumentCaptor.forClass(IBinder.DeathRecipient.class);
74
75        assertTrue(mWifiLockManager.acquireWifiLock(lockMode, tag, binder, ws));
76        assertThat(mWifiLockManager.getStrongestLockMode(),
77                not(WifiManager.WIFI_MODE_NO_LOCKS_HELD));
78        InOrder inOrder = inOrder(binder, mBatteryStats);
79        inOrder.verify(binder).linkToDeath(deathRecipient.capture(), eq(0));
80        inOrder.verify(mBatteryStats).noteFullWifiLockAcquiredFromSource(ws);
81    }
82
83    private void releaseWifiLockSuccessful(IBinder binder) throws Exception {
84        ArgumentCaptor<IBinder.DeathRecipient> deathRecipient =
85                ArgumentCaptor.forClass(IBinder.DeathRecipient.class);
86
87        assertTrue(mWifiLockManager.releaseWifiLock(binder));
88        InOrder inOrder = inOrder(binder, mBatteryStats);
89        inOrder.verify(binder).unlinkToDeath(deathRecipient.capture(), eq(0));
90        inOrder.verify(mBatteryStats).noteFullWifiLockReleasedFromSource(any(WorkSource.class));
91    }
92
93    /**
94     * Test to check that a new WifiLockManager should not be holding any locks.
95     */
96    @Test
97    public void newWifiLockManagerShouldNotHaveAnyLocks() {
98        assertEquals(WifiManager.WIFI_MODE_NO_LOCKS_HELD, mWifiLockManager.getStrongestLockMode());
99    }
100
101    /**
102     * Test to verify that the lock mode is verified before adding a lock.
103     *
104     * Steps: call acquireWifiLock with an invalid lock mode.
105     * Expected: the call should throw an IllegalArgumentException.
106     */
107    @Test(expected = IllegalArgumentException.class)
108    public void acquireWifiLockShouldThrowExceptionOnInivalidLockMode() throws Exception {
109        mWifiLockManager.acquireWifiLock(WIFI_LOCK_MODE_INVALID, "", mBinder, mWorkSource);
110    }
111
112    /**
113     * Test that a call to acquireWifiLock with valid parameters works.
114     *
115     * Steps: call acquireWifiLock on the empty WifiLockManager.
116     * Expected: A subsequent call to getStrongestLockMode should reflect the type of the lock we
117     * just added
118     */
119    @Test
120    public void acquireWifiLockWithValidParamsShouldSucceed() throws Exception {
121        acquireWifiLockSuccessful(WifiManager.WIFI_MODE_FULL, "", mBinder, mWorkSource);
122        assertEquals(WifiManager.WIFI_MODE_FULL, mWifiLockManager.getStrongestLockMode());
123    }
124
125    /**
126     * Test that a call to acquireWifiLock will not succeed if there is already a lock for the same
127     * binder instance.
128     *
129     * Steps: call acquireWifiLock twice
130     * Expected: Second call should return false
131     */
132    @Test
133    public void secondCallToAcquireWifiLockWithSameBinderShouldFail() throws Exception {
134        acquireWifiLockSuccessful(WifiManager.WIFI_MODE_SCAN_ONLY, "", mBinder, mWorkSource);
135        assertEquals(WifiManager.WIFI_MODE_SCAN_ONLY, mWifiLockManager.getStrongestLockMode());
136        assertFalse(mWifiLockManager.acquireWifiLock(
137                WifiManager.WIFI_MODE_SCAN_ONLY, "", mBinder, mWorkSource));
138    }
139
140    /**
141     * After acquiring a lock, we should be able to remove it.
142     *
143     * Steps: acquire a WifiLock and then remove it.
144     * Expected: Since a single lock was added, removing it should leave the WifiLockManager without
145     * any locks.  We should not see any errors.
146     */
147    @Test
148    public void releaseWifiLockShouldSucceed() throws Exception {
149        acquireWifiLockSuccessful(WifiManager.WIFI_MODE_FULL, "", mBinder, mWorkSource);
150        releaseWifiLockSuccessful(mBinder);
151        assertEquals(WifiManager.WIFI_MODE_NO_LOCKS_HELD, mWifiLockManager.getStrongestLockMode());
152    }
153
154    /**
155     * Releasing locks for one caller should not release locks for a different caller.
156     *
157     * Steps: acquire locks for two callers and remove locks for one.
158     * Expected: locks for remaining caller should still be active.
159     */
160    @Test
161    public void releaseLocksForOneCallerNotImpactOtherCallers() throws Exception {
162        IBinder toReleaseBinder = mock(IBinder.class);
163        WorkSource toReleaseWS = new WorkSource(DEFAULT_TEST_UID_1);
164        WorkSource toKeepWS = new WorkSource(DEFAULT_TEST_UID_2);
165
166        acquireWifiLockSuccessful(
167                WifiManager.WIFI_MODE_FULL_HIGH_PERF, "", toReleaseBinder, toReleaseWS);
168        acquireWifiLockSuccessful(WifiManager.WIFI_MODE_SCAN_ONLY, "", mBinder, toKeepWS);
169        assertEquals(mWifiLockManager.getStrongestLockMode(), WifiManager.WIFI_MODE_FULL_HIGH_PERF);
170        releaseWifiLockSuccessful(toReleaseBinder);
171        assertEquals(mWifiLockManager.getStrongestLockMode(), WifiManager.WIFI_MODE_SCAN_ONLY);
172        releaseWifiLockSuccessful(mBinder);
173        assertEquals(mWifiLockManager.getStrongestLockMode(), WifiManager.WIFI_MODE_NO_LOCKS_HELD);
174    }
175
176    /**
177     * Attempting to release a lock that we do not hold should return false.
178     *
179     * Steps: release a WifiLock
180     * Expected: call to releaseWifiLock should return false.
181     */
182    @Test
183    public void releaseWifiLockWithoutAcquireWillReturnFalse() {
184        assertFalse(mWifiLockManager.releaseWifiLock(mBinder));
185    }
186
187    /**
188     * Test used to verify call for getStrongestLockMode.
189     *
190     * Steps: The test first checks the return value for no held locks and then proceeds to test
191     * with a single lock of each type.
192     * Expected: getStrongestLockMode should reflect the type of lock we just added.
193     */
194    @Test
195    public void checkForProperValueForGetStrongestLockMode() throws Exception {
196        assertEquals(mWifiLockManager.getStrongestLockMode(), WifiManager.WIFI_MODE_NO_LOCKS_HELD);
197
198        acquireWifiLockSuccessful(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "", mBinder, mWorkSource);
199        assertEquals(mWifiLockManager.getStrongestLockMode(), WifiManager.WIFI_MODE_FULL_HIGH_PERF);
200        releaseWifiLockSuccessful(mBinder);
201
202        acquireWifiLockSuccessful(WifiManager.WIFI_MODE_FULL, "", mBinder, mWorkSource);
203        assertEquals(mWifiLockManager.getStrongestLockMode(), WifiManager.WIFI_MODE_FULL);
204        releaseWifiLockSuccessful(mBinder);
205
206        acquireWifiLockSuccessful(WifiManager.WIFI_MODE_SCAN_ONLY, "", mBinder, mWorkSource);
207        assertEquals(mWifiLockManager.getStrongestLockMode(), WifiManager.WIFI_MODE_SCAN_ONLY);
208    }
209
210    /**
211     * We should be able to create a merged WorkSource holding WorkSources for all active locks.
212     *
213     * Steps: call createMergedWorkSource and verify it is empty, add a lock and call again, it
214     * should have one entry.
215     * Expected: the first call should return a worksource with size 0 and the second should be size
216     * 1.
217     */
218    @Test
219    public void createMergedWorkSourceShouldSucceed() throws Exception {
220        WorkSource checkMWS = mWifiLockManager.createMergedWorkSource();
221        assertEquals(checkMWS.size(), 0);
222
223        acquireWifiLockSuccessful(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "", mBinder, mWorkSource);
224        checkMWS = mWifiLockManager.createMergedWorkSource();
225        assertEquals(checkMWS.size(), 1);
226    }
227
228    /**
229     * Test the ability to update a WifiLock WorkSource with a new WorkSource.
230     *
231     * Steps: acquire a WifiLock with the default test worksource, then attempt to update it.
232     * Expected: Verify calls to release the original WorkSource and acquire with the new one to
233     * BatteryStats.
234     */
235    @Test
236    public void testUpdateWifiLockWorkSourceCalledWithWorkSource() throws Exception {
237        WorkSource newWorkSource = new WorkSource(DEFAULT_TEST_UID_2);
238
239        acquireWifiLockSuccessful(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "", mBinder, mWorkSource);
240
241        mWifiLockManager.updateWifiLockWorkSource(mBinder, newWorkSource);
242        InOrder inOrder = inOrder(mBatteryStats);
243        inOrder.verify(mBatteryStats).noteFullWifiLockReleasedFromSource(mWorkSource);
244        inOrder.verify(mBatteryStats).noteFullWifiLockAcquiredFromSource(eq(newWorkSource));
245    }
246
247    /**
248     * Test the ability to update a WifiLock WorkSource with the callers UID.
249     *
250     * Steps: acquire a WifiLock with the default test worksource, then attempt to update it.
251     * Expected: Verify calls to release the original WorkSource and acquire with the new one to
252     * BatteryStats.
253     */
254    @Test
255    public void testUpdateWifiLockWorkSourceCalledWithUID()  throws Exception {
256        WorkSource newWorkSource = new WorkSource(Binder.getCallingUid());
257
258        acquireWifiLockSuccessful(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "", mBinder, mWorkSource);
259
260        mWifiLockManager.updateWifiLockWorkSource(mBinder, null);
261        InOrder inOrder = inOrder(mBatteryStats);
262        inOrder.verify(mBatteryStats).noteFullWifiLockReleasedFromSource(mWorkSource);
263        inOrder.verify(mBatteryStats).noteFullWifiLockAcquiredFromSource(eq(newWorkSource));
264    }
265
266    /**
267     * Test an attempt to update a WifiLock that is not active.
268     *
269     * Steps: call updateWifiLockWorkSource
270     * Expected: catch an IllegalArgumentException
271     */
272    @Test(expected = IllegalArgumentException.class)
273    public void testUpdateWifiLockWorkSourceCalledWithoutActiveLock()  throws Exception {
274        mWifiLockManager.updateWifiLockWorkSource(mBinder, null);
275    }
276
277    /**
278     * Verfies that dump() does not fail when no locks are held.
279     */
280    @Test
281    public void dumpDoesNotFailWhenNoLocksAreHeld() {
282        StringWriter sw = new StringWriter();
283        PrintWriter pw = new PrintWriter(sw);
284        mWifiLockManager.dump(pw);
285
286        String wifiLockManagerDumpString = sw.toString();
287        assertTrue(wifiLockManagerDumpString.contains(
288                "Locks acquired: 0 full, 0 full high perf, 0 scan"));
289        assertTrue(wifiLockManagerDumpString.contains(
290                "Locks released: 0 full, 0 full high perf, 0 scan"));
291        assertTrue(wifiLockManagerDumpString.contains("Locks held:"));
292        assertFalse(wifiLockManagerDumpString.contains("WifiLock{"));
293    }
294
295    /**
296     * Verifies that dump() contains lock information when there are locks held.
297     */
298    @Test
299    public void dumpOutputsCorrectInformationWithActiveLocks() throws Exception {
300        acquireWifiLockSuccessful(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "", mBinder, mWorkSource);
301        releaseWifiLockSuccessful(mBinder);
302
303        acquireWifiLockSuccessful(
304                WifiManager.WIFI_MODE_FULL, TEST_WIFI_LOCK_TAG, mBinder, mWorkSource);
305
306        StringWriter sw = new StringWriter();
307        PrintWriter pw = new PrintWriter(sw);
308        mWifiLockManager.dump(pw);
309
310        String wifiLockManagerDumpString = sw.toString();
311        assertTrue(wifiLockManagerDumpString.contains(
312                "Locks acquired: 1 full, 1 full high perf, 0 scan"));
313        assertTrue(wifiLockManagerDumpString.contains(
314                "Locks released: 0 full, 1 full high perf, 0 scan"));
315        assertTrue(wifiLockManagerDumpString.contains("Locks held:"));
316        assertTrue(wifiLockManagerDumpString.contains(
317                "WifiLock{" + TEST_WIFI_LOCK_TAG + " type=" + WifiManager.WIFI_MODE_FULL
318                + " uid=" + Binder.getCallingUid() + "}"));
319    }
320}
321