diff options
author | Ningyuan Wang <nywang@google.com> | 2017-06-01 22:26:33 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2017-06-01 22:26:33 +0000 |
commit | 9da08e01464d39de3f14fe09f535660635d39c42 (patch) | |
tree | 35fb83f5ce10e7b63ff0c469a3332f4ed37a3390 /service | |
parent | af32c06cd4eaca6492614d0c4aad69609022e030 (diff) | |
parent | 403df479e25031276c738dbea334f09bb7e4bf37 (diff) |
Merge changes from topic 'supplicant_sta_iface_hal_network_change' into oc-dev
* changes:
Remove network from supplicant when it is disabled
Do not remove and add the same network
Diffstat (limited to 'service')
6 files changed, 202 insertions, 64 deletions
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/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/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 ********************************************************/ |