Merge "Avoid reusing a currently active NetID." 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 8354137..96f8324 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -1743,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) {
@@ -1872,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);
}
@@ -2099,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();
@@ -2115,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);
}
}
@@ -2673,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
@@ -3500,10 +3542,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);
@@ -4394,6 +4439,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) {