Support registering a request for the default network
Change-Id: I079f5be97b585cf5692dd4c7a144b993d168a9a5
This commit is contained in:
@@ -2744,7 +2744,9 @@ public class ConnectivityManager {
|
||||
if (networkCallback == null) {
|
||||
throw new IllegalArgumentException("null NetworkCallback");
|
||||
}
|
||||
if (need == null) throw new IllegalArgumentException("null NetworkCapabilities");
|
||||
if (need == null && action != REQUEST) {
|
||||
throw new IllegalArgumentException("null NetworkCapabilities");
|
||||
}
|
||||
try {
|
||||
incCallbackHandlerRefCount();
|
||||
synchronized(sNetworkCallback) {
|
||||
@@ -2767,7 +2769,7 @@ public class ConnectivityManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to requests a network with a particular legacy type.
|
||||
* Helper function to request a network with a particular legacy type.
|
||||
*
|
||||
* This is temporarily public @hide so it can be called by system code that uses the
|
||||
* NetworkRequest API to request networks but relies on CONNECTIVITY_ACTION broadcasts for
|
||||
@@ -3010,6 +3012,28 @@ public class ConnectivityManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers to receive notifications about whichever network currently satisfies the
|
||||
* system default {@link NetworkRequest}. The callbacks will continue to be called until
|
||||
* either the application exits or {@link #unregisterNetworkCallback} is called
|
||||
* <p>This method requires the caller to hold the permission
|
||||
* {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
|
||||
*
|
||||
* @param networkCallback The {@link NetworkCallback} that the system will call as the
|
||||
* system default network changes.
|
||||
* @hide
|
||||
*/
|
||||
public void registerDefaultNetworkCallback(NetworkCallback networkCallback) {
|
||||
// This works because if the NetworkCapabilities are null,
|
||||
// ConnectivityService takes them from the default request.
|
||||
//
|
||||
// Since the capabilities are exactly the same as the default request's
|
||||
// capabilities, this request is guaranteed, at all times, to be
|
||||
// satisfied by the same network, if any, that satisfies the default
|
||||
// request, i.e., the system default network.
|
||||
sendRequestForNetwork(null, networkCallback, 0, REQUEST, TYPE_NONE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests bandwidth update for a given {@link Network} and returns whether the update request
|
||||
* is accepted by ConnectivityService. Once accepted, ConnectivityService will poll underlying
|
||||
|
||||
@@ -3845,8 +3845,16 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
@Override
|
||||
public NetworkRequest requestNetwork(NetworkCapabilities networkCapabilities,
|
||||
Messenger messenger, int timeoutMs, IBinder binder, int legacyType) {
|
||||
networkCapabilities = new NetworkCapabilities(networkCapabilities);
|
||||
enforceNetworkRequestPermissions(networkCapabilities);
|
||||
// If the requested networkCapabilities is null, take them instead from
|
||||
// the default network request. This allows callers to keep track of
|
||||
// the system default network.
|
||||
if (networkCapabilities == null) {
|
||||
networkCapabilities = new NetworkCapabilities(mDefaultRequest.networkCapabilities);
|
||||
enforceAccessPermission();
|
||||
} else {
|
||||
networkCapabilities = new NetworkCapabilities(networkCapabilities);
|
||||
enforceNetworkRequestPermissions(networkCapabilities);
|
||||
}
|
||||
enforceMeteredApnPolicy(networkCapabilities);
|
||||
ensureRequestableCapabilities(networkCapabilities);
|
||||
|
||||
|
||||
@@ -1008,29 +1008,41 @@ public class ConnectivityServiceTest extends AndroidTestCase {
|
||||
private class TestNetworkCallback extends NetworkCallback {
|
||||
private final ConditionVariable mConditionVariable = new ConditionVariable();
|
||||
private CallbackState mLastCallback = CallbackState.NONE;
|
||||
private Network mLastNetwork;
|
||||
|
||||
public void onAvailable(Network network) {
|
||||
assertEquals(CallbackState.NONE, mLastCallback);
|
||||
mLastCallback = CallbackState.AVAILABLE;
|
||||
mLastNetwork = network;
|
||||
mConditionVariable.open();
|
||||
}
|
||||
|
||||
public void onLosing(Network network, int maxMsToLive) {
|
||||
assertEquals(CallbackState.NONE, mLastCallback);
|
||||
mLastCallback = CallbackState.LOSING;
|
||||
mLastNetwork = network;
|
||||
mConditionVariable.open();
|
||||
}
|
||||
|
||||
public void onLost(Network network) {
|
||||
assertEquals(CallbackState.NONE, mLastCallback);
|
||||
mLastCallback = CallbackState.LOST;
|
||||
mLastNetwork = network;
|
||||
mConditionVariable.open();
|
||||
}
|
||||
|
||||
void expectCallback(CallbackState state) {
|
||||
expectCallback(state, null);
|
||||
}
|
||||
|
||||
void expectCallback(CallbackState state, MockNetworkAgent mockAgent) {
|
||||
waitFor(mConditionVariable);
|
||||
assertEquals(state, mLastCallback);
|
||||
if (mockAgent != null) {
|
||||
assertEquals(mockAgent.getNetwork(), mLastNetwork);
|
||||
}
|
||||
mLastCallback = CallbackState.NONE;
|
||||
mLastNetwork = null;
|
||||
mConditionVariable.close();
|
||||
}
|
||||
|
||||
@@ -1389,6 +1401,55 @@ public class ConnectivityServiceTest extends AndroidTestCase {
|
||||
execptionCalled);
|
||||
}
|
||||
|
||||
@LargeTest
|
||||
public void testRegisterDefaultNetworkCallback() throws Exception {
|
||||
final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback();
|
||||
mCm.registerDefaultNetworkCallback(defaultNetworkCallback);
|
||||
defaultNetworkCallback.assertNoCallback();
|
||||
|
||||
// Create a TRANSPORT_CELLULAR request to keep the mobile interface up
|
||||
// whenever Wi-Fi is up. Without this, the mobile network agent is
|
||||
// reaped before any other activity can take place.
|
||||
final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback();
|
||||
final NetworkRequest cellRequest = new NetworkRequest.Builder()
|
||||
.addTransportType(TRANSPORT_CELLULAR).build();
|
||||
mCm.requestNetwork(cellRequest, cellNetworkCallback);
|
||||
cellNetworkCallback.assertNoCallback();
|
||||
|
||||
// Bring up cell and expect CALLBACK_AVAILABLE.
|
||||
mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
|
||||
mCellNetworkAgent.connect(true);
|
||||
cellNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
|
||||
defaultNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
|
||||
|
||||
// Bring up wifi and expect CALLBACK_AVAILABLE.
|
||||
mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
|
||||
mWiFiNetworkAgent.connect(true);
|
||||
cellNetworkCallback.assertNoCallback();
|
||||
defaultNetworkCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
|
||||
|
||||
// Bring down cell. Expect no default network callback, since it wasn't the default.
|
||||
mCellNetworkAgent.disconnect();
|
||||
cellNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
|
||||
defaultNetworkCallback.assertNoCallback();
|
||||
|
||||
// Bring up cell. Expect no default network callback, since it won't be the default.
|
||||
mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
|
||||
mCellNetworkAgent.connect(true);
|
||||
cellNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
|
||||
defaultNetworkCallback.assertNoCallback();
|
||||
|
||||
// Bring down wifi. Expect the default network callback to notified of LOST wifi
|
||||
// followed by AVAILABLE cell.
|
||||
mWiFiNetworkAgent.disconnect();
|
||||
cellNetworkCallback.assertNoCallback();
|
||||
defaultNetworkCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
|
||||
defaultNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
|
||||
mCellNetworkAgent.disconnect();
|
||||
cellNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
|
||||
defaultNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
|
||||
}
|
||||
|
||||
private static class TestKeepaliveCallback extends PacketKeepaliveCallback {
|
||||
|
||||
public static enum CallbackType { ON_STARTED, ON_STOPPED, ON_ERROR };
|
||||
|
||||
Reference in New Issue
Block a user