blob: 40c47f4bfc41a76c66534b45a7c1dcc6dd3c1add [file] [log] [blame]
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.wifi;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import android.app.ActivityManager;
import android.content.Context;
import android.net.wifi.WifiManager;
import android.os.BatteryStatsManager;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.WorkSource;
import android.os.test.TestLooper;
import androidx.test.filters.SmallTest;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.NoSuchElementException;
/** Unit tests for {@link WifiLockManager}. */
@SmallTest
public class WifiLockManagerTest extends WifiBaseTest {
private static final int DEFAULT_TEST_UID_1 = 52;
private static final int DEFAULT_TEST_UID_2 = 53;
private static final int DEFAULT_TEST_UID_3 = 54;
private static final int DEFAULT_TEST_UID_4 = 55;
private static final int WIFI_LOCK_MODE_INVALID = -1;
private static final String TEST_WIFI_LOCK_TAG = "TestTag";
private static final String INTERFACE_NAME = "IfaceName";
private ActivityManager.OnUidImportanceListener mUidImportanceListener;
WifiLockManager mWifiLockManager;
@Mock Clock mClock;
@Mock BatteryStatsManager mBatteryStats;
@Mock IBinder mBinder;
@Mock IBinder mBinder2;
WorkSource mWorkSource;
WorkSource mChainedWorkSource;
@Mock Context mContext;
@Mock ClientModeImpl mClientModeImpl;
@Mock FrameworkFacade mFrameworkFacade;
@Mock ActivityManager mActivityManager;
@Mock WifiMetrics mWifiMetrics;
@Mock WifiNative mWifiNative;
TestLooper mLooper;
Handler mHandler;
/**
* Method to setup a WifiLockManager for the tests.
* The WifiLockManager uses mocks for BatteryStats and Context.
*/
@Before
public void setUp() {
mWorkSource = new WorkSource(DEFAULT_TEST_UID_1);
mChainedWorkSource = new WorkSource();
mChainedWorkSource.createWorkChain()
.addNode(DEFAULT_TEST_UID_1, "tag1")
.addNode(DEFAULT_TEST_UID_2, "tag2");
MockitoAnnotations.initMocks(this);
mLooper = new TestLooper();
mHandler = new Handler(mLooper.getLooper());
when(mContext.getSystemService(Context.ACTIVITY_SERVICE)).thenReturn(mActivityManager);
when(mWifiNative.getClientInterfaceName()).thenReturn(INTERFACE_NAME);
mWifiLockManager = new WifiLockManager(mContext, mBatteryStats,
mClientModeImpl, mFrameworkFacade, mHandler, mWifiNative, mClock, mWifiMetrics);
}
private void acquireWifiLockSuccessful(int lockMode, String tag, IBinder binder, WorkSource ws)
throws Exception {
ArgumentCaptor<IBinder.DeathRecipient> deathRecipient =
ArgumentCaptor.forClass(IBinder.DeathRecipient.class);
mWifiLockManager.updateWifiClientConnected(true);
assertTrue(mWifiLockManager.acquireWifiLock(lockMode, tag, binder, ws));
assertThat(mWifiLockManager.getStrongestLockMode(),
not(WifiManager.WIFI_MODE_NO_LOCKS_HELD));
InOrder inOrder = inOrder(binder, mBatteryStats);
inOrder.verify(binder).linkToDeath(deathRecipient.capture(), eq(0));
inOrder.verify(mBatteryStats).reportFullWifiLockAcquiredFromSource(ws);
}
private void captureUidImportanceListener() {
ArgumentCaptor<ActivityManager.OnUidImportanceListener> uidImportanceListener =
ArgumentCaptor.forClass(ActivityManager.OnUidImportanceListener.class);
verify(mActivityManager).addOnUidImportanceListener(uidImportanceListener.capture(),
anyInt());
mUidImportanceListener = uidImportanceListener.getValue();
assertNotNull(mUidImportanceListener);
}
private void releaseWifiLockSuccessful(IBinder binder) throws Exception {
ArgumentCaptor<IBinder.DeathRecipient> deathRecipient =
ArgumentCaptor.forClass(IBinder.DeathRecipient.class);
assertTrue(mWifiLockManager.releaseWifiLock(binder));
InOrder inOrder = inOrder(binder, mBatteryStats);
inOrder.verify(binder).unlinkToDeath(deathRecipient.capture(), eq(0));
inOrder.verify(mBatteryStats).reportFullWifiLockReleasedFromSource(any(WorkSource.class));
}
private void releaseWifiLockSuccessful_noBatteryStats(IBinder binder) throws Exception {
ArgumentCaptor<IBinder.DeathRecipient> deathRecipient =
ArgumentCaptor.forClass(IBinder.DeathRecipient.class);
assertTrue(mWifiLockManager.releaseWifiLock(binder));
InOrder inOrder = inOrder(binder, mBatteryStats);
inOrder.verify(binder).unlinkToDeath(deathRecipient.capture(), eq(0));
}
private void releaseLowLatencyWifiLockSuccessful(IBinder binder) throws Exception {
ArgumentCaptor<IBinder.DeathRecipient> deathRecipient =
ArgumentCaptor.forClass(IBinder.DeathRecipient.class);
assertTrue(mWifiLockManager.releaseWifiLock(binder));
InOrder inOrder = inOrder(binder, mBatteryStats);
inOrder.verify(binder).unlinkToDeath(deathRecipient.capture(), eq(0));
inOrder.verify(mBatteryStats).reportFullWifiLockReleasedFromSource(any(WorkSource.class));
}
/**
* Test to check that a new WifiLockManager should not be holding any locks.
*/
@Test
public void newWifiLockManagerShouldNotHaveAnyLocks() {
assertEquals(WifiManager.WIFI_MODE_NO_LOCKS_HELD, mWifiLockManager.getStrongestLockMode());
}
/**
* Test that a call to acquireWifiLock with valid parameters works.
*
* Steps: call acquireWifiLock on the empty WifiLockManager.
* Expected: A subsequent call to getStrongestLockMode should reflect the type of the lock we
* just added
*/
@Test
public void acquireWifiLockWithValidParamsShouldSucceed() throws Exception {
acquireWifiLockSuccessful(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "", mBinder, mWorkSource);
assertEquals(WifiManager.WIFI_MODE_FULL_HIGH_PERF, mWifiLockManager.getStrongestLockMode());
}
/**
* Test that a call to acquireWifiLock will not succeed if there is already a lock for the same
* binder instance.
*
* Steps: call acquireWifiLock twice
* Expected: Second call should return false
*/
@Test
public void secondCallToAcquireWifiLockWithSameBinderShouldFail() throws Exception {
acquireWifiLockSuccessful(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "", mBinder, mWorkSource);
assertEquals(WifiManager.WIFI_MODE_FULL_HIGH_PERF,
mWifiLockManager.getStrongestLockMode());
assertFalse(mWifiLockManager.acquireWifiLock(
WifiManager.WIFI_MODE_FULL_HIGH_PERF, "", mBinder, mWorkSource));
}
/**
* After acquiring a lock, we should be able to remove it.
*
* Steps: acquire a WifiLock and then remove it.
* Expected: Since a single lock was added, removing it should leave the WifiLockManager without
* any locks. We should not see any errors.
*/
@Test
public void releaseWifiLockShouldSucceed() throws Exception {
acquireWifiLockSuccessful(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "", mBinder, mWorkSource);
releaseWifiLockSuccessful(mBinder);
verify(mWifiMetrics).addWifiLockAcqSession(eq(WifiManager.WIFI_MODE_FULL_HIGH_PERF),
anyLong());
assertEquals(WifiManager.WIFI_MODE_NO_LOCKS_HELD, mWifiLockManager.getStrongestLockMode());
}
/**
* Releasing locks for one caller should not release locks for a different caller.
*
* Steps: acquire locks for two callers and remove locks for one.
* Expected: locks for remaining caller should still be active.
*/
@Test
public void releaseLocksForOneCallerNotImpactOtherCallers() throws Exception {
IBinder toReleaseBinder = mock(IBinder.class);
WorkSource toReleaseWS = new WorkSource(DEFAULT_TEST_UID_1);
WorkSource toKeepWS = new WorkSource(DEFAULT_TEST_UID_2);
acquireWifiLockSuccessful(
WifiManager.WIFI_MODE_FULL_HIGH_PERF, "", toReleaseBinder, toReleaseWS);
acquireWifiLockSuccessful(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "", mBinder, toKeepWS);
assertEquals(WifiManager.WIFI_MODE_FULL_HIGH_PERF, mWifiLockManager.getStrongestLockMode());
releaseWifiLockSuccessful(toReleaseBinder);
assertEquals(WifiManager.WIFI_MODE_FULL_HIGH_PERF, mWifiLockManager.getStrongestLockMode());
releaseWifiLockSuccessful(mBinder);
assertEquals(WifiManager.WIFI_MODE_NO_LOCKS_HELD, mWifiLockManager.getStrongestLockMode());
}
/**
* Attempting to release a lock that we do not hold should return false.
*
* Steps: release a WifiLock
* Expected: call to releaseWifiLock should return false.
*/
@Test
public void releaseWifiLockWithoutAcquireWillReturnFalse() {
assertFalse(mWifiLockManager.releaseWifiLock(mBinder));
}
/**
* Test used to verify call for getStrongestLockMode.
*
* Steps: The test first checks the return value for no held locks and then proceeds to test
* with a single lock of each type.
* Expected: getStrongestLockMode should reflect the type of lock we just added.
* Note: getStrongestLockMode should not reflect deprecated lock types
*/
@Test
public void checkForProperValueForGetStrongestLockMode() throws Exception {
assertEquals(WifiManager.WIFI_MODE_NO_LOCKS_HELD, mWifiLockManager.getStrongestLockMode());
acquireWifiLockSuccessful(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "", mBinder, mWorkSource);
assertEquals(WifiManager.WIFI_MODE_FULL_HIGH_PERF, mWifiLockManager.getStrongestLockMode());
releaseWifiLockSuccessful(mBinder);
assertTrue(mWifiLockManager.acquireWifiLock(WifiManager.WIFI_MODE_FULL, "",
mBinder, mWorkSource));
assertEquals(WifiManager.WIFI_MODE_NO_LOCKS_HELD, mWifiLockManager.getStrongestLockMode());
releaseWifiLockSuccessful(mBinder);
assertTrue(mWifiLockManager.acquireWifiLock(WifiManager.WIFI_MODE_SCAN_ONLY, "",
mBinder, mWorkSource));
assertEquals(WifiManager.WIFI_MODE_NO_LOCKS_HELD, mWifiLockManager.getStrongestLockMode());
}
/**
* We should be able to create a merged WorkSource holding WorkSources for all active locks.
*
* Steps: call createMergedWorkSource and verify it is empty, add a lock and call again, it
* should have one entry.
* Expected: the first call should return a worksource with size 0 and the second should be size
* 1.
*/
@Test
public void createMergedWorkSourceShouldSucceed() throws Exception {
WorkSource checkMWS = mWifiLockManager.createMergedWorkSource();
assertEquals(0, checkMWS.size());
acquireWifiLockSuccessful(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "", mBinder, mWorkSource);
checkMWS = mWifiLockManager.createMergedWorkSource();
assertEquals(1, checkMWS.size());
}
/**
* Checks that WorkChains are preserved when merged WorkSources are created.
*/
@Test
public void createMergedworkSourceWithChainsShouldSucceed() throws Exception {
acquireWifiLockSuccessful(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "", mBinder, mWorkSource);
acquireWifiLockSuccessful(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "", mBinder2,
mChainedWorkSource);
WorkSource merged = mWifiLockManager.createMergedWorkSource();
assertEquals(1, merged.size());
assertEquals(1, merged.getWorkChains().size());
}
/**
* A smoke test for acquiring, updating and releasing WifiLocks with chained WorkSources.
*/
@Test
public void smokeTestLockLifecycleWithChainedWorkSource() throws Exception {
acquireWifiLockSuccessful(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "", mBinder,
mChainedWorkSource);
WorkSource updated = new WorkSource();
updated.set(mChainedWorkSource);
updated.createWorkChain().addNode(
DEFAULT_TEST_UID_1, "chain2");
mWifiLockManager.updateWifiLockWorkSource(mBinder, updated);
InOrder inOrder = inOrder(mBatteryStats);
inOrder.verify(mBatteryStats).reportFullWifiLockAcquiredFromSource(eq(updated));
inOrder.verify(mBatteryStats).reportFullWifiLockReleasedFromSource(mChainedWorkSource);
releaseWifiLockSuccessful(mBinder);
}
/**
* Test the ability to update a WifiLock WorkSource with a new WorkSource.
*
* Steps: acquire a WifiLock with the default test worksource, then attempt to update it.
* Expected: Verify calls to release the original WorkSource and acquire with the new one to
* BatteryStats.
*/
@Test
public void testUpdateWifiLockWorkSourceCalledWithWorkSource() throws Exception {
WorkSource newWorkSource = new WorkSource(DEFAULT_TEST_UID_2);
acquireWifiLockSuccessful(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "", mBinder, mWorkSource);
mWifiLockManager.updateWifiLockWorkSource(mBinder, newWorkSource);
InOrder inOrder = inOrder(mBatteryStats);
inOrder.verify(mBatteryStats).reportFullWifiLockAcquiredFromSource(eq(newWorkSource));
inOrder.verify(mBatteryStats).reportFullWifiLockReleasedFromSource(mWorkSource);
}
/**
* Test the ability to update a WifiLock WorkSource with the callers UID.
*
* Steps: acquire a WifiLock with the default test worksource, then attempt to update it.
* Expected: Verify calls to release the original WorkSource and acquire with the new one to
* BatteryStats.
*/
@Test
public void testUpdateWifiLockWorkSourceCalledWithUID() throws Exception {
WorkSource newWorkSource = new WorkSource(Binder.getCallingUid());
acquireWifiLockSuccessful(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "", mBinder, mWorkSource);
mWifiLockManager.updateWifiLockWorkSource(mBinder, newWorkSource);
InOrder inOrder = inOrder(mBatteryStats);
inOrder.verify(mBatteryStats).reportFullWifiLockAcquiredFromSource(eq(newWorkSource));
inOrder.verify(mBatteryStats).reportFullWifiLockReleasedFromSource(mWorkSource);
}
/**
* Test an attempt to update a WifiLock that is not allocated.
*
* Steps: call updateWifiLockWorkSource
* Expected: catch an IllegalArgumentException
*/
@Test(expected = IllegalArgumentException.class)
public void testUpdateWifiLockWorkSourceCalledWithoutActiveLock() throws Exception {
mWifiLockManager.updateWifiLockWorkSource(mBinder, null);
}
/**
* Test when acquiring a hi-perf lock,
* WifiLockManager calls to disable power save mechanism.
*/
@Test
public void testHiPerfLockAcquireCauseDisablePS() throws Exception {
acquireWifiLockSuccessful(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "",
mBinder, mWorkSource);
assertEquals(WifiManager.WIFI_MODE_FULL_HIGH_PERF,
mWifiLockManager.getStrongestLockMode());
verify(mClientModeImpl).setPowerSave(false);
}
/**
* Test when releasing a hi-perf lock,
* WifiLockManager calls to enable power save mechanism.
*/
@Test
public void testHiPerfLockReleaseCauseEnablePS() throws Exception {
InOrder inOrder = inOrder(mClientModeImpl);
when(mClientModeImpl.setPowerSave(anyBoolean())).thenReturn(true);
acquireWifiLockSuccessful(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "",
mBinder, mWorkSource);
assertEquals(WifiManager.WIFI_MODE_FULL_HIGH_PERF,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl).setPowerSave(false);
releaseWifiLockSuccessful(mBinder);
assertEquals(WifiManager.WIFI_MODE_NO_LOCKS_HELD,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl).setPowerSave(true);
verify(mWifiMetrics).addWifiLockActiveSession(eq(WifiManager.WIFI_MODE_FULL_HIGH_PERF),
anyLong());
}
/**
* Test when acquiring two hi-perf locks, then releasing them.
* WifiLockManager calls to disable/enable power save mechanism only once.
*/
@Test
public void testHiPerfLockAcquireReleaseTwice() throws Exception {
InOrder inOrder = inOrder(mClientModeImpl);
when(mClientModeImpl.setPowerSave(anyBoolean())).thenReturn(true);
// Acquire the first lock
acquireWifiLockSuccessful(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "",
mBinder, mWorkSource);
assertEquals(WifiManager.WIFI_MODE_FULL_HIGH_PERF,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl).setPowerSave(false);
// Now acquire another lock
acquireWifiLockSuccessful(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "",
mBinder2, mWorkSource);
assertEquals(WifiManager.WIFI_MODE_FULL_HIGH_PERF,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl, never()).setPowerSave(anyBoolean());
// Release the first lock
releaseWifiLockSuccessful(mBinder);
verify(mWifiMetrics).addWifiLockAcqSession(eq(WifiManager.WIFI_MODE_FULL_HIGH_PERF),
anyLong());
assertEquals(WifiManager.WIFI_MODE_FULL_HIGH_PERF,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl, never()).setPowerSave(anyBoolean());
// Release the second lock
releaseWifiLockSuccessful(mBinder2);
verify(mWifiMetrics).addWifiLockActiveSession(eq(WifiManager.WIFI_MODE_FULL_HIGH_PERF),
anyLong());
assertEquals(WifiManager.WIFI_MODE_NO_LOCKS_HELD,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl).setPowerSave(true);
verify(mWifiMetrics).addWifiLockActiveSession(eq(WifiManager.WIFI_MODE_FULL_HIGH_PERF),
anyLong());
}
/**
* Test when acquiring/releasing deprecated locks does not result in any action .
*/
@Test
public void testFullScanOnlyAcquireRelease() throws Exception {
IBinder fullLockBinder = mock(IBinder.class);
WorkSource fullLockWS = new WorkSource(DEFAULT_TEST_UID_1);
IBinder scanOnlyLockBinder = mock(IBinder.class);
WorkSource scanOnlyLockWS = new WorkSource(DEFAULT_TEST_UID_2);
InOrder inOrder = inOrder(mClientModeImpl);
when(mClientModeImpl.setPowerSave(anyBoolean())).thenReturn(true);
// Acquire the first lock as FULL
assertTrue(mWifiLockManager.acquireWifiLock(WifiManager.WIFI_MODE_FULL, "",
fullLockBinder, fullLockWS));
assertEquals(WifiManager.WIFI_MODE_NO_LOCKS_HELD,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl, never()).setPowerSave(anyBoolean());
// Now acquire another lock with SCAN-ONLY
assertTrue(mWifiLockManager.acquireWifiLock(WifiManager.WIFI_MODE_SCAN_ONLY, "",
scanOnlyLockBinder, scanOnlyLockWS));
assertEquals(WifiManager.WIFI_MODE_NO_LOCKS_HELD,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl, never()).setPowerSave(anyBoolean());
// Release the FULL lock
releaseWifiLockSuccessful_noBatteryStats(fullLockBinder);
assertEquals(WifiManager.WIFI_MODE_NO_LOCKS_HELD,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl, never()).setPowerSave(anyBoolean());
// Release the SCAN-ONLY lock
releaseWifiLockSuccessful_noBatteryStats(scanOnlyLockBinder);
assertEquals(WifiManager.WIFI_MODE_NO_LOCKS_HELD,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl, never()).setPowerSave(anyBoolean());
}
/**
* Test failure case when setPowerSave() fails, during acquisition of hi-perf lock
* Note, the lock is still acquired despite the failure in setPowerSave().
* On any new lock activity, the setPowerSave() will be attempted if still needed.
*/
@Test
public void testHiPerfLockAcquireFail() throws Exception {
IBinder fullLockBinder = mock(IBinder.class);
WorkSource fullLockWS = new WorkSource(DEFAULT_TEST_UID_1);
InOrder inOrder = inOrder(mClientModeImpl);
when(mClientModeImpl.setPowerSave(anyBoolean())).thenReturn(false);
acquireWifiLockSuccessful(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "",
mBinder, mWorkSource);
assertEquals(WifiManager.WIFI_MODE_FULL_HIGH_PERF,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl).setPowerSave(false);
// Now attempting adding some other lock, WifiLockManager should retry setPowerSave()
when(mClientModeImpl.setPowerSave(anyBoolean())).thenReturn(true);
assertTrue(mWifiLockManager.acquireWifiLock(WifiManager.WIFI_MODE_FULL, "",
fullLockBinder, fullLockWS));
assertEquals(WifiManager.WIFI_MODE_FULL_HIGH_PERF,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl).setPowerSave(false);
}
/**
* Test failure case when setPowerSave() fails, during release of hi-perf lock
* Note, the lock is still released despite the failure in setPowerSave().
* On any new lock activity, the setPowerSave() will be re-attempted if still needed.
*/
@Test
public void testHiPerfLockReleaseFail() throws Exception {
IBinder fullLockBinder = mock(IBinder.class);
WorkSource fullLockWS = new WorkSource(DEFAULT_TEST_UID_1);
InOrder inOrder = inOrder(mClientModeImpl);
when(mClientModeImpl.setPowerSave(false)).thenReturn(true);
when(mClientModeImpl.setPowerSave(true)).thenReturn(false);
acquireWifiLockSuccessful(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "",
mBinder, mWorkSource);
assertEquals(WifiManager.WIFI_MODE_FULL_HIGH_PERF,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl).setPowerSave(false);
releaseWifiLockSuccessful(mBinder);
verify(mWifiMetrics).addWifiLockAcqSession(eq(WifiManager.WIFI_MODE_FULL_HIGH_PERF),
anyLong());
assertEquals(WifiManager.WIFI_MODE_NO_LOCKS_HELD,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl).setPowerSave(true);
verify(mWifiMetrics, never()).addWifiLockActiveSession(anyInt(), anyLong());
// Now attempting adding some other lock, WifiLockManager should retry setPowerSave()
when(mClientModeImpl.setPowerSave(true)).thenReturn(true);
assertTrue(mWifiLockManager.acquireWifiLock(WifiManager.WIFI_MODE_FULL, "",
fullLockBinder, fullLockWS));
assertEquals(WifiManager.WIFI_MODE_NO_LOCKS_HELD,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl).setPowerSave(true);
verify(mWifiMetrics).addWifiLockActiveSession(eq(WifiManager.WIFI_MODE_FULL_HIGH_PERF),
anyLong());
}
/**
* Test when forcing hi-perf mode, that it overrides apps requests
* until it is no longer forced.
*/
@Test
public void testForceHiPerf() throws Exception {
when(mClientModeImpl.setPowerSave(anyBoolean())).thenReturn(true);
InOrder inOrder = inOrder(mClientModeImpl);
mWifiLockManager.updateWifiClientConnected(true);
assertTrue(mWifiLockManager.acquireWifiLock(WifiManager.WIFI_MODE_SCAN_ONLY, "",
mBinder, mWorkSource));
assertEquals(WifiManager.WIFI_MODE_NO_LOCKS_HELD,
mWifiLockManager.getStrongestLockMode());
assertTrue(mWifiLockManager.forceHiPerfMode(true));
assertEquals(WifiManager.WIFI_MODE_FULL_HIGH_PERF,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl).setPowerSave(false);
assertTrue(mWifiLockManager.forceHiPerfMode(false));
assertEquals(WifiManager.WIFI_MODE_NO_LOCKS_HELD,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl).setPowerSave(true);
verify(mWifiMetrics).addWifiLockActiveSession(eq(WifiManager.WIFI_MODE_FULL_HIGH_PERF),
anyLong());
}
/**
* Test when forcing hi-perf mode, and aquire/release of hi-perf locks
*/
@Test
public void testForceHiPerfAcqRelHiPerf() throws Exception {
when(mClientModeImpl.setPowerSave(anyBoolean())).thenReturn(true);
InOrder inOrder = inOrder(mClientModeImpl);
acquireWifiLockSuccessful(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "",
mBinder, mWorkSource);
assertEquals(WifiManager.WIFI_MODE_FULL_HIGH_PERF,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl).setPowerSave(false);
assertTrue(mWifiLockManager.forceHiPerfMode(true));
assertEquals(WifiManager.WIFI_MODE_FULL_HIGH_PERF,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl, never()).setPowerSave(anyBoolean());
releaseWifiLockSuccessful(mBinder);
verify(mWifiMetrics).addWifiLockAcqSession(eq(WifiManager.WIFI_MODE_FULL_HIGH_PERF),
anyLong());
assertEquals(WifiManager.WIFI_MODE_FULL_HIGH_PERF,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl, never()).setPowerSave(anyBoolean());
assertTrue(mWifiLockManager.forceHiPerfMode(false));
assertEquals(WifiManager.WIFI_MODE_NO_LOCKS_HELD,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl).setPowerSave(true);
verify(mWifiMetrics).addWifiLockActiveSession(eq(WifiManager.WIFI_MODE_FULL_HIGH_PERF),
anyLong());
}
/**
* Test when trying to force hi-perf to true twice back to back
*/
@Test
public void testForceHiPerfTwice() throws Exception {
when(mClientModeImpl.setPowerSave(anyBoolean())).thenReturn(true);
mWifiLockManager.updateWifiClientConnected(true);
InOrder inOrder = inOrder(mClientModeImpl);
assertTrue(mWifiLockManager.forceHiPerfMode(true));
assertEquals(WifiManager.WIFI_MODE_FULL_HIGH_PERF,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl).setPowerSave(false);
assertTrue(mWifiLockManager.forceHiPerfMode(true));
assertEquals(WifiManager.WIFI_MODE_FULL_HIGH_PERF,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl, never()).setPowerSave(anyBoolean());
}
/**
* Test when failure when forcing hi-perf mode
*/
@Test
public void testForceHiPerfFailure() throws Exception {
when(mClientModeImpl.setPowerSave(anyBoolean())).thenReturn(false);
mWifiLockManager.updateWifiClientConnected(true);
InOrder inOrder = inOrder(mClientModeImpl);
assertTrue(mWifiLockManager.acquireWifiLock(WifiManager.WIFI_MODE_SCAN_ONLY, "",
mBinder, mWorkSource));
assertEquals(WifiManager.WIFI_MODE_NO_LOCKS_HELD,
mWifiLockManager.getStrongestLockMode());
assertFalse(mWifiLockManager.forceHiPerfMode(true));
assertEquals(WifiManager.WIFI_MODE_NO_LOCKS_HELD,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl).setPowerSave(false);
}
/**
* Test if a foreground app acquires a low-latency lock, and screen is on,
* then that lock becomes the strongest lock even with presence of other locks.
*/
@Test
public void testForegroundAppAcquireLowLatencyScreenOn() throws Exception {
// Set screen on, and app foreground
mWifiLockManager.handleScreenStateChanged(true);
when(mFrameworkFacade.isAppForeground(any(), anyInt())).thenReturn(true);
acquireWifiLockSuccessful(WifiManager.WIFI_MODE_FULL_LOW_LATENCY, "",
mBinder, mWorkSource);
acquireWifiLockSuccessful(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "",
mBinder2, mWorkSource);
assertEquals(WifiManager.WIFI_MODE_FULL_LOW_LATENCY,
mWifiLockManager.getStrongestLockMode());
}
/**
* Test if foreground app acquires a low-latency lock, and screen is off,
* then that lock becomes ineffective.
*/
@Test
public void testForegroundAppAcquireLowLatencyScreenOff() throws Exception {
// Set screen off, and app is foreground
mWifiLockManager.handleScreenStateChanged(false);
when(mFrameworkFacade.isAppForeground(any(), anyInt())).thenReturn(true);
assertTrue(mWifiLockManager.acquireWifiLock(WifiManager.WIFI_MODE_FULL_LOW_LATENCY,
"", mBinder, mWorkSource));
assertEquals(WifiManager.WIFI_MODE_NO_LOCKS_HELD,
mWifiLockManager.getStrongestLockMode());
}
/**
* Test if an app in background acquires a low-latency lock, and screen is on,
* then that lock becomes ineffective.
*/
@Test
public void testBackgroundAppAcquireLowLatencyScreenOn() throws Exception {
// Set screen on, and app is background
mWifiLockManager.handleScreenStateChanged(true);
when(mFrameworkFacade.isAppForeground(any(), anyInt())).thenReturn(false);
assertTrue(mWifiLockManager.acquireWifiLock(WifiManager.WIFI_MODE_FULL_LOW_LATENCY,
"", mBinder, mWorkSource));
assertEquals(WifiManager.WIFI_MODE_NO_LOCKS_HELD,
mWifiLockManager.getStrongestLockMode());
}
/**
* Test when acquiring a low-latency lock from a foreground app, and screen is on, then,
* WifiLockManager calls to enable low-latency mechanism for devices supporting this.
*/
@Test
public void testLatencyLockAcquireCauseLlEnableNew() throws Exception {
// Set screen on, and app foreground
mWifiLockManager.handleScreenStateChanged(true);
when(mFrameworkFacade.isAppForeground(any(), anyInt())).thenReturn(true);
when(mClientModeImpl.setLowLatencyMode(anyBoolean())).thenReturn(true);
when(mWifiNative.getSupportedFeatureSet(INTERFACE_NAME))
.thenReturn((long) WifiManager.WIFI_FEATURE_LOW_LATENCY);
acquireWifiLockSuccessful(WifiManager.WIFI_MODE_FULL_LOW_LATENCY, "",
mBinder, mWorkSource);
verify(mClientModeImpl).setLowLatencyMode(true);
verify(mClientModeImpl).setPowerSave(false);
}
/**
* Test when acquiring a low-latency lock from a foreground app, and screen is on, then,
* WifiLockManager calls to disable power save, when low-latency mechanism is not supported.
*/
@Test
public void testLatencyLockAcquireCauseLL_enableLegacy() throws Exception {
// Set screen on, and app foreground
mWifiLockManager.handleScreenStateChanged(true);
when(mFrameworkFacade.isAppForeground(any(), anyInt())).thenReturn(true);
when(mWifiNative.getSupportedFeatureSet(INTERFACE_NAME))
.thenReturn((long) WifiManager.WIFI_FEATURE_TX_POWER_LIMIT);
acquireWifiLockSuccessful(WifiManager.WIFI_MODE_FULL_LOW_LATENCY, "",
mBinder, mWorkSource);
verify(mClientModeImpl).setPowerSave(false);
verify(mClientModeImpl, never()).setLowLatencyMode(anyBoolean());
}
/**
* Test when releasing an acquired low-latency lock,
* WifiLockManager calls to disable low-latency mechanism.
*/
@Test
public void testLatencyLockReleaseCauseLlDisable() throws Exception {
// Set screen on, and app foreground
mWifiLockManager.handleScreenStateChanged(true);
when(mFrameworkFacade.isAppForeground(any(), anyInt())).thenReturn(true);
when(mWifiNative.getSupportedFeatureSet(INTERFACE_NAME))
.thenReturn((long) WifiManager.WIFI_FEATURE_LOW_LATENCY);
// Make sure setLowLatencyMode() is successful
when(mClientModeImpl.setLowLatencyMode(anyBoolean())).thenReturn(true);
when(mClientModeImpl.setPowerSave(anyBoolean())).thenReturn(true);
InOrder inOrder = inOrder(mClientModeImpl);
acquireWifiLockSuccessful(WifiManager.WIFI_MODE_FULL_LOW_LATENCY, "",
mBinder, mWorkSource);
inOrder.verify(mClientModeImpl).setLowLatencyMode(true);
inOrder.verify(mClientModeImpl).setPowerSave(false);
releaseLowLatencyWifiLockSuccessful(mBinder);
assertEquals(WifiManager.WIFI_MODE_NO_LOCKS_HELD,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl).setLowLatencyMode(false);
inOrder.verify(mClientModeImpl).setPowerSave(true);
verify(mWifiMetrics).addWifiLockActiveSession(eq(WifiManager.WIFI_MODE_FULL_LOW_LATENCY),
anyLong());
}
/**
* Test when acquire of low-latency lock fails to enable low-latency mode,
* then release will not result in calling to disable low-latency.
*/
@Test
public void testLatencyLockReleaseFailure() throws Exception {
InOrder inOrder = inOrder(mClientModeImpl);
// Set screen on, and app is foreground
mWifiLockManager.handleScreenStateChanged(true);
when(mFrameworkFacade.isAppForeground(any(), anyInt())).thenReturn(true);
when(mWifiNative.getSupportedFeatureSet(INTERFACE_NAME))
.thenReturn((long) WifiManager.WIFI_FEATURE_LOW_LATENCY);
// Fail the call to ClientModeImpl
when(mClientModeImpl.setLowLatencyMode(true)).thenReturn(false);
acquireWifiLockSuccessful(WifiManager.WIFI_MODE_FULL_LOW_LATENCY, "",
mBinder, mWorkSource);
assertEquals(WifiManager.WIFI_MODE_FULL_LOW_LATENCY,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl).setLowLatencyMode(true);
releaseLowLatencyWifiLockSuccessful(mBinder);
assertEquals(WifiManager.WIFI_MODE_NO_LOCKS_HELD,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl, never()).setLowLatencyMode(anyBoolean());
}
/**
* Test when acquire of low-latency lock succeeds in enable low latency
* but fails to disable power save, then low latency mode is reverted
*/
@Test
public void testLatencyfail2DisablePowerSave() throws Exception {
InOrder inOrder = inOrder(mClientModeImpl);
// Set screen on, and app is foreground
mWifiLockManager.handleScreenStateChanged(true);
when(mFrameworkFacade.isAppForeground(any(), anyInt())).thenReturn(true);
when(mWifiNative.getSupportedFeatureSet(INTERFACE_NAME))
.thenReturn((long) WifiManager.WIFI_FEATURE_LOW_LATENCY);
// Succeed to setLowLatencyMode()
when(mClientModeImpl.setLowLatencyMode(anyBoolean())).thenReturn(true);
// Fail to setPowerSave()
when(mClientModeImpl.setPowerSave(false)).thenReturn(false);
acquireWifiLockSuccessful(WifiManager.WIFI_MODE_FULL_LOW_LATENCY, "",
mBinder, mWorkSource);
assertEquals(WifiManager.WIFI_MODE_FULL_LOW_LATENCY,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl).setLowLatencyMode(true);
inOrder.verify(mClientModeImpl).setPowerSave(false);
inOrder.verify(mClientModeImpl).setLowLatencyMode(false);
}
/**
* Test when a low-latency lock is acquired (foreground app, screen-on),
* then, screen go off, then low-latency mode is turned off.
*/
@Test
public void testLatencyLockGoScreenOff() throws Exception {
// Set screen on, app foreground
mWifiLockManager.handleScreenStateChanged(true);
when(mFrameworkFacade.isAppForeground(any(), anyInt())).thenReturn(true);
when(mWifiNative.getSupportedFeatureSet(INTERFACE_NAME))
.thenReturn((long) WifiManager.WIFI_FEATURE_LOW_LATENCY);
// Make sure setLowLatencyMode() is successful
when(mClientModeImpl.setLowLatencyMode(anyBoolean())).thenReturn(true);
when(mClientModeImpl.setPowerSave(anyBoolean())).thenReturn(true);
InOrder inOrder = inOrder(mClientModeImpl);
acquireWifiLockSuccessful(WifiManager.WIFI_MODE_FULL_LOW_LATENCY, "",
mBinder, mWorkSource);
assertEquals(WifiManager.WIFI_MODE_FULL_LOW_LATENCY,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl).setLowLatencyMode(true);
inOrder.verify(mClientModeImpl).setPowerSave(false);
mWifiLockManager.handleScreenStateChanged(false);
assertEquals(WifiManager.WIFI_MODE_NO_LOCKS_HELD,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl).setLowLatencyMode(false);
inOrder.verify(mClientModeImpl).setPowerSave(true);
verify(mWifiMetrics).addWifiLockActiveSession(eq(WifiManager.WIFI_MODE_FULL_LOW_LATENCY),
anyLong());
}
/**
* Test when a low-latency lock is acquired (foreground app, screen-on),
* then, app goes to background, then low-latency mode is turned off.
*/
@Test
public void testLatencyLockGoBackground() throws Exception {
// Initially, set screen on, app foreground
mWifiLockManager.handleScreenStateChanged(true);
when(mFrameworkFacade.isAppForeground(any(), anyInt())).thenReturn(true);
when(mWifiNative.getSupportedFeatureSet(INTERFACE_NAME))
.thenReturn((long) WifiManager.WIFI_FEATURE_LOW_LATENCY);
// Make sure setLowLatencyMode() is successful
when(mClientModeImpl.setLowLatencyMode(anyBoolean())).thenReturn(true);
when(mClientModeImpl.setPowerSave(anyBoolean())).thenReturn(true);
InOrder inOrder = inOrder(mClientModeImpl);
acquireWifiLockSuccessful(WifiManager.WIFI_MODE_FULL_LOW_LATENCY, "",
mBinder, mWorkSource);
captureUidImportanceListener();
assertEquals(WifiManager.WIFI_MODE_FULL_LOW_LATENCY,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl).setLowLatencyMode(true);
inOrder.verify(mClientModeImpl).setPowerSave(false);
/* App going to background */
mUidImportanceListener.onUidImportance(DEFAULT_TEST_UID_1,
ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND);
mLooper.dispatchAll();
assertEquals(WifiManager.WIFI_MODE_NO_LOCKS_HELD,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl).setLowLatencyMode(false);
inOrder.verify(mClientModeImpl).setPowerSave(true);
verify(mWifiMetrics).addWifiLockActiveSession(eq(WifiManager.WIFI_MODE_FULL_LOW_LATENCY),
anyLong());
}
/**
* Test when a low-latency lock is acquired (background app, screen-on),
* then, lock is only effective when app goes to foreground.
*/
@Test
public void testLatencyLockGoForeground() throws Exception {
// Initially, set screen on, and app background
mWifiLockManager.handleScreenStateChanged(true);
when(mFrameworkFacade.isAppForeground(any(), anyInt())).thenReturn(false);
when(mWifiNative.getSupportedFeatureSet(INTERFACE_NAME))
.thenReturn((long) WifiManager.WIFI_FEATURE_LOW_LATENCY);
// Make sure setLowLatencyMode() is successful
when(mClientModeImpl.setLowLatencyMode(anyBoolean())).thenReturn(true);
mWifiLockManager.updateWifiClientConnected(true);
InOrder inOrder = inOrder(mClientModeImpl);
assertTrue(mWifiLockManager.acquireWifiLock(WifiManager.WIFI_MODE_FULL_LOW_LATENCY,
"", mBinder, mWorkSource));
captureUidImportanceListener();
assertEquals(WifiManager.WIFI_MODE_NO_LOCKS_HELD,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl, never()).setLowLatencyMode(anyBoolean());
inOrder.verify(mClientModeImpl, never()).setPowerSave(anyBoolean());
/* App going to foreground */
mUidImportanceListener.onUidImportance(DEFAULT_TEST_UID_1,
ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND);
mLooper.dispatchAll();
assertEquals(WifiManager.WIFI_MODE_FULL_LOW_LATENCY,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl).setLowLatencyMode(true);
inOrder.verify(mClientModeImpl).setPowerSave(false);
}
/**
* Test when both low-latency lock and hi-perf lock are acquired
* then, hi-perf is active when app is in background , while low-latency
* is active when app is in foreground (and screen on).
*/
@Test
public void testLatencyHiPerfLocks() throws Exception {
// Initially, set screen on, and app background
mWifiLockManager.handleScreenStateChanged(true);
when(mFrameworkFacade.isAppForeground(any(), anyInt())).thenReturn(false);
when(mWifiNative.getSupportedFeatureSet(INTERFACE_NAME))
.thenReturn((long) WifiManager.WIFI_FEATURE_LOW_LATENCY);
mWifiLockManager.updateWifiClientConnected(true);
// Make sure setLowLatencyMode()/setPowerSave() is successful
when(mClientModeImpl.setLowLatencyMode(anyBoolean())).thenReturn(true);
when(mClientModeImpl.setPowerSave(anyBoolean())).thenReturn(true);
InOrder inOrder = inOrder(mClientModeImpl);
assertTrue(mWifiLockManager.acquireWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF,
"", mBinder, mWorkSource));
assertTrue(mWifiLockManager.acquireWifiLock(WifiManager.WIFI_MODE_FULL_LOW_LATENCY,
"", mBinder2, mWorkSource));
captureUidImportanceListener();
assertEquals(WifiManager.WIFI_MODE_FULL_HIGH_PERF,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl, never()).setLowLatencyMode(anyBoolean());
inOrder.verify(mClientModeImpl).setPowerSave(false);
/* App going to foreground */
mUidImportanceListener.onUidImportance(DEFAULT_TEST_UID_1,
ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND);
mLooper.dispatchAll();
assertEquals(WifiManager.WIFI_MODE_FULL_LOW_LATENCY,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl).setPowerSave(true);
verify(mWifiMetrics).addWifiLockActiveSession(eq(WifiManager.WIFI_MODE_FULL_HIGH_PERF),
anyLong());
inOrder.verify(mClientModeImpl).setLowLatencyMode(true);
inOrder.verify(mClientModeImpl).setPowerSave(false);
}
/**
* Test when forcing low-latency mode, that it overrides apps requests
* until it is no longer forced.
*/
@Test
public void testForceLowLatency() throws Exception {
when(mClientModeImpl.setLowLatencyMode(anyBoolean())).thenReturn(true);
when(mClientModeImpl.setPowerSave(anyBoolean())).thenReturn(true);
when(mWifiNative.getSupportedFeatureSet(INTERFACE_NAME))
.thenReturn((long) WifiManager.WIFI_FEATURE_LOW_LATENCY);
InOrder inOrder = inOrder(mClientModeImpl);
acquireWifiLockSuccessful(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "",
mBinder, mWorkSource);
assertEquals(WifiManager.WIFI_MODE_FULL_HIGH_PERF,
mWifiLockManager.getStrongestLockMode());
assertTrue(mWifiLockManager.forceLowLatencyMode(true));
assertEquals(WifiManager.WIFI_MODE_FULL_LOW_LATENCY,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl).setLowLatencyMode(true);
inOrder.verify(mClientModeImpl).setPowerSave(false);
assertTrue(mWifiLockManager.forceLowLatencyMode(false));
assertEquals(WifiManager.WIFI_MODE_FULL_HIGH_PERF,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl).setLowLatencyMode(false);
inOrder.verify(mClientModeImpl).setPowerSave(true);
verify(mWifiMetrics).addWifiLockActiveSession(eq(WifiManager.WIFI_MODE_FULL_LOW_LATENCY),
anyLong());
}
/**
* Test when forcing low-latency mode, that it is effective even if screen is off.
*/
@Test
public void testForceLowLatencyScreenOff() throws Exception {
when(mClientModeImpl.setLowLatencyMode(anyBoolean())).thenReturn(true);
when(mClientModeImpl.setPowerSave(anyBoolean())).thenReturn(true);
mWifiLockManager.handleScreenStateChanged(false);
when(mWifiNative.getSupportedFeatureSet(INTERFACE_NAME))
.thenReturn((long) WifiManager.WIFI_FEATURE_LOW_LATENCY);
mWifiLockManager.updateWifiClientConnected(true);
InOrder inOrder = inOrder(mClientModeImpl);
assertEquals(WifiManager.WIFI_MODE_NO_LOCKS_HELD,
mWifiLockManager.getStrongestLockMode());
assertTrue(mWifiLockManager.forceLowLatencyMode(true));
assertEquals(WifiManager.WIFI_MODE_FULL_LOW_LATENCY,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl).setLowLatencyMode(true);
inOrder.verify(mClientModeImpl).setPowerSave(false);
mWifiLockManager.handleScreenStateChanged(true);
assertEquals(WifiManager.WIFI_MODE_FULL_LOW_LATENCY,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl, never()).setLowLatencyMode(anyBoolean());
inOrder.verify(mClientModeImpl, never()).setPowerSave(anyBoolean());
mWifiLockManager.handleScreenStateChanged(false);
assertEquals(WifiManager.WIFI_MODE_FULL_LOW_LATENCY,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl, never()).setLowLatencyMode(anyBoolean());
inOrder.verify(mClientModeImpl, never()).setPowerSave(anyBoolean());
}
/**
* Test when forcing low-latency mode, and aquire/release of low-latency locks
*/
@Test
public void testForceLowLatencyAcqRelLowLatency() throws Exception {
when(mClientModeImpl.setLowLatencyMode(anyBoolean())).thenReturn(true);
when(mClientModeImpl.setPowerSave(anyBoolean())).thenReturn(true);
mWifiLockManager.handleScreenStateChanged(true);
when(mFrameworkFacade.isAppForeground(any(), anyInt())).thenReturn(true);
when(mWifiNative.getSupportedFeatureSet(INTERFACE_NAME))
.thenReturn((long) WifiManager.WIFI_FEATURE_LOW_LATENCY);
InOrder inOrder = inOrder(mClientModeImpl);
acquireWifiLockSuccessful(WifiManager.WIFI_MODE_FULL_LOW_LATENCY, "",
mBinder, mWorkSource);
assertEquals(WifiManager.WIFI_MODE_FULL_LOW_LATENCY,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl).setLowLatencyMode(true);
inOrder.verify(mClientModeImpl).setPowerSave(false);
assertTrue(mWifiLockManager.forceLowLatencyMode(true));
assertEquals(WifiManager.WIFI_MODE_FULL_LOW_LATENCY,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl, never()).setLowLatencyMode(anyBoolean());
inOrder.verify(mClientModeImpl, never()).setPowerSave(anyBoolean());
releaseLowLatencyWifiLockSuccessful(mBinder);
assertEquals(WifiManager.WIFI_MODE_FULL_LOW_LATENCY,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl, never()).setLowLatencyMode(anyBoolean());
inOrder.verify(mClientModeImpl, never()).setPowerSave(anyBoolean());
assertTrue(mWifiLockManager.forceLowLatencyMode(false));
assertEquals(WifiManager.WIFI_MODE_NO_LOCKS_HELD,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl).setLowLatencyMode(false);
inOrder.verify(mClientModeImpl).setPowerSave(true);
verify(mWifiMetrics).addWifiLockActiveSession(eq(WifiManager.WIFI_MODE_FULL_LOW_LATENCY),
anyLong());
}
/**
* Test when trying to force low-latency to true twice back to back
*/
@Test
public void testForceLowLatencyTwice() throws Exception {
when(mClientModeImpl.setLowLatencyMode(anyBoolean())).thenReturn(true);
when(mClientModeImpl.setPowerSave(anyBoolean())).thenReturn(true);
when(mWifiNative.getSupportedFeatureSet(INTERFACE_NAME))
.thenReturn((long) WifiManager.WIFI_FEATURE_LOW_LATENCY);
mWifiLockManager.updateWifiClientConnected(true);
InOrder inOrder = inOrder(mClientModeImpl);
assertTrue(mWifiLockManager.forceLowLatencyMode(true));
assertEquals(WifiManager.WIFI_MODE_FULL_LOW_LATENCY,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl).setLowLatencyMode(true);
inOrder.verify(mClientModeImpl).setPowerSave(false);
assertTrue(mWifiLockManager.forceLowLatencyMode(true));
assertEquals(WifiManager.WIFI_MODE_FULL_LOW_LATENCY,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl, never()).setLowLatencyMode(anyBoolean());
inOrder.verify(mClientModeImpl, never()).setPowerSave(anyBoolean());
}
/**
* Test when forcing hi-perf mode then forcing low-latency mode
*/
@Test
public void testForceHiPerfLowLatency() throws Exception {
when(mClientModeImpl.setLowLatencyMode(anyBoolean())).thenReturn(true);
when(mClientModeImpl.setPowerSave(anyBoolean())).thenReturn(true);
when(mWifiNative.getSupportedFeatureSet(INTERFACE_NAME))
.thenReturn((long) WifiManager.WIFI_FEATURE_LOW_LATENCY);
mWifiLockManager.updateWifiClientConnected(true);
InOrder inOrder = inOrder(mClientModeImpl);
assertTrue(mWifiLockManager.forceHiPerfMode(true));
assertEquals(WifiManager.WIFI_MODE_FULL_HIGH_PERF,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl).setPowerSave(false);
assertTrue(mWifiLockManager.forceLowLatencyMode(true));
assertEquals(WifiManager.WIFI_MODE_FULL_LOW_LATENCY,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl).setPowerSave(true);
verify(mWifiMetrics).addWifiLockActiveSession(eq(WifiManager.WIFI_MODE_FULL_HIGH_PERF),
anyLong());
inOrder.verify(mClientModeImpl).setLowLatencyMode(true);
inOrder.verify(mClientModeImpl).setPowerSave(false);
}
/**
* Test when forcing low-latency mode then forcing high-perf mode
*/
@Test
public void testForceLowLatencyHiPerf() throws Exception {
when(mClientModeImpl.setLowLatencyMode(anyBoolean())).thenReturn(true);
when(mClientModeImpl.setPowerSave(anyBoolean())).thenReturn(true);
when(mWifiNative.getSupportedFeatureSet(INTERFACE_NAME))
.thenReturn((long) WifiManager.WIFI_FEATURE_LOW_LATENCY);
mWifiLockManager.updateWifiClientConnected(true);
InOrder inOrder = inOrder(mClientModeImpl);
assertTrue(mWifiLockManager.forceLowLatencyMode(true));
assertEquals(WifiManager.WIFI_MODE_FULL_LOW_LATENCY,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl).setLowLatencyMode(true);
inOrder.verify(mClientModeImpl).setPowerSave(false);
assertTrue(mWifiLockManager.forceHiPerfMode(true));
assertEquals(WifiManager.WIFI_MODE_FULL_HIGH_PERF,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl).setLowLatencyMode(false);
inOrder.verify(mClientModeImpl).setPowerSave(true);
verify(mWifiMetrics).addWifiLockActiveSession(eq(WifiManager.WIFI_MODE_FULL_LOW_LATENCY),
anyLong());
inOrder.verify(mClientModeImpl).setPowerSave(false);
}
/**
* Test when failure when forcing low-latency mode
*/
@Test
public void testForceLowLatencyFailure() throws Exception {
when(mClientModeImpl.setLowLatencyMode(anyBoolean())).thenReturn(false);
when(mWifiNative.getSupportedFeatureSet(INTERFACE_NAME))
.thenReturn((long) WifiManager.WIFI_FEATURE_LOW_LATENCY);
InOrder inOrder = inOrder(mClientModeImpl);
acquireWifiLockSuccessful(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "",
mBinder, mWorkSource);
assertEquals(WifiManager.WIFI_MODE_FULL_HIGH_PERF,
mWifiLockManager.getStrongestLockMode());
assertFalse(mWifiLockManager.forceLowLatencyMode(true));
assertEquals(WifiManager.WIFI_MODE_FULL_HIGH_PERF,
mWifiLockManager.getStrongestLockMode());
inOrder.verify(mClientModeImpl).setLowLatencyMode(true);
// Since setLowLatencyMode() failed, no call to setPowerSave()
inOrder.verify(mClientModeImpl, never()).setPowerSave(anyBoolean());
}
/**
* Test acquiring locks while device is not connected
* Expected: No locks are effective, and no call to other classes
*/
@Test
public void testAcquireLockWhileDisconnected() throws Exception {
assertTrue(mWifiLockManager.acquireWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "",
mBinder, mWorkSource));
assertEquals(WifiManager.WIFI_MODE_NO_LOCKS_HELD, mWifiLockManager.getStrongestLockMode());
verify(mBatteryStats, never()).reportFullWifiLockAcquiredFromSource(any());
}
/**
* Test acquiring locks while device is not connected, then connecting to an AP
* Expected: Upon Connection, lock becomes effective
*/
@Test
public void testAcquireLockWhileDisconnectedConnect() throws Exception {
assertTrue(mWifiLockManager.acquireWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "",
mBinder, mWorkSource));
mWifiLockManager.updateWifiClientConnected(true);
assertEquals(WifiManager.WIFI_MODE_FULL_HIGH_PERF, mWifiLockManager.getStrongestLockMode());
verify(mBatteryStats).reportFullWifiLockAcquiredFromSource(eq(mWorkSource));
}
/**
* Test acquiring locks while device is connected, then disconnecting from the AP
* Expected: Upon disconnection, lock becomes ineffective
*/
@Test
public void testAcquireLockWhileConnectedDisconnect() throws Exception {
// Set screen on, and app foreground
mWifiLockManager.handleScreenStateChanged(true);
when(mFrameworkFacade.isAppForeground(any(), anyInt())).thenReturn(true);
acquireWifiLockSuccessful(WifiManager.WIFI_MODE_FULL_LOW_LATENCY, "", mBinder, mWorkSource);
mWifiLockManager.updateWifiClientConnected(false);
assertEquals(WifiManager.WIFI_MODE_NO_LOCKS_HELD, mWifiLockManager.getStrongestLockMode());
verify(mBatteryStats).reportFullWifiLockReleasedFromSource(mWorkSource);
}
/**
* Test that reporting of metrics for hi-perf lock acquistion is correct for both acquisition
* time and active time.
*/
@Test
public void testHighPerfLockMetrics() throws Exception {
long acquireTime = 1000;
long activationTime = 2000;
long deactivationTime = 3000;
long releaseTime = 4000;
// Make sure setPowerSave() is successful
when(mClientModeImpl.setPowerSave(anyBoolean())).thenReturn(true);
InOrder inOrder = inOrder(mWifiMetrics);
// Acquire the lock
when(mClock.getElapsedSinceBootMillis()).thenReturn(acquireTime);
assertTrue(mWifiLockManager.acquireWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "",
mBinder, mWorkSource));
// Activate the lock
when(mClock.getElapsedSinceBootMillis()).thenReturn(activationTime);
mWifiLockManager.updateWifiClientConnected(true);
// Deactivate the lock
when(mClock.getElapsedSinceBootMillis()).thenReturn(deactivationTime);
mWifiLockManager.updateWifiClientConnected(false);
inOrder.verify(mWifiMetrics).addWifiLockActiveSession(
eq(WifiManager.WIFI_MODE_FULL_HIGH_PERF),
eq(deactivationTime - activationTime));
// Release the lock
when(mClock.getElapsedSinceBootMillis()).thenReturn(releaseTime);
releaseWifiLockSuccessful_noBatteryStats(mBinder);
inOrder.verify(mWifiMetrics).addWifiLockAcqSession(
eq(WifiManager.WIFI_MODE_FULL_HIGH_PERF),
eq(releaseTime - acquireTime));
}
/**
* Test that reporting of metrics for low-latency lock acquistion is correct for
* both acquisition time and active time.
*/
@Test
public void testLowLatencyLockMetrics() throws Exception {
long acquireTime = 1000;
long activationTime = 2000;
long deactivationTime = 3000;
long releaseTime = 4000;
// Make sure setLowLatencyMode()/setPowerSave() is successful
when(mClientModeImpl.setLowLatencyMode(anyBoolean())).thenReturn(true);
when(mClientModeImpl.setPowerSave(anyBoolean())).thenReturn(true);
// Set condition for activation of low-latency (except connection to AP)
mWifiLockManager.handleScreenStateChanged(true);
when(mFrameworkFacade.isAppForeground(any(), anyInt())).thenReturn(true);
when(mWifiNative.getSupportedFeatureSet(INTERFACE_NAME))
.thenReturn((long) WifiManager.WIFI_FEATURE_LOW_LATENCY);
InOrder inOrder = inOrder(mWifiMetrics);
// Acquire the lock
when(mClock.getElapsedSinceBootMillis()).thenReturn(acquireTime);
assertTrue(mWifiLockManager.acquireWifiLock(WifiManager.WIFI_MODE_FULL_LOW_LATENCY, "",
mBinder, mWorkSource));
// Activate the lock
when(mClock.getElapsedSinceBootMillis()).thenReturn(activationTime);
mWifiLockManager.updateWifiClientConnected(true);
// Deactivate the lock
when(mClock.getElapsedSinceBootMillis()).thenReturn(deactivationTime);
mWifiLockManager.updateWifiClientConnected(false);
inOrder.verify(mWifiMetrics).addWifiLockActiveSession(
eq(WifiManager.WIFI_MODE_FULL_LOW_LATENCY),
eq(deactivationTime - activationTime));
// Release the lock
when(mClock.getElapsedSinceBootMillis()).thenReturn(releaseTime);
releaseWifiLockSuccessful_noBatteryStats(mBinder);
inOrder.verify(mWifiMetrics).addWifiLockAcqSession(
eq(WifiManager.WIFI_MODE_FULL_LOW_LATENCY),
eq(releaseTime - acquireTime));
}
/**
* Verfies that dump() does not fail when no locks are held.
*/
@Test
public void dumpDoesNotFailWhenNoLocksAreHeld() {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
mWifiLockManager.dump(pw);
String wifiLockManagerDumpString = sw.toString();
assertTrue(wifiLockManagerDumpString.contains(
"Locks acquired: 0 full high perf, 0 full low latency"));
assertTrue(wifiLockManagerDumpString.contains(
"Locks released: 0 full high perf, 0 full low latency"));
assertTrue(wifiLockManagerDumpString.contains("Locks held:"));
assertFalse(wifiLockManagerDumpString.contains("WifiLock{"));
}
/**
* Verifies that dump() contains lock information when there are locks held.
*/
@Test
public void dumpOutputsCorrectInformationWithActiveLocks() throws Exception {
acquireWifiLockSuccessful(WifiManager.WIFI_MODE_FULL_HIGH_PERF, TEST_WIFI_LOCK_TAG,
mBinder, mWorkSource);
releaseWifiLockSuccessful(mBinder);
verify(mWifiMetrics).addWifiLockAcqSession(eq(WifiManager.WIFI_MODE_FULL_HIGH_PERF),
anyLong());
acquireWifiLockSuccessful(WifiManager.WIFI_MODE_FULL_HIGH_PERF, TEST_WIFI_LOCK_TAG,
mBinder, mWorkSource);
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
mWifiLockManager.dump(pw);
String wifiLockManagerDumpString = sw.toString();
assertTrue(wifiLockManagerDumpString.contains(
"Locks acquired: 2 full high perf, 0 full low latency"));
assertTrue(wifiLockManagerDumpString.contains(
"Locks released: 1 full high perf, 0 full low latency"));
assertTrue(wifiLockManagerDumpString.contains("Locks held:"));
assertTrue(wifiLockManagerDumpString.contains(
"WifiLock{" + TEST_WIFI_LOCK_TAG + " type=" + WifiManager.WIFI_MODE_FULL_HIGH_PERF
+ " uid=" + Binder.getCallingUid() + " workSource=WorkSource{"
+ DEFAULT_TEST_UID_1 + "}"));
}
/**
* Verify that an Exception in unlinkDeathRecipient is caught.
*/
@Test
public void testUnlinkDeathRecipiientCatchesException() throws Exception {
acquireWifiLockSuccessful(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "",
mBinder, mWorkSource);
assertEquals(WifiManager.WIFI_MODE_FULL_HIGH_PERF, mWifiLockManager.getStrongestLockMode());
doThrow(new NoSuchElementException()).when(mBinder).unlinkToDeath(any(), anyInt());
releaseLowLatencyWifiLockSuccessful(mBinder);
assertEquals(WifiManager.WIFI_MODE_NO_LOCKS_HELD,
mWifiLockManager.getStrongestLockMode());
}
}