Loading core/java/android/net/ConnectivityManager.java +3 −94 Original line number Diff line number Diff line Loading @@ -144,16 +144,6 @@ public class ConnectivityManager { @Deprecated public static final String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE"; /** * A temporary hack until SUPL system can get off the legacy APIS. * They do too many network requests and the long list of apps listening * and waking due to the CONNECTIVITY_ACTION broadcast makes it expensive. * Use this broadcast intent instead for SUPL requests. * @hide */ public static final String CONNECTIVITY_ACTION_SUPL = "android.net.conn.CONNECTIVITY_CHANGE_SUPL"; /** * The device has connected to a network that has presented a captive * portal, which is blocking Internet connectivity. The user was presented Loading Loading @@ -1517,84 +1507,6 @@ public class ConnectivityManager { return null; } /** * Guess what the network request was trying to say so that the resulting * network is accessible via the legacy (deprecated) API such as * requestRouteToHost. * * This means we should try to be fairly precise about transport and * capability but ignore things such as networkSpecifier. * If the request has more than one transport or capability it doesn't * match the old legacy requests (they selected only single transport/capability) * so this function cannot map the request to a single legacy type and * the resulting network will not be available to the legacy APIs. * * This code is only called from the requestNetwork API (L and above). * * Setting a legacy type causes CONNECTIVITY_ACTION broadcasts, which are expensive * because they wake up lots of apps - see http://b/23350688 . So we currently only * do this for SUPL requests, which are the only ones that we know need it. If * omitting these broadcasts causes unacceptable app breakage, then for backwards * compatibility we can send them: * * if (targetSdkVersion < Build.VERSION_CODES.M) && // legacy API unsupported >= M * targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP)) // requestNetwork not present < L * * TODO - This should be removed when the legacy APIs are removed. */ private int inferLegacyTypeForNetworkCapabilities(NetworkCapabilities netCap) { if (netCap == null) { return TYPE_NONE; } if (!netCap.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) { return TYPE_NONE; } // Do this only for SUPL, until GnssLocationProvider is fixed. http://b/25876485 . if (!netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)) { // NOTE: if this causes app breakage, we should not just comment out this early return; // instead, we should make this early return conditional on the requesting app's target // SDK version, as described in the comment above. return TYPE_NONE; } String type = null; int result = TYPE_NONE; if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)) { type = "enableCBS"; result = TYPE_MOBILE_CBS; } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)) { type = "enableIMS"; result = TYPE_MOBILE_IMS; } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_FOTA)) { type = "enableFOTA"; result = TYPE_MOBILE_FOTA; } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_DUN)) { type = "enableDUN"; result = TYPE_MOBILE_DUN; } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)) { type = "enableSUPL"; result = TYPE_MOBILE_SUPL; // back out this hack for mms as they no longer need this and it's causing // device slowdowns - b/23350688 (note, supl still needs this) //} else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMS)) { // type = "enableMMS"; // result = TYPE_MOBILE_MMS; } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) { type = "enableHIPRI"; result = TYPE_MOBILE_HIPRI; } if (type != null) { NetworkCapabilities testCap = networkCapabilitiesForFeature(TYPE_MOBILE, type); if (testCap.equalsNetCapabilities(netCap) && testCap.equalsTransportTypes(netCap)) { return result; } } return TYPE_NONE; } private int legacyTypeForNetworkCapabilities(NetworkCapabilities netCap) { if (netCap == null) return TYPE_NONE; if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)) { Loading Loading @@ -3893,9 +3805,8 @@ public class ConnectivityManager { */ public void requestNetwork(@NonNull NetworkRequest request, @NonNull NetworkCallback networkCallback, @NonNull Handler handler) { int legacyType = inferLegacyTypeForNetworkCapabilities(request.networkCapabilities); CallbackHandler cbHandler = new CallbackHandler(handler); requestNetwork(request, networkCallback, 0, legacyType, cbHandler); requestNetwork(request, networkCallback, 0, TYPE_NONE, cbHandler); } /** Loading Loading @@ -3928,8 +3839,7 @@ public class ConnectivityManager { public void requestNetwork(@NonNull NetworkRequest request, @NonNull NetworkCallback networkCallback, int timeoutMs) { checkTimeout(timeoutMs); int legacyType = inferLegacyTypeForNetworkCapabilities(request.networkCapabilities); requestNetwork(request, networkCallback, timeoutMs, legacyType, getDefaultHandler()); requestNetwork(request, networkCallback, timeoutMs, TYPE_NONE, getDefaultHandler()); } /** Loading @@ -3954,9 +3864,8 @@ public class ConnectivityManager { public void requestNetwork(@NonNull NetworkRequest request, @NonNull NetworkCallback networkCallback, @NonNull Handler handler, int timeoutMs) { checkTimeout(timeoutMs); int legacyType = inferLegacyTypeForNetworkCapabilities(request.networkCapabilities); CallbackHandler cbHandler = new CallbackHandler(handler); requestNetwork(request, networkCallback, timeoutMs, legacyType, cbHandler); requestNetwork(request, networkCallback, timeoutMs, TYPE_NONE, cbHandler); } /** Loading services/core/java/com/android/server/ConnectivityService.java +3 −8 Original line number Diff line number Diff line Loading @@ -2240,14 +2240,9 @@ public class ConnectivityService extends IConnectivityManager.Stub if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) { final NetworkInfo ni = intent.getParcelableExtra( ConnectivityManager.EXTRA_NETWORK_INFO); if (ni.getType() == ConnectivityManager.TYPE_MOBILE_SUPL) { intent.setAction(ConnectivityManager.CONNECTIVITY_ACTION_SUPL); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); } else { BroadcastOptions opts = BroadcastOptions.makeBasic(); final BroadcastOptions opts = BroadcastOptions.makeBasic(); opts.setMaxManifestReceiverApiLevel(Build.VERSION_CODES.M); options = opts.toBundle(); } final IBatteryStats bs = mDeps.getBatteryStatsService(); try { bs.noteConnectivityChanged(intent.getIntExtra( Loading tests/net/java/com/android/server/ConnectivityServiceTest.java +8 −38 Original line number Diff line number Diff line Loading @@ -25,7 +25,6 @@ import static android.content.pm.PackageManager.PERMISSION_DENIED; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.net.ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN; import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; import static android.net.ConnectivityManager.CONNECTIVITY_ACTION_SUPL; import static android.net.ConnectivityManager.EXTRA_NETWORK_INFO; import static android.net.ConnectivityManager.EXTRA_NETWORK_TYPE; import static android.net.ConnectivityManager.NETID_UNSET; Loading Loading @@ -1389,7 +1388,6 @@ public class ConnectivityServiceTest { @NonNull final Predicate<Intent> filter) { final ConditionVariable cv = new ConditionVariable(); final IntentFilter intentFilter = new IntentFilter(CONNECTIVITY_ACTION); intentFilter.addAction(CONNECTIVITY_ACTION_SUPL); final BroadcastReceiver receiver = new BroadcastReceiver() { private int remaining = count; public void onReceive(Context context, Intent intent) { Loading Loading @@ -1437,56 +1435,28 @@ public class ConnectivityServiceTest { final NetworkRequest legacyRequest = new NetworkRequest(legacyCaps, TYPE_MOBILE_SUPL, ConnectivityManager.REQUEST_ID_UNSET, NetworkRequest.Type.REQUEST); // Send request and check that the legacy broadcast for SUPL is sent correctly. // File request, withdraw it and make sure no broadcast is sent final ConditionVariable cv2 = registerConnectivityBroadcast(1); final TestNetworkCallback callback = new TestNetworkCallback(); final ConditionVariable cv2 = registerConnectivityBroadcastThat(1, intent -> intent.getIntExtra(EXTRA_NETWORK_TYPE, -1) == TYPE_MOBILE_SUPL); mCm.requestNetwork(legacyRequest, callback); callback.expectCallback(CallbackEntry.AVAILABLE, mCellNetworkAgent); waitFor(cv2); // File another request, withdraw it and make sure no broadcast is sent final ConditionVariable cv3 = registerConnectivityBroadcast(1); final TestNetworkCallback callback2 = new TestNetworkCallback(); mCm.requestNetwork(legacyRequest, callback2); callback2.expectCallback(CallbackEntry.AVAILABLE, mCellNetworkAgent); mCm.unregisterNetworkCallback(callback2); assertFalse(cv3.block(800)); // 800ms long enough to at least flake if this is sent mCm.unregisterNetworkCallback(callback); assertFalse(cv2.block(800)); // 800ms long enough to at least flake if this is sent // As the broadcast did not fire, the receiver was not unregistered. Do this now. mServiceContext.clearRegisteredReceivers(); // Withdraw the request and check that the broadcast for disconnection is sent. final ConditionVariable cv4 = registerConnectivityBroadcastThat(1, intent -> !((NetworkInfo) intent.getExtra(EXTRA_NETWORK_INFO, -1)).isConnected() && intent.getIntExtra(EXTRA_NETWORK_TYPE, -1) == TYPE_MOBILE_SUPL); mCm.unregisterNetworkCallback(callback); waitFor(cv4); // Re-file the request and expect the connected broadcast again final ConditionVariable cv5 = registerConnectivityBroadcastThat(1, intent -> intent.getIntExtra(EXTRA_NETWORK_TYPE, -1) == TYPE_MOBILE_SUPL); final TestNetworkCallback callback3 = new TestNetworkCallback(); mCm.requestNetwork(legacyRequest, callback3); callback3.expectCallback(CallbackEntry.AVAILABLE, mCellNetworkAgent); waitFor(cv5); // Disconnect the network and expect two disconnected broadcasts, one for SUPL and one // for mobile. Use a small hack to check that both have been sent, but the order is // not contractual. // Disconnect the network and expect mobile disconnected broadcast. Use a small hack to // check that has been sent. final AtomicBoolean vanillaAction = new AtomicBoolean(false); final AtomicBoolean suplAction = new AtomicBoolean(false); final ConditionVariable cv6 = registerConnectivityBroadcastThat(2, intent -> { final ConditionVariable cv3 = registerConnectivityBroadcastThat(1, intent -> { if (intent.getAction().equals(CONNECTIVITY_ACTION)) { vanillaAction.set(true); } else if (intent.getAction().equals(CONNECTIVITY_ACTION_SUPL)) { suplAction.set(true); } return !((NetworkInfo) intent.getExtra(EXTRA_NETWORK_INFO, -1)).isConnected(); }); mCellNetworkAgent.disconnect(); waitFor(cv6); waitFor(cv3); assertTrue(vanillaAction.get()); assertTrue(suplAction.get()); } @Test Loading Loading
core/java/android/net/ConnectivityManager.java +3 −94 Original line number Diff line number Diff line Loading @@ -144,16 +144,6 @@ public class ConnectivityManager { @Deprecated public static final String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE"; /** * A temporary hack until SUPL system can get off the legacy APIS. * They do too many network requests and the long list of apps listening * and waking due to the CONNECTIVITY_ACTION broadcast makes it expensive. * Use this broadcast intent instead for SUPL requests. * @hide */ public static final String CONNECTIVITY_ACTION_SUPL = "android.net.conn.CONNECTIVITY_CHANGE_SUPL"; /** * The device has connected to a network that has presented a captive * portal, which is blocking Internet connectivity. The user was presented Loading Loading @@ -1517,84 +1507,6 @@ public class ConnectivityManager { return null; } /** * Guess what the network request was trying to say so that the resulting * network is accessible via the legacy (deprecated) API such as * requestRouteToHost. * * This means we should try to be fairly precise about transport and * capability but ignore things such as networkSpecifier. * If the request has more than one transport or capability it doesn't * match the old legacy requests (they selected only single transport/capability) * so this function cannot map the request to a single legacy type and * the resulting network will not be available to the legacy APIs. * * This code is only called from the requestNetwork API (L and above). * * Setting a legacy type causes CONNECTIVITY_ACTION broadcasts, which are expensive * because they wake up lots of apps - see http://b/23350688 . So we currently only * do this for SUPL requests, which are the only ones that we know need it. If * omitting these broadcasts causes unacceptable app breakage, then for backwards * compatibility we can send them: * * if (targetSdkVersion < Build.VERSION_CODES.M) && // legacy API unsupported >= M * targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP)) // requestNetwork not present < L * * TODO - This should be removed when the legacy APIs are removed. */ private int inferLegacyTypeForNetworkCapabilities(NetworkCapabilities netCap) { if (netCap == null) { return TYPE_NONE; } if (!netCap.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) { return TYPE_NONE; } // Do this only for SUPL, until GnssLocationProvider is fixed. http://b/25876485 . if (!netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)) { // NOTE: if this causes app breakage, we should not just comment out this early return; // instead, we should make this early return conditional on the requesting app's target // SDK version, as described in the comment above. return TYPE_NONE; } String type = null; int result = TYPE_NONE; if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)) { type = "enableCBS"; result = TYPE_MOBILE_CBS; } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)) { type = "enableIMS"; result = TYPE_MOBILE_IMS; } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_FOTA)) { type = "enableFOTA"; result = TYPE_MOBILE_FOTA; } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_DUN)) { type = "enableDUN"; result = TYPE_MOBILE_DUN; } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)) { type = "enableSUPL"; result = TYPE_MOBILE_SUPL; // back out this hack for mms as they no longer need this and it's causing // device slowdowns - b/23350688 (note, supl still needs this) //} else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMS)) { // type = "enableMMS"; // result = TYPE_MOBILE_MMS; } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) { type = "enableHIPRI"; result = TYPE_MOBILE_HIPRI; } if (type != null) { NetworkCapabilities testCap = networkCapabilitiesForFeature(TYPE_MOBILE, type); if (testCap.equalsNetCapabilities(netCap) && testCap.equalsTransportTypes(netCap)) { return result; } } return TYPE_NONE; } private int legacyTypeForNetworkCapabilities(NetworkCapabilities netCap) { if (netCap == null) return TYPE_NONE; if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)) { Loading Loading @@ -3893,9 +3805,8 @@ public class ConnectivityManager { */ public void requestNetwork(@NonNull NetworkRequest request, @NonNull NetworkCallback networkCallback, @NonNull Handler handler) { int legacyType = inferLegacyTypeForNetworkCapabilities(request.networkCapabilities); CallbackHandler cbHandler = new CallbackHandler(handler); requestNetwork(request, networkCallback, 0, legacyType, cbHandler); requestNetwork(request, networkCallback, 0, TYPE_NONE, cbHandler); } /** Loading Loading @@ -3928,8 +3839,7 @@ public class ConnectivityManager { public void requestNetwork(@NonNull NetworkRequest request, @NonNull NetworkCallback networkCallback, int timeoutMs) { checkTimeout(timeoutMs); int legacyType = inferLegacyTypeForNetworkCapabilities(request.networkCapabilities); requestNetwork(request, networkCallback, timeoutMs, legacyType, getDefaultHandler()); requestNetwork(request, networkCallback, timeoutMs, TYPE_NONE, getDefaultHandler()); } /** Loading @@ -3954,9 +3864,8 @@ public class ConnectivityManager { public void requestNetwork(@NonNull NetworkRequest request, @NonNull NetworkCallback networkCallback, @NonNull Handler handler, int timeoutMs) { checkTimeout(timeoutMs); int legacyType = inferLegacyTypeForNetworkCapabilities(request.networkCapabilities); CallbackHandler cbHandler = new CallbackHandler(handler); requestNetwork(request, networkCallback, timeoutMs, legacyType, cbHandler); requestNetwork(request, networkCallback, timeoutMs, TYPE_NONE, cbHandler); } /** Loading
services/core/java/com/android/server/ConnectivityService.java +3 −8 Original line number Diff line number Diff line Loading @@ -2240,14 +2240,9 @@ public class ConnectivityService extends IConnectivityManager.Stub if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) { final NetworkInfo ni = intent.getParcelableExtra( ConnectivityManager.EXTRA_NETWORK_INFO); if (ni.getType() == ConnectivityManager.TYPE_MOBILE_SUPL) { intent.setAction(ConnectivityManager.CONNECTIVITY_ACTION_SUPL); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); } else { BroadcastOptions opts = BroadcastOptions.makeBasic(); final BroadcastOptions opts = BroadcastOptions.makeBasic(); opts.setMaxManifestReceiverApiLevel(Build.VERSION_CODES.M); options = opts.toBundle(); } final IBatteryStats bs = mDeps.getBatteryStatsService(); try { bs.noteConnectivityChanged(intent.getIntExtra( Loading
tests/net/java/com/android/server/ConnectivityServiceTest.java +8 −38 Original line number Diff line number Diff line Loading @@ -25,7 +25,6 @@ import static android.content.pm.PackageManager.PERMISSION_DENIED; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.net.ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN; import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; import static android.net.ConnectivityManager.CONNECTIVITY_ACTION_SUPL; import static android.net.ConnectivityManager.EXTRA_NETWORK_INFO; import static android.net.ConnectivityManager.EXTRA_NETWORK_TYPE; import static android.net.ConnectivityManager.NETID_UNSET; Loading Loading @@ -1389,7 +1388,6 @@ public class ConnectivityServiceTest { @NonNull final Predicate<Intent> filter) { final ConditionVariable cv = new ConditionVariable(); final IntentFilter intentFilter = new IntentFilter(CONNECTIVITY_ACTION); intentFilter.addAction(CONNECTIVITY_ACTION_SUPL); final BroadcastReceiver receiver = new BroadcastReceiver() { private int remaining = count; public void onReceive(Context context, Intent intent) { Loading Loading @@ -1437,56 +1435,28 @@ public class ConnectivityServiceTest { final NetworkRequest legacyRequest = new NetworkRequest(legacyCaps, TYPE_MOBILE_SUPL, ConnectivityManager.REQUEST_ID_UNSET, NetworkRequest.Type.REQUEST); // Send request and check that the legacy broadcast for SUPL is sent correctly. // File request, withdraw it and make sure no broadcast is sent final ConditionVariable cv2 = registerConnectivityBroadcast(1); final TestNetworkCallback callback = new TestNetworkCallback(); final ConditionVariable cv2 = registerConnectivityBroadcastThat(1, intent -> intent.getIntExtra(EXTRA_NETWORK_TYPE, -1) == TYPE_MOBILE_SUPL); mCm.requestNetwork(legacyRequest, callback); callback.expectCallback(CallbackEntry.AVAILABLE, mCellNetworkAgent); waitFor(cv2); // File another request, withdraw it and make sure no broadcast is sent final ConditionVariable cv3 = registerConnectivityBroadcast(1); final TestNetworkCallback callback2 = new TestNetworkCallback(); mCm.requestNetwork(legacyRequest, callback2); callback2.expectCallback(CallbackEntry.AVAILABLE, mCellNetworkAgent); mCm.unregisterNetworkCallback(callback2); assertFalse(cv3.block(800)); // 800ms long enough to at least flake if this is sent mCm.unregisterNetworkCallback(callback); assertFalse(cv2.block(800)); // 800ms long enough to at least flake if this is sent // As the broadcast did not fire, the receiver was not unregistered. Do this now. mServiceContext.clearRegisteredReceivers(); // Withdraw the request and check that the broadcast for disconnection is sent. final ConditionVariable cv4 = registerConnectivityBroadcastThat(1, intent -> !((NetworkInfo) intent.getExtra(EXTRA_NETWORK_INFO, -1)).isConnected() && intent.getIntExtra(EXTRA_NETWORK_TYPE, -1) == TYPE_MOBILE_SUPL); mCm.unregisterNetworkCallback(callback); waitFor(cv4); // Re-file the request and expect the connected broadcast again final ConditionVariable cv5 = registerConnectivityBroadcastThat(1, intent -> intent.getIntExtra(EXTRA_NETWORK_TYPE, -1) == TYPE_MOBILE_SUPL); final TestNetworkCallback callback3 = new TestNetworkCallback(); mCm.requestNetwork(legacyRequest, callback3); callback3.expectCallback(CallbackEntry.AVAILABLE, mCellNetworkAgent); waitFor(cv5); // Disconnect the network and expect two disconnected broadcasts, one for SUPL and one // for mobile. Use a small hack to check that both have been sent, but the order is // not contractual. // Disconnect the network and expect mobile disconnected broadcast. Use a small hack to // check that has been sent. final AtomicBoolean vanillaAction = new AtomicBoolean(false); final AtomicBoolean suplAction = new AtomicBoolean(false); final ConditionVariable cv6 = registerConnectivityBroadcastThat(2, intent -> { final ConditionVariable cv3 = registerConnectivityBroadcastThat(1, intent -> { if (intent.getAction().equals(CONNECTIVITY_ACTION)) { vanillaAction.set(true); } else if (intent.getAction().equals(CONNECTIVITY_ACTION_SUPL)) { suplAction.set(true); } return !((NetworkInfo) intent.getExtra(EXTRA_NETWORK_INFO, -1)).isConnected(); }); mCellNetworkAgent.disconnect(); waitFor(cv6); waitFor(cv3); assertTrue(vanillaAction.get()); assertTrue(suplAction.get()); } @Test Loading