Support requesting async LinkProperties/NetworkCapabilities updates
Bug: 9580643 Change-Id: I1d7ba7645c20d7d53f6eef777dfce43727940f13
This commit is contained in:
@@ -1034,6 +1034,26 @@ public class ConnectivityManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request that this callback be invoked at ConnectivityService's earliest
|
||||||
|
* convenience with the current satisfying network's LinkProperties.
|
||||||
|
* If no such network exists no callback invocation is performed.
|
||||||
|
*
|
||||||
|
* The callback must have been registered with #requestNetwork() or
|
||||||
|
* #registerDefaultNetworkCallback(); callbacks registered with
|
||||||
|
* registerNetworkCallback() are not specific to any particular Network so
|
||||||
|
* do not cause any updates.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public void requestLinkProperties(NetworkCallback networkCallback) {
|
||||||
|
try {
|
||||||
|
mService.requestLinkProperties(networkCallback.networkRequest);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
throw e.rethrowFromSystemServer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the {@link android.net.NetworkCapabilities} for the given {@link Network}. This
|
* Get the {@link android.net.NetworkCapabilities} for the given {@link Network}. This
|
||||||
* will return {@code null} if the network is unknown.
|
* will return {@code null} if the network is unknown.
|
||||||
@@ -1051,6 +1071,26 @@ public class ConnectivityManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request that this callback be invoked at ConnectivityService's earliest
|
||||||
|
* convenience with the current satisfying network's NetworkCapabilities.
|
||||||
|
* If no such network exists no callback invocation is performed.
|
||||||
|
*
|
||||||
|
* The callback must have been registered with #requestNetwork() or
|
||||||
|
* #registerDefaultNetworkCallback(); callbacks registered with
|
||||||
|
* registerNetworkCallback() are not specific to any particular Network so
|
||||||
|
* do not cause any updates.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public void requestNetworkCapabilities(NetworkCallback networkCallback) {
|
||||||
|
try {
|
||||||
|
mService.requestNetworkCapabilities(networkCallback.networkRequest);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
throw e.rethrowFromSystemServer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the URL that should be used for resolving whether a captive portal is present.
|
* Gets the URL that should be used for resolving whether a captive portal is present.
|
||||||
* 1. This URL should respond with a 204 response to a GET request to indicate no captive
|
* 1. This URL should respond with a 204 response to a GET request to indicate no captive
|
||||||
|
|||||||
@@ -156,6 +156,8 @@ interface IConnectivityManager
|
|||||||
void pendingListenForNetwork(in NetworkCapabilities networkCapabilities,
|
void pendingListenForNetwork(in NetworkCapabilities networkCapabilities,
|
||||||
in PendingIntent operation);
|
in PendingIntent operation);
|
||||||
|
|
||||||
|
void requestLinkProperties(in NetworkRequest networkRequest);
|
||||||
|
void requestNetworkCapabilities(in NetworkRequest networkRequest);
|
||||||
void releaseNetworkRequest(in NetworkRequest networkRequest);
|
void releaseNetworkRequest(in NetworkRequest networkRequest);
|
||||||
|
|
||||||
void setAcceptUnvalidated(in Network network, boolean accept, boolean always);
|
void setAcceptUnvalidated(in Network network, boolean accept, boolean always);
|
||||||
|
|||||||
@@ -303,7 +303,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* indicates a timeout period is over - check if we had a network yet or not
|
* indicates a timeout period is over - check if we had a network yet or not
|
||||||
* and if not, call the timeout calback (but leave the request live until they
|
* and if not, call the timeout callback (but leave the request live until they
|
||||||
* cancel it.
|
* cancel it.
|
||||||
* includes a NetworkRequestInfo
|
* includes a NetworkRequestInfo
|
||||||
*/
|
*/
|
||||||
@@ -380,6 +380,16 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
*/
|
*/
|
||||||
private static final int EVENT_REGISTER_NETWORK_LISTENER_WITH_INTENT = 31;
|
private static final int EVENT_REGISTER_NETWORK_LISTENER_WITH_INTENT = 31;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates a caller has requested to have its callback invoked with
|
||||||
|
* the latest LinkProperties or NetworkCapabilities.
|
||||||
|
*
|
||||||
|
* arg1 = UID of caller
|
||||||
|
* obj = NetworkRequest
|
||||||
|
*/
|
||||||
|
private static final int EVENT_REQUEST_LINKPROPERTIES = 32;
|
||||||
|
private static final int EVENT_REQUEST_NETCAPABILITIES = 33;
|
||||||
|
|
||||||
/** Handler thread used for both of the handlers below. */
|
/** Handler thread used for both of the handlers below. */
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
protected final HandlerThread mHandlerThread;
|
protected final HandlerThread mHandlerThread;
|
||||||
@@ -2447,106 +2457,146 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleReleaseNetworkRequest(NetworkRequest request, int callingUid) {
|
private NetworkRequestInfo getNriForAppRequest(
|
||||||
NetworkRequestInfo nri = mNetworkRequests.get(request);
|
NetworkRequest request, int callingUid, String requestedOperation) {
|
||||||
|
final NetworkRequestInfo nri = mNetworkRequests.get(request);
|
||||||
|
|
||||||
if (nri != null) {
|
if (nri != null) {
|
||||||
if (Process.SYSTEM_UID != callingUid && nri.mUid != callingUid) {
|
if (Process.SYSTEM_UID != callingUid && nri.mUid != callingUid) {
|
||||||
if (DBG) log("Attempt to release unowned NetworkRequest " + request);
|
log(String.format("UID %d attempted to %s for unowned request %s",
|
||||||
return;
|
callingUid, requestedOperation, nri));
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
if (VDBG || (DBG && nri.request.isRequest())) log("releasing " + request);
|
}
|
||||||
nri.unlinkDeathRecipient();
|
|
||||||
mNetworkRequests.remove(request);
|
return nri;
|
||||||
synchronized (mUidToNetworkRequestCount) {
|
}
|
||||||
int requests = mUidToNetworkRequestCount.get(nri.mUid, 0);
|
|
||||||
if (requests < 1) {
|
private void handleRequestCallbackUpdate(NetworkRequest request, int callingUid,
|
||||||
Slog.wtf(TAG, "BUG: too small request count " + requests + " for UID " +
|
String description, int callbackType) {
|
||||||
nri.mUid);
|
final NetworkRequestInfo nri = getNriForAppRequest(request, callingUid, description);
|
||||||
} else if (requests == 1) {
|
if (nri == null) return;
|
||||||
mUidToNetworkRequestCount.removeAt(
|
|
||||||
mUidToNetworkRequestCount.indexOfKey(nri.mUid));
|
final NetworkAgentInfo nai = mNetworkForRequestId.get(nri.request.requestId);
|
||||||
|
// The network that is satisfying this request may have changed since
|
||||||
|
// the application requested the update.
|
||||||
|
//
|
||||||
|
// - If the request is no longer satisfied, don't send any updates.
|
||||||
|
// - If the request is satisfied by a different network, it is the
|
||||||
|
// caller's responsibility to check that the Network object in the
|
||||||
|
// callback matches the network that was returned in the last
|
||||||
|
// onAvailable() callback for this request.
|
||||||
|
if (nai == null) return;
|
||||||
|
callCallbackForRequest(nri, nai, callbackType, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleRequestLinkProperties(NetworkRequest request, int callingUid) {
|
||||||
|
handleRequestCallbackUpdate(request, callingUid,
|
||||||
|
"request LinkProperties", ConnectivityManager.CALLBACK_IP_CHANGED);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleRequestNetworkCapabilities(NetworkRequest request, int callingUid) {
|
||||||
|
handleRequestCallbackUpdate(request, callingUid,
|
||||||
|
"request NetworkCapabilities", ConnectivityManager.CALLBACK_CAP_CHANGED);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleReleaseNetworkRequest(NetworkRequest request, int callingUid) {
|
||||||
|
final NetworkRequestInfo nri = getNriForAppRequest(
|
||||||
|
request, callingUid, "release NetworkRequest");
|
||||||
|
if (nri == null) return;
|
||||||
|
|
||||||
|
if (VDBG || (DBG && nri.request.isRequest())) log("releasing " + request);
|
||||||
|
nri.unlinkDeathRecipient();
|
||||||
|
mNetworkRequests.remove(request);
|
||||||
|
synchronized (mUidToNetworkRequestCount) {
|
||||||
|
int requests = mUidToNetworkRequestCount.get(nri.mUid, 0);
|
||||||
|
if (requests < 1) {
|
||||||
|
Slog.wtf(TAG, "BUG: too small request count " + requests + " for UID " +
|
||||||
|
nri.mUid);
|
||||||
|
} else if (requests == 1) {
|
||||||
|
mUidToNetworkRequestCount.removeAt(
|
||||||
|
mUidToNetworkRequestCount.indexOfKey(nri.mUid));
|
||||||
|
} else {
|
||||||
|
mUidToNetworkRequestCount.put(nri.mUid, requests - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mNetworkRequestInfoLogs.log("RELEASE " + nri);
|
||||||
|
if (nri.request.isRequest()) {
|
||||||
|
boolean wasKept = false;
|
||||||
|
NetworkAgentInfo nai = mNetworkForRequestId.get(nri.request.requestId);
|
||||||
|
if (nai != null) {
|
||||||
|
nai.removeRequest(nri.request.requestId);
|
||||||
|
if (VDBG) {
|
||||||
|
log(" Removing from current network " + nai.name() +
|
||||||
|
", leaving " + nai.numNetworkRequests() + " requests.");
|
||||||
|
}
|
||||||
|
// If there are still lingered requests on this network, don't tear it down,
|
||||||
|
// but resume lingering instead.
|
||||||
|
updateLingerState(nai, SystemClock.elapsedRealtime());
|
||||||
|
if (unneeded(nai)) {
|
||||||
|
if (DBG) log("no live requests for " + nai.name() + "; disconnecting");
|
||||||
|
teardownUnneededNetwork(nai);
|
||||||
} else {
|
} else {
|
||||||
mUidToNetworkRequestCount.put(nri.mUid, requests - 1);
|
wasKept = true;
|
||||||
|
}
|
||||||
|
mNetworkForRequestId.remove(nri.request.requestId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: remove this code once we know that the Slog.wtf is never hit.
|
||||||
|
//
|
||||||
|
// Find all networks that are satisfying this request and remove the request
|
||||||
|
// from their request lists.
|
||||||
|
// TODO - it's my understanding that for a request there is only a single
|
||||||
|
// network satisfying it, so this loop is wasteful
|
||||||
|
for (NetworkAgentInfo otherNai : mNetworkAgentInfos.values()) {
|
||||||
|
if (otherNai.isSatisfyingRequest(nri.request.requestId) && otherNai != nai) {
|
||||||
|
Slog.wtf(TAG, "Request " + nri.request + " satisfied by " +
|
||||||
|
otherNai.name() + ", but mNetworkAgentInfos says " +
|
||||||
|
(nai != null ? nai.name() : "null"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mNetworkRequestInfoLogs.log("RELEASE " + nri);
|
|
||||||
if (nri.request.isRequest()) {
|
|
||||||
boolean wasKept = false;
|
|
||||||
NetworkAgentInfo nai = mNetworkForRequestId.get(nri.request.requestId);
|
|
||||||
if (nai != null) {
|
|
||||||
nai.removeRequest(nri.request.requestId);
|
|
||||||
if (VDBG) {
|
|
||||||
log(" Removing from current network " + nai.name() +
|
|
||||||
", leaving " + nai.numNetworkRequests() + " requests.");
|
|
||||||
}
|
|
||||||
// If there are still lingered requests on this network, don't tear it down,
|
|
||||||
// but resume lingering instead.
|
|
||||||
updateLingerState(nai, SystemClock.elapsedRealtime());
|
|
||||||
if (unneeded(nai)) {
|
|
||||||
if (DBG) log("no live requests for " + nai.name() + "; disconnecting");
|
|
||||||
teardownUnneededNetwork(nai);
|
|
||||||
} else {
|
|
||||||
wasKept = true;
|
|
||||||
}
|
|
||||||
mNetworkForRequestId.remove(nri.request.requestId);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: remove this code once we know that the Slog.wtf is never hit.
|
// Maintain the illusion. When this request arrived, we might have pretended
|
||||||
//
|
// that a network connected to serve it, even though the network was already
|
||||||
// Find all networks that are satisfying this request and remove the request
|
// connected. Now that this request has gone away, we might have to pretend
|
||||||
// from their request lists.
|
// that the network disconnected. LegacyTypeTracker will generate that
|
||||||
// TODO - it's my understanding that for a request there is only a single
|
// phantom disconnect for this type.
|
||||||
// network satisfying it, so this loop is wasteful
|
if (nri.request.legacyType != TYPE_NONE && nai != null) {
|
||||||
for (NetworkAgentInfo otherNai : mNetworkAgentInfos.values()) {
|
boolean doRemove = true;
|
||||||
if (otherNai.isSatisfyingRequest(nri.request.requestId) && otherNai != nai) {
|
if (wasKept) {
|
||||||
Slog.wtf(TAG, "Request " + nri.request + " satisfied by " +
|
// check if any of the remaining requests for this network are for the
|
||||||
otherNai.name() + ", but mNetworkAgentInfos says " +
|
// same legacy type - if so, don't remove the nai
|
||||||
(nai != null ? nai.name() : "null"));
|
for (int i = 0; i < nai.numNetworkRequests(); i++) {
|
||||||
}
|
NetworkRequest otherRequest = nai.requestAt(i);
|
||||||
}
|
if (otherRequest.legacyType == nri.request.legacyType &&
|
||||||
|
otherRequest.isRequest()) {
|
||||||
// Maintain the illusion. When this request arrived, we might have pretended
|
if (DBG) log(" still have other legacy request - leaving");
|
||||||
// that a network connected to serve it, even though the network was already
|
doRemove = false;
|
||||||
// connected. Now that this request has gone away, we might have to pretend
|
|
||||||
// that the network disconnected. LegacyTypeTracker will generate that
|
|
||||||
// phantom disconnect for this type.
|
|
||||||
if (nri.request.legacyType != TYPE_NONE && nai != null) {
|
|
||||||
boolean doRemove = true;
|
|
||||||
if (wasKept) {
|
|
||||||
// check if any of the remaining requests for this network are for the
|
|
||||||
// same legacy type - if so, don't remove the nai
|
|
||||||
for (int i = 0; i < nai.numNetworkRequests(); i++) {
|
|
||||||
NetworkRequest otherRequest = nai.requestAt(i);
|
|
||||||
if (otherRequest.legacyType == nri.request.legacyType &&
|
|
||||||
otherRequest.isRequest()) {
|
|
||||||
if (DBG) log(" still have other legacy request - leaving");
|
|
||||||
doRemove = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (doRemove) {
|
|
||||||
mLegacyTypeTracker.remove(nri.request.legacyType, nai, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) {
|
if (doRemove) {
|
||||||
nfi.asyncChannel.sendMessage(android.net.NetworkFactory.CMD_CANCEL_REQUEST,
|
mLegacyTypeTracker.remove(nri.request.legacyType, nai, false);
|
||||||
nri.request);
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// listens don't have a singular affectedNetwork. Check all networks to see
|
for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) {
|
||||||
// if this listen request applies and remove it.
|
nfi.asyncChannel.sendMessage(android.net.NetworkFactory.CMD_CANCEL_REQUEST,
|
||||||
for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
|
nri.request);
|
||||||
nai.removeRequest(nri.request.requestId);
|
}
|
||||||
if (nri.request.networkCapabilities.hasSignalStrength() &&
|
} else {
|
||||||
nai.satisfiesImmutableCapabilitiesOf(nri.request)) {
|
// listens don't have a singular affectedNetwork. Check all networks to see
|
||||||
updateSignalStrengthThresholds(nai, "RELEASE", nri.request);
|
// if this listen request applies and remove it.
|
||||||
}
|
for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
|
||||||
|
nai.removeRequest(nri.request.requestId);
|
||||||
|
if (nri.request.networkCapabilities.hasSignalStrength() &&
|
||||||
|
nai.satisfiesImmutableCapabilitiesOf(nri.request)) {
|
||||||
|
updateSignalStrengthThresholds(nai, "RELEASE", nri.request);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
callCallbackForRequest(nri, null, ConnectivityManager.CALLBACK_RELEASED, 0);
|
|
||||||
}
|
}
|
||||||
|
callCallbackForRequest(nri, null, ConnectivityManager.CALLBACK_RELEASED, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -2709,6 +2759,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
handleMobileDataAlwaysOn();
|
handleMobileDataAlwaysOn();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case EVENT_REQUEST_LINKPROPERTIES:
|
||||||
|
handleRequestLinkProperties((NetworkRequest) msg.obj, msg.arg1);
|
||||||
|
break;
|
||||||
|
case EVENT_REQUEST_NETCAPABILITIES:
|
||||||
|
handleRequestNetworkCapabilities((NetworkRequest) msg.obj, msg.arg1);
|
||||||
|
break;
|
||||||
// Sent by KeepaliveTracker to process an app request on the state machine thread.
|
// Sent by KeepaliveTracker to process an app request on the state machine thread.
|
||||||
case NetworkAgent.CMD_START_PACKET_KEEPALIVE: {
|
case NetworkAgent.CMD_START_PACKET_KEEPALIVE: {
|
||||||
mKeepaliveTracker.handleStartKeepalive(msg);
|
mKeepaliveTracker.handleStartKeepalive(msg);
|
||||||
@@ -4169,11 +4225,27 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_LISTENER, nri));
|
mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_LISTENER, nri));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void requestLinkProperties(NetworkRequest networkRequest) {
|
||||||
|
ensureNetworkRequestHasType(networkRequest);
|
||||||
|
if (networkRequest.type == NetworkRequest.Type.LISTEN) return;
|
||||||
|
mHandler.sendMessage(mHandler.obtainMessage(
|
||||||
|
EVENT_REQUEST_LINKPROPERTIES, getCallingUid(), 0, networkRequest));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void requestNetworkCapabilities(NetworkRequest networkRequest) {
|
||||||
|
ensureNetworkRequestHasType(networkRequest);
|
||||||
|
if (networkRequest.type == NetworkRequest.Type.LISTEN) return;
|
||||||
|
mHandler.sendMessage(mHandler.obtainMessage(
|
||||||
|
EVENT_REQUEST_NETCAPABILITIES, getCallingUid(), 0, networkRequest));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void releaseNetworkRequest(NetworkRequest networkRequest) {
|
public void releaseNetworkRequest(NetworkRequest networkRequest) {
|
||||||
ensureNetworkRequestHasType(networkRequest);
|
ensureNetworkRequestHasType(networkRequest);
|
||||||
mHandler.sendMessage(mHandler.obtainMessage(EVENT_RELEASE_NETWORK_REQUEST, getCallingUid(),
|
mHandler.sendMessage(mHandler.obtainMessage(
|
||||||
0, networkRequest));
|
EVENT_RELEASE_NETWORK_REQUEST, getCallingUid(), 0, networkRequest));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1040,6 +1040,8 @@ public class ConnectivityServiceTest extends AndroidTestCase {
|
|||||||
enum CallbackState {
|
enum CallbackState {
|
||||||
NONE,
|
NONE,
|
||||||
AVAILABLE,
|
AVAILABLE,
|
||||||
|
NETWORK_CAPABILITIES,
|
||||||
|
LINK_PROPERTIES,
|
||||||
LOSING,
|
LOSING,
|
||||||
LOST
|
LOST
|
||||||
}
|
}
|
||||||
@@ -1072,18 +1074,21 @@ public class ConnectivityServiceTest extends AndroidTestCase {
|
|||||||
}
|
}
|
||||||
private final LinkedBlockingQueue<CallbackInfo> mCallbacks = new LinkedBlockingQueue<>();
|
private final LinkedBlockingQueue<CallbackInfo> mCallbacks = new LinkedBlockingQueue<>();
|
||||||
|
|
||||||
private void setLastCallback(CallbackState state, Network network, Object o) {
|
protected void setLastCallback(CallbackState state, Network network, Object o) {
|
||||||
mCallbacks.offer(new CallbackInfo(state, network, o));
|
mCallbacks.offer(new CallbackInfo(state, network, o));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void onAvailable(Network network) {
|
public void onAvailable(Network network) {
|
||||||
setLastCallback(CallbackState.AVAILABLE, network, null);
|
setLastCallback(CallbackState.AVAILABLE, network, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void onLosing(Network network, int maxMsToLive) {
|
public void onLosing(Network network, int maxMsToLive) {
|
||||||
setLastCallback(CallbackState.LOSING, network, maxMsToLive /* autoboxed int */);
|
setLastCallback(CallbackState.LOSING, network, maxMsToLive /* autoboxed int */);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void onLost(Network network) {
|
public void onLost(Network network) {
|
||||||
setLastCallback(CallbackState.LOST, network, null);
|
setLastCallback(CallbackState.LOST, network, null);
|
||||||
}
|
}
|
||||||
@@ -1744,6 +1749,67 @@ public class ConnectivityServiceTest extends AndroidTestCase {
|
|||||||
defaultNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
|
defaultNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class TestRequestUpdateCallback extends TestNetworkCallback {
|
||||||
|
@Override
|
||||||
|
public void onCapabilitiesChanged(Network network, NetworkCapabilities netCap) {
|
||||||
|
setLastCallback(CallbackState.NETWORK_CAPABILITIES, network, netCap);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLinkPropertiesChanged(Network network, LinkProperties linkProp) {
|
||||||
|
setLastCallback(CallbackState.LINK_PROPERTIES, network, linkProp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@LargeTest
|
||||||
|
public void testRequestCallbackUpdates() throws Exception {
|
||||||
|
// File a network request for mobile.
|
||||||
|
final TestNetworkCallback cellNetworkCallback = new TestRequestUpdateCallback();
|
||||||
|
final NetworkRequest cellRequest = new NetworkRequest.Builder()
|
||||||
|
.addTransportType(TRANSPORT_CELLULAR).build();
|
||||||
|
mCm.requestNetwork(cellRequest, cellNetworkCallback);
|
||||||
|
|
||||||
|
// Bring up the mobile network.
|
||||||
|
mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
|
||||||
|
mCellNetworkAgent.connect(true);
|
||||||
|
|
||||||
|
// We should get onAvailable().
|
||||||
|
cellNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
|
||||||
|
// We should get onCapabilitiesChanged(), when the mobile network successfully validates.
|
||||||
|
cellNetworkCallback.expectCallback(CallbackState.NETWORK_CAPABILITIES, mCellNetworkAgent);
|
||||||
|
cellNetworkCallback.assertNoCallback();
|
||||||
|
|
||||||
|
// Update LinkProperties.
|
||||||
|
final LinkProperties lp = new LinkProperties();
|
||||||
|
lp.setInterfaceName("foonet_data0");
|
||||||
|
mCellNetworkAgent.sendLinkProperties(lp);
|
||||||
|
// We should get onLinkPropertiesChanged().
|
||||||
|
cellNetworkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
|
||||||
|
cellNetworkCallback.assertNoCallback();
|
||||||
|
|
||||||
|
// Register a garden variety default network request.
|
||||||
|
final TestNetworkCallback dfltNetworkCallback = new TestRequestUpdateCallback();
|
||||||
|
mCm.registerDefaultNetworkCallback(dfltNetworkCallback);
|
||||||
|
// Only onAvailable() is called; no other information is delivered.
|
||||||
|
dfltNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
|
||||||
|
dfltNetworkCallback.assertNoCallback();
|
||||||
|
|
||||||
|
// Request a NetworkCapabilities update; only the requesting callback is notified.
|
||||||
|
mCm.requestNetworkCapabilities(dfltNetworkCallback);
|
||||||
|
dfltNetworkCallback.expectCallback(CallbackState.NETWORK_CAPABILITIES, mCellNetworkAgent);
|
||||||
|
cellNetworkCallback.assertNoCallback();
|
||||||
|
dfltNetworkCallback.assertNoCallback();
|
||||||
|
|
||||||
|
// Request a LinkProperties update; only the requesting callback is notified.
|
||||||
|
mCm.requestLinkProperties(dfltNetworkCallback);
|
||||||
|
dfltNetworkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
|
||||||
|
cellNetworkCallback.assertNoCallback();
|
||||||
|
dfltNetworkCallback.assertNoCallback();
|
||||||
|
|
||||||
|
mCm.unregisterNetworkCallback(dfltNetworkCallback);
|
||||||
|
mCm.unregisterNetworkCallback(cellNetworkCallback);
|
||||||
|
}
|
||||||
|
|
||||||
@SmallTest
|
@SmallTest
|
||||||
public void testRequestBenchmark() throws Exception {
|
public void testRequestBenchmark() throws Exception {
|
||||||
// Benchmarks connecting and switching performance in the presence of a large number of
|
// Benchmarks connecting and switching performance in the presence of a large number of
|
||||||
|
|||||||
Reference in New Issue
Block a user