From fffa983fe45c711e30894f11abff7aaaaa1deb64 Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Tue, 2 Dec 2014 18:30:14 -0800 Subject: [PATCH] Offer to "merge" subscribers for data usage. There are some cases where multiple subscriber identities (IMSI) should be treated as "merged together" from a data usage perspective. This is done by extending the template used for matching purposes to support multiple subscribers. Then, when we query historical usage or set network policies, we normalize the matching template to merge to any other identities that should be included. When normalizing, the "lowest" identity is always used for equality and storage purposes, which allows identities to come and go over time. This change also fixes data usage recording for multi-SIM devices by passing along the concrete subscriber identity for each network interface. Also correctly create default policies for multi-SIM devices. This change also drops setPolicyDataEnable() until it can be wired up to the right underlying NetworkAgent. (This means we still bring up the network, and then rely on iptables rules to block traffic when over the limit, instead of proactively disabling the connection.) Bug: 18012787 Change-Id: If6acf32009fdfea2b836f5aff8e2f3e5e0248b4a --- .../android/net/IConnectivityManager.aidl | 3 - core/java/android/net/NetworkMisc.java | 17 +++- core/java/android/net/NetworkState.java | 7 -- .../android/server/ConnectivityService.java | 98 ++++--------------- .../server/NetworkStatsServiceTest.java | 2 +- 5 files changed, 33 insertions(+), 94 deletions(-) diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl index 802121093a..d9921a6df0 100644 --- a/core/java/android/net/IConnectivityManager.aidl +++ b/core/java/android/net/IConnectivityManager.aidl @@ -68,9 +68,6 @@ interface IConnectivityManager boolean requestRouteToHostAddress(int networkType, in byte[] hostAddress); - /** Policy control over specific {@link NetworkStateTracker}. */ - void setPolicyDataEnable(int networkType, boolean enabled); - int tether(String iface); int untether(String iface); diff --git a/core/java/android/net/NetworkMisc.java b/core/java/android/net/NetworkMisc.java index 5d2a43d0f3..b92c9e3c5d 100644 --- a/core/java/android/net/NetworkMisc.java +++ b/core/java/android/net/NetworkMisc.java @@ -20,15 +20,18 @@ import android.os.Parcel; import android.os.Parcelable; /** - * A grab-bag of information (metadata, policies, properties, etc) about a {@link Network}. + * A grab-bag of information (metadata, policies, properties, etc) about a + * {@link Network}. Since this contains PII, it should not be sent outside the + * system. * * @hide */ public class NetworkMisc implements Parcelable { /** - * If the {@link Network} is a VPN, whether apps are allowed to bypass the VPN. This is set by - * a {@link VpnService} and used by {@link ConnectivityService} when creating a VPN. + * If the {@link Network} is a VPN, whether apps are allowed to bypass the + * VPN. This is set by a {@link VpnService} and used by + * {@link ConnectivityManager} when creating a VPN. */ public boolean allowBypass; @@ -41,6 +44,11 @@ public class NetworkMisc implements Parcelable { */ public boolean explicitlySelected; + /** + * For mobile networks, this is the subscriber ID (such as IMSI). + */ + public String subscriberId; + public NetworkMisc() { } @@ -48,6 +56,7 @@ public class NetworkMisc implements Parcelable { if (nm != null) { allowBypass = nm.allowBypass; explicitlySelected = nm.explicitlySelected; + subscriberId = nm.subscriberId; } } @@ -60,6 +69,7 @@ public class NetworkMisc implements Parcelable { public void writeToParcel(Parcel out, int flags) { out.writeInt(allowBypass ? 1 : 0); out.writeInt(explicitlySelected ? 1 : 0); + out.writeString(subscriberId); } public static final Creator CREATOR = new Creator() { @@ -68,6 +78,7 @@ public class NetworkMisc implements Parcelable { NetworkMisc networkMisc = new NetworkMisc(); networkMisc.allowBypass = in.readInt() != 0; networkMisc.explicitlySelected = in.readInt() != 0; + networkMisc.subscriberId = in.readString(); return networkMisc; } diff --git a/core/java/android/net/NetworkState.java b/core/java/android/net/NetworkState.java index d26c70d556..933287f634 100644 --- a/core/java/android/net/NetworkState.java +++ b/core/java/android/net/NetworkState.java @@ -30,15 +30,9 @@ public class NetworkState implements Parcelable { public final LinkProperties linkProperties; public final NetworkCapabilities networkCapabilities; public final Network network; - /** Currently only used by testing. */ public final String subscriberId; public final String networkId; - public NetworkState(NetworkInfo networkInfo, LinkProperties linkProperties, - NetworkCapabilities networkCapabilities, Network network) { - this(networkInfo, linkProperties, networkCapabilities, network, null, null); - } - public NetworkState(NetworkInfo networkInfo, LinkProperties linkProperties, NetworkCapabilities networkCapabilities, Network network, String subscriberId, String networkId) { @@ -85,5 +79,4 @@ public class NetworkState implements Parcelable { return new NetworkState[size]; } }; - } diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 9c0e486af7..dde158cddd 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -20,22 +20,8 @@ import static android.Manifest.permission.MANAGE_NETWORK_POLICY; import static android.Manifest.permission.RECEIVE_DATA_ACTIVITY_CHANGE; import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; import static android.net.ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE; -import static android.net.ConnectivityManager.TYPE_BLUETOOTH; -import static android.net.ConnectivityManager.TYPE_DUMMY; -import static android.net.ConnectivityManager.TYPE_MOBILE; -import static android.net.ConnectivityManager.TYPE_MOBILE_CBS; -import static android.net.ConnectivityManager.TYPE_MOBILE_DUN; -import static android.net.ConnectivityManager.TYPE_MOBILE_FOTA; -import static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI; -import static android.net.ConnectivityManager.TYPE_MOBILE_IA; -import static android.net.ConnectivityManager.TYPE_MOBILE_IMS; -import static android.net.ConnectivityManager.TYPE_MOBILE_MMS; -import static android.net.ConnectivityManager.TYPE_MOBILE_SUPL; import static android.net.ConnectivityManager.TYPE_NONE; -import static android.net.ConnectivityManager.TYPE_PROXY; import static android.net.ConnectivityManager.TYPE_VPN; -import static android.net.ConnectivityManager.TYPE_WIFI; -import static android.net.ConnectivityManager.TYPE_WIMAX; import static android.net.ConnectivityManager.getNetworkTypeName; import static android.net.ConnectivityManager.isNetworkTypeValid; import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL; @@ -45,11 +31,9 @@ import android.app.AlarmManager; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; -import android.content.ActivityNotFoundException; import android.content.BroadcastReceiver; import android.content.ContentResolver; import android.content.Context; -import android.content.ContextWrapper; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; @@ -62,7 +46,6 @@ import android.net.INetworkManagementEventObserver; import android.net.INetworkPolicyListener; import android.net.INetworkPolicyManager; import android.net.INetworkStatsService; -import android.net.LinkAddress; import android.net.LinkProperties; import android.net.LinkProperties.CompareResult; import android.net.MobileDataStateTracker; @@ -72,7 +55,6 @@ import android.net.NetworkCapabilities; import android.net.NetworkConfig; import android.net.NetworkInfo; import android.net.NetworkInfo.DetailedState; -import android.net.NetworkFactory; import android.net.NetworkMisc; import android.net.NetworkQuotaInfo; import android.net.NetworkRequest; @@ -80,16 +62,12 @@ import android.net.NetworkState; import android.net.NetworkStateTracker; import android.net.NetworkUtils; import android.net.Proxy; -import android.net.ProxyDataTracker; import android.net.ProxyInfo; import android.net.RouteInfo; import android.net.SamplingDataTracker; import android.net.UidRange; import android.net.Uri; -import android.net.wimax.WimaxManagerConstants; -import android.os.AsyncTask; import android.os.Binder; -import android.os.Build; import android.os.Bundle; import android.os.FileUtils; import android.os.Handler; @@ -103,7 +81,6 @@ import android.os.ParcelFileDescriptor; import android.os.PowerManager; import android.os.Process; import android.os.RemoteException; -import android.os.ServiceManager; import android.os.SystemClock; import android.os.SystemProperties; import android.os.UserHandle; @@ -126,9 +103,6 @@ import com.android.internal.net.NetworkStatsFactory; import com.android.internal.net.VpnConfig; import com.android.internal.net.VpnProfile; import com.android.internal.telephony.DctConstants; -import com.android.internal.telephony.Phone; -import com.android.internal.telephony.PhoneConstants; -import com.android.internal.telephony.TelephonyIntents; import com.android.internal.util.AsyncChannel; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.XmlUtils; @@ -146,8 +120,6 @@ import com.android.server.net.LockdownVpnTracker; import com.google.android.collect.Lists; import com.google.android.collect.Sets; -import dalvik.system.DexClassLoader; - import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -157,31 +129,20 @@ import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.PrintWriter; -import java.lang.reflect.Constructor; -import java.net.HttpURLConnection; import java.net.Inet4Address; -import java.net.Inet6Address; import java.net.InetAddress; -import java.net.URL; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; -import java.util.GregorianCalendar; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.Random; -import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; -import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.SSLSession; - /** * @hide */ @@ -327,12 +288,6 @@ public class ConnectivityService extends IConnectivityManager.Stub */ private static final int EVENT_SEND_STICKY_BROADCAST_INTENT = 11; - /** - * Used internally to - * {@link NetworkStateTracker#setPolicyDataEnable(boolean)}. - */ - private static final int EVENT_SET_POLICY_DATA_ENABLE = 12; - /** * Used internally to disable fail fast of mobile data */ @@ -850,6 +805,7 @@ public class ConnectivityService extends IConnectivityManager.Stub LinkProperties lp = null; NetworkCapabilities nc = null; Network network = null; + String subscriberId = null; if (mLegacyTypeTracker.isTypeSupported(networkType)) { NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType); @@ -859,6 +815,7 @@ public class ConnectivityService extends IConnectivityManager.Stub lp = new LinkProperties(nai.linkProperties); nc = new NetworkCapabilities(nai.networkCapabilities); network = new Network(nai.network); + subscriberId = (nai.networkMisc != null) ? nai.networkMisc.subscriberId : null; } info.setType(networkType); } else { @@ -872,7 +829,7 @@ public class ConnectivityService extends IConnectivityManager.Stub info = getFilteredNetworkInfo(info, lp, uid); } - return new NetworkState(info, lp, nc, network); + return new NetworkState(info, lp, nc, network, subscriberId, null); } private NetworkAgentInfo getNetworkAgentInfoForNetwork(Network network) { @@ -889,6 +846,7 @@ public class ConnectivityService extends IConnectivityManager.Stub LinkProperties lp = null; NetworkCapabilities nc = null; Network network = null; + String subscriberId = null; NetworkAgentInfo nai = mNetworkForRequestId.get(mDefaultRequest.requestId); @@ -920,10 +878,11 @@ public class ConnectivityService extends IConnectivityManager.Stub lp = new LinkProperties(nai.linkProperties); nc = new NetworkCapabilities(nai.networkCapabilities); network = new Network(nai.network); + subscriberId = (nai.networkMisc != null) ? nai.networkMisc.subscriberId : null; } } - return new NetworkState(info, lp, nc, network); + return new NetworkState(info, lp, nc, network, subscriberId, null); } /** @@ -1220,14 +1179,19 @@ public class ConnectivityService extends IConnectivityManager.Stub @Override public NetworkState[] getAllNetworkState() { - enforceAccessPermission(); - final int uid = Binder.getCallingUid(); + // Require internal since we're handing out IMSI details + enforceConnectivityInternalPermission(); + final ArrayList result = Lists.newArrayList(); - for (int networkType = 0; networkType <= ConnectivityManager.MAX_NETWORK_TYPE; - networkType++) { - NetworkState state = getFilteredNetworkState(networkType, uid); - if (state.networkInfo != null) { - result.add(state); + for (Network network : getAllNetworks()) { + final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); + if (nai != null) { + synchronized (nai) { + final String subscriberId = (nai.networkMisc != null) + ? nai.networkMisc.subscriberId : null; + result.add(new NetworkState(nai.networkInfo, nai.linkProperties, + nai.networkCapabilities, network, subscriberId, null)); + } } } return result.toArray(new NetworkState[result.size()]); @@ -1452,25 +1416,6 @@ public class ConnectivityService extends IConnectivityManager.Stub } }; - @Override - public void setPolicyDataEnable(int networkType, boolean enabled) { - // only someone like NPMS should only be calling us - mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); - - mHandler.sendMessage(mHandler.obtainMessage( - EVENT_SET_POLICY_DATA_ENABLE, networkType, (enabled ? ENABLED : DISABLED))); - } - - private void handleSetPolicyDataEnable(int networkType, boolean enabled) { - // TODO - handle this passing to factories -// if (isNetworkTypeValid(networkType)) { -// final NetworkStateTracker tracker = mNetTrackers[networkType]; -// if (tracker != null) { -// tracker.setPolicyDataEnable(enabled); -// } -// } - } - private void enforceInternetPermission() { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.INTERNET, @@ -2457,12 +2402,6 @@ public class ConnectivityService extends IConnectivityManager.Stub sendStickyBroadcast(intent); break; } - case EVENT_SET_POLICY_DATA_ENABLE: { - final int networkType = msg.arg1; - final boolean enabled = msg.arg2 == ENABLED; - handleSetPolicyDataEnable(networkType, enabled); - break; - } case EVENT_ENABLE_FAIL_FAST_MOBILE_DATA: { int tag = mEnableFailFastMobileDataTag.get(); if (msg.arg1 == tag) { @@ -3858,7 +3797,6 @@ public class ConnectivityService extends IConnectivityManager.Stub mNumDnsEntries = last; } - private void updateCapabilities(NetworkAgentInfo networkAgent, NetworkCapabilities networkCapabilities) { if (!Objects.equals(networkAgent.networkCapabilities, networkCapabilities)) { diff --git a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java index f9a03fc36f..7383478c44 100644 --- a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java @@ -1023,7 +1023,7 @@ public class NetworkStatsServiceTest extends AndroidTestCase { info.setDetailedState(DetailedState.CONNECTED, null, null); final LinkProperties prop = new LinkProperties(); prop.setInterfaceName(iface); - return new NetworkState(info, prop, null, null); + return new NetworkState(info, prop, null, null, null, null); } private NetworkStats buildEmptyStats() {