From 9686c96d8d0c0bc21ca069e244e2570c169724e1 Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Thu, 28 Sep 2017 14:46:29 +0900 Subject: Allow connecting with no requests if we're already connected. Currently, we drop all connection start attempts if we do not have any NetworkRequests that we can fulfil. This can happen if the default network has a score that's higher than our score filter. The reason for this is that we don't want to connect a new network if we're not already connected: if we did, ConnectivityService would immediately request that the network be torn down. However, it does make sense to connect if we are already connected, because that means that we ourselves are the highest-scoring network - otherwise, ConnectivityService would have torn us down. So, when deciding whether to process a connection request, allow it if mNetworkAgent is non-null, even if there are no NetworkRequests that we can fulfil. In order to do this, move the check from startConnectToNetwork to the code that processes CMD_START_CONNECT, because it's not safe to access mNetworkAgent except from the handler thread. Moving the check also seems more correct in general, because the return value of hasConnectionRequests() could change between when startConnectToNetwork is called and when the resulting CMD_START_CONNECT is processed. The connect requests are only allowed from the settings/sysui. We don't allow any non-privileged apps to be able to override the user's decision to stay connected to a network with no internet access (which causes the mNetworkAgent.releaseNetworkFor()). Bug: 65262556 Test: Unit tests for START_CONNECT handling for 4 scenarios: a) START_CONNECT with the default network request. b) START_CONNECT with no network request. c) START_CONNECT with no network request, but already connected d) START_CONNECT with no network request, but already connected, but from non-privileged app. Test: Settings can connect to a new network when wifi has a score of 100 Change-Id: Iad582b5109a81f238f335eaac3e7264c5da6e9b1 --- .../server/wifi/WifiConnectivityManager.java | 3 +- .../com/android/server/wifi/WifiStateMachine.java | 33 +++++++++++++++------- 2 files changed, 25 insertions(+), 11 deletions(-) (limited to 'service') diff --git a/service/java/com/android/server/wifi/WifiConnectivityManager.java b/service/java/com/android/server/wifi/WifiConnectivityManager.java index 7e730c838..6bfce74db 100644 --- a/service/java/com/android/server/wifi/WifiConnectivityManager.java +++ b/service/java/com/android/server/wifi/WifiConnectivityManager.java @@ -30,6 +30,7 @@ import android.net.wifi.WifiScanner.PnoSettings; import android.net.wifi.WifiScanner.ScanSettings; import android.os.Handler; import android.os.Looper; +import android.os.Process; import android.util.LocalLog; import android.util.Log; @@ -741,7 +742,7 @@ public class WifiConnectivityManager { localLog("connectToNetwork: Connect to " + targetAssociationId + " from " + currentAssociationId); } - mStateMachine.startConnectToNetwork(candidate.networkId, targetBssid); + mStateMachine.startConnectToNetwork(candidate.networkId, Process.WIFI_UID, targetBssid); } } diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java index a3054c92b..9e124463d 100644 --- a/service/java/com/android/server/wifi/WifiStateMachine.java +++ b/service/java/com/android/server/wifi/WifiStateMachine.java @@ -1321,7 +1321,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss /** * Initiates connection to a network specified by the user/app. This method checks if the - * requesting app holds the WIFI_CONFIG_OVERRIDE permission. + * requesting app holds the NETWORK_SETTINGS permission. * * @param netId Id network to initiate connection. * @param uid UID of the app requesting the connection. @@ -1350,7 +1350,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss logi("connectToUserSelectNetwork already connecting/connected=" + netId); } else { mWifiConnectivityManager.prepareForForcedConnection(netId); - startConnectToNetwork(netId, SUPPLICANT_BSSID_ANY); + startConnectToNetwork(netId, uid, SUPPLICANT_BSSID_ANY); } return true; } @@ -5178,7 +5178,23 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss case CMD_START_CONNECT: /* connect command coming from auto-join */ netId = message.arg1; + int uid = message.arg2; bssid = (String) message.obj; + + synchronized (mWifiReqCountLock) { + if (!hasConnectionRequests()) { + if (mNetworkAgent == null) { + loge("CMD_START_CONNECT but no requests and not connected," + + " bailing"); + break; + } else if (!mWifiPermissionsUtil.checkNetworkSettingsPermission(uid)) { + loge("CMD_START_CONNECT but no requests and connected, but app " + + "does not have sufficient permissions, bailing"); + break; + } + } + } + config = mWifiConfigManager.getConfiguredNetworkWithPassword(netId); logd("CMD_START_CONNECT sup state " + mSupplicantStateTracker.getSupplicantStateName() @@ -5278,7 +5294,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss // start a new connection with the updated credentials. logi("SAVE_NETWORK credential changed for config=" + config.configKey() + ", Reconnecting."); - startConnectToNetwork(netId, SUPPLICANT_BSSID_ANY); + startConnectToNetwork(netId, message.sendingUid, SUPPLICANT_BSSID_ANY); } else { if (result.hasProxyChanged()) { log("Reconfiguring proxy on connection"); @@ -6121,7 +6137,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss WifiConfiguration config = getCurrentWifiConfiguration(); if (shouldEvaluateWhetherToSendExplicitlySelected(config)) { boolean prompt = - mWifiPermissionsUtil.checkConfigOverridePermission(config.lastConnectUid); + mWifiPermissionsUtil.checkNetworkSettingsPermission(config.lastConnectUid); if (mVerboseLoggingEnabled) { log("Network selected by UID " + config.lastConnectUid + " prompt=" + prompt); } @@ -7097,14 +7113,11 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss * Automatically connect to the network specified * * @param networkId ID of the network to connect to + * @param uid UID of the app triggering the connection. * @param bssid BSSID of the network */ - public void startConnectToNetwork(int networkId, String bssid) { - synchronized (mWifiReqCountLock) { - if (hasConnectionRequests()) { - sendMessage(CMD_START_CONNECT, networkId, 0, bssid); - } - } + public void startConnectToNetwork(int networkId, int uid, String bssid) { + sendMessage(CMD_START_CONNECT, networkId, uid, bssid); } /** -- cgit v1.2.3