Merge "wifi data usage: support to get carrier merged wifi network."
diff --git a/tests/net/java/android/net/NetworkTemplateTest.kt b/tests/net/java/android/net/NetworkTemplateTest.kt
index 64b774c..ab6b2f4 100644
--- a/tests/net/java/android/net/NetworkTemplateTest.kt
+++ b/tests/net/java/android/net/NetworkTemplateTest.kt
@@ -31,11 +31,16 @@
 import android.net.NetworkTemplate.MATCH_MOBILE_WILDCARD
 import android.net.NetworkTemplate.MATCH_WIFI
 import android.net.NetworkTemplate.MATCH_WIFI_WILDCARD
+import android.net.NetworkTemplate.WIFI_NETWORKID_ALL
 import android.net.NetworkTemplate.NETWORK_TYPE_5G_NSA
 import android.net.NetworkTemplate.NETWORK_TYPE_ALL
 import android.net.NetworkTemplate.OEM_MANAGED_ALL
 import android.net.NetworkTemplate.OEM_MANAGED_NO
 import android.net.NetworkTemplate.OEM_MANAGED_YES
+import android.net.NetworkTemplate.SUBSCRIBER_ID_MATCH_RULE_EXACT
+import android.net.NetworkTemplate.buildTemplateWifi
+import android.net.NetworkTemplate.buildTemplateWifiWildcard
+import android.net.NetworkTemplate.buildTemplateCarrier
 import android.net.NetworkTemplate.buildTemplateMobileWithRatType
 import android.telephony.TelephonyManager
 import com.android.testutils.assertParcelSane
@@ -53,6 +58,7 @@
 private const val TEST_IMSI1 = "imsi1"
 private const val TEST_IMSI2 = "imsi2"
 private const val TEST_SSID1 = "ssid1"
