Merge "[CS] Support "instant failure" from factories"
This commit is contained in:
@@ -3147,9 +3147,9 @@ public class ConnectivityManager {
|
||||
|
||||
/**
|
||||
* Called if no network is found in the timeout time specified in
|
||||
* {@link #requestNetwork(NetworkRequest, NetworkCallback, int)} call. This callback is not
|
||||
* called for the version of {@link #requestNetwork(NetworkRequest, NetworkCallback)}
|
||||
* without timeout. When this callback is invoked the associated
|
||||
* {@link #requestNetwork(NetworkRequest, NetworkCallback, int)} call or if the
|
||||
* requested network request cannot be fulfilled (whether or not a timeout was
|
||||
* specified). When this callback is invoked the associated
|
||||
* {@link NetworkRequest} will have already been removed and released, as if
|
||||
* {@link #unregisterNetworkCallback(NetworkCallback)} had been called.
|
||||
*/
|
||||
|
||||
@@ -1060,7 +1060,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
handleRegisterNetworkRequest(new NetworkRequestInfo(
|
||||
null, networkRequest, new Binder()));
|
||||
} else {
|
||||
handleReleaseNetworkRequest(networkRequest, Process.SYSTEM_UID);
|
||||
handleReleaseNetworkRequest(networkRequest, Process.SYSTEM_UID,
|
||||
/* callOnUnavailable */ false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2641,11 +2642,25 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean maybeHandleNetworkFactoryMessage(Message msg) {
|
||||
switch (msg.what) {
|
||||
default:
|
||||
return false;
|
||||
case NetworkFactory.EVENT_UNFULFILLABLE_REQUEST: {
|
||||
handleReleaseNetworkRequest((NetworkRequest) msg.obj, msg.sendingUid,
|
||||
/* callOnUnavailable */ true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
if (!maybeHandleAsyncChannelMessage(msg) &&
|
||||
!maybeHandleNetworkMonitorMessage(msg) &&
|
||||
!maybeHandleNetworkAgentInfoMessage(msg)) {
|
||||
if (!maybeHandleAsyncChannelMessage(msg)
|
||||
&& !maybeHandleNetworkMonitorMessage(msg)
|
||||
&& !maybeHandleNetworkAgentInfoMessage(msg)
|
||||
&& !maybeHandleNetworkFactoryMessage(msg)) {
|
||||
maybeHandleNetworkAgentMessage(msg);
|
||||
}
|
||||
}
|
||||
@@ -2787,6 +2802,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
if (mNetworkFactoryInfos.containsKey(msg.replyTo)) {
|
||||
if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
|
||||
if (VDBG) log("NetworkFactory connected");
|
||||
// Finish setting up the full connection
|
||||
mNetworkFactoryInfos.get(msg.replyTo).asyncChannel.sendMessage(
|
||||
AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
|
||||
// A network factory has connected. Send it all current NetworkRequests.
|
||||
for (NetworkRequestInfo nri : mNetworkRequests.values()) {
|
||||
if (nri.request.isListen()) continue;
|
||||
@@ -2957,7 +2975,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
if (existingRequest != null) { // remove the existing request.
|
||||
if (DBG) log("Replacing " + existingRequest.request + " with "
|
||||
+ nri.request + " because their intents matched.");
|
||||
handleReleaseNetworkRequest(existingRequest.request, getCallingUid());
|
||||
handleReleaseNetworkRequest(existingRequest.request, getCallingUid(),
|
||||
/* callOnUnavailable */ false);
|
||||
}
|
||||
handleRegisterNetworkRequest(nri);
|
||||
}
|
||||
@@ -2983,7 +3002,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
int callingUid) {
|
||||
NetworkRequestInfo nri = findExistingNetworkRequestInfo(pendingIntent);
|
||||
if (nri != null) {
|
||||
handleReleaseNetworkRequest(nri.request, callingUid);
|
||||
handleReleaseNetworkRequest(nri.request, callingUid, /* callOnUnavailable */ false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3066,7 +3085,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
callCallbackForRequest(nri, null, ConnectivityManager.CALLBACK_UNAVAIL, 0);
|
||||
}
|
||||
|
||||
private void handleReleaseNetworkRequest(NetworkRequest request, int callingUid) {
|
||||
private void handleReleaseNetworkRequest(NetworkRequest request, int callingUid,
|
||||
boolean callOnUnavailable) {
|
||||
final NetworkRequestInfo nri =
|
||||
getNriForAppRequest(request, callingUid, "release NetworkRequest");
|
||||
if (nri == null) {
|
||||
@@ -3076,6 +3096,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
log("releasing " + nri.request + " (release request)");
|
||||
}
|
||||
handleRemoveNetworkRequest(nri);
|
||||
if (callOnUnavailable) {
|
||||
callCallbackForRequest(nri, null, ConnectivityManager.CALLBACK_UNAVAIL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleRemoveNetworkRequest(final NetworkRequestInfo nri) {
|
||||
@@ -3507,7 +3530,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
break;
|
||||
}
|
||||
case EVENT_RELEASE_NETWORK_REQUEST: {
|
||||
handleReleaseNetworkRequest((NetworkRequest) msg.obj, msg.arg1);
|
||||
handleReleaseNetworkRequest((NetworkRequest) msg.obj, msg.arg1,
|
||||
/* callOnUnavailable */ false);
|
||||
break;
|
||||
}
|
||||
case EVENT_SET_ACCEPT_UNVALIDATED: {
|
||||
|
||||
@@ -154,6 +154,7 @@ import android.test.mock.MockContentResolver;
|
||||
import android.text.TextUtils;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import com.android.internal.net.VpnConfig;
|
||||
import com.android.internal.util.ArrayUtils;
|
||||
@@ -748,6 +749,10 @@ public class ConnectivityServiceTest {
|
||||
// mExpectations is non-empty.
|
||||
private boolean mExpectingAdditions;
|
||||
|
||||
// Used to collect the networks requests managed by this factory. This is a duplicate of
|
||||
// the internal information stored in the NetworkFactory (which is private).
|
||||
private SparseArray<NetworkRequest> mNetworkRequests = new SparseArray<>();
|
||||
|
||||
public MockNetworkFactory(Looper looper, Context context, String logTag,
|
||||
NetworkCapabilities filter) {
|
||||
super(looper, context, logTag, filter);
|
||||
@@ -800,6 +805,7 @@ public class ConnectivityServiceTest {
|
||||
}
|
||||
|
||||
// Add the request.
|
||||
mNetworkRequests.put(request.requestId, request);
|
||||
super.handleAddRequest(request, score, factorySerialNumber);
|
||||
mExpectations.notify();
|
||||
}
|
||||
@@ -817,11 +823,17 @@ public class ConnectivityServiceTest {
|
||||
}
|
||||
|
||||
// Remove the request.
|
||||
mNetworkRequests.remove(request.requestId);
|
||||
super.handleRemoveRequest(request);
|
||||
mExpectations.notify();
|
||||
}
|
||||
}
|
||||
|
||||
// Trigger releasing the request as unfulfillable
|
||||
public void triggerUnfulfillable(NetworkRequest r) {
|
||||
super.releaseRequestAsUnfulfillableByAnyFactory(r);
|
||||
}
|
||||
|
||||
private void assertNoExpectations() {
|
||||
if (mExpectations.size() != 0) {
|
||||
fail("Can't add expectation, " + mExpectations.size() + " already pending");
|
||||
@@ -861,9 +873,11 @@ public class ConnectivityServiceTest {
|
||||
assertEquals(msg, 0, count);
|
||||
}
|
||||
|
||||
public void waitForNetworkRequests(final int count) throws InterruptedException {
|
||||
public SparseArray<NetworkRequest> waitForNetworkRequests(final int count)
|
||||
throws InterruptedException {
|
||||
waitForRequests();
|
||||
assertEquals(count, getMyRequestCount());
|
||||
return mNetworkRequests;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3533,6 +3547,55 @@ public class ConnectivityServiceTest {
|
||||
networkCallback.assertNoCallback();
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the callback flow for a factory releasing a request as unfulfillable.
|
||||
*/
|
||||
@Test
|
||||
public void testUnfulfillableNetworkRequest() throws Exception {
|
||||
NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
|
||||
NetworkCapabilities.TRANSPORT_WIFI).build();
|
||||
final TestNetworkCallback networkCallback = new TestNetworkCallback();
|
||||
|
||||
final HandlerThread handlerThread = new HandlerThread("testUnfulfillableNetworkRequest");
|
||||
handlerThread.start();
|
||||
NetworkCapabilities filter = new NetworkCapabilities()
|
||||
.addTransportType(TRANSPORT_WIFI)
|
||||
.addCapability(NET_CAPABILITY_INTERNET);
|
||||
final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(),
|
||||
mServiceContext, "testFactory", filter);
|
||||
testFactory.setScoreFilter(40);
|
||||
|
||||
// Register the factory and expect it to receive the default request.
|
||||
testFactory.expectAddRequestsWithScores(0);
|
||||
testFactory.register();
|
||||
SparseArray<NetworkRequest> requests = testFactory.waitForNetworkRequests(1);
|
||||
|
||||
assertEquals(1, requests.size()); // have 1 request at this point
|
||||
int origRequestId = requests.valueAt(0).requestId;
|
||||
|
||||
// Now file the test request and expect it.
|
||||
testFactory.expectAddRequestsWithScores(0);
|
||||
mCm.requestNetwork(nr, networkCallback);
|
||||
requests = testFactory.waitForNetworkRequests(2); // have 2 requests at this point
|
||||
|
||||
int newRequestId = 0;
|
||||
for (int i = 0; i < requests.size(); ++i) {
|
||||
if (requests.valueAt(i).requestId != origRequestId) {
|
||||
newRequestId = requests.valueAt(i).requestId;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Simulate the factory releasing the request as unfulfillable and expect onUnavailable!
|
||||
testFactory.expectRemoveRequests(1);
|
||||
testFactory.triggerUnfulfillable(requests.get(newRequestId));
|
||||
networkCallback.expectCallback(CallbackState.UNAVAILABLE, null);
|
||||
testFactory.waitForRequests();
|
||||
|
||||
testFactory.unregister();
|
||||
handlerThread.quit();
|
||||
}
|
||||
|
||||
private static class TestKeepaliveCallback extends PacketKeepaliveCallback {
|
||||
|
||||
public static enum CallbackType { ON_STARTED, ON_STOPPED, ON_ERROR };
|
||||
|
||||
Reference in New Issue
Block a user