diff options
7 files changed, 343 insertions, 42 deletions
diff --git a/service/java/com/android/server/wifi/WifiConfigStore.java b/service/java/com/android/server/wifi/WifiConfigStore.java index 77757a8b3..cc9e5068f 100644 --- a/service/java/com/android/server/wifi/WifiConfigStore.java +++ b/service/java/com/android/server/wifi/WifiConfigStore.java @@ -1363,6 +1363,84 @@ public class WifiConfigStore extends IpConfigStore { } } + + /** + * PnoNetwork list sorting algorithm: + * 1, Place the fully enabled networks first. Among the fully enabled networks, + * sort them in descending order of their |numAssociation| values. If networks have + * the same |numAssociation|, then sort them in descending order of their |priority| + * values. + * 2. Next place all the temporarily disabled networks. Among the temporarily disabled + * networks, sort them in the same order as the fully enabled networks. + * 3. Place the permanently disabled networks last. The order among permanently disabled + * networks doesn't matter. + */ + private static final Comparator<WifiConfiguration> sPnoListSortComparator = + new Comparator<WifiConfiguration>() { + public int compare(WifiConfiguration a, WifiConfiguration b) { + boolean isConfigAEnabled = a.getNetworkSelectionStatus().isNetworkEnabled(); + boolean isConfigBEnabled = b.getNetworkSelectionStatus().isNetworkEnabled(); + boolean isConfigATempDisabled = + a.getNetworkSelectionStatus().isNetworkTemporaryDisabled(); + boolean isConfigBTempDisabled = + b.getNetworkSelectionStatus().isNetworkTemporaryDisabled(); + if ((isConfigAEnabled && isConfigBEnabled) + || (isConfigATempDisabled && isConfigBTempDisabled)) { + // If 2 networks have the same saved |numAssociation| value, sort them + // according to their priority. + if (a.numAssociation != b.numAssociation) { + return Long.compare(b.numAssociation, a.numAssociation); + } else { + return Integer.compare(b.priority, a.priority); + } + } else if (isConfigAEnabled != isConfigBEnabled) { + return Boolean.compare(isConfigBEnabled, isConfigAEnabled); + } else { + return Boolean.compare(isConfigBTempDisabled, isConfigATempDisabled); + } + } + }; + + /** + * Retrieves an updated list of priorities for all the saved networks before + * enabling/disabling PNO. + * + * wpa_supplicant uses the priority of networks to build the list of SSID's to monitor + * during PNO. If there are a lot of saved networks, this list will be truncated and we + * might end up not connecting to the networks we use most frequently. So, We want the networks + * to be re-sorted based on the relative |numAssociation| values. + * + * @param enablePno boolean indicating whether PNO is being enabled or disabled. + * @return list of networks with updated priorities. + */ + ArrayList<WifiNative.PnoNetworkPriority> retrievePnoNetworkPriorityList(boolean enablePno) { + ArrayList<WifiNative.PnoNetworkPriority> pnoList = + new ArrayList<WifiNative.PnoNetworkPriority>(); + ArrayList<WifiConfiguration> wifiConfigurations = + new ArrayList<WifiConfiguration>(mConfiguredNetworks.valuesForCurrentUser()); + if (enablePno) { + Collections.sort(wifiConfigurations, sPnoListSortComparator); + // Let's use the network list size as the highest priority and then go down from there. + // So, the most frequently connected network has the highest priority now. + int priority = wifiConfigurations.size(); + if (DBG) { + Log.d(TAG, "Retrieve network priorities before PNO. Max priority: " + priority); + } + for (WifiConfiguration config : wifiConfigurations) { + pnoList.add(new WifiNative.PnoNetworkPriority(config.networkId, priority)); + priority--; + } + } else { + // Revert the priorities back to the saved config values after PNO. + if (DBG) Log.d(TAG, "Retrieve network priorities after PNO."); + for (WifiConfiguration config : wifiConfigurations) { + pnoList.add(new WifiNative.PnoNetworkPriority(config.networkId, config.priority)); + } + } + return pnoList; + } + + String[] getWhiteListedSsids(WifiConfiguration config) { int num_ssids = 0; String nonQuoteSSID; diff --git a/service/java/com/android/server/wifi/WifiNative.java b/service/java/com/android/server/wifi/WifiNative.java index 20f5ab3c7..9246c2ea9 100644 --- a/service/java/com/android/server/wifi/WifiNative.java +++ b/service/java/com/android/server/wifi/WifiNative.java @@ -880,6 +880,29 @@ public class WifiNative { return doBooleanCommand("DRIVER COUNTRY"); } + + /** + * Object holding the network ID and the corresponding priority to be set before enabling/ + * disabling PNO. + */ + public static class PnoNetworkPriority { + public int networkId; + public int priority; + + PnoNetworkPriority(int networkId, int priority) { + this.networkId = networkId; + this.priority = priority; + } + + @Override + public String toString() { + StringBuilder sbuf = new StringBuilder(); + sbuf.append(" Network ID=").append(this.networkId); + sbuf.append(" Priority=").append(this.priority); + return sbuf.toString(); + } + } + //PNO Monitor private class PnoMonitor { private static final int MINIMUM_PNO_GAP = 5 * 1000; @@ -887,6 +910,7 @@ public class WifiNative { "com.android.server.Wifi.action.TOGGLE_PNO"; long mLastPnoChangeTimeStamp = -1L; boolean mExpectedPnoState = false; + List<PnoNetworkPriority> mExpectedPnoNetworkPriorityList = null; boolean mCurrentPnoState = false;; boolean mWaitForTimer = false; final Object mPnoLock = new Object(); @@ -909,7 +933,8 @@ public class WifiNative { if (mCurrentPnoState != mExpectedPnoState) { if (DBG) Log.d(mTAG, "change PNO from " + mCurrentPnoState + " to " + mExpectedPnoState); - boolean ret = setPno(mExpectedPnoState); + boolean ret = setPno( + mExpectedPnoState, mExpectedPnoNetworkPriorityList); if (!ret) { Log.e(mTAG, "set PNO failure"); } @@ -923,7 +948,27 @@ public class WifiNative { new IntentFilter(ACTION_TOGGLE_PNO)); } - private boolean setPno(boolean enable) { + /* Enable/Disable PNO with updated network priorities. + * + * @param enable boolean indicating whether PNO is being enabled or disabled. + * @param pnoNetworkList list of networks with priorities to be set before PNO setting. + */ + private boolean setPno(boolean enable, List<PnoNetworkPriority> pnoNetworkList) { + // TODO: Couple of cases yet to be handled: + // 1. What if the network priority update fails, should we bail out of PNO setting? + // 2. If PNO setting fails below, should we go back and revert this priority change? + if (pnoNetworkList != null) { + if (DBG) Log.i(mTAG, "Update priorities for PNO. Enable: " + enable); + for (PnoNetworkPriority pnoNetwork : pnoNetworkList) { + // What if this fails? Should we bail out? + boolean isSuccess = setNetworkVariable(pnoNetwork.networkId, + WifiConfiguration.priorityVarName, + Integer.toString(pnoNetwork.priority)); + if (DBG && !isSuccess) { + Log.e(mTAG, "Update priority failed for :" + pnoNetwork.networkId); + } + } + } String cmd = enable ? "SET pno 1" : "SET pno 0"; boolean ret = doBooleanCommand(cmd); mLastPnoChangeTimeStamp = System.currentTimeMillis(); @@ -933,11 +978,14 @@ public class WifiNative { return ret; } - public boolean enableBackgroundScan(boolean enable) { + public boolean enableBackgroundScan( + boolean enable, + List<PnoNetworkPriority> pnoNetworkList) { synchronized(mPnoLock) { if (mWaitForTimer) { //already has a timer mExpectedPnoState = enable; + mExpectedPnoNetworkPriorityList = pnoNetworkList; if (DBG) Log.d(mTAG, "update expected PNO to " + mExpectedPnoState); } else { if (mCurrentPnoState == enable) { @@ -945,9 +993,10 @@ public class WifiNative { } long timeDifference = System.currentTimeMillis() - mLastPnoChangeTimeStamp; if (timeDifference >= MINIMUM_PNO_GAP) { - return setPno(enable); + return setPno(enable, pnoNetworkList); } else { mExpectedPnoState = enable; + mExpectedPnoNetworkPriorityList = pnoNetworkList; mWaitForTimer = true; if (DBG) Log.d(mTAG, "start PNO timer with delay:" + timeDifference); mAlarmManager.set(AlarmManager.RTC_WAKEUP, @@ -959,9 +1008,11 @@ public class WifiNative { } } - public boolean enableBackgroundScan(boolean enable) { + public boolean enableBackgroundScan( + boolean enable, + List<PnoNetworkPriority> pnoNetworkList) { if (mPnoMonitor != null) { - return mPnoMonitor.enableBackgroundScan(enable); + return mPnoMonitor.enableBackgroundScan(enable, pnoNetworkList); } else { return false; } diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java index 8aaa163bd..1bf89a683 100644 --- a/service/java/com/android/server/wifi/WifiStateMachine.java +++ b/service/java/com/android/server/wifi/WifiStateMachine.java @@ -2507,7 +2507,9 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno if (enable) { mWifiConfigStore.enableAllNetworks(); } - boolean ret = mWifiNative.enableBackgroundScan(enable); + List<WifiNative.PnoNetworkPriority> pnoList = + mWifiConfigStore.retrievePnoNetworkPriorityList(enable); + boolean ret = mWifiNative.enableBackgroundScan(enable, pnoList); if (ret) { mLegacyPnoEnabled = enable; } else { diff --git a/tests/wifitests/src/com/android/server/wifi/ScanResults.java b/tests/wifitests/src/com/android/server/wifi/ScanResults.java index d418451fc..8bbdc556c 100644 --- a/tests/wifitests/src/com/android/server/wifi/ScanResults.java +++ b/tests/wifitests/src/com/android/server/wifi/ScanResults.java @@ -22,8 +22,6 @@ import android.net.wifi.WifiSsid; import com.android.server.wifi.hotspot2.NetworkDetail; -import java.lang.annotation.Annotation; -import java.lang.reflect.Method; import java.math.BigInteger; import java.nio.charset.Charset; import java.util.ArrayList; @@ -59,42 +57,11 @@ public class ScanResults { return ie; } - /** - * Walk up the stack and find the first method annotated with @Test - * Note: this will evaluate all overloads with the method name for the @Test annotation - */ - private static String getTestMethod() { - StackTraceElement[] stack = Thread.currentThread().getStackTrace(); - for (StackTraceElement e : stack) { - if (e.isNativeMethod()) { - continue; - } - Class clazz; - try { - clazz = Class.forName(e.getClassName()); - } catch(ClassNotFoundException ex) { - throw new RuntimeException("Could not find class from stack", ex); - } - Method[] methods = clazz.getDeclaredMethods(); - for (Method method : methods) { - if (method.getName().equals(e.getMethodName())) { - Annotation[] annotations = method.getDeclaredAnnotations(); - for (Annotation annotation : annotations) { - if (annotation.annotationType().equals(org.junit.Test.class)) { - return e.getClassName() + "#" + e.getMethodName(); - } - } - } - } - } - throw new RuntimeException("Could not find a test method in the stack"); - } - private static ScanDetail[] generateNativeResults(int seed, int... freqs) { ScanDetail[] results = new ScanDetail[freqs.length]; // Seed the results based on the provided seed as well as the test method name // This provides more varied scan results between individual tests that are very similar. - Random r = new Random(seed + getTestMethod().hashCode()); + Random r = new Random(seed + WifiTestUtil.getTestMethod().hashCode()); for (int i = 0; i < freqs.length; ++i) { int freq = freqs[i]; String ssid = new BigInteger(128, r).toString(36); diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConfigStoreTest.java b/tests/wifitests/src/com/android/server/wifi/WifiConfigStoreTest.java index 146a59abf..592280335 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiConfigStoreTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiConfigStoreTest.java @@ -42,6 +42,7 @@ import android.os.UserHandle; import android.security.Credentials; import android.test.AndroidTestCase; import android.text.TextUtils; +import android.util.Log; import com.android.server.net.DelayedDiskWrite; import com.android.server.wifi.MockAnswerUtil.AnswerWithArguments; @@ -49,6 +50,7 @@ import com.android.server.wifi.hotspot2.omadm.PasspointManagementObjectManager; import com.android.server.wifi.hotspot2.pps.Credential; import com.android.server.wifi.hotspot2.pps.HomeSP; +import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -64,15 +66,19 @@ import java.lang.reflect.Field; import java.math.BigInteger; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; +import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Arrays; import java.util.BitSet; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Random; import java.util.Set; +import java.util.TreeMap; /** * Unit tests for {@link com.android.server.wifi.WifiConfigStore}. @@ -100,6 +106,7 @@ public class WifiConfigStoreTest extends AndroidTestCase { } } + public static final String TAG = "WifiConfigStoreTest"; @Mock private Context mContext; @Mock private WifiStateMachine mWifiStateMachine; @Mock private WifiNative mWifiNative; @@ -239,6 +246,7 @@ public class WifiConfigStoreTest extends AndroidTestCase { * Verifies that getConfiguredNetworksSize() returns the network configurations visible to the * current user. */ + @Test public void testGetConfiguredNetworks() throws Exception { addNetworks(); for (Map.Entry<Integer, List<WifiConfiguration>> entry : VISIBLE_CONFIGS.entrySet()) { @@ -251,6 +259,7 @@ public class WifiConfigStoreTest extends AndroidTestCase { * Verifies that getPrivilegedConfiguredNetworks() returns the network configurations visible to * the current user. */ + @Test public void testGetPrivilegedConfiguredNetworks() throws Exception { addNetworks(); for (Map.Entry<Integer, List<WifiConfiguration>> entry : VISIBLE_CONFIGS.entrySet()) { @@ -263,6 +272,7 @@ public class WifiConfigStoreTest extends AndroidTestCase { * Verifies that getWifiConfiguration(int netId) can be used to access network configurations * visible to the current user only. */ + @Test public void testGetWifiConfigurationByNetworkId() throws Exception { addNetworks(); for (int userId : USER_IDS) { @@ -283,6 +293,7 @@ public class WifiConfigStoreTest extends AndroidTestCase { * Verifies that getWifiConfiguration(String key) can be used to access network configurations * visible to the current user only. */ + @Test public void testGetWifiConfigurationByConfigKey() throws Exception { addNetworks(); for (int userId : USER_IDS) { @@ -303,6 +314,7 @@ public class WifiConfigStoreTest extends AndroidTestCase { * Verifies that enableAllNetworks() enables all temporarily disabled network configurations * visible to the current user. */ + @Test public void testEnableAllNetworks() throws Exception { addNetworks(); when(mWifiNative.enableNetwork(anyInt(), anyBoolean())).thenReturn(true); @@ -332,6 +344,7 @@ public class WifiConfigStoreTest extends AndroidTestCase { * Verifies that selectNetwork() disables all network configurations visible to the current user * except the selected one. */ + @Test public void testSelectNetwork() throws Exception { addNetworks(); @@ -464,6 +477,7 @@ public class WifiConfigStoreTest extends AndroidTestCase { /** * Verifies that saveNetwork() correctly stores a regular network configuration. */ + @Test public void testSaveNetworkRegular() throws Exception { verifySaveNetwork(0); } @@ -471,6 +485,7 @@ public class WifiConfigStoreTest extends AndroidTestCase { /** * Verifies that saveNetwork() correctly stores a HotSpot 2.0 network configuration. */ + @Test public void testSaveNetworkHotspot20() throws Exception { verifySaveNetwork(1); } @@ -478,6 +493,7 @@ public class WifiConfigStoreTest extends AndroidTestCase { /** * Verifies that saveNetwork() correctly stores a private network configuration. */ + @Test public void testSaveNetworkPrivate() throws Exception { verifySaveNetwork(2); } @@ -490,6 +506,7 @@ public class WifiConfigStoreTest extends AndroidTestCase { * - In the wpa_supplicant: "ssid", "id_str" * - In networkHistory.txt: "CONFIG", "CREATOR_UID_KEY", "SHARED" */ + @Test public void testLoadConfiguredNetworks() throws Exception { // Set up list of network configurations returned by wpa_supplicant. final String header = "network id / ssid / bssid / flags"; @@ -565,6 +582,7 @@ public class WifiConfigStoreTest extends AndroidTestCase { * Verifies that loadConfiguredNetworks() correctly handles duplicates when reading network * configurations from the wpa_supplicant: The second configuration overwrites the first. */ + @Test public void testLoadConfiguredNetworksEliminatesDuplicates() throws Exception { final WifiConfiguration config = new WifiConfiguration(CONFIGS.get(0)); config.networkId = 1; @@ -673,6 +691,7 @@ public class WifiConfigStoreTest extends AndroidTestCase { * Verifies that handleUserSwitch() behaves correctly when the user switch removes an ephemeral * network configuration and reveals a private network configuration. */ + @Test public void testHandleUserSwitchWithEphemeral() throws Exception { verifyHandleUserSwitch(USER_IDS[2], USER_IDS[0], true); } @@ -681,10 +700,12 @@ public class WifiConfigStoreTest extends AndroidTestCase { * Verifies that handleUserSwitch() behaves correctly when the user switch hides a private * network configuration. */ + @Test public void testHandleUserSwitchWithoutEphemeral() throws Exception { verifyHandleUserSwitch(USER_IDS[0], USER_IDS[2], false); } + @Test public void testSaveLoadEapNetworks() { testSaveLoadSingleEapNetwork("eap network", new EnterpriseConfig(Eap.TTLS) .setPhase2(Phase2.MSCHAPV2) @@ -861,4 +882,128 @@ public class WifiConfigStoreTest extends AndroidTestCase { return this; } } + + /** + * Generates an array of unique random numbers below the specified maxValue. + * Values range from 0 to maxValue-1. + */ + private static ArrayDeque<Integer> getUniqueRandomNumberValues( + int seed, + int maxValue, + int numValues) { + assertTrue(numValues <= maxValue); + Random rand = new Random(WifiTestUtil.getTestMethod().hashCode() + seed); + ArrayDeque<Integer> randomNumberList = new ArrayDeque<>(); + for (int i = 0; i < numValues; i++) { + int num = rand.nextInt(maxValue); + while (randomNumberList.contains(num)) { + num = rand.nextInt(maxValue); + } + randomNumberList.push(num); + } + return randomNumberList; + } + + /** + * Verifies that the networks in pnoNetworkList is sorted in the same order as the + * network in expectedNetworkIDOrder list. + */ + private static void verifyPnoNetworkListOrder( + ArrayList<WifiNative.PnoNetworkPriority> pnoNetworkList, + ArrayList<Integer> expectedNetworkIdOrder) throws Exception { + int i = 0; + for (WifiNative.PnoNetworkPriority pnoNetwork : pnoNetworkList) { + Log.i(TAG, "PNO Network List Index: " + i + ", networkID: " + pnoNetwork.networkId); + assertTrue(pnoNetwork.networkId == expectedNetworkIdOrder.get(i++)); + } + } + + /** + * Verifies the retrievePnoNetworkPriorityList API. The test verifies that the list returned + * from the API is sorted as expected. + */ + @Test + public void testPnoNetworkPriorityListCreation() throws Exception { + addNetworks(); + + Random rand = new Random(WifiTestUtil.getTestMethod().hashCode()); + + // First assign random |numAssociation| values and verify that the list is sorted + // in descending order of |numAssociation| values. Keep NetworkSelectionStatus + // values constant. + for (int userId : USER_IDS) { + switchUser(userId); + TreeMap<Integer, Integer> numAssociationToNetworkIdMap = + new TreeMap<>(Collections.reverseOrder()); + ArrayDeque<Integer> numAssociationValues = + getUniqueRandomNumberValues( + 1, 10000, mConfiguredNetworks.valuesForCurrentUser().size()); + for (WifiConfiguration config : mConfiguredNetworks.valuesForCurrentUser()) { + config.numAssociation = numAssociationValues.pop(); + config.priority = rand.nextInt(10000); + config.status = WifiConfiguration.Status.ENABLED; + config.getNetworkSelectionStatus().setNetworkSelectionStatus( + WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_ENABLED); + numAssociationToNetworkIdMap.put(config.numAssociation, config.networkId); + Log.i(TAG, "networkID: " + config.networkId + ", numAssociation: " + + config.numAssociation); + } + ArrayList<WifiNative.PnoNetworkPriority> pnoNetworkList = + mConfigStore.retrievePnoNetworkPriorityList(true); + verifyPnoNetworkListOrder(pnoNetworkList, + new ArrayList(numAssociationToNetworkIdMap.values())); + } + + // Assign random |priority| values and verify that the list is sorted in descending order + // of |priority| values. Keep numAssociation/NetworkSelectionStatus values constant. + for (int userId : USER_IDS) { + switchUser(userId); + TreeMap<Integer, Integer> priorityToNetworkIdMap = + new TreeMap<>(Collections.reverseOrder()); + ArrayDeque<Integer> priorityValues = + getUniqueRandomNumberValues( + 2, 10000, mConfiguredNetworks.valuesForCurrentUser().size()); + for (WifiConfiguration config : mConfiguredNetworks.valuesForCurrentUser()) { + config.numAssociation = 0; + config.priority = priorityValues.pop(); + config.status = WifiConfiguration.Status.ENABLED; + config.getNetworkSelectionStatus().setNetworkSelectionStatus( + WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_ENABLED); + priorityToNetworkIdMap.put(config.priority, config.networkId); + Log.i(TAG, "networkID: " + config.networkId + ", priority: " + config.priority); + } + ArrayList<WifiNative.PnoNetworkPriority> pnoNetworkList = + mConfigStore.retrievePnoNetworkPriorityList(true); + verifyPnoNetworkListOrder(pnoNetworkList, + new ArrayList(priorityToNetworkIdMap.values())); + } + + // Now assign random |NetworkSelectionStatus| values and verify that the list is sorted in + // ascending order of |NetworkSelectionStatus| values. + for (int userId : USER_IDS) { + switchUser(userId); + TreeMap<Integer, Integer> networkSelectionStatusToNetworkIdMap = new TreeMap<>(); + ArrayDeque<Integer> networkSelectionStatusValues = + getUniqueRandomNumberValues( + 3, + WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_STATUS_MAX, + mConfiguredNetworks.valuesForCurrentUser().size()); + for (WifiConfiguration config : mConfiguredNetworks.valuesForCurrentUser()) { + config.numAssociation = rand.nextInt(10000); + config.priority = rand.nextInt(10000); + config.status = WifiConfiguration.Status.ENABLED; + config.getNetworkSelectionStatus().setNetworkSelectionStatus( + networkSelectionStatusValues.pop()); + networkSelectionStatusToNetworkIdMap.put( + config.getNetworkSelectionStatus().getNetworkSelectionStatus(), + config.networkId); + Log.i(TAG, "networkID: " + config.networkId + ", NetworkSelectionStatus: " + + config.getNetworkSelectionStatus().getNetworkSelectionStatus()); + } + ArrayList<WifiNative.PnoNetworkPriority> pnoNetworkList = + mConfigStore.retrievePnoNetworkPriorityList(true); + verifyPnoNetworkListOrder(pnoNetworkList, + new ArrayList(networkSelectionStatusToNetworkIdMap.values())); + } + } } diff --git a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java index d95dc049f..43e5da06a 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java @@ -417,7 +417,8 @@ public class WifiStateMachineTest { when(mWifiNative.setDeviceType(anyString())).thenReturn(true); when(mWifiNative.setSerialNumber(anyString())).thenReturn(true); when(mWifiNative.setScanningMacOui(any(byte[].class))).thenReturn(true); - when(mWifiNative.enableBackgroundScan(anyBoolean())).thenReturn(true); + when(mWifiNative.enableBackgroundScan(anyBoolean(), + any(ArrayList.class))).thenReturn(true); mWsm.sendMessage(WifiMonitor.SUP_CONNECTION_EVENT); wait(200); diff --git a/tests/wifitests/src/com/android/server/wifi/WifiTestUtil.java b/tests/wifitests/src/com/android/server/wifi/WifiTestUtil.java new file mode 100644 index 000000000..cf40f47be --- /dev/null +++ b/tests/wifitests/src/com/android/server/wifi/WifiTestUtil.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2015 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 java.lang.annotation.Annotation; +import java.lang.reflect.Method; + +/** + * Generial Utilities for Wifi tests + */ +public class WifiTestUtil { + + /** + * Walk up the stack and find the first method annotated with @Test + * Note: this will evaluate all overloads with the method name for the @Test annotation + */ + public static String getTestMethod() { + StackTraceElement[] stack = Thread.currentThread().getStackTrace(); + for (StackTraceElement e : stack) { + if (e.isNativeMethod()) { + continue; + } + Class clazz; + try { + clazz = Class.forName(e.getClassName()); + } catch (ClassNotFoundException ex) { + throw new RuntimeException("Could not find class from stack", ex); + } + Method[] methods = clazz.getDeclaredMethods(); + for (Method method : methods) { + if (method.getName().equals(e.getMethodName())) { + Annotation[] annotations = method.getDeclaredAnnotations(); + for (Annotation annotation : annotations) { + if (annotation.annotationType().equals(org.junit.Test.class)) { + return e.getClassName() + "#" + e.getMethodName(); + } + } + } + } + } + throw new RuntimeException("Could not find a test method in the stack"); + } +} |