Merge "[CM] Fix NPE due to unvalidated callback value"

This commit is contained in:
Etan Cohen
2019-05-22 13:53:31 +00:00
committed by Gerrit Code Review
2 changed files with 34 additions and 13 deletions

View File

@@ -3449,6 +3449,11 @@ public class ConnectivityManager {
final NetworkCallback callback; final NetworkCallback callback;
synchronized (sCallbacks) { synchronized (sCallbacks) {
callback = sCallbacks.get(request); callback = sCallbacks.get(request);
if (callback == null) {
Log.w(TAG,
"callback not found for " + getCallbackName(message.what) + " message");
return;
}
if (message.what == CALLBACK_UNAVAIL) { if (message.what == CALLBACK_UNAVAIL) {
sCallbacks.remove(request); sCallbacks.remove(request);
callback.networkRequest = ALREADY_UNREGISTERED; callback.networkRequest = ALREADY_UNREGISTERED;
@@ -3457,10 +3462,6 @@ public class ConnectivityManager {
if (DBG) { if (DBG) {
Log.d(TAG, getCallbackName(message.what) + " for network " + network); Log.d(TAG, getCallbackName(message.what) + " for network " + network);
} }
if (callback == null) {
Log.w(TAG, "callback not found for " + getCallbackName(message.what) + " message");
return;
}
switch (message.what) { switch (message.what) {
case CALLBACK_PRECHECK: { case CALLBACK_PRECHECK: {

View File

@@ -3816,11 +3816,20 @@ public class ConnectivityServiceTest {
networkCallback.assertNoCallback(); networkCallback.assertNoCallback();
} }
@Test
public void testUnfulfillableNetworkRequest() throws Exception {
runUnfulfillableNetworkRequest(false);
}
@Test
public void testUnfulfillableNetworkRequestAfterUnregister() throws Exception {
runUnfulfillableNetworkRequest(true);
}
/** /**
* Validate the callback flow for a factory releasing a request as unfulfillable. * Validate the callback flow for a factory releasing a request as unfulfillable.
*/ */
@Test private void runUnfulfillableNetworkRequest(boolean preUnregister) throws Exception {
public void testUnfulfillableNetworkRequest() throws Exception {
NetworkRequest nr = new NetworkRequest.Builder().addTransportType( NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
NetworkCapabilities.TRANSPORT_WIFI).build(); NetworkCapabilities.TRANSPORT_WIFI).build();
final TestNetworkCallback networkCallback = new TestNetworkCallback(); final TestNetworkCallback networkCallback = new TestNetworkCallback();
@@ -3855,14 +3864,25 @@ public class ConnectivityServiceTest {
} }
} }
if (preUnregister) {
mCm.unregisterNetworkCallback(networkCallback);
// Simulate the factory releasing the request as unfulfillable: no-op since
// the callback has already been unregistered (but a test that no exceptions are
// thrown).
testFactory.triggerUnfulfillable(requests.get(newRequestId));
} else {
// Simulate the factory releasing the request as unfulfillable and expect onUnavailable! // Simulate the factory releasing the request as unfulfillable and expect onUnavailable!
testFactory.expectRemoveRequests(1); testFactory.expectRemoveRequests(1);
testFactory.triggerUnfulfillable(requests.get(newRequestId)); testFactory.triggerUnfulfillable(requests.get(newRequestId));
networkCallback.expectCallback(CallbackState.UNAVAILABLE, null); networkCallback.expectCallback(CallbackState.UNAVAILABLE, null);
testFactory.waitForRequests(); testFactory.waitForRequests();
// unregister network callback - a no-op, but should not fail // unregister network callback - a no-op (since already freed by the
// on-unavailable), but should not fail or throw exceptions.
mCm.unregisterNetworkCallback(networkCallback); mCm.unregisterNetworkCallback(networkCallback);
}
testFactory.unregister(); testFactory.unregister();
handlerThread.quit(); handlerThread.quit();