Merge "Fix findConnectionTypeForIface." into lmp-dev
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index 0814e0f..b2fc3be 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -108,6 +108,8 @@
boolean prepareVpn(String oldPackage, String newPackage);
+ void setVpnPackageAuthorization(boolean authorized);
+
ParcelFileDescriptor establishVpn(in VpnConfig config);
VpnConfig getVpnConfig();
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 4d7b2ef..54afe99 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -756,10 +756,20 @@
return mNextNetworkRequestId++;
}
- private synchronized int nextNetId() {
- int netId = mNextNetId;
- if (++mNextNetId > MAX_NET_ID) mNextNetId = MIN_NET_ID;
- return netId;
+ private void assignNextNetId(NetworkAgentInfo nai) {
+ synchronized (mNetworkForNetId) {
+ for (int i = MIN_NET_ID; i <= MAX_NET_ID; i++) {
+ int netId = mNextNetId;
+ if (++mNextNetId > MAX_NET_ID) mNextNetId = MIN_NET_ID;
+ // Make sure NetID unused. http://b/16815182
+ if (mNetworkForNetId.get(netId) == null) {
+ nai.network = new Network(netId);
+ mNetworkForNetId.put(netId, nai);
+ return;
+ }
+ }
+ }
+ throw new IllegalStateException("No free netIds");
}
private int getConnectivityChangeDelay() {
@@ -1733,6 +1743,19 @@
}
}
+ private boolean isLiveNetworkAgent(NetworkAgentInfo nai, String msg) {
+ final NetworkAgentInfo officialNai;
+ synchronized (mNetworkForNetId) {
+ officialNai = mNetworkForNetId.get(nai.network.netId);
+ }
+ if (officialNai != null && officialNai.equals(nai)) return true;
+ if (officialNai != null || VDBG) {
+ loge(msg + " - validateNetworkAgent found mismatched netId: " + officialNai +
+ " - " + nai);
+ }
+ return false;
+ }
+
// must be stateless - things change under us.
private class NetworkStateTrackerHandler extends Handler {
public NetworkStateTrackerHandler(Looper looper) {
@@ -1862,23 +1885,30 @@
}
case NetworkMonitor.EVENT_NETWORK_VALIDATED: {
NetworkAgentInfo nai = (NetworkAgentInfo)msg.obj;
- handleConnectionValidated(nai);
+ if (isLiveNetworkAgent(nai, "EVENT_NETWORK_VALIDATED")) {
+ handleConnectionValidated(nai);
+ }
break;
}
case NetworkMonitor.EVENT_NETWORK_LINGER_COMPLETE: {
NetworkAgentInfo nai = (NetworkAgentInfo)msg.obj;
- handleLingerComplete(nai);
+ if (isLiveNetworkAgent(nai, "EVENT_NETWORK_LINGER_COMPLETE")) {
+ handleLingerComplete(nai);
+ }
break;
}
case NetworkMonitor.EVENT_PROVISIONING_NOTIFICATION: {
+ NetworkAgentInfo nai = null;
+ synchronized (mNetworkForNetId) {
+ nai = mNetworkForNetId.get(msg.arg2);
+ }
+ if (nai == null) {
+ loge("EVENT_PROVISIONING_NOTIFICATION from unknown NetworkMonitor");
+ break;
+ }
if (msg.arg1 == 0) {
setProvNotificationVisibleIntent(false, msg.arg2, 0, null, null);
} else {
- NetworkAgentInfo nai = mNetworkForNetId.get(msg.arg2);
- if (nai == null) {
- loge("EVENT_PROVISIONING_NOTIFICATION from unknown NetworkMonitor");
- break;
- }
setProvNotificationVisibleIntent(true, msg.arg2, nai.networkInfo.getType(),
nai.networkInfo.getExtraInfo(), (PendingIntent)msg.obj);
}
@@ -2089,13 +2119,21 @@
if (newCap.satisfiedByNetworkCapabilities(network.networkCapabilities)) {
if (VDBG) log("apparently satisfied. currentScore=" + network.currentScore);
if ((bestNetwork == null) || bestNetwork.currentScore < network.currentScore) {
- bestNetwork = network;
+ if (!nri.isRequest) {
+ // Not setting bestNetwork here as a listening NetworkRequest may be
+ // satisfied by multiple Networks. Instead the request is added to
+ // each satisfying Network and notified about each.
+ network.addRequest(nri.request);
+ notifyNetworkCallback(network, nri);
+ } else {
+ bestNetwork = network;
+ }
}
}
}
if (bestNetwork != null) {
if (VDBG) log("using " + bestNetwork.name());
- if (nri.isRequest && bestNetwork.networkInfo.isConnected()) {
+ if (bestNetwork.networkInfo.isConnected()) {
// Cancel any lingering so the linger timeout doesn't teardown this network
// even though we have a request for it.
bestNetwork.networkLingered.clear();
@@ -2105,7 +2143,7 @@
mNetworkForRequestId.put(nri.request.requestId, bestNetwork);
notifyNetworkCallback(bestNetwork, nri);
score = bestNetwork.currentScore;
- if (nri.isRequest && nri.request.legacyType != TYPE_NONE) {
+ if (nri.request.legacyType != TYPE_NONE) {
mLegacyTypeTracker.add(nri.request.legacyType, bestNetwork);
}
}
@@ -2663,6 +2701,20 @@
}
/**
+ * Set whether the current VPN package has the ability to launch VPNs without
+ * user intervention. This method is used by system UIs and not available
+ * in ConnectivityManager. Permissions are checked in Vpn class.
+ * @hide
+ */
+ @Override
+ public void setVpnPackageAuthorization(boolean authorized) {
+ int user = UserHandle.getUserId(Binder.getCallingUid());
+ synchronized(mVpns) {
+ mVpns.get(user).setPackageAuthorization(authorized);
+ }
+ }
+
+ /**
* Configure a TUN interface and return its file descriptor. Parameters
* are encoded and opaque to this class. This method is used by VpnBuilder
* and not available in ConnectivityManager. Permissions are checked in
@@ -3492,10 +3544,13 @@
mIsProvisioningNetwork.set(false);
// Check for apps that can handle provisioning first
Intent provisioningIntent = new Intent(TelephonyIntents.ACTION_CARRIER_SETUP);
- provisioningIntent.addCategory(TelephonyIntents.CATEGORY_MCCMNC_PREFIX
- + mTelephonyManager.getSimOperator());
- if (mContext.getPackageManager().resolveActivity(provisioningIntent, 0 /* flags */)
- != null) {
+ List<String> carrierPackages =
+ mTelephonyManager.getCarrierPackageNamesForBroadcastIntent(provisioningIntent);
+ if (carrierPackages != null && !carrierPackages.isEmpty()) {
+ if (carrierPackages.size() != 1) {
+ if (DBG) log("Multiple matching carrier apps found, launching the first.");
+ }
+ provisioningIntent.setPackage(carrierPackages.get(0));
provisioningIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT |
Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(provisioningIntent);
@@ -4106,7 +4161,7 @@
int currentScore, NetworkMisc networkMisc) {
enforceConnectivityInternalPermission();
- NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(), nextNetId(),
+ NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(),
new NetworkInfo(networkInfo), new LinkProperties(linkProperties),
new NetworkCapabilities(networkCapabilities), currentScore, mContext, mTrackerHandler,
networkMisc);
@@ -4120,9 +4175,7 @@
private void handleRegisterNetworkAgent(NetworkAgentInfo na) {
if (VDBG) log("Got NetworkAgent Messenger");
mNetworkAgentInfos.put(na.messenger, na);
- synchronized (mNetworkForNetId) {
- mNetworkForNetId.put(na.network.netId, na);
- }
+ assignNextNetId(na);
na.asyncChannel.connect(mContext, mTrackerHandler, na.messenger);
NetworkInfo networkInfo = na.networkInfo;
na.networkInfo = null;
@@ -4388,6 +4441,10 @@
if (VDBG) log(" checking if request is satisfied: " + nri.request);
if (nri.request.networkCapabilities.satisfiedByNetworkCapabilities(
newNetwork.networkCapabilities)) {
+ if (!nri.isRequest) {
+ newNetwork.addRequest(nri.request);
+ continue;
+ }
// next check if it's better than any current network we're using for
// this request
if (VDBG) {
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index 4eb2ef1..5a97aee 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -40,7 +40,7 @@
*/
public class NetworkAgentInfo {
public NetworkInfo networkInfo;
- public final Network network;
+ public Network network;
public LinkProperties linkProperties;
public NetworkCapabilities networkCapabilities;
public int currentScore;
@@ -55,12 +55,12 @@
public final Messenger messenger;
public final AsyncChannel asyncChannel;
- public NetworkAgentInfo(Messenger messenger, AsyncChannel ac, int netId, NetworkInfo info,
+ public NetworkAgentInfo(Messenger messenger, AsyncChannel ac, NetworkInfo info,
LinkProperties lp, NetworkCapabilities nc, int score, Context context, Handler handler,
NetworkMisc misc) {
this.messenger = messenger;
asyncChannel = ac;
- network = new Network(netId);
+ network = null;
networkInfo = info;
linkProperties = lp;
networkCapabilities = nc;
@@ -87,6 +87,7 @@
public String name() {
return "NetworkAgentInfo [" + networkInfo.getTypeName() + " (" +
- networkInfo.getSubtypeName() + ") - " + network.toString() + "]";
+ networkInfo.getSubtypeName() + ") - " +
+ (network == null ? "null" : network.toString()) + "]";
}
}