+private const val TEST_SSID2 = "ssid2"
 
 @RunWith(JUnit4::class)
 class NetworkTemplateTest {
@@ -60,8 +66,8 @@
 
     private fun buildMobileNetworkState(subscriberId: String): NetworkStateSnapshot =
             buildNetworkState(TYPE_MOBILE, subscriberId = subscriberId)
-    private fun buildWifiNetworkState(ssid: String): NetworkStateSnapshot =
-            buildNetworkState(TYPE_WIFI, ssid = ssid)
+    private fun buildWifiNetworkState(subscriberId: String?, ssid: String?): NetworkStateSnapshot =
+            buildNetworkState(TYPE_WIFI, subscriberId = subscriberId, ssid = ssid)
 
     private fun buildNetworkState(
         type: Int,
@@ -94,6 +100,95 @@
     }
 
     @Test
+    fun testWifiWildcardMatches() {
+        val templateWifiWildcard = buildTemplateWifiWildcard()
+
+        val identMobileImsi1 = buildNetworkIdentity(mockContext,
+                buildMobileNetworkState(TEST_IMSI1),
+                false, TelephonyManager.NETWORK_TYPE_UMTS)
+        val identWifiImsiNullSsid1 = buildNetworkIdentity(
+                mockContext, buildWifiNetworkState(null, TEST_SSID1), true, 0)
+        val identWifiImsi1Ssid1 = buildNetworkIdentity(
+                mockContext, buildWifiNetworkState(TEST_IMSI1, TEST_SSID1), true, 0)
+
+        templateWifiWildcard.assertDoesNotMatch(identMobileImsi1)
+        templateWifiWildcard.assertMatches(identWifiImsiNullSsid1)
+        templateWifiWildcard.assertMatches(identWifiImsi1Ssid1)
+    }
+
+    @Test
+    fun testWifiMatches() {
+        val templateWifiSsid1 = buildTemplateWifi(TEST_SSID1)
+        val templateWifiSsid1ImsiNull = buildTemplateWifi(TEST_SSID1, null)
+        val templateWifiSsid1Imsi1 = buildTemplateWifi(TEST_SSID1, TEST_IMSI1)
+        val templateWifiSsidAllImsi1 = buildTemplateWifi(WIFI_NETWORKID_ALL, TEST_IMSI1)
+
+        val identMobile1 = buildNetworkIdentity(mockContext, buildMobileNetworkState(TEST_IMSI1),
+                false, TelephonyManager.NETWORK_TYPE_UMTS)
+        val identWifiImsiNullSsid1 = buildNetworkIdentity(
+                mockContext, buildWifiNetworkState(null, TEST_SSID1), true, 0)
+        val identWifiImsi1Ssid1 = buildNetworkIdentity(
+                mockContext, buildWifiNetworkState(TEST_IMSI1, TEST_SSID1), true, 0)
+        val identWifiImsi2Ssid1 = buildNetworkIdentity(
+                mockContext, buildWifiNetworkState(TEST_IMSI2, TEST_SSID1), true, 0)
+        val identWifiImsi1Ssid2 = buildNetworkIdentity(
+                mockContext, buildWifiNetworkState(TEST_IMSI1, TEST_SSID2), true, 0)
+
+        // Verify that template with SSID only matches any subscriberId and specific SSID.
+        templateWifiSsid1.assertDoesNotMatch(identMobile1)
+        templateWifiSsid1.assertMatches(identWifiImsiNullSsid1)
+        templateWifiSsid1.assertMatches(identWifiImsi1Ssid1)
+        templateWifiSsid1.assertMatches(identWifiImsi2Ssid1)
+        templateWifiSsid1.assertDoesNotMatch(identWifiImsi1Ssid2)
+
+        // Verify that template with SSID1 and null imsi matches any network with
+        // SSID1 and null imsi.
+        templateWifiSsid1ImsiNull.assertDoesNotMatch(identMobile1)
+        templateWifiSsid1ImsiNull.assertMatches(identWifiImsiNullSsid1)
+        templateWifiSsid1ImsiNull.assertDoesNotMatch(identWifiImsi1Ssid1)
+        templateWifiSsid1ImsiNull.assertDoesNotMatch(identWifiImsi2Ssid1)
+        templateWifiSsid1ImsiNull.assertDoesNotMatch(identWifiImsi1Ssid2)
+
+        // Verify that template with SSID1 and imsi1 matches any network with
+        // SSID1 and imsi1.
+        templateWifiSsid1Imsi1.assertDoesNotMatch(identMobile1)
+        templateWifiSsid1Imsi1.assertDoesNotMatch(identWifiImsiNullSsid1)
+        templateWifiSsid1Imsi1.assertMatches(identWifiImsi1Ssid1)
+        templateWifiSsid1Imsi1.assertDoesNotMatch(identWifiImsi2Ssid1)
+        templateWifiSsid1Imsi1.assertDoesNotMatch(identWifiImsi1Ssid2)
+
+        // Verify that template with SSID all and imsi1 matches any network with
+        // any SSID and imsi1.
+        templateWifiSsidAllImsi1.assertDoesNotMatch(identMobile1)
+        templateWifiSsidAllImsi1.assertDoesNotMatch(identWifiImsiNullSsid1)
+        templateWifiSsidAllImsi1.assertMatches(identWifiImsi1Ssid1)
+        templateWifiSsidAllImsi1.assertDoesNotMatch(identWifiImsi2Ssid1)
+        templateWifiSsidAllImsi1.assertMatches(identWifiImsi1Ssid2)
+    }
+
+    @Test
+    fun testCarrierMatches() {
+        val templateCarrierImsi1 = buildTemplateCarrier(TEST_IMSI1)
+
+        val identMobile1 = buildNetworkIdentity(mockContext, buildMobileNetworkState(TEST_IMSI1),
+                false, TelephonyManager.NETWORK_TYPE_UMTS)
+        val identMobile2 = buildNetworkIdentity(mockContext, buildMobileNetworkState(TEST_IMSI2),
+                false, TelephonyManager.NETWORK_TYPE_UMTS)
+        val identWifiSsid1 = buildNetworkIdentity(
+                mockContext, buildWifiNetworkState(null, TEST_SSID1), true, 0)
+        val identCarrierWifiImsi1 = buildNetworkIdentity(
+                mockContext, buildWifiNetworkState(TEST_IMSI1, TEST_SSID1), true, 0)
+        val identCarrierWifiImsi2 = buildNetworkIdentity(
+                mockContext, buildWifiNetworkState(TEST_IMSI2, TEST_SSID1), true, 0)
+
+        templateCarrierImsi1.assertMatches(identCarrierWifiImsi1)
+        templateCarrierImsi1.assertDoesNotMatch(identCarrierWifiImsi2)
+        templateCarrierImsi1.assertDoesNotMatch(identWifiSsid1)
+        templateCarrierImsi1.assertMatches(identMobile1)
+        templateCarrierImsi1.assertDoesNotMatch(identMobile2)
+    }
+
+    @Test
     fun testRatTypeGroupMatches() {
         val stateMobile = buildMobileNetworkState(TEST_IMSI1)
         // Build UMTS template that matches mobile identities with RAT in the same
@@ -117,7 +212,7 @@
         val identImsi2 = buildNetworkIdentity(mockContext, buildMobileNetworkState(TEST_IMSI2),
                 false, TelephonyManager.NETWORK_TYPE_UMTS)
         val identWifi = buildNetworkIdentity(
-                mockContext, buildWifiNetworkState(TEST_SSID1), true, 0)
+                mockContext, buildWifiNetworkState(null, TEST_SSID1), true, 0)
 
         // Assert that identity with the same RAT matches.
         templateUmts.assertMatches(identUmts)
@@ -151,14 +246,16 @@
     fun testParcelUnparcel() {
         val templateMobile = NetworkTemplate(MATCH_MOBILE, TEST_IMSI1, null, null, METERED_ALL,
                 ROAMING_ALL, DEFAULT_NETWORK_ALL, TelephonyManager.NETWORK_TYPE_LTE,
-                OEM_MANAGED_ALL)
+                OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_EXACT)
         val templateWifi = NetworkTemplate(MATCH_WIFI, null, null, TEST_SSID1, METERED_ALL,
-                ROAMING_ALL, DEFAULT_NETWORK_ALL, 0, OEM_MANAGED_ALL)
+                ROAMING_ALL, DEFAULT_NETWORK_ALL, 0, OEM_MANAGED_ALL,
+                SUBSCRIBER_ID_MATCH_RULE_EXACT)
         val templateOem = NetworkTemplate(MATCH_MOBILE, null, null, null, METERED_ALL,
-                ROAMING_ALL, DEFAULT_NETWORK_ALL, 0, OEM_MANAGED_YES)
-        assertParcelSane(templateMobile, 9)
-        assertParcelSane(templateWifi, 9)
-        assertParcelSane(templateOem, 9)
+                ROAMING_ALL, DEFAULT_NETWORK_ALL, 0, OEM_MANAGED_YES,
+                SUBSCRIBER_ID_MATCH_RULE_EXACT)
+        assertParcelSane(templateMobile, 10)
+        assertParcelSane(templateWifi, 10)
+        assertParcelSane(templateOem, 10)
     }
 
     // Verify NETWORK_TYPE_* constants in NetworkTemplate do not conflict with
