Merge "Only force drawing status bar background if target >= N" into nyc-dev
diff --git a/core/java/android/net/NetworkIdentity.java b/core/java/android/net/NetworkIdentity.java
index a9de23e..9cd563e 100644
--- a/core/java/android/net/NetworkIdentity.java
+++ b/core/java/android/net/NetworkIdentity.java
@@ -55,19 +55,22 @@
     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 @@
             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 @@
         if (mRoaming) {
             builder.append(", ROAMING");
         }
+        builder.append(", metered=").append(mMetered);
         return builder.append("}").toString();
     }
 
@@ -125,6 +130,10 @@
         return mRoaming;
     }
 
+    public boolean getMetered() {
+        return mMetered;
+    }
+
     /**
      * Scrub given IMSI on production builds.
      */
@@ -162,6 +171,7 @@
         String subscriberId = null;
         String networkId = null;
         boolean roaming = false;
+        boolean metered = false;
 
         if (isNetworkTypeMobile(type)) {
             if (state.subscriberId == null) {
@@ -171,6 +181,9 @@
             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 @@
             }
         }
 
-        return new NetworkIdentity(type, subType, subscriberId, networkId, roaming);
+        return new NetworkIdentity(type, subType, subscriberId, networkId, roaming, metered);
     }
 
     @Override
@@ -200,6 +213,9 @@
         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 b32b2cc..caf7982 100644
--- a/core/java/android/net/NetworkTemplate.java
+++ b/core/java/android/net/NetworkTemplate.java
@@ -19,6 +19,7 @@
 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_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 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 @@
             // 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 @@
         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 b4371c1..5cbe672 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -265,19 +265,6 @@
         <item>"0,1"</item>
     </string-array>
 
-    <!-- Set of NetworkInfo.getType() that reflect data usage. -->
-    <integer-array translatable="false" name="config_data_usage_network_types">
-        <item>0</item> <!-- TYPE_MOBILE -->
-        <item>2</item> <!-- TYPE_MOBILE_MMS -->
-        <item>3</item> <!-- TYPE_MOBILE_SUPL -->
-        <item>4</item> <!-- TYPE_MOBILE_DUN -->
-        <item>5</item> <!-- TYPE_MOBILE_HIPRI -->
-        <item>10</item> <!-- TYPE_MOBILE_FOTA -->
-        <item>11</item> <!-- TYPE_MOBILE_IMS -->
-        <item>12</item> <!-- TYPE_MOBILE_CBS -->
-        <item>14</item> <!-- TYPE_MOBILE_IA -->
-    </integer-array>
-
     <!-- The maximum duration (in milliseconds) we expect a network transition to take -->
     <integer name="config_networkTransitionTimeout">60000</integer>
 
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 9342eb1..d218509 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1128,7 +1128,6 @@
   <java-symbol type="plurals" name="pinpuk_attempts" />
 
   <java-symbol type="array" name="carrier_properties" />
-  <java-symbol type="array" name="config_data_usage_network_types" />
   <java-symbol type="array" name="config_sms_enabled_locking_shift_tables" />
   <java-symbol type="array" name="config_sms_enabled_single_shift_tables" />
   <java-symbol type="array" name="config_twoDigitNumberPattern" />
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index 771d5b2..6fba8c8 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -986,8 +986,12 @@
             }
             top.deliverNewIntentLocked(
                     mCallingUid, mStartActivity.intent, mStartActivity.launchedFromPackage);
-            mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.task,
-                    preferredLaunchStackId, topStack.mStackId);
+
+            // Don't use mStartActivity.task to show the toast. We're not starting a new activity
+            // but reusing 'top'. Fields in mStartActivity may not be fully initialized.
+            mSupervisor.handleNonResizableTaskIfNeeded(
+                    top.task, preferredLaunchStackId, topStack.mStackId);
+
             return START_DELIVERED_TO_TOP;
         }
 
diff --git a/services/core/java/com/android/server/net/NetworkIdentitySet.java b/services/core/java/com/android/server/net/NetworkIdentitySet.java
index 68dc715..959a823 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.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 @@
     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 @@
                 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 @@
             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 612bae2..c248608 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 @@
             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 @@
     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 6026644..9f53c87 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 @@
         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 82c6b6d..cff5876 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 @@
         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 @@
         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 @@
         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 @@
         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 @@
         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 @@
         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 @@
         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 @@
         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 @@
         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 461611d..adc7c21 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -419,6 +419,13 @@
     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 @@
         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);