From bfd17b75a67e3a3c9a99a87db35be4d753e6bd08 Mon Sep 17 00:00:00 2001 From: Paul Jensen Date: Tue, 7 Apr 2015 12:43:13 -0400 Subject: [PATCH] Add ConnectivityManager.reportNetworkConnectivity() API This new API allows reporting networks that are perceived to provide Internet connectivity and networks that are not. This allows the framework to avoid needlessly reevaluating networks where the apps perception matches the framework's perception. This was not possible with the prior API, reportBadNetwork. Bug: 16214361 Change-Id: Id4409bd7538854bd837231fb50e693c10a62b4f2 --- api/current.txt | 3 +- api/system-current.txt | 3 +- .../java/android/net/ConnectivityManager.java | 25 ++++++++++++++++- .../android/net/IConnectivityManager.aidl | 2 +- .../android/server/ConnectivityService.java | 28 ++++++++++--------- .../server/connectivity/NetworkMonitor.java | 2 +- 6 files changed, 45 insertions(+), 18 deletions(-) diff --git a/api/current.txt b/api/current.txt index b59d2173bfa5f..de0e3361d7f96 100644 --- a/api/current.txt +++ b/api/current.txt @@ -16980,7 +16980,8 @@ package android.net { method public void registerNetworkCallback(android.net.NetworkRequest, android.net.ConnectivityManager.NetworkCallback); method public void releaseNetworkRequest(android.app.PendingIntent); method public void removeDefaultNetworkActiveListener(android.net.ConnectivityManager.OnNetworkActiveListener); - method public void reportBadNetwork(android.net.Network); + method public deprecated void reportBadNetwork(android.net.Network); + method public void reportNetworkConnectivity(android.net.Network, boolean); method public void requestNetwork(android.net.NetworkRequest, android.net.ConnectivityManager.NetworkCallback); method public void requestNetwork(android.net.NetworkRequest, android.app.PendingIntent); method public deprecated boolean requestRouteToHost(int, int); diff --git a/api/system-current.txt b/api/system-current.txt index aefa9993c26c9..8afac60275e14 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -18241,7 +18241,8 @@ package android.net { method public void registerNetworkCallback(android.net.NetworkRequest, android.net.ConnectivityManager.NetworkCallback); method public void releaseNetworkRequest(android.app.PendingIntent); method public void removeDefaultNetworkActiveListener(android.net.ConnectivityManager.OnNetworkActiveListener); - method public void reportBadNetwork(android.net.Network); + method public deprecated void reportBadNetwork(android.net.Network); + method public void reportNetworkConnectivity(android.net.Network, boolean); method public void requestNetwork(android.net.NetworkRequest, android.net.ConnectivityManager.NetworkCallback); method public void requestNetwork(android.net.NetworkRequest, android.app.PendingIntent); method public deprecated boolean requestRouteToHost(int, int); diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index 99e368d5e45f8..050cafc562493 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -1708,10 +1708,33 @@ public class ConnectivityManager { * * @param network The {@link Network} the application was attempting to use * or {@code null} to indicate the current default network. + * @deprecated Use {@link #reportNetworkConnectivity} which allows reporting both + * working and non-working connectivity. */ public void reportBadNetwork(Network network) { try { - mService.reportBadNetwork(network); + // One of these will be ignored because it matches system's current state. + // The other will trigger the necessary reevaluation. + mService.reportNetworkConnectivity(network, true); + mService.reportNetworkConnectivity(network, false); + } catch (RemoteException e) { + } + } + + /** + * Report to the framework whether a network has working connectivity. + * This provides a hint to the system that a particular network is providing + * working connectivity or not. In response the framework may re-evaluate + * the network's connectivity and might take further action thereafter. + * + * @param network The {@link Network} the application was attempting to use + * or {@code null} to indicate the current default network. + * @param hasConnectivity {@code true} if the application was able to successfully access the + * Internet using {@code network} or {@code false} if not. + */ + public void reportNetworkConnectivity(Network network, boolean hasConnectivity) { + try { + mService.reportNetworkConnectivity(network, hasConnectivity); } catch (RemoteException e) { } } diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl index 171c7d414d8cc..05ef2e60faaea 100644 --- a/core/java/android/net/IConnectivityManager.aidl +++ b/core/java/android/net/IConnectivityManager.aidl @@ -95,7 +95,7 @@ interface IConnectivityManager void reportInetCondition(int networkType, int percentage); - void reportBadNetwork(in Network network); + void reportNetworkConnectivity(in Network network, boolean hasConnectivity); ProxyInfo getGlobalProxy(); diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index ee44b0990cf07..ff6dc38298c6e 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -2461,25 +2461,27 @@ public class ConnectivityService extends IConnectivityManager.Stub public void reportInetCondition(int networkType, int percentage) { NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType); if (nai == null) return; - boolean isGood = percentage > 50; - // Revalidate if the app report does not match our current validated state. - if (isGood != nai.lastValidated) { - // Make the message logged by reportBadNetwork below less confusing. - if (DBG && isGood) log("reportInetCondition: type=" + networkType + " ok, revalidate"); - reportBadNetwork(nai.network); - } + reportNetworkConnectivity(nai.network, percentage > 50); } - public void reportBadNetwork(Network network) { + public void reportNetworkConnectivity(Network network, boolean hasConnectivity) { enforceAccessPermission(); enforceInternetPermission(); - if (network == null) return; - - final int uid = Binder.getCallingUid(); - NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); + NetworkAgentInfo nai; + if (network == null) { + nai = getDefaultNetwork(); + } else { + nai = getNetworkAgentInfoForNetwork(network); + } if (nai == null) return; - if (DBG) log("reportBadNetwork(" + nai.name() + ") by " + uid); + // Revalidate if the app report does not match our current validated state. + if (hasConnectivity == nai.lastValidated) return; + final int uid = Binder.getCallingUid(); + if (DBG) { + log("reportNetworkConnectivity(" + nai.network.netId + ", " + hasConnectivity + + ") by " + uid); + } synchronized (nai) { // Validating an uncreated network could result in a call to rematchNetworkAndRequests() // which isn't meant to work on uncreated networks. diff --git a/services/core/java/com/android/server/connectivity/NetworkMonitor.java b/services/core/java/com/android/server/connectivity/NetworkMonitor.java index 87f78c1bb4488..76220dbf32d15 100644 --- a/services/core/java/com/android/server/connectivity/NetworkMonitor.java +++ b/services/core/java/com/android/server/connectivity/NetworkMonitor.java @@ -220,7 +220,7 @@ public class NetworkMonitor extends StateMachine { // If a network is not validated, make one attempt every 10 mins to see if it starts working. private static final int REEVALUATE_PAUSE_MS = 10*60*1000; private static final int PERIODIC_ATTEMPTS = 1; - // When an application calls reportBadNetwork, only make one attempt. + // When an application calls reportNetworkConnectivity, only make one attempt. private static final int REEVALUATE_ATTEMPTS = 1; private final int mReevaluateDelayMs; private int mReevaluateToken = 0;