diff options
Diffstat (limited to 'service')
9 files changed, 178 insertions, 52 deletions
diff --git a/service/java/com/android/server/wifi/ClientModeImpl.java b/service/java/com/android/server/wifi/ClientModeImpl.java index 85eeb22fa..2b391050c 100644 --- a/service/java/com/android/server/wifi/ClientModeImpl.java +++ b/service/java/com/android/server/wifi/ClientModeImpl.java @@ -1105,12 +1105,31 @@ public class ClientModeImpl extends StateMachine { mWifiNative.removeNetworkCachedData(config.networkId); } - @Override - public void onNetworkUpdated(WifiConfiguration config) { - // User might have changed meteredOverride, so update capabilities - if (config.networkId == mLastNetworkId) { - updateCapabilities(); + public void onNetworkUpdated(WifiConfiguration newConfig, WifiConfiguration oldConfig) { + // Check if user/app change meteredOverride for connected network. + if (newConfig.networkId != mLastNetworkId + || newConfig.meteredOverride == oldConfig.meteredOverride) { + // nothing to do. + return; + } + boolean isMetered = WifiConfiguration.isMetered(newConfig, mWifiInfo); + boolean wasMetered = WifiConfiguration.isMetered(oldConfig, mWifiInfo); + if (isMetered == wasMetered) { + // no meteredness change, nothing to do. + if (mVerboseLoggingEnabled) { + Log.v(TAG, "User/app changed meteredOverride, but no change in meteredness"); + } + return; + } + // If unmetered->metered trigger a disconnect. + // If metered->unmetered update capabilities. + if (isMetered) { + Log.w(TAG, "Network marked metered, triggering disconnect"); + sendMessage(CMD_DISCONNECT); + } else { + Log.i(TAG, "Network marked unmetered, triggering capabilities update"); + updateCapabilities(newConfig); } } @@ -4446,10 +4465,14 @@ public class ClientModeImpl extends StateMachine { } private void updateCapabilities(WifiConfiguration currentWifiConfiguration) { + updateCapabilities(getCapabilities(currentWifiConfiguration)); + } + + private void updateCapabilities(NetworkCapabilities networkCapabilities) { if (mNetworkAgent == null) { return; } - mNetworkAgent.sendNetworkCapabilities(getCapabilities(currentWifiConfiguration)); + mNetworkAgent.sendNetworkCapabilities(networkCapabilities); } private void handleEapAuthFailure(int networkId, int errorCode) { diff --git a/service/java/com/android/server/wifi/NetworkSuggestionNominator.java b/service/java/com/android/server/wifi/NetworkSuggestionNominator.java index a8d181fdc..c4fd6a908 100644 --- a/service/java/com/android/server/wifi/NetworkSuggestionNominator.java +++ b/service/java/com/android/server/wifi/NetworkSuggestionNominator.java @@ -196,19 +196,6 @@ public class NetworkSuggestionNominator implements WifiNetworkSelector.NetworkNo if (matchingExtNetworkSuggestionsFromSamePackage.isEmpty()) { continue; } - ExtendedWifiNetworkSuggestion matchingExtNetworkSuggestion = - matchingExtNetworkSuggestionsFromSamePackage.stream().findFirst().get(); - // Update the WifiConfigManager with the latest WifiConfig - WifiConfiguration config = - matchingExtNetworkSuggestion.createInternalWifiConfiguration(); - NetworkUpdateResult result = mWifiConfigManager.addOrUpdateNetwork( - config, - matchingExtNetworkSuggestion.perAppInfo.uid, - matchingExtNetworkSuggestion.perAppInfo.packageName); - if (result.isSuccess()) { - wCmConfiguredNetwork = mWifiConfigManager.getConfiguredNetwork( - result.getNetworkId()); - } // If the network is currently blacklisted, ignore. if (!wCmConfiguredNetwork.getNetworkSelectionStatus().isNetworkEnabled() && !mWifiConfigManager.tryEnableNetwork(wCmConfiguredNetwork.networkId)) { diff --git a/service/java/com/android/server/wifi/WifiConfigManager.java b/service/java/com/android/server/wifi/WifiConfigManager.java index 4e4f51d60..91ebe6bc7 100644 --- a/service/java/com/android/server/wifi/WifiConfigManager.java +++ b/service/java/com/android/server/wifi/WifiConfigManager.java @@ -107,6 +107,8 @@ public class WifiConfigManager { /** * Interface for other modules to listen to the network updated * events. + * Note: Credentials are masked to avoid accidentally sending credentials outside the stack. + * Use WifiConfigManager#getConfiguredNetworkWithPassword() to retrieve credentials. */ public interface OnNetworkUpdateListener { /** @@ -131,8 +133,12 @@ public class WifiConfigManager { void onNetworkTemporarilyDisabled(@NonNull WifiConfiguration config, int disableReason); /** * Invoked on network being updated. + * + * @param newConfig Updated WifiConfiguration object. + * @param oldConfig Prev WifiConfiguration object. */ - void onNetworkUpdated(@NonNull WifiConfiguration config); + void onNetworkUpdated( + @NonNull WifiConfiguration newConfig, @NonNull WifiConfiguration oldConfig); } /** * Max size of scan details to cache in {@link #mScanDetailCaches}. @@ -1323,9 +1329,9 @@ public class WifiConfigManager { Log.e(TAG, "Cannot add/update network before store is read!"); return new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID); } + WifiConfiguration existingConfig = getInternalConfiguredNetwork(config); if (!config.isEphemeral()) { // Removes the existing ephemeral network if it exists to add this configuration. - WifiConfiguration existingConfig = getConfiguredNetwork(config.getKey()); if (existingConfig != null && existingConfig.isEphemeral()) { // In this case, new connection for this config won't happen because same // network is already registered as an ephemeral network. @@ -1352,11 +1358,13 @@ public class WifiConfigManager { } for (OnNetworkUpdateListener listener : mListeners) { - WifiConfiguration configForListener = new WifiConfiguration(newConfig); if (result.isNewNetwork()) { - listener.onNetworkAdded(configForListener); + listener.onNetworkAdded( + createExternalWifiConfiguration(newConfig, true, Process.WIFI_UID)); } else { - listener.onNetworkUpdated(configForListener); + listener.onNetworkUpdated( + createExternalWifiConfiguration(newConfig, true, Process.WIFI_UID), + createExternalWifiConfiguration(existingConfig, true, Process.WIFI_UID)); } } return result; @@ -1445,8 +1453,8 @@ public class WifiConfigManager { saveToStore(true); } for (OnNetworkUpdateListener listener : mListeners) { - WifiConfiguration configForListener = new WifiConfiguration(config); - listener.onNetworkRemoved(configForListener); + listener.onNetworkRemoved( + createExternalWifiConfiguration(config, true, Process.WIFI_UID)); } return true; } @@ -1606,8 +1614,8 @@ public class WifiConfigManager { // Clear out all the disable reason counters. status.clearDisableReasonCounter(); for (OnNetworkUpdateListener listener : mListeners) { - WifiConfiguration configForListener = new WifiConfiguration(config); - listener.onNetworkEnabled(configForListener); + listener.onNetworkEnabled( + createExternalWifiConfiguration(config, true, Process.WIFI_UID)); } } @@ -1623,8 +1631,8 @@ public class WifiConfigManager { status.setDisableTime(mClock.getElapsedSinceBootMillis()); status.setNetworkSelectionDisableReason(disableReason); for (OnNetworkUpdateListener listener : mListeners) { - WifiConfiguration configForListener = new WifiConfiguration(config); - listener.onNetworkTemporarilyDisabled(configForListener, disableReason); + listener.onNetworkTemporarilyDisabled( + createExternalWifiConfiguration(config, true, Process.WIFI_UID), disableReason); } } @@ -1641,7 +1649,8 @@ public class WifiConfigManager { status.setNetworkSelectionDisableReason(disableReason); for (OnNetworkUpdateListener listener : mListeners) { WifiConfiguration configForListener = new WifiConfiguration(config); - listener.onNetworkPermanentlyDisabled(configForListener, disableReason); + listener.onNetworkPermanentlyDisabled( + createExternalWifiConfiguration(config, true, Process.WIFI_UID), disableReason); } } diff --git a/service/java/com/android/server/wifi/WifiConnectivityManager.java b/service/java/com/android/server/wifi/WifiConnectivityManager.java index 712dbcd7f..59b3e3d86 100644 --- a/service/java/com/android/server/wifi/WifiConnectivityManager.java +++ b/service/java/com/android/server/wifi/WifiConnectivityManager.java @@ -709,7 +709,7 @@ public class WifiConnectivityManager { updateScan(); } @Override - public void onNetworkUpdated(WifiConfiguration config) { + public void onNetworkUpdated(WifiConfiguration newConfig, WifiConfiguration oldConfig) { updateScan(); } @Override diff --git a/service/java/com/android/server/wifi/WifiHealthMonitor.java b/service/java/com/android/server/wifi/WifiHealthMonitor.java index 123c576bd..0b0c68d88 100644 --- a/service/java/com/android/server/wifi/WifiHealthMonitor.java +++ b/service/java/com/android/server/wifi/WifiHealthMonitor.java @@ -965,7 +965,7 @@ public class WifiHealthMonitor { } @Override - public void onNetworkUpdated(WifiConfiguration config) { + public void onNetworkUpdated(WifiConfiguration newConfig, WifiConfiguration oldConfig) { } } diff --git a/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java b/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java index 19c9da156..ef05ccb58 100644 --- a/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java +++ b/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java @@ -264,6 +264,17 @@ public class WifiNetworkSuggestionsManager { && TextUtils.equals(perAppInfo.packageName, other.perAppInfo.packageName); } + /** + * Helper method to set the carrier Id. + */ + public void setCarrierId(int carrierId) { + if (wns.passpointConfiguration == null) { + wns.wifiConfiguration.carrierId = carrierId; + } else { + wns.passpointConfiguration.setCarrierId(carrierId); + } + } + @Override public String toString() { return new StringBuilder(wns.toString()) @@ -794,6 +805,29 @@ public class WifiNetworkSuggestionsManager { Collectors.toSet())); } + private void updateWifiConfigInWcmIfPresent( + WifiConfiguration newConfig, int uid, String packageName) { + WifiConfiguration configInWcm = + mWifiConfigManager.getConfiguredNetwork(newConfig.getKey()); + if (configInWcm == null) return; + // !suggestion + if (!configInWcm.fromWifiNetworkSuggestion) return; + // is suggestion from same app. + if (configInWcm.creatorUid != uid + || !TextUtils.equals(configInWcm.creatorName, packageName)) { + return; + } + NetworkUpdateResult result = mWifiConfigManager.addOrUpdateNetwork( + newConfig, uid, packageName); + if (!result.isSuccess()) { + Log.e(TAG, "Failed to update config in WifiConfigManager"); + } else { + if (mVerboseLoggingEnabled) { + Log.v(TAG, "Updated config in WifiConfigManager"); + } + } + } + /** * Add the provided list of network suggestions from the corresponding app's active list. */ @@ -862,10 +896,20 @@ public class WifiNetworkSuggestionsManager { } for (ExtendedWifiNetworkSuggestion ewns: extNetworkSuggestions) { - if (ewns.wns.passpointConfiguration == null) { - if (carrierId != TelephonyManager.UNKNOWN_CARRIER_ID) { - ewns.wns.wifiConfiguration.carrierId = carrierId; + if (carrierId != TelephonyManager.UNKNOWN_CARRIER_ID) { + ewns.setCarrierId(carrierId); + } + // If network has no IMSI protection and user didn't approve exemption, make it initial + // auto join disabled + if (isSimBasedSuggestion(ewns)) { + int subId = mTelephonyUtil.getMatchingSubId(getCarrierIdFromSuggestion(ewns)); + if (!(mTelephonyUtil.requiresImsiEncryption(subId) + || hasUserApprovedImsiPrivacyExemptionForCarrier( + getCarrierIdFromSuggestion(ewns)))) { + ewns.isAutojoinEnabled = false; } + } + if (ewns.wns.passpointConfiguration == null) { if (ewns.wns.wifiConfiguration.isEnterprise()) { if (!mWifiKeyStore.updateNetworkKeys(ewns.wns.wifiConfiguration, null)) { Log.e(TAG, "Enterprise network install failure for SSID: " @@ -873,11 +917,13 @@ public class WifiNetworkSuggestionsManager { continue; } } + // If we have a config in WifiConfigManager for this suggestion, update + // WifiConfigManager with the latest WifiConfig. + // Note: Similar logic is present in PasspointManager for passpoint networks. + updateWifiConfigInWcmIfPresent( + ewns.createInternalWifiConfiguration(), uid, packageName); addToScanResultMatchInfoMap(ewns); } else { - if (carrierId != TelephonyManager.UNKNOWN_CARRIER_ID) { - ewns.wns.passpointConfiguration.setCarrierId(carrierId); - } ewns.wns.passpointConfiguration.setAutojoinEnabled(ewns.isAutojoinEnabled); // Install Passpoint config, if failure, ignore that suggestion if (!mWifiInjector.getPasspointManager().addOrUpdateProvider( @@ -889,16 +935,6 @@ public class WifiNetworkSuggestionsManager { } addToPasspointInfoMap(ewns); } - // If network has no IMSI protection and user didn't approve exemption, make it initial - // auto join disabled - if (isSimBasedSuggestion(ewns)) { - int subId = mTelephonyUtil.getMatchingSubId(getCarrierIdFromSuggestion(ewns)); - if (!(mTelephonyUtil.requiresImsiEncryption(subId) - || hasUserApprovedImsiPrivacyExemptionForCarrier( - getCarrierIdFromSuggestion(ewns)))) { - ewns.isAutojoinEnabled = false; - } - } perAppInfo.extNetworkSuggestions.remove(ewns); perAppInfo.extNetworkSuggestions.add(ewns); } diff --git a/service/java/com/android/server/wifi/WifiShellCommand.java b/service/java/com/android/server/wifi/WifiShellCommand.java index cbab50cd4..37f8d10c8 100644 --- a/service/java/com/android/server/wifi/WifiShellCommand.java +++ b/service/java/com/android/server/wifi/WifiShellCommand.java @@ -25,6 +25,8 @@ import android.content.Context; import android.content.pm.ParceledListSlice; import android.net.ConnectivityManager; import android.net.MacAddress; +import android.net.Network; +import android.net.NetworkCapabilities; import android.net.NetworkRequest; import android.net.wifi.IActionListener; import android.net.wifi.ScanResult; @@ -77,6 +79,7 @@ public class WifiShellCommand extends BasicShellCommandHandler { // However, these do perform permission checks in the corresponding WifiService methods. private static final String[] NON_PRIVILEGED_COMMANDS = { "add-suggestion", + "add-network", "connect-network", "forget-network", "get-country-code", @@ -410,6 +413,28 @@ public class WifiShellCommand extends BasicShellCommandHandler { countDownLatch.await(500, TimeUnit.MILLISECONDS); break; } + case "add-network": { + CountDownLatch countDownLatch = new CountDownLatch(1); + IActionListener.Stub actionListener = new IActionListener.Stub() { + @Override + public void onSuccess() throws RemoteException { + pw.println("Save successful"); + countDownLatch.countDown(); + } + + @Override + public void onFailure(int i) throws RemoteException { + pw.println("Save failed"); + countDownLatch.countDown(); + } + }; + mWifiService.save( + buildWifiConfiguration(pw), new Binder(), actionListener, + actionListener.hashCode()); + // wait for status. + countDownLatch.await(500, TimeUnit.MILLISECONDS); + break; + } case "forget-network": { String networkId = getNextArgRequired(); CountDownLatch countDownLatch = new CountDownLatch(1); @@ -444,7 +469,11 @@ public class WifiShellCommand extends BasicShellCommandHandler { if (wifiEnabled) { if (info.getSupplicantState() == SupplicantState.COMPLETED) { pw.println("Wifi is connected to " + info.getSSID()); - pw.println("Connection Details: " + info); + pw.println("WifiInfo: " + info); + Network network = mWifiService.getCurrentNetwork(); + NetworkCapabilities capabilities = + mConnectivityManager.getNetworkCapabilities(network); + pw.println("NetworkCapabilities: " + capabilities); } else { pw.println("Wifi is not connected"); } @@ -762,7 +791,18 @@ public class WifiShellCommand extends BasicShellCommandHandler { pw.println(" list-networks"); pw.println(" Lists the saved networks"); pw.println(" connect-network <ssid> open|owe|wpa2|wpa3 [<passphrase>] [-m]"); - pw.println(" Connect to a network with provided params and save"); + pw.println(" Connect to a network with provided params and add to saved networks list"); + pw.println(" <ssid> - SSID of the network"); + pw.println(" open|owe|wpa2|wpa3 - Security type of the network."); + pw.println(" - Use 'open' or 'owe' for networks with no passphrase"); + pw.println(" - 'open' - Open networks (Most prevalent)"); + pw.println(" - 'owe' - Enhanced open networks"); + pw.println(" - Use 'wpa2' or 'wpa3' for networks with passphrase"); + pw.println(" - 'wpa2' - WPA-2 PSK networks (Most prevalent)"); + pw.println(" - 'wpa3' - WPA-3 PSK networks"); + pw.println(" -m - Mark the network metered."); + pw.println(" add-network <ssid> open|owe|wpa2|wpa3 [<passphrase>] [-m]"); + pw.println(" Add/update saved network with provided params"); pw.println(" <ssid> - SSID of the network"); pw.println(" open|owe|wpa2|wpa3 - Security type of the network."); pw.println(" - Use 'open' or 'owe' for networks with no passphrase"); diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointManager.java b/service/java/com/android/server/wifi/hotspot2/PasspointManager.java index d3e405b1d..14f326ef0 100644 --- a/service/java/com/android/server/wifi/hotspot2/PasspointManager.java +++ b/service/java/com/android/server/wifi/hotspot2/PasspointManager.java @@ -51,6 +51,7 @@ import android.util.Log; import android.util.Pair; import com.android.server.wifi.Clock; +import com.android.server.wifi.NetworkUpdateResult; import com.android.server.wifi.WifiConfigManager; import com.android.server.wifi.WifiConfigStore; import com.android.server.wifi.WifiInjector; @@ -375,6 +376,30 @@ public class PasspointManager { } } + private void updateWifiConfigInWcmIfPresent( + WifiConfiguration newConfig, int uid, String packageName, boolean isFromSuggestion) { + WifiConfiguration configInWcm = + mWifiConfigManager.getConfiguredNetwork(newConfig.getKey()); + if (configInWcm == null) return; + // suggestion != saved + if (isFromSuggestion != configInWcm.fromWifiNetworkSuggestion) return; + // is suggestion from same app. + if (isFromSuggestion + && (configInWcm.creatorUid != uid + || !TextUtils.equals(configInWcm.creatorName, packageName))) { + return; + } + NetworkUpdateResult result = mWifiConfigManager.addOrUpdateNetwork( + newConfig, uid, packageName); + if (!result.isSuccess()) { + Log.e(TAG, "Failed to update config in WifiConfigManager"); + } else { + if (mVerboseLoggingEnabled) { + Log.v(TAG, "Updated config in WifiConfigManager"); + } + } + } + /** * Add or update a Passpoint provider with the given configuration. * @@ -423,7 +448,7 @@ public class PasspointManager { if (mProviders.containsKey(config.getUniqueId())) { PasspointProvider old = mProviders.get(config.getUniqueId()); // If new profile is from suggestion and from a different App, ignore new profile, - // return true. + // return false. // If from same app, update it. if (isFromSuggestion && !old.getPackageName().equals(packageName)) { newProvider.uninstallCertsAndKeys(); @@ -437,6 +462,10 @@ public class PasspointManager { if (!old.equals(newProvider)) { mWifiConfigManager.removePasspointConfiguredNetwork( newProvider.getWifiConfig().getKey()); + } else { + // If there is a config cached in WifiConfigManager, update it with new info. + updateWifiConfigInWcmIfPresent( + newProvider.getWifiConfig(), uid, packageName, isFromSuggestion); } } newProvider.enableVerboseLogging(mVerboseLoggingEnabled ? 1 : 0); diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointNetworkNominateHelper.java b/service/java/com/android/server/wifi/hotspot2/PasspointNetworkNominateHelper.java index 27c8331ec..22ce2f07a 100644 --- a/service/java/com/android/server/wifi/hotspot2/PasspointNetworkNominateHelper.java +++ b/service/java/com/android/server/wifi/hotspot2/PasspointNetworkNominateHelper.java @@ -202,6 +202,8 @@ public class PasspointNetworkNominateHelper { } // Add or update with the newly created WifiConfiguration to WifiConfigManager. + // NOTE: if existingNetwork != null, this update is a no-op in most cases if the SSID is the + // same (since we update the cached config in PasspointManager#addOrUpdateProvider(). NetworkUpdateResult result; if (config.fromWifiNetworkSuggestion) { result = mWifiConfigManager.addOrUpdateNetwork( |