Support registering a request for the default network

Change-Id: I079f5be97b585cf5692dd4c7a144b993d168a9a5
This commit is contained in:
Erik Kline
2016-03-16 15:31:39 +09:00
parent d8332d1a1b
commit 23bf99c956
3 changed files with 97 additions and 4 deletions

View File

@@ -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

View File

@@ -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);

View File

@@ -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 };