@@ -207,15 +304,14 @@
         identSsid: String? = null
     ) {
         val oemManagedStates = arrayOf(OEM_NONE, OEM_PAID, OEM_PRIVATE, OEM_PAID or OEM_PRIVATE)
-        // A null subscriberId needs a null matchSubscriberIds argument as well.
-        val matchSubscriberIds = if (subscriberId == null) null else arrayOf(subscriberId)
+        val matchSubscriberIds = arrayOf(subscriberId)
 
         val templateOemYes = NetworkTemplate(matchType, subscriberId, matchSubscriberIds,
                 templateSsid, METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
-                OEM_MANAGED_YES)
+                OEM_MANAGED_YES, SUBSCRIBER_ID_MATCH_RULE_EXACT)
         val templateOemAll = NetworkTemplate(matchType, subscriberId, matchSubscriberIds,
                 templateSsid, METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
-                OEM_MANAGED_ALL)
+                OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_EXACT)
 
         for (identityOemManagedState in oemManagedStates) {
             val ident = buildNetworkIdentity(mockContext, buildNetworkState(networkType,
@@ -226,7 +322,7 @@
             for (templateOemManagedState in oemManagedStates) {
                 val template = NetworkTemplate(matchType, subscriberId, matchSubscriberIds,
                         templateSsid, METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL,
-                        NETWORK_TYPE_ALL, templateOemManagedState)
+                        NETWORK_TYPE_ALL, templateOemManagedState, SUBSCRIBER_ID_MATCH_RULE_EXACT)
                 if (identityOemManagedState == templateOemManagedState) {
                     template.assertMatches(ident)
                 } else {
diff --git a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
index 0ab4d2b..d6b8e68 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -45,6 +45,7 @@
 import static android.net.NetworkTemplate.NETWORK_TYPE_ALL;
 import static android.net.NetworkTemplate.OEM_MANAGED_NO;
 import static android.net.NetworkTemplate.OEM_MANAGED_YES;
+import static android.net.NetworkTemplate.SUBSCRIBER_ID_MATCH_RULE_EXACT;
 import static android.net.NetworkTemplate.buildTemplateMobileAll;
 import static android.net.NetworkTemplate.buildTemplateMobileWithRatType;
 import static android.net.NetworkTemplate.buildTemplateWifi;
@@ -669,24 +670,28 @@
     public void testMobileStatsOemManaged() throws Exception {
         final NetworkTemplate templateOemPaid = new NetworkTemplate(MATCH_MOBILE_WILDCARD,
                 /*subscriberId=*/null, /*matchSubscriberIds=*/null, /*networkId=*/null,
-                METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_PAID);
+                METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_PAID,
+                SUBSCRIBER_ID_MATCH_RULE_EXACT);
 
         final NetworkTemplate templateOemPrivate = new NetworkTemplate(MATCH_MOBILE_WILDCARD,
                 /*subscriberId=*/null, /*matchSubscriberIds=*/null, /*networkId=*/null,
-                METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_PRIVATE);
+                METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_PRIVATE,
+                SUBSCRIBER_ID_MATCH_RULE_EXACT);
 
         final NetworkTemplate templateOemAll = new NetworkTemplate(MATCH_MOBILE_WILDCARD,
                 /*subscriberId=*/null, /*matchSubscriberIds=*/null, /*networkId=*/null,
                 METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
-                OEM_PAID | OEM_PRIVATE);
+                OEM_PAID | OEM_PRIVATE, SUBSCRIBER_ID_MATCH_RULE_EXACT);
 
         final NetworkTemplate templateOemYes = new NetworkTemplate(MATCH_MOBILE_WILDCARD,
                 /*subscriberId=*/null, /*matchSubscriberIds=*/null, /*networkId=*/null,
-                METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_YES);
+                METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_YES,
+                SUBSCRIBER_ID_MATCH_RULE_EXACT);
 
         final NetworkTemplate templateOemNone = new NetworkTemplate(MATCH_MOBILE_WILDCARD,
                 /*subscriberId=*/null, /*matchSubscriberIds=*/null, /*networkId=*/null,
-                METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_NO);
+                METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_NO,
+                SUBSCRIBER_ID_MATCH_RULE_EXACT);
 
         // OEM_PAID network comes online.
         NetworkStateSnapshot[] states = new NetworkStateSnapshot[]{