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