Merge "Update UpstreamNetworkMonitor to use custom Handlers"
am: 35c89886c2
Change-Id: I76433822a9b7c124e4b7cfcf2a20cb0e43a60199
This commit is contained in:
@@ -2930,15 +2930,6 @@ public class ConnectivityManager {
|
|||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public void requestNetwork(NetworkRequest request, NetworkCallback networkCallback,
|
public void requestNetwork(NetworkRequest request, NetworkCallback networkCallback,
|
||||||
int timeoutMs, int legacyType) {
|
|
||||||
requestNetwork(request, networkCallback, timeoutMs, legacyType, getDefaultHandler());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper function to request a network with a particular legacy type.
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
private void requestNetwork(NetworkRequest request, NetworkCallback networkCallback,
|
|
||||||
int timeoutMs, int legacyType, Handler handler) {
|
int timeoutMs, int legacyType, Handler handler) {
|
||||||
CallbackHandler cbHandler = new CallbackHandler(handler);
|
CallbackHandler cbHandler = new CallbackHandler(handler);
|
||||||
NetworkCapabilities nc = request.networkCapabilities;
|
NetworkCapabilities nc = request.networkCapabilities;
|
||||||
@@ -3040,7 +3031,7 @@ public class ConnectivityManager {
|
|||||||
public void requestNetwork(NetworkRequest request, NetworkCallback networkCallback,
|
public void requestNetwork(NetworkRequest request, NetworkCallback networkCallback,
|
||||||
int timeoutMs) {
|
int timeoutMs) {
|
||||||
int legacyType = inferLegacyTypeForNetworkCapabilities(request.networkCapabilities);
|
int legacyType = inferLegacyTypeForNetworkCapabilities(request.networkCapabilities);
|
||||||
requestNetwork(request, networkCallback, timeoutMs, legacyType);
|
requestNetwork(request, networkCallback, timeoutMs, legacyType, getDefaultHandler());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ import static android.net.ConnectivityManager.TYPE_MOBILE_DUN;
|
|||||||
import static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI;
|
import static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
import android.net.ConnectivityManager.NetworkCallback;
|
import android.net.ConnectivityManager.NetworkCallback;
|
||||||
import android.net.LinkProperties;
|
import android.net.LinkProperties;
|
||||||
@@ -72,6 +74,7 @@ public class UpstreamNetworkMonitor {
|
|||||||
|
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private final StateMachine mTarget;
|
private final StateMachine mTarget;
|
||||||
|
private final Handler mHandler;
|
||||||
private final int mWhat;
|
private final int mWhat;
|
||||||
private final HashMap<Network, NetworkState> mNetworkMap = new HashMap<>();
|
private final HashMap<Network, NetworkState> mNetworkMap = new HashMap<>();
|
||||||
private ConnectivityManager mCM;
|
private ConnectivityManager mCM;
|
||||||
@@ -84,6 +87,7 @@ public class UpstreamNetworkMonitor {
|
|||||||
public UpstreamNetworkMonitor(Context ctx, StateMachine tgt, int what) {
|
public UpstreamNetworkMonitor(Context ctx, StateMachine tgt, int what) {
|
||||||
mContext = ctx;
|
mContext = ctx;
|
||||||
mTarget = tgt;
|
mTarget = tgt;
|
||||||
|
mHandler = mTarget.getHandler();
|
||||||
mWhat = what;
|
mWhat = what;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,10 +103,10 @@ public class UpstreamNetworkMonitor {
|
|||||||
final NetworkRequest listenAllRequest = new NetworkRequest.Builder()
|
final NetworkRequest listenAllRequest = new NetworkRequest.Builder()
|
||||||
.clearCapabilities().build();
|
.clearCapabilities().build();
|
||||||
mListenAllCallback = new UpstreamNetworkCallback(CALLBACK_LISTEN_ALL);
|
mListenAllCallback = new UpstreamNetworkCallback(CALLBACK_LISTEN_ALL);
|
||||||
cm().registerNetworkCallback(listenAllRequest, mListenAllCallback);
|
cm().registerNetworkCallback(listenAllRequest, mListenAllCallback, mHandler);
|
||||||
|
|
||||||
mDefaultNetworkCallback = new UpstreamNetworkCallback(CALLBACK_TRACK_DEFAULT);
|
mDefaultNetworkCallback = new UpstreamNetworkCallback(CALLBACK_TRACK_DEFAULT);
|
||||||
cm().registerDefaultNetworkCallback(mDefaultNetworkCallback);
|
cm().registerDefaultNetworkCallback(mDefaultNetworkCallback, mHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stop() {
|
public void stop() {
|
||||||
@@ -154,7 +158,7 @@ public class UpstreamNetworkMonitor {
|
|||||||
// Additionally, we log a message to aid in any subsequent debugging.
|
// Additionally, we log a message to aid in any subsequent debugging.
|
||||||
Log.d(TAG, "requesting mobile upstream network: " + mobileUpstreamRequest);
|
Log.d(TAG, "requesting mobile upstream network: " + mobileUpstreamRequest);
|
||||||
|
|
||||||
cm().requestNetwork(mobileUpstreamRequest, mMobileNetworkCallback, 0, legacyType);
|
cm().requestNetwork(mobileUpstreamRequest, mMobileNetworkCallback, 0, legacyType, mHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void releaseMobileNetworkRequest() {
|
public void releaseMobileNetworkRequest() {
|
||||||
@@ -185,11 +189,13 @@ public class UpstreamNetworkMonitor {
|
|||||||
case CALLBACK_TRACK_DEFAULT:
|
case CALLBACK_TRACK_DEFAULT:
|
||||||
if (mDefaultNetworkCallback == null) {
|
if (mDefaultNetworkCallback == null) {
|
||||||
// The callback was unregistered in the interval between
|
// The callback was unregistered in the interval between
|
||||||
// ConnectivityService calling onAvailable() and our
|
// ConnectivityService enqueueing onAvailable() and our
|
||||||
// handling of it here on the mTarget.getHandler() thread.
|
// handling of it here on the mHandler thread.
|
||||||
|
//
|
||||||
// Clean-up of this network entry is deferred to the
|
// Clean-up of this network entry is deferred to the
|
||||||
// handling of onLost() by other callbacks.
|
// handling of onLost() by other callbacks.
|
||||||
// TODO: change to Log.wtf() after oag/331764 is merged.
|
//
|
||||||
|
// These request*() calls can be deleted post oag/339444.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,11 +206,13 @@ public class UpstreamNetworkMonitor {
|
|||||||
case CALLBACK_MOBILE_REQUEST:
|
case CALLBACK_MOBILE_REQUEST:
|
||||||
if (mMobileNetworkCallback == null) {
|
if (mMobileNetworkCallback == null) {
|
||||||
// The callback was unregistered in the interval between
|
// The callback was unregistered in the interval between
|
||||||
// ConnectivityService calling onAvailable() and our
|
// ConnectivityService enqueueing onAvailable() and our
|
||||||
// handling of it here on the mTarget.getHandler() thread.
|
// handling of it here on the mHandler thread.
|
||||||
|
//
|
||||||
// Clean-up of this network entry is deferred to the
|
// Clean-up of this network entry is deferred to the
|
||||||
// handling of onLost() by other callbacks.
|
// handling of onLost() by other callbacks.
|
||||||
// TODO: change to Log.wtf() after oag/331764 is merged.
|
//
|
||||||
|
// These request*() calls can be deleted post oag/339444.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -312,8 +320,9 @@ public class UpstreamNetworkMonitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A NetworkCallback class that relays information of interest to the
|
* A NetworkCallback class that handles information of interest directly
|
||||||
* tethering master state machine thread for subsequent processing.
|
* in the thread on which it is invoked. To avoid locking, this MUST be
|
||||||
|
* run on the same thread as the target state machine's handler.
|
||||||
*/
|
*/
|
||||||
private class UpstreamNetworkCallback extends NetworkCallback {
|
private class UpstreamNetworkCallback extends NetworkCallback {
|
||||||
private final int mCallbackType;
|
private final int mCallbackType;
|
||||||
@@ -324,22 +333,35 @@ public class UpstreamNetworkMonitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAvailable(Network network) {
|
public void onAvailable(Network network) {
|
||||||
mTarget.getHandler().post(() -> handleAvailable(mCallbackType, network));
|
checkExpectedThread();
|
||||||
|
handleAvailable(mCallbackType, network);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCapabilitiesChanged(Network network, NetworkCapabilities newNc) {
|
public void onCapabilitiesChanged(Network network, NetworkCapabilities newNc) {
|
||||||
mTarget.getHandler().post(() -> handleNetCap(network, newNc));
|
checkExpectedThread();
|
||||||
|
handleNetCap(network, newNc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLinkPropertiesChanged(Network network, LinkProperties newLp) {
|
public void onLinkPropertiesChanged(Network network, LinkProperties newLp) {
|
||||||
mTarget.getHandler().post(() -> handleLinkProp(network, newLp));
|
checkExpectedThread();
|
||||||
|
handleLinkProp(network, newLp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Handle onNetworkSuspended();
|
||||||
|
// TODO: Handle onNetworkResumed();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLost(Network network) {
|
public void onLost(Network network) {
|
||||||
mTarget.getHandler().post(() -> handleLost(mCallbackType, network));
|
checkExpectedThread();
|
||||||
|
handleLost(mCallbackType, network);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkExpectedThread() {
|
||||||
|
if (Looper.myLooper() != mHandler.getLooper()) {
|
||||||
|
Log.wtf(TAG, "Handling callback in unexpected thread.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ import static org.mockito.Mockito.verify;
|
|||||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Message;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
import android.net.ConnectivityManager.NetworkCallback;
|
import android.net.ConnectivityManager.NetworkCallback;
|
||||||
import android.net.IConnectivityManager;
|
import android.net.IConnectivityManager;
|
||||||
@@ -42,6 +44,10 @@ import android.net.NetworkRequest;
|
|||||||
import android.support.test.filters.SmallTest;
|
import android.support.test.filters.SmallTest;
|
||||||
import android.support.test.runner.AndroidJUnit4;
|
import android.support.test.runner.AndroidJUnit4;
|
||||||
|
|
||||||
|
import com.android.internal.util.State;
|
||||||
|
import com.android.internal.util.StateMachine;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@@ -49,6 +55,7 @@ import org.mockito.Mock;
|
|||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -63,6 +70,7 @@ public class UpstreamNetworkMonitorTest {
|
|||||||
@Mock private Context mContext;
|
@Mock private Context mContext;
|
||||||
@Mock private IConnectivityManager mCS;
|
@Mock private IConnectivityManager mCS;
|
||||||
|
|
||||||
|
private TestStateMachine mSM;
|
||||||
private TestConnectivityManager mCM;
|
private TestConnectivityManager mCM;
|
||||||
private UpstreamNetworkMonitor mUNM;
|
private UpstreamNetworkMonitor mUNM;
|
||||||
|
|
||||||
@@ -72,7 +80,15 @@ public class UpstreamNetworkMonitorTest {
|
|||||||
reset(mCS);
|
reset(mCS);
|
||||||
|
|
||||||
mCM = spy(new TestConnectivityManager(mContext, mCS));
|
mCM = spy(new TestConnectivityManager(mContext, mCS));
|
||||||
mUNM = new UpstreamNetworkMonitor(null, EVENT_UNM_UPDATE, (ConnectivityManager) mCM);
|
mSM = new TestStateMachine();
|
||||||
|
mUNM = new UpstreamNetworkMonitor(mSM, EVENT_UNM_UPDATE, (ConnectivityManager) mCM);
|
||||||
|
}
|
||||||
|
|
||||||
|
@After public void tearDown() throws Exception {
|
||||||
|
if (mSM != null) {
|
||||||
|
mSM.quit();
|
||||||
|
mSM = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -139,15 +155,17 @@ public class UpstreamNetworkMonitorTest {
|
|||||||
|
|
||||||
mUNM.start();
|
mUNM.start();
|
||||||
verify(mCM, Mockito.times(1)).registerNetworkCallback(
|
verify(mCM, Mockito.times(1)).registerNetworkCallback(
|
||||||
any(NetworkRequest.class), any(NetworkCallback.class));
|
any(NetworkRequest.class), any(NetworkCallback.class), any(Handler.class));
|
||||||
verify(mCM, Mockito.times(1)).registerDefaultNetworkCallback(any(NetworkCallback.class));
|
verify(mCM, Mockito.times(1)).registerDefaultNetworkCallback(
|
||||||
|
any(NetworkCallback.class), any(Handler.class));
|
||||||
assertFalse(mUNM.mobileNetworkRequested());
|
assertFalse(mUNM.mobileNetworkRequested());
|
||||||
assertEquals(0, mCM.requested.size());
|
assertEquals(0, mCM.requested.size());
|
||||||
|
|
||||||
mUNM.updateMobileRequiresDun(true);
|
mUNM.updateMobileRequiresDun(true);
|
||||||
mUNM.registerMobileNetworkRequest();
|
mUNM.registerMobileNetworkRequest();
|
||||||
verify(mCM, Mockito.times(1)).requestNetwork(
|
verify(mCM, Mockito.times(1)).requestNetwork(
|
||||||
any(NetworkRequest.class), any(NetworkCallback.class), anyInt(), anyInt());
|
any(NetworkRequest.class), any(NetworkCallback.class), anyInt(), anyInt(),
|
||||||
|
any(Handler.class));
|
||||||
|
|
||||||
assertTrue(mUNM.mobileNetworkRequested());
|
assertTrue(mUNM.mobileNetworkRequested());
|
||||||
assertUpstreamTypeRequested(TYPE_MOBILE_DUN);
|
assertUpstreamTypeRequested(TYPE_MOBILE_DUN);
|
||||||
@@ -224,6 +242,7 @@ public class UpstreamNetworkMonitorTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class TestConnectivityManager extends ConnectivityManager {
|
public static class TestConnectivityManager extends ConnectivityManager {
|
||||||
|
public Map<NetworkCallback, Handler> allCallbacks = new HashMap<>();
|
||||||
public Set<NetworkCallback> trackingDefault = new HashSet<>();
|
public Set<NetworkCallback> trackingDefault = new HashSet<>();
|
||||||
public Map<NetworkCallback, NetworkRequest> listening = new HashMap<>();
|
public Map<NetworkCallback, NetworkRequest> listening = new HashMap<>();
|
||||||
public Map<NetworkCallback, NetworkRequest> requested = new HashMap<>();
|
public Map<NetworkCallback, NetworkRequest> requested = new HashMap<>();
|
||||||
@@ -234,7 +253,8 @@ public class UpstreamNetworkMonitorTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean hasNoCallbacks() {
|
boolean hasNoCallbacks() {
|
||||||
return trackingDefault.isEmpty() &&
|
return allCallbacks.isEmpty() &&
|
||||||
|
trackingDefault.isEmpty() &&
|
||||||
listening.isEmpty() &&
|
listening.isEmpty() &&
|
||||||
requested.isEmpty() &&
|
requested.isEmpty() &&
|
||||||
legacyTypeMap.isEmpty();
|
legacyTypeMap.isEmpty();
|
||||||
@@ -262,14 +282,23 @@ public class UpstreamNetworkMonitorTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void requestNetwork(NetworkRequest req, NetworkCallback cb) {
|
public void requestNetwork(NetworkRequest req, NetworkCallback cb, Handler h) {
|
||||||
|
assertFalse(allCallbacks.containsKey(cb));
|
||||||
|
allCallbacks.put(cb, h);
|
||||||
assertFalse(requested.containsKey(cb));
|
assertFalse(requested.containsKey(cb));
|
||||||
requested.put(cb, req);
|
requested.put(cb, req);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void requestNetwork(NetworkRequest req, NetworkCallback cb) {
|
||||||
|
fail("Should never be called.");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void requestNetwork(NetworkRequest req, NetworkCallback cb,
|
public void requestNetwork(NetworkRequest req, NetworkCallback cb,
|
||||||
int timeoutMs, int legacyType) {
|
int timeoutMs, int legacyType, Handler h) {
|
||||||
|
assertFalse(allCallbacks.containsKey(cb));
|
||||||
|
allCallbacks.put(cb, h);
|
||||||
assertFalse(requested.containsKey(cb));
|
assertFalse(requested.containsKey(cb));
|
||||||
requested.put(cb, req);
|
requested.put(cb, req);
|
||||||
assertFalse(legacyTypeMap.containsKey(cb));
|
assertFalse(legacyTypeMap.containsKey(cb));
|
||||||
@@ -279,17 +308,31 @@ public class UpstreamNetworkMonitorTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void registerNetworkCallback(NetworkRequest req, NetworkCallback cb) {
|
public void registerNetworkCallback(NetworkRequest req, NetworkCallback cb, Handler h) {
|
||||||
|
assertFalse(allCallbacks.containsKey(cb));
|
||||||
|
allCallbacks.put(cb, h);
|
||||||
assertFalse(listening.containsKey(cb));
|
assertFalse(listening.containsKey(cb));
|
||||||
listening.put(cb, req);
|
listening.put(cb, req);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void registerDefaultNetworkCallback(NetworkCallback cb) {
|
public void registerNetworkCallback(NetworkRequest req, NetworkCallback cb) {
|
||||||
|
fail("Should never be called.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerDefaultNetworkCallback(NetworkCallback cb, Handler h) {
|
||||||
|
assertFalse(allCallbacks.containsKey(cb));
|
||||||
|
allCallbacks.put(cb, h);
|
||||||
assertFalse(trackingDefault.contains(cb));
|
assertFalse(trackingDefault.contains(cb));
|
||||||
trackingDefault.add(cb);
|
trackingDefault.add(cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerDefaultNetworkCallback(NetworkCallback cb) {
|
||||||
|
fail("Should never be called.");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void unregisterNetworkCallback(NetworkCallback cb) {
|
public void unregisterNetworkCallback(NetworkCallback cb) {
|
||||||
if (trackingDefault.contains(cb)) {
|
if (trackingDefault.contains(cb)) {
|
||||||
@@ -302,10 +345,35 @@ public class UpstreamNetworkMonitorTest {
|
|||||||
} else {
|
} else {
|
||||||
fail("Unexpected callback removed");
|
fail("Unexpected callback removed");
|
||||||
}
|
}
|
||||||
|
allCallbacks.remove(cb);
|
||||||
|
|
||||||
|
assertFalse(allCallbacks.containsKey(cb));
|
||||||
assertFalse(trackingDefault.contains(cb));
|
assertFalse(trackingDefault.contains(cb));
|
||||||
assertFalse(listening.containsKey(cb));
|
assertFalse(listening.containsKey(cb));
|
||||||
assertFalse(requested.containsKey(cb));
|
assertFalse(requested.containsKey(cb));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class TestStateMachine extends StateMachine {
|
||||||
|
public final ArrayList<Message> messages = new ArrayList<>();
|
||||||
|
private final State mLoggingState = new LoggingState();
|
||||||
|
|
||||||
|
class LoggingState extends State {
|
||||||
|
@Override public void enter() { messages.clear(); }
|
||||||
|
|
||||||
|
@Override public void exit() { messages.clear(); }
|
||||||
|
|
||||||
|
@Override public boolean processMessage(Message msg) {
|
||||||
|
messages.add(msg);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public TestStateMachine() {
|
||||||
|
super("UpstreamNetworkMonitor.TestStateMachine");
|
||||||
|
addState(mLoggingState);
|
||||||
|
setInitialState(mLoggingState);
|
||||||
|
super.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user