From 15ff2fc68d42c926defb2aeaa3c52a9332a7404f Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Wed, 22 Apr 2015 10:44:49 +0900 Subject: [PATCH] Allow apps with ACCESS_WIFI_STATE to listen for wifi networks The compatibility measure introduced in bug 20081183 for apps that connect to a Wi-Fi network without Internet access and then expect to be able to use that network requires that such apps register a NetworkCallback so that their WifiManager can pin them to whatever wifi Network connects. Currently, registering the callback requires ACCESS_NETWORK_STATE and the app may not have that permission. Allow registering wifi (only) callbacks if the app has ACCESS_WIFI_STATE. If the app does not have ACCESS_WIFI_STATE (unlikely, since CHANGE_WIFI_STATE is not very useful without ACCESS_WIFI_STATE), then don't enable the compatibility measure. Bug: 20081183 Bug: 20423580 Change-Id: Iad328d30c2d170dead883868fece3d922da68f6f --- .../android/server/ConnectivityService.java | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 9ec1c6aa5e..7d8e9de798 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -3518,10 +3518,34 @@ public class ConnectivityService extends IConnectivityManager.Stub getCallingUid(), 0, operation)); } + // In order to implement the compatibility measure for pre-M apps that call + // WifiManager.enableNetwork(..., true) without also binding to that network explicitly, + // WifiManager registers a network listen for the purpose of calling setProcessDefaultNetwork. + // This ensures it has permission to do so. + private boolean hasWifiNetworkListenPermission(NetworkCapabilities nc) { + if (nc == null) { + return false; + } + int[] transportTypes = nc.getTransportTypes(); + if (transportTypes.length != 1 || transportTypes[0] != NetworkCapabilities.TRANSPORT_WIFI) { + return false; + } + try { + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.ACCESS_WIFI_STATE, + "ConnectivityService"); + } catch (SecurityException e) { + return false; + } + return true; + } + @Override public NetworkRequest listenForNetwork(NetworkCapabilities networkCapabilities, Messenger messenger, IBinder binder) { - enforceAccessPermission(); + if (!hasWifiNetworkListenPermission(networkCapabilities)) { + enforceAccessPermission(); + } NetworkRequest networkRequest = new NetworkRequest(new NetworkCapabilities( networkCapabilities), TYPE_NONE, nextNetworkRequestId());