Publish FOREGROUND and add NOT_SUSPENDED capabilities.
NOT_SUSPENDED and FOREGROUND are capabilities that need to be public so as to reach feature parity with what information can be gotten through the use of CONNECTIVITY_ACTION and synchronous calls to ConnectivityManager. This change makes them public, and wires up the NOT_SUSPENDED capability. This deprecates in effect the old onSuspended and onResumed callbacks, but these have never been public. This also converts the onAvailable path from a multiple binder call design to a simpler, single binder call. This is only for internal convenience Test: runtest frameworks-net Test: cts Test: also manual testing Change-Id: I6ea524bb361ecef0569ea2f9006c1e516378bc25
This commit is contained in:
@@ -2685,6 +2685,32 @@ public class ConnectivityManager {
|
||||
* satisfying the request changes.
|
||||
*
|
||||
* @param network The {@link Network} of the satisfying network.
|
||||
* @param networkCapabilities The {@link NetworkCapabilities} of the satisfying network.
|
||||
* @param linkProperties The {@link LinkProperties} of the satisfying network.
|
||||
* @hide
|
||||
*/
|
||||
public void onAvailable(Network network, NetworkCapabilities networkCapabilities,
|
||||
LinkProperties linkProperties) {
|
||||
// Internally only this method is called when a new network is available, and
|
||||
// it calls the callback in the same way and order that older versions used
|
||||
// to call so as not to change the behavior.
|
||||
onAvailable(network);
|
||||
if (!networkCapabilities.hasCapability(
|
||||
NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED)) {
|
||||
onNetworkSuspended(network);
|
||||
}
|
||||
onCapabilitiesChanged(network, networkCapabilities);
|
||||
onLinkPropertiesChanged(network, linkProperties);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the framework connects and has declared a new network ready for use.
|
||||
* This callback may be called more than once if the {@link Network} that is
|
||||
* satisfying the request changes. This will always immediately be followed by a
|
||||
* call to {@link #onCapabilitiesChanged(Network, NetworkCapabilities)} then by a
|
||||
* call to {@link #onLinkPropertiesChanged(Network, LinkProperties)}.
|
||||
*
|
||||
* @param network The {@link Network} of the satisfying network.
|
||||
*/
|
||||
public void onAvailable(Network network) {}
|
||||
|
||||
@@ -2727,7 +2753,8 @@ public class ConnectivityManager {
|
||||
* changes capabilities but still satisfies the stated need.
|
||||
*
|
||||
* @param network The {@link Network} whose capabilities have changed.
|
||||
* @param networkCapabilities The new {@link android.net.NetworkCapabilities} for this network.
|
||||
* @param networkCapabilities The new {@link android.net.NetworkCapabilities} for this
|
||||
* network.
|
||||
*/
|
||||
public void onCapabilitiesChanged(Network network,
|
||||
NetworkCapabilities networkCapabilities) {}
|
||||
@@ -2743,7 +2770,7 @@ public class ConnectivityManager {
|
||||
|
||||
/**
|
||||
* Called when the network the framework connected to for this request
|
||||
* goes into {@link NetworkInfo.DetailedState.SUSPENDED}.
|
||||
* goes into {@link NetworkInfo.State#SUSPENDED}.
|
||||
* This generally means that while the TCP connections are still live,
|
||||
* temporarily network data fails to transfer. Specifically this is used
|
||||
* on cellular networks to mask temporary outages when driving through
|
||||
@@ -2754,9 +2781,8 @@ public class ConnectivityManager {
|
||||
|
||||
/**
|
||||
* Called when the network the framework connected to for this request
|
||||
* returns from a {@link NetworkInfo.DetailedState.SUSPENDED} state.
|
||||
* This should always be preceeded by a matching {@code onNetworkSuspended}
|
||||
* call.
|
||||
* returns from a {@link NetworkInfo.State#SUSPENDED} state. This should always be
|
||||
* preceded by a matching {@link NetworkCallback#onNetworkSuspended} call.
|
||||
* @hide
|
||||
*/
|
||||
public void onNetworkResumed(Network network) {}
|
||||
@@ -2865,7 +2891,9 @@ public class ConnectivityManager {
|
||||
break;
|
||||
}
|
||||
case CALLBACK_AVAILABLE: {
|
||||
callback.onAvailable(network);
|
||||
NetworkCapabilities cap = getObject(message, NetworkCapabilities.class);
|
||||
LinkProperties lp = getObject(message, LinkProperties.class);
|
||||
callback.onAvailable(network, cap, lp);
|
||||
break;
|
||||
}
|
||||
case CALLBACK_LOSING: {
|
||||
|
||||
@@ -116,6 +116,7 @@ public final class NetworkCapabilities implements Parcelable {
|
||||
NET_CAPABILITY_NOT_ROAMING,
|
||||
NET_CAPABILITY_FOREGROUND,
|
||||
NET_CAPABILITY_NOT_CONGESTED,
|
||||
NET_CAPABILITY_NOT_SUSPENDED,
|
||||
})
|
||||
public @interface NetCapability { }
|
||||
|
||||
@@ -239,7 +240,6 @@ public final class NetworkCapabilities implements Parcelable {
|
||||
/**
|
||||
* Indicates that this network is available for use by apps, and not a network that is being
|
||||
* kept up in the background to facilitate fast network switching.
|
||||
* @hide
|
||||
*/
|
||||
public static final int NET_CAPABILITY_FOREGROUND = 19;
|
||||
|
||||
@@ -252,8 +252,20 @@ public final class NetworkCapabilities implements Parcelable {
|
||||
*/
|
||||
public static final int NET_CAPABILITY_NOT_CONGESTED = 20;
|
||||
|
||||
/**
|
||||
* Indicates that this network is not currently suspended.
|
||||
* <p>
|
||||
* When a network is suspended, the network's IP addresses and any connections
|
||||
* established on the network remain valid, but the network is temporarily unable
|
||||
* to transfer data. This can happen, for example, if a cellular network experiences
|
||||
* a temporary loss of signal, such as when driving through a tunnel, etc.
|
||||
* A network with this capability is not suspended, so is expected to be able to
|
||||
* transfer data.
|
||||
*/
|
||||
public static final int NET_CAPABILITY_NOT_SUSPENDED = 21;
|
||||
|
||||
private static final int MIN_NET_CAPABILITY = NET_CAPABILITY_MMS;
|
||||
private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_NOT_CONGESTED;
|
||||
private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_NOT_SUSPENDED;
|
||||
|
||||
/**
|
||||
* Network capabilities that are expected to be mutable, i.e., can change while a particular
|
||||
@@ -262,12 +274,13 @@ public final class NetworkCapabilities implements Parcelable {
|
||||
private static final long MUTABLE_CAPABILITIES =
|
||||
// TRUSTED can change when user explicitly connects to an untrusted network in Settings.
|
||||
// http://b/18206275
|
||||
(1 << NET_CAPABILITY_TRUSTED) |
|
||||
(1 << NET_CAPABILITY_VALIDATED) |
|
||||
(1 << NET_CAPABILITY_CAPTIVE_PORTAL) |
|
||||
(1 << NET_CAPABILITY_NOT_ROAMING) |
|
||||
(1 << NET_CAPABILITY_FOREGROUND) |
|
||||
(1 << NET_CAPABILITY_NOT_CONGESTED);
|
||||
(1 << NET_CAPABILITY_TRUSTED)
|
||||
| (1 << NET_CAPABILITY_VALIDATED)
|
||||
| (1 << NET_CAPABILITY_CAPTIVE_PORTAL)
|
||||
| (1 << NET_CAPABILITY_NOT_ROAMING)
|
||||
| (1 << NET_CAPABILITY_FOREGROUND)
|
||||
| (1 << NET_CAPABILITY_NOT_CONGESTED)
|
||||
| (1 << NET_CAPABILITY_NOT_SUSPENDED);
|
||||
|
||||
/**
|
||||
* Network capabilities that are not allowed in NetworkRequests. This exists because the
|
||||
@@ -1276,6 +1289,7 @@ public final class NetworkCapabilities implements Parcelable {
|
||||
case NET_CAPABILITY_NOT_ROAMING: return "NOT_ROAMING";
|
||||
case NET_CAPABILITY_FOREGROUND: return "FOREGROUND";
|
||||
case NET_CAPABILITY_NOT_CONGESTED: return "NOT_CONGESTED";
|
||||
case NET_CAPABILITY_NOT_SUSPENDED: return "NOT_SUSPENDED";
|
||||
default: return Integer.toString(capability);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED;
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
|
||||
import static android.net.NetworkCapabilities.TRANSPORT_VPN;
|
||||
@@ -4503,10 +4504,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
lp.ensureDirectlyConnectedRoutes();
|
||||
// TODO: Instead of passing mDefaultRequest, provide an API to determine whether a Network
|
||||
// satisfies mDefaultRequest.
|
||||
final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities);
|
||||
final NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(),
|
||||
new Network(reserveNetId()), new NetworkInfo(networkInfo), lp,
|
||||
new NetworkCapabilities(networkCapabilities), currentScore,
|
||||
new Network(reserveNetId()), new NetworkInfo(networkInfo), lp, nc, currentScore,
|
||||
mContext, mTrackerHandler, new NetworkMisc(networkMisc), mDefaultRequest, this);
|
||||
// Make sure the network capabilities reflect what the agent info says.
|
||||
nai.networkCapabilities = mixInCapabilities(nai, nc);
|
||||
synchronized (this) {
|
||||
nai.networkMonitor.systemReady = mSystemReady;
|
||||
}
|
||||
@@ -4735,6 +4738,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
} else {
|
||||
newNc.addCapability(NET_CAPABILITY_FOREGROUND);
|
||||
}
|
||||
if (nai.isSuspended()) {
|
||||
newNc.removeCapability(NET_CAPABILITY_NOT_SUSPENDED);
|
||||
} else {
|
||||
newNc.addCapability(NET_CAPABILITY_NOT_SUSPENDED);
|
||||
}
|
||||
|
||||
return newNc;
|
||||
}
|
||||
@@ -4928,6 +4936,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
putParcelable(bundle, networkAgent.network);
|
||||
}
|
||||
switch (notificationType) {
|
||||
case ConnectivityManager.CALLBACK_AVAILABLE: {
|
||||
putParcelable(bundle, new NetworkCapabilities(networkAgent.networkCapabilities));
|
||||
putParcelable(bundle, new LinkProperties(networkAgent.linkProperties));
|
||||
break;
|
||||
}
|
||||
case ConnectivityManager.CALLBACK_LOSING: {
|
||||
msg.arg1 = arg1;
|
||||
break;
|
||||
@@ -5468,6 +5481,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
if (networkAgent.getCurrentScore() != oldScore) {
|
||||
rematchAllNetworksAndRequests(networkAgent, oldScore);
|
||||
}
|
||||
updateCapabilities(networkAgent.getCurrentScore(), networkAgent,
|
||||
networkAgent.networkCapabilities);
|
||||
// TODO (b/73132094) : remove this call once the few users of onSuspended and
|
||||
// onResumed have been removed.
|
||||
notifyNetworkCallbacks(networkAgent, (state == NetworkInfo.State.SUSPENDED ?
|
||||
ConnectivityManager.CALLBACK_SUSPENDED :
|
||||
ConnectivityManager.CALLBACK_RESUMED));
|
||||
@@ -5504,14 +5521,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
}
|
||||
|
||||
callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_AVAILABLE, 0);
|
||||
// Whether a network is currently suspended is also an important
|
||||
// element of state to be transferred (it would not otherwise be
|
||||
// delivered by any currently available mechanism).
|
||||
if (nai.networkInfo.getState() == NetworkInfo.State.SUSPENDED) {
|
||||
callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_SUSPENDED, 0);
|
||||
}
|
||||
callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_CAP_CHANGED, 0);
|
||||
callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_IP_CHANGED, 0);
|
||||
}
|
||||
|
||||
private void sendLegacyNetworkBroadcast(NetworkAgentInfo nai, DetailedState state, int type) {
|
||||
|
||||
@@ -392,6 +392,15 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
|
||||
return !isVPN() && numForegroundNetworkRequests() == 0 && mNumBackgroundNetworkRequests > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this network is currently suspended. A network is suspended if it is still
|
||||
* connected but data temporarily fails to transfer. See {@link NetworkInfo.State#SUSPENDED}
|
||||
* and {@link NetworkCapabilities#NET_CAPABILITY_NOT_SUSPENDED}.
|
||||
*/
|
||||
public boolean isSuspended() {
|
||||
return networkInfo.getState() == NetworkInfo.State.SUSPENDED;
|
||||
}
|
||||
|
||||
// Does this network satisfy request?
|
||||
public boolean satisfies(NetworkRequest request) {
|
||||
return created &&
|
||||
@@ -458,7 +467,7 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
|
||||
|
||||
public NetworkState getNetworkState() {
|
||||
synchronized (this) {
|
||||
// Network objects are outwardly immutable so there is no point to duplicating.
|
||||
// Network objects are outwardly immutable so there is no point in duplicating.
|
||||
// Duplicating also precludes sharing socket factories and connection pools.
|
||||
final String subscriberId = (networkMisc != null) ? networkMisc.subscriberId : null;
|
||||
return new NetworkState(new NetworkInfo(networkInfo),
|
||||
|
||||
@@ -38,6 +38,7 @@ import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.anyBoolean;
|
||||
import static org.mockito.Mockito.anyInt;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.timeout;
|
||||
@@ -217,7 +218,8 @@ public class ConnectivityManagerTest {
|
||||
|
||||
// callback triggers
|
||||
captor.getValue().send(makeMessage(request, ConnectivityManager.CALLBACK_AVAILABLE));
|
||||
verify(callback, timeout(500).times(1)).onAvailable(any());
|
||||
verify(callback, timeout(500).times(1)).onAvailable(any(Network.class),
|
||||
any(NetworkCapabilities.class), any(LinkProperties.class));
|
||||
|
||||
// unregister callback
|
||||
manager.unregisterNetworkCallback(callback);
|
||||
@@ -244,7 +246,8 @@ public class ConnectivityManagerTest {
|
||||
|
||||
// callback triggers
|
||||
captor.getValue().send(makeMessage(req1, ConnectivityManager.CALLBACK_AVAILABLE));
|
||||
verify(callback, timeout(100).times(1)).onAvailable(any());
|
||||
verify(callback, timeout(100).times(1)).onAvailable(any(Network.class),
|
||||
any(NetworkCapabilities.class), any(LinkProperties.class));
|
||||
|
||||
// unregister callback
|
||||
manager.unregisterNetworkCallback(callback);
|
||||
@@ -335,6 +338,10 @@ public class ConnectivityManagerTest {
|
||||
static Message makeMessage(NetworkRequest req, int messageType) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putParcelable(NetworkRequest.class.getSimpleName(), req);
|
||||
// Pass default objects as we don't care which get passed here
|
||||
bundle.putParcelable(Network.class.getSimpleName(), new Network(1));
|
||||
bundle.putParcelable(NetworkCapabilities.class.getSimpleName(), new NetworkCapabilities());
|
||||
bundle.putParcelable(LinkProperties.class.getSimpleName(), new LinkProperties());
|
||||
Message msg = Message.obtain();
|
||||
msg.what = messageType;
|
||||
msg.setData(bundle);
|
||||
|
||||
@@ -35,6 +35,7 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_MMS;
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED;
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_RCS;
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_SUPL;
|
||||
@@ -528,6 +529,11 @@ public class ConnectivityServiceTest {
|
||||
mNetworkAgent.sendNetworkInfo(mNetworkInfo);
|
||||
}
|
||||
|
||||
public void resume() {
|
||||
mNetworkInfo.setDetailedState(DetailedState.CONNECTED, null, null);
|
||||
mNetworkAgent.sendNetworkInfo(mNetworkInfo);
|
||||
}
|
||||
|
||||
public void disconnect() {
|
||||
mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null, null);
|
||||
mNetworkAgent.sendNetworkInfo(mNetworkInfo);
|
||||
@@ -569,6 +575,10 @@ public class ConnectivityServiceTest {
|
||||
assertTrue(mNetworkStatusReceived.block(TIMEOUT_MS));
|
||||
return mRedirectUrl;
|
||||
}
|
||||
|
||||
public NetworkCapabilities getNetworkCapabilities() {
|
||||
return mNetworkCapabilities;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1273,6 +1283,7 @@ public class ConnectivityServiceTest {
|
||||
NETWORK_CAPABILITIES,
|
||||
LINK_PROPERTIES,
|
||||
SUSPENDED,
|
||||
RESUMED,
|
||||
LOSING,
|
||||
LOST,
|
||||
UNAVAILABLE
|
||||
@@ -1343,6 +1354,11 @@ public class ConnectivityServiceTest {
|
||||
setLastCallback(CallbackState.SUSPENDED, network, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNetworkResumed(Network network) {
|
||||
setLastCallback(CallbackState.RESUMED, network, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLosing(Network network, int maxMsToLive) {
|
||||
setLastCallback(CallbackState.LOSING, network, maxMsToLive /* autoboxed int */);
|
||||
@@ -2459,16 +2475,31 @@ public class ConnectivityServiceTest {
|
||||
|
||||
// Suspend the network.
|
||||
mCellNetworkAgent.suspend();
|
||||
cellNetworkCallback.expectCapabilitiesWithout(NET_CAPABILITY_NOT_SUSPENDED,
|
||||
mCellNetworkAgent);
|
||||
cellNetworkCallback.expectCallback(CallbackState.SUSPENDED, mCellNetworkAgent);
|
||||
cellNetworkCallback.assertNoCallback();
|
||||
|
||||
// Register a garden variety default network request.
|
||||
final TestNetworkCallback dfltNetworkCallback = new TestNetworkCallback();
|
||||
TestNetworkCallback dfltNetworkCallback = new TestNetworkCallback();
|
||||
mCm.registerDefaultNetworkCallback(dfltNetworkCallback);
|
||||
// We should get onAvailable(), onCapabilitiesChanged(), onLinkPropertiesChanged(),
|
||||
// as well as onNetworkSuspended() in rapid succession.
|
||||
dfltNetworkCallback.expectAvailableAndSuspendedCallbacks(mCellNetworkAgent, true);
|
||||
dfltNetworkCallback.assertNoCallback();
|
||||
mCm.unregisterNetworkCallback(dfltNetworkCallback);
|
||||
|
||||
mCellNetworkAgent.resume();
|
||||
cellNetworkCallback.expectCapabilitiesWith(NET_CAPABILITY_NOT_SUSPENDED,
|
||||
mCellNetworkAgent);
|
||||
cellNetworkCallback.expectCallback(CallbackState.RESUMED, mCellNetworkAgent);
|
||||
cellNetworkCallback.assertNoCallback();
|
||||
|
||||
dfltNetworkCallback = new TestNetworkCallback();
|
||||
mCm.registerDefaultNetworkCallback(dfltNetworkCallback);
|
||||
// This time onNetworkSuspended should not be called.
|
||||
dfltNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent);
|
||||
dfltNetworkCallback.assertNoCallback();
|
||||
|
||||
mCm.unregisterNetworkCallback(dfltNetworkCallback);
|
||||
mCm.unregisterNetworkCallback(cellNetworkCallback);
|
||||
|
||||
Reference in New Issue
Block a user