Merge "Restore the null behavior of buildWifiTemplate"
diff --git a/framework-t/src/android/net/NetworkTemplate.java b/framework-t/src/android/net/NetworkTemplate.java
index 9d0476e..af68e2e 100644
--- a/framework-t/src/android/net/NetworkTemplate.java
+++ b/framework-t/src/android/net/NetworkTemplate.java
@@ -184,6 +184,23 @@
         }
     }
 
+    private static Set<String> setOf(@Nullable final String item) {
+        if (item == null) {
+            // Set.of will throw if item is null
+            final Set<String> set = new HashSet<>();
+            set.add(null);
+            return Collections.unmodifiableSet(set);
+        } else {
+            return Set.of(item);
+        }
+    }
+
+    private static void throwAboveU() {
+        if (SdkLevel.isAtLeastU()) {
+            throw new UnsupportedOperationException("Method not supported on Android U or above");
+        }
+    }
+
     /**
      * Template to match {@link ConnectivityManager#TYPE_MOBILE} networks with
      * the given IMSI.
@@ -195,22 +212,8 @@
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.TIRAMISU,
             publicAlternatives = "Use {@code Builder} instead.")
     public static NetworkTemplate buildTemplateMobileAll(@NonNull String subscriberId) {
-        final Set<String> set;
-        // Prevent from crash for b/273963543, where the OEMs still call into this method
-        // with null subscriberId and get crashed.
-        final int firstSdk = Build.VERSION.DEVICE_INITIAL_SDK_INT;
-        if (firstSdk > Build.VERSION_CODES.TIRAMISU && subscriberId == null) {
-            throw new IllegalArgumentException("buildTemplateMobileAll does not accept null"
-                    + " subscriberId on Android U devices or above");
-        }
-        if (subscriberId == null) {
-            set = new HashSet<>();
-            set.add(null);
-        } else {
-            set = Set.of(subscriberId);
-        }
         return new NetworkTemplate.Builder(MATCH_MOBILE).setMeteredness(METERED_YES)
-                .setSubscriberIds(set).build();
+                .setSubscriberIds(setOf(subscriberId)).build();
     }
 
     /**
@@ -274,10 +277,8 @@
     // TODO(b/270089918): Remove this method. This can only be done after there are no more callers,
     //  including in OEM code which can access this by linking against the framework.
     public static NetworkTemplate buildTemplateBluetooth() {
-        if (SdkLevel.isAtLeastU()) {
-            throw new UnsupportedOperationException(
-                    "buildTemplateBluetooth is not supported on Android U devices or above");
-        }
+        // TODO : this is part of hidden-o txt, does that mean it should be annotated with
+        // @UnsupportedAppUsage(maxTargetSdk = O) ? If yes, can't throwAboveU().
         return new NetworkTemplate.Builder(MATCH_BLUETOOTH).build();
     }
 
@@ -290,10 +291,8 @@
     // TODO(b/270089918): Remove this method. This can only be done after there are no more callers,
     //  including in OEM code which can access this by linking against the framework.
     public static NetworkTemplate buildTemplateProxy() {
-        if (SdkLevel.isAtLeastU()) {
-            throw new UnsupportedOperationException(
-                    "buildTemplateProxy is not supported on Android U devices or above");
-        }
+        // TODO : this is part of hidden-o txt, does that mean it should be annotated with
+        // @UnsupportedAppUsage(maxTargetSdk = O) ? If yes, can't throwAboveU().
         return new NetworkTemplate(MATCH_PROXY, null, null);
     }
 
@@ -305,10 +304,7 @@
     // TODO(b/273963543): Remove this method. This can only be done after there are no more callers,
     //  including in OEM code which can access this by linking against the framework.
     public static NetworkTemplate buildTemplateCarrierMetered(@NonNull String subscriberId) {
-        if (SdkLevel.isAtLeastU()) {
-            throw new UnsupportedOperationException(
-                    "buildTemplateCarrierMetered is not supported on Android U devices or above");
-        }
+        throwAboveU();
         return new NetworkTemplate.Builder(MATCH_CARRIER)
                 // Set.of will throw if subscriberId is null
                 .setSubscriberIds(Set.of(subscriberId))
@@ -327,10 +323,7 @@
     //  including in OEM code which can access this by linking against the framework.
     public static NetworkTemplate buildTemplateMobileWithRatType(@Nullable String subscriberId,
             int ratType, int metered) {
-        if (SdkLevel.isAtLeastU()) {
-            throw new UnsupportedOperationException("buildTemplateMobileWithRatType is not "
-                    + "supported on Android U devices or above");
-        }
+        throwAboveU();
         return new NetworkTemplate.Builder(MATCH_MOBILE)
                 .setSubscriberIds(TextUtils.isEmpty(subscriberId)
                         ? Collections.emptySet()
@@ -340,7 +333,6 @@
                 .build();
     }
 
-
     /**
      * Template to match {@link ConnectivityManager#TYPE_WIFI} networks with the
      * given key of the wifi network.
@@ -352,12 +344,9 @@
     // TODO(b/273963543): Remove this method. This can only be done after there are no more callers,
     //  including in OEM code which can access this by linking against the framework.
     public static NetworkTemplate buildTemplateWifi(@NonNull String wifiNetworkKey) {
-        if (SdkLevel.isAtLeastU()) {
-            throw new UnsupportedOperationException("buildTemplateWifi is not "
-                    + "supported on Android U devices or above");
-        }
+        // TODO : this is part of hidden-o txt, does that mean it should be annotated with
+        // @UnsupportedAppUsage(maxTargetSdk = O) ? If yes, can't throwAboveU().
         return new NetworkTemplate.Builder(MATCH_WIFI)
-                // Set.of will throw if wifiNetworkKey is null
                 .setWifiNetworkKeys(Set.of(wifiNetworkKey))
                 .build();
     }
@@ -379,14 +368,9 @@
     //  including in OEM code which can access this by linking against the framework.
     public static NetworkTemplate buildTemplateWifi(@Nullable String wifiNetworkKey,
             @Nullable String subscriberId) {
-        if (SdkLevel.isAtLeastU()) {
-            throw new UnsupportedOperationException("buildTemplateWifi is not "
-                    + "supported on Android U devices or above");
-        }
+        throwAboveU();
         return new NetworkTemplate.Builder(MATCH_WIFI)
-                .setSubscriberIds(subscriberId == null
-                        ? Collections.emptySet()
-                        : Set.of(subscriberId))
+                .setSubscriberIds(setOf(subscriberId))
                 .setWifiNetworkKeys(wifiNetworkKey == null
                         ? Collections.emptySet()
                         : Set.of(wifiNetworkKey))
@@ -471,10 +455,6 @@
         if (matchRule == 6 || matchRule == 7) {
             Log.e(TAG, "Use MATCH_MOBILE with empty subscriberIds or MATCH_WIFI with empty "
                     + "wifiNetworkKeys instead of template with matchRule=" + matchRule);
-            if (SdkLevel.isAtLeastU()) {
-                throw new UnsupportedOperationException(
-                        "Wildcard templates are not supported on Android U devices or above");
-            }
         }
     }
 
@@ -508,10 +488,8 @@
                 getMeterednessForBackwardsCompatibility(matchRule),
                 ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
                 OEM_MANAGED_ALL);
-        if (SdkLevel.isAtLeastU()) {
-            throw new UnsupportedOperationException(
-                    "This constructor is not supported on Android U devices or above");
-        }
+        // TODO : this is part of hidden-o txt, does that mean it should be annotated with
+        // @UnsupportedAppUsage(maxTargetSdk = O) ? If yes, can't throwAboveU().
     }
 
     /** @hide */
