diff --git a/core/java/android/net/NetworkIdentity.java b/core/java/android/net/NetworkIdentity.java index a9de23ef1b22c..9cd563e87c4a8 100644 --- a/core/java/android/net/NetworkIdentity.java +++ b/core/java/android/net/NetworkIdentity.java @@ -55,19 +55,22 @@ public class NetworkIdentity implements Comparable { final String mSubscriberId; final String mNetworkId; final boolean mRoaming; + final boolean mMetered; public NetworkIdentity( - int type, int subType, String subscriberId, String networkId, boolean roaming) { + int type, int subType, String subscriberId, String networkId, boolean roaming, + boolean metered) { mType = type; mSubType = COMBINE_SUBTYPE_ENABLED ? SUBTYPE_COMBINED : subType; mSubscriberId = subscriberId; mNetworkId = networkId; mRoaming = roaming; + mMetered = metered; } @Override public int hashCode() { - return Objects.hash(mType, mSubType, mSubscriberId, mNetworkId, mRoaming); + return Objects.hash(mType, mSubType, mSubscriberId, mNetworkId, mRoaming, mMetered); } @Override @@ -76,7 +79,8 @@ public class NetworkIdentity implements Comparable { final NetworkIdentity ident = (NetworkIdentity) obj; return mType == ident.mType && mSubType == ident.mSubType && mRoaming == ident.mRoaming && Objects.equals(mSubscriberId, ident.mSubscriberId) - && Objects.equals(mNetworkId, ident.mNetworkId); + && Objects.equals(mNetworkId, ident.mNetworkId) + && mMetered == ident.mMetered; } return false; } @@ -102,6 +106,7 @@ public class NetworkIdentity implements Comparable { if (mRoaming) { builder.append(", ROAMING"); } + builder.append(", metered=").append(mMetered); return builder.append("}").toString(); } @@ -125,6 +130,10 @@ public class NetworkIdentity implements Comparable { return mRoaming; } + public boolean getMetered() { + return mMetered; + } + /** * Scrub given IMSI on production builds. */ @@ -162,6 +171,7 @@ public class NetworkIdentity implements Comparable { String subscriberId = null; String networkId = null; boolean roaming = false; + boolean metered = false; if (isNetworkTypeMobile(type)) { if (state.subscriberId == null) { @@ -171,6 +181,9 @@ public class NetworkIdentity implements Comparable { subscriberId = state.subscriberId; roaming = state.networkInfo.isRoaming(); + metered = !state.networkCapabilities.hasCapability( + NetworkCapabilities.NET_CAPABILITY_NOT_METERED); + } else if (type == TYPE_WIFI) { if (state.networkId != null) { networkId = state.networkId; @@ -182,7 +195,7 @@ public class NetworkIdentity implements Comparable { } } - return new NetworkIdentity(type, subType, subscriberId, networkId, roaming); + return new NetworkIdentity(type, subType, subscriberId, networkId, roaming, metered); } @Override @@ -200,6 +213,9 @@ public class NetworkIdentity implements Comparable { if (res == 0) { res = Boolean.compare(mRoaming, another.mRoaming); } + if (res == 0) { + res = Boolean.compare(mMetered, another.mMetered); + } return res; } } diff --git a/core/java/android/net/NetworkTemplate.java b/core/java/android/net/NetworkTemplate.java index b32b2ccd7667d..caf79829db9c3 100644 --- a/core/java/android/net/NetworkTemplate.java +++ b/core/java/android/net/NetworkTemplate.java @@ -19,6 +19,7 @@ package android.net; import static android.net.ConnectivityManager.TYPE_BLUETOOTH; import static android.net.ConnectivityManager.TYPE_ETHERNET; import static android.net.ConnectivityManager.TYPE_PROXY; +import static android.net.ConnectivityManager.TYPE_MOBILE; import static android.net.ConnectivityManager.TYPE_WIFI; import static android.net.ConnectivityManager.TYPE_WIFI_P2P; import static android.net.ConnectivityManager.TYPE_WIMAX; @@ -30,9 +31,6 @@ import static android.telephony.TelephonyManager.NETWORK_CLASS_4_G; import static android.telephony.TelephonyManager.NETWORK_CLASS_UNKNOWN; import static android.telephony.TelephonyManager.getNetworkClass; -import static com.android.internal.util.ArrayUtils.contains; - -import android.content.res.Resources; import android.os.Parcel; import android.os.Parcelable; import android.util.BackupUtils; @@ -71,16 +69,6 @@ public class NetworkTemplate implements Parcelable { public static final int MATCH_BLUETOOTH = 8; public static final int MATCH_PROXY = 9; - /** - * Set of {@link NetworkInfo#getType()} that reflect data usage. - */ - private static final int[] DATA_USAGE_NETWORK_TYPES; - - static { - DATA_USAGE_NETWORK_TYPES = Resources.getSystem().getIntArray( - com.android.internal.R.array.config_data_usage_network_types); - } - private static boolean sForceAllNetworkTypes = false; @VisibleForTesting @@ -318,9 +306,8 @@ public class NetworkTemplate implements Parcelable { // TODO: consider matching against WiMAX subscriber identity return true; } else { - final boolean matchesType = (sForceAllNetworkTypes - || contains(DATA_USAGE_NETWORK_TYPES, ident.mType)); - return matchesType && !ArrayUtils.isEmpty(mMatchSubscriberIds) + return (sForceAllNetworkTypes || (ident.mType == TYPE_MOBILE && ident.mMetered)) + && !ArrayUtils.isEmpty(mMatchSubscriberIds) && ArrayUtils.contains(mMatchSubscriberIds, ident.mSubscriberId); } } @@ -389,7 +376,7 @@ public class NetworkTemplate implements Parcelable { if (ident.mType == TYPE_WIMAX) { return true; } else { - return sForceAllNetworkTypes || contains(DATA_USAGE_NETWORK_TYPES, ident.mType); + return sForceAllNetworkTypes || (ident.mType == TYPE_MOBILE && ident.mMetered); } } diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 35b75248cb4ee..c4ec93325a30b 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -265,19 +265,6 @@ "0,1" - - - 0 - 2 - 3 - 4 - 5 - 10 - 11 - 12 - 14 - - 60000 diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 9342eb1b93979..d21850922357a 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -1128,7 +1128,6 @@ - diff --git a/services/core/java/com/android/server/net/NetworkIdentitySet.java b/services/core/java/com/android/server/net/NetworkIdentitySet.java index 68dc715b08afa..959a823290014 100644 --- a/services/core/java/com/android/server/net/NetworkIdentitySet.java +++ b/services/core/java/com/android/server/net/NetworkIdentitySet.java @@ -23,6 +23,8 @@ import java.io.DataOutputStream; import java.io.IOException; import java.util.HashSet; +import static android.net.ConnectivityManager.TYPE_MOBILE; + /** * Identity of a {@code iface}, defined by the set of {@link NetworkIdentity} * active on that interface. @@ -34,6 +36,7 @@ public class NetworkIdentitySet extends HashSet implements private static final int VERSION_INIT = 1; private static final int VERSION_ADD_ROAMING = 2; private static final int VERSION_ADD_NETWORK_ID = 3; + private static final int VERSION_ADD_METERED = 4; public NetworkIdentitySet() { } @@ -61,12 +64,22 @@ public class NetworkIdentitySet extends HashSet implements roaming = false; } - add(new NetworkIdentity(type, subType, subscriberId, networkId, roaming)); + final boolean metered; + if (version >= VERSION_ADD_METERED) { + metered = in.readBoolean(); + } else { + // If this is the old data and the type is mobile, treat it as metered. (Note that + // if this is a mobile network, TYPE_MOBILE is the only possible type that could be + // used.) + metered = (type == TYPE_MOBILE); + } + + add(new NetworkIdentity(type, subType, subscriberId, networkId, roaming, metered)); } } public void writeToStream(DataOutputStream out) throws IOException { - out.writeInt(VERSION_ADD_NETWORK_ID); + out.writeInt(VERSION_ADD_METERED); out.writeInt(size()); for (NetworkIdentity ident : this) { out.writeInt(ident.getType()); @@ -74,6 +87,7 @@ public class NetworkIdentitySet extends HashSet implements writeOptionalString(out, ident.getSubscriberId()); writeOptionalString(out, ident.getNetworkId()); out.writeBoolean(ident.getRoaming()); + out.writeBoolean(ident.getMetered()); } } diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index 612bae21b24cd..c24860886d729 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -940,7 +940,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { for (int subId : subIds) { final String subscriberId = tele.getSubscriberId(subId); final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE, - TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false); + TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true); if (template.matches(probeIdent)) { return true; } @@ -1333,7 +1333,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { private void ensureActiveMobilePolicyLocked(String subscriberId) { // Poke around to see if we already have a policy final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE, - TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false); + TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true); for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) { final NetworkTemplate template = mNetworkPolicy.keyAt(i); if (template.matches(probeIdent)) { diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkStatsCollectionTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkStatsCollectionTest.java index 60266445930ab..9f53c87834e91 100644 --- a/services/tests/servicestests/src/com/android/server/net/NetworkStatsCollectionTest.java +++ b/services/tests/servicestests/src/com/android/server/net/NetworkStatsCollectionTest.java @@ -162,7 +162,7 @@ public class NetworkStatsCollectionTest extends AndroidTestCase { final NetworkStats.Entry entry = new NetworkStats.Entry(); final NetworkIdentitySet identSet = new NetworkIdentitySet(); identSet.add(new NetworkIdentity(TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN, - TEST_IMSI, null, false)); + TEST_IMSI, null, false, true)); int myUid = Process.myUid(); int otherUidInSameUser = Process.myUid() + 1; diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkStatsObserversTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkStatsObserversTest.java index 82c6b6d8804da..cff5876f858e9 100644 --- a/services/tests/servicestests/src/com/android/server/net/NetworkStatsObserversTest.java +++ b/services/tests/servicestests/src/com/android/server/net/NetworkStatsObserversTest.java @@ -283,7 +283,7 @@ public class NetworkStatsObserversTest extends TestCase { NetworkIdentitySet identSet = new NetworkIdentitySet(); identSet.add(new NetworkIdentity( TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN, - IMSI_1, null /* networkId */, false /* roaming */)); + IMSI_1, null /* networkId */, false /* roaming */, true /* metered */)); mActiveIfaces.put(TEST_IFACE, identSet); // Baseline @@ -315,7 +315,7 @@ public class NetworkStatsObserversTest extends TestCase { NetworkIdentitySet identSet = new NetworkIdentitySet(); identSet.add(new NetworkIdentity( TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN, - IMSI_1, null /* networkId */, false /* roaming */)); + IMSI_1, null /* networkId */, false /* roaming */, true /* metered */)); mActiveIfaces.put(TEST_IFACE, identSet); // Baseline @@ -354,7 +354,7 @@ public class NetworkStatsObserversTest extends TestCase { NetworkIdentitySet identSet = new NetworkIdentitySet(); identSet.add(new NetworkIdentity( TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN, - IMSI_1, null /* networkId */, false /* roaming */)); + IMSI_1, null /* networkId */, false /* roaming */, true /* metered */)); mActiveIfaces.put(TEST_IFACE, identSet); // Baseline @@ -393,13 +393,13 @@ public class NetworkStatsObserversTest extends TestCase { NetworkIdentitySet identSet1 = new NetworkIdentitySet(); identSet1.add(new NetworkIdentity( TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN, - IMSI_1, null /* networkId */, false /* roaming */)); + IMSI_1, null /* networkId */, false /* roaming */, true /* metered */)); mActiveIfaces.put(TEST_IFACE, identSet1); NetworkIdentitySet identSet2 = new NetworkIdentitySet(); identSet2.add(new NetworkIdentity( TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN, - IMSI_2, null /* networkId */, false /* roaming */)); + IMSI_2, null /* networkId */, false /* roaming */, true /* metered */)); mActiveIfaces.put(TEST_IFACE2, identSet2); // Baseline @@ -441,7 +441,7 @@ public class NetworkStatsObserversTest extends TestCase { NetworkIdentitySet identSet = new NetworkIdentitySet(); identSet.add(new NetworkIdentity( TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN, - IMSI_1, null /* networkId */, false /* roaming */)); + IMSI_1, null /* networkId */, false /* roaming */, true /* metered */)); mActiveUidIfaces.put(TEST_IFACE, identSet); // Baseline @@ -481,7 +481,7 @@ public class NetworkStatsObserversTest extends TestCase { NetworkIdentitySet identSet = new NetworkIdentitySet(); identSet.add(new NetworkIdentity( TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN, - IMSI_1, null /* networkId */, false /* roaming */)); + IMSI_1, null /* networkId */, false /* roaming */, true /* metered */)); mActiveUidIfaces.put(TEST_IFACE, identSet); // Baseline @@ -521,7 +521,7 @@ public class NetworkStatsObserversTest extends TestCase { NetworkIdentitySet identSet = new NetworkIdentitySet(); identSet.add(new NetworkIdentity( TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN, - IMSI_1, null /* networkId */, false /* roaming */)); + IMSI_1, null /* networkId */, false /* roaming */, true /* metered */)); mActiveUidIfaces.put(TEST_IFACE, identSet); // Baseline @@ -561,7 +561,7 @@ public class NetworkStatsObserversTest extends TestCase { NetworkIdentitySet identSet = new NetworkIdentitySet(); identSet.add(new NetworkIdentity( TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN, - IMSI_1, null /* networkId */, false /* roaming */)); + IMSI_1, null /* networkId */, false /* roaming */, true /* metered */)); mActiveUidIfaces.put(TEST_IFACE, identSet); // Baseline @@ -601,7 +601,7 @@ public class NetworkStatsObserversTest extends TestCase { NetworkIdentitySet identSet = new NetworkIdentitySet(); identSet.add(new NetworkIdentity( TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN, - IMSI_1, null /* networkId */, false /* roaming */)); + IMSI_1, null /* networkId */, false /* roaming */, true /* metered */)); mActiveUidIfaces.put(TEST_IFACE, identSet); // Baseline diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index 461611d0114c3..adc7c218799b8 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -419,6 +419,13 @@ public class CarrierConfigManager { public static final String KEY_CARRIER_DATA_CALL_APN_DELAY_FASTER_LONG = "carrier_data_call_apn_delay_faster_long"; + /** + * Default APN types that are metered by the carrier + * @hide + */ + public static final String KEY_CARRIER_METERED_APN_TYPES_STRINGS = + "carrier_metered_apn_types_strings"; + /* The following 3 fields are related to carrier visual voicemail. */ /** @@ -699,6 +706,8 @@ public class CarrierConfigManager { sDefaults.putLong(KEY_CARRIER_DATA_CALL_APN_DELAY_DEFAULT_LONG, 20000); sDefaults.putLong(KEY_CARRIER_DATA_CALL_APN_DELAY_FASTER_LONG, 3000); sDefaults.putInt(KEY_DURATION_BLOCKING_DISABLED_AFTER_EMERGENCY_INT, 7200); + sDefaults.putStringArray(KEY_CARRIER_METERED_APN_TYPES_STRINGS, + new String[]{"default", "mms", "dun", "supl"}); sDefaults.putStringArray(KEY_GSM_ROAMING_NETWORKS_STRING_ARRAY, null); sDefaults.putStringArray(KEY_GSM_NONROAMING_NETWORKS_STRING_ARRAY, null);