summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libwifi_system/hostapd_manager.cpp8
-rw-r--r--service/java/com/android/server/wifi/FrameworkFacade.java11
-rw-r--r--service/java/com/android/server/wifi/SavedNetworkEvaluator.java50
-rw-r--r--service/java/com/android/server/wifi/SoftApModeConfiguration.java42
-rw-r--r--service/java/com/android/server/wifi/SupplicantStaIfaceHal.java128
-rw-r--r--service/java/com/android/server/wifi/WifiApConfigStore.java1
-rw-r--r--service/java/com/android/server/wifi/WifiBackupRestore.java12
-rw-r--r--service/java/com/android/server/wifi/WifiConfigManager.java55
-rw-r--r--service/java/com/android/server/wifi/WifiConfigurationUtil.java36
-rw-r--r--service/java/com/android/server/wifi/WifiConnectivityHelper.java10
-rw-r--r--service/java/com/android/server/wifi/WifiConnectivityManager.java27
-rw-r--r--service/java/com/android/server/wifi/WifiController.java3
-rw-r--r--service/java/com/android/server/wifi/WifiInjector.java3
-rw-r--r--service/java/com/android/server/wifi/WifiMonitor.java4
-rw-r--r--service/java/com/android/server/wifi/WifiNative.java10
-rw-r--r--service/java/com/android/server/wifi/WifiServiceImpl.java87
-rw-r--r--service/java/com/android/server/wifi/WifiStateMachine.java33
-rw-r--r--service/java/com/android/server/wifi/WifiVendorHal.java60
-rw-r--r--service/java/com/android/server/wifi/p2p/WifiP2pMonitor.java4
-rw-r--r--service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java8
-rw-r--r--service/java/com/android/server/wifi/scanner/WificondScannerImpl.java10
-rw-r--r--tests/wifitests/src/com/android/server/wifi/SavedNetworkEvaluatorTest.java27
-rw-r--r--tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalTest.java51
-rw-r--r--tests/wifitests/src/com/android/server/wifi/TestUtil.java8
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java2
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiBackupRestoreTest.java22
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java25
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiConfigurationTestUtil.java17
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiConfigurationUtilTest.java36
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java159
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java81
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java14
-rw-r--r--tests/wifitests/src/com/android/server/wifi/scanner/WifiScanningServiceTest.java62
33 files changed, 831 insertions, 275 deletions
diff --git a/libwifi_system/hostapd_manager.cpp b/libwifi_system/hostapd_manager.cpp
index 13bacae22..68184e901 100644
--- a/libwifi_system/hostapd_manager.cpp
+++ b/libwifi_system/hostapd_manager.cpp
@@ -109,6 +109,14 @@ bool HostapdManager::WriteHostapdConfig(const string& config) {
int error = errno;
LOG(ERROR) << "Cannot write hostapd config to \""
<< kHostapdConfigFilePath << "\": " << strerror(error);
+ struct stat st;
+ int result = stat(kHostapdConfigFilePath, &st);
+ if (result == 0) {
+ LOG(ERROR) << "hostapd config file uid: "<< st.st_uid << ", gid: " << st.st_gid
+ << ", mode: " << st.st_mode;
+ } else {
+ LOG(ERROR) << "Error calling stat() on hostapd config file: " << strerror(errno);
+ }
return false;
}
return true;
diff --git a/service/java/com/android/server/wifi/FrameworkFacade.java b/service/java/com/android/server/wifi/FrameworkFacade.java
index 2c3e5f7e0..ba114df8a 100644
--- a/service/java/com/android/server/wifi/FrameworkFacade.java
+++ b/service/java/com/android/server/wifi/FrameworkFacade.java
@@ -16,6 +16,7 @@
package com.android.server.wifi;
+import android.app.ActivityManager;
import android.app.AppGlobals;
import android.app.PendingIntent;
import android.content.Context;
@@ -161,4 +162,14 @@ public class FrameworkFacade {
public boolean inStorageManagerCryptKeeperBounce() {
return StorageManager.inCryptKeeperBounce();
}
+
+ /**
+ * Check if the provided uid is the app in the foreground.
+ * @param uid the uid to check
+ * @return true if the app is in the foreground, false otherwise
+ * @throws RemoteException
+ */
+ public boolean isAppForeground(int uid) throws RemoteException {
+ return ActivityManager.getService().isAppForeground(uid);
+ }
}
diff --git a/service/java/com/android/server/wifi/SavedNetworkEvaluator.java b/service/java/com/android/server/wifi/SavedNetworkEvaluator.java
index bf79edaf8..9ac70689b 100644
--- a/service/java/com/android/server/wifi/SavedNetworkEvaluator.java
+++ b/service/java/com/android/server/wifi/SavedNetworkEvaluator.java
@@ -107,9 +107,6 @@ public class SavedNetworkEvaluator implements WifiNetworkSelector.NetworkEvaluat
continue;
}
- WifiConfiguration.NetworkSelectionStatus status =
- network.getNetworkSelectionStatus();
-
// If a configuration is temporarily disabled, re-enable it before trying
// to connect to it.
mWifiConfigManager.tryEnableNetwork(network.networkId);
@@ -120,28 +117,26 @@ public class SavedNetworkEvaluator implements WifiNetworkSelector.NetworkEvaluat
// Clear the cached candidate, score and seen.
mWifiConfigManager.clearNetworkCandidateScanResult(network.networkId);
- boolean networkDisabled = false;
- boolean networkStringLogged = false;
- for (int index = WifiConfiguration.NetworkSelectionStatus
- .NETWORK_SELECTION_DISABLED_STARTING_INDEX;
- index < WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_DISABLED_MAX;
- index++) {
- int count = status.getDisableReasonCounter(index);
- if (count > 0) {
- networkDisabled = true;
- if (!networkStringLogged) {
- sbuf.append(" ").append(WifiNetworkSelector.toNetworkString(network))
- .append(" ");
- networkStringLogged = true;
+ // Log disabled network.
+ WifiConfiguration.NetworkSelectionStatus status = network.getNetworkSelectionStatus();
+ if (!status.isNetworkEnabled()) {
+ sbuf.append(" ").append(WifiNetworkSelector.toNetworkString(network)).append(" ");
+ for (int index = WifiConfiguration.NetworkSelectionStatus
+ .NETWORK_SELECTION_DISABLED_STARTING_INDEX;
+ index < WifiConfiguration.NetworkSelectionStatus
+ .NETWORK_SELECTION_DISABLED_MAX;
+ index++) {
+ int count = status.getDisableReasonCounter(index);
+ // Here we log the reason as long as its count is greater than zero. The
+ // network may not be disabled because of this particular reason. Logging
+ // this information anyway to help understand what happened to the network.
+ if (count > 0) {
+ sbuf.append("reason=")
+ .append(WifiConfiguration.NetworkSelectionStatus
+ .getNetworkDisableReasonString(index))
+ .append(", count=").append(count).append("; ");
}
- sbuf.append("reason=")
- .append(WifiConfiguration.NetworkSelectionStatus
- .getNetworkDisableReasonString(index))
- .append(", count=").append(count).append("; ");
}
- }
-
- if (networkDisabled) {
sbuf.append("\n");
}
}
@@ -264,11 +259,12 @@ public class SavedNetworkEvaluator implements WifiNetworkSelector.NetworkEvaluat
for (WifiConfiguration network : associatedConfigurations) {
/**
- * Ignore Passpoint networks. Passpoint networks are also considered as "saved"
- * network, but without being persisted to the storage. They are being evaluated
- * by {@link PasspointNetworkEvaluator}.
+ * Ignore Passpoint and Ephemeral networks. They are configured networks,
+ * but without being persisted to the storage. They are evaluated by
+ * {@link PasspointNetworkEvaluator} and {@link ScoredNetworkEvaluator}
+ * respectively.
*/
- if (network.isPasspoint()) {
+ if (network.isPasspoint() || network.isEphemeral()) {
continue;
}
diff --git a/service/java/com/android/server/wifi/SoftApModeConfiguration.java b/service/java/com/android/server/wifi/SoftApModeConfiguration.java
new file mode 100644
index 000000000..e8805602e
--- /dev/null
+++ b/service/java/com/android/server/wifi/SoftApModeConfiguration.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2017 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 android.net.wifi.WifiConfiguration;
+
+/**
+ * Object holding the parameters needed to start SoftAp mode.
+ *
+ * Initially, this will hold the WifiConfiguration and mode.
+ */
+public class SoftApModeConfiguration {
+ final int mTargetMode;
+ final WifiConfiguration mConfig;
+
+ SoftApModeConfiguration(int targetMode, WifiConfiguration config) {
+ mTargetMode = targetMode;
+ mConfig = config;
+ }
+
+ public int getTargetMode() {
+ return mTargetMode;
+ }
+
+ public WifiConfiguration getWifiConfiguration() {
+ return mConfig;
+ }
+}
diff --git a/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java b/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java
index 99067430b..e9c20db32 100644
--- a/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java
+++ b/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java
@@ -26,6 +26,7 @@ import static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.HS
import static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.HSOSUProviders;
import static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.HSWANMetrics;
+import android.annotation.NonNull;
import android.content.Context;
import android.hardware.wifi.supplicant.V1_0.ISupplicant;
import android.hardware.wifi.supplicant.V1_0.ISupplicantIface;
@@ -49,6 +50,7 @@ import android.os.HwRemoteBinder;
import android.os.RemoteException;
import android.text.TextUtils;
import android.util.Log;
+import android.util.Pair;
import android.util.SparseArray;
import com.android.server.wifi.hotspot2.AnqpEvent;
@@ -125,10 +127,8 @@ public class SupplicantStaIfaceHal {
};
private String mIfaceName;
- // Currently configured network in wpa_supplicant
- private SupplicantStaNetworkHal mCurrentNetwork;
- // Currently configured network's framework network Id.
- private int mFrameworkNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
+ private SupplicantStaNetworkHal mCurrentNetworkRemoteHandle;
+ private WifiConfiguration mCurrentNetworkLocalConfig;
private final Context mContext;
private final WifiMonitor mWifiMonitor;
@@ -254,6 +254,13 @@ public class SupplicantStaIfaceHal {
return true;
}
+ private int getCurrentNetworkId() {
+ if (mCurrentNetworkLocalConfig == null) {
+ return WifiConfiguration.INVALID_NETWORK_ID;
+ }
+ return mCurrentNetworkLocalConfig.networkId;
+ }
+
private boolean initSupplicantStaIface() {
synchronized (mLock) {
/** List all supplicant Ifaces */
@@ -353,9 +360,11 @@ public class SupplicantStaIfaceHal {
* Add a network configuration to wpa_supplicant.
*
* @param config Config corresponding to the network.
- * @return SupplicantStaNetwork of the added network in wpa_supplicant.
+ * @return a Pair object including SupplicantStaNetworkHal and WifiConfiguration objects
+ * for the current network.
*/
- private SupplicantStaNetworkHal addNetworkAndSaveConfig(WifiConfiguration config) {
+ private Pair<SupplicantStaNetworkHal, WifiConfiguration>
+ addNetworkAndSaveConfig(WifiConfiguration config) {
logi("addSupplicantStaNetwork via HIDL");
if (config == null) {
loge("Cannot add NULL network!");
@@ -379,39 +388,43 @@ public class SupplicantStaIfaceHal {
}
return null;
}
- return network;
+ return new Pair(network, new WifiConfiguration(config));
}
/**
* Add the provided network configuration to wpa_supplicant and initiate connection to it.
* This method does the following:
- * 1. Triggers disconnect command to wpa_supplicant (if |shouldDisconnect| is true).
- * 2. Remove any existing network in wpa_supplicant.
- * 3. Add a new network to wpa_supplicant.
- * 4. Save the provided configuration to wpa_supplicant.
- * 5. Select the new network in wpa_supplicant.
+ * 1. If |config| is different to the current supplicant network, removes all supplicant
+ * networks and saves |config|.
+ * 2. Select the new network in wpa_supplicant.
*
* @param config WifiConfiguration parameters for the provided network.
* @return {@code true} if it succeeds, {@code false} otherwise
*/
- public boolean connectToNetwork(WifiConfiguration config) {
- mFrameworkNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
- mCurrentNetwork = null;
+ public boolean connectToNetwork(@NonNull WifiConfiguration config) {
logd("connectToNetwork " + config.configKey());
- if (!removeAllNetworks()) {
- loge("Failed to remove existing networks");
- return false;
- }
- mCurrentNetwork = addNetworkAndSaveConfig(config);
- if (mCurrentNetwork == null) {
- loge("Failed to add/save network configuration: " + config.configKey());
- return false;
+ if (WifiConfigurationUtil.isSameNetwork(config, mCurrentNetworkLocalConfig)) {
+ logd("Network is already saved, will not trigger remove and add operation.");
+ } else {
+ mCurrentNetworkRemoteHandle = null;
+ mCurrentNetworkLocalConfig = null;
+ if (!removeAllNetworks()) {
+ loge("Failed to remove existing networks");
+ return false;
+ }
+ Pair<SupplicantStaNetworkHal, WifiConfiguration> pair = addNetworkAndSaveConfig(config);
+ if (pair == null) {
+ loge("Failed to add/save network configuration: " + config.configKey());
+ return false;
+ }
+ mCurrentNetworkRemoteHandle = pair.first;
+ mCurrentNetworkLocalConfig = pair.second;
}
- if (!mCurrentNetwork.select()) {
+
+ if (!mCurrentNetworkRemoteHandle.select()) {
loge("Failed to select network configuration: " + config.configKey());
return false;
}
- mFrameworkNetworkId = config.networkId;
return true;
}
@@ -428,14 +441,14 @@ public class SupplicantStaIfaceHal {
* @return {@code true} if it succeeds, {@code false} otherwise
*/
public boolean roamToNetwork(WifiConfiguration config) {
- if (mFrameworkNetworkId != config.networkId || mCurrentNetwork == null) {
+ if (getCurrentNetworkId() != config.networkId) {
Log.w(TAG, "Cannot roam to a different network, initiate new connection. "
- + "Current network ID: " + mFrameworkNetworkId);
+ + "Current network ID: " + getCurrentNetworkId());
return connectToNetwork(config);
}
String bssid = config.getNetworkSelectionStatus().getNetworkSelectionBSSID();
logd("roamToNetwork" + config.configKey() + " (bssid " + bssid + ")");
- if (!mCurrentNetwork.setBssid(bssid)) {
+ if (!mCurrentNetworkRemoteHandle.setBssid(bssid)) {
loge("Failed to set new bssid on network: " + config.configKey());
return false;
}
@@ -498,6 +511,21 @@ public class SupplicantStaIfaceHal {
}
/**
+ * Remove the request |networkId| from supplicant if it's the current network,
+ * if the current configured network matches |networkId|.
+ *
+ * @param networkId network id of the network to be removed from supplicant.
+ */
+ public void removeNetworkIfCurrent(int networkId) {
+ synchronized (mLock) {
+ if (getCurrentNetworkId() == networkId) {
+ // Currently we only save 1 network in supplicant.
+ removeAllNetworks();
+ }
+ }
+ }
+
+ /**
* Remove all networks from supplicant
*/
public boolean removeAllNetworks() {
@@ -516,8 +544,8 @@ public class SupplicantStaIfaceHal {
}
// Reset current network info. Probably not needed once we add support to remove/reset
// current network on receiving disconnection event from supplicant (b/32898136).
- mFrameworkNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
- mCurrentNetwork = null;
+ mCurrentNetworkLocalConfig = null;
+ mCurrentNetworkRemoteHandle = null;
return true;
}
@@ -528,8 +556,8 @@ public class SupplicantStaIfaceHal {
* @return true if succeeds, false otherwise.
*/
public boolean setCurrentNetworkBssid(String bssidStr) {
- if (mCurrentNetwork == null) return false;
- return mCurrentNetwork.setBssid(bssidStr);
+ if (mCurrentNetworkRemoteHandle == null) return false;
+ return mCurrentNetworkRemoteHandle.setBssid(bssidStr);
}
/**
@@ -538,8 +566,8 @@ public class SupplicantStaIfaceHal {
* @return Hex string corresponding to the WPS NFC token.
*/
public String getCurrentNetworkWpsNfcConfigurationToken() {
- if (mCurrentNetwork == null) return null;
- return mCurrentNetwork.getWpsNfcConfigurationToken();
+ if (mCurrentNetworkRemoteHandle == null) return null;
+ return mCurrentNetworkRemoteHandle.getWpsNfcConfigurationToken();
}
/**
@@ -548,8 +576,8 @@ public class SupplicantStaIfaceHal {
* @return anonymous identity string if succeeds, null otherwise.
*/
public String getCurrentNetworkEapAnonymousIdentity() {
- if (mCurrentNetwork == null) return null;
- return mCurrentNetwork.fetchEapAnonymousIdentity();
+ if (mCurrentNetworkRemoteHandle == null) return null;
+ return mCurrentNetworkRemoteHandle.fetchEapAnonymousIdentity();
}
/**
@@ -559,8 +587,8 @@ public class SupplicantStaIfaceHal {
* @return true if succeeds, false otherwise.
*/
public boolean sendCurrentNetworkEapIdentityResponse(String identityStr) {
- if (mCurrentNetwork == null) return false;
- return mCurrentNetwork.sendNetworkEapIdentityResponse(identityStr);
+ if (mCurrentNetworkRemoteHandle == null) return false;
+ return mCurrentNetworkRemoteHandle.sendNetworkEapIdentityResponse(identityStr);
}
/**
@@ -570,8 +598,8 @@ public class SupplicantStaIfaceHal {
* @return true if succeeds, false otherwise.
*/
public boolean sendCurrentNetworkEapSimGsmAuthResponse(String paramsStr) {
- if (mCurrentNetwork == null) return false;
- return mCurrentNetwork.sendNetworkEapSimGsmAuthResponse(paramsStr);
+ if (mCurrentNetworkRemoteHandle == null) return false;
+ return mCurrentNetworkRemoteHandle.sendNetworkEapSimGsmAuthResponse(paramsStr);
}
/**
@@ -580,8 +608,8 @@ public class SupplicantStaIfaceHal {
* @return true if succeeds, false otherwise.
*/
public boolean sendCurrentNetworkEapSimGsmAuthFailure() {
- if (mCurrentNetwork == null) return false;
- return mCurrentNetwork.sendNetworkEapSimGsmAuthFailure();
+ if (mCurrentNetworkRemoteHandle == null) return false;
+ return mCurrentNetworkRemoteHandle.sendNetworkEapSimGsmAuthFailure();
}
/**
@@ -591,8 +619,8 @@ public class SupplicantStaIfaceHal {
* @return true if succeeds, false otherwise.
*/
public boolean sendCurrentNetworkEapSimUmtsAuthResponse(String paramsStr) {
- if (mCurrentNetwork == null) return false;
- return mCurrentNetwork.sendNetworkEapSimUmtsAuthResponse(paramsStr);
+ if (mCurrentNetworkRemoteHandle == null) return false;
+ return mCurrentNetworkRemoteHandle.sendNetworkEapSimUmtsAuthResponse(paramsStr);
}
/**
@@ -602,8 +630,8 @@ public class SupplicantStaIfaceHal {
* @return true if succeeds, false otherwise.
*/
public boolean sendCurrentNetworkEapSimUmtsAutsResponse(String paramsStr) {
- if (mCurrentNetwork == null) return false;
- return mCurrentNetwork.sendNetworkEapSimUmtsAutsResponse(paramsStr);
+ if (mCurrentNetworkRemoteHandle == null) return false;
+ return mCurrentNetworkRemoteHandle.sendNetworkEapSimUmtsAutsResponse(paramsStr);
}
/**
@@ -612,8 +640,8 @@ public class SupplicantStaIfaceHal {
* @return true if succeeds, false otherwise.
*/
public boolean sendCurrentNetworkEapSimUmtsAuthFailure() {
- if (mCurrentNetwork == null) return false;
- return mCurrentNetwork.sendNetworkEapSimUmtsAuthFailure();
+ if (mCurrentNetworkRemoteHandle == null) return false;
+ return mCurrentNetworkRemoteHandle.sendNetworkEapSimUmtsAuthFailure();
}
/**
@@ -1858,10 +1886,10 @@ public class SupplicantStaIfaceHal {
mStateIsFourway = (newState == ISupplicantStaIfaceCallback.State.FOURWAY_HANDSHAKE);
if (newSupplicantState == SupplicantState.COMPLETED) {
mWifiMonitor.broadcastNetworkConnectionEvent(
- mIfaceName, mFrameworkNetworkId, bssidStr);
+ mIfaceName, getCurrentNetworkId(), bssidStr);
}
mWifiMonitor.broadcastSupplicantStateChangeEvent(
- mIfaceName, mFrameworkNetworkId, wifiSsid, bssidStr, newSupplicantState);
+ mIfaceName, getCurrentNetworkId(), wifiSsid, bssidStr, newSupplicantState);
}
}
diff --git a/service/java/com/android/server/wifi/WifiApConfigStore.java b/service/java/com/android/server/wifi/WifiApConfigStore.java
index 850c5aebe..9c90bcf47 100644
--- a/service/java/com/android/server/wifi/WifiApConfigStore.java
+++ b/service/java/com/android/server/wifi/WifiApConfigStore.java
@@ -218,6 +218,7 @@ public class WifiApConfigStore {
R.string.wifi_localhotspot_configure_ssid_default) + "_"
+ getRandomIntForDefaultSsid();
config.allowedKeyManagement.set(KeyMgmt.WPA2_PSK);
+ config.networkId = WifiConfiguration.LOCAL_ONLY_NETWORK_ID;
String randomUUID = UUID.randomUUID().toString();
// first 12 chars from xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
config.preSharedKey = randomUUID.substring(0, 8) + randomUUID.substring(9, 13);
diff --git a/service/java/com/android/server/wifi/WifiBackupRestore.java b/service/java/com/android/server/wifi/WifiBackupRestore.java
index 4095d8283..60c3b488d 100644
--- a/service/java/com/android/server/wifi/WifiBackupRestore.java
+++ b/service/java/com/android/server/wifi/WifiBackupRestore.java
@@ -28,6 +28,7 @@ import android.util.Xml;
import com.android.internal.util.FastXmlSerializer;
import com.android.server.net.IpConfigStore;
import com.android.server.wifi.util.NativeUtil;
+import com.android.server.wifi.util.WifiPermissionsUtil;
import com.android.server.wifi.util.XmlUtil;
import com.android.server.wifi.util.XmlUtil.IpConfigurationXmlUtil;
import com.android.server.wifi.util.XmlUtil.WifiConfigurationXmlUtil;
@@ -96,6 +97,7 @@ public class WifiBackupRestore {
private static final String WEP_KEYS_MASK_SEARCH_PATTERN = "(<.*=)(.*)(/>)";
private static final String WEP_KEYS_MASK_REPLACE_PATTERN = "$1*$3";
+ private final WifiPermissionsUtil mWifiPermissionsUtil;
/**
* Verbose logging flag.
*/
@@ -109,6 +111,10 @@ public class WifiBackupRestore {
private byte[] mDebugLastBackupDataRestored;
private byte[] mDebugLastSupplicantBackupDataRestored;
+ public WifiBackupRestore(WifiPermissionsUtil wifiPermissionsUtil) {
+ mWifiPermissionsUtil = wifiPermissionsUtil;
+ }
+
/**
* Retrieve an XML byte stream representing the data that needs to be backed up from the
* provided configurations.
@@ -163,7 +169,9 @@ public class WifiBackupRestore {
if (configuration.isEnterprise() || configuration.isPasspoint()) {
continue;
}
- if (configuration.creatorUid >= Process.FIRST_APPLICATION_UID) {
+ if (!mWifiPermissionsUtil.checkConfigOverridePermission(configuration.creatorUid)) {
+ Log.d(TAG, "Ignoring network from an app with no config override permission: "
+ + configuration.configKey());
continue;
}
// Write this configuration data now.
@@ -702,6 +710,8 @@ public class WifiBackupRestore {
Integer.parseInt(extras.get(
SupplicantStaNetworkHal.ID_STRING_KEY_CREATOR_UID));
if (creatorUid >= Process.FIRST_APPLICATION_UID) {
+ Log.d(TAG, "Ignoring network from non-system app: "
+ + configuration.configKey());
return null;
}
}
diff --git a/service/java/com/android/server/wifi/WifiConfigManager.java b/service/java/com/android/server/wifi/WifiConfigManager.java
index 3f31c7ff8..4b2bb1c49 100644
--- a/service/java/com/android/server/wifi/WifiConfigManager.java
+++ b/service/java/com/android/server/wifi/WifiConfigManager.java
@@ -152,10 +152,29 @@ public class WifiConfigManager {
*/
public interface OnSavedNetworkUpdateListener {
/**
- * Invoked on saved network being enabled, disabled, blacklisted or
- * un-blacklisted.
+ * Invoked on saved network being added.
*/
- void onSavedNetworkUpdate();
+ void onSavedNetworkAdded(int networkId);
+ /**
+ * Invoked on saved network being enabled.
+ */
+ void onSavedNetworkEnabled(int networkId);
+ /**
+ * Invoked on saved network being permanently disabled.
+ */
+ void onSavedNetworkPermanentlyDisabled(int networkId);
+ /**
+ * Invoked on saved network being removed.
+ */
+ void onSavedNetworkRemoved(int networkId);
+ /**
+ * Invoked on saved network being temporarily disabled.
+ */
+ void onSavedNetworkTemporarilyDisabled(int networkId);
+ /**
+ * Invoked on saved network being updated.
+ */
+ void onSavedNetworkUpdated(int networkId);
}
/**
* Max size of scan details to cache in {@link #mScanDetailCaches}.
@@ -1039,7 +1058,13 @@ public class WifiConfigManager {
// Unless the added network is ephemeral or Passpoint, persist the network update/addition.
if (!config.ephemeral && !config.isPasspoint()) {
saveToStore(true);
- if (mListener != null) mListener.onSavedNetworkUpdate();
+ if (mListener != null) {
+ if (result.isNewNetwork()) {
+ mListener.onSavedNetworkAdded(newConfig.networkId);
+ } else {
+ mListener.onSavedNetworkUpdated(newConfig.networkId);
+ }
+ }
}
return result;
}
@@ -1104,7 +1129,7 @@ public class WifiConfigManager {
// Unless the removed network is ephemeral or Passpoint, persist the network removal.
if (!config.ephemeral && !config.isPasspoint()) {
saveToStore(true);
- if (mListener != null) mListener.onSavedNetworkUpdate();
+ if (mListener != null) mListener.onSavedNetworkRemoved(networkId);
}
return true;
}
@@ -1165,7 +1190,8 @@ public class WifiConfigManager {
/**
* Helper method to mark a network enabled for network selection.
*/
- private void setNetworkSelectionEnabled(NetworkSelectionStatus status) {
+ private void setNetworkSelectionEnabled(WifiConfiguration config) {
+ NetworkSelectionStatus status = config.getNetworkSelectionStatus();
status.setNetworkSelectionStatus(
NetworkSelectionStatus.NETWORK_SELECTION_ENABLED);
status.setDisableTime(
@@ -1174,32 +1200,35 @@ public class WifiConfigManager {
// Clear out all the disable reason counters.
status.clearDisableReasonCounter();
- if (mListener != null) mListener.onSavedNetworkUpdate();
+ if (mListener != null) mListener.onSavedNetworkEnabled(config.networkId);
}
/**
* Helper method to mark a network temporarily disabled for network selection.
*/
private void setNetworkSelectionTemporarilyDisabled(
- NetworkSelectionStatus status, int disableReason) {
+ WifiConfiguration config, int disableReason) {
+ NetworkSelectionStatus status = config.getNetworkSelectionStatus();
status.setNetworkSelectionStatus(
NetworkSelectionStatus.NETWORK_SELECTION_TEMPORARY_DISABLED);
// Only need a valid time filled in for temporarily disabled networks.
status.setDisableTime(mClock.getElapsedSinceBootMillis());
status.setNetworkSelectionDisableReason(disableReason);
+ if (mListener != null) mListener.onSavedNetworkTemporarilyDisabled(config.networkId);
}
/**
* Helper method to mark a network permanently disabled for network selection.
*/
private void setNetworkSelectionPermanentlyDisabled(
- NetworkSelectionStatus status, int disableReason) {
+ WifiConfiguration config, int disableReason) {
+ NetworkSelectionStatus status = config.getNetworkSelectionStatus();
status.setNetworkSelectionStatus(
NetworkSelectionStatus.NETWORK_SELECTION_PERMANENTLY_DISABLED);
status.setDisableTime(
NetworkSelectionStatus.INVALID_NETWORK_SELECTION_DISABLE_TIMESTAMP);
status.setNetworkSelectionDisableReason(disableReason);
- if (mListener != null) mListener.onSavedNetworkUpdate();
+ if (mListener != null) mListener.onSavedNetworkPermanentlyDisabled(config.networkId);
}
/**
@@ -1230,12 +1259,12 @@ public class WifiConfigManager {
return false;
}
if (reason == NetworkSelectionStatus.NETWORK_SELECTION_ENABLE) {
- setNetworkSelectionEnabled(networkStatus);
+ setNetworkSelectionEnabled(config);
setNetworkStatus(config, WifiConfiguration.Status.ENABLED);
} else if (reason < NetworkSelectionStatus.DISABLED_TLS_VERSION_MISMATCH) {
- setNetworkSelectionTemporarilyDisabled(networkStatus, reason);
+ setNetworkSelectionTemporarilyDisabled(config, reason);
} else {
- setNetworkSelectionPermanentlyDisabled(networkStatus, reason);
+ setNetworkSelectionPermanentlyDisabled(config, reason);
setNetworkStatus(config, WifiConfiguration.Status.DISABLED);
}
localLog("setNetworkSelectionStatus: configKey=" + config.configKey()
diff --git a/service/java/com/android/server/wifi/WifiConfigurationUtil.java b/service/java/com/android/server/wifi/WifiConfigurationUtil.java
index 67f1faded..c726f4966 100644
--- a/service/java/com/android/server/wifi/WifiConfigurationUtil.java
+++ b/service/java/com/android/server/wifi/WifiConfigurationUtil.java
@@ -235,6 +235,41 @@ public class WifiConfigurationUtil {
}
/**
+ * Check if the provided two networks are the same.
+ *
+ * @param config Configuration corresponding to a network.
+ * @param config1 Configuration corresponding to another network.
+ *
+ * @return true if |config| and |config1| are the same network.
+ * false otherwise.
+ */
+ public static boolean isSameNetwork(WifiConfiguration config, WifiConfiguration config1) {
+ if (config == null && config1 == null) {
+ return true;
+ }
+ if (config == null || config1 == null) {
+ return false;
+ }
+ if (config.networkId != config1.networkId) {
+ return false;
+ }
+ if (!Objects.equals(config.SSID, config1.SSID)) {
+ return false;
+ }
+ String networkSelectionBSSID = config.getNetworkSelectionStatus()
+ .getNetworkSelectionBSSID();
+ String networkSelectionBSSID1 = config1.getNetworkSelectionStatus()
+ .getNetworkSelectionBSSID();
+ if (!Objects.equals(networkSelectionBSSID, networkSelectionBSSID1)) {
+ return false;
+ }
+ if (WifiConfigurationUtil.hasCredentialChanged(config, config1)) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
* Create a PnoNetwork object from the provided WifiConfiguration.
*
* @param config Configuration corresponding to the network.
@@ -261,6 +296,7 @@ public class WifiConfigurationUtil {
return pnoNetwork;
}
+
/**
* General WifiConfiguration list sorting algorithm:
* 1, Place the fully enabled networks first.
diff --git a/service/java/com/android/server/wifi/WifiConnectivityHelper.java b/service/java/com/android/server/wifi/WifiConnectivityHelper.java
index 6016b57b5..4aac31168 100644
--- a/service/java/com/android/server/wifi/WifiConnectivityHelper.java
+++ b/service/java/com/android/server/wifi/WifiConnectivityHelper.java
@@ -161,4 +161,14 @@ public class WifiConnectivityHelper {
return mWifiNative.configureRoaming(roamConfig);
}
+
+ /**
+ * Remove the request |networkId| from supplicant if it's the current network,
+ * if the current configured network matches |networkId|.
+ *
+ * @param networkId network id of the network to be removed from supplicant.
+ */
+ public void removeNetworkIfCurrent(int networkId) {
+ mWifiNative.removeNetworkIfCurrent(networkId);
+ }
}
diff --git a/service/java/com/android/server/wifi/WifiConnectivityManager.java b/service/java/com/android/server/wifi/WifiConnectivityManager.java
index 6d82ce869..f45d17b41 100644
--- a/service/java/com/android/server/wifi/WifiConnectivityManager.java
+++ b/service/java/com/android/server/wifi/WifiConnectivityManager.java
@@ -487,7 +487,32 @@ public class WifiConnectivityManager {
private class OnSavedNetworkUpdateListener implements
WifiConfigManager.OnSavedNetworkUpdateListener {
- public void onSavedNetworkUpdate() {
+ @Override
+ public void onSavedNetworkAdded(int networkId) {
+ updatePnoScan();
+ }
+ @Override
+ public void onSavedNetworkEnabled(int networkId) {
+ updatePnoScan();
+ }
+ @Override
+ public void onSavedNetworkRemoved(int networkId) {
+ updatePnoScan();
+ }
+ @Override
+ public void onSavedNetworkUpdated(int networkId) {
+ updatePnoScan();
+ }
+ @Override
+ public void onSavedNetworkTemporarilyDisabled(int networkId) {
+ mConnectivityHelper.removeNetworkIfCurrent(networkId);
+ }
+ @Override
+ public void onSavedNetworkPermanentlyDisabled(int networkId) {
+ mConnectivityHelper.removeNetworkIfCurrent(networkId);
+ updatePnoScan();
+ }
+ private void updatePnoScan() {
// Update the PNO scan network list when screen is off. Here we
// rely on startConnectivityScan() to perform all the checks and clean up.
if (!mScreenOn) {
diff --git a/service/java/com/android/server/wifi/WifiController.java b/service/java/com/android/server/wifi/WifiController.java
index ed82b2b2d..c1b186142 100644
--- a/service/java/com/android/server/wifi/WifiController.java
+++ b/service/java/com/android/server/wifi/WifiController.java
@@ -30,7 +30,6 @@ import android.content.IntentFilter;
import android.database.ContentObserver;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
-import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.os.Looper;
@@ -480,7 +479,7 @@ public class WifiController extends StateMachine {
if (msg.arg2 == 0) { // previous wifi state has not been saved yet
mSettingsStore.setWifiSavedState(WifiSettingsStore.WIFI_DISABLED);
}
- mWifiStateMachine.setHostApRunning((WifiConfiguration) msg.obj,
+ mWifiStateMachine.setHostApRunning((SoftApModeConfiguration) msg.obj,
true);
transitionTo(mApEnabledState);
}
diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java
index 90e400cc1..c51778578 100644
--- a/service/java/com/android/server/wifi/WifiInjector.java
+++ b/service/java/com/android/server/wifi/WifiInjector.java
@@ -96,7 +96,7 @@ public class WifiInjector {
private final PropertyService mPropertyService = new SystemPropertyService();
private final BuildProperties mBuildProperties = new SystemBuildProperties();
private final KeyStore mKeyStore = KeyStore.getInstance();
- private final WifiBackupRestore mWifiBackupRestore = new WifiBackupRestore();
+ private final WifiBackupRestore mWifiBackupRestore;
private final WifiMulticastLockManager mWifiMulticastLockManager;
private final WifiConfigStore mWifiConfigStore;
private final WifiKeyStore mWifiKeyStore;
@@ -150,6 +150,7 @@ public class WifiInjector {
mWifiNetworkScoreCache, NetworkScoreManager.CACHE_FILTER_NONE);
mWifiPermissionsUtil = new WifiPermissionsUtil(mWifiPermissionsWrapper, mContext,
mSettingsStore, UserManager.get(mContext), mNetworkScoreManager, this);
+ mWifiBackupRestore = new WifiBackupRestore(mWifiPermissionsUtil);
mBatteryStats = IBatteryStats.Stub.asInterface(mFrameworkFacade.getService(
BatteryStats.SERVICE_NAME));
mWifiStateTracker = new WifiStateTracker(mBatteryStats);
diff --git a/service/java/com/android/server/wifi/WifiMonitor.java b/service/java/com/android/server/wifi/WifiMonitor.java
index 385bfccaa..b2fc56e25 100644
--- a/service/java/com/android/server/wifi/WifiMonitor.java
+++ b/service/java/com/android/server/wifi/WifiMonitor.java
@@ -179,9 +179,9 @@ public class WifiMonitor {
if (mConnected) {
return true;
}
- if (connectTries++ < 5) {
+ if (connectTries++ < 50) {
try {
- Thread.sleep(1000);
+ Thread.sleep(100);
} catch (InterruptedException ignore) {
}
} else {
diff --git a/service/java/com/android/server/wifi/WifiNative.java b/service/java/com/android/server/wifi/WifiNative.java
index abe692346..90f6ac195 100644
--- a/service/java/com/android/server/wifi/WifiNative.java
+++ b/service/java/com/android/server/wifi/WifiNative.java
@@ -787,6 +787,16 @@ public class WifiNative {
public String getCurrentNetworkWpsNfcConfigurationToken() {
return mSupplicantStaIfaceHal.getCurrentNetworkWpsNfcConfigurationToken();
}
+
+ /** Remove the request |networkId| from supplicant if it's the current network,
+ * if the current configured network matches |networkId|.
+ *
+ * @param networkId network id of the network to be removed from supplicant.
+ */
+ public void removeNetworkIfCurrent(int networkId) {
+ mSupplicantStaIfaceHal.removeNetworkIfCurrent(networkId);
+ }
+
/********************************************************
* Vendor HAL operations
********************************************************/
diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java
index ec05f7cec..5c9548a54 100644
--- a/service/java/com/android/server/wifi/WifiServiceImpl.java
+++ b/service/java/com/android/server/wifi/WifiServiceImpl.java
@@ -18,6 +18,8 @@ package com.android.server.wifi;
import static android.net.wifi.WifiManager.EXTRA_PREVIOUS_WIFI_AP_STATE;
import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_FAILURE_REASON;
+import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME;
+import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_MODE;
import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_STATE;
import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_GENERIC;
import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_NO_CHANNEL;
@@ -26,8 +28,6 @@ import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED;
import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLING;
import static android.net.wifi.WifiManager.WIFI_AP_STATE_FAILED;
-import static com.android.server.connectivity.tethering.IControlsTethering.STATE_LOCAL_ONLY;
-import static com.android.server.connectivity.tethering.IControlsTethering.STATE_TETHERED;
import static com.android.server.wifi.LocalOnlyHotspotRequestInfo.HOTSPOT_NO_ERROR;
import static com.android.server.wifi.WifiController.CMD_AIRPLANE_TOGGLED;
import static com.android.server.wifi.WifiController.CMD_BATTERY_CHANGED;
@@ -485,13 +485,17 @@ public class WifiServiceImpl extends IWifiManager.Stub {
new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- final int currentState = intent.getIntExtra(EXTRA_WIFI_AP_STATE,
+ final int currState = intent.getIntExtra(EXTRA_WIFI_AP_STATE,
WIFI_AP_STATE_DISABLED);
final int prevState = intent.getIntExtra(EXTRA_PREVIOUS_WIFI_AP_STATE,
WIFI_AP_STATE_DISABLED);
final int errorCode = intent.getIntExtra(EXTRA_WIFI_AP_FAILURE_REASON,
HOTSPOT_NO_ERROR);
- handleWifiApStateChange(currentState, prevState, errorCode);
+ final String ifaceName =
+ intent.getStringExtra(EXTRA_WIFI_AP_INTERFACE_NAME);
+ final int mode = intent.getIntExtra(EXTRA_WIFI_AP_MODE,
+ WifiManager.IFACE_IP_MODE_UNSPECIFIED);
+ handleWifiApStateChange(currState, prevState, errorCode, ifaceName, mode);
}
},
new IntentFilter(WifiManager.WIFI_AP_STATE_CHANGED_ACTION));
@@ -818,7 +822,9 @@ public class WifiServiceImpl extends IWifiManager.Stub {
}
// null wifiConfig is a meaningful input for CMD_SET_AP
if (wifiConfig == null || isValid(wifiConfig)) {
- mWifiController.sendMessage(CMD_SET_AP, enabled ? 1 : 0, 0, wifiConfig);
+ int mode = WifiManager.IFACE_IP_MODE_UNSPECIFIED;
+ SoftApModeConfiguration softApConfig = new SoftApModeConfiguration(mode, wifiConfig);
+ mWifiController.sendMessage(CMD_SET_AP, enabled ? 1 : 0, 0, softApConfig);
} else {
Slog.e(TAG, "Invalid WifiConfiguration");
}
@@ -892,14 +898,12 @@ public class WifiServiceImpl extends IWifiManager.Stub {
// between a tether request and a hotspot request (tethering wins).
sendHotspotFailedMessageToAllLOHSRequestInfoEntriesLocked(
LocalOnlyHotspotCallback.ERROR_INCOMPATIBLE_MODE);
- mLocalOnlyHotspotRequests.clear();
break;
case WifiManager.IFACE_IP_MODE_CONFIGURATION_ERROR:
// there was an error setting up the hotspot... trigger onFailed for the
// registered LOHS requestors
sendHotspotFailedMessageToAllLOHSRequestInfoEntriesLocked(
LocalOnlyHotspotCallback.ERROR_GENERIC);
- mLocalOnlyHotspotRequests.clear();
updateInterfaceIpStateInternal(null, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
break;
case WifiManager.IFACE_IP_MODE_UNSPECIFIED:
@@ -930,12 +934,15 @@ public class WifiServiceImpl extends IWifiManager.Stub {
mLog.trace("startSoftAp uid=%").c(Binder.getCallingUid()).flush();
- // TODO: determine if we need to stop softap and clean up state if a tethering request comes
- // from the user while we are just setting up. For now, the second CMD_START_AP will be
- // ignored in WifiStateMachine. This will still bring up tethering and the registered LOHS
- // requests will be cleared when we get the interface ip tethered status.
+ synchronized (mLocalOnlyHotspotRequests) {
+ // If a tethering request comes in while we have LOHS running (or requested), call stop
+ // for softap mode and restart softap with the tethering config.
+ if (!mLocalOnlyHotspotRequests.isEmpty()) {
+ stopSoftApInternal();
+ }
- return startSoftApInternal(wifiConfig, STATE_TETHERED);
+ return startSoftApInternal(wifiConfig, WifiManager.IFACE_IP_MODE_TETHERED);
+ }
}
/**
@@ -948,8 +955,8 @@ public class WifiServiceImpl extends IWifiManager.Stub {
// null wifiConfig is a meaningful input for CMD_SET_AP
if (wifiConfig == null || isValid(wifiConfig)) {
- // TODO: need a way to set the mode
- mWifiController.sendMessage(CMD_SET_AP, 1, 0, wifiConfig);
+ SoftApModeConfiguration softApConfig = new SoftApModeConfiguration(mode, wifiConfig);
+ mWifiController.sendMessage(CMD_SET_AP, 1, 0, softApConfig);
return true;
}
Slog.e(TAG, "Invalid WifiConfiguration");
@@ -966,12 +973,21 @@ public class WifiServiceImpl extends IWifiManager.Stub {
// NETWORK_STACK is a signature only permission.
enforceNetworkStackPermission();
+ // only permitted callers are allowed to this point - they must have gone through
+ // connectivity service since this method is protected with the NETWORK_STACK PERMISSION
+
mLog.trace("stopSoftAp uid=%").c(Binder.getCallingUid()).flush();
- // add checks here to make sure this is the proper caller - apps can't disable tethering or
- // instances of local only hotspot that they didn't start. return false for those cases
+ synchronized (mLocalOnlyHotspotRequests) {
+ // If a tethering request comes in while we have LOHS running (or requested), call stop
+ // for softap mode and restart softap with the tethering config.
+ if (!mLocalOnlyHotspotRequests.isEmpty()) {
+ mLog.trace("Call to stop Tethering while LOHS is active,"
+ + " Registered LOHS callers will be updated when softap stopped.");
+ }
- return stopSoftApInternal();
+ return stopSoftApInternal();
+ }
}
/**
@@ -981,11 +997,6 @@ public class WifiServiceImpl extends IWifiManager.Stub {
private boolean stopSoftApInternal() {
mLog.trace("stopSoftApInternal uid=%").c(Binder.getCallingUid()).flush();
- // we have an allowed caller - clear local only hotspot if it was enabled
- synchronized (mLocalOnlyHotspotRequests) {
- mLocalOnlyHotspotRequests.clear();
- mLocalOnlyHotspotConfig = null;
- }
mWifiController.sendMessage(CMD_SET_AP, 0, 0);
return true;
}
@@ -993,10 +1004,12 @@ public class WifiServiceImpl extends IWifiManager.Stub {
/**
* Private method to handle SoftAp state changes
*/
- private void handleWifiApStateChange(int currentState, int previousState, int errorCode) {
+ private void handleWifiApStateChange(
+ int currentState, int previousState, int errorCode, String ifaceName, int mode) {
// The AP state update from WifiStateMachine for softap
Slog.d(TAG, "handleWifiApStateChange: currentState=" + currentState
- + " previousState=" + previousState + " errorCode= " + errorCode);
+ + " previousState=" + previousState + " errorCode= " + errorCode
+ + " ifaceName=" + ifaceName + " mode=" + mode);
// check if we have a failure - since it is possible (worst case scenario where
// WifiController and WifiStateMachine are out of sync wrt modes) to get two FAILED
@@ -1050,6 +1063,7 @@ public class WifiServiceImpl extends IWifiManager.Stub {
for (LocalOnlyHotspotRequestInfo requestor : mLocalOnlyHotspotRequests.values()) {
try {
requestor.sendHotspotFailedMessage(arg1);
+ requestor.unlinkDeathRecipient();
} catch (RemoteException e) {
// This will be cleaned up by binder death handling
}
@@ -1069,6 +1083,7 @@ public class WifiServiceImpl extends IWifiManager.Stub {
for (LocalOnlyHotspotRequestInfo requestor : mLocalOnlyHotspotRequests.values()) {
try {
requestor.sendHotspotStoppedMessage();
+ requestor.unlinkDeathRecipient();
} catch (RemoteException e) {
// This will be cleaned up by binder death handling
}
@@ -1144,6 +1159,16 @@ public class WifiServiceImpl extends IWifiManager.Stub {
return LocalOnlyHotspotCallback.ERROR_TETHERING_DISALLOWED;
}
+ // the app should be in the foreground
+ try {
+ if (!mFrameworkFacade.isAppForeground(uid)) {
+ return LocalOnlyHotspotCallback.ERROR_INCOMPATIBLE_MODE;
+ }
+ } catch (RemoteException e) {
+ mLog.trace("RemoteException during isAppForeground when calling startLOHS");
+ return LocalOnlyHotspotCallback.ERROR_INCOMPATIBLE_MODE;
+ }
+
mLog.trace("startLocalOnlyHotspot uid=% pid=%").c(uid).c(pid).flush();
synchronized (mLocalOnlyHotspotRequests) {
@@ -1179,7 +1204,7 @@ public class WifiServiceImpl extends IWifiManager.Stub {
// this is the first request, then set up our config and start LOHS
mLocalOnlyHotspotConfig =
WifiApConfigStore.generateLocalOnlyHotspotConfig(mContext);
- startSoftApInternal(mLocalOnlyHotspotConfig, STATE_LOCAL_ONLY);
+ startSoftApInternal(mLocalOnlyHotspotConfig, WifiManager.IFACE_IP_MODE_LOCAL_ONLY);
}
mLocalOnlyHotspotRequests.put(pid, request);
@@ -2383,8 +2408,9 @@ public class WifiServiceImpl extends IWifiManager.Stub {
}
if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING)) {
- // Turn mobile hotspot off
- setWifiApEnabled(null, false);
+ // Turn mobile hotspot off - will also clear any registered LOHS requests when it is
+ // shut down
+ stopSoftApInternal();
}
if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_WIFI)) {
@@ -2495,8 +2521,7 @@ public class WifiServiceImpl extends IWifiManager.Stub {
*/
@Override
public byte[] retrieveBackupData() {
- enforceReadCredentialPermission();
- enforceAccessPermission();
+ enforceNetworkSettingsPermission();
mLog.trace("retrieveBackupData uid=%").c(Binder.getCallingUid()).flush();
if (mWifiStateMachineChannel == null) {
Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
@@ -2541,7 +2566,7 @@ public class WifiServiceImpl extends IWifiManager.Stub {
*/
@Override
public void restoreBackupData(byte[] data) {
- enforceChangePermission();
+ enforceNetworkSettingsPermission();
mLog.trace("restoreBackupData uid=%").c(Binder.getCallingUid()).flush();
if (mWifiStateMachineChannel == null) {
Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
@@ -2563,7 +2588,7 @@ public class WifiServiceImpl extends IWifiManager.Stub {
* @param ipConfigData Raw byte stream of ipconfig.txt
*/
public void restoreSupplicantBackupData(byte[] supplicantData, byte[] ipConfigData) {
- enforceChangePermission();
+ enforceNetworkSettingsPermission();
mLog.trace("restoreSupplicantBackupData uid=%").c(Binder.getCallingUid()).flush();
if (mWifiStateMachineChannel == null) {
Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java
index 7f57316a6..19c4812b0 100644
--- a/service/java/com/android/server/wifi/WifiStateMachine.java
+++ b/service/java/com/android/server/wifi/WifiStateMachine.java
@@ -1607,7 +1607,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss
/**
* TODO: doc
*/
- public void setHostApRunning(WifiConfiguration wifiConfig, boolean enable) {
+ public void setHostApRunning(SoftApModeConfiguration wifiConfig, boolean enable) {
if (enable) {
sendMessage(CMD_START_AP, wifiConfig);
} else {
@@ -2806,7 +2806,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss
mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
}
- private void setWifiApState(int wifiApState, int reason) {
+ private void setWifiApState(int wifiApState, int reason, String ifaceName, int mode) {
final int previousWifiApState = mWifiApState.get();
try {
@@ -2833,6 +2833,12 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss
intent.putExtra(WifiManager.EXTRA_WIFI_AP_FAILURE_REASON, reason);
}
+ if (ifaceName == null) {
+ loge("Updating wifiApState with a null iface name");
+ }
+ intent.putExtra(WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME, ifaceName);
+ intent.putExtra(WifiManager.EXTRA_WIFI_AP_MODE, mode);
+
mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
}
@@ -4277,7 +4283,8 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss
case CMD_START_AP:
/* Cannot start soft AP while in client mode */
loge("Failed to start soft AP with a running supplicant");
- setWifiApState(WIFI_AP_STATE_FAILED, WifiManager.SAP_START_FAILURE_GENERAL);
+ setWifiApState(WIFI_AP_STATE_FAILED, WifiManager.SAP_START_FAILURE_GENERAL,
+ null, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
break;
case CMD_SET_OPERATIONAL_MODE:
mOperationalMode = message.arg1;
@@ -6667,6 +6674,8 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss
class SoftApState extends State {
private SoftApManager mSoftApManager;
+ private String mIfaceName;
+ private int mMode;
private class SoftApListener implements SoftApManager.Listener {
@Override
@@ -6677,7 +6686,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss
sendMessage(CMD_START_AP_FAILURE);
}
- setWifiApState(state, reason);
+ setWifiApState(state, reason, mIfaceName, mMode);
}
}
@@ -6687,11 +6696,13 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss
if (message.what != CMD_START_AP) {
throw new RuntimeException("Illegal transition to SoftApState: " + message);
}
+ SoftApModeConfiguration config = (SoftApModeConfiguration) message.obj;
+ mMode = config.getTargetMode();
IApInterface apInterface = mWifiNative.setupForSoftApMode();
if (apInterface == null) {
setWifiApState(WIFI_AP_STATE_FAILED,
- WifiManager.SAP_START_FAILURE_GENERAL);
+ WifiManager.SAP_START_FAILURE_GENERAL, null, mMode);
/**
* Transition to InitialState to reset the
* driver/HAL back to the initial state.
@@ -6700,13 +6711,19 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss
return;
}
- WifiConfiguration config = (WifiConfiguration) message.obj;
+ try {
+ mIfaceName = apInterface.getInterfaceName();
+ } catch (RemoteException e) {
+ // Failed to get the interface name. The name will not be available for
+ // the enabled broadcast, but since we had an error getting the name, we most likely
+ // won't be able to fully start softap mode.
+ }
checkAndSetConnectivityInstance();
mSoftApManager = mWifiInjector.makeSoftApManager(mNwService,
new SoftApListener(),
apInterface,
- config);
+ config.getWifiConfiguration());
mSoftApManager.start();
mWifiStateTracker.updateState(WifiStateTracker.SOFT_AP);
}
@@ -6714,6 +6731,8 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss
@Override
public void exit() {
mSoftApManager = null;
+ mIfaceName = null;
+ mMode = WifiManager.IFACE_IP_MODE_UNSPECIFIED;
}
@Override
diff --git a/service/java/com/android/server/wifi/WifiVendorHal.java b/service/java/com/android/server/wifi/WifiVendorHal.java
index 9c1ae94b5..88f189814 100644
--- a/service/java/com/android/server/wifi/WifiVendorHal.java
+++ b/service/java/com/android/server/wifi/WifiVendorHal.java
@@ -64,6 +64,7 @@ import android.net.wifi.WifiManager;
import android.net.wifi.WifiScanner;
import android.net.wifi.WifiSsid;
import android.net.wifi.WifiWakeReasonAndCounts;
+import android.os.Handler;
import android.os.Looper;
import android.os.RemoteException;
import android.util.MutableBoolean;
@@ -204,16 +205,23 @@ public class WifiVendorHal {
private IWifiRttController mIWifiRttController;
private final HalDeviceManager mHalDeviceManager;
private final HalDeviceManagerStatusListener mHalDeviceManagerStatusCallbacks;
- private final Looper mLooper;
private final IWifiStaIfaceEventCallback mIWifiStaIfaceEventCallback;
private final IWifiChipEventCallback mIWifiChipEventCallback;
private final RttEventCallback mRttEventCallback;
+ // Plumbing for event handling.
+ //
+ // Being final fields, they can be accessed without synchronization under
+ // some reasonable assumptions. See
+ // https://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.5
+ private final Looper mLooper;
+ private final Handler mHalEventHandler;
public WifiVendorHal(HalDeviceManager halDeviceManager,
Looper looper) {
mHalDeviceManager = halDeviceManager;
mLooper = looper;
+ mHalEventHandler = new Handler(looper);
mHalDeviceManagerStatusCallbacks = new HalDeviceManagerStatusListener();
mIWifiStaIfaceEventCallback = new StaIfaceEventCallback();
mIWifiChipEventCallback = new ChipEventCallback();
@@ -2455,25 +2463,47 @@ public class WifiVendorHal {
WifiDebugRingBufferStatus status, java.util.ArrayList<Byte> data) {
//TODO(b/35875078) Reinstate logging when execessive callbacks are fixed
// mVerboseLog.d("onDebugRingBufferDataAvailable " + status);
- WifiNative.WifiLoggerEventHandler eventHandler;
- synchronized (sLock) {
- if (mLogEventHandler == null || status == null || data == null) return;
- eventHandler = mLogEventHandler;
- }
- eventHandler.onRingBufferData(
- ringBufferStatus(status), NativeUtil.byteArrayFromArrayList(data));
+ mHalEventHandler.post(() -> {
+ WifiNative.WifiLoggerEventHandler eventHandler;
+ synchronized (sLock) {
+ if (mLogEventHandler == null || status == null || data == null) return;
+ eventHandler = mLogEventHandler;
+ }
+ // Because |sLock| has been released, there is a chance that we'll execute
+ // a spurious callback (after someone has called resetLogHandler()).
+ //
+ // However, the alternative risks deadlock. Consider:
+ // [T1.1] WifiDiagnostics.captureBugReport()
+ // [T1.2] -- acquire WifiDiagnostics object's intrinsic lock
+ // [T1.3] -> WifiVendorHal.getRingBufferData()
+ // [T1.4] -- acquire WifiVendorHal.sLock
+ // [T2.1] <lambda>()
+ // [T2.2] -- acquire WifiVendorHal.sLock
+ // [T2.3] -> WifiDiagnostics.onRingBufferData()
+ // [T2.4] -- acquire WifiDiagnostics object's intrinsic lock
+ //
+ // The problem here is that the two threads acquire the locks in opposite order.
+ // If, for example, T2.2 executes between T1.2 and 1.4, then T1 and T2
+ // will be deadlocked.
+ eventHandler.onRingBufferData(
+ ringBufferStatus(status), NativeUtil.byteArrayFromArrayList(data));
+ });
}
@Override
public void onDebugErrorAlert(int errorCode, java.util.ArrayList<Byte> debugData) {
mVerboseLog.d("onDebugErrorAlert " + errorCode);
- WifiNative.WifiLoggerEventHandler eventHandler;
- synchronized (sLock) {
- if (mLogEventHandler == null || debugData == null) return;
- eventHandler = mLogEventHandler;
- }
- eventHandler.onWifiAlert(
- errorCode, NativeUtil.byteArrayFromArrayList(debugData));
+ mHalEventHandler.post(() -> {
+ WifiNative.WifiLoggerEventHandler eventHandler;
+ synchronized (sLock) {
+ if (mLogEventHandler == null || debugData == null) return;
+ eventHandler = mLogEventHandler;
+ }
+ // See comment in onDebugRingBufferDataAvailable(), for an explanation
+ // of why this callback is invoked without |sLock| held.
+ eventHandler.onWifiAlert(
+ errorCode, NativeUtil.byteArrayFromArrayList(debugData));
+ });
}
}
diff --git a/service/java/com/android/server/wifi/p2p/WifiP2pMonitor.java b/service/java/com/android/server/wifi/p2p/WifiP2pMonitor.java
index 0411f3073..e14c10c91 100644
--- a/service/java/com/android/server/wifi/p2p/WifiP2pMonitor.java
+++ b/service/java/com/android/server/wifi/p2p/WifiP2pMonitor.java
@@ -158,9 +158,9 @@ public class WifiP2pMonitor {
if (mConnected) {
return true;
}
- if (connectTries++ < 5) {
+ if (connectTries++ < 50) {
try {
- Thread.sleep(1000);
+ Thread.sleep(100);
} catch (InterruptedException ignore) {
}
} else {
diff --git a/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java b/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java
index 771e336d5..08c9e1359 100644
--- a/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java
+++ b/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java
@@ -447,7 +447,6 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
private RequestList<ScanSettings> mActiveScans = new RequestList<>();
private RequestList<ScanSettings> mPendingScans = new RequestList<>();
- // Scan results cached from the last full single scan request.
private ScanResult[] mCachedScanResults = new ScanResult[0];
WifiSingleScanStateMachine(Looper looper) {
@@ -880,11 +879,8 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
entry.reportEvent(WifiScanner.CMD_SCAN_RESULT, 0, parcelableAllResults);
}
- // Since we use NoBandChannelHelper, as long as a specific band is mentioned, the scan
- // request is treated as full band (WifiScanner.WIFI_BAND_*).
- if (results.isAllChannelsScanned()) {
- mCachedScanResults = results.getResults();
- }
+ // Cache the results here so that apps can retrieve them.
+ mCachedScanResults = results.getResults();
sendScanResultBroadcast(true);
}
diff --git a/service/java/com/android/server/wifi/scanner/WificondScannerImpl.java b/service/java/com/android/server/wifi/scanner/WificondScannerImpl.java
index b088cc01d..4aa9bc972 100644
--- a/service/java/com/android/server/wifi/scanner/WificondScannerImpl.java
+++ b/service/java/com/android/server/wifi/scanner/WificondScannerImpl.java
@@ -563,6 +563,16 @@ public class WificondScannerImpl extends WifiScannerImpl implements Handler.Call
}
mLastScanSettings.pnoScanEventHandler.onPnoNetworkFound(pnoScanResultsArray);
}
+ // On pno scan result event, we are expecting a mLastScanSettings for pno scan.
+ // However, if unlikey mLastScanSettings is for single scan, we need this part
+ // to protect from leaving WifiSingleScanStateMachine in a forever wait state.
+ if (mLastScanSettings.singleScanActive
+ && mLastScanSettings.singleScanEventHandler != null) {
+ Log.w(TAG, "Polling pno scan result when single scan is active, reporting"
+ + " single scan failure");
+ mLastScanSettings.singleScanEventHandler
+ .onScanStatus(WifiNative.WIFI_SCAN_FAILED);
+ }
// mLastScanSettings is for either single/batched scan or pno scan.
// We can safely set it to null when pno scan finishes.
mLastScanSettings = null;
diff --git a/tests/wifitests/src/com/android/server/wifi/SavedNetworkEvaluatorTest.java b/tests/wifitests/src/com/android/server/wifi/SavedNetworkEvaluatorTest.java
index 78a3a3d0f..7f6360408 100644
--- a/tests/wifitests/src/com/android/server/wifi/SavedNetworkEvaluatorTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/SavedNetworkEvaluatorTest.java
@@ -172,6 +172,33 @@ public class SavedNetworkEvaluatorTest {
}
/**
+ * Do not evaluate networks that {@link WifiConfiguration#isEphemeral}.
+ */
+ @Test
+ public void ignoreEphemeralNetworks() {
+ String[] ssids = {"\"test1\"", "\"test2\""};
+ String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
+ int[] freqs = {2470, 2437};
+ String[] caps = {"[ESS]", "[ESS]"};
+ int[] levels = {mThresholdQualifiedRssi2G + 8, mThresholdQualifiedRssi2G + 10};
+ int[] securities = {SECURITY_NONE, SECURITY_NONE};
+
+ ScanDetailsAndWifiConfigs scanDetailsAndConfigs =
+ WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids,
+ freqs, caps, levels, securities, mWifiConfigManager, mClock);
+ List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails();
+ WifiConfiguration[] savedConfigs = scanDetailsAndConfigs.getWifiConfigs();
+ for (WifiConfiguration wifiConfiguration : savedConfigs) {
+ wifiConfiguration.ephemeral = true;
+ }
+
+ WifiConfiguration candidate = mSavedNetworkEvaluator.evaluateNetworks(scanDetails,
+ null, null, true, false, null);
+
+ assertNull(candidate);
+ }
+
+ /**
* Set the candidate {@link ScanResult} for all {@link WifiConfiguration}s regardless of
* whether they are secure saved, open saved, or {@link WifiConfiguration#useExternalScores}.
*/
diff --git a/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalTest.java b/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalTest.java
index ef393f364..2deef52e4 100644
--- a/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalTest.java
@@ -457,13 +457,35 @@ public class SupplicantStaIfaceHalTest {
executeAndValidateConnectSequence(0, false);
}
- /**
- * Tests connection to a specified network with single existing network.
- */
@Test
- public void testConnectWithSingleExistingNetwork() throws Exception {
+ public void testConnectToNetworkWithDifferentConfigReplacesNetworkInSupplicant()
+ throws Exception {
executeAndValidateInitializationSequence();
- executeAndValidateConnectSequence(0, true);
+ WifiConfiguration config = executeAndValidateConnectSequence(
+ SUPPLICANT_NETWORK_ID, false);
+ // Reset mocks for mISupplicantStaIfaceMock because we finished the first connection.
+ reset(mISupplicantStaIfaceMock);
+ setupMocksForConnectSequence(true /*haveExistingNetwork*/);
+ // Make this network different by changing SSID.
+ config.SSID = "AnDifferentSSID";
+ assertTrue(mDut.connectToNetwork(config));
+ verify(mISupplicantStaIfaceMock).removeNetwork(SUPPLICANT_NETWORK_ID);
+ verify(mISupplicantStaIfaceMock)
+ .addNetwork(any(ISupplicantStaIface.addNetworkCallback.class));
+ }
+
+ @Test
+ public void connectToNetworkWithSameNetworkDoesNotRemoveNetworkFromSupplicant()
+ throws Exception {
+ executeAndValidateInitializationSequence();
+ WifiConfiguration config = executeAndValidateConnectSequence(SUPPLICANT_NETWORK_ID, false);
+ // Reset mocks for mISupplicantStaIfaceMock because we finished the first connection.
+ reset(mISupplicantStaIfaceMock);
+ setupMocksForConnectSequence(true /*haveExistingNetwork*/);
+ assertTrue(mDut.connectToNetwork(config));
+ verify(mISupplicantStaIfaceMock, never()).removeNetwork(anyInt());
+ verify(mISupplicantStaIfaceMock, never())
+ .addNetwork(any(ISupplicantStaIface.addNetworkCallback.class));
}
/**
@@ -481,7 +503,7 @@ public class SupplicantStaIfaceHalTest {
}).when(mISupplicantStaIfaceMock).addNetwork(
any(ISupplicantStaIface.addNetworkCallback.class));
- assertFalse(mDut.connectToNetwork(new WifiConfiguration()));
+ assertFalse(mDut.connectToNetwork(createTestWifiConfiguration()));
}
/**
@@ -495,7 +517,7 @@ public class SupplicantStaIfaceHalTest {
when(mSupplicantStaNetworkMock.saveWifiConfiguration(any(WifiConfiguration.class)))
.thenReturn(false);
- assertFalse(mDut.connectToNetwork(new WifiConfiguration()));
+ assertFalse(mDut.connectToNetwork(createTestWifiConfiguration()));
// We should have removed the existing network once before connection and once more
// on failure to save network configuration.
verify(mISupplicantStaIfaceMock, times(2)).removeNetwork(anyInt());
@@ -513,7 +535,7 @@ public class SupplicantStaIfaceHalTest {
.when(mSupplicantStaNetworkMock).saveWifiConfiguration(
any(WifiConfiguration.class));
- assertFalse(mDut.connectToNetwork(new WifiConfiguration()));
+ assertFalse(mDut.connectToNetwork(createTestWifiConfiguration()));
// We should have removed the existing network once before connection and once more
// on failure to save network configuration.
verify(mISupplicantStaIfaceMock, times(2)).removeNetwork(anyInt());
@@ -529,7 +551,7 @@ public class SupplicantStaIfaceHalTest {
when(mSupplicantStaNetworkMock.select()).thenReturn(false);
- assertFalse(mDut.connectToNetwork(new WifiConfiguration()));
+ assertFalse(mDut.connectToNetwork(createTestWifiConfiguration()));
}
/**
@@ -539,6 +561,7 @@ public class SupplicantStaIfaceHalTest {
public void testRoamToSameNetwork() throws Exception {
executeAndValidateInitializationSequence();
executeAndValidateRoamSequence(true);
+ assertTrue(mDut.connectToNetwork(createTestWifiConfiguration()));
}
/**
@@ -1282,6 +1305,12 @@ public class SupplicantStaIfaceHalTest {
verify(mISupplicantStaIfaceMock).startWpsPbc(eq(anyBssidBytes));
}
+ private WifiConfiguration createTestWifiConfiguration() {
+ WifiConfiguration config = new WifiConfiguration();
+ config.networkId = SUPPLICANT_NETWORK_ID;
+ return config;
+ }
+
private void executeAndValidateHs20DeauthImminentCallback(boolean isEss) throws Exception {
executeAndValidateInitializationSequence();
assertNotNull(mISupplicantStaIfaceCallback);
@@ -1493,14 +1522,16 @@ public class SupplicantStaIfaceHalTest {
*
* @param newFrameworkNetworkId Framework Network Id of the new network to connect.
* @param haveExistingNetwork Removes the existing network.
+ * @return the WifiConfiguration object of the new network to connect.
*/
- private void executeAndValidateConnectSequence(
+ private WifiConfiguration executeAndValidateConnectSequence(
final int newFrameworkNetworkId, final boolean haveExistingNetwork) throws Exception {
setupMocksForConnectSequence(haveExistingNetwork);
WifiConfiguration config = new WifiConfiguration();
config.networkId = newFrameworkNetworkId;
assertTrue(mDut.connectToNetwork(config));
validateConnectSequence(haveExistingNetwork, 1);
+ return config;
}
/**
diff --git a/tests/wifitests/src/com/android/server/wifi/TestUtil.java b/tests/wifitests/src/com/android/server/wifi/TestUtil.java
index 90df07a61..a0a103026 100644
--- a/tests/wifitests/src/com/android/server/wifi/TestUtil.java
+++ b/tests/wifitests/src/com/android/server/wifi/TestUtil.java
@@ -74,14 +74,18 @@ public class TestUtil {
* Send {@link WifiManager#WIFI_AP_STATE_CHANGED} broadcast.
*/
public static void sendWifiApStateChanged(BroadcastReceiver broadcastReceiver,
- Context context, int apState, int previousState, int error) {
+ Context context, int apState, int previousState, int error, String ifaceName,
+ int mode) {
Intent intent = new Intent(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
intent.putExtra(WifiManager.EXTRA_WIFI_AP_STATE, apState);
intent.putExtra(WifiManager.EXTRA_PREVIOUS_WIFI_AP_STATE, previousState);
if (apState == WifiManager.WIFI_AP_STATE_FAILED) {
- //only set reason number when softAP start failed
+ // only set reason number when softAP start failed
intent.putExtra(WifiManager.EXTRA_WIFI_AP_FAILURE_REASON, error);
}
+ intent.putExtra(WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME, ifaceName);
+ intent.putExtra(WifiManager.EXTRA_WIFI_AP_MODE, mode);
+
broadcastReceiver.onReceive(context, intent);
}
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java b/tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java
index d4a3ff549..2d3b06695 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java
@@ -202,5 +202,7 @@ public class WifiApConfigStoreTest {
public void generateLocalOnlyHotspotConfigIsValid() {
WifiConfiguration config = WifiApConfigStore.generateLocalOnlyHotspotConfig(mContext);
verifyDefaultApConfig(config, TEST_DEFAULT_HOTSPOT_SSID);
+ // The LOHS config should also have a specific network id set - check that as well.
+ assertEquals(WifiConfiguration.LOCAL_ONLY_NETWORK_ID, config.networkId);
}
}
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiBackupRestoreTest.java b/tests/wifitests/src/com/android/server/wifi/WifiBackupRestoreTest.java
index 362540517..58b8d394b 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiBackupRestoreTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiBackupRestoreTest.java
@@ -24,10 +24,13 @@ import android.os.Process;
import android.test.suitebuilder.annotation.SmallTest;
import com.android.server.net.IpConfigStore;
+import com.android.server.wifi.util.WifiPermissionsUtil;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
@@ -48,11 +51,15 @@ import java.util.Random;
@SmallTest
public class WifiBackupRestoreTest {
- private final WifiBackupRestore mWifiBackupRestore = new WifiBackupRestore();
+ @Mock WifiPermissionsUtil mWifiPermissionsUtil;
+ private WifiBackupRestore mWifiBackupRestore;
private boolean mCheckDump = true;
@Before
public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(true);
+ mWifiBackupRestore = new WifiBackupRestore(mWifiPermissionsUtil);
// Enable verbose logging before tests to check the backup data dumps.
mWifiBackupRestore.enableVerboseLogging(1);
}
@@ -361,25 +368,34 @@ public class WifiBackupRestoreTest {
*/
@Test
public void testMultipleNetworksSystemAppBackupRestore() {
+ int systemAppUid = Process.SYSTEM_UID;
+ int nonSystemAppUid = Process.FIRST_APPLICATION_UID + 556;
+ when(mWifiPermissionsUtil.checkConfigOverridePermission(eq(systemAppUid)))
+ .thenReturn(true);
+ when(mWifiPermissionsUtil.checkConfigOverridePermission(eq(nonSystemAppUid)))
+ .thenReturn(false);
+
List<WifiConfiguration> configurations = new ArrayList<>();
List<WifiConfiguration> expectedConfigurations = new ArrayList<>();
WifiConfiguration wepNetwork = WifiConfigurationTestUtil.createWepNetwork();
+ wepNetwork.creatorUid = systemAppUid;
configurations.add(wepNetwork);
expectedConfigurations.add(wepNetwork);
// These should not be in |expectedConfigurations|.
WifiConfiguration nonSystemAppWepNetwork = WifiConfigurationTestUtil.createWepNetwork();
- nonSystemAppWepNetwork.creatorUid = Process.FIRST_APPLICATION_UID;
+ nonSystemAppWepNetwork.creatorUid = nonSystemAppUid;
configurations.add(nonSystemAppWepNetwork);
WifiConfiguration pskNetwork = WifiConfigurationTestUtil.createPskNetwork();
+ pskNetwork.creatorUid = systemAppUid;
configurations.add(pskNetwork);
expectedConfigurations.add(pskNetwork);
// These should not be in |expectedConfigurations|.
WifiConfiguration nonSystemAppPskNetwork = WifiConfigurationTestUtil.createPskNetwork();
- nonSystemAppPskNetwork.creatorUid = Process.FIRST_APPLICATION_UID + 1;
+ nonSystemAppPskNetwork.creatorUid = nonSystemAppUid;
configurations.add(nonSystemAppPskNetwork);
WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
index f61013841..e85686fa7 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
@@ -247,6 +247,8 @@ public class WifiConfigManagerTest {
networks.add(openNetwork);
verifyAddNetworkToWifiConfigManager(openNetwork);
+ verify(mWcmListener).onSavedNetworkAdded(openNetwork.networkId);
+ reset(mWcmListener);
// Now change BSSID for the network.
assertAndSetNetworkBSSID(openNetwork, TEST_BSSID);
@@ -257,7 +259,7 @@ public class WifiConfigManagerTest {
mWifiConfigManager.getConfiguredNetworksWithPasswords();
WifiConfigurationTestUtil.assertConfigurationsEqualForConfigManagerAddOrUpdate(
networks, retrievedNetworks);
- verify(mWcmListener, times(2)).onSavedNetworkUpdate();
+ verify(mWcmListener).onSavedNetworkUpdated(openNetwork.networkId);
}
/**
@@ -281,7 +283,7 @@ public class WifiConfigManagerTest {
// Ensure that this is not returned in the saved network list.
assertTrue(mWifiConfigManager.getSavedNetworks().isEmpty());
- verify(mWcmListener, never()).onSavedNetworkUpdate();
+ verify(mWcmListener, never()).onSavedNetworkAdded(ephemeralNetwork.networkId);
}
/**
@@ -453,13 +455,16 @@ public class WifiConfigManagerTest {
WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
verifyAddNetworkToWifiConfigManager(openNetwork);
+ verify(mWcmListener).onSavedNetworkAdded(openNetwork.networkId);
+ reset(mWcmListener);
+
// Ensure that configured network list is not empty.
assertFalse(mWifiConfigManager.getConfiguredNetworks().isEmpty());
verifyRemoveNetworkFromWifiConfigManager(openNetwork);
// Ensure that configured network list is empty now.
assertTrue(mWifiConfigManager.getConfiguredNetworks().isEmpty());
- verify(mWcmListener, times(2)).onSavedNetworkUpdate();
+ verify(mWcmListener).onSavedNetworkRemoved(openNetwork.networkId);
}
/**
@@ -474,11 +479,12 @@ public class WifiConfigManagerTest {
verifyAddEphemeralNetworkToWifiConfigManager(ephemeralNetwork);
// Ensure that configured network list is not empty.
assertFalse(mWifiConfigManager.getConfiguredNetworks().isEmpty());
+ verify(mWcmListener, never()).onSavedNetworkAdded(ephemeralNetwork.networkId);
verifyRemoveEphemeralNetworkFromWifiConfigManager(ephemeralNetwork);
// Ensure that configured network list is empty now.
assertTrue(mWifiConfigManager.getConfiguredNetworks().isEmpty());
- verify(mWcmListener, never()).onSavedNetworkUpdate();
+ verify(mWcmListener, never()).onSavedNetworkRemoved(ephemeralNetwork.networkId);
}
/**
@@ -492,11 +498,12 @@ public class WifiConfigManagerTest {
verifyAddPasspointNetworkToWifiConfigManager(passpointNetwork);
// Ensure that configured network list is not empty.
assertFalse(mWifiConfigManager.getConfiguredNetworks().isEmpty());
+ verify(mWcmListener, never()).onSavedNetworkAdded(passpointNetwork.networkId);
verifyRemovePasspointNetworkFromWifiConfigManager(passpointNetwork);
// Ensure that configured network list is empty now.
assertTrue(mWifiConfigManager.getConfiguredNetworks().isEmpty());
- verify(mWcmListener, never()).onSavedNetworkUpdate();
+ verify(mWcmListener, never()).onSavedNetworkRemoved(passpointNetwork.networkId);
}
/**
@@ -588,9 +595,10 @@ public class WifiConfigManagerTest {
NetworkUpdateResult result = verifyAddNetworkToWifiConfigManager(openNetwork);
+ int networkId = result.getNetworkId();
// First set it to enabled.
verifyUpdateNetworkSelectionStatus(
- result.getNetworkId(), NetworkSelectionStatus.NETWORK_SELECTION_ENABLE, 0);
+ networkId, NetworkSelectionStatus.NETWORK_SELECTION_ENABLE, 0);
// Now set it to temporarily disabled. The threshold for association rejection is 5, so
// disable it 5 times to actually mark it temporarily disabled.
@@ -600,16 +608,17 @@ public class WifiConfigManagerTest {
for (int i = 1; i <= assocRejectThreshold; i++) {
verifyUpdateNetworkSelectionStatus(result.getNetworkId(), assocRejectReason, i);
}
+ verify(mWcmListener).onSavedNetworkTemporarilyDisabled(networkId);
// Now set it to permanently disabled.
verifyUpdateNetworkSelectionStatus(
result.getNetworkId(), NetworkSelectionStatus.DISABLED_BY_WIFI_MANAGER, 0);
- verify(mWcmListener, times(3)).onSavedNetworkUpdate();
+ verify(mWcmListener).onSavedNetworkPermanentlyDisabled(networkId);
// Now set it back to enabled.
verifyUpdateNetworkSelectionStatus(
result.getNetworkId(), NetworkSelectionStatus.NETWORK_SELECTION_ENABLE, 0);
- verify(mWcmListener, times(4)).onSavedNetworkUpdate();
+ verify(mWcmListener, times(2)).onSavedNetworkEnabled(networkId);
}
/**
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConfigurationTestUtil.java b/tests/wifitests/src/com/android/server/wifi/WifiConfigurationTestUtil.java
index 917a64cc9..b53732a91 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiConfigurationTestUtil.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiConfigurationTestUtil.java
@@ -241,6 +241,15 @@ public class WifiConfigurationTestUtil {
return configuration;
}
+ public static WifiConfiguration createPskNetwork(String ssid) {
+ WifiConfiguration configuration =
+ generateWifiConfig(TEST_NETWORK_ID, TEST_UID, ssid, true, true, null,
+ null, SECURITY_PSK);
+ configuration.preSharedKey = TEST_PSK;
+ return configuration;
+ }
+
+
public static WifiConfiguration createPskHiddenNetwork() {
WifiConfiguration configuration = createPskNetwork();
configuration.hiddenSSID = true;
@@ -280,6 +289,14 @@ public class WifiConfigurationTestUtil {
return configuration;
}
+ public static WifiConfiguration createEapNetwork(String ssid) {
+ WifiConfiguration configuration =
+ generateWifiConfig(TEST_NETWORK_ID, TEST_UID, ssid, true, true,
+ null, null, SECURITY_EAP);
+ return configuration;
+ }
+
+
public static WifiConfiguration createEapNetwork(int eapMethod, int phase2Method) {
WifiConfiguration configuration =
generateWifiConfig(TEST_NETWORK_ID, TEST_UID, createNewSSID(), true, true,
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConfigurationUtilTest.java b/tests/wifitests/src/com/android/server/wifi/WifiConfigurationUtilTest.java
index 1b4a16d1c..506db9150 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiConfigurationUtilTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiConfigurationUtilTest.java
@@ -41,6 +41,8 @@ public class WifiConfigurationUtilTest {
static final int CURRENT_USER_ID = 0;
static final int CURRENT_USER_MANAGED_PROFILE_USER_ID = 10;
static final int OTHER_USER_ID = 11;
+ static final String TEST_SSID = "test_ssid";
+ static final String TEST_SSID_1 = "test_ssid_1";
static final List<UserInfo> PROFILES = Arrays.asList(
new UserInfo(CURRENT_USER_ID, "owner", 0),
new UserInfo(CURRENT_USER_MANAGED_PROFILE_USER_ID, "managed profile", 0));
@@ -239,6 +241,40 @@ public class WifiConfigurationUtilTest {
}
/**
+ * Verify that WifiConfigurationUtil.isSameNetwork returns true when two WifiConfiguration
+ * objects have the same parameters.
+ */
+ @Test
+ public void testIsSameNetworkReturnsTrueOnSameNetwork() {
+ WifiConfiguration network = WifiConfigurationTestUtil.createPskNetwork(TEST_SSID);
+ WifiConfiguration network1 = WifiConfigurationTestUtil.createPskNetwork(TEST_SSID);
+ assertTrue(WifiConfigurationUtil.isSameNetwork(network, network1));
+ }
+
+ /**
+ * Verify that WifiConfigurationUtil.isSameNetwork returns false when two WifiConfiguration
+ * objects have the different SSIDs.
+ */
+ @Test
+ public void testIsSameNetworkReturnsFalseOnDifferentSSID() {
+ WifiConfiguration network = WifiConfigurationTestUtil.createPskNetwork(TEST_SSID);
+ WifiConfiguration network1 = WifiConfigurationTestUtil.createPskNetwork(TEST_SSID_1);
+ assertFalse(WifiConfigurationUtil.isSameNetwork(network, network1));
+ }
+
+ /**
+ * Verify that WifiConfigurationUtil.isSameNetwork returns false when two WifiConfiguration
+ * objects have the different security type.
+ */
+ @Test
+ public void testIsSameNetworkReturnsFalseOnDifferentSecurityType() {
+ WifiConfiguration network = WifiConfigurationTestUtil.createPskNetwork(TEST_SSID);
+ WifiConfiguration network1 = WifiConfigurationTestUtil.createEapNetwork(TEST_SSID);
+ assertFalse(WifiConfigurationUtil.isSameNetwork(network, network1));
+ }
+
+
+ /**
* Verify the instance of {@link android.net.wifi.WifiScanner.PnoSettings.PnoNetwork} created
* for a EAP network using {@link WifiConfigurationUtil#createPnoNetwork(WifiConfiguration, int)
* }.
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java b/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
index 7342cdb16..d5bfb2045 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
@@ -74,6 +74,7 @@ import android.os.Message;
import android.os.Messenger;
import android.os.PowerManager;
import android.os.Process;
+import android.os.RemoteException;
import android.os.UserManager;
import android.os.WorkSource;
import android.os.test.TestLooper;
@@ -97,6 +98,7 @@ import org.mockito.Spy;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.io.StringWriter;
+import java.util.List;
/**
* Unit tests for {@link WifiServiceImpl}.
@@ -132,6 +134,8 @@ public class WifiServiceImplTest {
ArgumentCaptor.forClass(IntentFilter.class);
final ArgumentCaptor<Message> mMessageCaptor = ArgumentCaptor.forClass(Message.class);
+ final ArgumentCaptor<SoftApModeConfiguration> mSoftApModeConfigCaptor =
+ ArgumentCaptor.forClass(SoftApModeConfiguration.class);
@Mock Context mContext;
@Mock WifiInjector mWifiInjector;
@@ -534,7 +538,9 @@ public class WifiServiceImplTest {
when(mUserManager.hasUserRestriction(eq(UserManager.DISALLOW_CONFIG_TETHERING)))
.thenReturn(false);
mWifiServiceImpl.setWifiApEnabled(null, true);
- verify(mWifiController).sendMessage(eq(CMD_SET_AP), eq(1), eq(0), eq(null));
+ verify(mWifiController)
+ .sendMessage(eq(CMD_SET_AP), eq(1), eq(0), mSoftApModeConfigCaptor.capture());
+ assertNull(mSoftApModeConfigCaptor.getValue().getWifiConfiguration());
}
/**
@@ -549,7 +555,9 @@ public class WifiServiceImplTest {
.thenReturn(false);
WifiConfiguration apConfig = new WifiConfiguration();
mWifiServiceImpl.setWifiApEnabled(apConfig, true);
- verify(mWifiController).sendMessage(eq(CMD_SET_AP), eq(1), eq(0), eq(apConfig));
+ verify(mWifiController).sendMessage(
+ eq(CMD_SET_AP), eq(1), eq(0), mSoftApModeConfigCaptor.capture());
+ assertEquals(apConfig, mSoftApModeConfigCaptor.getValue().getWifiConfiguration());
}
/**
@@ -562,7 +570,9 @@ public class WifiServiceImplTest {
when(mUserManager.hasUserRestriction(eq(UserManager.DISALLOW_CONFIG_TETHERING)))
.thenReturn(false);
mWifiServiceImpl.setWifiApEnabled(null, false);
- verify(mWifiController).sendMessage(eq(CMD_SET_AP), eq(0), eq(0), eq(null));
+ verify(mWifiController)
+ .sendMessage(eq(CMD_SET_AP), eq(0), eq(0), mSoftApModeConfigCaptor.capture());
+ assertNull(mSoftApModeConfigCaptor.getValue().getWifiConfiguration());
}
/**
@@ -576,7 +586,8 @@ public class WifiServiceImplTest {
// mApConfig is a mock and the values are not set - triggering the invalid config. Testing
// will be improved when we actually do test softap configs in b/37280779
mWifiServiceImpl.setWifiApEnabled(mApConfig, true);
- verify(mWifiController, never()).sendMessage(eq(CMD_SET_AP), eq(1), eq(0), eq(mApConfig));
+ verify(mWifiController, never())
+ .sendMessage(eq(CMD_SET_AP), eq(1), eq(0), any(SoftApModeConfiguration.class));
}
/**
@@ -613,7 +624,9 @@ public class WifiServiceImplTest {
public void testStartSoftApWithPermissionsAndNullConfig() {
boolean result = mWifiServiceImpl.startSoftAp(null);
assertTrue(result);
- verify(mWifiController).sendMessage(eq(CMD_SET_AP), eq(1), eq(0), eq(null));
+ verify(mWifiController)
+ .sendMessage(eq(CMD_SET_AP), eq(1), eq(0), mSoftApModeConfigCaptor.capture());
+ assertNull(mSoftApModeConfigCaptor.getValue().getWifiConfiguration());
}
/**
@@ -634,7 +647,9 @@ public class WifiServiceImplTest {
WifiConfiguration config = new WifiConfiguration();
boolean result = mWifiServiceImpl.startSoftAp(config);
assertTrue(result);
- verify(mWifiController).sendMessage(eq(CMD_SET_AP), eq(1), eq(0), eq(config));
+ verify(mWifiController)
+ .sendMessage(eq(CMD_SET_AP), eq(1), eq(0), mSoftApModeConfigCaptor.capture());
+ assertEquals(config, mSoftApModeConfigCaptor.getValue().getWifiConfiguration());
}
/**
@@ -747,6 +762,9 @@ public class WifiServiceImplTest {
// allow test to proceed without a permission check failure
when(mSettingsStore.getLocationModeSetting(mContext))
.thenReturn(LOCATION_MODE_HIGH_ACCURACY);
+ try {
+ when(mFrameworkFacade.isAppForeground(anyInt())).thenReturn(true);
+ } catch (RemoteException e) { }
when(mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING))
.thenReturn(false);
int result = mWifiServiceImpl.startLocalOnlyHotspot(mAppMessenger, mAppBinder,
@@ -799,12 +817,43 @@ public class WifiServiceImplTest {
}
/**
+ * Only start LocalOnlyHotspot if the caller is the foreground app at the time of the request.
+ */
+ @Test
+ public void testStartLocalOnlyHotspotFailsIfRequestorNotForegroundApp() throws Exception {
+ when(mSettingsStore.getLocationModeSetting(mContext))
+ .thenReturn(LOCATION_MODE_HIGH_ACCURACY);
+
+ when(mFrameworkFacade.isAppForeground(anyInt())).thenReturn(false);
+ int result = mWifiServiceImpl.startLocalOnlyHotspot(mAppMessenger, mAppBinder,
+ TEST_PACKAGE_NAME);
+ assertEquals(LocalOnlyHotspotCallback.ERROR_INCOMPATIBLE_MODE, result);
+ }
+
+ /**
+ * Do not register the LocalOnlyHotspot request if the caller app cannot be verified as the
+ * foreground app at the time of the request (ie, throws an exception in the check).
+ */
+ @Test
+ public void testStartLocalOnlyHotspotFailsIfForegroundAppCheckThrowsRemoteException()
+ throws Exception {
+ when(mSettingsStore.getLocationModeSetting(mContext))
+ .thenReturn(LOCATION_MODE_HIGH_ACCURACY);
+
+ when(mFrameworkFacade.isAppForeground(anyInt())).thenThrow(new RemoteException());
+ int result = mWifiServiceImpl.startLocalOnlyHotspot(mAppMessenger, mAppBinder,
+ TEST_PACKAGE_NAME);
+ assertEquals(LocalOnlyHotspotCallback.ERROR_INCOMPATIBLE_MODE, result);
+ }
+
+ /**
* Only start LocalOnlyHotspot if we are not tethering.
*/
@Test
- public void testHotspotDoesNotStartWhenAlreadyTethering() {
+ public void testHotspotDoesNotStartWhenAlreadyTethering() throws Exception {
when(mSettingsStore.getLocationModeSetting(mContext))
.thenReturn(LOCATION_MODE_HIGH_ACCURACY);
+ when(mFrameworkFacade.isAppForeground(anyInt())).thenReturn(true);
mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_TETHERED);
mLooper.dispatchAll();
int returnCode = mWifiServiceImpl.startLocalOnlyHotspot(
@@ -816,9 +865,10 @@ public class WifiServiceImplTest {
* Only start LocalOnlyHotspot if admin setting does not disallow tethering.
*/
@Test
- public void testHotspotDoesNotStartWhenTetheringDisallowed() {
+ public void testHotspotDoesNotStartWhenTetheringDisallowed() throws Exception {
when(mSettingsStore.getLocationModeSetting(mContext))
.thenReturn(LOCATION_MODE_HIGH_ACCURACY);
+ when(mFrameworkFacade.isAppForeground(anyInt())).thenReturn(true);
when(mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING))
.thenReturn(true);
int returnCode = mWifiServiceImpl.startLocalOnlyHotspot(
@@ -874,7 +924,7 @@ public class WifiServiceImplTest {
public void testStopLocalOnlyHotspotTriggersSoftApStopWithOneRegisteredRequest() {
registerLOHSRequestFull();
verify(mWifiController)
- .sendMessage(eq(CMD_SET_AP), eq(1), eq(0), any(WifiConfiguration.class));
+ .sendMessage(eq(CMD_SET_AP), eq(1), eq(0), any(SoftApModeConfiguration.class));
mWifiServiceImpl.stopLocalOnlyHotspot();
// there is was only one request registered, we should tear down softap
@@ -957,7 +1007,8 @@ public class WifiServiceImplTest {
registerLOHSRequestFull();
TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
- WIFI_AP_STATE_FAILED, WIFI_AP_STATE_DISABLED, SAP_START_FAILURE_GENERAL);
+ WIFI_AP_STATE_FAILED, WIFI_AP_STATE_DISABLED, SAP_START_FAILURE_GENERAL,
+ WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
mLooper.dispatchAll();
verify(mHandler).handleMessage(mMessageCaptor.capture());
Message message = mMessageCaptor.getValue();
@@ -981,7 +1032,8 @@ public class WifiServiceImplTest {
registerLOHSRequestFull();
TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
- WIFI_AP_STATE_FAILED, WIFI_AP_STATE_DISABLED, SAP_START_FAILURE_NO_CHANNEL);
+ WIFI_AP_STATE_FAILED, WIFI_AP_STATE_DISABLED, SAP_START_FAILURE_NO_CHANNEL,
+ WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
mLooper.dispatchAll();
verify(mHandler).handleMessage(mMessageCaptor.capture());
@@ -1013,7 +1065,8 @@ public class WifiServiceImplTest {
reset(mHandler);
TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
- WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_ENABLED, HOTSPOT_NO_ERROR);
+ WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_ENABLED, HOTSPOT_NO_ERROR,
+ WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
mLooper.dispatchAll();
verify(mHandler).handleMessage(mMessageCaptor.capture());
@@ -1045,7 +1098,8 @@ public class WifiServiceImplTest {
reset(mHandler);
TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
- WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_DISABLING, HOTSPOT_NO_ERROR);
+ WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_DISABLING, HOTSPOT_NO_ERROR,
+ WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
mLooper.dispatchAll();
verify(mHandler).handleMessage(mMessageCaptor.capture());
@@ -1069,7 +1123,8 @@ public class WifiServiceImplTest {
registerLOHSRequestFull();
TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
- WIFI_AP_STATE_ENABLED, WIFI_AP_STATE_DISABLED, HOTSPOT_NO_ERROR);
+ WIFI_AP_STATE_ENABLED, WIFI_AP_STATE_DISABLED, HOTSPOT_NO_ERROR, WIFI_IFACE_NAME,
+ IFACE_IP_MODE_LOCAL_ONLY);
mLooper.dispatchAll();
verifyNoMoreInteractions(mHandler);
@@ -1099,9 +1154,11 @@ public class WifiServiceImplTest {
reset(mHandler);
TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
- WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_ENABLED, HOTSPOT_NO_ERROR);
+ WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_ENABLED, HOTSPOT_NO_ERROR,
+ WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
- WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_DISABLING, HOTSPOT_NO_ERROR);
+ WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_DISABLING, HOTSPOT_NO_ERROR,
+ WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
mLooper.dispatchAll();
verify(mHandler).handleMessage(mMessageCaptor.capture());
@@ -1125,9 +1182,11 @@ public class WifiServiceImplTest {
registerLOHSRequestFull();
TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
- WIFI_AP_STATE_FAILED, WIFI_AP_STATE_FAILED, ERROR_GENERIC);
+ WIFI_AP_STATE_FAILED, WIFI_AP_STATE_FAILED, ERROR_GENERIC,
+ WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
- WIFI_AP_STATE_FAILED, WIFI_AP_STATE_FAILED, ERROR_GENERIC);
+ WIFI_AP_STATE_FAILED, WIFI_AP_STATE_FAILED, ERROR_GENERIC,
+ WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
mLooper.dispatchAll();
verify(mHandler).handleMessage(mMessageCaptor.capture());
@@ -1155,9 +1214,11 @@ public class WifiServiceImplTest {
registerLOHSRequestFull();
TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
- WIFI_AP_STATE_FAILED, WIFI_AP_STATE_FAILED, ERROR_GENERIC);
+ WIFI_AP_STATE_FAILED, WIFI_AP_STATE_FAILED, ERROR_GENERIC,
+ WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
- WIFI_AP_STATE_FAILED, WIFI_AP_STATE_FAILED, ERROR_GENERIC);
+ WIFI_AP_STATE_FAILED, WIFI_AP_STATE_FAILED, ERROR_GENERIC,
+ WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
verify(mRequestInfo).sendHotspotFailedMessage(ERROR_GENERIC);
mLooper.dispatchAll();
@@ -1194,9 +1255,11 @@ public class WifiServiceImplTest {
reset(mHandler);
TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
- WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_ENABLED, HOTSPOT_NO_ERROR);
+ WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_ENABLED, HOTSPOT_NO_ERROR,
+ WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
- WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_DISABLING, HOTSPOT_NO_ERROR);
+ WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_DISABLING, HOTSPOT_NO_ERROR,
+ WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
verify(mRequestInfo).sendHotspotStoppedMessage();
mLooper.dispatchAll();
@@ -1223,9 +1286,11 @@ public class WifiServiceImplTest {
mWifiServiceImpl.registerLOHSForTest(TEST_PID2, mRequestInfo2);
TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
- WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_ENABLED, HOTSPOT_NO_ERROR);
+ WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_ENABLED, HOTSPOT_NO_ERROR,
+ WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
- WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_DISABLING, HOTSPOT_NO_ERROR);
+ WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_DISABLING, HOTSPOT_NO_ERROR,
+ WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
verify(mRequestInfo).sendHotspotFailedMessage(ERROR_GENERIC);
verify(mRequestInfo2).sendHotspotFailedMessage(ERROR_GENERIC);
@@ -1383,9 +1448,11 @@ public class WifiServiceImplTest {
// now stop the hotspot
TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
- WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_ENABLED, HOTSPOT_NO_ERROR);
+ WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_ENABLED, HOTSPOT_NO_ERROR,
+ WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
- WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_DISABLING, HOTSPOT_NO_ERROR);
+ WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_DISABLING, HOTSPOT_NO_ERROR,
+ WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
mLooper.dispatchAll();
verify(mHandler).handleMessage(mMessageCaptor.capture());
assertEquals(HOTSPOT_STOPPED, mMessageCaptor.getValue().what);
@@ -1473,4 +1540,44 @@ public class WifiServiceImplTest {
verify(mWifiStateMachine).syncAddOrUpdatePasspointConfig(any(),
any(PasspointConfiguration.class), anyInt());
}
+
+ /**
+ * Verify that a call to {@link WifiServiceImpl#restoreBackupData(byte[])} is only allowed from
+ * callers with the signature only NETWORK_SETTINGS permission.
+ */
+ @Test(expected = SecurityException.class)
+ public void testRestoreBackupDataNotApprovedCaller() {
+ doThrow(new SecurityException()).when(mContext)
+ .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
+ eq("WifiService"));
+ mWifiServiceImpl.restoreBackupData(null);
+ verify(mWifiBackupRestore, never()).retrieveConfigurationsFromBackupData(any(byte[].class));
+ }
+
+ /**
+ * Verify that a call to {@link WifiServiceImpl#restoreSupplicantBackupData(byte[], byte[])} is
+ * only allowed from callers with the signature only NETWORK_SETTINGS permission.
+ */
+ @Test(expected = SecurityException.class)
+ public void testRestoreSupplicantBackupDataNotApprovedCaller() {
+ doThrow(new SecurityException()).when(mContext)
+ .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
+ eq("WifiService"));
+ mWifiServiceImpl.restoreSupplicantBackupData(null, null);
+ verify(mWifiBackupRestore, never()).retrieveConfigurationsFromSupplicantBackupData(
+ any(byte[].class), any(byte[].class));
+ }
+
+ /**
+ * Verify that a call to {@link WifiServiceImpl#retrieveBackupData()} is only allowed from
+ * callers with the signature only NETWORK_SETTINGS permission.
+ */
+ @Test(expected = SecurityException.class)
+ public void testRetrieveBackupDataNotApprovedCaller() {
+ doThrow(new SecurityException()).when(mContext)
+ .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
+ eq("WifiService"));
+ mWifiServiceImpl.retrieveBackupData();
+ verify(mWifiBackupRestore, never()).retrieveBackupDataFromConfigurations(any(List.class));
+ }
}
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java
index be9b0c544..2a30b671b 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java
@@ -16,6 +16,18 @@
package com.android.server.wifi;
+import static android.net.wifi.WifiManager.EXTRA_PREVIOUS_WIFI_AP_STATE;
+import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_FAILURE_REASON;
+import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME;
+import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_MODE;
+import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_STATE;
+import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED;
+import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLING;
+import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED;
+import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLING;
+
+import static com.android.server.wifi.LocalOnlyHotspotRequestInfo.HOTSPOT_NO_ERROR;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
@@ -303,6 +315,7 @@ public class WifiStateMachineTest {
static final String sHexSSID = sWifiSsid.getHexString().replace("0x", "").replace("22", "");
static final String sBSSID = "01:02:03:04:05:06";
static final int sFreq = 2437;
+ static final String WIFI_IFACE_NAME = "mockWlan";
WifiStateMachine mWsm;
HandlerThread mWsmThread;
@@ -315,6 +328,9 @@ public class WifiStateMachineTest {
TestLooper mLooper;
Context mContext;
+ final ArgumentCaptor<SoftApManager.Listener> mSoftApManagerListenerCaptor =
+ ArgumentCaptor.forClass(SoftApManager.Listener.class);
+
@Mock WifiScanner mWifiScanner;
@Mock SupplicantStateTracker mSupplicantStateTracker;
@Mock WifiMetrics mWifiMetrics;
@@ -370,7 +386,7 @@ public class WifiStateMachineTest {
when(mWifiInjector.makeWifiConnectivityManager(any(WifiInfo.class), anyBoolean()))
.thenReturn(mWifiConnectivityManager);
when(mWifiInjector.makeSoftApManager(any(INetworkManagementService.class),
- any(SoftApManager.Listener.class), any(IApInterface.class),
+ mSoftApManagerListenerCaptor.capture(), any(IApInterface.class),
any(WifiConfiguration.class)))
.thenReturn(mSoftApManager);
when(mWifiInjector.getPasspointManager()).thenReturn(mPasspointManager);
@@ -381,7 +397,8 @@ public class WifiStateMachineTest {
when(mWifiNative.setupForClientMode()).thenReturn(mClientInterface);
when(mWifiNative.setupForSoftApMode()).thenReturn(mApInterface);
- when(mWifiNative.getInterfaceName()).thenReturn("mockWlan");
+ when(mApInterface.getInterfaceName()).thenReturn(WIFI_IFACE_NAME);
+ when(mWifiNative.getInterfaceName()).thenReturn(WIFI_IFACE_NAME);
when(mWifiNative.enableSupplicant()).thenReturn(true);
when(mWifiNative.disableSupplicant()).thenReturn(true);
when(mWifiNative.getFrameworkNetworkId(anyInt())).thenReturn(0);
@@ -478,14 +495,64 @@ public class WifiStateMachineTest {
assertEquals("DisconnectedState", getCurrentState().getName());
}
- @Test
- public void loadComponentsInApMode() throws Exception {
- mWsm.setHostApRunning(new WifiConfiguration(), true);
+ private void checkApStateChangedBroadcast(Intent intent, int expectedCurrentState,
+ int expectedPrevState, int expectedErrorCode, String expectedIfaceName,
+ int expectedMode) {
+ int currentState = intent.getIntExtra(EXTRA_WIFI_AP_STATE, WIFI_AP_STATE_DISABLED);
+ int prevState = intent.getIntExtra(EXTRA_PREVIOUS_WIFI_AP_STATE, WIFI_AP_STATE_DISABLED);
+ int errorCode = intent.getIntExtra(EXTRA_WIFI_AP_FAILURE_REASON, HOTSPOT_NO_ERROR);
+ String ifaceName = intent.getStringExtra(EXTRA_WIFI_AP_INTERFACE_NAME);
+ int mode = intent.getIntExtra(EXTRA_WIFI_AP_MODE, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
+ assertEquals(expectedCurrentState, currentState);
+ assertEquals(expectedPrevState, prevState);
+ assertEquals(expectedErrorCode, errorCode);
+ assertEquals(expectedIfaceName, ifaceName);
+ assertEquals(expectedMode, mode);
+ }
+
+ private void loadComponentsInApMode(int mode) throws Exception {
+ SoftApModeConfiguration config = new SoftApModeConfiguration(mode, new WifiConfiguration());
+ mWsm.setHostApRunning(config, true);
mLooper.dispatchAll();
assertEquals("SoftApState", getCurrentState().getName());
verify(mSoftApManager).start();
+
+ // reset expectations for mContext due to previously sent AP broadcast
+ reset(mContext);
+
+ // get the SoftApManager.Listener and trigger some updates
+ SoftApManager.Listener listener = mSoftApManagerListenerCaptor.getValue();
+ listener.onStateChanged(WIFI_AP_STATE_ENABLING, 0);
+ listener.onStateChanged(WIFI_AP_STATE_ENABLED, 0);
+ listener.onStateChanged(WIFI_AP_STATE_DISABLING, 0);
+ // note, this will trigger a mode change when TestLooper is dispatched
+ listener.onStateChanged(WIFI_AP_STATE_DISABLED, 0);
+
+ ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+ verify(mContext, times(4))
+ .sendStickyBroadcastAsUser(intentCaptor.capture(), eq(UserHandle.ALL));
+
+ List<Intent> capturedIntents = intentCaptor.getAllValues();
+ checkApStateChangedBroadcast(capturedIntents.get(0), WIFI_AP_STATE_ENABLING,
+ WIFI_AP_STATE_DISABLED, HOTSPOT_NO_ERROR, WIFI_IFACE_NAME, mode);
+ checkApStateChangedBroadcast(capturedIntents.get(1), WIFI_AP_STATE_ENABLED,
+ WIFI_AP_STATE_ENABLING, HOTSPOT_NO_ERROR, WIFI_IFACE_NAME, mode);
+ checkApStateChangedBroadcast(capturedIntents.get(2), WIFI_AP_STATE_DISABLING,
+ WIFI_AP_STATE_ENABLED, HOTSPOT_NO_ERROR, WIFI_IFACE_NAME, mode);
+ checkApStateChangedBroadcast(capturedIntents.get(3), WIFI_AP_STATE_DISABLED,
+ WIFI_AP_STATE_DISABLING, HOTSPOT_NO_ERROR, WIFI_IFACE_NAME, mode);
+ }
+
+ @Test
+ public void loadComponentsInApModeForTethering() throws Exception {
+ loadComponentsInApMode(WifiManager.IFACE_IP_MODE_TETHERED);
+ }
+
+ @Test
+ public void loadComponentsInApModeForLOHS() throws Exception {
+ loadComponentsInApMode(WifiManager.IFACE_IP_MODE_LOCAL_ONLY);
}
@Test
@@ -609,7 +676,9 @@ public class WifiStateMachineTest {
mWsm.setSupplicantRunning(false);
mWsm.sendMessage(WifiStateMachine.CMD_DISABLE_P2P_RSP);
mWsm.sendMessage(WifiMonitor.SUP_DISCONNECTION_EVENT);
- mWsm.setHostApRunning(new WifiConfiguration(), true);
+ SoftApModeConfiguration config = new SoftApModeConfiguration(
+ WifiManager.IFACE_IP_MODE_TETHERED, new WifiConfiguration());
+ mWsm.setHostApRunning(config, true);
mLooper.dispatchAll();
assertEquals("SoftApState", getCurrentState().getName());
assertEquals(WifiManager.WIFI_STATE_DISABLED, mWsm.syncGetWifiState());
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java b/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java
index 66a55b51a..34ddf2378 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java
@@ -1679,9 +1679,10 @@ public class WifiVendorHalTest {
new Random().nextBytes(errorData);
// Randomly raise the HIDL callback before we register for the log callback.
- // This should be ignored.
+ // This should be safely ignored. (Not trigger NPE.)
mIWifiChipEventCallback.onDebugErrorAlert(
errorCode, NativeUtil.byteArrayToArrayList(errorData));
+ mLooper.dispatchAll();
WifiNative.WifiLoggerEventHandler eventHandler =
mock(WifiNative.WifiLoggerEventHandler.class);
@@ -1691,12 +1692,16 @@ public class WifiVendorHalTest {
// Now raise the HIDL callback, this should be properly handled.
mIWifiChipEventCallback.onDebugErrorAlert(
errorCode, NativeUtil.byteArrayToArrayList(errorData));
+ mLooper.dispatchAll();
verify(eventHandler).onWifiAlert(eq(errorCode), eq(errorData));
// Now stop the logging and invoke the callback. This should be ignored.
+ reset(eventHandler);
assertTrue(mWifiVendorHal.resetLogHandler());
mIWifiChipEventCallback.onDebugErrorAlert(
errorCode, NativeUtil.byteArrayToArrayList(errorData));
+ mLooper.dispatchAll();
+ verify(eventHandler, never()).onWifiAlert(anyInt(), anyObject());
}
/**
@@ -1714,9 +1719,10 @@ public class WifiVendorHalTest {
new Random().nextBytes(errorData);
// Randomly raise the HIDL callback before we register for the log callback.
- // This should be ignored.
+ // This should be safely ignored. (Not trigger NPE.)
mIWifiChipEventCallback.onDebugRingBufferDataAvailable(
new WifiDebugRingBufferStatus(), NativeUtil.byteArrayToArrayList(errorData));
+ mLooper.dispatchAll();
WifiNative.WifiLoggerEventHandler eventHandler =
mock(WifiNative.WifiLoggerEventHandler.class);
@@ -1726,13 +1732,17 @@ public class WifiVendorHalTest {
// Now raise the HIDL callback, this should be properly handled.
mIWifiChipEventCallback.onDebugRingBufferDataAvailable(
new WifiDebugRingBufferStatus(), NativeUtil.byteArrayToArrayList(errorData));
+ mLooper.dispatchAll();
verify(eventHandler).onRingBufferData(
any(WifiNative.RingBufferStatus.class), eq(errorData));
// Now stop the logging and invoke the callback. This should be ignored.
+ reset(eventHandler);
assertTrue(mWifiVendorHal.resetLogHandler());
mIWifiChipEventCallback.onDebugRingBufferDataAvailable(
new WifiDebugRingBufferStatus(), NativeUtil.byteArrayToArrayList(errorData));
+ mLooper.dispatchAll();
+ verify(eventHandler, never()).onRingBufferData(anyObject(), anyObject());
}
/**
diff --git a/tests/wifitests/src/com/android/server/wifi/scanner/WifiScanningServiceTest.java b/tests/wifitests/src/com/android/server/wifi/scanner/WifiScanningServiceTest.java
index d9fbb1d28..e7c5fa962 100644
--- a/tests/wifitests/src/com/android/server/wifi/scanner/WifiScanningServiceTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/scanner/WifiScanningServiceTest.java
@@ -1257,10 +1257,10 @@ public class WifiScanningServiceTest {
}
/**
- * Verify that the newest full scan results are returned by WifiService.getSingleScanResults.
+ * Verify that the newest scan results are returned by WifiService.getSingleScanResults.
*/
@Test
- public void retrieveMostRecentFullSingleScanResults() throws Exception {
+ public void retrieveMostRecentSingleScanResults() throws Exception {
WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0,
0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
ScanResults expectedResults = ScanResults.create(0, true, 2400, 5150, 5175);
@@ -1312,64 +1312,6 @@ public class WifiScanningServiceTest {
}
/**
- * Verify that the newest partial scan results are not returned by
- * WifiService.getSingleScanResults.
- */
- @Test
- public void doesNotRetrieveMostRecentPartialSingleScanResults() throws Exception {
- WifiScanner.ScanSettings fullRequestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0,
- 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
- ScanResults expectedFullResults = ScanResults.create(0, true, 2400, 5150, 5175);
- doSuccessfulSingleScan(fullRequestSettings,
- computeSingleScanNativeSettings(fullRequestSettings),
- expectedFullResults);
-
- Handler handler = mock(Handler.class);
- BidirectionalAsyncChannel controlChannel = connectChannel(handler);
- InOrder order = inOrder(handler, mWifiScannerImpl);
-
- controlChannel.sendMessage(
- Message.obtain(null, WifiScanner.CMD_GET_SINGLE_SCAN_RESULTS, 0));
- mLooper.dispatchAll();
- Message response = verifyHandleMessageAndGetMessage(order, handler);
-
- List<ScanResult> results = Arrays.asList(
- ((WifiScanner.ParcelableScanResults) response.obj).getResults());
- assertEquals(results.size(), expectedFullResults.getRawScanResults().length);
-
- // now update with a new scan that only has one result
- int secondScanRequestId = 35;
- WifiScanner.ScanSettings partialRequestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH,
- 0, 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
- ScanResults expectedPartialResults = ScanResults.create(0, false, 5150);
- sendSingleScanRequest(controlChannel, secondScanRequestId, partialRequestSettings, null);
-
- mLooper.dispatchAll();
- WifiNative.ScanEventHandler eventHandler = verifyStartSingleScan(order,
- computeSingleScanNativeSettings(partialRequestSettings));
- verifySuccessfulResponse(order, handler, secondScanRequestId);
-
- // dispatch scan 2 results
- when(mWifiScannerImpl.getLatestSingleScanResults())
- .thenReturn(expectedPartialResults.getScanData());
- eventHandler.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
-
- mLooper.dispatchAll();
- verifyScanResultsReceived(order, handler, secondScanRequestId,
- expectedPartialResults.getScanData());
- verifySingleScanCompletedReceived(order, handler, secondScanRequestId);
-
- controlChannel.sendMessage(
- Message.obtain(null, WifiScanner.CMD_GET_SINGLE_SCAN_RESULTS, 0));
- mLooper.dispatchAll();
- Message response2 = verifyHandleMessageAndGetMessage(order, handler);
-
- List<ScanResult> results2 = Arrays.asList(
- ((WifiScanner.ParcelableScanResults) response2.obj).getResults());
- assertEquals(results2.size(), expectedFullResults.getRawScanResults().length);
- }
-
- /**
* Cached scan results should be cleared after the driver is unloaded.
*/
@Test