Merge "wifi(service): Use FastXmlSerializer module utils" into main
diff --git a/framework/api/current.txt b/framework/api/current.txt
index 0047d50..524c2f4 100644
--- a/framework/api/current.txt
+++ b/framework/api/current.txt
@@ -427,6 +427,7 @@
     method @NonNull public android.net.wifi.WifiInfo.Builder setNetworkId(int);
     method @NonNull public android.net.wifi.WifiInfo.Builder setRssi(int);
     method @NonNull public android.net.wifi.WifiInfo.Builder setSsid(@NonNull byte[]);
+    method @FlaggedApi(android.net.wifi.WifiInfo.Flags.ADD_SUBSCRIPTION_ID) @NonNull public android.net.wifi.WifiInfo.Builder setSubscriptionId(int);
   }
 
   public class WifiManager {
diff --git a/framework/java/android/net/wifi/SoftApCapability.java b/framework/java/android/net/wifi/SoftApCapability.java
index 58a760c..9a5afaa 100644
--- a/framework/java/android/net/wifi/SoftApCapability.java
+++ b/framework/java/android/net/wifi/SoftApCapability.java
@@ -380,7 +380,7 @@
     }
 
     @Override
-    public boolean equals(@NonNull Object o) {
+    public boolean equals(@Nullable Object o) {
         if (this == o) return true;
         if (!(o instanceof SoftApCapability)) return false;
         SoftApCapability capability = (SoftApCapability) o;
diff --git a/framework/java/android/net/wifi/SoftApInfo.java b/framework/java/android/net/wifi/SoftApInfo.java
index faf064a..89d4782 100644
--- a/framework/java/android/net/wifi/SoftApInfo.java
+++ b/framework/java/android/net/wifi/SoftApInfo.java
@@ -378,7 +378,7 @@
     }
 
     @Override
-    public boolean equals(@NonNull Object o) {
+    public boolean equals(@Nullable Object o) {
         if (this == o) return true;
         if (!(o instanceof SoftApInfo)) return false;
         SoftApInfo softApInfo = (SoftApInfo) o;
diff --git a/framework/java/android/net/wifi/WifiClient.java b/framework/java/android/net/wifi/WifiClient.java
index f47c237..c69b039 100644
--- a/framework/java/android/net/wifi/WifiClient.java
+++ b/framework/java/android/net/wifi/WifiClient.java
@@ -17,6 +17,7 @@
 package android.net.wifi;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.net.MacAddress;
 import android.os.Parcel;
@@ -105,7 +106,7 @@
     }
 
     @Override
-    public boolean equals(@NonNull Object o) {
+    public boolean equals(@Nullable Object o) {
         if (this == o) return true;
         if (!(o instanceof WifiClient)) return false;
         WifiClient client = (WifiClient) o;
diff --git a/framework/java/android/net/wifi/WifiInfo.java b/framework/java/android/net/wifi/WifiInfo.java
index ef38163..41279ce 100644
--- a/framework/java/android/net/wifi/WifiInfo.java
+++ b/framework/java/android/net/wifi/WifiInfo.java
@@ -19,6 +19,7 @@
 import static android.net.wifi.WifiConfiguration.INVALID_NETWORK_ID;
 
 import android.Manifest;
+import android.annotation.FlaggedApi;
 import android.annotation.IntDef;
 import android.annotation.IntRange;
 import android.annotation.NonNull;
@@ -76,6 +77,18 @@
  */
 public class WifiInfo implements TransportInfo, Parcelable {
     private static final String TAG = "WifiInfo";
+
+    /**
+     * Stopgap for trunk stable flags, as they are not yet supported by Mainline for lack
+     * of support in udc-mainline-prod.
+     * TODO : remove this class when udc-mainline-prod is abandoned and android.net.flags.Flags is
+     * available here, and replace it with a generated Flags class created with flags.aconfig.
+     * @hide
+     */
+    private static class Flags {
+        public static final String ADD_SUBSCRIPTION_ID = "com.android.net.wifi.add_subscription_id";
+    }
+
     /**
      * This is the map described in the Javadoc comment above. The positions
      * of the elements of the array must correspond to the ordinal values
@@ -718,6 +731,17 @@
         }
 
         /**
+         * Set the subscription ID.
+         * @see WifiInfo#getSubscriptionId()
+         */
+        @FlaggedApi(Flags.ADD_SUBSCRIPTION_ID)
+        @NonNull
+        public Builder setSubscriptionId(int subId) {
+            mWifiInfo.setSubscriptionId(subId);
+            return this;
+        }
+
+        /**
          * Set the current security type
          * @see WifiInfo#getCurrentSecurityType()
          */
diff --git a/service/java/com/android/server/wifi/HostapdHalAidlImp.java b/service/java/com/android/server/wifi/HostapdHalAidlImp.java
index 76f48b5..f8c0791 100644
--- a/service/java/com/android/server/wifi/HostapdHalAidlImp.java
+++ b/service/java/com/android/server/wifi/HostapdHalAidlImp.java
@@ -91,6 +91,7 @@
     private Set<String> mActiveInstances = new HashSet<>();
     private HostapdDeathEventHandler mDeathEventHandler;
     private boolean mServiceDeclared = false;
+    private int mServiceVersion;
     private CountDownLatch mWaitForDeathLatch;
 
     /**
@@ -462,6 +463,14 @@
     }
 
     /**
+     * Check that the service is running at least the expected version. Use to avoid the case where
+     * the framework is using a newer interface version than the service.
+     */
+    private boolean isServiceVersionAtLeast(int expectedVersion) {
+        return expectedVersion <= mServiceVersion;
+    }
+
+    /**
      * Wrapper functions created to be mockable in unit tests
      */
     @VisibleForTesting
@@ -501,7 +510,8 @@
             Log.i(TAG, "Local Version: " + IHostapd.VERSION);
 
             try {
-                Log.i(TAG, "Remote Version: " + mIHostapd.getInterfaceVersion());
+                mServiceVersion = mIHostapd.getInterfaceVersion();
+                Log.i(TAG, "Remote Version: " + mServiceVersion);
                 IBinder serviceBinder = getServiceBinderMockable();
                 if (serviceBinder == null) return false;
                 mWaitForDeathLatch = null;
diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java
index 83d737d..227cabc 100644
--- a/service/java/com/android/server/wifi/WifiServiceImpl.java
+++ b/service/java/com/android/server/wifi/WifiServiceImpl.java
@@ -7837,4 +7837,28 @@
             }
         });
     }
+
+    /**
+     * Set the mock wifi service for testing
+     */
+    public void setMockWifiService(String serviceName) {
+        int uid = Binder.getCallingUid();
+        if (!mWifiPermissionsUtil.checkNetworkSettingsPermission(uid)) {
+            throw new SecurityException(TAG + " Uid " + uid
+                    + " Missing NETWORK_SETTINGS permission");
+        }
+        mWifiNative.setMockWifiService(serviceName);
+    }
+
+    /**
+     * Set the mock wifi methods for testing
+     */
+    public boolean setMockWifiMethods(String methods) {
+        int uid = Binder.getCallingUid();
+        if (!mWifiPermissionsUtil.checkNetworkSettingsPermission(uid)) {
+            throw new SecurityException(TAG + " Uid " + uid
+                    + " Missing NETWORK_SETTINGS permission");
+        }
+        return mWifiNative.setMockWifiMethods(methods);
+    }
 }
diff --git a/service/java/com/android/server/wifi/WifiShellCommand.java b/service/java/com/android/server/wifi/WifiShellCommand.java
index ad50e0a..9093f8e 100644
--- a/service/java/com/android/server/wifi/WifiShellCommand.java
+++ b/service/java/com/android/server/wifi/WifiShellCommand.java
@@ -172,6 +172,9 @@
             "get-ipreach-disconnect",
             "take-bugreport",
             "get-allowed-channel",
+            "set-mock-wifimodem-service",
+            "get-mock-wifimodem-service",
+            "set-mock-wifimodem-methods",
     };
 
     private static final Map<String, Pair<NetworkRequest, ConnectivityManager.NetworkCallback>>
@@ -1818,7 +1821,7 @@
                                 return -1;
                         }
                     }
-                    mWifiNative.setMockWifiService(serviceName);
+                    mWifiService.setMockWifiService(serviceName);
                     // The result will be checked, must print result "true"
                     pw.print("true");
                     return 0;
@@ -1827,7 +1830,7 @@
                     return 0;
                 case "set-mock-wifimodem-methods":
                     String methods = getNextArgRequired();
-                    if (mWifiNative.setMockWifiMethods(methods)) {
+                    if (mWifiService.setMockWifiMethods(methods)) {
                         pw.print("true");
                     } else {
                         pw.print("fail to set mock method: " + methods);