Send callbacks for Net property changes

LinkProperties and NetworkCapabilities changes were not calling app callbacks.

bug:17681483
Change-Id: I67dac3c4dc1284f5c4bfb24de239da4ec776336f
This commit is contained in:
Robert Greenwalt
2014-09-30 16:50:07 -07:00
parent d4a26e96c2
commit e525a0a7f7
2 changed files with 66 additions and 59 deletions

View File

@@ -25,6 +25,7 @@ import android.content.Intent;
import android.net.NetworkUtils; import android.net.NetworkUtils;
import android.os.Binder; import android.os.Binder;
import android.os.Build.VERSION_CODES; import android.os.Build.VERSION_CODES;
import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.HandlerThread; import android.os.HandlerThread;
import android.os.IBinder; import android.os.IBinder;
@@ -2147,50 +2148,57 @@ public class ConnectivityManager {
Log.d(TAG, "CM callback handler got msg " + message.what); Log.d(TAG, "CM callback handler got msg " + message.what);
switch (message.what) { switch (message.what) {
case CALLBACK_PRECHECK: { case CALLBACK_PRECHECK: {
NetworkRequest request = getNetworkRequest(message); NetworkRequest request = (NetworkRequest)getObject(message,
NetworkRequest.class);
NetworkCallback callbacks = getCallbacks(request); NetworkCallback callbacks = getCallbacks(request);
if (callbacks != null) { if (callbacks != null) {
callbacks.onPreCheck(getNetwork(message)); callbacks.onPreCheck((Network)getObject(message, Network.class));
} else { } else {
Log.e(TAG, "callback not found for PRECHECK message"); Log.e(TAG, "callback not found for PRECHECK message");
} }
break; break;
} }
case CALLBACK_AVAILABLE: { case CALLBACK_AVAILABLE: {
NetworkRequest request = getNetworkRequest(message); NetworkRequest request = (NetworkRequest)getObject(message,
NetworkRequest.class);
NetworkCallback callbacks = getCallbacks(request); NetworkCallback callbacks = getCallbacks(request);
if (callbacks != null) { if (callbacks != null) {
callbacks.onAvailable(getNetwork(message)); callbacks.onAvailable((Network)getObject(message, Network.class));
} else { } else {
Log.e(TAG, "callback not found for AVAILABLE message"); Log.e(TAG, "callback not found for AVAILABLE message");
} }
break; break;
} }
case CALLBACK_LOSING: { case CALLBACK_LOSING: {
NetworkRequest request = getNetworkRequest(message); NetworkRequest request = (NetworkRequest)getObject(message,
NetworkRequest.class);
NetworkCallback callbacks = getCallbacks(request); NetworkCallback callbacks = getCallbacks(request);
if (callbacks != null) { if (callbacks != null) {
callbacks.onLosing(getNetwork(message), message.arg1); callbacks.onLosing((Network)getObject(message, Network.class),
message.arg1);
} else { } else {
Log.e(TAG, "callback not found for LOSING message"); Log.e(TAG, "callback not found for LOSING message");
} }
break; break;
} }
case CALLBACK_LOST: { case CALLBACK_LOST: {
NetworkRequest request = getNetworkRequest(message); NetworkRequest request = (NetworkRequest)getObject(message,
NetworkRequest.class);
NetworkCallback callbacks = getCallbacks(request); NetworkCallback callbacks = getCallbacks(request);
if (callbacks != null) { if (callbacks != null) {
callbacks.onLost(getNetwork(message)); callbacks.onLost((Network)getObject(message, Network.class));
} else { } else {
Log.e(TAG, "callback not found for LOST message"); Log.e(TAG, "callback not found for LOST message");
} }
break; break;
} }
case CALLBACK_UNAVAIL: { case CALLBACK_UNAVAIL: {
NetworkRequest req = (NetworkRequest)message.obj; NetworkRequest request = (NetworkRequest)getObject(message,
NetworkRequest.class);
NetworkCallback callbacks = null; NetworkCallback callbacks = null;
synchronized(mCallbackMap) { synchronized(mCallbackMap) {
callbacks = mCallbackMap.get(req); callbacks = mCallbackMap.get(request);
} }
if (callbacks != null) { if (callbacks != null) {
callbacks.onUnavailable(); callbacks.onUnavailable();
@@ -2200,33 +2208,37 @@ public class ConnectivityManager {
break; break;
} }
case CALLBACK_CAP_CHANGED: { case CALLBACK_CAP_CHANGED: {
NetworkRequest request = getNetworkRequest(message); NetworkRequest request = (NetworkRequest)getObject(message,
NetworkRequest.class);
NetworkCallback callbacks = getCallbacks(request); NetworkCallback callbacks = getCallbacks(request);
if (callbacks != null) { if (callbacks != null) {
Network network = getNetwork(message); Network network = (Network)getObject(message, Network.class);
NetworkCapabilities cap = mCm.getNetworkCapabilities(network); NetworkCapabilities cap = (NetworkCapabilities)getObject(message,
NetworkCapabilities.class);
callbacks.onCapabilitiesChanged(network, cap); callbacks.onCapabilitiesChanged(network, cap);
} else { } else {
Log.e(TAG, "callback not found for CHANGED message"); Log.e(TAG, "callback not found for CAP_CHANGED message");
} }
break; break;
} }
case CALLBACK_IP_CHANGED: { case CALLBACK_IP_CHANGED: {
NetworkRequest request = getNetworkRequest(message); NetworkRequest request = (NetworkRequest)getObject(message,
NetworkRequest.class);
NetworkCallback callbacks = getCallbacks(request); NetworkCallback callbacks = getCallbacks(request);
if (callbacks != null) { if (callbacks != null) {
Network network = getNetwork(message); Network network = (Network)getObject(message, Network.class);
LinkProperties lp = mCm.getLinkProperties(network); LinkProperties lp = (LinkProperties)getObject(message,
LinkProperties.class);
callbacks.onLinkPropertiesChanged(network, lp); callbacks.onLinkPropertiesChanged(network, lp);
} else { } else {
Log.e(TAG, "callback not found for CHANGED message"); Log.e(TAG, "callback not found for IP_CHANGED message");
} }
break; break;
} }
case CALLBACK_RELEASED: { case CALLBACK_RELEASED: {
NetworkRequest req = (NetworkRequest)message.obj; NetworkRequest req = (NetworkRequest)getObject(message, NetworkRequest.class);
NetworkCallback callbacks = null; NetworkCallback callbacks = null;
synchronized(mCallbackMap) { synchronized(mCallbackMap) {
callbacks = mCallbackMap.remove(req); callbacks = mCallbackMap.remove(req);
@@ -2254,23 +2266,14 @@ public class ConnectivityManager {
} }
} }
private NetworkRequest getNetworkRequest(Message msg) { private Object getObject(Message msg, Class c) {
return (NetworkRequest)(msg.obj); return msg.getData().getParcelable(c.getSimpleName());
} }
private NetworkCallback getCallbacks(NetworkRequest req) { private NetworkCallback getCallbacks(NetworkRequest req) {
synchronized(mCallbackMap) { synchronized(mCallbackMap) {
return mCallbackMap.get(req); return mCallbackMap.get(req);
} }
} }
private Network getNetwork(Message msg) {
return new Network(msg.arg2);
}
private NetworkCallback removeCallbacks(Message msg) {
NetworkRequest req = (NetworkRequest)msg.obj;
synchronized(mCallbackMap) {
return mCallbackMap.remove(req);
}
}
} }
private void incCallbackHandlerRefCount() { private void incCallbackHandlerRefCount() {

View File

@@ -90,6 +90,7 @@ import android.net.wimax.WimaxManagerConstants;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Binder; import android.os.Binder;
import android.os.Build; import android.os.Build;
import android.os.Bundle;
import android.os.FileUtils; import android.os.FileUtils;
import android.os.Handler; import android.os.Handler;
import android.os.HandlerThread; import android.os.HandlerThread;
@@ -170,6 +171,7 @@ import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.Random; import java.util.Random;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
@@ -3533,6 +3535,10 @@ public class ConnectivityService extends IConnectivityManager.Stub {
updateDnses(newLp, oldLp, netId, flushDns); updateDnses(newLp, oldLp, netId, flushDns);
updateClat(newLp, oldLp, networkAgent); updateClat(newLp, oldLp, networkAgent);
if (isDefaultNetwork(networkAgent)) handleApplyDefaultProxy(newLp.getHttpProxy()); if (isDefaultNetwork(networkAgent)) handleApplyDefaultProxy(newLp.getHttpProxy());
// TODO - move this check to cover the whole function
if (!Objects.equals(newLp, oldLp)) {
notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_IP_CHANGED);
}
} }
private void updateClat(LinkProperties newLp, LinkProperties oldLp, NetworkAgentInfo na) { private void updateClat(LinkProperties newLp, LinkProperties oldLp, NetworkAgentInfo na) {
@@ -3670,11 +3676,14 @@ public class ConnectivityService extends IConnectivityManager.Stub {
private void updateCapabilities(NetworkAgentInfo networkAgent, private void updateCapabilities(NetworkAgentInfo networkAgent,
NetworkCapabilities networkCapabilities) { NetworkCapabilities networkCapabilities) {
// TODO - what else here? Verify still satisfies everybody? // TODO - turn this on in MR1 when we have more dogfooding time.
// Check if satisfies somebody new? call callbacks? // rematchAllNetworksAndRequests();
if (!Objects.equals(networkAgent.networkCapabilities, networkCapabilities)) {
synchronized (networkAgent) { synchronized (networkAgent) {
networkAgent.networkCapabilities = networkCapabilities; networkAgent.networkCapabilities = networkCapabilities;
} }
notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_CAP_CHANGED);
}
} }
private void sendUpdatedScoreToFactories(NetworkRequest networkRequest, int score) { private void sendUpdatedScoreToFactories(NetworkRequest networkRequest, int score) {
@@ -3688,37 +3697,32 @@ public class ConnectivityService extends IConnectivityManager.Stub {
private void callCallbackForRequest(NetworkRequestInfo nri, private void callCallbackForRequest(NetworkRequestInfo nri,
NetworkAgentInfo networkAgent, int notificationType) { NetworkAgentInfo networkAgent, int notificationType) {
if (nri.messenger == null) return; // Default request has no msgr if (nri.messenger == null) return; // Default request has no msgr
Object o; Bundle bundle = new Bundle();
int a1 = 0; bundle.putParcelable(NetworkRequest.class.getSimpleName(),
int a2 = 0; new NetworkRequest(nri.request));
switch (notificationType) {
case ConnectivityManager.CALLBACK_LOSING:
a1 = 30 * 1000; // TODO - read this from NetworkMonitor
// fall through
case ConnectivityManager.CALLBACK_PRECHECK:
case ConnectivityManager.CALLBACK_AVAILABLE:
case ConnectivityManager.CALLBACK_LOST:
case ConnectivityManager.CALLBACK_CAP_CHANGED:
case ConnectivityManager.CALLBACK_IP_CHANGED: {
o = new NetworkRequest(nri.request);
a2 = networkAgent.network.netId;
break;
}
case ConnectivityManager.CALLBACK_UNAVAIL:
case ConnectivityManager.CALLBACK_RELEASED: {
o = new NetworkRequest(nri.request);
break;
}
default: {
loge("Unknown notificationType " + notificationType);
return;
}
}
Message msg = Message.obtain(); Message msg = Message.obtain();
msg.arg1 = a1; if (notificationType != ConnectivityManager.CALLBACK_UNAVAIL &&
msg.arg2 = a2; notificationType != ConnectivityManager.CALLBACK_RELEASED) {
msg.obj = o; bundle.putParcelable(Network.class.getSimpleName(), networkAgent.network);
}
switch (notificationType) {
case ConnectivityManager.CALLBACK_LOSING: {
msg.arg1 = 30 * 1000; // TODO - read this from NetworkMonitor
break;
}
case ConnectivityManager.CALLBACK_CAP_CHANGED: {
bundle.putParcelable(NetworkCapabilities.class.getSimpleName(),
new NetworkCapabilities(networkAgent.networkCapabilities));
break;
}
case ConnectivityManager.CALLBACK_IP_CHANGED: {
bundle.putParcelable(LinkProperties.class.getSimpleName(),
new LinkProperties(networkAgent.linkProperties));
break;
}
}
msg.what = notificationType; msg.what = notificationType;
msg.setData(bundle);
try { try {
if (VDBG) { if (VDBG) {
log("sending notification " + notifyTypeToName(notificationType) + log("sending notification " + notifyTypeToName(notificationType) +