@@ -526,10 +504,7 @@
         this(getBackwardsCompatibleMatchRule(matchRule),
                 matchSubscriberIds == null ? new String[]{} : matchSubscriberIds,
                 matchWifiNetworkKeys, metered, roaming, defaultNetwork, ratType, oemManaged);
-        if (SdkLevel.isAtLeastU()) {
-            throw new UnsupportedOperationException(
-                    "This constructor is not supported on Android U devices or above");
-        }
+        throwAboveU();
     }
 
     /** @hide */
@@ -636,10 +611,8 @@
     //  including in OEM code which can access this by linking against the framework.
     /** @hide */
     public boolean isMatchRuleMobile() {
-        if (SdkLevel.isAtLeastU()) {
-            throw new UnsupportedOperationException(
-                    "isMatchRuleMobile is not supported on Android U devices or above");
-        }
+        // TODO : this is part of hidden-o txt, does that mean it should be annotated with
+        // @UnsupportedAppUsage(maxTargetSdk = O) ? If yes, can't throwAboveU().
         switch (mMatchRule) {
             case MATCH_MOBILE:
             // Old MATCH_MOBILE_WILDCARD
@@ -981,10 +954,7 @@
     // TODO(b/273963543): Remove this method. This can only be done after there are no more callers,
     //  including in OEM code which can access this by linking against the framework.
     public static NetworkTemplate normalize(NetworkTemplate template, List<String[]> mergedList) {
-        if (SdkLevel.isAtLeastU()) {
-            throw new UnsupportedOperationException(
-                    "normalize is not supported on Android U devices or above");
-        }
+        throwAboveU();
         return normalizeImpl(template, mergedList);
     }