diff --git a/Android.bp b/Android.bp
index c7d69cd..9873c61 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1191,6 +1191,7 @@
     visibility: [
         "//frameworks/base/wifi",
         "//frameworks/base/services/net",
+        "//packages/modules/Wifi/framework",
     ],
 }
 
@@ -1216,7 +1217,10 @@
         "core/java/com/android/internal/util/StateMachine.java",
         "core/java/com/android/internal/util/WakeupMessage.java",
     ],
-    visibility: ["//frameworks/opt/net/wifi/service"],
+    visibility: [
+        "//frameworks/opt/net/wifi/service",
+        "//packages/modules/Wifi/service",
+    ],
 }
 
 // TODO(b/145644363): move this to under StubLibraries.bp or ApiDocs.bp
diff --git a/core/java/android/accounts/ChooseAccountActivity.java b/core/java/android/accounts/ChooseAccountActivity.java
index 4af22bf..b826def 100644
--- a/core/java/android/accounts/ChooseAccountActivity.java
+++ b/core/java/android/accounts/ChooseAccountActivity.java
@@ -16,7 +16,6 @@
 package android.accounts;
 
 import android.app.Activity;
-import android.app.ActivityManager;
 import android.app.ActivityTaskManager;
 import android.content.Context;
 import android.content.pm.PackageManager;
@@ -25,8 +24,8 @@
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.Parcelable;
-import android.os.RemoteException;
 import android.os.Process;
+import android.os.RemoteException;
 import android.os.UserHandle;
 import android.util.Log;
 import android.view.LayoutInflater;
@@ -37,6 +36,7 @@
 import android.widget.ImageView;
 import android.widget.ListView;
 import android.widget.TextView;
+
 import com.android.internal.R;
 
 import java.util.HashMap;
@@ -60,6 +60,9 @@
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
+        getWindow().addSystemFlags(
+                android.view.WindowManager.LayoutParams
+                        .SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
         mAccounts = getIntent().getParcelableArrayExtra(AccountManager.KEY_ACCOUNTS);
         mAccountManagerResponse =
                 getIntent().getParcelableExtra(AccountManager.KEY_ACCOUNT_MANAGER_RESPONSE);
diff --git a/core/java/android/accounts/ChooseAccountTypeActivity.java b/core/java/android/accounts/ChooseAccountTypeActivity.java
index e3352bc..300fdd4 100644
--- a/core/java/android/accounts/ChooseAccountTypeActivity.java
+++ b/core/java/android/accounts/ChooseAccountTypeActivity.java
@@ -31,6 +31,7 @@
 import android.widget.ImageView;
 import android.widget.ListView;
 import android.widget.TextView;
+
 import com.android.internal.R;
 
 import java.util.ArrayList;
@@ -51,7 +52,9 @@
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-
+        getWindow().addSystemFlags(
+                android.view.WindowManager.LayoutParams
+                        .SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
         if (Log.isLoggable(TAG, Log.VERBOSE)) {
             Log.v(TAG, "ChooseAccountTypeActivity.onCreate(savedInstanceState="
                     + savedInstanceState + ")");
diff --git a/core/java/android/accounts/ChooseTypeAndAccountActivity.java b/core/java/android/accounts/ChooseTypeAndAccountActivity.java
index 57c1083..8cdc6a7 100644
--- a/core/java/android/accounts/ChooseTypeAndAccountActivity.java
+++ b/core/java/android/accounts/ChooseTypeAndAccountActivity.java
@@ -15,11 +15,8 @@
  */
 package android.accounts;
 
-import android.app.ActivityTaskManager;
-import com.google.android.collect.Sets;
-
 import android.app.Activity;
-import android.app.ActivityManager;
+import android.app.ActivityTaskManager;
 import android.content.Intent;
 import android.os.Bundle;
 import android.os.IBinder;
@@ -39,6 +36,8 @@
 
 import com.android.internal.R;
 
+import com.google.android.collect.Sets;
+
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.HashSet;
@@ -143,7 +142,9 @@
             Log.v(TAG, "ChooseTypeAndAccountActivity.onCreate(savedInstanceState="
                     + savedInstanceState + ")");
         }
-
+        getWindow().addSystemFlags(
+                android.view.WindowManager.LayoutParams
+                        .SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
         String message = null;
 
         try {
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index e123af7..c976a9b 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -5183,12 +5183,6 @@
      * #checkSelfPermission(String)}.
      * </p>
      * <p>
-     * Calling this API for permissions already granted to your app would show UI
-     * to the user to decide whether the app can still hold these permissions. This
-     * can be useful if the way your app uses data guarded by the permissions
-     * changes significantly.
-     * </p>
-     * <p>
      * You cannot request a permission if your activity sets {@link
      * android.R.styleable#AndroidManifestActivity_noHistory noHistory} to
      * <code>true</code> because in this case the activity would not receive
diff --git a/packages/OsuLogin/Android.bp b/packages/OsuLogin/Android.bp
deleted file mode 100644
index 445c81b..0000000
--- a/packages/OsuLogin/Android.bp
+++ /dev/null
@@ -1,18 +0,0 @@
-android_app {
-    name: "OsuLogin",
-    defaults: ["wifi-module-sdk-version-defaults"],
-    static_libs: ["androidx.legacy_legacy-support-v4"],
-    resource_dirs: ["res"],
-    srcs: ["src/**/*.java"],
-    sdk_version: "system_current",
-    certificate: ":com.android.hotspot2.osulogin.certificate",
-    apex_available: [
-        "com.android.wifi",
-        "test_com.android.wifi",
-    ],
-}
-
-android_app_certificate {
-    name: "com.android.hotspot2.osulogin.certificate",
-    certificate: "certs/com.android.hotspot2.osulogin"
-}
diff --git a/packages/OsuLogin/AndroidManifest.xml b/packages/OsuLogin/AndroidManifest.xml
deleted file mode 100644
index a428cb3..0000000
--- a/packages/OsuLogin/AndroidManifest.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.hotspot2.osulogin">
-    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
-    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
-    <uses-permission android:name="android.permission.INTERNET"/>
-
-    <application
-        android:networkSecurityConfig="@xml/network_security_config"
-        android:enabled="true"
-        android:label="@string/app_name"
-        android:configChanges="keyboardHidden|orientation|screenSize"
-        android:supportsRtl="true">
-        <activity android:name="com.android.hotspot2.osulogin.OsuLoginActivity"
-                  android:label="@string/action_bar_label"
-                  android:theme="@style/AppTheme"
-                  android:configChanges="keyboardHidden|orientation|screenSize">
-            <intent-filter>
-                <action android:name="android.net.wifi.action.PASSPOINT_LAUNCH_OSU_VIEW"/>
-                <category android:name="android.intent.category.DEFAULT"/>
-            </intent-filter>
-        </activity>
-    </application>
-</manifest>
diff --git a/packages/OsuLogin/OWNERS b/packages/OsuLogin/OWNERS
deleted file mode 100644
index aa7c3e6..0000000
--- a/packages/OsuLogin/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-satk@google.com
-etancohen@google.com
diff --git a/packages/OsuLogin/certs/com.android.hotspot2.osulogin.pk8 b/packages/OsuLogin/certs/com.android.hotspot2.osulogin.pk8
deleted file mode 100644
index 87fd622..0000000
--- a/packages/OsuLogin/certs/com.android.hotspot2.osulogin.pk8
+++ /dev/null
Binary files differ
diff --git a/packages/OsuLogin/certs/com.android.hotspot2.osulogin.x509.pem b/packages/OsuLogin/certs/com.android.hotspot2.osulogin.x509.pem
deleted file mode 100644
index 1dfe701..0000000
--- a/packages/OsuLogin/certs/com.android.hotspot2.osulogin.x509.pem
+++ /dev/null
@@ -1,35 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIGDzCCA/egAwIBAgIUHzkh0UCF/H+1mZZp0ROX4nXKOUowDQYJKoZIhvcNAQEL
-BQAwgZUxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQH
-DA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAwDgYDVQQLDAdBbmRy
-b2lkMREwDwYDVQQDDAhPc3VMb2dpbjEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBh
-bmRyb2lkLmNvbTAgFw0yMDAzMjUwMjQ5MTNaGA80NzU4MDIxOTAyNDkxM1owgZUx
-CzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1Nb3Vu
-dGFpbiBWaWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAwDgYDVQQLDAdBbmRyb2lkMREw
-DwYDVQQDDAhPc3VMb2dpbjEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lk
-LmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMJDnjAeIZ2KUvKc
-ONwxuzIhLvXr6LRm+Uz0ebjz++5IzQJLwr/COPBG9zbIm8izj2acp+l4WVEYT6I4
-Es5LEp556ySCuZx8IjOd0Zd6NCdaKmYouDTjYTrELWUlZjfA7Km2L5x2M6ArnDO5
-zJ1BIsQ06S3C7iR3ktAQ1cFdidg6Ha2gainS0A1JKN3kL9BL1pvHRLzWZX4gsNhB
-C/6Ue3W3Sx2JRQkaaLksDdoKq0QswEk5tGfKbVr9+hHv/pztaaqEXSeV6f305cAx
-Hzd6+QJ8f8AJz2Rhnv43y72UO8b02CSP3laUj8geidR8XXw+R7Kzu8NfFDL7uVIh
-ktPaBxfWPNYtedp3JrGeZhkzljsushY+bVHECEzROhY2CiUZBEn+wwZLWe2W7oee
-VCL1EZBYctK5CfrrV6x0wvbBUF/ViwV+2LQXQNp08xB8bJBqoBn4KZjK0tTN86Dq
-qRALyoVIVh5VDU9Wbi3vrJb0/9TEQtMjuo0DS3hdtnowdRyAyhwbQHO26dqnnzBI
-XtTAve4RkOwnb8QzZde56qvRgweDE9Im1jpx4E+MMGqVYs8Txurmd/t6bCjTvp1P
-4i88crk/zqCoHEQEbiaNdfkULJAWg9wqxPjqPCTVNtOXoJwuHsNymQVSztIUSySz
-ZQ8Trk0ApqQf8yH2mjM6HJJZoNpBAgMBAAGjUzBRMB0GA1UdDgQWBBRdpduh1P+I
-BMbg5S4n1kbj5hQsOzAfBgNVHSMEGDAWgBRdpduh1P+IBMbg5S4n1kbj5hQsOzAP
-BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4ICAQB+FzSuoA7LCvn8l86V
-sSI4lH1KLLH+wrXp20w/wYcBY+s4hYPpAJ8YbEMOT9uibK/HpEWYFqiVCqk4gKXr
-Qraxvmtqq0WNSwkjeopTYlZeBzTC/If3UoOCp7KCfMdydIcxvk6LNokMWWqSCNP8
-QiD872XuBvj/uQeBsbHZTqruqPnu+LZwpuHFVRp/Pyj9rT61PsvGitb7q/chW0G7
-7csHOc5q2223LKlNknPsfbcR6nVEg4KfN7kPKny8iJtl2pdbfBjFDp+73nzW8qZU
-5JWO5nWL7cJh4mt5sPGrzpt/Hf8/Dngg69sImRqjv/6/wCV0pEmmNjKJkXcMaZ0T
-2TSs+A7K6l15NYk8exkMymTU7jk+iDud3tnQ68YHf/A9pDu15OCw6U/pTgOgu9co
-rBLLhGV0Tb6XAnsWKe9tsLcumQXU5ZUn9m5VJl58wQHNhUqpT7L0fWtpiTMTStVA
-/yZbndPO4SbjR5rjcAk1xge8lyIIp0WBWmwoQ/1y4DXF/yPaX733wO7uWUljgKuy
-MM/zM4zklB8nFjXfPNf3j24Bzqmy7rqy4XB64enVmYQ2mVNqfwXvINoo2XOrAmj/
-bhSWXiCFltJFM7fmJGOMEEHBt9QfbmCgmM4aoWMgH7P+HxGW+Vc3tGixBbsxNRC+
-/VrPAINQV4x5q8zGYNQBqNFn/A==
------END CERTIFICATE-----
diff --git a/packages/OsuLogin/certs/key.pem b/packages/OsuLogin/certs/key.pem
deleted file mode 100644
index f560a8d..0000000
--- a/packages/OsuLogin/certs/key.pem
+++ /dev/null
@@ -1,52 +0,0 @@
------BEGIN PRIVATE KEY-----
-MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQDCQ54wHiGdilLy
-nDjcMbsyIS716+i0ZvlM9Hm48/vuSM0CS8K/wjjwRvc2yJvIs49mnKfpeFlRGE+i
-OBLOSxKeeeskgrmcfCIzndGXejQnWipmKLg042E6xC1lJWY3wOypti+cdjOgK5wz
-ucydQSLENOktwu4kd5LQENXBXYnYOh2toGop0tANSSjd5C/QS9abx0S81mV+ILDY
-QQv+lHt1t0sdiUUJGmi5LA3aCqtELMBJObRnym1a/foR7/6c7WmqhF0nlen99OXA
-MR83evkCfH/ACc9kYZ7+N8u9lDvG9Ngkj95WlI/IHonUfF18Pkeys7vDXxQy+7lS
-IZLT2gcX1jzWLXnadyaxnmYZM5Y7LrIWPm1RxAhM0ToWNgolGQRJ/sMGS1ntlu6H
-nlQi9RGQWHLSuQn661esdML2wVBf1YsFfti0F0DadPMQfGyQaqAZ+CmYytLUzfOg
-6qkQC8qFSFYeVQ1PVm4t76yW9P/UxELTI7qNA0t4XbZ6MHUcgMocG0Bztunap58w
-SF7UwL3uEZDsJ2/EM2XXueqr0YMHgxPSJtY6ceBPjDBqlWLPE8bq5nf7emwo076d
-T+IvPHK5P86gqBxEBG4mjXX5FCyQFoPcKsT46jwk1TbTl6CcLh7DcpkFUs7SFEsk
-s2UPE65NAKakH/Mh9pozOhySWaDaQQIDAQABAoICAGgX7XKhIqgVD59aoIk0yLby
-2wQBdf780ocu1O6LJiqnrdqWF/PCsdnmXN9pHTitJqD4Pm03BL0Uhs9ItqL9zStH
-7vzwY177kSQRY9aEL+AKS3/UP+hvEpF3v09ce+pSIT5LFjYDjGQ+GgQJgh+dYHC8
-XVodAphdzjhZXQCxC4TmlzKLK3ffs4X69r/3XruBd6yfWTDKvTWZdMlcCX5Pt9v6
-7HAWNvzKvuTCO2Xjo6PzStGx7v5SlMhWISJtdARInv80z+m/RdPD3zxd1flXloiD
-h7yyRQPn31cfNLgP7vwMBKmKwbuo/WZhHr/SKBHEGY0jC/CDSQKMqd/dh5ynTnbC
-vi/qjKFIHofmhzgQ+fiHMeMsAO1c9eYs8a6bDeJjhA5qJP1HjSie9Ss9z94mp6Ww
-TRkU93yVX04DU4TCCf0IcFpKdbtKp84i6iLV9lKGh9juM42hSOFUV6bhxmlJ9zvM
-yl7vfhhuFHy1SypmaK/oJ+nwac4vIMaHCX9ifl6hm/z4PrGFSYJGQoJtVOz0vT15
-lSwCJVdHkGAe0LI+3iFn5jJlluD7TqsLmZLxqTTmzDZ3U9WhAslmn5TcZd92mL0i
-ZVTfCkjyl1wUHeif2992oTUH6CFZ1jKd8xwdWvyKkvQcjhiS9GUsm7j6jolR/QI7
-VPQlocM/vCCusrMWnR7xAoIBAQDv9O8kboz6WzN6Xw5UC7MWpi2jZg1bTs/uKcfz
-biAEC96iJQ33YSkYi6QzV4jSaackU99vGkHbQIdaBTkudz+FK5XqH0auImB2xxcR
-Xu9G2j2fhzESchVTtOnotVgjiuv18SLZ/GQoSIccs0QxcisPiTa5Ij9pl8xVoS6J
-sxfqAe15hASqLh+9Ula3+Orb1kCkqK0UwU0nM9nfUH88BKvUwQIMA7kipTA8jJog
-MJOlYPQUGxkltlim8Vip//P336E7CWT6fWbfo62US6IEu6HcC6T8u8jcLjIKsmjJ
-YJyqrepZqAVMPlv2Z+mNhxRR0ct6blfjJSrEZEtxBRn98kZ1AoIBAQDPQJ1z7Mfy
-AOfjSO6Dlfr7V9SWmGvexosH0gu6H8KO+n1/ZPH5fHGt7ORubUDhkNI/fqZK0Hls
-Q9Jwgq1QI9UwMTogF8DgmZ6L6jiXhUScIk0BFhUxOBoplugaI0jdTW350D2quFUJ
-LjYo+VcRapTfXXVehHSjbUh3nmTWj0WboA+//7xq8q9KHPb1Sbiwjf7N1iYD5R8p
-PaaG0DMET+l90bxI+QVX1enwjZGcFjo8VI+qXGGkpB/1zK5yWm29ZWypLw8TZreM
-7rLUdBY1/m7MB54zOaJ2jSsxLQSXIVSGPI1ugkmFr6OxeuLdcCLN4yca3+HYHewa
-w3GCBP3kfYMdAoIBAAxG0slhYpMYgWy8WkZQhuwcum8GtJ48TQUZXCKHOtoaJVzU
-Wn+SmACqfE8oJlblkuiX5fGQPVhTV9lyNPe8oCJXFYdx7DLSjW7mRrbbzZApcEeu
-KgOQlKjAs8r1JDpFTEc7/BV9BT7OXyNHxLBm7+8OjR8xsl7bplenNHNVF18glB7I
-c1ilnXgZM1icQp/WuV3zR0+tiB3+WCJFwwy2DHiJG2qz8g/ktbATXXtSIOuwJyy0
-Kjg0uRppdKjV8Ix5A426sFDkg5PjkujoabSmSOSyL9HCZcdmEadcc2ICMGHHHhtS
-Lls1QY08ycU06QQ6oJd198cmSqbbnsR8h1TnxVUCggEBAI2zF/QSiAImLGVxj+HX
-wWnneyobvGTsSlJmgi4XWOZ4zSU011xEgVTxCp2VhS6z3YwcA4ZTUzF6jX7vWZ/Z
-YAE7JwqaMv1dCtGOqnKuY2J88Tk05/hm6zxUOQzl4wOr1O1gO0lmDn3gYpdRIv59
-aJvvQjgFR9oU9d8TJM6t1mG45gvXxfM5Si/Z7d93MBdGflgteoBfPxbrV9gEsVzZ
-ZkLoC1u5JrYPQ4t8v3mAmQB2sGNCFmCC9ncQIpV8zlsX5VsnGZ+iMwzghtRLKoRw
-GUDWVIuhdDqp+kX9CY5q82d0Lx7HZY1JsRm/cy0DZkhubmYpfDhO/QavagQDdbOr
-POECggEAXOliqX4yFvy6USXihHVM44s63gK+yH0+0iRppqoB3+E5tDyhvvvBMPLZ
-7EBkhd7ILTDXbc0c8nSl8I/556YSlIaOB4Xbf4UQbsmD4fNGEnNWFbCzcEWYOjpQ
-5QyXjIzK/k8eg22OZlC3XNjGHgb/mA5f+v2enGQNuy7WRTl1mKYZB2h/2p6xy+jV
-CGhd4btB2bOu+1XR/B2KFvI5NdtPPti05LmsYgsU00yYJfQkpc7VvOSH5Jyy3eZL
-L9xTAy7NWBQ3LGdIpX+V1jcn3SzVits0m6hOUCtJLT1snMXAKFweTvWAQynuGomc
-VPf88ITMTOBjOH6YC8jKd/n2lVWLjw==
------END PRIVATE KEY-----
diff --git a/packages/OsuLogin/res/layout/osu_web_view.xml b/packages/OsuLogin/res/layout/osu_web_view.xml
deleted file mode 100644
index 4436aab..0000000
--- a/packages/OsuLogin/res/layout/osu_web_view.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-             xmlns:tools="http://schemas.android.com/tools"
-             android:id="@+id/container"
-             android:layout_width="match_parent"
-             android:layout_height="match_parent"
-             tools:context="com.android.hotspot2.osulogin.OsuLoginActivity">
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:orientation="vertical">
-        <FrameLayout
-            android:layout_width="match_parent"
-            android:layout_height="4dp">
-
-            <!-- Eliminates ProgressBar padding by boxing it into a 4dp high container -->
-            <ProgressBar
-                android:id="@+id/progress_bar"
-                style="@android:style/Widget.Material.Light.ProgressBar.Horizontal"
-                android:indeterminate="false"
-                android:max="100"
-                android:progress="0"
-                android:layout_gravity="center"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"/>
-        </FrameLayout>
-        <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
-            android:id="@+id/swipe_refresh"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent">
-        <WebView
-            android:id="@+id/webview"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:layout_alignParentBottom="false"
-            android:layout_alignParentRight="false"/>
-        </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
-    </LinearLayout>
-</FrameLayout>
diff --git a/packages/OsuLogin/res/values-af/strings.xml b/packages/OsuLogin/res/values-af/strings.xml
deleted file mode 100644
index bfeee10..0000000
--- a/packages/OsuLogin/res/values-af/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Sluit aanlyn aan"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Kon nie aanmeld nie"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-am/strings.xml b/packages/OsuLogin/res/values-am/strings.xml
deleted file mode 100644
index e27c578..0000000
--- a/packages/OsuLogin/res/values-am/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"የመስመር ላይ ምዝገባ"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"ምዝገባ አልተሳካም"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ar/strings.xml b/packages/OsuLogin/res/values-ar/strings.xml
deleted file mode 100644
index b72d7c1..0000000
--- a/packages/OsuLogin/res/values-ar/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"الاشتراك على الإنترنت"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"تعذّر الاشتراك."</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-as/strings.xml b/packages/OsuLogin/res/values-as/strings.xml
deleted file mode 100644
index 422de32..0000000
--- a/packages/OsuLogin/res/values-as/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"অনলাইনত ছাই আপ কৰক"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"ছাইন আপ কৰিব পৰা নগ’ল"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-az/strings.xml b/packages/OsuLogin/res/values-az/strings.xml
deleted file mode 100644
index 977f939..0000000
--- a/packages/OsuLogin/res/values-az/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Onlayn Qeydiyyat"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Qeydiyyat alınmadı"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-b+sr+Latn/strings.xml b/packages/OsuLogin/res/values-b+sr+Latn/strings.xml
deleted file mode 100644
index 6eb2cc1..0000000
--- a/packages/OsuLogin/res/values-b+sr+Latn/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Onlajn registracija"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Registracija nije uspela"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-be/strings.xml b/packages/OsuLogin/res/values-be/strings.xml
deleted file mode 100644
index 158c3f2..0000000
--- a/packages/OsuLogin/res/values-be/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Зарэгістравацца ў інтэрнэце"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Не ўдалося зарэгістравацца"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-bg/strings.xml b/packages/OsuLogin/res/values-bg/strings.xml
deleted file mode 100644
index ea3145d..0000000
--- a/packages/OsuLogin/res/values-bg/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Онлайн регистрация"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Регистрацията не бе успешна"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-bn/strings.xml b/packages/OsuLogin/res/values-bn/strings.xml
deleted file mode 100644
index c9f615e..0000000
--- a/packages/OsuLogin/res/values-bn/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"অনলাইনে সাইন-আপ করুন"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"সাইন-আপ করা যায়নি"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-bs/strings.xml b/packages/OsuLogin/res/values-bs/strings.xml
deleted file mode 100644
index e9b9751..0000000
--- a/packages/OsuLogin/res/values-bs/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Online registracija"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Registracija nije uspjela"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ca/strings.xml b/packages/OsuLogin/res/values-ca/strings.xml
deleted file mode 100644
index 7d93096..0000000
--- a/packages/OsuLogin/res/values-ca/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Registre en línia"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Ha fallat el registre"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-cs/strings.xml b/packages/OsuLogin/res/values-cs/strings.xml
deleted file mode 100644
index b9cb794..0000000
--- a/packages/OsuLogin/res/values-cs/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Online registrace"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Registrace selhala"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-da/strings.xml b/packages/OsuLogin/res/values-da/strings.xml
deleted file mode 100644
index 68c93b7..0000000
--- a/packages/OsuLogin/res/values-da/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Online registrering"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Registrering mislykkedes"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-de/strings.xml b/packages/OsuLogin/res/values-de/strings.xml
deleted file mode 100644
index 7e5a310..0000000
--- a/packages/OsuLogin/res/values-de/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Online-Registrierung"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Registrierung fehlgeschlagen"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-el/strings.xml b/packages/OsuLogin/res/values-el/strings.xml
deleted file mode 100644
index a58e481..0000000
--- a/packages/OsuLogin/res/values-el/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Εγγραφή στο διαδίκτυο"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Αποτυχία εγγραφής"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-en-rAU/strings.xml b/packages/OsuLogin/res/values-en-rAU/strings.xml
deleted file mode 100644
index fbbcab1..0000000
--- a/packages/OsuLogin/res/values-en-rAU/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Online sign-up"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Sign-up failed"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-en-rCA/strings.xml b/packages/OsuLogin/res/values-en-rCA/strings.xml
deleted file mode 100644
index fbbcab1..0000000
--- a/packages/OsuLogin/res/values-en-rCA/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Online sign-up"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Sign-up failed"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-en-rGB/strings.xml b/packages/OsuLogin/res/values-en-rGB/strings.xml
deleted file mode 100644
index fbbcab1..0000000
--- a/packages/OsuLogin/res/values-en-rGB/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Online sign-up"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Sign-up failed"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-en-rIN/strings.xml b/packages/OsuLogin/res/values-en-rIN/strings.xml
deleted file mode 100644
index fbbcab1..0000000
--- a/packages/OsuLogin/res/values-en-rIN/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Online sign-up"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Sign-up failed"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-en-rXC/strings.xml b/packages/OsuLogin/res/values-en-rXC/strings.xml
deleted file mode 100644
index af7ff67..0000000
--- a/packages/OsuLogin/res/values-en-rXC/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‎‎‏‎‏‏‏‎‏‏‎‏‎‏‏‏‏‎‎‏‏‏‎‏‎‏‎‏‏‎‎‎‏‎‏‎‏‏‎‎‎‎‏‎‏‏‎‏‎‎‏‎‏‎OsuLogin‎‏‎‎‏‎"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‏‏‎‏‎‎‏‎‏‏‎‎‎‎‏‏‏‏‎‎‎‏‎‏‎‏‏‏‏‎‏‏‎‏‏‏‏‏‎‎‏‎‎‎‏‎‎‏‎‎‏‎‏‎‏‎‏‎Online Sign Up‎‏‎‎‏‎"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‏‎‎‏‏‏‏‎‎‏‏‎‎‎‏‏‏‎‏‏‏‏‎‏‎‎‎‏‏‎‏‏‏‏‎‎‏‏‎‎‏‏‎‏‎‎‎‏‏‎‏‏‎‎‎‎‎Sign-up failed‎‏‎‎‏‎"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-es-rUS/strings.xml b/packages/OsuLogin/res/values-es-rUS/strings.xml
deleted file mode 100644
index 144804c..0000000
--- a/packages/OsuLogin/res/values-es-rUS/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Registrarse en línea"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Se produjo un error de registro"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-es/strings.xml b/packages/OsuLogin/res/values-es/strings.xml
deleted file mode 100644
index 3ad95cd..0000000
--- a/packages/OsuLogin/res/values-es/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Registro online"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Error al completar el registro"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-et/strings.xml b/packages/OsuLogin/res/values-et/strings.xml
deleted file mode 100644
index 94c5cea..0000000
--- a/packages/OsuLogin/res/values-et/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Veebis registreerimine"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Registreerimine ebaõnnestus"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-eu/strings.xml b/packages/OsuLogin/res/values-eu/strings.xml
deleted file mode 100644
index 30caa87..0000000
--- a/packages/OsuLogin/res/values-eu/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Sarean izen-ematea"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Ezin izan da eman izena"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-fa/strings.xml b/packages/OsuLogin/res/values-fa/strings.xml
deleted file mode 100644
index 3005203..0000000
--- a/packages/OsuLogin/res/values-fa/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"ثبت‌نام آنلاین"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"ثبت‌نام انجام نشد"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-fi/strings.xml b/packages/OsuLogin/res/values-fi/strings.xml
deleted file mode 100644
index 24eac8a..0000000
--- a/packages/OsuLogin/res/values-fi/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Rekisteröidy verkossa"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Rekisteröityminen ei onnistunut"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-fr-rCA/strings.xml b/packages/OsuLogin/res/values-fr-rCA/strings.xml
deleted file mode 100644
index bcaa662..0000000
--- a/packages/OsuLogin/res/values-fr-rCA/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Inscription en ligne"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Échec de l\'inscription"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-fr/strings.xml b/packages/OsuLogin/res/values-fr/strings.xml
deleted file mode 100644
index bcaa662..0000000
--- a/packages/OsuLogin/res/values-fr/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Inscription en ligne"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Échec de l\'inscription"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-gl/strings.xml b/packages/OsuLogin/res/values-gl/strings.xml
deleted file mode 100644
index 5fc4444..0000000
--- a/packages/OsuLogin/res/values-gl/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Rexistro en liña"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Produciuse un erro co rexistro"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-gu/strings.xml b/packages/OsuLogin/res/values-gu/strings.xml
deleted file mode 100644
index 8449963..0000000
--- a/packages/OsuLogin/res/values-gu/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"ઑનલાઇન સાઇન અપ કરો"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"સાઇન અપ નિષ્ફળ"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-hi/strings.xml b/packages/OsuLogin/res/values-hi/strings.xml
deleted file mode 100644
index 9e07438..0000000
--- a/packages/OsuLogin/res/values-hi/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"ऑनलाइन साइन अप करें"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"साइन अप नहीं किया जा सका"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-hr/strings.xml b/packages/OsuLogin/res/values-hr/strings.xml
deleted file mode 100644
index e9b9751..0000000
--- a/packages/OsuLogin/res/values-hr/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Online registracija"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Registracija nije uspjela"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-hu/strings.xml b/packages/OsuLogin/res/values-hu/strings.xml
deleted file mode 100644
index cb0e036..0000000
--- a/packages/OsuLogin/res/values-hu/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Online regisztráció"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"A regisztráció nem sikerült"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-hy/strings.xml b/packages/OsuLogin/res/values-hy/strings.xml
deleted file mode 100644
index ae1c36a..0000000
--- a/packages/OsuLogin/res/values-hy/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Առցանց գրանցում"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Չհաջողվեց գրանցվել"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-in/strings.xml b/packages/OsuLogin/res/values-in/strings.xml
deleted file mode 100644
index 6aaf694..0000000
--- a/packages/OsuLogin/res/values-in/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Pendaftaran Online"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Pendaftaran gagal"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-is/strings.xml b/packages/OsuLogin/res/values-is/strings.xml
deleted file mode 100644
index f1ae520..0000000
--- a/packages/OsuLogin/res/values-is/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Skráning á netinu"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Skráning mistókst"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-it/strings.xml b/packages/OsuLogin/res/values-it/strings.xml
deleted file mode 100644
index fbff7b0..0000000
--- a/packages/OsuLogin/res/values-it/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Registrazione online"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Registrazione non riuscita"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-iw/strings.xml b/packages/OsuLogin/res/values-iw/strings.xml
deleted file mode 100644
index 866ef88..0000000
--- a/packages/OsuLogin/res/values-iw/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"הרשמה אונליין"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"ההרשמה נכשלה"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ja/strings.xml b/packages/OsuLogin/res/values-ja/strings.xml
deleted file mode 100644
index 8a220d6..0000000
--- a/packages/OsuLogin/res/values-ja/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"オンライン登録"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"登録できませんでした"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ka/strings.xml b/packages/OsuLogin/res/values-ka/strings.xml
deleted file mode 100644
index bf08006..0000000
--- a/packages/OsuLogin/res/values-ka/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"ონლაინ რეგისტრაცია"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"რეგისტრაცია ვერ მოხერხდა"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-kk/strings.xml b/packages/OsuLogin/res/values-kk/strings.xml
deleted file mode 100644
index 8b87356..0000000
--- a/packages/OsuLogin/res/values-kk/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Онлайн тіркелу"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Тіркелмеді."</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-km/strings.xml b/packages/OsuLogin/res/values-km/strings.xml
deleted file mode 100644
index f58ccc3..0000000
--- a/packages/OsuLogin/res/values-km/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"ការចុះឈ្មោះ​លើអ៊ីនធឺណិត"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"ការចុះឈ្មោះ​មិនបានសម្រេច"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-kn/strings.xml b/packages/OsuLogin/res/values-kn/strings.xml
deleted file mode 100644
index 49a6562..0000000
--- a/packages/OsuLogin/res/values-kn/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"ಆನ್‌ಲೈನ್ ಸೈನ್ ಅಪ್"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"ಸೈನ್ ಅಪ್ ವಿಫಲವಾಗಿದೆ"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ko/strings.xml b/packages/OsuLogin/res/values-ko/strings.xml
deleted file mode 100644
index e647ca0..0000000
--- a/packages/OsuLogin/res/values-ko/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"온라인 가입"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"가입에 실패했습니다."</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ky/strings.xml b/packages/OsuLogin/res/values-ky/strings.xml
deleted file mode 100644
index 42da248..0000000
--- a/packages/OsuLogin/res/values-ky/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Интернет аркылуу катталуу"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Катталган жоксуз"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-lo/strings.xml b/packages/OsuLogin/res/values-lo/strings.xml
deleted file mode 100644
index 9ff2241..0000000
--- a/packages/OsuLogin/res/values-lo/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"ສະໝັກອອນລາຍ"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"ສະໝັກບໍ່ສຳເລັດ"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-lt/strings.xml b/packages/OsuLogin/res/values-lt/strings.xml
deleted file mode 100644
index 1a4c06e..0000000
--- a/packages/OsuLogin/res/values-lt/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Internetinis prisiregistravimas"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Nepavyko prisiregistruoti"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-lv/strings.xml b/packages/OsuLogin/res/values-lv/strings.xml
deleted file mode 100644
index 11cdb97..0000000
--- a/packages/OsuLogin/res/values-lv/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Reģistrācija tiešsaistē"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Reģistrācija neizdevās."</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-mk/strings.xml b/packages/OsuLogin/res/values-mk/strings.xml
deleted file mode 100644
index de608e1..0000000
--- a/packages/OsuLogin/res/values-mk/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Онлајн регистрација"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Регистрацијата не успеа"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ml/strings.xml b/packages/OsuLogin/res/values-ml/strings.xml
deleted file mode 100644
index 8e797c8..0000000
--- a/packages/OsuLogin/res/values-ml/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"ഓൺലെെൻ സെെൻ അപ്പ്"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"സൈൻ അപ്പ് ചെയ്യാനായില്ല"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-mn/strings.xml b/packages/OsuLogin/res/values-mn/strings.xml
deleted file mode 100644
index 59d79d0..0000000
--- a/packages/OsuLogin/res/values-mn/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Онлайнаар бүртгүүлэх"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Бүртгүүлж чадсангүй"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-mr/strings.xml b/packages/OsuLogin/res/values-mr/strings.xml
deleted file mode 100644
index 15479a6..0000000
--- a/packages/OsuLogin/res/values-mr/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"ऑनलाइन साइन अप करा"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"साइन-अप करता आले नाही"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ms/strings.xml b/packages/OsuLogin/res/values-ms/strings.xml
deleted file mode 100644
index 7e1cf95..0000000
--- a/packages/OsuLogin/res/values-ms/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Pendaftaran Dalam Talian"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Pendaftaran gagal"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-my/strings.xml b/packages/OsuLogin/res/values-my/strings.xml
deleted file mode 100644
index 1bd992e..0000000
--- a/packages/OsuLogin/res/values-my/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"အွန်လိုင်း အကောင့်ဖွင့်ရန်"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"အကောင့်ဖွင့်၍ မရပါ"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-nb/strings.xml b/packages/OsuLogin/res/values-nb/strings.xml
deleted file mode 100644
index 2e0c47a1..0000000
--- a/packages/OsuLogin/res/values-nb/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Registrering på nettet"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Registreringen mislyktes"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ne/strings.xml b/packages/OsuLogin/res/values-ne/strings.xml
deleted file mode 100644
index 16bd92f..0000000
--- a/packages/OsuLogin/res/values-ne/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"अनलाइन साइन अप"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"साइन अप गर्न सकिएन"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-nl/strings.xml b/packages/OsuLogin/res/values-nl/strings.xml
deleted file mode 100644
index 7cf8bd2..0000000
--- a/packages/OsuLogin/res/values-nl/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Online aanmelding"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Aanmelding mislukt"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-or/strings.xml b/packages/OsuLogin/res/values-or/strings.xml
deleted file mode 100644
index e0584d7..0000000
--- a/packages/OsuLogin/res/values-or/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"ଅନଲାଇନ୍ ସାଇନ୍ ଅପ୍ କରନ୍ତୁ"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"ସାଇନ୍ ଅପ୍ ବିଫଳ ହୋଇଛି"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-pa/strings.xml b/packages/OsuLogin/res/values-pa/strings.xml
deleted file mode 100644
index 7e47d0e..0000000
--- a/packages/OsuLogin/res/values-pa/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"ਆਨਲਾਈਨ ਸਾਈਨ-ਅੱਪ ਕਰੋ"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"ਸਾਈਨ-ਅੱਪ ਕਰਨਾ ਅਸਫਲ ਰਿਹਾ"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-pl/strings.xml b/packages/OsuLogin/res/values-pl/strings.xml
deleted file mode 100644
index c0722ab..0000000
--- a/packages/OsuLogin/res/values-pl/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Rejestracja online"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Nie udało się zarejestrować"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-pt-rBR/strings.xml b/packages/OsuLogin/res/values-pt-rBR/strings.xml
deleted file mode 100644
index c9fe377..0000000
--- a/packages/OsuLogin/res/values-pt-rBR/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Inscrição on-line"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Falha na inscrição"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-pt-rPT/strings.xml b/packages/OsuLogin/res/values-pt-rPT/strings.xml
deleted file mode 100644
index 0059281..0000000
--- a/packages/OsuLogin/res/values-pt-rPT/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Inscrição online"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Falha na inscrição."</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-pt/strings.xml b/packages/OsuLogin/res/values-pt/strings.xml
deleted file mode 100644
index c9fe377..0000000
--- a/packages/OsuLogin/res/values-pt/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Inscrição on-line"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Falha na inscrição"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ro/strings.xml b/packages/OsuLogin/res/values-ro/strings.xml
deleted file mode 100644
index eead127..0000000
--- a/packages/OsuLogin/res/values-ro/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Înscriere online"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Nu s-a înscris"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ru/strings.xml b/packages/OsuLogin/res/values-ru/strings.xml
deleted file mode 100644
index a271ef7..0000000
--- a/packages/OsuLogin/res/values-ru/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Регистрация в Интернете"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Не удалось зарегистрироваться."</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-si/strings.xml b/packages/OsuLogin/res/values-si/strings.xml
deleted file mode 100644
index 52e5979..0000000
--- a/packages/OsuLogin/res/values-si/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"සබැඳි ලියාපදිංචිය"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"ලියාපදිංචිය අසාර්ථක විය"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-sk/strings.xml b/packages/OsuLogin/res/values-sk/strings.xml
deleted file mode 100644
index f6b9f70..0000000
--- a/packages/OsuLogin/res/values-sk/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Online registrácia"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Registrácia zlyhala"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-sl/strings.xml b/packages/OsuLogin/res/values-sl/strings.xml
deleted file mode 100644
index 6e6b95c..0000000
--- a/packages/OsuLogin/res/values-sl/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Spletna registracija"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Registracija ni uspela"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-sq/strings.xml b/packages/OsuLogin/res/values-sq/strings.xml
deleted file mode 100644
index f67a238..0000000
--- a/packages/OsuLogin/res/values-sq/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Regjistrimi në linjë"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Regjistrimi dështoi"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-sr/strings.xml b/packages/OsuLogin/res/values-sr/strings.xml
deleted file mode 100644
index 14e0828..0000000
--- a/packages/OsuLogin/res/values-sr/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Онлајн регистрација"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Регистрација није успела"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-sv/strings.xml b/packages/OsuLogin/res/values-sv/strings.xml
deleted file mode 100644
index ea5fdfd..0000000
--- a/packages/OsuLogin/res/values-sv/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Registrering online"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Registreringen misslyckades"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-sw/strings.xml b/packages/OsuLogin/res/values-sw/strings.xml
deleted file mode 100644
index c20a402..0000000
--- a/packages/OsuLogin/res/values-sw/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Kujisajili Mtandaoni"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Imeshindwa kukusajili"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ta/strings.xml b/packages/OsuLogin/res/values-ta/strings.xml
deleted file mode 100644
index e2eb567..0000000
--- a/packages/OsuLogin/res/values-ta/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"ஆன்லைனில் பதிவு செய்"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"பதிவு செய்ய முடியவில்லை"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-te/strings.xml b/packages/OsuLogin/res/values-te/strings.xml
deleted file mode 100644
index 56b0b44..0000000
--- a/packages/OsuLogin/res/values-te/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"ఆన్‌లైన్ సైన్ అప్"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"సైన్-అప్ విఫలమయ్యింది"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-th/strings.xml b/packages/OsuLogin/res/values-th/strings.xml
deleted file mode 100644
index 552dca2..0000000
--- a/packages/OsuLogin/res/values-th/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"การลงชื่อสมัครใช้ออนไลน์"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"ลงชื่อสมัครใช้ไม่สำเร็จ"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-tl/strings.xml b/packages/OsuLogin/res/values-tl/strings.xml
deleted file mode 100644
index ba89e96..0000000
--- a/packages/OsuLogin/res/values-tl/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Pag-sign Up Online"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Hindi nakapag-sign up"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-tr/strings.xml b/packages/OsuLogin/res/values-tr/strings.xml
deleted file mode 100644
index 1d927fe..0000000
--- a/packages/OsuLogin/res/values-tr/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Online Kaydolma"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Kaydolma işlemi başarısız oldu"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-uk/strings.xml b/packages/OsuLogin/res/values-uk/strings.xml
deleted file mode 100644
index 6e60ff0..0000000
--- a/packages/OsuLogin/res/values-uk/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Онлайн-реєстрація"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Не вдалося зареєструватись"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ur/strings.xml b/packages/OsuLogin/res/values-ur/strings.xml
deleted file mode 100644
index eed7686..0000000
--- a/packages/OsuLogin/res/values-ur/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"آن لائن سائن اپ کریں"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"سائن اپ ناکام ہو گیا"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-uz/strings.xml b/packages/OsuLogin/res/values-uz/strings.xml
deleted file mode 100644
index 152d129..0000000
--- a/packages/OsuLogin/res/values-uz/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Onlayn registratsiya"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Registratsiya qilinmadi"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-vi/strings.xml b/packages/OsuLogin/res/values-vi/strings.xml
deleted file mode 100644
index 84558076..0000000
--- a/packages/OsuLogin/res/values-vi/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Đăng ký trực tuyến"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Không đăng ký được"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-zh-rCN/strings.xml b/packages/OsuLogin/res/values-zh-rCN/strings.xml
deleted file mode 100644
index 7f13647..0000000
--- a/packages/OsuLogin/res/values-zh-rCN/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"在线注册"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"注册失败"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-zh-rHK/strings.xml b/packages/OsuLogin/res/values-zh-rHK/strings.xml
deleted file mode 100644
index 8731791..0000000
--- a/packages/OsuLogin/res/values-zh-rHK/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"網上申請"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"無法申請"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-zh-rTW/strings.xml b/packages/OsuLogin/res/values-zh-rTW/strings.xml
deleted file mode 100644
index 79208c8..0000000
--- a/packages/OsuLogin/res/values-zh-rTW/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"線上註冊"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"註冊失敗"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-zu/strings.xml b/packages/OsuLogin/res/values-zu/strings.xml
deleted file mode 100644
index 27ac6bb..0000000
--- a/packages/OsuLogin/res/values-zu/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"I-OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Ukubhalisa Okuku-inthanethi"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Ukubhalisa kuhlulekile"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values/dimens.xml b/packages/OsuLogin/res/values/dimens.xml
deleted file mode 100644
index 47c8224..0000000
--- a/packages/OsuLogin/res/values/dimens.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<resources>
-    <!-- Default screen margins, per the Android Design guidelines. -->
-    <dimen name="activity_horizontal_margin">16dp</dimen>
-    <dimen name="activity_vertical_margin">16dp</dimen>
-</resources>
diff --git a/packages/OsuLogin/res/values/strings.xml b/packages/OsuLogin/res/values/strings.xml
deleted file mode 100644
index 14de0f5..0000000
--- a/packages/OsuLogin/res/values/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<resources>
-    <!-- application name [CHAR LIMIT=32] -->
-    <string name="app_name">OsuLogin</string>
-    <!-- action bar label [CHAR LIMIT=32] -->
-    <string name="action_bar_label">Online Sign Up</string>
-    <!-- toast message [CHAR LIMIT=32] -->
-    <string name="sign_up_failed">Sign-up failed</string>
-</resources>
diff --git a/packages/OsuLogin/res/values/styles.xml b/packages/OsuLogin/res/values/styles.xml
deleted file mode 100644
index f6c2339..0000000
--- a/packages/OsuLogin/res/values/styles.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<resources>
-
-    <!--
-        Base application theme, dependent on API level. This theme is replaced
-        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
-    -->
-    <style name="AppBaseTheme" parent="@android:style/Theme.DeviceDefault.Settings">
-        <!--
-            Theme customizations available in newer API levels can go in
-            res/values-vXX/styles.xml, while customizations related to
-            backward-compatibility can go here.
-        -->
-    </style>
-
-    <!-- Application theme. -->
-    <style name="AppTheme" parent="AppBaseTheme">
-        <!-- All customizations that are NOT specific to a particular API-level can go here. -->
-    </style>
-</resources>
diff --git a/packages/OsuLogin/res/xml/network_security_config.xml b/packages/OsuLogin/res/xml/network_security_config.xml
deleted file mode 100644
index 3ef4b84..0000000
--- a/packages/OsuLogin/res/xml/network_security_config.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<network-security-config>
-<base-config cleartextTrafficPermitted="true">
-    <trust-anchors>
-        <certificates src="system" />
-        <certificates src="wfa" />
-    </trust-anchors>
-</base-config>
-</network-security-config>
diff --git a/packages/OsuLogin/src/com/android/hotspot2/osulogin/OsuLoginActivity.java b/packages/OsuLogin/src/com/android/hotspot2/osulogin/OsuLoginActivity.java
deleted file mode 100644
index 9797846..0000000
--- a/packages/OsuLogin/src/com/android/hotspot2/osulogin/OsuLoginActivity.java
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.hotspot2.osulogin;
-
-import static android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED;
-
-import android.app.Activity;
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.net.ConnectivityManager;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.net.NetworkRequest;
-import android.net.wifi.WifiManager;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.view.View;
-import android.webkit.WebChromeClient;
-import android.webkit.WebResourceError;
-import android.webkit.WebResourceRequest;
-import android.webkit.WebSettings;
-import android.webkit.WebView;
-import android.webkit.WebViewClient;
-import android.widget.ProgressBar;
-import android.widget.Toast;
-
-import androidx.annotation.Nullable;
-import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
-
-import java.net.MalformedURLException;
-import java.net.URL;
-
-/**
- * Online Sign Up Login Web View launched during Provision Process of Hotspot 2.0 rel2.
- */
-public class OsuLoginActivity extends Activity {
-    private static final String TAG = "OsuLogin";
-    private static final boolean DBG = true;
-
-    private String mUrl;
-    private String mHostName;
-    private Network mNetwork;
-    private ConnectivityManager mCm;
-    private ConnectivityManager.NetworkCallback mNetworkCallback;
-    private WifiManager mWifiManager;
-    private WebView mWebView;
-    private SwipeRefreshLayout mSwipeRefreshLayout;
-    private ProgressBar mProgressBar;
-    private boolean mForceDisconnect = true;
-    boolean mRedirectResponseReceived = false;
-
-    @Override
-    protected void onCreate(@Nullable Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        if (DBG) {
-            Log.d(TAG, "onCreate: Opening OSU Web View");
-        }
-
-        mWifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
-        if (mWifiManager == null) {
-            Log.e(TAG, "Cannot get wifi service");
-            finishAndRemoveTask();
-            return;
-        }
-
-        if (getIntent() == null) {
-            Log.e(TAG, "Intent is null");
-            finishAndRemoveTask();
-            return;
-        }
-
-        mNetwork = getIntent().getParcelableExtra(WifiManager.EXTRA_OSU_NETWORK);
-        if (mNetwork == null) {
-            Log.e(TAG, "Cannot get the network instance for OSU from intent");
-            finishAndRemoveTask();
-            return;
-        }
-
-        mUrl = getIntent().getStringExtra(WifiManager.EXTRA_URL);
-        if (mUrl == null) {
-            Log.e(TAG, "Cannot get OSU server url from intent");
-            finishAndRemoveTask();
-            return;
-        }
-
-        mHostName = getHost(mUrl);
-        if (mHostName == null) {
-            Log.e(TAG, "Cannot get host from the url");
-            finishAndRemoveTask();
-            return;
-        }
-
-        mCm = (ConnectivityManager) getApplicationContext().getSystemService(
-                Context.CONNECTIVITY_SERVICE);
-        if (mCm == null) {
-            Log.e(TAG, "Cannot get connectivity service");
-            finishAndRemoveTask();
-            return;
-        }
-
-        if (!mCm.bindProcessToNetwork(mNetwork)) {
-            Log.e(TAG, "Network is no longer valid");
-            finishAndRemoveTask();
-            return;
-        }
-
-        final NetworkCapabilities networkCapabilities = mCm.getNetworkCapabilities(mNetwork);
-        if (networkCapabilities == null || !networkCapabilities.hasTransport(
-                NetworkCapabilities.TRANSPORT_WIFI)) {
-            Log.e(TAG, "WiFi is not supported for the Network");
-            finishAndRemoveTask();
-            return;
-        }
-
-        getActionBar().setDisplayShowHomeEnabled(false);
-        getActionBar().setElevation(0); // remove shadow
-        getActionBar().setTitle(getString(R.string.action_bar_label));
-        getActionBar().setSubtitle("");
-        setContentView(R.layout.osu_web_view);
-
-        // Exit this app if network disappeared.
-        mNetworkCallback = new ConnectivityManager.NetworkCallback() {
-            @Override
-            public void onLost(Network network) {
-                if (DBG) {
-                    Log.d(TAG, "Lost for the current Network, close the browser");
-                }
-                mForceDisconnect = false; // It is already disconnected.
-                if (!mRedirectResponseReceived) {
-                    showSignUpFailedToast();
-                }
-                if (mNetwork.equals(network)) {
-                    finishAndRemoveTask();
-                }
-            }
-        };
-
-        mCm.registerNetworkCallback(
-                new NetworkRequest.Builder().addTransportType(
-                        NetworkCapabilities.TRANSPORT_WIFI).removeCapability(
-                        NET_CAPABILITY_TRUSTED).build(),
-                mNetworkCallback);
-
-        mWebView = findViewById(R.id.webview);
-        mWebView.clearCache(true);
-        WebSettings webSettings = mWebView.getSettings();
-        webSettings.setJavaScriptEnabled(true);
-        webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE);
-        webSettings.setUseWideViewPort(true);
-        webSettings.setLoadWithOverviewMode(true);
-        webSettings.setSupportZoom(true);
-        webSettings.setBuiltInZoomControls(true);
-        webSettings.setDisplayZoomControls(false);
-        mProgressBar = findViewById(R.id.progress_bar);
-        mWebView.setWebViewClient(new OsuWebViewClient());
-        mWebView.setWebChromeClient(new WebChromeClient() {
-            @Override
-            public void onProgressChanged(WebView view, int newProgress) {
-                mProgressBar.setProgress(newProgress);
-            }
-        });
-
-        if (DBG) {
-            Log.d(TAG, "OSU Web View to " + mUrl);
-        }
-
-        mWebView.loadUrl(mUrl);
-        mSwipeRefreshLayout = findViewById(R.id.swipe_refresh);
-        mSwipeRefreshLayout.setOnRefreshListener(() -> {
-            mWebView.reload();
-            mSwipeRefreshLayout.setRefreshing(true);
-        });
-    }
-
-    @Override
-    public boolean onKeyDown(int keyCode, KeyEvent event) {
-        // Check if the key event was the Back button.
-        if ((keyCode == KeyEvent.KEYCODE_BACK)) {
-            // If there is a history to move back
-            if (mWebView.canGoBack()) {
-                mWebView.goBack();
-                return true;
-            }
-        }
-        return super.onKeyDown(keyCode, event);
-    }
-
-    @Override
-    protected void onDestroy() {
-        if (mNetworkCallback != null) {
-            mCm.unregisterNetworkCallback(mNetworkCallback);
-            mNetworkCallback = null;
-        }
-        if (mWifiManager != null && mForceDisconnect) {
-            mWifiManager.disconnect();
-            mWifiManager = null;
-        }
-        super.onDestroy();
-    }
-
-    private String getHost(String url) {
-        try {
-            return new URL(url).getHost();
-        } catch (MalformedURLException e) {
-            Log.e(TAG, "Invalid URL " + url);
-        }
-        return null;
-    }
-
-    private String getHeaderSubtitle(String urlString) {
-        try {
-            URL url = new URL(urlString);
-            return url.getProtocol() + "://" +  url.getHost();
-        } catch (MalformedURLException e) {
-            Log.e(TAG, "Invalid URL " + urlString);
-        }
-        return "";
-    }
-
-    private void showSignUpFailedToast() {
-        Toast.makeText(getApplicationContext(), R.string.sign_up_failed,
-                Toast.LENGTH_SHORT).show();
-    }
-
-    private class OsuWebViewClient extends WebViewClient {
-        boolean mPageError = false;
-
-        @Override
-        public void onPageStarted(WebView view, String urlString, Bitmap favicon) {
-            String subtitle = getHeaderSubtitle(urlString);
-            getActionBar().setSubtitle(subtitle);
-            mProgressBar.setVisibility(View.VISIBLE);
-        }
-
-        @Override
-        public void onPageFinished(WebView view, String url) {
-            mProgressBar.setVisibility(View.INVISIBLE);
-            mSwipeRefreshLayout.setRefreshing(false);
-
-            // Do not show the page error on UI.
-            if (mPageError) {
-                if (mRedirectResponseReceived) {
-                    // Do not disconnect current connection while provisioning is in progress.
-                    mForceDisconnect = false;
-                }
-                finishAndRemoveTask();
-            }
-        }
-
-        @Override
-        public void onReceivedError(WebView view, WebResourceRequest request,
-                WebResourceError error) {
-            if (request.getUrl().toString().startsWith("http://127.0.0.1")) {
-                mRedirectResponseReceived = true;
-                view.stopLoading();
-            }
-
-            if (request.isForMainFrame()) {
-                // This happens right after getting HTTP redirect response from an OSU server
-                // since no more Http request is allowed to send to the OSU server.
-                mPageError = true;
-                Log.e(TAG, "onReceived Error for MainFrame: " + error.getErrorCode());
-            }
-        }
-    }
-}
diff --git a/packages/SystemUI/res/values-be/strings_tv.xml b/packages/SystemUI/res/values-be/strings_tv.xml
index c75a492..14a4e55 100644
--- a/packages/SystemUI/res/values-be/strings_tv.xml
+++ b/packages/SystemUI/res/values-be/strings_tv.xml
@@ -22,7 +22,7 @@
     <string name="notification_channel_tv_pip" msgid="844249465483874817">"Відарыс у відарысе"</string>
     <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(Праграма без назвы)"</string>
     <string name="pip_close" msgid="5775212044472849930">"Закрыць PIP"</string>
-    <string name="pip_fullscreen" msgid="3877997489869475181">"Ва ўвесь экран"</string>
+    <string name="pip_fullscreen" msgid="3877997489869475181">"Поўнаэкранны рэжым"</string>
     <string name="mic_active" msgid="5766614241012047024">"Мікрафон актыўны"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"Праграма \"%1$s\" атрымала доступ да мікрафона"</string>
 </resources>
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 3f867f6..dd0e1f6 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -1836,11 +1836,13 @@
         if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "bindService: " + service
                 + " type=" + resolvedType + " conn=" + connection.asBinder()
                 + " flags=0x" + Integer.toHexString(flags));
+        final int callingPid = Binder.getCallingPid();
+        final int callingUid = Binder.getCallingUid();
         final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
         if (callerApp == null) {
             throw new SecurityException(
                     "Unable to find app for caller " + caller
-                    + " (pid=" + Binder.getCallingPid()
+                    + " (pid=" + callingPid
                     + ") when binding service " + service);
         }
 
@@ -1880,19 +1882,19 @@
         }
 
         if ((flags & Context.BIND_SCHEDULE_LIKE_TOP_APP) != 0 && !isCallerSystem) {
-            throw new SecurityException("Non-system caller (pid=" + Binder.getCallingPid()
+            throw new SecurityException("Non-system caller (pid=" + callingPid
                     + ") set BIND_SCHEDULE_LIKE_TOP_APP when binding service " + service);
         }
 
         if ((flags & Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0 && !isCallerSystem) {
             throw new SecurityException(
-                    "Non-system caller " + caller + " (pid=" + Binder.getCallingPid()
+                    "Non-system caller " + caller + " (pid=" + callingPid
                     + ") set BIND_ALLOW_WHITELIST_MANAGEMENT when binding service " + service);
         }
 
         if ((flags & Context.BIND_ALLOW_INSTANT) != 0 && !isCallerSystem) {
             throw new SecurityException(
-                    "Non-system caller " + caller + " (pid=" + Binder.getCallingPid()
+                    "Non-system caller " + caller + " (pid=" + callingPid
                             + ") set BIND_ALLOW_INSTANT when binding service " + service);
         }
 
@@ -1908,7 +1910,7 @@
 
         ServiceLookupResult res =
             retrieveServiceLocked(service, instanceName, resolvedType, callingPackage,
-                    Binder.getCallingPid(), Binder.getCallingUid(), userId, true,
+                    callingPid, callingUid, userId, true,
                     callerFg, isBindExternal, allowInstant);
         if (res == null) {
             return 0;
@@ -2068,7 +2070,7 @@
             if (!s.mAllowWhileInUsePermissionInFgs) {
                 s.mAllowWhileInUsePermissionInFgs =
                         shouldAllowWhileInUsePermissionInFgsLocked(callingPackage,
-                                Binder.getCallingPid(), Binder.getCallingUid(),
+                                callingPid, callingUid,
                                 service, s, false);
             }
 
diff --git a/services/core/jni/com_android_server_power_PowerManagerService.cpp b/services/core/jni/com_android_server_power_PowerManagerService.cpp
index 4698383..85d5c1f 100644
--- a/services/core/jni/com_android_server_power_PowerManagerService.cpp
+++ b/services/core/jni/com_android_server_power_PowerManagerService.cpp
@@ -190,19 +190,18 @@
     static std::array<std::atomic<HalSupport>,
                       static_cast<int32_t>(Boost::DISPLAY_UPDATE_IMMINENT) + 1>
             boostSupportedArray = {HalSupport::UNKNOWN};
+    size_t idx = static_cast<size_t>(boost);
 
     // Quick return if boost is not supported by HAL
-    if (boost > Boost::DISPLAY_UPDATE_IMMINENT ||
-        boostSupportedArray[static_cast<int32_t>(boost)] == HalSupport::OFF) {
+    if (idx >= boostSupportedArray.size() || boostSupportedArray[idx] == HalSupport::OFF) {
         ALOGV("Skipped setPowerBoost %s because HAL doesn't support it", toString(boost).c_str());
         return;
     }
 
-    if (boostSupportedArray[static_cast<int32_t>(boost)] == HalSupport::UNKNOWN) {
+    if (boostSupportedArray[idx] == HalSupport::UNKNOWN) {
         bool isSupported = false;
         handle->isBoostSupported(boost, &isSupported);
-        boostSupportedArray[static_cast<int32_t>(boost)] =
-            isSupported ? HalSupport::ON : HalSupport::OFF;
+        boostSupportedArray[idx] = isSupported ? HalSupport::ON : HalSupport::OFF;
         if (!isSupported) {
             ALOGV("Skipped setPowerBoost %s because HAL doesn't support it",
                   toString(boost).c_str());
@@ -230,19 +229,18 @@
     // Need to increase the array if more mode supported.
     static std::array<std::atomic<HalSupport>, static_cast<int32_t>(Mode::DISPLAY_INACTIVE) + 1>
             modeSupportedArray = {HalSupport::UNKNOWN};
+    size_t idx = static_cast<size_t>(mode);
 
     // Quick return if mode is not supported by HAL
-    if (mode > Mode::DISPLAY_INACTIVE ||
-        modeSupportedArray[static_cast<int32_t>(mode)] == HalSupport::OFF) {
+    if (idx >= modeSupportedArray.size() || modeSupportedArray[idx] == HalSupport::OFF) {
         ALOGV("Skipped setPowerMode %s because HAL doesn't support it", toString(mode).c_str());
         return false;
     }
 
-    if (modeSupportedArray[static_cast<int32_t>(mode)] == HalSupport::UNKNOWN) {
+    if (modeSupportedArray[idx] == HalSupport::UNKNOWN) {
         bool isSupported = false;
         handle->isModeSupported(mode, &isSupported);
-        modeSupportedArray[static_cast<int32_t>(mode)] =
-            isSupported ? HalSupport::ON : HalSupport::OFF;
+        modeSupportedArray[idx] = isSupported ? HalSupport::ON : HalSupport::OFF;
         if (!isSupported) {
             ALOGV("Skipped setPowerMode %s because HAL doesn't support it", toString(mode).c_str());
             return false;
diff --git a/services/net/Android.bp b/services/net/Android.bp
index 6bc0eaf..312b1dd 100644
--- a/services/net/Android.bp
+++ b/services/net/Android.bp
@@ -57,6 +57,8 @@
     visibility: [
         "//frameworks/opt/net/wifi/service",
         "//frameworks/opt/net/wifi/tests/wifitests",
+        "//packages/modules/Wifi/service",
+        "//packages/modules/Wifi/service/tests/wifitests",
     ],
 }
 
diff --git a/wifi/Android.bp b/wifi/Android.bp
deleted file mode 100644
index 0eac968..0000000
--- a/wifi/Android.bp
+++ /dev/null
@@ -1,152 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-java_defaults {
-    name: "wifi-module-sdk-version-defaults",
-    min_sdk_version: "30",
-    target_sdk_version: "30",
-}
-
-filegroup {
-    name: "framework-wifi-updatable-exported-aidl-sources",
-    srcs: ["aidl-export/**/*.aidl"],
-    path: "aidl-export",
-    visibility: ["//visibility:private"],
-}
-
-filegroup {
-    name: "framework-wifi-updatable-java-sources",
-    srcs: [
-        "java/**/*.java",
-        "java/**/*.aidl",
-    ],
-    path: "java",
-    visibility: ["//visibility:private"],
-}
-
-filegroup {
-    name: "framework-wifi-updatable-sources",
-    srcs: [
-        ":framework-wifi-updatable-java-sources",
-        ":framework-wifi-updatable-exported-aidl-sources",
-    ],
-}
-
-filegroup {
-    name: "framework-wifi-annotations",
-    srcs: ["java/android/net/wifi/WifiAnnotations.java"],
-}
-
-// list of tests that are allowed to access @hide APIs from framework-wifi
-test_access_hidden_api_whitelist = [
-    "//frameworks/base/wifi/tests",
-    "//frameworks/base/wifi/non-updatable/tests",
-    "//frameworks/opt/net/wifi/tests/wifitests:__subpackages__",
-
-    "//external/robolectric-shadows:__subpackages__",
-    "//frameworks/base/packages/SettingsLib/tests/integ",
-    "//external/sl4a:__subpackages__",
-]
-
-// wifi-service needs pre-jarjared version of framework-wifi so it can reference copied utility
-// classes before they are renamed.
-java_library {
-    name: "framework-wifi-pre-jarjar",
-    defaults: ["wifi-module-sdk-version-defaults"],
-    sdk_version: "module_current",
-    static_libs: [
-        "framework-wifi-util-lib",
-        "android.hardware.wifi-V1.0-java-constants",
-    ],
-    libs: [
-        "framework-annotations-lib",
-        "unsupportedappusage", // for android.compat.annotation.UnsupportedAppUsage
-    ],
-    srcs: [
-        ":framework-wifi-updatable-sources",
-        ":framework-wifi-util-lib-aidls",
-    ],
-    // java_api_finder must accompany `srcs`
-    plugins: ["java_api_finder"],
-    installable: false,
-    visibility: [
-        "//frameworks/opt/net/wifi/service",
-        "//frameworks/opt/net/wifi/tests/wifitests",
-    ],
-}
-
-// post-jarjar version of framework-wifi
-java_sdk_library {
-    name: "framework-wifi",
-    defaults: [
-        "framework-module-defaults",
-        "wifi-module-sdk-version-defaults",
-    ],
-    static_libs: [
-        "framework-wifi-util-lib",
-        "android.hardware.wifi-V1.0-java-constants",
-    ],
-    libs: [
-        "unsupportedappusage", // for android.compat.annotation.UnsupportedAppUsage
-    ],
-    srcs: [
-        ":framework-wifi-updatable-sources",
-        ":framework-wifi-util-lib-aidls",
-    ],
-
-    jarjar_rules: ":wifi-jarjar-rules",
-
-    installable: true,
-    optimize: {
-        enabled: false
-    },
-    hostdex: true, // for hiddenapi check
-
-    // Restrict access to implementation library.
-    impl_library_visibility: [
-        "//frameworks/opt/net/wifi/service:__subpackages__",
-    ] + test_access_hidden_api_whitelist,
-
-    apex_available: [
-        "com.android.wifi",
-        "test_com.android.wifi",
-    ],
-    permitted_packages: [
-        "android.hardware.wifi",
-        "android.net.wifi",
-        // Created by jarjar rules.
-        "com.android.wifi.x",
-    ],
-}
-
-// defaults for tests that need to build against framework-wifi's @hide APIs
-java_defaults {
-    name: "framework-wifi-test-defaults",
-    sdk_version: "core_platform", // tests can use @CorePlatformApi's
-    libs: [
-        // order matters: classes in framework-wifi are resolved before framework, meaning
-        // @hide APIs in framework-wifi are resolved before @SystemApi stubs in framework
-        "framework-wifi.impl",
-        "framework",
-
-        // if sdk_version="" this gets automatically included, but here we need to add manually.
-        "framework-res",
-    ],
-    visibility: test_access_hidden_api_whitelist,
-}
-
-filegroup {
-    name: "wifi-jarjar-rules",
-    srcs: ["jarjar-rules.txt"],
-}
diff --git a/wifi/MOVED.txt b/wifi/MOVED.txt
new file mode 100644
index 0000000..6ffb23c
--- /dev/null
+++ b/wifi/MOVED.txt
@@ -0,0 +1,8 @@
+Source code and tests for Wifi module APIs have moved to
+packages/modules/Wifi/framework.
+
+- frameworks/base/wifi/java -> packages/modules/Wifi/framework/java
+- frameworks/base/wifi/tests -> packages/modules/Wifi/framework/tests
+
+What remains in frameworks/base/wifi are Wifi APIs that
+are not part of the Wifi module.
diff --git a/wifi/TEST_MAPPING b/wifi/TEST_MAPPING
deleted file mode 100644
index bb5e241..0000000
--- a/wifi/TEST_MAPPING
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-  "mainline-presubmit": [
-    {
-      // Install com.google.android.wifi.apex and run FrameworksWifiApiTests.
-      "name": "FrameworksWifiApiTests[com.google.android.wifi.apex]"
-    },
-    {
-      "name": "CtsWifiTestCases[com.google.android.wifi.apex]",
-      "options": [
-        {
-          "exclude-annotation": "android.net.wifi.cts.VirtualDeviceNotSupported"
-        }
-      ]
-    }
-  ]
-}
diff --git a/wifi/aidl-export/android/net/wifi/ScanResult.aidl b/wifi/aidl-export/android/net/wifi/ScanResult.aidl
deleted file mode 100644
index b30689c..0000000
--- a/wifi/aidl-export/android/net/wifi/ScanResult.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) 2008, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-@JavaOnlyStableParcelable parcelable ScanResult;
diff --git a/wifi/aidl-export/android/net/wifi/SoftApCapability.aidl b/wifi/aidl-export/android/net/wifi/SoftApCapability.aidl
deleted file mode 100644
index bf30709..0000000
--- a/wifi/aidl-export/android/net/wifi/SoftApCapability.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-parcelable SoftApCapability;
diff --git a/wifi/aidl-export/android/net/wifi/SoftApConfiguration.aidl b/wifi/aidl-export/android/net/wifi/SoftApConfiguration.aidl
deleted file mode 100644
index 1d06f45..0000000
--- a/wifi/aidl-export/android/net/wifi/SoftApConfiguration.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-parcelable SoftApConfiguration;
\ No newline at end of file
diff --git a/wifi/aidl-export/android/net/wifi/SoftApInfo.aidl b/wifi/aidl-export/android/net/wifi/SoftApInfo.aidl
deleted file mode 100644
index d4551cf..0000000
--- a/wifi/aidl-export/android/net/wifi/SoftApInfo.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-parcelable SoftApInfo;
-
diff --git a/wifi/aidl-export/android/net/wifi/WifiClient.aidl b/wifi/aidl-export/android/net/wifi/WifiClient.aidl
deleted file mode 100644
index accdadd..0000000
--- a/wifi/aidl-export/android/net/wifi/WifiClient.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-@JavaOnlyStableParcelable parcelable WifiClient;
\ No newline at end of file
diff --git a/wifi/aidl-export/android/net/wifi/WifiConfiguration.aidl b/wifi/aidl-export/android/net/wifi/WifiConfiguration.aidl
deleted file mode 100644
index 237a74d..0000000
--- a/wifi/aidl-export/android/net/wifi/WifiConfiguration.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) 2008, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-parcelable WifiConfiguration;
diff --git a/wifi/aidl-export/android/net/wifi/WifiEnterpriseConfig.aidl b/wifi/aidl-export/android/net/wifi/WifiEnterpriseConfig.aidl
deleted file mode 100644
index b0f5f84..0000000
--- a/wifi/aidl-export/android/net/wifi/WifiEnterpriseConfig.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) 2013, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-parcelable WifiEnterpriseConfig;
diff --git a/wifi/aidl-export/android/net/wifi/WifiInfo.aidl b/wifi/aidl-export/android/net/wifi/WifiInfo.aidl
deleted file mode 100644
index db47f0b..0000000
--- a/wifi/aidl-export/android/net/wifi/WifiInfo.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) 2008, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-parcelable WifiInfo;
diff --git a/wifi/aidl-export/android/net/wifi/WifiNetworkConnectionStatistics.aidl b/wifi/aidl-export/android/net/wifi/WifiNetworkConnectionStatistics.aidl
deleted file mode 100644
index 5f497e2..0000000
--- a/wifi/aidl-export/android/net/wifi/WifiNetworkConnectionStatistics.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) 2014, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-parcelable WifiNetworkConnectionStatistics;
diff --git a/wifi/aidl-export/android/net/wifi/WifiNetworkSuggestion.aidl b/wifi/aidl-export/android/net/wifi/WifiNetworkSuggestion.aidl
deleted file mode 100644
index eb6995f..0000000
--- a/wifi/aidl-export/android/net/wifi/WifiNetworkSuggestion.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) 2018, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-parcelable WifiNetworkSuggestion;
diff --git a/wifi/aidl-export/android/net/wifi/WifiUsabilityStatsEntry.aidl b/wifi/aidl-export/android/net/wifi/WifiUsabilityStatsEntry.aidl
deleted file mode 100644
index 839af54..0000000
--- a/wifi/aidl-export/android/net/wifi/WifiUsabilityStatsEntry.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-parcelable WifiUsabilityStatsEntry;
diff --git a/wifi/aidl-export/android/net/wifi/WpsInfo.aidl b/wifi/aidl-export/android/net/wifi/WpsInfo.aidl
deleted file mode 100644
index f5e4ebe..0000000
--- a/wifi/aidl-export/android/net/wifi/WpsInfo.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) 2011, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-parcelable WpsInfo;
diff --git a/wifi/aidl-export/android/net/wifi/aware/Characteristics.aidl b/wifi/aidl-export/android/net/wifi/aware/Characteristics.aidl
deleted file mode 100644
index 77305e9..0000000
--- a/wifi/aidl-export/android/net/wifi/aware/Characteristics.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.aware;
-
-parcelable Characteristics;
diff --git a/wifi/aidl-export/android/net/wifi/aware/PublishConfig.aidl b/wifi/aidl-export/android/net/wifi/aware/PublishConfig.aidl
deleted file mode 100644
index 2e6dd00..0000000
--- a/wifi/aidl-export/android/net/wifi/aware/PublishConfig.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.aware;
-
-parcelable PublishConfig;
diff --git a/wifi/aidl-export/android/net/wifi/aware/SubscribeConfig.aidl b/wifi/aidl-export/android/net/wifi/aware/SubscribeConfig.aidl
deleted file mode 100644
index bd73d5e..0000000
--- a/wifi/aidl-export/android/net/wifi/aware/SubscribeConfig.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.aware;
-
-parcelable SubscribeConfig;
diff --git a/wifi/aidl-export/android/net/wifi/hotspot2/OsuProvider.aidl b/wifi/aidl-export/android/net/wifi/hotspot2/OsuProvider.aidl
deleted file mode 100644
index 23d0f22..0000000
--- a/wifi/aidl-export/android/net/wifi/hotspot2/OsuProvider.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package android.net.wifi.hotspot2;
-
-parcelable OsuProvider;
diff --git a/wifi/aidl-export/android/net/wifi/hotspot2/PasspointConfiguration.aidl b/wifi/aidl-export/android/net/wifi/hotspot2/PasspointConfiguration.aidl
deleted file mode 100644
index 6b1cea8..0000000
--- a/wifi/aidl-export/android/net/wifi/hotspot2/PasspointConfiguration.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) 2016, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.hotspot2;
-
-parcelable PasspointConfiguration;
diff --git a/wifi/aidl-export/android/net/wifi/hotspot2/pps/Credential.aidl b/wifi/aidl-export/android/net/wifi/hotspot2/pps/Credential.aidl
deleted file mode 100644
index 3d8e833..0000000
--- a/wifi/aidl-export/android/net/wifi/hotspot2/pps/Credential.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) 2016, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.hotspot2.pps;
-
-parcelable Credential;
diff --git a/wifi/aidl-export/android/net/wifi/hotspot2/pps/HomeSp.aidl b/wifi/aidl-export/android/net/wifi/hotspot2/pps/HomeSp.aidl
deleted file mode 100644
index 6d343bd..0000000
--- a/wifi/aidl-export/android/net/wifi/hotspot2/pps/HomeSp.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) 2016, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.hotspot2.pps;
-
-parcelable HomeSp;
diff --git a/wifi/aidl-export/android/net/wifi/p2p/WifiP2pConfig.aidl b/wifi/aidl-export/android/net/wifi/p2p/WifiP2pConfig.aidl
deleted file mode 100644
index ea3b280..0000000
--- a/wifi/aidl-export/android/net/wifi/p2p/WifiP2pConfig.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) 2011, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p;
-
-parcelable WifiP2pConfig;
diff --git a/wifi/aidl-export/android/net/wifi/p2p/WifiP2pDevice.aidl b/wifi/aidl-export/android/net/wifi/p2p/WifiP2pDevice.aidl
deleted file mode 100644
index 8790c6f..0000000
--- a/wifi/aidl-export/android/net/wifi/p2p/WifiP2pDevice.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) 2011, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p;
-
-parcelable WifiP2pDevice;
diff --git a/wifi/aidl-export/android/net/wifi/p2p/WifiP2pDeviceList.aidl b/wifi/aidl-export/android/net/wifi/p2p/WifiP2pDeviceList.aidl
deleted file mode 100644
index 6c79009..0000000
--- a/wifi/aidl-export/android/net/wifi/p2p/WifiP2pDeviceList.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) 2011, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p;
-
-parcelable WifiP2pDeviceList;
diff --git a/wifi/aidl-export/android/net/wifi/p2p/WifiP2pGroup.aidl b/wifi/aidl-export/android/net/wifi/p2p/WifiP2pGroup.aidl
deleted file mode 100644
index 403f2b1..0000000
--- a/wifi/aidl-export/android/net/wifi/p2p/WifiP2pGroup.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) 2011, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p;
-
-parcelable WifiP2pGroup;
diff --git a/wifi/aidl-export/android/net/wifi/p2p/WifiP2pInfo.aidl b/wifi/aidl-export/android/net/wifi/p2p/WifiP2pInfo.aidl
deleted file mode 100644
index a347148..0000000
--- a/wifi/aidl-export/android/net/wifi/p2p/WifiP2pInfo.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) 2011, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p;
-
-parcelable WifiP2pInfo;
diff --git a/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.aidl b/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.aidl
deleted file mode 100644
index cf2cb4a..0000000
--- a/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p.servicediscovery;
-
-parcelable WifiP2pServiceInfo;
diff --git a/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.aidl b/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.aidl
deleted file mode 100644
index d5a1e8f..0000000
--- a/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p.servicediscovery;
-
-parcelable WifiP2pServiceRequest;
diff --git a/wifi/aidl-export/android/net/wifi/rtt/RangingRequest.aidl b/wifi/aidl-export/android/net/wifi/rtt/RangingRequest.aidl
deleted file mode 100644
index 8053c94..0000000
--- a/wifi/aidl-export/android/net/wifi/rtt/RangingRequest.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.rtt;
-
-parcelable RangingRequest;
diff --git a/wifi/aidl-export/android/net/wifi/rtt/RangingResult.aidl b/wifi/aidl-export/android/net/wifi/rtt/RangingResult.aidl
deleted file mode 100644
index ae295a6..0000000
--- a/wifi/aidl-export/android/net/wifi/rtt/RangingResult.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.rtt;
-
-parcelable RangingResult;
diff --git a/wifi/aidl-export/android/net/wifi/rtt/ResponderConfig.aidl b/wifi/aidl-export/android/net/wifi/rtt/ResponderConfig.aidl
deleted file mode 100644
index fd3988a..0000000
--- a/wifi/aidl-export/android/net/wifi/rtt/ResponderConfig.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.rtt;
-
-parcelable ResponderConfig;
diff --git a/wifi/api/current.txt b/wifi/api/current.txt
deleted file mode 100644
index 53c3b33..0000000
--- a/wifi/api/current.txt
+++ /dev/null
@@ -1,1199 +0,0 @@
-// Signature format: 2.0
-package android.net.wifi {
-
-  public abstract class EasyConnectStatusCallback {
-    field public static final int EASY_CONNECT_EVENT_FAILURE_AUTHENTICATION = -2; // 0xfffffffe
-    field public static final int EASY_CONNECT_EVENT_FAILURE_BUSY = -5; // 0xfffffffb
-    field public static final int EASY_CONNECT_EVENT_FAILURE_CANNOT_FIND_NETWORK = -10; // 0xfffffff6
-    field public static final int EASY_CONNECT_EVENT_FAILURE_CONFIGURATION = -4; // 0xfffffffc
-    field public static final int EASY_CONNECT_EVENT_FAILURE_ENROLLEE_AUTHENTICATION = -11; // 0xfffffff5
-    field public static final int EASY_CONNECT_EVENT_FAILURE_ENROLLEE_REJECTED_CONFIGURATION = -12; // 0xfffffff4
-    field public static final int EASY_CONNECT_EVENT_FAILURE_GENERIC = -7; // 0xfffffff9
-    field public static final int EASY_CONNECT_EVENT_FAILURE_INVALID_NETWORK = -9; // 0xfffffff7
-    field public static final int EASY_CONNECT_EVENT_FAILURE_INVALID_URI = -1; // 0xffffffff
-    field public static final int EASY_CONNECT_EVENT_FAILURE_NOT_COMPATIBLE = -3; // 0xfffffffd
-    field public static final int EASY_CONNECT_EVENT_FAILURE_NOT_SUPPORTED = -8; // 0xfffffff8
-    field public static final int EASY_CONNECT_EVENT_FAILURE_TIMEOUT = -6; // 0xfffffffa
-  }
-
-  public final class ScanResult implements android.os.Parcelable {
-    ctor public ScanResult(@NonNull android.net.wifi.ScanResult);
-    ctor public ScanResult();
-    method public int describeContents();
-    method @NonNull public java.util.List<android.net.wifi.ScanResult.InformationElement> getInformationElements();
-    method public int getWifiStandard();
-    method public boolean is80211mcResponder();
-    method public boolean isPasspointNetwork();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public String BSSID;
-    field public static final int CHANNEL_WIDTH_160MHZ = 3; // 0x3
-    field public static final int CHANNEL_WIDTH_20MHZ = 0; // 0x0
-    field public static final int CHANNEL_WIDTH_40MHZ = 1; // 0x1
-    field public static final int CHANNEL_WIDTH_80MHZ = 2; // 0x2
-    field public static final int CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 4; // 0x4
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.ScanResult> CREATOR;
-    field public String SSID;
-    field public static final int WIFI_STANDARD_11AC = 5; // 0x5
-    field public static final int WIFI_STANDARD_11AX = 6; // 0x6
-    field public static final int WIFI_STANDARD_11N = 4; // 0x4
-    field public static final int WIFI_STANDARD_LEGACY = 1; // 0x1
-    field public static final int WIFI_STANDARD_UNKNOWN = 0; // 0x0
-    field public String capabilities;
-    field public int centerFreq0;
-    field public int centerFreq1;
-    field public int channelWidth;
-    field public int frequency;
-    field public int level;
-    field public CharSequence operatorFriendlyName;
-    field public long timestamp;
-    field public CharSequence venueName;
-  }
-
-  public static class ScanResult.InformationElement {
-    ctor public ScanResult.InformationElement(@NonNull android.net.wifi.ScanResult.InformationElement);
-    method @NonNull public java.nio.ByteBuffer getBytes();
-    method public int getId();
-    method public int getIdExt();
-  }
-
-  public final class SoftApConfiguration implements android.os.Parcelable {
-    method public int describeContents();
-    method @Nullable public android.net.MacAddress getBssid();
-    method @Nullable public String getPassphrase();
-    method public int getSecurityType();
-    method @Nullable public String getSsid();
-    method public boolean isHiddenSsid();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.SoftApConfiguration> CREATOR;
-    field public static final int SECURITY_TYPE_OPEN = 0; // 0x0
-    field public static final int SECURITY_TYPE_WPA2_PSK = 1; // 0x1
-    field public static final int SECURITY_TYPE_WPA3_SAE = 3; // 0x3
-    field public static final int SECURITY_TYPE_WPA3_SAE_TRANSITION = 2; // 0x2
-  }
-
-  public enum SupplicantState implements android.os.Parcelable {
-    method public int describeContents();
-    method public static boolean isValidState(android.net.wifi.SupplicantState);
-    method public void writeToParcel(android.os.Parcel, int);
-    enum_constant public static final android.net.wifi.SupplicantState ASSOCIATED;
-    enum_constant public static final android.net.wifi.SupplicantState ASSOCIATING;
-    enum_constant public static final android.net.wifi.SupplicantState AUTHENTICATING;
-    enum_constant public static final android.net.wifi.SupplicantState COMPLETED;
-    enum_constant public static final android.net.wifi.SupplicantState DISCONNECTED;
-    enum_constant public static final android.net.wifi.SupplicantState DORMANT;
-    enum_constant public static final android.net.wifi.SupplicantState FOUR_WAY_HANDSHAKE;
-    enum_constant public static final android.net.wifi.SupplicantState GROUP_HANDSHAKE;
-    enum_constant public static final android.net.wifi.SupplicantState INACTIVE;
-    enum_constant public static final android.net.wifi.SupplicantState INTERFACE_DISABLED;
-    enum_constant public static final android.net.wifi.SupplicantState INVALID;
-    enum_constant public static final android.net.wifi.SupplicantState SCANNING;
-    enum_constant public static final android.net.wifi.SupplicantState UNINITIALIZED;
-  }
-
-  @Deprecated public class WifiConfiguration implements android.os.Parcelable {
-    ctor @Deprecated public WifiConfiguration();
-    ctor @Deprecated public WifiConfiguration(@NonNull android.net.wifi.WifiConfiguration);
-    method public int describeContents();
-    method @Deprecated public android.net.ProxyInfo getHttpProxy();
-    method @Deprecated @NonNull public String getKey();
-    method @Deprecated @NonNull public android.net.MacAddress getRandomizedMacAddress();
-    method @Deprecated public boolean isPasspoint();
-    method @Deprecated public void setHttpProxy(android.net.ProxyInfo);
-    method @Deprecated public void setSecurityParams(int);
-    method public void writeToParcel(android.os.Parcel, int);
-    field @Deprecated public String BSSID;
-    field @Deprecated public String FQDN;
-    field @Deprecated public static final int SECURITY_TYPE_EAP = 3; // 0x3
-    field @Deprecated public static final int SECURITY_TYPE_EAP_SUITE_B = 5; // 0x5
-    field @Deprecated public static final int SECURITY_TYPE_OPEN = 0; // 0x0
-    field @Deprecated public static final int SECURITY_TYPE_OWE = 6; // 0x6
-    field @Deprecated public static final int SECURITY_TYPE_PSK = 2; // 0x2
-    field @Deprecated public static final int SECURITY_TYPE_SAE = 4; // 0x4
-    field @Deprecated public static final int SECURITY_TYPE_WAPI_CERT = 8; // 0x8
-    field @Deprecated public static final int SECURITY_TYPE_WAPI_PSK = 7; // 0x7
-    field @Deprecated public static final int SECURITY_TYPE_WEP = 1; // 0x1
-    field @Deprecated public String SSID;
-    field @Deprecated @NonNull public java.util.BitSet allowedAuthAlgorithms;
-    field @Deprecated @NonNull public java.util.BitSet allowedGroupCiphers;
-    field @Deprecated @NonNull public java.util.BitSet allowedGroupManagementCiphers;
-    field @Deprecated @NonNull public java.util.BitSet allowedKeyManagement;
-    field @Deprecated @NonNull public java.util.BitSet allowedPairwiseCiphers;
-    field @Deprecated @NonNull public java.util.BitSet allowedProtocols;
-    field @Deprecated @NonNull public java.util.BitSet allowedSuiteBCiphers;
-    field @Deprecated public android.net.wifi.WifiEnterpriseConfig enterpriseConfig;
-    field @Deprecated public boolean hiddenSSID;
-    field @Deprecated public boolean isHomeProviderNetwork;
-    field @Deprecated public int networkId;
-    field @Deprecated public String preSharedKey;
-    field @Deprecated public int priority;
-    field @Deprecated public String providerFriendlyName;
-    field @Deprecated public long[] roamingConsortiumIds;
-    field @Deprecated public int status;
-    field @Deprecated public String[] wepKeys;
-    field @Deprecated public int wepTxKeyIndex;
-  }
-
-  @Deprecated public static class WifiConfiguration.AuthAlgorithm {
-    field @Deprecated public static final int LEAP = 2; // 0x2
-    field @Deprecated public static final int OPEN = 0; // 0x0
-    field @Deprecated public static final int SAE = 3; // 0x3
-    field @Deprecated public static final int SHARED = 1; // 0x1
-    field @Deprecated public static final String[] strings;
-    field @Deprecated public static final String varName = "auth_alg";
-  }
-
-  @Deprecated public static class WifiConfiguration.GroupCipher {
-    field @Deprecated public static final int CCMP = 3; // 0x3
-    field @Deprecated public static final int GCMP_256 = 5; // 0x5
-    field @Deprecated public static final int SMS4 = 6; // 0x6
-    field @Deprecated public static final int TKIP = 2; // 0x2
-    field @Deprecated public static final int WEP104 = 1; // 0x1
-    field @Deprecated public static final int WEP40 = 0; // 0x0
-    field @Deprecated public static final String[] strings;
-    field @Deprecated public static final String varName = "group";
-  }
-
-  @Deprecated public static class WifiConfiguration.GroupMgmtCipher {
-    field @Deprecated public static final int BIP_CMAC_256 = 0; // 0x0
-    field @Deprecated public static final int BIP_GMAC_128 = 1; // 0x1
-    field @Deprecated public static final int BIP_GMAC_256 = 2; // 0x2
-  }
-
-  @Deprecated public static class WifiConfiguration.KeyMgmt {
-    field @Deprecated public static final int IEEE8021X = 3; // 0x3
-    field @Deprecated public static final int NONE = 0; // 0x0
-    field @Deprecated public static final int OWE = 9; // 0x9
-    field @Deprecated public static final int SAE = 8; // 0x8
-    field @Deprecated public static final int SUITE_B_192 = 10; // 0xa
-    field @Deprecated public static final int WPA_EAP = 2; // 0x2
-    field @Deprecated public static final int WPA_PSK = 1; // 0x1
-    field @Deprecated public static final String[] strings;
-    field @Deprecated public static final String varName = "key_mgmt";
-  }
-
-  @Deprecated public static class WifiConfiguration.PairwiseCipher {
-    field @Deprecated public static final int CCMP = 2; // 0x2
-    field @Deprecated public static final int GCMP_256 = 3; // 0x3
-    field @Deprecated public static final int NONE = 0; // 0x0
-    field @Deprecated public static final int SMS4 = 4; // 0x4
-    field @Deprecated public static final int TKIP = 1; // 0x1
-    field @Deprecated public static final String[] strings;
-    field @Deprecated public static final String varName = "pairwise";
-  }
-
-  @Deprecated public static class WifiConfiguration.Protocol {
-    field @Deprecated public static final int RSN = 1; // 0x1
-    field @Deprecated public static final int WAPI = 3; // 0x3
-    field @Deprecated public static final int WPA = 0; // 0x0
-    field @Deprecated public static final String[] strings;
-    field @Deprecated public static final String varName = "proto";
-  }
-
-  @Deprecated public static class WifiConfiguration.Status {
-    field @Deprecated public static final int CURRENT = 0; // 0x0
-    field @Deprecated public static final int DISABLED = 1; // 0x1
-    field @Deprecated public static final int ENABLED = 2; // 0x2
-    field @Deprecated public static final String[] strings;
-  }
-
-  public class WifiEnterpriseConfig implements android.os.Parcelable {
-    ctor public WifiEnterpriseConfig();
-    ctor public WifiEnterpriseConfig(android.net.wifi.WifiEnterpriseConfig);
-    method public int describeContents();
-    method public String getAltSubjectMatch();
-    method public String getAnonymousIdentity();
-    method @Nullable public java.security.cert.X509Certificate getCaCertificate();
-    method @Nullable public java.security.cert.X509Certificate[] getCaCertificates();
-    method public java.security.cert.X509Certificate getClientCertificate();
-    method @Nullable public java.security.cert.X509Certificate[] getClientCertificateChain();
-    method @Nullable public java.security.PrivateKey getClientPrivateKey();
-    method public String getDomainSuffixMatch();
-    method public int getEapMethod();
-    method public String getIdentity();
-    method public String getPassword();
-    method public int getPhase2Method();
-    method public String getPlmn();
-    method public String getRealm();
-    method @Deprecated public String getSubjectMatch();
-    method public boolean isAuthenticationSimBased();
-    method public void setAltSubjectMatch(String);
-    method public void setAnonymousIdentity(String);
-    method public void setCaCertificate(@Nullable java.security.cert.X509Certificate);
-    method public void setCaCertificates(@Nullable java.security.cert.X509Certificate[]);
-    method public void setClientKeyEntry(java.security.PrivateKey, java.security.cert.X509Certificate);
-    method public void setClientKeyEntryWithCertificateChain(java.security.PrivateKey, java.security.cert.X509Certificate[]);
-    method public void setDomainSuffixMatch(String);
-    method public void setEapMethod(int);
-    method public void setIdentity(String);
-    method public void setPassword(String);
-    method public void setPhase2Method(int);
-    method public void setPlmn(String);
-    method public void setRealm(String);
-    method @Deprecated public void setSubjectMatch(String);
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.WifiEnterpriseConfig> CREATOR;
-    field public static final String EXTRA_WAPI_AS_CERTIFICATE_DATA = "android.net.wifi.extra.WAPI_AS_CERTIFICATE_DATA";
-    field public static final String EXTRA_WAPI_AS_CERTIFICATE_NAME = "android.net.wifi.extra.WAPI_AS_CERTIFICATE_NAME";
-    field public static final String EXTRA_WAPI_USER_CERTIFICATE_DATA = "android.net.wifi.extra.WAPI_USER_CERTIFICATE_DATA";
-    field public static final String EXTRA_WAPI_USER_CERTIFICATE_NAME = "android.net.wifi.extra.WAPI_USER_CERTIFICATE_NAME";
-    field public static final String WAPI_AS_CERTIFICATE = "WAPIAS_";
-    field public static final String WAPI_USER_CERTIFICATE = "WAPIUSR_";
-  }
-
-  public static final class WifiEnterpriseConfig.Eap {
-    field public static final int AKA = 5; // 0x5
-    field public static final int AKA_PRIME = 6; // 0x6
-    field public static final int NONE = -1; // 0xffffffff
-    field public static final int PEAP = 0; // 0x0
-    field public static final int PWD = 3; // 0x3
-    field public static final int SIM = 4; // 0x4
-    field public static final int TLS = 1; // 0x1
-    field public static final int TTLS = 2; // 0x2
-    field public static final int UNAUTH_TLS = 7; // 0x7
-    field public static final int WAPI_CERT = 8; // 0x8
-  }
-
-  public static final class WifiEnterpriseConfig.Phase2 {
-    field public static final int AKA = 6; // 0x6
-    field public static final int AKA_PRIME = 7; // 0x7
-    field public static final int GTC = 4; // 0x4
-    field public static final int MSCHAP = 2; // 0x2
-    field public static final int MSCHAPV2 = 3; // 0x3
-    field public static final int NONE = 0; // 0x0
-    field public static final int PAP = 1; // 0x1
-    field public static final int SIM = 5; // 0x5
-  }
-
-  public class WifiInfo implements android.os.Parcelable {
-    method public int describeContents();
-    method public String getBSSID();
-    method public static android.net.NetworkInfo.DetailedState getDetailedStateOf(android.net.wifi.SupplicantState);
-    method public int getFrequency();
-    method public boolean getHiddenSSID();
-    method public int getIpAddress();
-    method public int getLinkSpeed();
-    method public String getMacAddress();
-    method public int getMaxSupportedRxLinkSpeedMbps();
-    method public int getMaxSupportedTxLinkSpeedMbps();
-    method public int getNetworkId();
-    method @Nullable public String getPasspointFqdn();
-    method @Nullable public String getPasspointProviderFriendlyName();
-    method public int getRssi();
-    method @IntRange(from=0xffffffff) public int getRxLinkSpeedMbps();
-    method public String getSSID();
-    method public android.net.wifi.SupplicantState getSupplicantState();
-    method @IntRange(from=0xffffffff) public int getTxLinkSpeedMbps();
-    method public int getWifiStandard();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final String FREQUENCY_UNITS = "MHz";
-    field public static final String LINK_SPEED_UNITS = "Mbps";
-    field public static final int LINK_SPEED_UNKNOWN = -1; // 0xffffffff
-  }
-
-  public static final class WifiInfo.Builder {
-    ctor public WifiInfo.Builder();
-    method @NonNull public android.net.wifi.WifiInfo build();
-    method @NonNull public android.net.wifi.WifiInfo.Builder setBssid(@NonNull String);
-    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[]);
-  }
-
-  public class WifiManager {
-    method @Deprecated public int addNetwork(android.net.wifi.WifiConfiguration);
-    method @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE) public int addNetworkSuggestions(@NonNull java.util.List<android.net.wifi.WifiNetworkSuggestion>);
-    method public void addOrUpdatePasspointConfiguration(android.net.wifi.hotspot2.PasspointConfiguration);
-    method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_WIFI_STATE}) public void addSuggestionConnectionStatusListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.SuggestionConnectionStatusListener);
-    method @Deprecated public static int calculateSignalLevel(int, int);
-    method @IntRange(from=0) public int calculateSignalLevel(int);
-    method @Deprecated public void cancelWps(android.net.wifi.WifiManager.WpsCallback);
-    method public static int compareSignalLevel(int, int);
-    method public android.net.wifi.WifiManager.MulticastLock createMulticastLock(String);
-    method public android.net.wifi.WifiManager.WifiLock createWifiLock(int, String);
-    method @Deprecated public android.net.wifi.WifiManager.WifiLock createWifiLock(String);
-    method @Deprecated public boolean disableNetwork(int);
-    method @Deprecated public boolean disconnect();
-    method @Deprecated public boolean enableNetwork(int, boolean);
-    method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_WIFI_STATE}) public java.util.List<android.net.wifi.WifiConfiguration> getConfiguredNetworks();
-    method public android.net.wifi.WifiInfo getConnectionInfo();
-    method public android.net.DhcpInfo getDhcpInfo();
-    method public int getMaxNumberOfNetworkSuggestionsPerApp();
-    method @IntRange(from=0) public int getMaxSignalLevel();
-    method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public java.util.List<android.net.wifi.WifiNetworkSuggestion> getNetworkSuggestions();
-    method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.List<android.net.wifi.hotspot2.PasspointConfiguration> getPasspointConfigurations();
-    method public java.util.List<android.net.wifi.ScanResult> getScanResults();
-    method public int getWifiState();
-    method public boolean is5GHzBandSupported();
-    method public boolean is6GHzBandSupported();
-    method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public boolean isAutoWakeupEnabled();
-    method @Deprecated public boolean isDeviceToApRttSupported();
-    method public boolean isEasyConnectSupported();
-    method public boolean isEnhancedOpenSupported();
-    method public boolean isEnhancedPowerReportingSupported();
-    method public boolean isP2pSupported();
-    method public boolean isPreferredNetworkOffloadSupported();
-    method @Deprecated public boolean isScanAlwaysAvailable();
-    method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public boolean isScanThrottleEnabled();
-    method public boolean isStaApConcurrencySupported();
-    method public boolean isTdlsSupported();
-    method public boolean isWapiSupported();
-    method public boolean isWifiEnabled();
-    method public boolean isWifiStandardSupported(int);
-    method public boolean isWpa3SaeSupported();
-    method public boolean isWpa3SuiteBSupported();
-    method @Deprecated public boolean pingSupplicant();
-    method @Deprecated public boolean reassociate();
-    method @Deprecated public boolean reconnect();
-    method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public void registerScanResultsCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.ScanResultsCallback);
-    method @Deprecated public boolean removeNetwork(int);
-    method @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE) public int removeNetworkSuggestions(@NonNull java.util.List<android.net.wifi.WifiNetworkSuggestion>);
-    method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_CARRIER_PROVISIONING}) public void removePasspointConfiguration(String);
-    method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public void removeSuggestionConnectionStatusListener(@NonNull android.net.wifi.WifiManager.SuggestionConnectionStatusListener);
-    method @Deprecated public boolean saveConfiguration();
-    method public void setTdlsEnabled(java.net.InetAddress, boolean);
-    method public void setTdlsEnabledWithMacAddress(String, boolean);
-    method @Deprecated public boolean setWifiEnabled(boolean);
-    method @RequiresPermission(allOf={android.Manifest.permission.CHANGE_WIFI_STATE, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void startLocalOnlyHotspot(android.net.wifi.WifiManager.LocalOnlyHotspotCallback, @Nullable android.os.Handler);
-    method @Deprecated public boolean startScan();
-    method @Deprecated public void startWps(android.net.wifi.WpsInfo, android.net.wifi.WifiManager.WpsCallback);
-    method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public void unregisterScanResultsCallback(@NonNull android.net.wifi.WifiManager.ScanResultsCallback);
-    method @Deprecated public int updateNetwork(android.net.wifi.WifiConfiguration);
-    field public static final String ACTION_PICK_WIFI_NETWORK = "android.net.wifi.PICK_WIFI_NETWORK";
-    field public static final String ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE = "android.net.wifi.action.REQUEST_SCAN_ALWAYS_AVAILABLE";
-    field public static final String ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION = "android.net.wifi.action.WIFI_NETWORK_SUGGESTION_POST_CONNECTION";
-    field public static final String ACTION_WIFI_SCAN_AVAILABILITY_CHANGED = "android.net.wifi.action.WIFI_SCAN_AVAILABILITY_CHANGED";
-    field @Deprecated public static final int ERROR_AUTHENTICATING = 1; // 0x1
-    field @Deprecated public static final String EXTRA_BSSID = "bssid";
-    field public static final String EXTRA_NETWORK_INFO = "networkInfo";
-    field public static final String EXTRA_NETWORK_SUGGESTION = "android.net.wifi.extra.NETWORK_SUGGESTION";
-    field public static final String EXTRA_NEW_RSSI = "newRssi";
-    field @Deprecated public static final String EXTRA_NEW_STATE = "newState";
-    field public static final String EXTRA_PREVIOUS_WIFI_STATE = "previous_wifi_state";
-    field public static final String EXTRA_RESULTS_UPDATED = "resultsUpdated";
-    field public static final String EXTRA_SCAN_AVAILABLE = "android.net.wifi.extra.SCAN_AVAILABLE";
-    field @Deprecated public static final String EXTRA_SUPPLICANT_CONNECTED = "connected";
-    field @Deprecated public static final String EXTRA_SUPPLICANT_ERROR = "supplicantError";
-    field @Deprecated public static final String EXTRA_WIFI_INFO = "wifiInfo";
-    field public static final String EXTRA_WIFI_STATE = "wifi_state";
-    field public static final String NETWORK_IDS_CHANGED_ACTION = "android.net.wifi.NETWORK_IDS_CHANGED";
-    field public static final String NETWORK_STATE_CHANGED_ACTION = "android.net.wifi.STATE_CHANGE";
-    field public static final String RSSI_CHANGED_ACTION = "android.net.wifi.RSSI_CHANGED";
-    field public static final String SCAN_RESULTS_AVAILABLE_ACTION = "android.net.wifi.SCAN_RESULTS";
-    field public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_DUPLICATE = 3; // 0x3
-    field public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_EXCEEDS_MAX_PER_APP = 4; // 0x4
-    field public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_INVALID = 7; // 0x7
-    field public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_NOT_ALLOWED = 6; // 0x6
-    field public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_APP_DISALLOWED = 2; // 0x2
-    field public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_INTERNAL = 1; // 0x1
-    field public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_REMOVE_INVALID = 5; // 0x5
-    field public static final int STATUS_NETWORK_SUGGESTIONS_SUCCESS = 0; // 0x0
-    field public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_ASSOCIATION = 1; // 0x1
-    field public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION = 2; // 0x2
-    field public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_IP_PROVISIONING = 3; // 0x3
-    field public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_UNKNOWN = 0; // 0x0
-    field @Deprecated public static final String SUPPLICANT_CONNECTION_CHANGE_ACTION = "android.net.wifi.supplicant.CONNECTION_CHANGE";
-    field @Deprecated public static final String SUPPLICANT_STATE_CHANGED_ACTION = "android.net.wifi.supplicant.STATE_CHANGE";
-    field public static final String UNKNOWN_SSID = "<unknown ssid>";
-    field @Deprecated public static final int WIFI_MODE_FULL = 1; // 0x1
-    field public static final int WIFI_MODE_FULL_HIGH_PERF = 3; // 0x3
-    field public static final int WIFI_MODE_FULL_LOW_LATENCY = 4; // 0x4
-    field @Deprecated public static final int WIFI_MODE_SCAN_ONLY = 2; // 0x2
-    field public static final String WIFI_STATE_CHANGED_ACTION = "android.net.wifi.WIFI_STATE_CHANGED";
-    field public static final int WIFI_STATE_DISABLED = 1; // 0x1
-    field public static final int WIFI_STATE_DISABLING = 0; // 0x0
-    field public static final int WIFI_STATE_ENABLED = 3; // 0x3
-    field public static final int WIFI_STATE_ENABLING = 2; // 0x2
-    field public static final int WIFI_STATE_UNKNOWN = 4; // 0x4
-    field @Deprecated public static final int WPS_AUTH_FAILURE = 6; // 0x6
-    field @Deprecated public static final int WPS_OVERLAP_ERROR = 3; // 0x3
-    field @Deprecated public static final int WPS_TIMED_OUT = 7; // 0x7
-    field @Deprecated public static final int WPS_TKIP_ONLY_PROHIBITED = 5; // 0x5
-    field @Deprecated public static final int WPS_WEP_PROHIBITED = 4; // 0x4
-  }
-
-  public static class WifiManager.LocalOnlyHotspotCallback {
-    ctor public WifiManager.LocalOnlyHotspotCallback();
-    method public void onFailed(int);
-    method public void onStarted(android.net.wifi.WifiManager.LocalOnlyHotspotReservation);
-    method public void onStopped();
-    field public static final int ERROR_GENERIC = 2; // 0x2
-    field public static final int ERROR_INCOMPATIBLE_MODE = 3; // 0x3
-    field public static final int ERROR_NO_CHANNEL = 1; // 0x1
-    field public static final int ERROR_TETHERING_DISALLOWED = 4; // 0x4
-  }
-
-  public class WifiManager.LocalOnlyHotspotReservation implements java.lang.AutoCloseable {
-    method public void close();
-    method @NonNull public android.net.wifi.SoftApConfiguration getSoftApConfiguration();
-    method @Deprecated @Nullable public android.net.wifi.WifiConfiguration getWifiConfiguration();
-  }
-
-  public class WifiManager.MulticastLock {
-    method public void acquire();
-    method public boolean isHeld();
-    method public void release();
-    method public void setReferenceCounted(boolean);
-  }
-
-  public abstract static class WifiManager.ScanResultsCallback {
-    ctor public WifiManager.ScanResultsCallback();
-    method public abstract void onScanResultsAvailable();
-  }
-
-  public static interface WifiManager.SuggestionConnectionStatusListener {
-    method public void onConnectionStatus(@NonNull android.net.wifi.WifiNetworkSuggestion, int);
-  }
-
-  public class WifiManager.WifiLock {
-    method public void acquire();
-    method public boolean isHeld();
-    method public void release();
-    method public void setReferenceCounted(boolean);
-    method public void setWorkSource(android.os.WorkSource);
-  }
-
-  @Deprecated public abstract static class WifiManager.WpsCallback {
-    ctor @Deprecated public WifiManager.WpsCallback();
-    method @Deprecated public abstract void onFailed(int);
-    method @Deprecated public abstract void onStarted(String);
-    method @Deprecated public abstract void onSucceeded();
-  }
-
-  public final class WifiNetworkSpecifier extends android.net.NetworkSpecifier implements android.os.Parcelable {
-    method public int describeContents();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.WifiNetworkSpecifier> CREATOR;
-  }
-
-  public static final class WifiNetworkSpecifier.Builder {
-    ctor public WifiNetworkSpecifier.Builder();
-    method @NonNull public android.net.wifi.WifiNetworkSpecifier build();
-    method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setBssid(@NonNull android.net.MacAddress);
-    method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setBssidPattern(@NonNull android.net.MacAddress, @NonNull android.net.MacAddress);
-    method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setIsEnhancedOpen(boolean);
-    method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setIsHiddenSsid(boolean);
-    method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setSsid(@NonNull String);
-    method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setSsidPattern(@NonNull android.os.PatternMatcher);
-    method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setWpa2EnterpriseConfig(@NonNull android.net.wifi.WifiEnterpriseConfig);
-    method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setWpa2Passphrase(@NonNull String);
-    method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setWpa3EnterpriseConfig(@NonNull android.net.wifi.WifiEnterpriseConfig);
-    method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setWpa3Passphrase(@NonNull String);
-  }
-
-  public final class WifiNetworkSuggestion implements android.os.Parcelable {
-    method public int describeContents();
-    method @Nullable public android.net.MacAddress getBssid();
-    method @Nullable public android.net.wifi.WifiEnterpriseConfig getEnterpriseConfig();
-    method @Nullable public String getPassphrase();
-    method @Nullable public android.net.wifi.hotspot2.PasspointConfiguration getPasspointConfig();
-    method @IntRange(from=0) public int getPriority();
-    method @Nullable public String getSsid();
-    method public boolean isAppInteractionRequired();
-    method public boolean isCredentialSharedWithUser();
-    method public boolean isEnhancedOpen();
-    method public boolean isHiddenSsid();
-    method public boolean isInitialAutojoinEnabled();
-    method public boolean isMetered();
-    method public boolean isUntrusted();
-    method public boolean isUserInteractionRequired();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.WifiNetworkSuggestion> CREATOR;
-  }
-
-  public static final class WifiNetworkSuggestion.Builder {
-    ctor public WifiNetworkSuggestion.Builder();
-    method @NonNull public android.net.wifi.WifiNetworkSuggestion build();
-    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setBssid(@NonNull android.net.MacAddress);
-    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setCredentialSharedWithUser(boolean);
-    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setIsAppInteractionRequired(boolean);
-    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setIsEnhancedOpen(boolean);
-    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setIsHiddenSsid(boolean);
-    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setIsInitialAutojoinEnabled(boolean);
-    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setIsMetered(boolean);
-    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setIsUserInteractionRequired(boolean);
-    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setPasspointConfig(@NonNull android.net.wifi.hotspot2.PasspointConfiguration);
-    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setPriority(@IntRange(from=0) int);
-    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setSsid(@NonNull String);
-    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setUntrusted(boolean);
-    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setWapiEnterpriseConfig(@NonNull android.net.wifi.WifiEnterpriseConfig);
-    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setWapiPassphrase(@NonNull String);
-    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setWpa2EnterpriseConfig(@NonNull android.net.wifi.WifiEnterpriseConfig);
-    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setWpa2Passphrase(@NonNull String);
-    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setWpa3EnterpriseConfig(@NonNull android.net.wifi.WifiEnterpriseConfig);
-    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setWpa3Passphrase(@NonNull String);
-  }
-
-  public class WpsInfo implements android.os.Parcelable {
-    ctor public WpsInfo();
-    ctor public WpsInfo(android.net.wifi.WpsInfo);
-    method public int describeContents();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public String BSSID;
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.WpsInfo> CREATOR;
-    field public static final int DISPLAY = 1; // 0x1
-    field public static final int INVALID = 4; // 0x4
-    field public static final int KEYPAD = 2; // 0x2
-    field public static final int LABEL = 3; // 0x3
-    field public static final int PBC = 0; // 0x0
-    field public String pin;
-    field public int setup;
-  }
-
-}
-
-package android.net.wifi.aware {
-
-  public class AttachCallback {
-    ctor public AttachCallback();
-    method public void onAttachFailed();
-    method public void onAttached(android.net.wifi.aware.WifiAwareSession);
-  }
-
-  public final class Characteristics implements android.os.Parcelable {
-    method public int describeContents();
-    method public int getMaxMatchFilterLength();
-    method public int getMaxServiceNameLength();
-    method public int getMaxServiceSpecificInfoLength();
-    method public int getSupportedCipherSuites();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.aware.Characteristics> CREATOR;
-    field public static final int WIFI_AWARE_CIPHER_SUITE_NCS_SK_128 = 1; // 0x1
-    field public static final int WIFI_AWARE_CIPHER_SUITE_NCS_SK_256 = 2; // 0x2
-  }
-
-  public class DiscoverySession implements java.lang.AutoCloseable {
-    method public void close();
-    method @Deprecated public android.net.NetworkSpecifier createNetworkSpecifierOpen(@NonNull android.net.wifi.aware.PeerHandle);
-    method @Deprecated public android.net.NetworkSpecifier createNetworkSpecifierPassphrase(@NonNull android.net.wifi.aware.PeerHandle, @NonNull String);
-    method public void sendMessage(@NonNull android.net.wifi.aware.PeerHandle, int, @Nullable byte[]);
-  }
-
-  public class DiscoverySessionCallback {
-    ctor public DiscoverySessionCallback();
-    method public void onMessageReceived(android.net.wifi.aware.PeerHandle, byte[]);
-    method public void onMessageSendFailed(int);
-    method public void onMessageSendSucceeded(int);
-    method public void onPublishStarted(@NonNull android.net.wifi.aware.PublishDiscoverySession);
-    method public void onServiceDiscovered(android.net.wifi.aware.PeerHandle, byte[], java.util.List<byte[]>);
-    method public void onServiceDiscoveredWithinRange(android.net.wifi.aware.PeerHandle, byte[], java.util.List<byte[]>, int);
-    method public void onSessionConfigFailed();
-    method public void onSessionConfigUpdated();
-    method public void onSessionTerminated();
-    method public void onSubscribeStarted(@NonNull android.net.wifi.aware.SubscribeDiscoverySession);
-  }
-
-  public class IdentityChangedListener {
-    ctor public IdentityChangedListener();
-    method public void onIdentityChanged(byte[]);
-  }
-
-  public final class ParcelablePeerHandle extends android.net.wifi.aware.PeerHandle implements android.os.Parcelable {
-    ctor public ParcelablePeerHandle(@NonNull android.net.wifi.aware.PeerHandle);
-    method public int describeContents();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.aware.ParcelablePeerHandle> CREATOR;
-  }
-
-  public class PeerHandle {
-  }
-
-  public final class PublishConfig implements android.os.Parcelable {
-    method public int describeContents();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.aware.PublishConfig> CREATOR;
-    field public static final int PUBLISH_TYPE_SOLICITED = 1; // 0x1
-    field public static final int PUBLISH_TYPE_UNSOLICITED = 0; // 0x0
-  }
-
-  public static final class PublishConfig.Builder {
-    ctor public PublishConfig.Builder();
-    method public android.net.wifi.aware.PublishConfig build();
-    method public android.net.wifi.aware.PublishConfig.Builder setMatchFilter(@Nullable java.util.List<byte[]>);
-    method public android.net.wifi.aware.PublishConfig.Builder setPublishType(int);
-    method public android.net.wifi.aware.PublishConfig.Builder setRangingEnabled(boolean);
-    method public android.net.wifi.aware.PublishConfig.Builder setServiceName(@NonNull String);
-    method public android.net.wifi.aware.PublishConfig.Builder setServiceSpecificInfo(@Nullable byte[]);
-    method public android.net.wifi.aware.PublishConfig.Builder setTerminateNotificationEnabled(boolean);
-    method public android.net.wifi.aware.PublishConfig.Builder setTtlSec(int);
-  }
-
-  public class PublishDiscoverySession extends android.net.wifi.aware.DiscoverySession {
-    method public void updatePublish(@NonNull android.net.wifi.aware.PublishConfig);
-  }
-
-  public final class SubscribeConfig implements android.os.Parcelable {
-    method public int describeContents();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.aware.SubscribeConfig> CREATOR;
-    field public static final int SUBSCRIBE_TYPE_ACTIVE = 1; // 0x1
-    field public static final int SUBSCRIBE_TYPE_PASSIVE = 0; // 0x0
-  }
-
-  public static final class SubscribeConfig.Builder {
-    ctor public SubscribeConfig.Builder();
-    method public android.net.wifi.aware.SubscribeConfig build();
-    method public android.net.wifi.aware.SubscribeConfig.Builder setMatchFilter(@Nullable java.util.List<byte[]>);
-    method public android.net.wifi.aware.SubscribeConfig.Builder setMaxDistanceMm(int);
-    method public android.net.wifi.aware.SubscribeConfig.Builder setMinDistanceMm(int);
-    method public android.net.wifi.aware.SubscribeConfig.Builder setServiceName(@NonNull String);
-    method public android.net.wifi.aware.SubscribeConfig.Builder setServiceSpecificInfo(@Nullable byte[]);
-    method public android.net.wifi.aware.SubscribeConfig.Builder setSubscribeType(int);
-    method public android.net.wifi.aware.SubscribeConfig.Builder setTerminateNotificationEnabled(boolean);
-    method public android.net.wifi.aware.SubscribeConfig.Builder setTtlSec(int);
-  }
-
-  public class SubscribeDiscoverySession extends android.net.wifi.aware.DiscoverySession {
-    method public void updateSubscribe(@NonNull android.net.wifi.aware.SubscribeConfig);
-  }
-
-  public class WifiAwareManager {
-    method public void attach(@NonNull android.net.wifi.aware.AttachCallback, @Nullable android.os.Handler);
-    method public void attach(@NonNull android.net.wifi.aware.AttachCallback, @NonNull android.net.wifi.aware.IdentityChangedListener, @Nullable android.os.Handler);
-    method public android.net.wifi.aware.Characteristics getCharacteristics();
-    method public boolean isAvailable();
-    field public static final String ACTION_WIFI_AWARE_STATE_CHANGED = "android.net.wifi.aware.action.WIFI_AWARE_STATE_CHANGED";
-    field public static final int WIFI_AWARE_DATA_PATH_ROLE_INITIATOR = 0; // 0x0
-    field public static final int WIFI_AWARE_DATA_PATH_ROLE_RESPONDER = 1; // 0x1
-  }
-
-  public final class WifiAwareNetworkInfo implements android.os.Parcelable android.net.TransportInfo {
-    method public int describeContents();
-    method @Nullable public java.net.Inet6Address getPeerIpv6Addr();
-    method public int getPort();
-    method public int getTransportProtocol();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.aware.WifiAwareNetworkInfo> CREATOR;
-  }
-
-  public final class WifiAwareNetworkSpecifier extends android.net.NetworkSpecifier implements android.os.Parcelable {
-    method public int describeContents();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.aware.WifiAwareNetworkSpecifier> CREATOR;
-  }
-
-  public static final class WifiAwareNetworkSpecifier.Builder {
-    ctor public WifiAwareNetworkSpecifier.Builder(@NonNull android.net.wifi.aware.DiscoverySession, @NonNull android.net.wifi.aware.PeerHandle);
-    method @NonNull public android.net.wifi.aware.WifiAwareNetworkSpecifier build();
-    method @NonNull public android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder setPmk(@NonNull byte[]);
-    method @NonNull public android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder setPort(@IntRange(from=0, to=65535) int);
-    method @NonNull public android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder setPskPassphrase(@NonNull String);
-    method @NonNull public android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder setTransportProtocol(@IntRange(from=0, to=255) int);
-  }
-
-  public class WifiAwareSession implements java.lang.AutoCloseable {
-    method public void close();
-    method public android.net.NetworkSpecifier createNetworkSpecifierOpen(int, @NonNull byte[]);
-    method public android.net.NetworkSpecifier createNetworkSpecifierPassphrase(int, @NonNull byte[], @NonNull String);
-    method public void publish(@NonNull android.net.wifi.aware.PublishConfig, @NonNull android.net.wifi.aware.DiscoverySessionCallback, @Nullable android.os.Handler);
-    method public void subscribe(@NonNull android.net.wifi.aware.SubscribeConfig, @NonNull android.net.wifi.aware.DiscoverySessionCallback, @Nullable android.os.Handler);
-  }
-
-}
-
-package android.net.wifi.hotspot2 {
-
-  public final class ConfigParser {
-    method public static android.net.wifi.hotspot2.PasspointConfiguration parsePasspointConfig(String, byte[]);
-  }
-
-  public final class PasspointConfiguration implements android.os.Parcelable {
-    ctor public PasspointConfiguration();
-    ctor public PasspointConfiguration(android.net.wifi.hotspot2.PasspointConfiguration);
-    method public int describeContents();
-    method public android.net.wifi.hotspot2.pps.Credential getCredential();
-    method public android.net.wifi.hotspot2.pps.HomeSp getHomeSp();
-    method public long getSubscriptionExpirationTimeMillis();
-    method @NonNull public String getUniqueId();
-    method public boolean isOsuProvisioned();
-    method public void setCredential(android.net.wifi.hotspot2.pps.Credential);
-    method public void setHomeSp(android.net.wifi.hotspot2.pps.HomeSp);
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.PasspointConfiguration> CREATOR;
-  }
-
-}
-
-package android.net.wifi.hotspot2.omadm {
-
-  public final class PpsMoParser {
-    method public static android.net.wifi.hotspot2.PasspointConfiguration parseMoText(String);
-  }
-
-}
-
-package android.net.wifi.hotspot2.pps {
-
-  public final class Credential implements android.os.Parcelable {
-    ctor public Credential();
-    ctor public Credential(android.net.wifi.hotspot2.pps.Credential);
-    method public int describeContents();
-    method public java.security.cert.X509Certificate getCaCertificate();
-    method public android.net.wifi.hotspot2.pps.Credential.CertificateCredential getCertCredential();
-    method public java.security.cert.X509Certificate[] getClientCertificateChain();
-    method public java.security.PrivateKey getClientPrivateKey();
-    method public String getRealm();
-    method public android.net.wifi.hotspot2.pps.Credential.SimCredential getSimCredential();
-    method public android.net.wifi.hotspot2.pps.Credential.UserCredential getUserCredential();
-    method public void setCaCertificate(java.security.cert.X509Certificate);
-    method public void setCertCredential(android.net.wifi.hotspot2.pps.Credential.CertificateCredential);
-    method public void setClientCertificateChain(java.security.cert.X509Certificate[]);
-    method public void setClientPrivateKey(java.security.PrivateKey);
-    method public void setRealm(String);
-    method public void setSimCredential(android.net.wifi.hotspot2.pps.Credential.SimCredential);
-    method public void setUserCredential(android.net.wifi.hotspot2.pps.Credential.UserCredential);
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential> CREATOR;
-  }
-
-  public static final class Credential.CertificateCredential implements android.os.Parcelable {
-    ctor public Credential.CertificateCredential();
-    ctor public Credential.CertificateCredential(android.net.wifi.hotspot2.pps.Credential.CertificateCredential);
-    method public int describeContents();
-    method public byte[] getCertSha256Fingerprint();
-    method public String getCertType();
-    method public void setCertSha256Fingerprint(byte[]);
-    method public void setCertType(String);
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential.CertificateCredential> CREATOR;
-  }
-
-  public static final class Credential.SimCredential implements android.os.Parcelable {
-    ctor public Credential.SimCredential();
-    ctor public Credential.SimCredential(android.net.wifi.hotspot2.pps.Credential.SimCredential);
-    method public int describeContents();
-    method public int getEapType();
-    method public String getImsi();
-    method public void setEapType(int);
-    method public void setImsi(String);
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential.SimCredential> CREATOR;
-  }
-
-  public static final class Credential.UserCredential implements android.os.Parcelable {
-    ctor public Credential.UserCredential();
-    ctor public Credential.UserCredential(android.net.wifi.hotspot2.pps.Credential.UserCredential);
-    method public int describeContents();
-    method public int getEapType();
-    method public String getNonEapInnerMethod();
-    method public String getPassword();
-    method public String getUsername();
-    method public void setEapType(int);
-    method public void setNonEapInnerMethod(String);
-    method public void setPassword(String);
-    method public void setUsername(String);
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential.UserCredential> CREATOR;
-  }
-
-  public final class HomeSp implements android.os.Parcelable {
-    ctor public HomeSp();
-    ctor public HomeSp(android.net.wifi.hotspot2.pps.HomeSp);
-    method public int describeContents();
-    method public String getFqdn();
-    method public String getFriendlyName();
-    method public long[] getRoamingConsortiumOis();
-    method public void setFqdn(String);
-    method public void setFriendlyName(String);
-    method public void setRoamingConsortiumOis(long[]);
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.HomeSp> CREATOR;
-  }
-
-}
-
-package android.net.wifi.p2p {
-
-  public class WifiP2pConfig implements android.os.Parcelable {
-    ctor public WifiP2pConfig();
-    ctor public WifiP2pConfig(android.net.wifi.p2p.WifiP2pConfig);
-    method public int describeContents();
-    method public int getGroupOwnerBand();
-    method public int getNetworkId();
-    method @Nullable public String getNetworkName();
-    method @Nullable public String getPassphrase();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.p2p.WifiP2pConfig> CREATOR;
-    field public static final int GROUP_OWNER_BAND_2GHZ = 1; // 0x1
-    field public static final int GROUP_OWNER_BAND_5GHZ = 2; // 0x2
-    field public static final int GROUP_OWNER_BAND_AUTO = 0; // 0x0
-    field public static final int GROUP_OWNER_INTENT_AUTO = -1; // 0xffffffff
-    field public static final int GROUP_OWNER_INTENT_MAX = 15; // 0xf
-    field public static final int GROUP_OWNER_INTENT_MIN = 0; // 0x0
-    field public String deviceAddress;
-    field @IntRange(from=0, to=15) public int groupOwnerIntent;
-    field public android.net.wifi.WpsInfo wps;
-  }
-
-  public static final class WifiP2pConfig.Builder {
-    ctor public WifiP2pConfig.Builder();
-    method @NonNull public android.net.wifi.p2p.WifiP2pConfig build();
-    method @NonNull public android.net.wifi.p2p.WifiP2pConfig.Builder enablePersistentMode(boolean);
-    method @NonNull public android.net.wifi.p2p.WifiP2pConfig.Builder setDeviceAddress(@Nullable android.net.MacAddress);
-    method @NonNull public android.net.wifi.p2p.WifiP2pConfig.Builder setGroupOperatingBand(int);
-    method @NonNull public android.net.wifi.p2p.WifiP2pConfig.Builder setGroupOperatingFrequency(int);
-    method @NonNull public android.net.wifi.p2p.WifiP2pConfig.Builder setNetworkName(@NonNull String);
-    method @NonNull public android.net.wifi.p2p.WifiP2pConfig.Builder setPassphrase(@NonNull String);
-  }
-
-  public class WifiP2pDevice implements android.os.Parcelable {
-    ctor public WifiP2pDevice();
-    ctor public WifiP2pDevice(android.net.wifi.p2p.WifiP2pDevice);
-    method public int describeContents();
-    method @Nullable public android.net.wifi.p2p.WifiP2pWfdInfo getWfdInfo();
-    method public boolean isGroupOwner();
-    method public boolean isServiceDiscoveryCapable();
-    method public void update(@NonNull android.net.wifi.p2p.WifiP2pDevice);
-    method public boolean wpsDisplaySupported();
-    method public boolean wpsKeypadSupported();
-    method public boolean wpsPbcSupported();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final int AVAILABLE = 3; // 0x3
-    field public static final int CONNECTED = 0; // 0x0
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.p2p.WifiP2pDevice> CREATOR;
-    field public static final int FAILED = 2; // 0x2
-    field public static final int INVITED = 1; // 0x1
-    field public static final int UNAVAILABLE = 4; // 0x4
-    field public String deviceAddress;
-    field public String deviceName;
-    field public String primaryDeviceType;
-    field public String secondaryDeviceType;
-    field public int status;
-  }
-
-  public class WifiP2pDeviceList implements android.os.Parcelable {
-    ctor public WifiP2pDeviceList();
-    ctor public WifiP2pDeviceList(android.net.wifi.p2p.WifiP2pDeviceList);
-    method public int describeContents();
-    method public android.net.wifi.p2p.WifiP2pDevice get(String);
-    method public java.util.Collection<android.net.wifi.p2p.WifiP2pDevice> getDeviceList();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.p2p.WifiP2pDeviceList> CREATOR;
-  }
-
-  public class WifiP2pGroup implements android.os.Parcelable {
-    ctor public WifiP2pGroup();
-    ctor public WifiP2pGroup(android.net.wifi.p2p.WifiP2pGroup);
-    method public int describeContents();
-    method public java.util.Collection<android.net.wifi.p2p.WifiP2pDevice> getClientList();
-    method public int getFrequency();
-    method public String getInterface();
-    method public int getNetworkId();
-    method public String getNetworkName();
-    method public android.net.wifi.p2p.WifiP2pDevice getOwner();
-    method public String getPassphrase();
-    method public boolean isGroupOwner();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.p2p.WifiP2pGroup> CREATOR;
-    field public static final int NETWORK_ID_PERSISTENT = -2; // 0xfffffffe
-    field public static final int NETWORK_ID_TEMPORARY = -1; // 0xffffffff
-  }
-
-  public class WifiP2pInfo implements android.os.Parcelable {
-    ctor public WifiP2pInfo();
-    ctor public WifiP2pInfo(android.net.wifi.p2p.WifiP2pInfo);
-    method public int describeContents();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.p2p.WifiP2pInfo> CREATOR;
-    field public boolean groupFormed;
-    field public java.net.InetAddress groupOwnerAddress;
-    field public boolean isGroupOwner;
-  }
-
-  public class WifiP2pManager {
-    method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void addLocalService(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.nsd.WifiP2pServiceInfo, android.net.wifi.p2p.WifiP2pManager.ActionListener);
-    method public void addServiceRequest(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.nsd.WifiP2pServiceRequest, android.net.wifi.p2p.WifiP2pManager.ActionListener);
-    method public void cancelConnect(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener);
-    method public void clearLocalServices(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener);
-    method public void clearServiceRequests(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener);
-    method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void connect(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pConfig, android.net.wifi.p2p.WifiP2pManager.ActionListener);
-    method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void createGroup(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener);
-    method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void createGroup(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @Nullable android.net.wifi.p2p.WifiP2pConfig, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener);
-    method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void discoverPeers(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener);
-    method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void discoverServices(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener);
-    method public android.net.wifi.p2p.WifiP2pManager.Channel initialize(android.content.Context, android.os.Looper, android.net.wifi.p2p.WifiP2pManager.ChannelListener);
-    method public void removeGroup(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener);
-    method public void removeLocalService(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.nsd.WifiP2pServiceInfo, android.net.wifi.p2p.WifiP2pManager.ActionListener);
-    method public void removeServiceRequest(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.nsd.WifiP2pServiceRequest, android.net.wifi.p2p.WifiP2pManager.ActionListener);
-    method public void requestConnectionInfo(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ConnectionInfoListener);
-    method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void requestDeviceInfo(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @NonNull android.net.wifi.p2p.WifiP2pManager.DeviceInfoListener);
-    method public void requestDiscoveryState(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @NonNull android.net.wifi.p2p.WifiP2pManager.DiscoveryStateListener);
-    method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void requestGroupInfo(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.GroupInfoListener);
-    method public void requestNetworkInfo(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @NonNull android.net.wifi.p2p.WifiP2pManager.NetworkInfoListener);
-    method public void requestP2pState(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @NonNull android.net.wifi.p2p.WifiP2pManager.P2pStateListener);
-    method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void requestPeers(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.PeerListListener);
-    method public void setDnsSdResponseListeners(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.DnsSdServiceResponseListener, android.net.wifi.p2p.WifiP2pManager.DnsSdTxtRecordListener);
-    method public void setServiceResponseListener(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ServiceResponseListener);
-    method public void setUpnpServiceResponseListener(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.UpnpServiceResponseListener);
-    method public void stopPeerDiscovery(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener);
-    field public static final int BUSY = 2; // 0x2
-    field public static final int ERROR = 0; // 0x0
-    field public static final String EXTRA_DISCOVERY_STATE = "discoveryState";
-    field public static final String EXTRA_NETWORK_INFO = "networkInfo";
-    field public static final String EXTRA_P2P_DEVICE_LIST = "wifiP2pDeviceList";
-    field public static final String EXTRA_WIFI_P2P_DEVICE = "wifiP2pDevice";
-    field public static final String EXTRA_WIFI_P2P_GROUP = "p2pGroupInfo";
-    field public static final String EXTRA_WIFI_P2P_INFO = "wifiP2pInfo";
-    field public static final String EXTRA_WIFI_STATE = "wifi_p2p_state";
-    field public static final int NO_SERVICE_REQUESTS = 3; // 0x3
-    field public static final int P2P_UNSUPPORTED = 1; // 0x1
-    field public static final String WIFI_P2P_CONNECTION_CHANGED_ACTION = "android.net.wifi.p2p.CONNECTION_STATE_CHANGE";
-    field public static final String WIFI_P2P_DISCOVERY_CHANGED_ACTION = "android.net.wifi.p2p.DISCOVERY_STATE_CHANGE";
-    field public static final int WIFI_P2P_DISCOVERY_STARTED = 2; // 0x2
-    field public static final int WIFI_P2P_DISCOVERY_STOPPED = 1; // 0x1
-    field public static final String WIFI_P2P_PEERS_CHANGED_ACTION = "android.net.wifi.p2p.PEERS_CHANGED";
-    field public static final String WIFI_P2P_STATE_CHANGED_ACTION = "android.net.wifi.p2p.STATE_CHANGED";
-    field public static final int WIFI_P2P_STATE_DISABLED = 1; // 0x1
-    field public static final int WIFI_P2P_STATE_ENABLED = 2; // 0x2
-    field public static final String WIFI_P2P_THIS_DEVICE_CHANGED_ACTION = "android.net.wifi.p2p.THIS_DEVICE_CHANGED";
-  }
-
-  public static interface WifiP2pManager.ActionListener {
-    method public void onFailure(int);
-    method public void onSuccess();
-  }
-
-  public static class WifiP2pManager.Channel implements java.lang.AutoCloseable {
-    method public void close();
-  }
-
-  public static interface WifiP2pManager.ChannelListener {
-    method public void onChannelDisconnected();
-  }
-
-  public static interface WifiP2pManager.ConnectionInfoListener {
-    method public void onConnectionInfoAvailable(android.net.wifi.p2p.WifiP2pInfo);
-  }
-
-  public static interface WifiP2pManager.DeviceInfoListener {
-    method public void onDeviceInfoAvailable(@Nullable android.net.wifi.p2p.WifiP2pDevice);
-  }
-
-  public static interface WifiP2pManager.DiscoveryStateListener {
-    method public void onDiscoveryStateAvailable(int);
-  }
-
-  public static interface WifiP2pManager.DnsSdServiceResponseListener {
-    method public void onDnsSdServiceAvailable(String, String, android.net.wifi.p2p.WifiP2pDevice);
-  }
-
-  public static interface WifiP2pManager.DnsSdTxtRecordListener {
-    method public void onDnsSdTxtRecordAvailable(String, java.util.Map<java.lang.String,java.lang.String>, android.net.wifi.p2p.WifiP2pDevice);
-  }
-
-  public static interface WifiP2pManager.GroupInfoListener {
-    method public void onGroupInfoAvailable(android.net.wifi.p2p.WifiP2pGroup);
-  }
-
-  public static interface WifiP2pManager.NetworkInfoListener {
-    method public void onNetworkInfoAvailable(@NonNull android.net.NetworkInfo);
-  }
-
-  public static interface WifiP2pManager.P2pStateListener {
-    method public void onP2pStateAvailable(int);
-  }
-
-  public static interface WifiP2pManager.PeerListListener {
-    method public void onPeersAvailable(android.net.wifi.p2p.WifiP2pDeviceList);
-  }
-
-  public static interface WifiP2pManager.ServiceResponseListener {
-    method public void onServiceAvailable(int, byte[], android.net.wifi.p2p.WifiP2pDevice);
-  }
-
-  public static interface WifiP2pManager.UpnpServiceResponseListener {
-    method public void onUpnpServiceAvailable(java.util.List<java.lang.String>, android.net.wifi.p2p.WifiP2pDevice);
-  }
-
-  public final class WifiP2pWfdInfo implements android.os.Parcelable {
-    ctor public WifiP2pWfdInfo();
-    ctor public WifiP2pWfdInfo(@Nullable android.net.wifi.p2p.WifiP2pWfdInfo);
-    method public int describeContents();
-    method public int getControlPort();
-    method public int getDeviceType();
-    method public int getMaxThroughput();
-    method public boolean isContentProtectionSupported();
-    method public boolean isEnabled();
-    method public boolean isSessionAvailable();
-    method public void setContentProtectionSupported(boolean);
-    method public void setControlPort(@IntRange(from=0) int);
-    method public boolean setDeviceType(int);
-    method public void setEnabled(boolean);
-    method public void setMaxThroughput(@IntRange(from=0) int);
-    method public void setSessionAvailable(boolean);
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.p2p.WifiP2pWfdInfo> CREATOR;
-    field public static final int DEVICE_TYPE_PRIMARY_SINK = 1; // 0x1
-    field public static final int DEVICE_TYPE_SECONDARY_SINK = 2; // 0x2
-    field public static final int DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK = 3; // 0x3
-    field public static final int DEVICE_TYPE_WFD_SOURCE = 0; // 0x0
-  }
-
-}
-
-package android.net.wifi.p2p.nsd {
-
-  public class WifiP2pDnsSdServiceInfo extends android.net.wifi.p2p.nsd.WifiP2pServiceInfo {
-    method public static android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceInfo newInstance(String, String, java.util.Map<java.lang.String,java.lang.String>);
-  }
-
-  public class WifiP2pDnsSdServiceRequest extends android.net.wifi.p2p.nsd.WifiP2pServiceRequest {
-    method public static android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceRequest newInstance();
-    method public static android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceRequest newInstance(String);
-    method public static android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceRequest newInstance(String, String);
-  }
-
-  public class WifiP2pServiceInfo implements android.os.Parcelable {
-    method public int describeContents();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final int SERVICE_TYPE_ALL = 0; // 0x0
-    field public static final int SERVICE_TYPE_BONJOUR = 1; // 0x1
-    field public static final int SERVICE_TYPE_UPNP = 2; // 0x2
-    field public static final int SERVICE_TYPE_VENDOR_SPECIFIC = 255; // 0xff
-  }
-
-  public class WifiP2pServiceRequest implements android.os.Parcelable {
-    method public int describeContents();
-    method public static android.net.wifi.p2p.nsd.WifiP2pServiceRequest newInstance(int, String);
-    method public static android.net.wifi.p2p.nsd.WifiP2pServiceRequest newInstance(int);
-    method public void writeToParcel(android.os.Parcel, int);
-  }
-
-  public class WifiP2pUpnpServiceInfo extends android.net.wifi.p2p.nsd.WifiP2pServiceInfo {
-    method public static android.net.wifi.p2p.nsd.WifiP2pUpnpServiceInfo newInstance(String, String, java.util.List<java.lang.String>);
-  }
-
-  public class WifiP2pUpnpServiceRequest extends android.net.wifi.p2p.nsd.WifiP2pServiceRequest {
-    method public static android.net.wifi.p2p.nsd.WifiP2pUpnpServiceRequest newInstance();
-    method public static android.net.wifi.p2p.nsd.WifiP2pUpnpServiceRequest newInstance(String);
-  }
-
-}
-
-package android.net.wifi.rtt {
-
-  public class CivicLocationKeys {
-    field public static final int ADDITIONAL_CODE = 32; // 0x20
-    field public static final int APT = 26; // 0x1a
-    field public static final int BOROUGH = 4; // 0x4
-    field public static final int BRANCH_ROAD_NAME = 36; // 0x24
-    field public static final int BUILDING = 25; // 0x19
-    field public static final int CITY = 3; // 0x3
-    field public static final int COUNTY = 2; // 0x2
-    field public static final int DESK = 33; // 0x21
-    field public static final int FLOOR = 27; // 0x1b
-    field public static final int GROUP_OF_STREETS = 6; // 0x6
-    field public static final int HNO = 19; // 0x13
-    field public static final int HNS = 20; // 0x14
-    field public static final int LANGUAGE = 0; // 0x0
-    field public static final int LMK = 21; // 0x15
-    field public static final int LOC = 22; // 0x16
-    field public static final int NAM = 23; // 0x17
-    field public static final int NEIGHBORHOOD = 5; // 0x5
-    field public static final int PCN = 30; // 0x1e
-    field public static final int POD = 17; // 0x11
-    field public static final int POSTAL_CODE = 24; // 0x18
-    field public static final int PO_BOX = 31; // 0x1f
-    field public static final int PRD = 16; // 0x10
-    field public static final int PRIMARY_ROAD_NAME = 34; // 0x22
-    field public static final int ROAD_SECTION = 35; // 0x23
-    field public static final int ROOM = 28; // 0x1c
-    field public static final int SCRIPT = 128; // 0x80
-    field public static final int STATE = 1; // 0x1
-    field public static final int STREET_NAME_POST_MODIFIER = 39; // 0x27
-    field public static final int STREET_NAME_PRE_MODIFIER = 38; // 0x26
-    field public static final int STS = 18; // 0x12
-    field public static final int SUBBRANCH_ROAD_NAME = 37; // 0x25
-    field public static final int TYPE_OF_PLACE = 29; // 0x1d
-  }
-
-  public final class RangingRequest implements android.os.Parcelable {
-    method public int describeContents();
-    method public static int getMaxPeers();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.rtt.RangingRequest> CREATOR;
-  }
-
-  public static final class RangingRequest.Builder {
-    ctor public RangingRequest.Builder();
-    method public android.net.wifi.rtt.RangingRequest.Builder addAccessPoint(@NonNull android.net.wifi.ScanResult);
-    method public android.net.wifi.rtt.RangingRequest.Builder addAccessPoints(@NonNull java.util.List<android.net.wifi.ScanResult>);
-    method public android.net.wifi.rtt.RangingRequest.Builder addWifiAwarePeer(@NonNull android.net.MacAddress);
-    method public android.net.wifi.rtt.RangingRequest.Builder addWifiAwarePeer(@NonNull android.net.wifi.aware.PeerHandle);
-    method public android.net.wifi.rtt.RangingRequest build();
-  }
-
-  public final class RangingResult implements android.os.Parcelable {
-    method public int describeContents();
-    method public int getDistanceMm();
-    method public int getDistanceStdDevMm();
-    method @Nullable public android.net.MacAddress getMacAddress();
-    method public int getNumAttemptedMeasurements();
-    method public int getNumSuccessfulMeasurements();
-    method @Nullable public android.net.wifi.aware.PeerHandle getPeerHandle();
-    method public long getRangingTimestampMillis();
-    method public int getRssi();
-    method public int getStatus();
-    method @Nullable public android.net.wifi.rtt.ResponderLocation getUnverifiedResponderLocation();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.rtt.RangingResult> CREATOR;
-    field public static final int STATUS_FAIL = 1; // 0x1
-    field public static final int STATUS_RESPONDER_DOES_NOT_SUPPORT_IEEE80211MC = 2; // 0x2
-    field public static final int STATUS_SUCCESS = 0; // 0x0
-  }
-
-  public abstract class RangingResultCallback {
-    ctor public RangingResultCallback();
-    method public abstract void onRangingFailure(int);
-    method public abstract void onRangingResults(@NonNull java.util.List<android.net.wifi.rtt.RangingResult>);
-    field public static final int STATUS_CODE_FAIL = 1; // 0x1
-    field public static final int STATUS_CODE_FAIL_RTT_NOT_AVAILABLE = 2; // 0x2
-  }
-
-  public final class ResponderLocation implements android.os.Parcelable {
-    method public int describeContents();
-    method public double getAltitude();
-    method public int getAltitudeType();
-    method public double getAltitudeUncertainty();
-    method public java.util.List<android.net.MacAddress> getColocatedBssids();
-    method public int getDatum();
-    method public int getExpectedToMove();
-    method public double getFloorNumber();
-    method public double getHeightAboveFloorMeters();
-    method public double getHeightAboveFloorUncertaintyMeters();
-    method public double getLatitude();
-    method public double getLatitudeUncertainty();
-    method public int getLciVersion();
-    method public double getLongitude();
-    method public double getLongitudeUncertainty();
-    method @Nullable public String getMapImageMimeType();
-    method @Nullable public android.net.Uri getMapImageUri();
-    method public boolean getRegisteredLocationAgreementIndication();
-    method public boolean isLciSubelementValid();
-    method public boolean isZaxisSubelementValid();
-    method @Nullable public android.location.Address toCivicLocationAddress();
-    method @Nullable public android.util.SparseArray<java.lang.String> toCivicLocationSparseArray();
-    method @NonNull public android.location.Location toLocation();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final int ALTITUDE_FLOORS = 2; // 0x2
-    field public static final int ALTITUDE_METERS = 1; // 0x1
-    field public static final int ALTITUDE_UNDEFINED = 0; // 0x0
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.rtt.ResponderLocation> CREATOR;
-    field public static final int DATUM_NAD83_MLLW = 3; // 0x3
-    field public static final int DATUM_NAD83_NAV88 = 2; // 0x2
-    field public static final int DATUM_UNDEFINED = 0; // 0x0
-    field public static final int DATUM_WGS84 = 1; // 0x1
-    field public static final int LCI_VERSION_1 = 1; // 0x1
-    field public static final int LOCATION_FIXED = 0; // 0x0
-    field public static final int LOCATION_MOVEMENT_UNKNOWN = 2; // 0x2
-    field public static final int LOCATION_RESERVED = 3; // 0x3
-    field public static final int LOCATION_VARIABLE = 1; // 0x1
-  }
-
-  public class WifiRttManager {
-    method public boolean isAvailable();
-    method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.CHANGE_WIFI_STATE, android.Manifest.permission.ACCESS_WIFI_STATE}) public void startRanging(@NonNull android.net.wifi.rtt.RangingRequest, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.rtt.RangingResultCallback);
-    field public static final String ACTION_WIFI_RTT_STATE_CHANGED = "android.net.wifi.rtt.action.WIFI_RTT_STATE_CHANGED";
-  }
-
-}
-
diff --git a/wifi/api/lint-baseline.txt b/wifi/api/lint-baseline.txt
deleted file mode 100644
index 892411f..0000000
--- a/wifi/api/lint-baseline.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-// Baseline format: 1.0
-GenericException: android.net.wifi.WifiManager.LocalOnlyHotspotReservation#finalize():
-    Methods must not throw generic exceptions (`java.lang.Throwable`)
-GenericException: android.net.wifi.WifiManager.MulticastLock#finalize():
-    Methods must not throw generic exceptions (`java.lang.Throwable`)
-GenericException: android.net.wifi.WifiManager.WifiLock#finalize():
-    Methods must not throw generic exceptions (`java.lang.Throwable`)
-
-
-VisiblySynchronized: PsiThisExpression:WifiManager.this:
-    Internal locks must not be exposed (synchronizing on this or class is still externally observable): method android.net.wifi.WifiManager.WifiLock.finalize()
-VisiblySynchronized: android.net.wifi.WifiManager.WifiLock#finalize():
-    Internal locks must not be exposed (synchronizing on this or class is still externally observable): method android.net.wifi.WifiManager.WifiLock.finalize()
diff --git a/wifi/api/module-lib-current.txt b/wifi/api/module-lib-current.txt
deleted file mode 100644
index d802177..0000000
--- a/wifi/api/module-lib-current.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/wifi/api/module-lib-removed.txt b/wifi/api/module-lib-removed.txt
deleted file mode 100644
index d802177..0000000
--- a/wifi/api/module-lib-removed.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/wifi/api/removed.txt b/wifi/api/removed.txt
deleted file mode 100644
index d802177..0000000
--- a/wifi/api/removed.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/wifi/api/system-current.txt b/wifi/api/system-current.txt
deleted file mode 100644
index 07793c1..0000000
--- a/wifi/api/system-current.txt
+++ /dev/null
@@ -1,939 +0,0 @@
-// Signature format: 2.0
-package android.net.wifi {
-
-  public abstract class EasyConnectStatusCallback {
-    ctor public EasyConnectStatusCallback();
-    method public abstract void onConfiguratorSuccess(int);
-    method public abstract void onEnrolleeSuccess(int);
-    method public void onFailure(int);
-    method public void onFailure(int, @Nullable String, @NonNull android.util.SparseArray<int[]>, @NonNull int[]);
-    method public abstract void onProgress(int);
-    field public static final int EASY_CONNECT_EVENT_PROGRESS_AUTHENTICATION_SUCCESS = 0; // 0x0
-    field public static final int EASY_CONNECT_EVENT_PROGRESS_CONFIGURATION_ACCEPTED = 3; // 0x3
-    field public static final int EASY_CONNECT_EVENT_PROGRESS_CONFIGURATION_SENT_WAITING_RESPONSE = 2; // 0x2
-    field public static final int EASY_CONNECT_EVENT_PROGRESS_RESPONSE_PENDING = 1; // 0x1
-    field public static final int EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_APPLIED = 1; // 0x1
-    field public static final int EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_SENT = 0; // 0x0
-  }
-
-  @Deprecated public class RttManager {
-    method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void disableResponder(android.net.wifi.RttManager.ResponderCallback);
-    method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void enableResponder(android.net.wifi.RttManager.ResponderCallback);
-    method @Deprecated public android.net.wifi.RttManager.Capabilities getCapabilities();
-    method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public android.net.wifi.RttManager.RttCapabilities getRttCapabilities();
-    method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void startRanging(android.net.wifi.RttManager.RttParams[], android.net.wifi.RttManager.RttListener);
-    method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void stopRanging(android.net.wifi.RttManager.RttListener);
-    field @Deprecated public static final int BASE = 160256; // 0x27200
-    field @Deprecated public static final int CMD_OP_ABORTED = 160260; // 0x27204
-    field @Deprecated public static final int CMD_OP_DISABLE_RESPONDER = 160262; // 0x27206
-    field @Deprecated public static final int CMD_OP_ENABLE_RESPONDER = 160261; // 0x27205
-    field @Deprecated public static final int CMD_OP_ENALBE_RESPONDER_FAILED = 160264; // 0x27208
-    field @Deprecated public static final int CMD_OP_ENALBE_RESPONDER_SUCCEEDED = 160263; // 0x27207
-    field @Deprecated public static final int CMD_OP_FAILED = 160258; // 0x27202
-    field @Deprecated public static final int CMD_OP_START_RANGING = 160256; // 0x27200
-    field @Deprecated public static final int CMD_OP_STOP_RANGING = 160257; // 0x27201
-    field @Deprecated public static final int CMD_OP_SUCCEEDED = 160259; // 0x27203
-    field @Deprecated public static final String DESCRIPTION_KEY = "android.net.wifi.RttManager.Description";
-    field @Deprecated public static final int PREAMBLE_HT = 2; // 0x2
-    field @Deprecated public static final int PREAMBLE_LEGACY = 1; // 0x1
-    field @Deprecated public static final int PREAMBLE_VHT = 4; // 0x4
-    field @Deprecated public static final int REASON_INITIATOR_NOT_ALLOWED_WHEN_RESPONDER_ON = -6; // 0xfffffffa
-    field @Deprecated public static final int REASON_INVALID_LISTENER = -3; // 0xfffffffd
-    field @Deprecated public static final int REASON_INVALID_REQUEST = -4; // 0xfffffffc
-    field @Deprecated public static final int REASON_NOT_AVAILABLE = -2; // 0xfffffffe
-    field @Deprecated public static final int REASON_PERMISSION_DENIED = -5; // 0xfffffffb
-    field @Deprecated public static final int REASON_UNSPECIFIED = -1; // 0xffffffff
-    field @Deprecated public static final int RTT_BW_10_SUPPORT = 2; // 0x2
-    field @Deprecated public static final int RTT_BW_160_SUPPORT = 32; // 0x20
-    field @Deprecated public static final int RTT_BW_20_SUPPORT = 4; // 0x4
-    field @Deprecated public static final int RTT_BW_40_SUPPORT = 8; // 0x8
-    field @Deprecated public static final int RTT_BW_5_SUPPORT = 1; // 0x1
-    field @Deprecated public static final int RTT_BW_80_SUPPORT = 16; // 0x10
-    field @Deprecated public static final int RTT_CHANNEL_WIDTH_10 = 6; // 0x6
-    field @Deprecated public static final int RTT_CHANNEL_WIDTH_160 = 3; // 0x3
-    field @Deprecated public static final int RTT_CHANNEL_WIDTH_20 = 0; // 0x0
-    field @Deprecated public static final int RTT_CHANNEL_WIDTH_40 = 1; // 0x1
-    field @Deprecated public static final int RTT_CHANNEL_WIDTH_5 = 5; // 0x5
-    field @Deprecated public static final int RTT_CHANNEL_WIDTH_80 = 2; // 0x2
-    field @Deprecated public static final int RTT_CHANNEL_WIDTH_80P80 = 4; // 0x4
-    field @Deprecated public static final int RTT_CHANNEL_WIDTH_UNSPECIFIED = -1; // 0xffffffff
-    field @Deprecated public static final int RTT_PEER_NAN = 5; // 0x5
-    field @Deprecated public static final int RTT_PEER_P2P_CLIENT = 4; // 0x4
-    field @Deprecated public static final int RTT_PEER_P2P_GO = 3; // 0x3
-    field @Deprecated public static final int RTT_PEER_TYPE_AP = 1; // 0x1
-    field @Deprecated public static final int RTT_PEER_TYPE_STA = 2; // 0x2
-    field @Deprecated public static final int RTT_PEER_TYPE_UNSPECIFIED = 0; // 0x0
-    field @Deprecated public static final int RTT_STATUS_ABORTED = 8; // 0x8
-    field @Deprecated public static final int RTT_STATUS_FAILURE = 1; // 0x1
-    field @Deprecated public static final int RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL = 6; // 0x6
-    field @Deprecated public static final int RTT_STATUS_FAIL_BUSY_TRY_LATER = 12; // 0xc
-    field @Deprecated public static final int RTT_STATUS_FAIL_FTM_PARAM_OVERRIDE = 15; // 0xf
-    field @Deprecated public static final int RTT_STATUS_FAIL_INVALID_TS = 9; // 0x9
-    field @Deprecated public static final int RTT_STATUS_FAIL_NOT_SCHEDULED_YET = 4; // 0x4
-    field @Deprecated public static final int RTT_STATUS_FAIL_NO_CAPABILITY = 7; // 0x7
-    field @Deprecated public static final int RTT_STATUS_FAIL_NO_RSP = 2; // 0x2
-    field @Deprecated public static final int RTT_STATUS_FAIL_PROTOCOL = 10; // 0xa
-    field @Deprecated public static final int RTT_STATUS_FAIL_REJECTED = 3; // 0x3
-    field @Deprecated public static final int RTT_STATUS_FAIL_SCHEDULE = 11; // 0xb
-    field @Deprecated public static final int RTT_STATUS_FAIL_TM_TIMEOUT = 5; // 0x5
-    field @Deprecated public static final int RTT_STATUS_INVALID_REQ = 13; // 0xd
-    field @Deprecated public static final int RTT_STATUS_NO_WIFI = 14; // 0xe
-    field @Deprecated public static final int RTT_STATUS_SUCCESS = 0; // 0x0
-    field @Deprecated public static final int RTT_TYPE_11_MC = 4; // 0x4
-    field @Deprecated public static final int RTT_TYPE_11_V = 2; // 0x2
-    field @Deprecated public static final int RTT_TYPE_ONE_SIDED = 1; // 0x1
-    field @Deprecated public static final int RTT_TYPE_TWO_SIDED = 2; // 0x2
-    field @Deprecated public static final int RTT_TYPE_UNSPECIFIED = 0; // 0x0
-  }
-
-  @Deprecated public class RttManager.Capabilities {
-    ctor @Deprecated public RttManager.Capabilities();
-    field @Deprecated public int supportedPeerType;
-    field @Deprecated public int supportedType;
-  }
-
-  @Deprecated public static class RttManager.ParcelableRttParams implements android.os.Parcelable {
-    field @Deprecated @NonNull public android.net.wifi.RttManager.RttParams[] mParams;
-  }
-
-  @Deprecated public static class RttManager.ParcelableRttResults implements android.os.Parcelable {
-    ctor @Deprecated public RttManager.ParcelableRttResults(android.net.wifi.RttManager.RttResult[]);
-    field @Deprecated public android.net.wifi.RttManager.RttResult[] mResults;
-  }
-
-  @Deprecated public abstract static class RttManager.ResponderCallback {
-    ctor @Deprecated public RttManager.ResponderCallback();
-    method @Deprecated public abstract void onResponderEnableFailure(int);
-    method @Deprecated public abstract void onResponderEnabled(android.net.wifi.RttManager.ResponderConfig);
-  }
-
-  @Deprecated public static class RttManager.ResponderConfig implements android.os.Parcelable {
-    ctor @Deprecated public RttManager.ResponderConfig();
-    method @Deprecated public int describeContents();
-    method @Deprecated public void writeToParcel(android.os.Parcel, int);
-    field @Deprecated @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.RttManager.ResponderConfig> CREATOR;
-    field @Deprecated public int centerFreq0;
-    field @Deprecated public int centerFreq1;
-    field @Deprecated public int channelWidth;
-    field @Deprecated public int frequency;
-    field @Deprecated public String macAddress;
-    field @Deprecated public int preamble;
-  }
-
-  @Deprecated public static class RttManager.RttCapabilities implements android.os.Parcelable {
-    ctor @Deprecated public RttManager.RttCapabilities();
-    field @Deprecated public int bwSupported;
-    field @Deprecated public boolean lciSupported;
-    field @Deprecated public boolean lcrSupported;
-    field @Deprecated public int mcVersion;
-    field @Deprecated public boolean oneSidedRttSupported;
-    field @Deprecated public int preambleSupported;
-    field @Deprecated public boolean responderSupported;
-    field @Deprecated public boolean secureRttSupported;
-    field @Deprecated public boolean supportedPeerType;
-    field @Deprecated public boolean supportedType;
-    field @Deprecated public boolean twoSided11McRttSupported;
-  }
-
-  @Deprecated public static interface RttManager.RttListener {
-    method @Deprecated public void onAborted();
-    method @Deprecated public void onFailure(int, String);
-    method @Deprecated public void onSuccess(android.net.wifi.RttManager.RttResult[]);
-  }
-
-  @Deprecated public static class RttManager.RttParams {
-    ctor @Deprecated public RttManager.RttParams();
-    field @Deprecated public boolean LCIRequest;
-    field @Deprecated public boolean LCRRequest;
-    field @Deprecated public int bandwidth;
-    field @Deprecated public String bssid;
-    field @Deprecated public int burstTimeout;
-    field @Deprecated public int centerFreq0;
-    field @Deprecated public int centerFreq1;
-    field @Deprecated public int channelWidth;
-    field @Deprecated public int deviceType;
-    field @Deprecated public int frequency;
-    field @Deprecated public int interval;
-    field @Deprecated public int numRetriesPerFTMR;
-    field @Deprecated public int numRetriesPerMeasurementFrame;
-    field @Deprecated public int numSamplesPerBurst;
-    field @Deprecated public int num_retries;
-    field @Deprecated public int num_samples;
-    field @Deprecated public int numberBurst;
-    field @Deprecated public int preamble;
-    field @Deprecated public int requestType;
-    field @Deprecated public boolean secure;
-  }
-
-  @Deprecated public static class RttManager.RttResult {
-    ctor @Deprecated public RttManager.RttResult();
-    field @Deprecated public android.net.wifi.RttManager.WifiInformationElement LCI;
-    field @Deprecated public android.net.wifi.RttManager.WifiInformationElement LCR;
-    field @Deprecated public String bssid;
-    field @Deprecated public int burstDuration;
-    field @Deprecated public int burstNumber;
-    field @Deprecated public int distance;
-    field @Deprecated public int distanceSpread;
-    field @Deprecated public int distanceStandardDeviation;
-    field @Deprecated public int distance_cm;
-    field @Deprecated public int distance_sd_cm;
-    field @Deprecated public int distance_spread_cm;
-    field @Deprecated public int frameNumberPerBurstPeer;
-    field @Deprecated public int measurementFrameNumber;
-    field @Deprecated public int measurementType;
-    field @Deprecated public int negotiatedBurstNum;
-    field @Deprecated public int requestType;
-    field @Deprecated public int retryAfterDuration;
-    field @Deprecated public int rssi;
-    field @Deprecated public int rssiSpread;
-    field @Deprecated public int rssi_spread;
-    field @Deprecated public long rtt;
-    field @Deprecated public long rttSpread;
-    field @Deprecated public long rttStandardDeviation;
-    field @Deprecated public long rtt_ns;
-    field @Deprecated public long rtt_sd_ns;
-    field @Deprecated public long rtt_spread_ns;
-    field @Deprecated public int rxRate;
-    field @Deprecated public boolean secure;
-    field @Deprecated public int status;
-    field @Deprecated public int successMeasurementFrameNumber;
-    field @Deprecated public long ts;
-    field @Deprecated public int txRate;
-    field @Deprecated public int tx_rate;
-  }
-
-  @Deprecated public static class RttManager.WifiInformationElement {
-    ctor @Deprecated public RttManager.WifiInformationElement();
-    field @Deprecated public byte[] data;
-    field @Deprecated public byte id;
-  }
-
-  public final class ScanResult implements android.os.Parcelable {
-    field public static final int CIPHER_CCMP = 3; // 0x3
-    field public static final int CIPHER_GCMP_256 = 4; // 0x4
-    field public static final int CIPHER_NONE = 0; // 0x0
-    field public static final int CIPHER_NO_GROUP_ADDRESSED = 1; // 0x1
-    field public static final int CIPHER_SMS4 = 5; // 0x5
-    field public static final int CIPHER_TKIP = 2; // 0x2
-    field public static final int KEY_MGMT_EAP = 2; // 0x2
-    field public static final int KEY_MGMT_EAP_SHA256 = 6; // 0x6
-    field public static final int KEY_MGMT_EAP_SUITE_B_192 = 10; // 0xa
-    field public static final int KEY_MGMT_FT_EAP = 4; // 0x4
-    field public static final int KEY_MGMT_FT_PSK = 3; // 0x3
-    field public static final int KEY_MGMT_FT_SAE = 11; // 0xb
-    field public static final int KEY_MGMT_NONE = 0; // 0x0
-    field public static final int KEY_MGMT_OSEN = 7; // 0x7
-    field public static final int KEY_MGMT_OWE = 9; // 0x9
-    field public static final int KEY_MGMT_OWE_TRANSITION = 12; // 0xc
-    field public static final int KEY_MGMT_PSK = 1; // 0x1
-    field public static final int KEY_MGMT_PSK_SHA256 = 5; // 0x5
-    field public static final int KEY_MGMT_SAE = 8; // 0x8
-    field public static final int KEY_MGMT_WAPI_CERT = 14; // 0xe
-    field public static final int KEY_MGMT_WAPI_PSK = 13; // 0xd
-    field public static final int PROTOCOL_NONE = 0; // 0x0
-    field public static final int PROTOCOL_OSEN = 3; // 0x3
-    field public static final int PROTOCOL_RSN = 2; // 0x2
-    field public static final int PROTOCOL_WAPI = 4; // 0x4
-    field public static final int PROTOCOL_WPA = 1; // 0x1
-  }
-
-  public final class SoftApCapability implements android.os.Parcelable {
-    method public boolean areFeaturesSupported(long);
-    method public int describeContents();
-    method public int getMaxSupportedClients();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.SoftApCapability> CREATOR;
-    field public static final long SOFTAP_FEATURE_ACS_OFFLOAD = 1L; // 0x1L
-    field public static final long SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT = 2L; // 0x2L
-    field public static final long SOFTAP_FEATURE_WPA3_SAE = 4L; // 0x4L
-  }
-
-  public final class SoftApConfiguration implements android.os.Parcelable {
-    method @NonNull public java.util.List<android.net.MacAddress> getAllowedClientList();
-    method public int getBand();
-    method @NonNull public java.util.List<android.net.MacAddress> getBlockedClientList();
-    method public int getChannel();
-    method public int getMaxNumberOfClients();
-    method public long getShutdownTimeoutMillis();
-    method public boolean isAutoShutdownEnabled();
-    method public boolean isClientControlByUserEnabled();
-    method @Nullable public android.net.wifi.WifiConfiguration toWifiConfiguration();
-    field public static final int BAND_2GHZ = 1; // 0x1
-    field public static final int BAND_5GHZ = 2; // 0x2
-    field public static final int BAND_6GHZ = 4; // 0x4
-    field public static final int BAND_ANY = 7; // 0x7
-  }
-
-  public static final class SoftApConfiguration.Builder {
-    ctor public SoftApConfiguration.Builder();
-    ctor public SoftApConfiguration.Builder(@NonNull android.net.wifi.SoftApConfiguration);
-    method @NonNull public android.net.wifi.SoftApConfiguration build();
-    method @NonNull public android.net.wifi.SoftApConfiguration.Builder setAllowedClientList(@NonNull java.util.List<android.net.MacAddress>);
-    method @NonNull public android.net.wifi.SoftApConfiguration.Builder setAutoShutdownEnabled(boolean);
-    method @NonNull public android.net.wifi.SoftApConfiguration.Builder setBand(int);
-    method @NonNull public android.net.wifi.SoftApConfiguration.Builder setBlockedClientList(@NonNull java.util.List<android.net.MacAddress>);
-    method @NonNull public android.net.wifi.SoftApConfiguration.Builder setBssid(@Nullable android.net.MacAddress);
-    method @NonNull public android.net.wifi.SoftApConfiguration.Builder setChannel(int, int);
-    method @NonNull public android.net.wifi.SoftApConfiguration.Builder setClientControlByUserEnabled(boolean);
-    method @NonNull public android.net.wifi.SoftApConfiguration.Builder setHiddenSsid(boolean);
-    method @NonNull public android.net.wifi.SoftApConfiguration.Builder setMaxNumberOfClients(@IntRange(from=0) int);
-    method @NonNull public android.net.wifi.SoftApConfiguration.Builder setPassphrase(@Nullable String, int);
-    method @NonNull public android.net.wifi.SoftApConfiguration.Builder setShutdownTimeoutMillis(@IntRange(from=0) long);
-    method @NonNull public android.net.wifi.SoftApConfiguration.Builder setSsid(@Nullable String);
-  }
-
-  public final class SoftApInfo implements android.os.Parcelable {
-    method public int describeContents();
-    method public int getBandwidth();
-    method public int getFrequency();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field public static final int CHANNEL_WIDTH_160MHZ = 6; // 0x6
-    field public static final int CHANNEL_WIDTH_20MHZ = 2; // 0x2
-    field public static final int CHANNEL_WIDTH_20MHZ_NOHT = 1; // 0x1
-    field public static final int CHANNEL_WIDTH_40MHZ = 3; // 0x3
-    field public static final int CHANNEL_WIDTH_80MHZ = 4; // 0x4
-    field public static final int CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 5; // 0x5
-    field public static final int CHANNEL_WIDTH_INVALID = 0; // 0x0
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.SoftApInfo> CREATOR;
-  }
-
-  public final class WifiClient implements android.os.Parcelable {
-    method public int describeContents();
-    method @NonNull public android.net.MacAddress getMacAddress();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.WifiClient> CREATOR;
-  }
-
-  @Deprecated public class WifiConfiguration implements android.os.Parcelable {
-    method @Deprecated public int getAuthType();
-    method @Deprecated @NonNull public android.net.IpConfiguration getIpConfiguration();
-    method @Deprecated @NonNull public android.net.wifi.WifiConfiguration.NetworkSelectionStatus getNetworkSelectionStatus();
-    method @Deprecated @NonNull public String getPrintableSsid();
-    method @Deprecated public int getRecentFailureReason();
-    method @Deprecated public boolean hasNoInternetAccess();
-    method @Deprecated public boolean isEphemeral();
-    method @Deprecated public static boolean isMetered(@Nullable android.net.wifi.WifiConfiguration, @Nullable android.net.wifi.WifiInfo);
-    method @Deprecated public boolean isNoInternetAccessExpected();
-    method @Deprecated public void setIpConfiguration(@Nullable android.net.IpConfiguration);
-    method @Deprecated public void setNetworkSelectionStatus(@NonNull android.net.wifi.WifiConfiguration.NetworkSelectionStatus);
-    field @Deprecated public static final int INVALID_NETWORK_ID = -1; // 0xffffffff
-    field @Deprecated public static final int METERED_OVERRIDE_METERED = 1; // 0x1
-    field @Deprecated public static final int METERED_OVERRIDE_NONE = 0; // 0x0
-    field @Deprecated public static final int METERED_OVERRIDE_NOT_METERED = 2; // 0x2
-    field @Deprecated public static final int RANDOMIZATION_NONE = 0; // 0x0
-    field @Deprecated public static final int RANDOMIZATION_PERSISTENT = 1; // 0x1
-    field @Deprecated public static final int RECENT_FAILURE_AP_UNABLE_TO_HANDLE_NEW_STA = 17; // 0x11
-    field @Deprecated public static final int RECENT_FAILURE_NONE = 0; // 0x0
-    field @Deprecated public boolean allowAutojoin;
-    field @Deprecated public int carrierId;
-    field @Deprecated public String creatorName;
-    field @Deprecated public int creatorUid;
-    field @Deprecated public boolean fromWifiNetworkSpecifier;
-    field @Deprecated public boolean fromWifiNetworkSuggestion;
-    field @Deprecated public String lastUpdateName;
-    field @Deprecated public int lastUpdateUid;
-    field @Deprecated public int macRandomizationSetting;
-    field @Deprecated public boolean meteredHint;
-    field @Deprecated public int meteredOverride;
-    field @Deprecated public int numAssociation;
-    field @Deprecated public int numScorerOverride;
-    field @Deprecated public int numScorerOverrideAndSwitchedNetwork;
-    field @Deprecated public boolean requirePmf;
-    field @Deprecated public boolean shared;
-    field @Deprecated public boolean useExternalScores;
-  }
-
-  @Deprecated public static class WifiConfiguration.KeyMgmt {
-    field @Deprecated public static final int WAPI_CERT = 14; // 0xe
-    field @Deprecated public static final int WAPI_PSK = 13; // 0xd
-    field @Deprecated public static final int WPA2_PSK = 4; // 0x4
-  }
-
-  @Deprecated public static class WifiConfiguration.NetworkSelectionStatus {
-    method @Deprecated public int getDisableReasonCounter(int);
-    method @Deprecated public long getDisableTime();
-    method @Deprecated public static int getMaxNetworkSelectionDisableReason();
-    method @Deprecated public int getNetworkSelectionDisableReason();
-    method @Deprecated @Nullable public static String getNetworkSelectionDisableReasonString(int);
-    method @Deprecated public int getNetworkSelectionStatus();
-    method @Deprecated @NonNull public String getNetworkStatusString();
-    method @Deprecated public boolean hasEverConnected();
-    field @Deprecated public static final int DISABLED_ASSOCIATION_REJECTION = 1; // 0x1
-    field @Deprecated public static final int DISABLED_AUTHENTICATION_FAILURE = 2; // 0x2
-    field @Deprecated public static final int DISABLED_AUTHENTICATION_NO_CREDENTIALS = 5; // 0x5
-    field @Deprecated public static final int DISABLED_AUTHENTICATION_NO_SUBSCRIPTION = 9; // 0x9
-    field @Deprecated public static final int DISABLED_BY_WIFI_MANAGER = 7; // 0x7
-    field @Deprecated public static final int DISABLED_BY_WRONG_PASSWORD = 8; // 0x8
-    field @Deprecated public static final int DISABLED_DHCP_FAILURE = 3; // 0x3
-    field @Deprecated public static final int DISABLED_NONE = 0; // 0x0
-    field @Deprecated public static final int DISABLED_NO_INTERNET_PERMANENT = 6; // 0x6
-    field @Deprecated public static final int DISABLED_NO_INTERNET_TEMPORARY = 4; // 0x4
-    field @Deprecated public static final int NETWORK_SELECTION_ENABLED = 0; // 0x0
-    field @Deprecated public static final int NETWORK_SELECTION_PERMANENTLY_DISABLED = 2; // 0x2
-    field @Deprecated public static final int NETWORK_SELECTION_TEMPORARY_DISABLED = 1; // 0x1
-  }
-
-  @Deprecated public static final class WifiConfiguration.NetworkSelectionStatus.Builder {
-    ctor @Deprecated public WifiConfiguration.NetworkSelectionStatus.Builder();
-    method @Deprecated @NonNull public android.net.wifi.WifiConfiguration.NetworkSelectionStatus build();
-    method @Deprecated @NonNull public android.net.wifi.WifiConfiguration.NetworkSelectionStatus.Builder setNetworkSelectionDisableReason(int);
-    method @Deprecated @NonNull public android.net.wifi.WifiConfiguration.NetworkSelectionStatus.Builder setNetworkSelectionStatus(int);
-  }
-
-  public class WifiEnterpriseConfig implements android.os.Parcelable {
-    method @Nullable public String[] getCaCertificateAliases();
-    method @NonNull public String getCaPath();
-    method @NonNull public String getClientCertificateAlias();
-    method public int getOcsp();
-    method @NonNull public String getWapiCertSuite();
-    method public void setCaCertificateAliases(@Nullable String[]);
-    method public void setCaPath(@NonNull String);
-    method public void setClientCertificateAlias(@NonNull String);
-    method public void setOcsp(int);
-    method public void setWapiCertSuite(@NonNull String);
-    field public static final int OCSP_NONE = 0; // 0x0
-    field public static final int OCSP_REQUEST_CERT_STATUS = 1; // 0x1
-    field public static final int OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS = 3; // 0x3
-    field public static final int OCSP_REQUIRE_CERT_STATUS = 2; // 0x2
-  }
-
-  public class WifiFrameworkInitializer {
-    method public static void registerServiceWrappers();
-  }
-
-  public class WifiInfo implements android.os.Parcelable {
-    method public double getLostTxPacketsPerSecond();
-    method @Nullable public String getRequestingPackageName();
-    method public double getRetriedTxPacketsPerSecond();
-    method public int getScore();
-    method public double getSuccessfulRxPacketsPerSecond();
-    method public double getSuccessfulTxPacketsPerSecond();
-    method public boolean isEphemeral();
-    method public boolean isOsuAp();
-    method public boolean isPasspointAp();
-    method @Nullable public static String sanitizeSsid(@Nullable String);
-    field public static final String DEFAULT_MAC_ADDRESS = "02:00:00:00:00:00";
-    field public static final int INVALID_RSSI = -127; // 0xffffff81
-  }
-
-  public class WifiManager {
-    method @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE) public void addOnWifiUsabilityStatsListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.OnWifiUsabilityStatsListener);
-    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void allowAutojoin(int, boolean);
-    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void allowAutojoinGlobal(boolean);
-    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void allowAutojoinPasspoint(@NonNull String, boolean);
-    method @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE) public void clearWifiConnectedNetworkScorer();
-    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void connect(@NonNull android.net.wifi.WifiConfiguration, @Nullable android.net.wifi.WifiManager.ActionListener);
-    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void connect(int, @Nullable android.net.wifi.WifiManager.ActionListener);
-    method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void disable(int, @Nullable android.net.wifi.WifiManager.ActionListener);
-    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK}) public void disableEphemeralNetwork(@NonNull String);
-    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void factoryReset();
-    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void forget(int, @Nullable android.net.wifi.WifiManager.ActionListener);
-    method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.List<android.util.Pair<android.net.wifi.WifiConfiguration,java.util.Map<java.lang.Integer,java.util.List<android.net.wifi.ScanResult>>>> getAllMatchingWifiConfigs(@NonNull java.util.List<android.net.wifi.ScanResult>);
-    method @Nullable @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public String getCountryCode();
-    method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public android.net.Network getCurrentNetwork();
-    method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public String[] getFactoryMacAddresses();
-    method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.Map<android.net.wifi.hotspot2.OsuProvider,java.util.List<android.net.wifi.ScanResult>> getMatchingOsuProviders(@Nullable java.util.List<android.net.wifi.ScanResult>);
-    method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.Map<android.net.wifi.hotspot2.OsuProvider,android.net.wifi.hotspot2.PasspointConfiguration> getMatchingPasspointConfigsForOsuProviders(@NonNull java.util.Set<android.net.wifi.hotspot2.OsuProvider>);
-    method @NonNull @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_WIFI_STATE}) public java.util.Map<android.net.wifi.WifiNetworkSuggestion,java.util.List<android.net.wifi.ScanResult>> getMatchingScanResults(@NonNull java.util.List<android.net.wifi.WifiNetworkSuggestion>, @Nullable java.util.List<android.net.wifi.ScanResult>);
-    method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_WIFI_STATE, android.Manifest.permission.READ_WIFI_CREDENTIAL}) public java.util.List<android.net.wifi.WifiConfiguration> getPrivilegedConfiguredNetworks();
-    method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public android.net.wifi.SoftApConfiguration getSoftApConfiguration();
-    method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public void getWifiActivityEnergyInfoAsync(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.OnWifiActivityEnergyInfoListener);
-    method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public android.net.wifi.WifiConfiguration getWifiApConfiguration();
-    method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public int getWifiApState();
-    method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.List<android.net.wifi.WifiConfiguration> getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(@NonNull java.util.List<android.net.wifi.ScanResult>);
-    method public boolean isApMacRandomizationSupported();
-    method public boolean isConnectedMacRandomizationSupported();
-    method @Deprecated public boolean isDeviceToDeviceRttSupported();
-    method public boolean isPortableHotspotSupported();
-    method public boolean isVerboseLoggingEnabled();
-    method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public boolean isWifiApEnabled();
-    method public boolean isWifiScannerSupported();
-    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void registerNetworkRequestMatchCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.NetworkRequestMatchCallback);
-    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void registerSoftApCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.SoftApCallback);
-    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void registerTrafficStateCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.TrafficStateCallback);
-    method @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE) public void removeOnWifiUsabilityStatsListener(@NonNull android.net.wifi.WifiManager.OnWifiUsabilityStatsListener);
-    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void restoreBackupData(@NonNull byte[]);
-    method @Nullable @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public android.net.wifi.SoftApConfiguration restoreSoftApBackupData(@NonNull byte[]);
-    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void restoreSupplicantBackupData(@NonNull byte[], @NonNull byte[]);
-    method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public byte[] retrieveBackupData();
-    method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public byte[] retrieveSoftApBackupData();
-    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void save(@NonNull android.net.wifi.WifiConfiguration, @Nullable android.net.wifi.WifiManager.ActionListener);
-    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void setAutoWakeupEnabled(boolean);
-    method @RequiresPermission(android.Manifest.permission.WIFI_SET_DEVICE_MOBILITY_STATE) public void setDeviceMobilityState(int);
-    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void setMacRandomizationSettingPasspointEnabled(@NonNull String, boolean);
-    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void setPasspointMeteredOverride(@NonNull String, int);
-    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void setScanAlwaysAvailable(boolean);
-    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void setScanThrottleEnabled(boolean);
-    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public boolean setSoftApConfiguration(@NonNull android.net.wifi.SoftApConfiguration);
-    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void setVerboseLoggingEnabled(boolean);
-    method @Deprecated @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE) public boolean setWifiApConfiguration(android.net.wifi.WifiConfiguration);
-    method @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE) public boolean setWifiConnectedNetworkScorer(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.WifiConnectedNetworkScorer);
-    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startEasyConnectAsConfiguratorInitiator(@NonNull String, int, int, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.EasyConnectStatusCallback);
-    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startEasyConnectAsEnrolleeInitiator(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.EasyConnectStatusCallback);
-    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startLocalOnlyHotspot(@NonNull android.net.wifi.SoftApConfiguration, @Nullable java.util.concurrent.Executor, @Nullable android.net.wifi.WifiManager.LocalOnlyHotspotCallback);
-    method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public boolean startScan(android.os.WorkSource);
-    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startSubscriptionProvisioning(@NonNull android.net.wifi.hotspot2.OsuProvider, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.hotspot2.ProvisioningCallback);
-    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public boolean startTetheredHotspot(@Nullable android.net.wifi.SoftApConfiguration);
-    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void stopEasyConnectSession();
-    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public boolean stopSoftAp();
-    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void unregisterNetworkRequestMatchCallback(@NonNull android.net.wifi.WifiManager.NetworkRequestMatchCallback);
-    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void unregisterSoftApCallback(@NonNull android.net.wifi.WifiManager.SoftApCallback);
-    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void unregisterTrafficStateCallback(@NonNull android.net.wifi.WifiManager.TrafficStateCallback);
-    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void updateInterfaceIpState(@Nullable String, int);
-    method @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE) public void updateWifiUsabilityScore(int, int, int);
-    field public static final String ACTION_LINK_CONFIGURATION_CHANGED = "android.net.wifi.LINK_CONFIGURATION_CHANGED";
-    field @RequiresPermission(android.Manifest.permission.NETWORK_CARRIER_PROVISIONING) public static final String ACTION_NETWORK_SETTINGS_RESET = "android.net.wifi.action.NETWORK_SETTINGS_RESET";
-    field public static final String ACTION_PASSPOINT_LAUNCH_OSU_VIEW = "android.net.wifi.action.PASSPOINT_LAUNCH_OSU_VIEW";
-    field public static final String ACTION_REQUEST_DISABLE = "android.net.wifi.action.REQUEST_DISABLE";
-    field public static final String ACTION_REQUEST_ENABLE = "android.net.wifi.action.REQUEST_ENABLE";
-    field public static final int CHANGE_REASON_ADDED = 0; // 0x0
-    field public static final int CHANGE_REASON_CONFIG_CHANGE = 2; // 0x2
-    field public static final int CHANGE_REASON_REMOVED = 1; // 0x1
-    field public static final String CONFIGURED_NETWORKS_CHANGED_ACTION = "android.net.wifi.CONFIGURED_NETWORKS_CHANGE";
-    field public static final int DEVICE_MOBILITY_STATE_HIGH_MVMT = 1; // 0x1
-    field public static final int DEVICE_MOBILITY_STATE_LOW_MVMT = 2; // 0x2
-    field public static final int DEVICE_MOBILITY_STATE_STATIONARY = 3; // 0x3
-    field public static final int DEVICE_MOBILITY_STATE_UNKNOWN = 0; // 0x0
-    field public static final int EASY_CONNECT_NETWORK_ROLE_AP = 1; // 0x1
-    field public static final int EASY_CONNECT_NETWORK_ROLE_STA = 0; // 0x0
-    field public static final String EXTRA_CHANGE_REASON = "changeReason";
-    field public static final String EXTRA_LINK_PROPERTIES = "android.net.wifi.extra.LINK_PROPERTIES";
-    field public static final String EXTRA_MULTIPLE_NETWORKS_CHANGED = "multipleChanges";
-    field public static final String EXTRA_OSU_NETWORK = "android.net.wifi.extra.OSU_NETWORK";
-    field public static final String EXTRA_PREVIOUS_WIFI_AP_STATE = "previous_wifi_state";
-    field public static final String EXTRA_URL = "android.net.wifi.extra.URL";
-    field public static final String EXTRA_WIFI_AP_FAILURE_REASON = "android.net.wifi.extra.WIFI_AP_FAILURE_REASON";
-    field public static final String EXTRA_WIFI_AP_INTERFACE_NAME = "android.net.wifi.extra.WIFI_AP_INTERFACE_NAME";
-    field public static final String EXTRA_WIFI_AP_MODE = "android.net.wifi.extra.WIFI_AP_MODE";
-    field public static final String EXTRA_WIFI_AP_STATE = "wifi_state";
-    field public static final String EXTRA_WIFI_CONFIGURATION = "wifiConfiguration";
-    field public static final String EXTRA_WIFI_CREDENTIAL_EVENT_TYPE = "et";
-    field public static final String EXTRA_WIFI_CREDENTIAL_SSID = "ssid";
-    field public static final int IFACE_IP_MODE_CONFIGURATION_ERROR = 0; // 0x0
-    field public static final int IFACE_IP_MODE_LOCAL_ONLY = 2; // 0x2
-    field public static final int IFACE_IP_MODE_TETHERED = 1; // 0x1
-    field public static final int IFACE_IP_MODE_UNSPECIFIED = -1; // 0xffffffff
-    field public static final int PASSPOINT_HOME_NETWORK = 0; // 0x0
-    field public static final int PASSPOINT_ROAMING_NETWORK = 1; // 0x1
-    field public static final int SAP_CLIENT_BLOCK_REASON_CODE_BLOCKED_BY_USER = 0; // 0x0
-    field public static final int SAP_CLIENT_BLOCK_REASON_CODE_NO_MORE_STAS = 1; // 0x1
-    field public static final int SAP_START_FAILURE_GENERAL = 0; // 0x0
-    field public static final int SAP_START_FAILURE_NO_CHANNEL = 1; // 0x1
-    field public static final int SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION = 2; // 0x2
-    field public static final String WIFI_AP_STATE_CHANGED_ACTION = "android.net.wifi.WIFI_AP_STATE_CHANGED";
-    field public static final int WIFI_AP_STATE_DISABLED = 11; // 0xb
-    field public static final int WIFI_AP_STATE_DISABLING = 10; // 0xa
-    field public static final int WIFI_AP_STATE_ENABLED = 13; // 0xd
-    field public static final int WIFI_AP_STATE_ENABLING = 12; // 0xc
-    field public static final int WIFI_AP_STATE_FAILED = 14; // 0xe
-    field public static final String WIFI_CREDENTIAL_CHANGED_ACTION = "android.net.wifi.WIFI_CREDENTIAL_CHANGED";
-    field public static final int WIFI_CREDENTIAL_FORGOT = 1; // 0x1
-    field public static final int WIFI_CREDENTIAL_SAVED = 0; // 0x0
-  }
-
-  public static interface WifiManager.ActionListener {
-    method public void onFailure(int);
-    method public void onSuccess();
-  }
-
-  public static interface WifiManager.NetworkRequestMatchCallback {
-    method public default void onAbort();
-    method public default void onMatch(@NonNull java.util.List<android.net.wifi.ScanResult>);
-    method public default void onUserSelectionCallbackRegistration(@NonNull android.net.wifi.WifiManager.NetworkRequestUserSelectionCallback);
-    method public default void onUserSelectionConnectFailure(@NonNull android.net.wifi.WifiConfiguration);
-    method public default void onUserSelectionConnectSuccess(@NonNull android.net.wifi.WifiConfiguration);
-  }
-
-  public static interface WifiManager.NetworkRequestUserSelectionCallback {
-    method public default void reject();
-    method public default void select(@NonNull android.net.wifi.WifiConfiguration);
-  }
-
-  public static interface WifiManager.OnWifiActivityEnergyInfoListener {
-    method public void onWifiActivityEnergyInfo(@Nullable android.os.connectivity.WifiActivityEnergyInfo);
-  }
-
-  public static interface WifiManager.OnWifiUsabilityStatsListener {
-    method public void onWifiUsabilityStats(int, boolean, @NonNull android.net.wifi.WifiUsabilityStatsEntry);
-  }
-
-  public static interface WifiManager.ScoreUpdateObserver {
-    method public void notifyScoreUpdate(int, int);
-    method public void triggerUpdateOfWifiUsabilityStats(int);
-  }
-
-  public static interface WifiManager.SoftApCallback {
-    method public default void onBlockedClientConnecting(@NonNull android.net.wifi.WifiClient, int);
-    method public default void onCapabilityChanged(@NonNull android.net.wifi.SoftApCapability);
-    method public default void onConnectedClientsChanged(@NonNull java.util.List<android.net.wifi.WifiClient>);
-    method public default void onInfoChanged(@NonNull android.net.wifi.SoftApInfo);
-    method public default void onStateChanged(int, int);
-  }
-
-  public static interface WifiManager.TrafficStateCallback {
-    method public void onStateChanged(int);
-    field public static final int DATA_ACTIVITY_IN = 1; // 0x1
-    field public static final int DATA_ACTIVITY_INOUT = 3; // 0x3
-    field public static final int DATA_ACTIVITY_NONE = 0; // 0x0
-    field public static final int DATA_ACTIVITY_OUT = 2; // 0x2
-  }
-
-  public static interface WifiManager.WifiConnectedNetworkScorer {
-    method public void onSetScoreUpdateObserver(@NonNull android.net.wifi.WifiManager.ScoreUpdateObserver);
-    method public void onStart(int);
-    method public void onStop(int);
-  }
-
-  public class WifiNetworkConnectionStatistics implements android.os.Parcelable {
-    ctor public WifiNetworkConnectionStatistics(int, int);
-    ctor public WifiNetworkConnectionStatistics();
-    ctor public WifiNetworkConnectionStatistics(android.net.wifi.WifiNetworkConnectionStatistics);
-    method public int describeContents();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.WifiNetworkConnectionStatistics> CREATOR;
-    field public int numConnection;
-    field public int numUsage;
-  }
-
-  public final class WifiNetworkSuggestion implements android.os.Parcelable {
-    method @NonNull public android.net.wifi.WifiConfiguration getWifiConfiguration();
-  }
-
-  public static final class WifiNetworkSuggestion.Builder {
-    method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_CARRIER_PROVISIONING) public android.net.wifi.WifiNetworkSuggestion.Builder setCarrierId(int);
-  }
-
-  public class WifiScanner {
-    method @Deprecated public void configureWifiChange(int, int, int, int, int, android.net.wifi.WifiScanner.BssidInfo[]);
-    method @Deprecated public void configureWifiChange(android.net.wifi.WifiScanner.WifiChangeSettings);
-    method @NonNull @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public java.util.List<java.lang.Integer> getAvailableChannels(int);
-    method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public boolean getScanResults();
-    method @NonNull @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public java.util.List<android.net.wifi.ScanResult> getSingleScanResults();
-    method @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public void registerScanListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiScanner.ScanListener);
-    method @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public void setScanningEnabled(boolean);
-    method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void startBackgroundScan(android.net.wifi.WifiScanner.ScanSettings, android.net.wifi.WifiScanner.ScanListener);
-    method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void startBackgroundScan(android.net.wifi.WifiScanner.ScanSettings, android.net.wifi.WifiScanner.ScanListener, android.os.WorkSource);
-    method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void startScan(android.net.wifi.WifiScanner.ScanSettings, android.net.wifi.WifiScanner.ScanListener);
-    method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void startScan(android.net.wifi.WifiScanner.ScanSettings, android.net.wifi.WifiScanner.ScanListener, android.os.WorkSource);
-    method @Deprecated public void startTrackingBssids(android.net.wifi.WifiScanner.BssidInfo[], int, android.net.wifi.WifiScanner.BssidListener);
-    method @Deprecated public void startTrackingWifiChange(android.net.wifi.WifiScanner.WifiChangeListener);
-    method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void stopBackgroundScan(android.net.wifi.WifiScanner.ScanListener);
-    method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void stopScan(android.net.wifi.WifiScanner.ScanListener);
-    method @Deprecated public void stopTrackingBssids(android.net.wifi.WifiScanner.BssidListener);
-    method @Deprecated public void stopTrackingWifiChange(android.net.wifi.WifiScanner.WifiChangeListener);
-    method public void unregisterScanListener(@NonNull android.net.wifi.WifiScanner.ScanListener);
-    field public static final int MAX_SCAN_PERIOD_MS = 1024000; // 0xfa000
-    field public static final int MIN_SCAN_PERIOD_MS = 1000; // 0x3e8
-    field public static final int REASON_DUPLICATE_REQEUST = -5; // 0xfffffffb
-    field public static final int REASON_INVALID_LISTENER = -2; // 0xfffffffe
-    field public static final int REASON_INVALID_REQUEST = -3; // 0xfffffffd
-    field public static final int REASON_NOT_AUTHORIZED = -4; // 0xfffffffc
-    field public static final int REASON_SUCCEEDED = 0; // 0x0
-    field public static final int REASON_UNSPECIFIED = -1; // 0xffffffff
-    field @Deprecated public static final int REPORT_EVENT_AFTER_BUFFER_FULL = 0; // 0x0
-    field public static final int REPORT_EVENT_AFTER_EACH_SCAN = 1; // 0x1
-    field public static final int REPORT_EVENT_FULL_SCAN_RESULT = 2; // 0x2
-    field public static final int REPORT_EVENT_NO_BATCH = 4; // 0x4
-    field public static final int SCAN_TYPE_HIGH_ACCURACY = 2; // 0x2
-    field public static final int SCAN_TYPE_LOW_LATENCY = 0; // 0x0
-    field public static final int SCAN_TYPE_LOW_POWER = 1; // 0x1
-    field public static final int WIFI_BAND_24_5_6_GHZ = 11; // 0xb
-    field public static final int WIFI_BAND_24_5_WITH_DFS_6_GHZ = 15; // 0xf
-    field public static final int WIFI_BAND_24_GHZ = 1; // 0x1
-    field public static final int WIFI_BAND_5_GHZ = 2; // 0x2
-    field public static final int WIFI_BAND_5_GHZ_DFS_ONLY = 4; // 0x4
-    field public static final int WIFI_BAND_5_GHZ_WITH_DFS = 6; // 0x6
-    field public static final int WIFI_BAND_6_GHZ = 8; // 0x8
-    field public static final int WIFI_BAND_BOTH = 3; // 0x3
-    field public static final int WIFI_BAND_BOTH_WITH_DFS = 7; // 0x7
-    field public static final int WIFI_BAND_UNSPECIFIED = 0; // 0x0
-  }
-
-  public static interface WifiScanner.ActionListener {
-    method public void onFailure(int, String);
-    method public void onSuccess();
-  }
-
-  @Deprecated public static class WifiScanner.BssidInfo {
-    ctor @Deprecated public WifiScanner.BssidInfo();
-    field @Deprecated public String bssid;
-    field @Deprecated public int frequencyHint;
-    field @Deprecated public int high;
-    field @Deprecated public int low;
-  }
-
-  @Deprecated public static interface WifiScanner.BssidListener extends android.net.wifi.WifiScanner.ActionListener {
-    method @Deprecated public void onFound(android.net.wifi.ScanResult[]);
-    method @Deprecated public void onLost(android.net.wifi.ScanResult[]);
-  }
-
-  public static class WifiScanner.ChannelSpec {
-    ctor public WifiScanner.ChannelSpec(int);
-    field public int frequency;
-  }
-
-  @Deprecated public static class WifiScanner.HotlistSettings implements android.os.Parcelable {
-    ctor @Deprecated public WifiScanner.HotlistSettings();
-    field @Deprecated public int apLostThreshold;
-    field @Deprecated public android.net.wifi.WifiScanner.BssidInfo[] bssidInfos;
-  }
-
-  public static class WifiScanner.ParcelableScanData implements android.os.Parcelable {
-    ctor public WifiScanner.ParcelableScanData(android.net.wifi.WifiScanner.ScanData[]);
-    method public android.net.wifi.WifiScanner.ScanData[] getResults();
-    field public android.net.wifi.WifiScanner.ScanData[] mResults;
-  }
-
-  public static class WifiScanner.ParcelableScanResults implements android.os.Parcelable {
-    ctor public WifiScanner.ParcelableScanResults(android.net.wifi.ScanResult[]);
-    method public android.net.wifi.ScanResult[] getResults();
-    field public android.net.wifi.ScanResult[] mResults;
-  }
-
-  public static class WifiScanner.ScanData implements android.os.Parcelable {
-    ctor public WifiScanner.ScanData(int, int, android.net.wifi.ScanResult[]);
-    ctor public WifiScanner.ScanData(android.net.wifi.WifiScanner.ScanData);
-    method public int getFlags();
-    method public int getId();
-    method public android.net.wifi.ScanResult[] getResults();
-  }
-
-  public static interface WifiScanner.ScanListener extends android.net.wifi.WifiScanner.ActionListener {
-    method public void onFullResult(android.net.wifi.ScanResult);
-    method @Deprecated public void onPeriodChanged(int);
-    method public void onResults(android.net.wifi.WifiScanner.ScanData[]);
-  }
-
-  public static class WifiScanner.ScanSettings implements android.os.Parcelable {
-    ctor public WifiScanner.ScanSettings();
-    field public int band;
-    field public android.net.wifi.WifiScanner.ChannelSpec[] channels;
-    field @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public final java.util.List<android.net.wifi.WifiScanner.ScanSettings.HiddenNetwork> hiddenNetworks;
-    field public boolean hideFromAppOps;
-    field public boolean ignoreLocationSettings;
-    field @Deprecated public int maxPeriodInMs;
-    field @Deprecated public int maxScansToCache;
-    field @Deprecated public int numBssidsPerScan;
-    field @Deprecated public int periodInMs;
-    field @Deprecated public int reportEvents;
-    field @Deprecated public int stepCount;
-    field @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public int type;
-  }
-
-  public static class WifiScanner.ScanSettings.HiddenNetwork {
-    ctor public WifiScanner.ScanSettings.HiddenNetwork(@NonNull String);
-    field @NonNull public final String ssid;
-  }
-
-  @Deprecated public static interface WifiScanner.WifiChangeListener extends android.net.wifi.WifiScanner.ActionListener {
-    method @Deprecated public void onChanging(android.net.wifi.ScanResult[]);
-    method @Deprecated public void onQuiescence(android.net.wifi.ScanResult[]);
-  }
-
-  @Deprecated public static class WifiScanner.WifiChangeSettings implements android.os.Parcelable {
-    ctor @Deprecated public WifiScanner.WifiChangeSettings();
-    field @Deprecated public android.net.wifi.WifiScanner.BssidInfo[] bssidInfos;
-    field @Deprecated public int lostApSampleSize;
-    field @Deprecated public int minApsBreachingThreshold;
-    field @Deprecated public int periodInMs;
-    field @Deprecated public int rssiSampleSize;
-    field @Deprecated public int unchangedSampleSize;
-  }
-
-  public final class WifiUsabilityStatsEntry implements android.os.Parcelable {
-    method public int describeContents();
-    method public int getCellularDataNetworkType();
-    method public int getCellularSignalStrengthDb();
-    method public int getCellularSignalStrengthDbm();
-    method public int getLinkSpeedMbps();
-    method public int getProbeElapsedTimeSinceLastUpdateMillis();
-    method public int getProbeMcsRateSinceLastUpdate();
-    method public int getProbeStatusSinceLastUpdate();
-    method public int getRssi();
-    method public int getRxLinkSpeedMbps();
-    method public long getTimeStampMillis();
-    method public long getTotalBackgroundScanTimeMillis();
-    method public long getTotalBeaconRx();
-    method public long getTotalCcaBusyFreqTimeMillis();
-    method public long getTotalHotspot2ScanTimeMillis();
-    method public long getTotalNanScanTimeMillis();
-    method public long getTotalPnoScanTimeMillis();
-    method public long getTotalRadioOnFreqTimeMillis();
-    method public long getTotalRadioOnTimeMillis();
-    method public long getTotalRadioRxTimeMillis();
-    method public long getTotalRadioTxTimeMillis();
-    method public long getTotalRoamScanTimeMillis();
-    method public long getTotalRxSuccess();
-    method public long getTotalScanTimeMillis();
-    method public long getTotalTxBad();
-    method public long getTotalTxRetries();
-    method public long getTotalTxSuccess();
-    method public boolean isSameRegisteredCell();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.WifiUsabilityStatsEntry> CREATOR;
-    field public static final int PROBE_STATUS_FAILURE = 3; // 0x3
-    field public static final int PROBE_STATUS_NO_PROBE = 1; // 0x1
-    field public static final int PROBE_STATUS_SUCCESS = 2; // 0x2
-    field public static final int PROBE_STATUS_UNKNOWN = 0; // 0x0
-  }
-
-}
-
-package android.net.wifi.aware {
-
-  public class DiscoverySession implements java.lang.AutoCloseable {
-    method @Deprecated public android.net.NetworkSpecifier createNetworkSpecifierPmk(@NonNull android.net.wifi.aware.PeerHandle, @NonNull byte[]);
-  }
-
-  public class WifiAwareSession implements java.lang.AutoCloseable {
-    method public android.net.NetworkSpecifier createNetworkSpecifierPmk(int, @NonNull byte[], @NonNull byte[]);
-  }
-
-}
-
-package android.net.wifi.hotspot2 {
-
-  public final class OsuProvider implements android.os.Parcelable {
-    method public int describeContents();
-    method @Nullable public String getFriendlyName();
-    method @Nullable public android.net.Uri getServerUri();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.OsuProvider> CREATOR;
-  }
-
-  public final class PasspointConfiguration implements android.os.Parcelable {
-    method public int getMeteredOverride();
-    method public boolean isAutojoinEnabled();
-    method public boolean isMacRandomizationEnabled();
-  }
-
-  public abstract class ProvisioningCallback {
-    ctor public ProvisioningCallback();
-    method public abstract void onProvisioningComplete();
-    method public abstract void onProvisioningFailure(int);
-    method public abstract void onProvisioningStatus(int);
-    field public static final int OSU_FAILURE_ADD_PASSPOINT_CONFIGURATION = 22; // 0x16
-    field public static final int OSU_FAILURE_AP_CONNECTION = 1; // 0x1
-    field public static final int OSU_FAILURE_INVALID_URL_FORMAT_FOR_OSU = 8; // 0x8
-    field public static final int OSU_FAILURE_NO_AAA_SERVER_TRUST_ROOT_NODE = 17; // 0x11
-    field public static final int OSU_FAILURE_NO_AAA_TRUST_ROOT_CERTIFICATE = 21; // 0x15
-    field public static final int OSU_FAILURE_NO_OSU_ACTIVITY_FOUND = 14; // 0xe
-    field public static final int OSU_FAILURE_NO_POLICY_SERVER_TRUST_ROOT_NODE = 19; // 0x13
-    field public static final int OSU_FAILURE_NO_PPS_MO = 16; // 0x10
-    field public static final int OSU_FAILURE_NO_REMEDIATION_SERVER_TRUST_ROOT_NODE = 18; // 0x12
-    field public static final int OSU_FAILURE_OSU_PROVIDER_NOT_FOUND = 23; // 0x17
-    field public static final int OSU_FAILURE_PROVISIONING_ABORTED = 6; // 0x6
-    field public static final int OSU_FAILURE_PROVISIONING_NOT_AVAILABLE = 7; // 0x7
-    field public static final int OSU_FAILURE_RETRIEVE_TRUST_ROOT_CERTIFICATES = 20; // 0x14
-    field public static final int OSU_FAILURE_SERVER_CONNECTION = 3; // 0x3
-    field public static final int OSU_FAILURE_SERVER_URL_INVALID = 2; // 0x2
-    field public static final int OSU_FAILURE_SERVER_VALIDATION = 4; // 0x4
-    field public static final int OSU_FAILURE_SERVICE_PROVIDER_VERIFICATION = 5; // 0x5
-    field public static final int OSU_FAILURE_SOAP_MESSAGE_EXCHANGE = 11; // 0xb
-    field public static final int OSU_FAILURE_START_REDIRECT_LISTENER = 12; // 0xc
-    field public static final int OSU_FAILURE_TIMED_OUT_REDIRECT_LISTENER = 13; // 0xd
-    field public static final int OSU_FAILURE_UNEXPECTED_COMMAND_TYPE = 9; // 0x9
-    field public static final int OSU_FAILURE_UNEXPECTED_SOAP_MESSAGE_STATUS = 15; // 0xf
-    field public static final int OSU_FAILURE_UNEXPECTED_SOAP_MESSAGE_TYPE = 10; // 0xa
-    field public static final int OSU_STATUS_AP_CONNECTED = 2; // 0x2
-    field public static final int OSU_STATUS_AP_CONNECTING = 1; // 0x1
-    field public static final int OSU_STATUS_INIT_SOAP_EXCHANGE = 6; // 0x6
-    field public static final int OSU_STATUS_REDIRECT_RESPONSE_RECEIVED = 8; // 0x8
-    field public static final int OSU_STATUS_RETRIEVING_TRUST_ROOT_CERTS = 11; // 0xb
-    field public static final int OSU_STATUS_SECOND_SOAP_EXCHANGE = 9; // 0x9
-    field public static final int OSU_STATUS_SERVER_CONNECTED = 5; // 0x5
-    field public static final int OSU_STATUS_SERVER_CONNECTING = 3; // 0x3
-    field public static final int OSU_STATUS_SERVER_VALIDATED = 4; // 0x4
-    field public static final int OSU_STATUS_THIRD_SOAP_EXCHANGE = 10; // 0xa
-    field public static final int OSU_STATUS_WAITING_FOR_REDIRECT_RESPONSE = 7; // 0x7
-  }
-
-}
-
-package android.net.wifi.p2p {
-
-  public final class WifiP2pGroupList implements android.os.Parcelable {
-    method public int describeContents();
-    method @NonNull public java.util.List<android.net.wifi.p2p.WifiP2pGroup> getGroupList();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.p2p.WifiP2pGroupList> CREATOR;
-  }
-
-  public class WifiP2pManager {
-    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.OVERRIDE_WIFI_CONFIG}) public void deletePersistentGroup(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, int, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener);
-    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void factoryReset(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener);
-    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.READ_WIFI_CREDENTIAL}) public void requestPersistentGroupInfo(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @Nullable android.net.wifi.p2p.WifiP2pManager.PersistentGroupInfoListener);
-    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.OVERRIDE_WIFI_CONFIG}) public void setDeviceName(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @NonNull String, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener);
-    method @RequiresPermission(android.Manifest.permission.CONFIGURE_WIFI_DISPLAY) public void setMiracastMode(int);
-    method @RequiresPermission(android.Manifest.permission.CONFIGURE_WIFI_DISPLAY) public void setWfdInfo(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @NonNull android.net.wifi.p2p.WifiP2pWfdInfo, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener);
-    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.OVERRIDE_WIFI_CONFIG}) public void setWifiP2pChannels(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, int, int, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener);
-    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void startListening(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener);
-    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void stopListening(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener);
-    field public static final String ACTION_WIFI_P2P_PERSISTENT_GROUPS_CHANGED = "android.net.wifi.p2p.action.WIFI_P2P_PERSISTENT_GROUPS_CHANGED";
-    field public static final int MIRACAST_DISABLED = 0; // 0x0
-    field public static final int MIRACAST_SINK = 2; // 0x2
-    field public static final int MIRACAST_SOURCE = 1; // 0x1
-  }
-
-  public static interface WifiP2pManager.PersistentGroupInfoListener {
-    method public void onPersistentGroupInfoAvailable(@NonNull android.net.wifi.p2p.WifiP2pGroupList);
-  }
-
-}
-
-package android.net.wifi.rtt {
-
-  public static final class RangingRequest.Builder {
-    method public android.net.wifi.rtt.RangingRequest.Builder addResponder(@NonNull android.net.wifi.rtt.ResponderConfig);
-  }
-
-  public final class RangingResult implements android.os.Parcelable {
-    method @NonNull public byte[] getLci();
-    method @NonNull public byte[] getLcr();
-  }
-
-  public final class ResponderConfig implements android.os.Parcelable {
-    ctor public ResponderConfig(@NonNull android.net.MacAddress, int, boolean, int, int, int, int, int);
-    ctor public ResponderConfig(@NonNull android.net.wifi.aware.PeerHandle, int, boolean, int, int, int, int, int);
-    method public int describeContents();
-    method public static android.net.wifi.rtt.ResponderConfig fromScanResult(android.net.wifi.ScanResult);
-    method public static android.net.wifi.rtt.ResponderConfig fromWifiAwarePeerHandleWithDefaults(android.net.wifi.aware.PeerHandle);
-    method public static android.net.wifi.rtt.ResponderConfig fromWifiAwarePeerMacAddressWithDefaults(android.net.MacAddress);
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final int CHANNEL_WIDTH_160MHZ = 3; // 0x3
-    field public static final int CHANNEL_WIDTH_20MHZ = 0; // 0x0
-    field public static final int CHANNEL_WIDTH_40MHZ = 1; // 0x1
-    field public static final int CHANNEL_WIDTH_80MHZ = 2; // 0x2
-    field public static final int CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 4; // 0x4
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.rtt.ResponderConfig> CREATOR;
-    field public static final int PREAMBLE_HE = 3; // 0x3
-    field public static final int PREAMBLE_HT = 1; // 0x1
-    field public static final int PREAMBLE_LEGACY = 0; // 0x0
-    field public static final int PREAMBLE_VHT = 2; // 0x2
-    field public static final int RESPONDER_AP = 0; // 0x0
-    field public static final int RESPONDER_AWARE = 4; // 0x4
-    field public static final int RESPONDER_P2P_CLIENT = 3; // 0x3
-    field public static final int RESPONDER_P2P_GO = 2; // 0x2
-    field public static final int RESPONDER_STA = 1; // 0x1
-    field public final int centerFreq0;
-    field public final int centerFreq1;
-    field public final int channelWidth;
-    field public final int frequency;
-    field public final android.net.MacAddress macAddress;
-    field public final android.net.wifi.aware.PeerHandle peerHandle;
-    field public final int preamble;
-    field public final int responderType;
-    field public final boolean supports80211mc;
-  }
-
-  public final class ResponderLocation implements android.os.Parcelable {
-    method public boolean getExtraInfoOnAssociationIndication();
-  }
-
-  public class WifiRttManager {
-    method @RequiresPermission(allOf={android.Manifest.permission.LOCATION_HARDWARE}) public void cancelRanging(@Nullable android.os.WorkSource);
-    method @RequiresPermission(allOf={android.Manifest.permission.LOCATION_HARDWARE, android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.CHANGE_WIFI_STATE, android.Manifest.permission.ACCESS_WIFI_STATE}) public void startRanging(@Nullable android.os.WorkSource, @NonNull android.net.wifi.rtt.RangingRequest, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.rtt.RangingResultCallback);
-  }
-
-}
-
diff --git a/wifi/api/system-lint-baseline.txt b/wifi/api/system-lint-baseline.txt
deleted file mode 100644
index 6547ee8..0000000
--- a/wifi/api/system-lint-baseline.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-// Baseline format: 1.0
-MissingGetterMatchingBuilder: android.net.wifi.rtt.RangingRequest.Builder#addResponder(android.net.wifi.rtt.ResponderConfig):
-    android.net.wifi.rtt.RangingRequest does not declare a `getResponders()` method matching method android.net.wifi.rtt.RangingRequest.Builder.addResponder(android.net.wifi.rtt.ResponderConfig)
-
-MissingNullability: android.net.wifi.rtt.RangingRequest.Builder#addResponder(android.net.wifi.rtt.ResponderConfig):
-
diff --git a/wifi/api/system-removed.txt b/wifi/api/system-removed.txt
deleted file mode 100644
index a2d0dff..0000000
--- a/wifi/api/system-removed.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-// Signature format: 2.0
-package android.net.wifi {
-
-  @Deprecated public class BatchedScanResult implements android.os.Parcelable {
-    ctor public BatchedScanResult();
-    ctor public BatchedScanResult(android.net.wifi.BatchedScanResult);
-    field public final java.util.List<android.net.wifi.ScanResult> scanResults;
-    field public boolean truncated;
-  }
-
-  public final class ScanResult implements android.os.Parcelable {
-    field public boolean untrusted;
-  }
-
-}
-
diff --git a/wifi/jarjar-rules.txt b/wifi/jarjar-rules.txt
deleted file mode 100644
index 0568696..0000000
--- a/wifi/jarjar-rules.txt
+++ /dev/null
@@ -1,124 +0,0 @@
-## used by service-wifi ##
-
-# Network Stack AIDL interface.
-rule android.net.DataStallReportParcelable* com.android.wifi.x.@0
-rule android.net.DhcpResultsParcelable* com.android.wifi.x.@0
-rule android.net.IIpMemoryStore* com.android.wifi.x.@0
-rule android.net.IIpMemoryStoreCallbacks* com.android.wifi.x.@0
-rule android.net.INetd* com.android.wifi.x.@0
-rule android.net.INetdUnsolicitedEventListener* com.android.wifi.x.@0
-rule android.net.INetworkStackConnector* com.android.wifi.x.@0
-rule android.net.InformationElementParcelable* com.android.wifi.x.@0
-rule android.net.InitialConfigurationParcelable* com.android.wifi.x.@0
-rule android.net.InterfaceConfigurationParcel* com.android.wifi.x.@0
-rule android.net.Layer2InformationParcelable* com.android.wifi.x.@0
-rule android.net.Layer2PacketParcelable* com.android.wifi.x.@0
-rule android.net.MarkMaskParcel* com.android.wifi.x.@0
-rule android.net.NattKeepalivePacketDataParcelable* com.android.wifi.x.@0
-rule android.net.NetworkTestResultParcelable* com.android.wifi.x.@0
-rule android.net.PrivateDnsConfigParcel* com.android.wifi.x.@0
-rule android.net.ProvisioningConfigurationParcelable* com.android.wifi.x.@0
-rule android.net.ResolverParamsParcel* com.android.wifi.x.@0
-rule android.net.RouteInfoParcel* com.android.wifi.x.@0
-rule android.net.ScanResultInfoParcelable* com.android.wifi.x.@0
-rule android.net.TetherConfigParcel* com.android.wifi.x.@0
-rule android.net.TetherOffloadRuleParcel* com.android.wifi.x.@0
-rule android.net.TetherStatsParcel* com.android.wifi.x.@0
-rule android.net.UidRangeParcel* com.android.wifi.x.@0
-rule android.net.dhcp.DhcpLeaseParcelable* com.android.wifi.x.@0
-rule android.net.dhcp.DhcpServingParamsParcel* com.android.wifi.x.@0
-rule android.net.ip.IIpClient* com.android.wifi.x.@0
-rule android.net.ip.IIpClientCallbacks* com.android.wifi.x.@0
-rule android.net.ipmemorystore.Blob* com.android.wifi.x.@0
-rule android.net.ipmemorystore.IOnBlobRetrievedListener* com.android.wifi.x.@0
-rule android.net.ipmemorystore.IOnStatusAndCountListener* com.android.wifi.x.@0
-rule android.net.ipmemorystore.IOnStatusListener* com.android.wifi.x.@0
-rule android.net.ipmemorystore.NetworkAttributesParcelable* com.android.wifi.x.@0
-rule android.net.ipmemorystore.SameL3NetworkResponseParcelable* com.android.wifi.x.@0
-rule android.net.ipmemorystore.StatusParcelable* com.android.wifi.x.@0
-
-# Net utils (includes Network Stack helper classes).
-rule android.net.DhcpResults* com.android.wifi.x.@0
-rule android.net.InterfaceConfiguration* com.android.wifi.x.@0
-rule android.net.IpMemoryStore* com.android.wifi.x.@0
-rule android.net.NetworkMonitorManager* com.android.wifi.x.@0
-rule android.net.TcpKeepalivePacketData* com.android.wifi.x.@0
-rule android.net.NetworkFactory* com.android.wifi.x.@0
-rule android.net.ip.IpClientCallbacks* com.android.wifi.x.@0
-rule android.net.ip.IpClientManager* com.android.wifi.x.@0
-rule android.net.ip.IpClientUtil* com.android.wifi.x.@0
-rule android.net.ipmemorystore.NetworkAttributes* com.android.wifi.x.@0
-rule android.net.ipmemorystore.OnBlobRetrievedListener* com.android.wifi.x.@0
-rule android.net.ipmemorystore.OnDeleteStatusListener* com.android.wifi.x.@0
-rule android.net.ipmemorystore.OnStatusListener* com.android.wifi.x.@0
-rule android.net.ipmemorystore.Status* com.android.wifi.x.@0
-rule android.net.networkstack.ModuleNetworkStackClient* com.android.wifi.x.@0
-rule android.net.networkstack.NetworkStackClientBase* com.android.wifi.x.@0
-rule android.net.shared.InetAddressUtils* com.android.wifi.x.@0
-rule android.net.shared.InitialConfiguration* com.android.wifi.x.@0
-rule android.net.shared.IpConfigurationParcelableUtil* com.android.wifi.x.@0
-rule android.net.shared.Layer2Information* com.android.wifi.x.@0
-rule android.net.shared.LinkPropertiesParcelableUtil* com.android.wifi.x.@0
-rule android.net.shared.NetdUtils* com.android.wifi.x.@0
-rule android.net.shared.NetworkMonitorUtils* com.android.wifi.x.@0
-rule android.net.shared.ParcelableUtil* com.android.wifi.x.@0
-rule android.net.shared.PrivateDnsConfig* com.android.wifi.x.@0
-rule android.net.shared.ProvisioningConfiguration* com.android.wifi.x.@0
-rule android.net.shared.RouteUtils* com.android.wifi.x.@0
-rule android.net.util.KeepalivePacketDataUtil* com.android.wifi.x.@0
-rule android.net.util.NetworkConstants* com.android.wifi.x.@0
-rule android.net.util.InterfaceParams* com.android.wifi.x.@0
-rule android.net.util.SharedLog* com.android.wifi.x.@0
-rule android.net.util.NetUtils* com.android.wifi.x.@0
-rule android.net.util.IpUtils* com.android.wifi.x.@0
-
-rule androidx.annotation.** com.android.wifi.x.@0
-
-# We don't jar-jar the entire package because, we still use some classes (like
-# AsyncChannel in com.android.internal.util) from these packages which are not
-# inside our jar (currently in framework.jar, but will be in wifisdk.jar in the future).
-rule com.android.internal.util.FastXmlSerializer* com.android.wifi.x.@0
-rule com.android.internal.util.HexDump* com.android.wifi.x.@0
-rule com.android.internal.util.IState* com.android.wifi.x.@0
-rule com.android.internal.util.MessageUtils* com.android.wifi.x.@0
-rule com.android.internal.util.State* com.android.wifi.x.@0
-rule com.android.internal.util.StateMachine* com.android.wifi.x.@0
-rule com.android.internal.util.WakeupMessage* com.android.wifi.x.@0
-
-rule android.util.BackupUtils* com.android.wifi.x.@0
-rule android.util.LocalLog* com.android.wifi.x.@0
-rule android.util.Rational* com.android.wifi.x.@0
-
-rule android.os.BasicShellCommandHandler* com.android.wifi.x.@0
-
-# Use our statically linked bouncy castle library
-rule org.bouncycastle.** com.android.wifi.x.@0
-# Use our statically linked protobuf library
-rule com.google.protobuf.** com.android.wifi.x.@0
-# use statically linked SystemMessageProto
-rule com.android.internal.messages.SystemMessageProto* com.android.wifi.x.@0
-# Use our statically linked PlatformProperties library
-rule android.sysprop.** com.android.wifi.x.@0
-# Use our statically linked HIDL stubs
-# Note: android.hardware.wifi.** is used by various wifi feature flags. This unfortunately is also the namespace
-# used by vendor HAL stubs. So, this rule is intentionally weird to try and filter the vendor HAL stubs only.
-rule android.hardware.wifi.V** com.android.wifi.x.@0
-rule android.hardware.wifi.supplicant.** com.android.wifi.x.@0
-rule android.hardware.wifi.hostapd.** com.android.wifi.x.@0
-rule android.hidl.** com.android.wifi.x.@0
-# Use our statically linked ksoap2
-rule org.ksoap2.** com.android.wifi.x.@0
-# Use our statically linked nanohttpd
-rule fi.iki.elonen.** com.android.wifi.x.@0
-
-## used by both framework-wifi and service-wifi ##
-rule android.content.pm.BaseParceledListSlice* com.android.wifi.x.@0
-rule android.content.pm.ParceledListSlice* com.android.wifi.x.@0
-rule android.os.HandlerExecutor* com.android.wifi.x.@0
-rule android.telephony.Annotation* com.android.wifi.x.@0
-rule com.android.internal.util.AsyncChannel* com.android.wifi.x.@0
-rule com.android.internal.util.AsyncService* com.android.wifi.x.@0
-rule com.android.internal.util.Preconditions* com.android.wifi.x.@0
-rule com.android.internal.util.Protocol* com.android.wifi.x.@0
-
-rule com.android.net.module.util.** com.android.wifi.x.@0
diff --git a/wifi/non-updatable/java/Android.bp b/wifi/java/Android.bp
similarity index 100%
rename from wifi/non-updatable/java/Android.bp
rename to wifi/java/Android.bp
diff --git a/wifi/java/android/net/wifi/AnqpInformationElement.java b/wifi/java/android/net/wifi/AnqpInformationElement.java
deleted file mode 100644
index 47b7129..0000000
--- a/wifi/java/android/net/wifi/AnqpInformationElement.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-/**
- * This object contains the payload of an ANQP element.
- * Vendor id is the vendor ID for the element, or 0 if it is an 802.11(u) element.
- * Hotspot 2.0 uses the WFA Vendor ID which is 0x506f9a
- * The payload contains the bytes of the payload, starting after the length octet(s).
- * @hide
- */
-public class AnqpInformationElement {
-    public static final int HOTSPOT20_VENDOR_ID = 0x506f9a;
-
-    public static final int ANQP_QUERY_LIST = 256;
-    public static final int ANQP_CAPABILITY_LIST = 257;
-    public static final int ANQP_VENUE_NAME = 258;
-    public static final int ANQP_EMERGENCY_NUMBER = 259;
-    public static final int ANQP_NWK_AUTH_TYPE = 260;
-    public static final int ANQP_ROAMING_CONSORTIUM = 261;
-    public static final int ANQP_IP_ADDR_AVAILABILITY = 262;
-    public static final int ANQP_NAI_REALM = 263;
-    public static final int ANQP_3GPP_NETWORK = 264;
-    public static final int ANQP_GEO_LOC = 265;
-    public static final int ANQP_CIVIC_LOC = 266;
-    public static final int ANQP_LOC_URI = 267;
-    public static final int ANQP_DOM_NAME = 268;
-    public static final int ANQP_EMERGENCY_ALERT = 269;
-    public static final int ANQP_TDLS_CAP = 270;
-    public static final int ANQP_EMERGENCY_NAI = 271;
-    public static final int ANQP_NEIGHBOR_REPORT = 272;
-    public static final int ANQP_VENDOR_SPEC = 56797;
-
-    public static final int HS_QUERY_LIST = 1;
-    public static final int HS_CAPABILITY_LIST = 2;
-    public static final int HS_FRIENDLY_NAME = 3;
-    public static final int HS_WAN_METRICS = 4;
-    public static final int HS_CONN_CAPABILITY = 5;
-    public static final int HS_NAI_HOME_REALM_QUERY = 6;
-    public static final int HS_OPERATING_CLASS = 7;
-    public static final int HS_OSU_PROVIDERS = 8;
-    public static final int HS_ICON_REQUEST = 10;
-    public static final int HS_ICON_FILE = 11;
-
-    private final int mVendorId;
-    private final int mElementId;
-    private final byte[] mPayload;
-
-    public AnqpInformationElement(int vendorId, int elementId, byte[] payload) {
-        mVendorId = vendorId;
-        mElementId = elementId;
-        mPayload = payload;
-    }
-
-    public int getVendorId() {
-        return mVendorId;
-    }
-
-    public int getElementId() {
-        return mElementId;
-    }
-
-    public byte[] getPayload() {
-        return mPayload;
-    }
-}
diff --git a/wifi/java/android/net/wifi/BatchedScanResult.java b/wifi/java/android/net/wifi/BatchedScanResult.java
deleted file mode 100644
index ed8845dd..0000000
--- a/wifi/java/android/net/wifi/BatchedScanResult.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import android.os.Parcelable;
-import android.annotation.SystemApi;
-import android.os.Parcel;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Describes the Results of a batched set of wifi scans where the firmware performs many
- * scans and stores the timestamped results without waking the main processor each time.
- * @hide
- * @removed
- */
-@Deprecated
-@SystemApi
-public class BatchedScanResult implements Parcelable {
-    private static final String TAG = "BatchedScanResult";
-
-    /** Inidcates this scan was interrupted and may only have partial results. */
-    public boolean truncated;
-
-    /** The result of this particular scan. */
-    public final List<ScanResult> scanResults = new ArrayList<ScanResult>();
-
-
-    public BatchedScanResult() {
-    }
-
-    public BatchedScanResult(BatchedScanResult source) {
-        truncated = source.truncated;
-        for (ScanResult s : source.scanResults) scanResults.add(new ScanResult(s));
-    }
-
-    @Override
-    public String toString() {
-        StringBuffer sb = new StringBuffer();
-
-        sb.append("BatchedScanResult: ").
-                append("truncated: ").append(String.valueOf(truncated)).
-                append("scanResults: [");
-        for (ScanResult s : scanResults) {
-            sb.append(" <").append(s.toString()).append("> ");
-        }
-        sb.append(" ]");
-        return sb.toString();
-    }
-
-    /** Implement the Parcelable interface {@hide} */
-    public int describeContents() {
-        return 0;
-    }
-
-    /** Implement the Parcelable interface {@hide} */
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(truncated ? 1 : 0);
-        dest.writeInt(scanResults.size());
-        for (ScanResult s : scanResults) {
-            s.writeToParcel(dest, flags);
-        }
-    }
-
-    /** Implement the Parcelable interface {@hide} */
-    public static final @android.annotation.NonNull Creator<BatchedScanResult> CREATOR =
-        new Creator<BatchedScanResult>() {
-            public BatchedScanResult createFromParcel(Parcel in) {
-                BatchedScanResult result = new BatchedScanResult();
-                result.truncated = (in.readInt() == 1);
-                int count = in.readInt();
-                while (count-- > 0) {
-                    result.scanResults.add(ScanResult.CREATOR.createFromParcel(in));
-                }
-                return result;
-            }
-
-            public BatchedScanResult[] newArray(int size) {
-                return new BatchedScanResult[size];
-            }
-        };
-}
diff --git a/wifi/java/android/net/wifi/EAPConstants.java b/wifi/java/android/net/wifi/EAPConstants.java
deleted file mode 100644
index b5f7c94..0000000
--- a/wifi/java/android/net/wifi/EAPConstants.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- * Copyright (c) 2016, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-/**
- * Utility class containing EAP (Extensible Authentication Protocol) Related constants.
- *
- * @hide
- */
-public final class EAPConstants {
-    // Constant definition for EAP types. Refer to
-    // http://www.iana.org/assignments/eap-numbers/eap-numbers.xhtml for more info.
-    public static final int EAP_MD5 = 4;
-    public static final int EAP_OTP = 5;
-    public static final int EAP_RSA = 9;
-    public static final int EAP_KEA = 11;
-    public static final int EAP_KEA_VALIDATE = 12;
-    public static final int EAP_TLS = 13;
-    public static final int EAP_LEAP = 17;
-    public static final int EAP_SIM = 18;
-    public static final int EAP_TTLS = 21;
-    public static final int EAP_AKA = 23;
-    public static final int EAP_3Com = 24;
-    public static final int EAP_MSCHAPv2 = 26;
-    public static final int EAP_PEAP = 29;
-    public static final int EAP_POTP = 32;
-    public static final int EAP_ActiontecWireless = 35;
-    public static final int EAP_HTTPDigest = 38;
-    public static final int EAP_SPEKE = 41;
-    public static final int EAP_MOBAC = 42;
-    public static final int EAP_FAST = 43;
-    public static final int EAP_ZLXEAP = 44;
-    public static final int EAP_Link = 45;
-    public static final int EAP_PAX = 46;
-    public static final int EAP_PSK = 47;
-    public static final int EAP_SAKE = 48;
-    public static final int EAP_IKEv2 = 49;
-    public static final int EAP_AKA_PRIME = 50;
-    public static final int EAP_GPSK = 51;
-    public static final int EAP_PWD = 52;
-    public static final int EAP_EKE = 53;
-    public static final int EAP_TEAP = 55;
-}
diff --git a/wifi/java/android/net/wifi/EasyConnectStatusCallback.java b/wifi/java/android/net/wifi/EasyConnectStatusCallback.java
deleted file mode 100644
index 6c2e6dd..0000000
--- a/wifi/java/android/net/wifi/EasyConnectStatusCallback.java
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.util.SparseArray;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.concurrent.Executor;
-
-/**
- * Easy Connect (DPP) Status Callback. Use this callback to get status updates (success, failure,
- * progress) from the Easy Connect operations.
- */
-public abstract class EasyConnectStatusCallback {
-    /**
-     * Easy Connect R1 Success event: Configuration sent (Configurator mode). This is the last
-     * and final Easy Connect event when either the local device or remote device implement R1.
-     * If both devices implement R2, this event will never be received, and the
-     * {@link #EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_APPLIED} will be received.
-     * @hide
-     */
-    @SystemApi
-    public static final int EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_SENT = 0;
-
-    /**
-     * Easy Connect R2 Success event: Configuration applied by Enrollee (Configurator mode).
-     * This is the last and final Easy Connect event when both the local device and remote device
-     * implement R2. If either the local device or remote device implement R1, this event will never
-     * be received, and the {@link #EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_SENT} will be received.
-     * @hide
-     */
-    @SystemApi
-    public static final int EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_APPLIED = 1;
-
-    /** @hide */
-    @IntDef(prefix = {"EASY_CONNECT_EVENT_SUCCESS_"}, value = {
-            EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_SENT,
-            EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_APPLIED,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface EasyConnectSuccessStatusCode {
-    }
-
-    /**
-     * Easy Connect Progress event: Initial authentication with peer succeeded.
-     * @hide
-     */
-    @SystemApi
-    public static final int EASY_CONNECT_EVENT_PROGRESS_AUTHENTICATION_SUCCESS = 0;
-
-    /**
-     * Easy Connect Progress event: Peer requires more time to process bootstrapping.
-     * @hide
-     */
-    @SystemApi
-    public static final int EASY_CONNECT_EVENT_PROGRESS_RESPONSE_PENDING = 1;
-
-    /**
-     * Easy Connect R2 Progress event: Configuration sent to Enrollee, waiting for response
-     * @hide
-     */
-    @SystemApi
-    public static final int EASY_CONNECT_EVENT_PROGRESS_CONFIGURATION_SENT_WAITING_RESPONSE = 2;
-
-    /**
-     * Easy Connect R2 Progress event: Configuration accepted by Enrollee, waiting for response
-     * @hide
-     */
-    @SystemApi
-    public static final int EASY_CONNECT_EVENT_PROGRESS_CONFIGURATION_ACCEPTED = 3;
-
-    /** @hide */
-    @IntDef(prefix = {"EASY_CONNECT_EVENT_PROGRESS_"}, value = {
-            EASY_CONNECT_EVENT_PROGRESS_AUTHENTICATION_SUCCESS,
-            EASY_CONNECT_EVENT_PROGRESS_RESPONSE_PENDING,
-            EASY_CONNECT_EVENT_PROGRESS_CONFIGURATION_SENT_WAITING_RESPONSE,
-            EASY_CONNECT_EVENT_PROGRESS_CONFIGURATION_ACCEPTED,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface EasyConnectProgressStatusCode {
-    }
-
-    /**
-     * Easy Connect Failure event: Scanned QR code is either not a Easy Connect URI, or the Easy
-     * Connect URI has errors.
-     */
-    public static final int EASY_CONNECT_EVENT_FAILURE_INVALID_URI = -1;
-
-    /**
-     * Easy Connect Failure event: Bootstrapping/Authentication initialization process failure.
-     */
-    public static final int EASY_CONNECT_EVENT_FAILURE_AUTHENTICATION = -2;
-
-    /**
-     * Easy Connect Failure event: Both devices are implementing the same role and are incompatible.
-     */
-    public static final int EASY_CONNECT_EVENT_FAILURE_NOT_COMPATIBLE = -3;
-
-    /**
-     * Easy Connect Failure event: Configuration process has failed due to malformed message.
-     */
-    public static final int EASY_CONNECT_EVENT_FAILURE_CONFIGURATION = -4;
-
-    /**
-     * Easy Connect Failure event: Easy Connect request while in another Easy Connect exchange.
-     */
-    public static final int EASY_CONNECT_EVENT_FAILURE_BUSY = -5;
-
-    /**
-     * Easy Connect Failure event: No response from the peer.
-     */
-    public static final int EASY_CONNECT_EVENT_FAILURE_TIMEOUT = -6;
-
-    /**
-     * Easy Connect Failure event: General protocol failure.
-     */
-    public static final int EASY_CONNECT_EVENT_FAILURE_GENERIC = -7;
-
-    /**
-     * Easy Connect Failure event: Feature or option is not supported.
-     */
-    public static final int EASY_CONNECT_EVENT_FAILURE_NOT_SUPPORTED = -8;
-
-    /**
-     * Easy Connect Failure event: Invalid network provided to Easy Connect configurator.
-     * Network must either be WPA3-Personal (SAE) or WPA2-Personal (PSK).
-     */
-    public static final int EASY_CONNECT_EVENT_FAILURE_INVALID_NETWORK = -9;
-
-    /**
-     * Easy Connect R2 Failure event: Enrollee cannot find the network.
-     */
-    public static final int EASY_CONNECT_EVENT_FAILURE_CANNOT_FIND_NETWORK = -10;
-
-    /**
-     * Easy Connect R2 Failure event: Enrollee failed to authenticate with the network.
-     */
-    public static final int EASY_CONNECT_EVENT_FAILURE_ENROLLEE_AUTHENTICATION = -11;
-
-    /**
-     * Easy Connect R2 Failure event: Enrollee rejected the configuration.
-     */
-    public static final int EASY_CONNECT_EVENT_FAILURE_ENROLLEE_REJECTED_CONFIGURATION = -12;
-
-    /** @hide */
-    @IntDef(prefix = {"EASY_CONNECT_EVENT_FAILURE_"}, value = {
-            EASY_CONNECT_EVENT_FAILURE_INVALID_URI,
-            EASY_CONNECT_EVENT_FAILURE_AUTHENTICATION,
-            EASY_CONNECT_EVENT_FAILURE_NOT_COMPATIBLE,
-            EASY_CONNECT_EVENT_FAILURE_CONFIGURATION,
-            EASY_CONNECT_EVENT_FAILURE_BUSY,
-            EASY_CONNECT_EVENT_FAILURE_TIMEOUT,
-            EASY_CONNECT_EVENT_FAILURE_GENERIC,
-            EASY_CONNECT_EVENT_FAILURE_NOT_SUPPORTED,
-            EASY_CONNECT_EVENT_FAILURE_INVALID_NETWORK,
-            EASY_CONNECT_EVENT_FAILURE_CANNOT_FIND_NETWORK,
-            EASY_CONNECT_EVENT_FAILURE_ENROLLEE_AUTHENTICATION,
-            EASY_CONNECT_EVENT_FAILURE_ENROLLEE_REJECTED_CONFIGURATION,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface EasyConnectFailureStatusCode {
-    }
-
-    /** @hide */
-    @SystemApi
-    public EasyConnectStatusCallback() {
-        // Fully-static utility classes must not have constructor
-    }
-
-    /**
-     * Called when local Easy Connect Enrollee successfully receives a new Wi-Fi configuration from
-     * the
-     * peer Easy Connect configurator. This callback marks the successful end of the Easy Connect
-     * current Easy Connect
-     * session, and no further callbacks will be called. This callback is the successful outcome
-     * of a Easy Connect flow starting with
-     * {@link WifiManager#startEasyConnectAsEnrolleeInitiator(String, Executor,
-     * EasyConnectStatusCallback)} .
-     *
-     * @param newNetworkId New Wi-Fi configuration with a network ID received from the configurator
-     * @hide
-     */
-    @SystemApi
-    public abstract void onEnrolleeSuccess(int newNetworkId);
-
-    /**
-     * Called when a Easy Connect success event takes place, except for when configuration is
-     * received from an external Configurator. The callback onSuccessConfigReceived will be used in
-     * this case. This callback marks the successful end of the current Easy Connect session, and no
-     * further callbacks will be called. This callback is the successful outcome of a Easy Connect
-     * flow starting with {@link WifiManager#startEasyConnectAsConfiguratorInitiator(String, int,
-     * int, Executor,EasyConnectStatusCallback)}.
-     *
-     * @param code Easy Connect success status code.
-     * @hide
-     */
-    @SystemApi
-    public abstract void onConfiguratorSuccess(@EasyConnectSuccessStatusCode int code);
-
-    /**
-     * Called when a Easy Connect Failure event takes place. This callback marks the unsuccessful
-     * end of the current Easy Connect session, and no further callbacks will be called.
-     *
-     * @param code Easy Connect failure status code.
-     * @hide
-     */
-    @SystemApi
-    public void onFailure(@EasyConnectFailureStatusCode int code) {}
-
-    /**
-     * Called when a Easy Connect Failure event takes place. This callback marks the unsuccessful
-     * end of the current Easy Connect session, and no further callbacks will be called.
-     *
-     * Note: Easy Connect (DPP) R2, provides additional details for the Configurator when the
-     * remote Enrollee is unable to connect to a network. The ssid, channelList and bandList
-     * inputs are initialized only for the EASY_CONNECT_EVENT_FAILURE_CANNOT_FIND_NETWORK failure
-     * code, and the ssid and bandList are initialized for the
-     * EASY_CONNECT_EVENT_FAILURE_ENROLLEE_AUTHENTICATION failure code.
-     *
-     * @param code Easy Connect failure status code.
-     * @param ssid SSID of the network the Enrollee tried to connect to.
-     * @param channelListArray List of Global Operating classes and channel sets the Enrollee used
-     *                         to scan to find the network, see the "DPP Connection Status Object"
-     *                         section in the specification for the format, and Table E-4 in
-     *                         IEEE Std 802.11-2016 - Global operating classes for more details.
-     *                         The sparse array key is the Global Operating class, and the value
-     *                         is an integer array of Wi-Fi channels.
-     * @param operatingClassArray Array of bands the Enrollee supports as expressed as the Global
-     *                            Operating Class, see Table E-4 in IEEE Std 802.11-2016 - Global
-     *                            operating classes.
-     * @hide
-     */
-    @SystemApi
-    public void onFailure(@EasyConnectFailureStatusCode int code, @Nullable String ssid,
-            @NonNull SparseArray<int[]> channelListArray, @NonNull int[] operatingClassArray) {
-        onFailure(code);
-    }
-
-    /**
-     * Called when Easy Connect events that indicate progress take place. Can be used by UI elements
-     * to show progress.
-     *
-     * @param code Easy Connect progress status code.
-     * @hide
-     */
-    @SystemApi
-    public abstract void onProgress(@EasyConnectProgressStatusCode int code);
-}
diff --git a/wifi/java/android/net/wifi/IActionListener.aidl b/wifi/java/android/net/wifi/IActionListener.aidl
deleted file mode 100644
index faa0901..0000000
--- a/wifi/java/android/net/wifi/IActionListener.aidl
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-/**
- * Interface for generic wifi callbacks.
- * @hide
- */
-oneway interface IActionListener
-{
-    void onSuccess();
-    void onFailure(int reason);
-}
diff --git a/wifi/java/android/net/wifi/IDppCallback.aidl b/wifi/java/android/net/wifi/IDppCallback.aidl
deleted file mode 100644
index d7a958a..0000000
--- a/wifi/java/android/net/wifi/IDppCallback.aidl
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-/**
- * Interface for DPP callback.
- *
- * @hide
- */
-oneway interface IDppCallback
-{
-    /**
-     * Called when local DPP Enrollee successfully receives a new Wi-Fi configuratrion from the
-     * peer DPP configurator.
-     */
-    void onSuccessConfigReceived(int newNetworkId);
-
-    /**
-     * Called when DPP success events take place, except for when configuration is received from
-     * an external Configurator. The callback onSuccessConfigReceived will be used in this case.
-     */
-    void onSuccess(int status);
-
-    /**
-     * Called when DPP Failure events take place.
-     */
-    void onFailure(int status, String ssid, String channelList, in int[] bandArray);
-
-    /**
-     * Called when DPP events that indicate progress take place. Can be used by UI elements
-     * to show progress.
-     */
-    void onProgress(int status);
-}
diff --git a/wifi/java/android/net/wifi/ILocalOnlyHotspotCallback.aidl b/wifi/java/android/net/wifi/ILocalOnlyHotspotCallback.aidl
deleted file mode 100644
index b567f29..0000000
--- a/wifi/java/android/net/wifi/ILocalOnlyHotspotCallback.aidl
+++ /dev/null
@@ -1,30 +0,0 @@
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import android.net.wifi.SoftApConfiguration;
-
-/**
- * Communicates LOHS status back to the application process.
- *
- * @hide
- */
-oneway interface ILocalOnlyHotspotCallback {
-    void onHotspotStarted(in SoftApConfiguration config);
-    void onHotspotStopped();
-    void onHotspotFailed(int reason);
-}
diff --git a/wifi/java/android/net/wifi/INetworkRequestMatchCallback.aidl b/wifi/java/android/net/wifi/INetworkRequestMatchCallback.aidl
deleted file mode 100644
index d14ec57..0000000
--- a/wifi/java/android/net/wifi/INetworkRequestMatchCallback.aidl
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import android.net.wifi.INetworkRequestUserSelectionCallback;
-import android.net.wifi.ScanResult;
-import android.net.wifi.WifiConfiguration;
-
-/**
- * Interface for network request match callback.
- *
- * @hide
- */
-oneway interface INetworkRequestMatchCallback
-{
-   void onUserSelectionCallbackRegistration(in INetworkRequestUserSelectionCallback userSelectionCallback);
-
-   void onAbort();
-
-   void onMatch(in List<ScanResult> scanResults);
-
-   void onUserSelectionConnectSuccess(in WifiConfiguration wificonfiguration);
-
-   void onUserSelectionConnectFailure(in WifiConfiguration wificonfiguration);
-}
diff --git a/wifi/java/android/net/wifi/INetworkRequestUserSelectionCallback.aidl b/wifi/java/android/net/wifi/INetworkRequestUserSelectionCallback.aidl
deleted file mode 100644
index 524cefb..0000000
--- a/wifi/java/android/net/wifi/INetworkRequestUserSelectionCallback.aidl
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import android.net.wifi.WifiConfiguration;
-
-/**
- * Interface for providing user selection in response to
- * network request match callback.
- * @hide
- */
-oneway interface INetworkRequestUserSelectionCallback
-{
-   void select(in WifiConfiguration wificonfiguration);
-
-   void reject();
-}
diff --git a/wifi/java/android/net/wifi/IOnWifiActivityEnergyInfoListener.aidl b/wifi/java/android/net/wifi/IOnWifiActivityEnergyInfoListener.aidl
deleted file mode 100644
index 7e25fd8a..0000000
--- a/wifi/java/android/net/wifi/IOnWifiActivityEnergyInfoListener.aidl
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import android.os.connectivity.WifiActivityEnergyInfo;
-
-/**
- * Interface for Wi-Fi activity energy info listener.
- *
- * @hide
- */
-oneway interface IOnWifiActivityEnergyInfoListener
-{
-    /**
-     * Service to manager callback providing current Wi-Fi activity energy info.
-     * @param info the Wi-Fi activity energy info
-     */
-    void onWifiActivityEnergyInfo(in WifiActivityEnergyInfo info);
-}
diff --git a/wifi/java/android/net/wifi/IOnWifiUsabilityStatsListener.aidl b/wifi/java/android/net/wifi/IOnWifiUsabilityStatsListener.aidl
deleted file mode 100644
index 4687f30..0000000
--- a/wifi/java/android/net/wifi/IOnWifiUsabilityStatsListener.aidl
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import android.net.wifi.WifiUsabilityStatsEntry;
-
-/**
- * Interface for Wi-Fi usability stats listener.
- *
- * @hide
- */
-oneway interface IOnWifiUsabilityStatsListener
-{
-    /**
-     * Service to manager callback providing current Wi-Fi usability stats.
-     *
-     * @param seqNum The sequence number of stats, used to derive the timing of updated Wi-Fi
-     *               usability statistics, set by framework and shall be incremented by one
-     *               after each update.
-     * @param isSameBssidAndFreq The flag to indicate whether the BSSID and the frequency of
-     *                           network stays the same or not relative to the last update of
-     *                           Wi-Fi usability stats.
-     * @param stats The updated Wi-Fi usability statistics.
-     */
-    void onWifiUsabilityStats(int seqNum, boolean isSameBssidAndFreq,
-            in WifiUsabilityStatsEntry stats);
-}
diff --git a/wifi/java/android/net/wifi/IScanResultsCallback.aidl b/wifi/java/android/net/wifi/IScanResultsCallback.aidl
deleted file mode 100644
index 56f6025..0000000
--- a/wifi/java/android/net/wifi/IScanResultsCallback.aidl
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-/**
- * Interface for Wi-Fi scan result available callback.
- *
- * @hide
- */
-oneway interface IScanResultsCallback
-{
-    void onScanResultsAvailable();
-}
diff --git a/wifi/java/android/net/wifi/IScanResultsListener.aidl b/wifi/java/android/net/wifi/IScanResultsListener.aidl
deleted file mode 100644
index e7eaddd..0000000
--- a/wifi/java/android/net/wifi/IScanResultsListener.aidl
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-/** @hide */
-
-oneway interface IScanResultsListener
-{
-    void onScanResultsAvailable();
-}
diff --git a/wifi/java/android/net/wifi/IScoreUpdateObserver.aidl b/wifi/java/android/net/wifi/IScoreUpdateObserver.aidl
deleted file mode 100644
index 775fed7..0000000
--- a/wifi/java/android/net/wifi/IScoreUpdateObserver.aidl
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-/**
- * Interface for Wi-Fi score callback.
- *
- * @hide
- */
-oneway interface IScoreUpdateObserver
-{
-    void notifyScoreUpdate(int sessionId, int score);
-
-    void triggerUpdateOfWifiUsabilityStats(int sessionId);
-}
diff --git a/wifi/java/android/net/wifi/ISoftApCallback.aidl b/wifi/java/android/net/wifi/ISoftApCallback.aidl
deleted file mode 100644
index f81bcb9..0000000
--- a/wifi/java/android/net/wifi/ISoftApCallback.aidl
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-import android.net.wifi.SoftApCapability;
-import android.net.wifi.SoftApInfo;
-
-import android.net.wifi.WifiClient;
-
-/**
- * Interface for Soft AP callback.
- *
- * @hide
- */
-oneway interface ISoftApCallback
-{
-    /**
-     * Service to manager callback providing current soft AP state. The possible
-     * parameter values listed are defined in WifiManager.java
-     *
-     * @param state new AP state. One of WIFI_AP_STATE_DISABLED,
-     *        WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_ENABLED,
-     *        WIFI_AP_STATE_ENABLING, WIFI_AP_STATE_FAILED
-     * @param failureReason reason when in failed state. One of
-     *        SAP_START_FAILURE_GENERAL, SAP_START_FAILURE_NO_CHANNEL
-     */
-    void onStateChanged(int state, int failureReason);
-
-    /**
-     * Service to manager callback providing connected client's information.
-     *
-     * @param clients the currently connected clients
-     */
-    void onConnectedClientsChanged(in List<WifiClient> clients);
-
-    /**
-     * Service to manager callback providing information of softap.
-     *
-     * @param softApInfo is the softap information. {@link SoftApInfo}
-     */
-    void onInfoChanged(in SoftApInfo softApInfo);
-
-
-    /**
-     * Service to manager callback providing capability of softap.
-     *
-     * @param capability is the softap capability. {@link SoftApCapability}
-     */
-    void onCapabilityChanged(in SoftApCapability capability);
-
-    /**
-     * Service to manager callback providing blocked client of softap with specific reason code.
-     *
-     * @param client the currently blocked client.
-     * @param blockedReason one of blocked reason from {@link WifiManager.SapClientBlockedReason}
-     */
-    void onBlockedClientConnecting(in WifiClient client, int blockedReason);
-}
diff --git a/wifi/java/android/net/wifi/ISuggestionConnectionStatusListener.aidl b/wifi/java/android/net/wifi/ISuggestionConnectionStatusListener.aidl
deleted file mode 100644
index b49e49b..0000000
--- a/wifi/java/android/net/wifi/ISuggestionConnectionStatusListener.aidl
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import android.net.wifi.WifiNetworkSuggestion;
-
-/**
- * Interface for suggestion network connection listener.
- *
- * @hide
- */
-oneway interface ISuggestionConnectionStatusListener
-{
-   void onConnectionStatus(in WifiNetworkSuggestion wifiNetworkSuggestion, int failureReason);
-}
diff --git a/wifi/java/android/net/wifi/ITrafficStateCallback.aidl b/wifi/java/android/net/wifi/ITrafficStateCallback.aidl
deleted file mode 100644
index 0c8e777..0000000
--- a/wifi/java/android/net/wifi/ITrafficStateCallback.aidl
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-/**
- * Interface for Traffic state callback.
- *
- * @hide
- */
-oneway interface ITrafficStateCallback
-{
-   /**
-    * Callback invoked to inform clients about the current traffic state.
-    *
-    * @param state One of the values: {@link #DATA_ACTIVITY_NONE}, {@link #DATA_ACTIVITY_IN},
-    * {@link #DATA_ACTIVITY_OUT} & {@link #DATA_ACTIVITY_INOUT}.
-    * @hide
-    */
-   void onStateChanged(int state);
-}
diff --git a/wifi/java/android/net/wifi/ITxPacketCountListener.aidl b/wifi/java/android/net/wifi/ITxPacketCountListener.aidl
deleted file mode 100644
index 9105bd0..0000000
--- a/wifi/java/android/net/wifi/ITxPacketCountListener.aidl
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-/**
- * Interface for tx packet counter callback.
- * @deprecated no longer used, remove once removed from BaseWifiService
- * @hide
- */
-oneway interface ITxPacketCountListener
-{
-    void onSuccess(int count);
-    void onFailure(int reason);
-}
diff --git a/wifi/java/android/net/wifi/IWifiConnectedNetworkScorer.aidl b/wifi/java/android/net/wifi/IWifiConnectedNetworkScorer.aidl
deleted file mode 100644
index f96d037..0000000
--- a/wifi/java/android/net/wifi/IWifiConnectedNetworkScorer.aidl
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import android.net.wifi.IScoreUpdateObserver;
-
-/**
- * Interface for Wi-Fi connected network scorer.
- *
- * @hide
- */
-oneway interface IWifiConnectedNetworkScorer
-{
-    void onStart(int sessionId);
-
-    void onStop(int sessionId);
-
-    void onSetScoreUpdateObserver(IScoreUpdateObserver observerImpl);
-}
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
deleted file mode 100644
index 5063ad6..0000000
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ /dev/null
@@ -1,278 +0,0 @@
-/**
- * Copyright (c) 2008, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import android.content.pm.ParceledListSlice;
-
-import android.net.wifi.hotspot2.OsuProvider;
-import android.net.wifi.hotspot2.PasspointConfiguration;
-import android.net.wifi.hotspot2.IProvisioningCallback;
-
-import android.net.DhcpInfo;
-import android.net.Network;
-import android.net.wifi.IActionListener;
-import android.net.wifi.IDppCallback;
-import android.net.wifi.ILocalOnlyHotspotCallback;
-import android.net.wifi.INetworkRequestMatchCallback;
-import android.net.wifi.IOnWifiActivityEnergyInfoListener;
-import android.net.wifi.IOnWifiUsabilityStatsListener;
-import android.net.wifi.IScanResultsCallback;
-import android.net.wifi.ISoftApCallback;
-import android.net.wifi.ISuggestionConnectionStatusListener;
-import android.net.wifi.ITrafficStateCallback;
-import android.net.wifi.IWifiConnectedNetworkScorer;
-import android.net.wifi.ScanResult;
-import android.net.wifi.SoftApConfiguration;
-import android.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiInfo;
-import android.net.wifi.WifiNetworkSuggestion;
-
-import android.os.Messenger;
-import android.os.ResultReceiver;
-import android.os.WorkSource;
-
-/**
- * Interface that allows controlling and querying Wi-Fi connectivity.
- *
- * {@hide}
- */
-interface IWifiManager
-{
-    long getSupportedFeatures();
-
-    oneway void getWifiActivityEnergyInfoAsync(in IOnWifiActivityEnergyInfoListener listener);
-
-    ParceledListSlice getConfiguredNetworks(String packageName, String featureId);
-
-    ParceledListSlice getPrivilegedConfiguredNetworks(String packageName, String featureId);
-
-    Map getAllMatchingFqdnsForScanResults(in List<ScanResult> scanResult);
-
-    Map getMatchingOsuProviders(in List<ScanResult> scanResult);
-
-    Map getMatchingPasspointConfigsForOsuProviders(in List<OsuProvider> osuProviders);
-
-    int addOrUpdateNetwork(in WifiConfiguration config, String packageName);
-
-    boolean addOrUpdatePasspointConfiguration(in PasspointConfiguration config, String packageName);
-
-    boolean removePasspointConfiguration(in String fqdn, String packageName);
-
-    List<PasspointConfiguration> getPasspointConfigurations(in String packageName);
-
-    List<WifiConfiguration> getWifiConfigsForPasspointProfiles(in List<String> fqdnList);
-
-    void queryPasspointIcon(long bssid, String fileName);
-
-    int matchProviderWithCurrentNetwork(String fqdn);
-
-    void deauthenticateNetwork(long holdoff, boolean ess);
-
-    boolean removeNetwork(int netId, String packageName);
-
-    boolean enableNetwork(int netId, boolean disableOthers, String packageName);
-
-    boolean disableNetwork(int netId, String packageName);
-
-    void allowAutojoinGlobal(boolean choice);
-
-    void allowAutojoin(int netId, boolean choice);
-
-    void allowAutojoinPasspoint(String fqdn, boolean enableAutoJoin);
-
-    void setMacRandomizationSettingPasspointEnabled(String fqdn, boolean enable);
-
-    void setPasspointMeteredOverride(String fqdn, int meteredOverride);
-
-    boolean startScan(String packageName, String featureId);
-
-    List<ScanResult> getScanResults(String callingPackage, String callingFeatureId);
-
-    boolean disconnect(String packageName);
-
-    boolean reconnect(String packageName);
-
-    boolean reassociate(String packageName);
-
-    WifiInfo getConnectionInfo(String callingPackage, String callingFeatureId);
-
-    boolean setWifiEnabled(String packageName, boolean enable);
-
-    int getWifiEnabledState();
-
-    String getCountryCode();
-
-    boolean is5GHzBandSupported();
-
-    boolean is6GHzBandSupported();
-
-    boolean isWifiStandardSupported(int standard);
-
-    DhcpInfo getDhcpInfo();
-
-    void setScanAlwaysAvailable(boolean isAvailable);
-
-    boolean isScanAlwaysAvailable();
-
-    boolean acquireWifiLock(IBinder lock, int lockType, String tag, in WorkSource ws);
-
-    void updateWifiLockWorkSource(IBinder lock, in WorkSource ws);
-
-    boolean releaseWifiLock(IBinder lock);
-
-    void initializeMulticastFiltering();
-
-    boolean isMulticastEnabled();
-
-    void acquireMulticastLock(IBinder binder, String tag);
-
-    void releaseMulticastLock(String tag);
-
-    void updateInterfaceIpState(String ifaceName, int mode);
-
-    boolean startSoftAp(in WifiConfiguration wifiConfig);
-
-    boolean startTetheredHotspot(in SoftApConfiguration softApConfig);
-
-    boolean stopSoftAp();
-
-    int startLocalOnlyHotspot(in ILocalOnlyHotspotCallback callback, String packageName,
-                              String featureId, in SoftApConfiguration customConfig);
-
-    void stopLocalOnlyHotspot();
-
-    void startWatchLocalOnlyHotspot(in ILocalOnlyHotspotCallback callback);
-
-    void stopWatchLocalOnlyHotspot();
-
-    @UnsupportedAppUsage
-    int getWifiApEnabledState();
-
-    @UnsupportedAppUsage
-    WifiConfiguration getWifiApConfiguration();
-
-    SoftApConfiguration getSoftApConfiguration();
-
-    boolean setWifiApConfiguration(in WifiConfiguration wifiConfig, String packageName);
-
-    boolean setSoftApConfiguration(in SoftApConfiguration softApConfig, String packageName);
-
-    void notifyUserOfApBandConversion(String packageName);
-
-    void enableTdls(String remoteIPAddress, boolean enable);
-
-    void enableTdlsWithMacAddress(String remoteMacAddress, boolean enable);
-
-    String getCurrentNetworkWpsNfcConfigurationToken();
-
-    void enableVerboseLogging(int verbose);
-
-    int getVerboseLoggingLevel();
-
-    void disableEphemeralNetwork(String SSID, String packageName);
-
-    void factoryReset(String packageName);
-
-    @UnsupportedAppUsage
-    Network getCurrentNetwork();
-
-    byte[] retrieveBackupData();
-
-    void restoreBackupData(in byte[] data);
-
-    byte[] retrieveSoftApBackupData();
-
-    SoftApConfiguration restoreSoftApBackupData(in byte[] data);
-
-    void restoreSupplicantBackupData(in byte[] supplicantData, in byte[] ipConfigData);
-
-    void startSubscriptionProvisioning(in OsuProvider provider, in IProvisioningCallback callback);
-
-    void registerSoftApCallback(in IBinder binder, in ISoftApCallback callback, int callbackIdentifier);
-
-    void unregisterSoftApCallback(int callbackIdentifier);
-
-    void addOnWifiUsabilityStatsListener(in IBinder binder, in IOnWifiUsabilityStatsListener listener, int listenerIdentifier);
-
-    void removeOnWifiUsabilityStatsListener(int listenerIdentifier);
-
-    void registerTrafficStateCallback(in IBinder binder, in ITrafficStateCallback callback, int callbackIdentifier);
-
-    void unregisterTrafficStateCallback(int callbackIdentifier);
-
-    void registerNetworkRequestMatchCallback(in IBinder binder, in INetworkRequestMatchCallback callback, int callbackIdentifier);
-
-    void unregisterNetworkRequestMatchCallback(int callbackIdentifier);
-
-    int addNetworkSuggestions(in List<WifiNetworkSuggestion> networkSuggestions, in String packageName,
-        in String featureId);
-
-    int removeNetworkSuggestions(in List<WifiNetworkSuggestion> networkSuggestions, in String packageName);
-
-    List<WifiNetworkSuggestion> getNetworkSuggestions(in String packageName);
-
-    String[] getFactoryMacAddresses();
-
-    void setDeviceMobilityState(int state);
-
-    void startDppAsConfiguratorInitiator(in IBinder binder, in String enrolleeUri,
-        int selectedNetworkId, int netRole, in IDppCallback callback);
-
-    void startDppAsEnrolleeInitiator(in IBinder binder, in String configuratorUri,
-        in IDppCallback callback);
-
-    void stopDppSession();
-
-    void updateWifiUsabilityScore(int seqNum, int score, int predictionHorizonSec);
-
-    oneway void connect(in WifiConfiguration config, int netId, in IBinder binder, in IActionListener listener, int callbackIdentifier);
-
-    oneway void save(in WifiConfiguration config, in IBinder binder, in IActionListener listener, int callbackIdentifier);
-
-    oneway void forget(int netId, in IBinder binder, in IActionListener listener, int callbackIdentifier);
-
-    void registerScanResultsCallback(in IScanResultsCallback callback);
-
-    void unregisterScanResultsCallback(in IScanResultsCallback callback);
-
-    void registerSuggestionConnectionStatusListener(in IBinder binder, in ISuggestionConnectionStatusListener listener, int listenerIdentifier, String packageName, String featureId);
-
-    void unregisterSuggestionConnectionStatusListener(int listenerIdentifier, String packageName);
-
-    int calculateSignalLevel(int rssi);
-
-    List<WifiConfiguration> getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(in List<ScanResult> scanResults);
-
-    boolean setWifiConnectedNetworkScorer(in IBinder binder, in IWifiConnectedNetworkScorer scorer);
-
-    void clearWifiConnectedNetworkScorer();
-
-    /**
-     * Return the Map of {@link WifiNetworkSuggestion} and the list of <ScanResult>
-     */
-    Map getMatchingScanResults(in List<WifiNetworkSuggestion> networkSuggestions, in List<ScanResult> scanResults, String callingPackage, String callingFeatureId);
-
-    void setScanThrottleEnabled(boolean enable);
-
-    boolean isScanThrottleEnabled();
-
-    Map getAllMatchingPasspointProfilesForScanResults(in List<ScanResult> scanResult);
-
-    void setAutoWakeupEnabled(boolean enable);
-
-    boolean isAutoWakeupEnabled();
-}
diff --git a/wifi/java/android/net/wifi/IWifiScanner.aidl b/wifi/java/android/net/wifi/IWifiScanner.aidl
deleted file mode 100644
index 485f5ce..0000000
--- a/wifi/java/android/net/wifi/IWifiScanner.aidl
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import android.os.Messenger;
-import android.os.Bundle;
-
-/**
- * {@hide}
- */
-interface IWifiScanner
-{
-    Messenger getMessenger();
-
-    Bundle getAvailableChannels(int band, String packageName, String featureId);
-}
diff --git a/wifi/java/android/net/wifi/ParcelUtil.java b/wifi/java/android/net/wifi/ParcelUtil.java
deleted file mode 100644
index a26877d..0000000
--- a/wifi/java/android/net/wifi/ParcelUtil.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/**
- * Copyright (c) 2016, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import android.os.Parcel;
-
-import java.io.ByteArrayInputStream;
-import java.security.KeyFactory;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.PKCS8EncodedKeySpec;
-
-/**
- * Provides utilities for writing/reading a non-Parcelable objects to/from
- * a Parcel object.
- *
- * @hide
- */
-public class ParcelUtil {
-    /**
-     * Write a PrivateKey object |key| to the specified Parcel |dest|.
-     *
-     * Below is the data format:
-     * |algorithm|     -> String of algorithm name
-     * |endcodedKey|  -> byte[] of key data
-     *
-     * For a null PrivateKey object, a null string will be written to |algorithm| and
-     * |encodedKey| will be skipped. Since a PrivateKey can only be constructed with
-     * a valid algorithm String.
-     *
-     * @param dest Parcel object to write to
-     * @param key PrivateKey object to read from.
-     */
-    public static void writePrivateKey(Parcel dest, PrivateKey key) {
-        if (key == null) {
-            dest.writeString(null);
-            return;
-        }
-
-        dest.writeString(key.getAlgorithm());
-        dest.writeByteArray(key.getEncoded());
-    }
-
-    /**
-     * Read/create a PrivateKey object from a specified Parcel object |in|.
-     *
-     * Refer to the function above for the expected data format.
-     *
-     * @param in Parcel object to read from
-     * @return a PrivateKey object or null
-     */
-    public static PrivateKey readPrivateKey(Parcel in) {
-        String algorithm = in.readString();
-        if (algorithm == null) {
-            return null;
-        }
-
-        byte[] userKeyBytes = in.createByteArray();
-        try {
-            KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
-            return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(userKeyBytes));
-       } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
-            return null;
-       }
-    }
-
-    /**
-     * Write a X509Certificate object |cert| to a Parcel object |dest|.
-     * The data being written to the Parcel is just a byte[] of the encoded certificate data.
-     *
-     * @param dest Parcel object to write to
-     * @param cert X509Certificate object to read from
-     */
-    public static void writeCertificate(Parcel dest, X509Certificate cert) {
-        byte[] certBytes = null;
-        if (cert != null) {
-            try {
-                certBytes = cert.getEncoded();
-            } catch (CertificateEncodingException e) {
-                /* empty, write null. */
-            }
-        }
-        dest.writeByteArray(certBytes);
-    }
-
-    /**
-     * Read/create a X509Certificate object from a specified Parcel object |in|.
-     *
-     * @param in Parcel object to read from
-     * @return a X509Certficate object or null
-     */
-    public static X509Certificate readCertificate(Parcel in) {
-        byte[] certBytes = in.createByteArray();
-        if (certBytes == null) {
-            return null;
-        }
-
-        try {
-            CertificateFactory cFactory = CertificateFactory.getInstance("X.509");
-            return (X509Certificate) cFactory
-                    .generateCertificate(new ByteArrayInputStream(certBytes));
-        } catch (CertificateException e) {
-            return null;
-        }
-    }
-
-    /**
-     * Write an array of X509Certificate objects |certs| to a Parcel object |dest|.
-     * The data being written to the Parcel are consist of an integer indicating
-     * the size of the array and the certificates data.  Certificates data will be
-     * skipped for a null array or size of 0 array.
-     *
-     * @param dest Parcel object to write to
-     * @param certs array of X509Certificate objects to read from
-     */
-    public static void writeCertificates(Parcel dest, X509Certificate[] certs) {
-        if (certs == null || certs.length == 0) {
-            dest.writeInt(0);
-            return;
-        }
-
-        dest.writeInt(certs.length);
-        for (int i = 0; i < certs.length; i++) {
-            writeCertificate(dest, certs[i]);
-        }
-    }
-
-    /**
-     * Read/create an array of X509Certificate objects from a specified Parcel object |in|.
-     *
-     * @param in Parcel object to read from
-     * @return X509Certficate[] or null
-     */
-    public static X509Certificate[] readCertificates(Parcel in) {
-        int length = in.readInt();
-        if (length == 0) {
-            return null;
-        }
-
-        X509Certificate[] certs = new X509Certificate[length];
-        for (int i = 0; i < length; i++) {
-            certs[i] = readCertificate(in);
-        }
-        return certs;
-    }
-}
diff --git a/wifi/java/android/net/wifi/RttManager.aidl b/wifi/java/android/net/wifi/RttManager.aidl
deleted file mode 100644
index 9479cf0..0000000
--- a/wifi/java/android/net/wifi/RttManager.aidl
+++ /dev/null
@@ -1,21 +0,0 @@
-/**
- * Copyright (c) 2015, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-parcelable RttManager.RttCapabilities;
-parcelable RttManager.ParcelableRttResults;
-parcelable RttManager.ParcelableRttParams;
diff --git a/wifi/java/android/net/wifi/RttManager.java b/wifi/java/android/net/wifi/RttManager.java
deleted file mode 100644
index 73c52ab..0000000
--- a/wifi/java/android/net/wifi/RttManager.java
+++ /dev/null
@@ -1,1233 +0,0 @@
-package android.net.wifi;
-
-import android.Manifest;
-import android.annotation.NonNull;
-import android.annotation.RequiresPermission;
-import android.annotation.SuppressLint;
-import android.annotation.SystemApi;
-import android.annotation.SystemService;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.net.wifi.rtt.RangingRequest;
-import android.net.wifi.rtt.RangingResult;
-import android.net.wifi.rtt.RangingResultCallback;
-import android.net.wifi.rtt.WifiRttManager;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.SystemClock;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.Protocol;
-
-import java.util.List;
-
-/** @hide */
-@SystemApi
-@Deprecated
-@SystemService(Context.WIFI_RTT_SERVICE)
-public class RttManager {
-
-    private static final boolean DBG = false;
-    private static final String TAG = "RttManager";
-
-    /** @deprecated It is Not supported anymore. */
-    @Deprecated
-    public static final int RTT_TYPE_UNSPECIFIED        = 0;
-
-    public static final int RTT_TYPE_ONE_SIDED          = 1;
-    public static final int RTT_TYPE_TWO_SIDED          = 2;
-
-    /** @deprecated It is not supported anymore. */
-    @Deprecated
-    public static final int RTT_TYPE_11_V               = 2;
-
-    /** @deprecated It is not supported anymore. */
-    @Deprecated
-    public static final int RTT_TYPE_11_MC              = 4;
-
-    /** @deprecated It is not supported anymore. */
-    @Deprecated
-    public static final int RTT_PEER_TYPE_UNSPECIFIED    = 0;
-
-    public static final int RTT_PEER_TYPE_AP             = 1;
-    public static final int RTT_PEER_TYPE_STA            = 2;       /* requires NAN */
-    public static final int RTT_PEER_P2P_GO              = 3;
-    public static final int RTT_PEER_P2P_CLIENT          = 4;
-    public static final int RTT_PEER_NAN                 = 5;
-
-    /**
-     * @deprecated It is not supported anymore.
-     * Use {@link android.net.wifi.RttManager#RTT_BW_20_SUPPORT} API.
-     */
-    @Deprecated
-    public static final int RTT_CHANNEL_WIDTH_20      = 0;
-
-    /**
-     * @deprecated It is not supported anymore.
-     * Use {@link android.net.wifi.RttManager#RTT_BW_40_SUPPORT} API.
-     */
-    @Deprecated
-    public static final int RTT_CHANNEL_WIDTH_40      = 1;
-
-    /**
-     * @deprecated It is not supported anymore.
-     * Use {@link android.net.wifi.RttManager#RTT_BW_80_SUPPORT} API.
-     */
-    @Deprecated
-    public static final int RTT_CHANNEL_WIDTH_80      = 2;
-
-    /**@deprecated It is not supported anymore.
-     * Use {@link android.net.wifi.RttManager#RTT_BW_160_SUPPORT} API.
-     */
-    @Deprecated
-    public static final int RTT_CHANNEL_WIDTH_160     = 3;
-
-    /**@deprecated not supported anymore*/
-    @Deprecated
-    public static final int RTT_CHANNEL_WIDTH_80P80   = 4;
-
-    /**@deprecated It is not supported anymore.
-     * Use {@link android.net.wifi.RttManager#RTT_BW_5_SUPPORT} API.
-     */
-    @Deprecated
-    public static final int RTT_CHANNEL_WIDTH_5       = 5;
-
-    /**@deprecated It is not supported anymore.
-     * Use {@link android.net.wifi.RttManager#RTT_BW_10_SUPPORT} API.
-     */
-    @Deprecated
-    public static final int RTT_CHANNEL_WIDTH_10      = 6;
-
-    /** @deprecated channel info must be specified. */
-    @Deprecated
-    public static final int RTT_CHANNEL_WIDTH_UNSPECIFIED = -1;
-
-    public static final int RTT_STATUS_SUCCESS                  = 0;
-    /** General failure*/
-    public static final int RTT_STATUS_FAILURE                  = 1;
-    /** Destination does not respond to RTT request*/
-    public static final int RTT_STATUS_FAIL_NO_RSP              = 2;
-    /** RTT request is rejected by the destination. Double side RTT only*/
-    public static final int RTT_STATUS_FAIL_REJECTED            = 3;
-    /** */
-    public static final int RTT_STATUS_FAIL_NOT_SCHEDULED_YET   = 4;
-    /** Timing measurement timeout*/
-    public static final int RTT_STATUS_FAIL_TM_TIMEOUT          = 5;
-    /** Destination is on a different channel from the RTT Request*/
-    public static final int RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL  = 6;
-    /** This type of Ranging is not support by Hardware*/
-    public static final int RTT_STATUS_FAIL_NO_CAPABILITY       = 7;
-    /** Request abort fro uncertain reason*/
-    public static final int RTT_STATUS_ABORTED                  = 8;
-    /** The T1-T4 or TOD/TOA Timestamp is illegal*/
-    public static final int RTT_STATUS_FAIL_INVALID_TS          = 9;
-    /** 11mc protocol level failed, eg, unrecognized FTMR/FTM frame*/
-    public static final int RTT_STATUS_FAIL_PROTOCOL            = 10;
-    /** Request can not be scheduled by hardware*/
-    public static final int RTT_STATUS_FAIL_SCHEDULE            = 11;
-    /** destination is busy now, you can try after a specified time from destination*/
-    public static final int RTT_STATUS_FAIL_BUSY_TRY_LATER      = 12;
-    /** Bad Request argument*/
-    public static final int RTT_STATUS_INVALID_REQ              = 13;
-    /** Wifi is not enabled*/
-    public static final int RTT_STATUS_NO_WIFI                  = 14;
-    /** Responder overrides param info, cannot range with new params 2-side RTT only*/
-    public static final int RTT_STATUS_FAIL_FTM_PARAM_OVERRIDE  = 15;
-
-    public static final int REASON_UNSPECIFIED              = -1;
-    public static final int REASON_NOT_AVAILABLE            = -2;
-    public static final int REASON_INVALID_LISTENER         = -3;
-    public static final int REASON_INVALID_REQUEST          = -4;
-    /** Do not have required permission */
-    public static final int REASON_PERMISSION_DENIED        = -5;
-    /** Ranging failed because responder role is enabled in STA mode.*/
-    public static final int
-            REASON_INITIATOR_NOT_ALLOWED_WHEN_RESPONDER_ON  = -6;
-
-    public static final String DESCRIPTION_KEY  = "android.net.wifi.RttManager.Description";
-
-    /**
-     * RTT BW supported bit mask, used as RTT param bandWidth too
-     */
-    public static final int RTT_BW_5_SUPPORT   = 0x01;
-    public static final int RTT_BW_10_SUPPORT  = 0x02;
-    public static final int RTT_BW_20_SUPPORT  = 0x04;
-    public static final int RTT_BW_40_SUPPORT  = 0x08;
-    public static final int RTT_BW_80_SUPPORT  = 0x10;
-    public static final int RTT_BW_160_SUPPORT = 0x20;
-
-    /**
-     * RTT Preamble Support bit mask
-     */
-    public static final int PREAMBLE_LEGACY  = 0x01;
-    public static final int PREAMBLE_HT      = 0x02;
-    public static final int PREAMBLE_VHT     = 0x04;
-
-    /** @deprecated Use the new {@link android.net.wifi.RttManager.RttCapabilities} API */
-    @Deprecated
-    public class Capabilities {
-        public int supportedType;
-        public int supportedPeerType;
-    }
-
-    /** @deprecated Use the new {@link android.net.wifi.RttManager#getRttCapabilities()} API.*/
-    @Deprecated
-    @SuppressLint("Doclava125")
-    public Capabilities getCapabilities() {
-        throw new UnsupportedOperationException(
-                "getCapabilities is not supported in the adaptation layer");
-    }
-
-    /**
-     * This class describe the RTT capability of the Hardware
-     */
-    @Deprecated
-    public static class RttCapabilities implements Parcelable {
-        /** @deprecated It is not supported*/
-        @Deprecated
-        public boolean supportedType;
-        /** @deprecated It is not supported*/
-        @Deprecated
-        public boolean supportedPeerType;
-        //1-sided rtt measurement is supported
-        public boolean oneSidedRttSupported;
-        //11mc 2-sided rtt measurement is supported
-        public boolean twoSided11McRttSupported;
-        //location configuration information supported
-        public boolean lciSupported;
-        //location civic records supported
-        public boolean lcrSupported;
-        //preamble supported, see bit mask definition above
-        public int preambleSupported;
-        //RTT bandwidth supported
-        public int bwSupported;
-        // Whether STA responder role is supported.
-        public boolean responderSupported;
-
-        /** Whether the secure RTT protocol is supported. */
-        public boolean secureRttSupported;
-
-        /** Draft 11mc version supported, including major and minor version. e.g, draft 4.3 is 43 */
-        public int mcVersion;
-
-        @NonNull
-        @Override
-        public String toString() {
-            StringBuffer sb = new StringBuffer();
-            sb.append("oneSidedRtt ").
-            append(oneSidedRttSupported ? "is Supported. " : "is not supported. ").
-            append("twoSided11McRtt ").
-            append(twoSided11McRttSupported ? "is Supported. " : "is not supported. ").
-            append("lci ").
-            append(lciSupported ? "is Supported. " : "is not supported. ").
-            append("lcr ").
-            append(lcrSupported ? "is Supported. " : "is not supported. ");
-
-            if ((preambleSupported & PREAMBLE_LEGACY) != 0) {
-                sb.append("Legacy ");
-            }
-
-            if ((preambleSupported & PREAMBLE_HT) != 0) {
-                sb.append("HT ");
-            }
-
-            if ((preambleSupported & PREAMBLE_VHT) != 0) {
-                sb.append("VHT ");
-            }
-
-            sb.append("is supported. ");
-
-            if ((bwSupported & RTT_BW_5_SUPPORT) != 0) {
-                sb.append("5 MHz ");
-            }
-
-            if ((bwSupported & RTT_BW_10_SUPPORT) != 0) {
-                sb.append("10 MHz ");
-            }
-
-            if ((bwSupported & RTT_BW_20_SUPPORT) != 0) {
-                sb.append("20 MHz ");
-            }
-
-            if ((bwSupported & RTT_BW_40_SUPPORT) != 0) {
-                sb.append("40 MHz ");
-            }
-
-            if ((bwSupported & RTT_BW_80_SUPPORT) != 0) {
-                sb.append("80 MHz ");
-            }
-
-            if ((bwSupported & RTT_BW_160_SUPPORT) != 0) {
-                sb.append("160 MHz ");
-            }
-
-            sb.append("is supported.");
-
-            sb.append(" STA responder role is ")
-                    .append(responderSupported ? "supported" : "not supported");
-            sb.append(" Secure RTT protocol is ")
-                    .append(secureRttSupported ? "supported" : "not supported");
-            sb.append(" 11mc version is " + mcVersion);
-
-            return sb.toString();
-        }
-        /** Implement the Parcelable interface {@hide} */
-        @Override
-        public int describeContents() {
-            return 0;
-        }
-
-        /** Implement the Parcelable interface {@hide} */
-        @Override
-        public void writeToParcel(Parcel dest, int flags) {
-            dest.writeInt(oneSidedRttSupported ? 1 : 0);
-            dest.writeInt(twoSided11McRttSupported ? 1 : 0);
-            dest.writeInt(lciSupported ? 1 : 0);
-            dest.writeInt(lcrSupported ? 1 : 0);
-            dest.writeInt(preambleSupported);
-            dest.writeInt(bwSupported);
-            dest.writeInt(responderSupported ? 1 : 0);
-            dest.writeInt(secureRttSupported ? 1 : 0);
-            dest.writeInt(mcVersion);
-        }
-
-        /** Implement the Parcelable interface {@hide} */
-        public static final @android.annotation.NonNull Creator<RttCapabilities> CREATOR =
-            new Creator<RttCapabilities>() {
-            @Override
-            public RttCapabilities createFromParcel(Parcel in) {
-                RttCapabilities capabilities = new RttCapabilities();
-                capabilities.oneSidedRttSupported = (in.readInt() == 1);
-                capabilities.twoSided11McRttSupported = (in.readInt() == 1);
-                capabilities.lciSupported = (in.readInt() == 1);
-                capabilities.lcrSupported = (in.readInt() == 1);
-                capabilities.preambleSupported = in.readInt();
-                capabilities.bwSupported = in.readInt();
-                capabilities.responderSupported = (in.readInt() == 1);
-                capabilities.secureRttSupported = (in.readInt() == 1);
-                capabilities.mcVersion = in.readInt();
-                return capabilities;
-            }
-                /** Implement the Parcelable interface {@hide} */
-                @Override
-                public RttCapabilities[] newArray(int size) {
-                    return new RttCapabilities[size];
-                }
-             };
-    }
-
-    /**
-     * This method is deprecated. Please use the {@link WifiRttManager} API.
-     */
-    @RequiresPermission(Manifest.permission.LOCATION_HARDWARE)
-    public RttCapabilities getRttCapabilities() {
-        return mRttCapabilities;
-    }
-
-    /** specifies parameters for RTT request */
-    @Deprecated
-    public static class RttParams {
-        /**
-         * type of destination device being ranged
-         * currently only support RTT_PEER_TYPE_AP
-         * Range:RTT_PEER_TYPE_xxxx Default value:RTT_PEER_TYPE_AP
-         */
-        public int deviceType;
-
-        /**
-         * type of RTT measurement method. Need check scan result and RttCapabilities first
-         * Range: RTT_TYPE_ONE_SIDED or RTT_TYPE_TWO_SIDED
-         * Default value: RTT_TYPE_ONE_SIDED
-         */
-        public int requestType;
-
-        /**
-         * Whether the secure RTT protocol needs to be used for ranging this peer device.
-         */
-        public boolean secure;
-
-        /**
-         * mac address of the device being ranged
-         * Default value: null
-         */
-        public String bssid;
-
-        /**
-         * The primary control channel over which the client is
-         * communicating with the AP.Same as ScanResult.frequency
-         * Default value: 0
-         */
-        public int frequency;
-
-        /**
-         * channel width of the destination AP. Same as ScanResult.channelWidth
-         * Default value: 0
-         */
-        public int channelWidth;
-
-        /**
-         * Not used if the AP bandwidth is 20 MHz
-         * If the AP use 40, 80 or 160 MHz, this is the center frequency
-         * if the AP use 80 + 80 MHz, this is the center frequency of the first segment
-         * same as ScanResult.centerFreq0
-         * Default value: 0
-         */
-         public int centerFreq0;
-
-         /**
-          * Only used if the AP bandwidth is 80 + 80 MHz
-          * if the AP use 80 + 80 MHz, this is the center frequency of the second segment
-          * same as ScanResult.centerFreq1
-          * Default value: 0
-          */
-          public int centerFreq1;
-
-        /**
-         * number of samples to be taken
-         * @deprecated Use the new {@link android.net.wifi.RttManager.RttParams#numSamplesPerBurst}
-         */
-        @Deprecated
-        public int num_samples;
-
-        /**
-         * number of retries if a sample fails
-         * @deprecated
-         * Use {@link android.net.wifi.RttManager.RttParams#numRetriesPerMeasurementFrame} API.
-         */
-        @Deprecated
-        public int num_retries;
-
-        /** Number of burst in exp , 2^x. 0 means single shot measurement, range 0-15
-         * Currently only single shot is supported
-         * Default value: 0
-         */
-        public int numberBurst;
-
-        /**
-         * valid only if numberBurst > 1, interval between burst(100ms).
-         * Range : 0-31, 0--means no specific
-         * Default value: 0
-         */
-        public int interval;
-
-        /**
-         * number of samples to be taken in one burst
-         * Range: 1-31
-         * Default value: 8
-         */
-        public int numSamplesPerBurst;
-
-        /** number of retries for each measurement frame if a sample fails
-         *  Only used by single side RTT,
-         *  Range 0 - 3 Default value: 0
-         */
-        public int numRetriesPerMeasurementFrame;
-
-        /**
-         * number of retries for FTMR frame (control frame) if it fails.
-         * Only used by 80211MC double side RTT
-         * Range: 0-3  Default Value : 0
-         */
-        public int numRetriesPerFTMR;
-
-        /**
-         * Request LCI information, only available when choose double side RTT measurement
-         * need check RttCapabilties first.
-         * Default value: false
-         * */
-        public boolean LCIRequest;
-
-        /**
-         * Request LCR information, only available when choose double side RTT measurement
-         * need check RttCapabilties first.
-         * Default value: false
-         * */
-        public boolean LCRRequest;
-
-        /**
-         * Timeout for each burst, (250 * 2^x) us,
-         * Range 1-11 and 15. 15 means no control Default value: 15
-         * */
-        public int burstTimeout;
-
-        /** preamble used for RTT measurement
-         *  Range: PREAMBLE_LEGACY, PREAMBLE_HT, PREAMBLE_VHT
-         *  Default value: PREAMBLE_HT
-         */
-        public int preamble;
-
-        /** bandWidth used for RTT measurement.User need verify the highest BW the destination
-         * support (from scan result etc) before set this value. Wider channels result usually give
-         * better accuracy. However, the frame loss can increase too.
-         * should be one of RTT_BW_5_SUPPORT to RTT_BW_160_SUPPORT. However, need check
-         * RttCapabilities firstto verify HW support this bandwidth.
-         * Default value:RTT_BW_20_SUPPORT
-         */
-        public int bandwidth;
-
-        public RttParams() {
-            //provide initial value for RttParams
-            deviceType = RTT_PEER_TYPE_AP;
-            requestType = RTT_TYPE_ONE_SIDED;
-            numberBurst = 0;
-            numSamplesPerBurst = 8;
-            numRetriesPerMeasurementFrame  = 0;
-            numRetriesPerFTMR = 0;
-            burstTimeout = 15;
-            preamble = PREAMBLE_HT;
-            bandwidth = RTT_BW_20_SUPPORT;
-        }
-
-        /**
-         * {@hide}
-         */
-        public String toString() {
-            StringBuilder sb = new StringBuilder();
-            sb.append("deviceType=" + deviceType);
-            sb.append(", requestType=" + requestType);
-            sb.append(", secure=" + secure);
-            sb.append(", bssid=" + bssid);
-            sb.append(", frequency=" + frequency);
-            sb.append(", channelWidth=" + channelWidth);
-            sb.append(", centerFreq0=" + centerFreq0);
-            sb.append(", centerFreq1=" + centerFreq1);
-            sb.append(", num_samples=" + num_samples);
-            sb.append(", num_retries=" + num_retries);
-            sb.append(", numberBurst=" + numberBurst);
-            sb.append(", interval=" + interval);
-            sb.append(", numSamplesPerBurst=" + numSamplesPerBurst);
-            sb.append(", numRetriesPerMeasurementFrame=" + numRetriesPerMeasurementFrame);
-            sb.append(", numRetriesPerFTMR=" + numRetriesPerFTMR);
-            sb.append(", LCIRequest=" + LCIRequest);
-            sb.append(", LCRRequest=" + LCRRequest);
-            sb.append(", burstTimeout=" + burstTimeout);
-            sb.append(", preamble=" + preamble);
-            sb.append(", bandwidth=" + bandwidth);
-            return sb.toString();
-        }
-    }
-
-    /** pseudo-private class used to parcel arguments */
-    @Deprecated
-    public static class ParcelableRttParams implements Parcelable {
-
-        @NonNull
-        public RttParams mParams[];
-
-        /**
-         * @hide
-         */
-        @VisibleForTesting
-        public ParcelableRttParams(RttParams[] params) {
-            mParams = (params == null ? new RttParams[0] : params);
-        }
-
-        /** Implement the Parcelable interface {@hide} */
-        @Override
-        public int describeContents() {
-            return 0;
-        }
-
-        /** Implement the Parcelable interface {@hide} */
-        @Override
-        public void writeToParcel(Parcel dest, int flags) {
-            dest.writeInt(mParams.length);
-
-            for (RttParams params : mParams) {
-                dest.writeInt(params.deviceType);
-                dest.writeInt(params.requestType);
-                dest.writeByte(params.secure ? (byte) 1 : 0);
-                dest.writeString(params.bssid);
-                dest.writeInt(params.channelWidth);
-                dest.writeInt(params.frequency);
-                dest.writeInt(params.centerFreq0);
-                dest.writeInt(params.centerFreq1);
-                dest.writeInt(params.numberBurst);
-                dest.writeInt(params.interval);
-                dest.writeInt(params.numSamplesPerBurst);
-                dest.writeInt(params.numRetriesPerMeasurementFrame);
-                dest.writeInt(params.numRetriesPerFTMR);
-                dest.writeInt(params.LCIRequest ? 1 : 0);
-                dest.writeInt(params.LCRRequest ? 1 : 0);
-                dest.writeInt(params.burstTimeout);
-                dest.writeInt(params.preamble);
-                dest.writeInt(params.bandwidth);
-            }
-        }
-
-        /** Implement the Parcelable interface {@hide} */
-        public static final @android.annotation.NonNull Creator<ParcelableRttParams> CREATOR =
-                new Creator<ParcelableRttParams>() {
-                    @Override
-                    public ParcelableRttParams createFromParcel(Parcel in) {
-
-                        int num = in.readInt();
-                        RttParams params[] = new RttParams[num];
-                        for (int i = 0; i < num; i++) {
-                            params[i] = new RttParams();
-                            params[i].deviceType = in.readInt();
-                            params[i].requestType = in.readInt();
-                            params[i].secure = (in.readByte() != 0);
-                            params[i].bssid = in.readString();
-                            params[i].channelWidth = in.readInt();
-                            params[i].frequency = in.readInt();
-                            params[i].centerFreq0 = in.readInt();
-                            params[i].centerFreq1 = in.readInt();
-                            params[i].numberBurst = in.readInt();
-                            params[i].interval = in.readInt();
-                            params[i].numSamplesPerBurst = in.readInt();
-                            params[i].numRetriesPerMeasurementFrame = in.readInt();
-                            params[i].numRetriesPerFTMR = in.readInt();
-                            params[i].LCIRequest = (in.readInt() == 1);
-                            params[i].LCRRequest = (in.readInt() == 1);
-                            params[i].burstTimeout = in.readInt();
-                            params[i].preamble = in.readInt();
-                            params[i].bandwidth = in.readInt();
-                        }
-
-                        ParcelableRttParams parcelableParams = new ParcelableRttParams(params);
-                        return parcelableParams;
-                    }
-
-                    @Override
-                    public ParcelableRttParams[] newArray(int size) {
-                        return new ParcelableRttParams[size];
-                    }
-                };
-    }
-
-    @Deprecated
-    public static class WifiInformationElement {
-        /** Information Element ID 0xFF means element is invalid. */
-        public byte id;
-        public byte[] data;
-    }
-    /** specifies RTT results */
-    @Deprecated
-    public static class RttResult {
-        /** mac address of the device being ranged. */
-        public String bssid;
-
-        /** # of burst for this measurement. */
-        public int burstNumber;
-
-        /** total number of measurement frames attempted in this measurement. */
-        public int measurementFrameNumber;
-
-        /** total successful number of measurement frames in this measurement. */
-        public int successMeasurementFrameNumber;
-
-        /**
-         * Maximum number of frames per burst supported by peer. Two side RTT only
-         * Valid only if less than request
-         */
-        public int frameNumberPerBurstPeer;
-
-        /** status of the request */
-        public int status;
-
-        /**
-         * type of the request used
-         * @deprecated Use {@link android.net.wifi.RttManager.RttResult#measurementType}
-         */
-        @Deprecated
-        public int requestType;
-
-        /** RTT measurement method type used, should be one of RTT_TYPE_ONE_SIDED or
-         *  RTT_TYPE_TWO_SIDED.
-         */
-        public int measurementType;
-
-        /**
-         * only valid when status ==  RTT_STATUS_FAIL_BUSY_TRY_LATER
-         * please retry RTT measurement after this duration since peer indicate busy at ths moment
-         *  Unit S  Range:1-31
-         */
-        public int retryAfterDuration;
-
-        /** timestamp of completion, in microsecond since boot. */
-        public long ts;
-
-        /** average RSSI observed, unit of 0.5 dB. */
-        public int rssi;
-
-        /**
-         * RSSI spread (i.e. max - min)
-         * @deprecated Use {@link android.net.wifi.RttManager.RttResult#rssiSpread} API.
-         */
-        @Deprecated
-        public int rssi_spread;
-
-        /**RSSI spread (i.e. max - min), unit of 0.5 dB. */
-        public int rssiSpread;
-
-        /**
-         * average transmit rate
-         * @deprecated Use {@link android.net.wifi.RttManager.RttResult#txRate} API.
-         */
-        @Deprecated
-        public int tx_rate;
-
-        /** average transmit rate. Unit (kbps). */
-        public int txRate;
-
-        /** average receiving rate Unit (kbps). */
-        public int rxRate;
-
-       /**
-        * average round trip time in nano second
-        * @deprecated  Use {@link android.net.wifi.RttManager.RttResult#rtt} API.
-        */
-        @Deprecated
-        public long rtt_ns;
-
-        /** average round trip time in picoseconds. */
-        public long rtt;
-
-        /**
-         * standard deviation observed in round trip time
-         * @deprecated Use {@link android.net.wifi.RttManager.RttResult#rttStandardDeviation} API.
-         */
-        @Deprecated
-        public long rtt_sd_ns;
-
-        /** standard deviation of RTT in picoseconds. */
-        public long rttStandardDeviation;
-
-        /**
-         * spread (i.e. max - min) round trip time
-         * @deprecated Use {@link android.net.wifi.RttManager.RttResult#rttSpread} API.
-         */
-        @Deprecated
-        public long rtt_spread_ns;
-
-        /** spread (i.e. max - min) RTT in picoseconds. */
-        public long rttSpread;
-
-        /**
-         * average distance in centimeter, computed based on rtt_ns
-         * @deprecated use {@link android.net.wifi.RttManager.RttResult#distance} API.
-         */
-        @Deprecated
-        public int distance_cm;
-
-        /** average distance in cm, computed based on rtt. */
-        public int distance;
-
-        /**
-         * standard deviation observed in distance
-         * @deprecated
-         * Use {@link .android.net.wifi.RttManager.RttResult#distanceStandardDeviation} API.
-         */
-        @Deprecated
-        public int distance_sd_cm;
-
-        /** standard deviation observed in distance in cm. */
-        public int distanceStandardDeviation;
-
-        /**
-         * spread (i.e. max - min) distance
-         * @deprecated Use {@link android.net.wifi.RttManager.RttResult#distanceSpread} API.
-         */
-        @Deprecated
-        public int distance_spread_cm;
-
-        /** spread (i.e. max - min) distance in cm. */
-        public int distanceSpread;
-
-        /** the duration of this measurement burst, unit ms. */
-        public int burstDuration;
-
-        /** Burst number supported by peer after negotiation, 2side RTT only*/
-        public int negotiatedBurstNum;
-
-        /** LCI information Element, only available for double side RTT. */
-        public WifiInformationElement LCI;
-
-        /** LCR information Element, only available to double side RTT. */
-        public WifiInformationElement LCR;
-
-        /**
-         * Whether the secure RTT protocol was used for ranging.
-         */
-        public boolean secure;
-    }
-
-
-    /** pseudo-private class used to parcel results. */
-    @Deprecated
-    public static class ParcelableRttResults implements Parcelable {
-
-        public RttResult mResults[];
-
-        public ParcelableRttResults(RttResult[] results) {
-            mResults = results;
-        }
-
-        /**
-         * {@hide}
-         */
-        public String toString() {
-            StringBuilder sb = new StringBuilder();
-            for (int i = 0; i < mResults.length; ++i) {
-                sb.append("[" + i + "]: ");
-                sb.append("bssid=" + mResults[i].bssid);
-                sb.append(", burstNumber=" + mResults[i].burstNumber);
-                sb.append(", measurementFrameNumber=" + mResults[i].measurementFrameNumber);
-                sb.append(", successMeasurementFrameNumber="
-                        + mResults[i].successMeasurementFrameNumber);
-                sb.append(", frameNumberPerBurstPeer=" + mResults[i].frameNumberPerBurstPeer);
-                sb.append(", status=" + mResults[i].status);
-                sb.append(", requestType=" + mResults[i].requestType);
-                sb.append(", measurementType=" + mResults[i].measurementType);
-                sb.append(", retryAfterDuration=" + mResults[i].retryAfterDuration);
-                sb.append(", ts=" + mResults[i].ts);
-                sb.append(", rssi=" + mResults[i].rssi);
-                sb.append(", rssi_spread=" + mResults[i].rssi_spread);
-                sb.append(", rssiSpread=" + mResults[i].rssiSpread);
-                sb.append(", tx_rate=" + mResults[i].tx_rate);
-                sb.append(", txRate=" + mResults[i].txRate);
-                sb.append(", rxRate=" + mResults[i].rxRate);
-                sb.append(", rtt_ns=" + mResults[i].rtt_ns);
-                sb.append(", rtt=" + mResults[i].rtt);
-                sb.append(", rtt_sd_ns=" + mResults[i].rtt_sd_ns);
-                sb.append(", rttStandardDeviation=" + mResults[i].rttStandardDeviation);
-                sb.append(", rtt_spread_ns=" + mResults[i].rtt_spread_ns);
-                sb.append(", rttSpread=" + mResults[i].rttSpread);
-                sb.append(", distance_cm=" + mResults[i].distance_cm);
-                sb.append(", distance=" + mResults[i].distance);
-                sb.append(", distance_sd_cm=" + mResults[i].distance_sd_cm);
-                sb.append(", distanceStandardDeviation=" + mResults[i].distanceStandardDeviation);
-                sb.append(", distance_spread_cm=" + mResults[i].distance_spread_cm);
-                sb.append(", distanceSpread=" + mResults[i].distanceSpread);
-                sb.append(", burstDuration=" + mResults[i].burstDuration);
-                sb.append(", negotiatedBurstNum=" + mResults[i].negotiatedBurstNum);
-                sb.append(", LCI=" + mResults[i].LCI);
-                sb.append(", LCR=" + mResults[i].LCR);
-                sb.append(", secure=" + mResults[i].secure);
-            }
-            return sb.toString();
-        }
-
-        /** Implement the Parcelable interface {@hide} */
-        @Override
-        public int describeContents() {
-            return 0;
-        }
-
-        /** Implement the Parcelable interface {@hide} */
-        @Override
-        public void writeToParcel(Parcel dest, int flags) {
-            if (mResults != null) {
-                dest.writeInt(mResults.length);
-                for (RttResult result : mResults) {
-                    dest.writeString(result.bssid);
-                    dest.writeInt(result.burstNumber);
-                    dest.writeInt(result.measurementFrameNumber);
-                    dest.writeInt(result.successMeasurementFrameNumber);
-                    dest.writeInt(result.frameNumberPerBurstPeer);
-                    dest.writeInt(result.status);
-                    dest.writeInt(result.measurementType);
-                    dest.writeInt(result.retryAfterDuration);
-                    dest.writeLong(result.ts);
-                    dest.writeInt(result.rssi);
-                    dest.writeInt(result.rssiSpread);
-                    dest.writeInt(result.txRate);
-                    dest.writeLong(result.rtt);
-                    dest.writeLong(result.rttStandardDeviation);
-                    dest.writeLong(result.rttSpread);
-                    dest.writeInt(result.distance);
-                    dest.writeInt(result.distanceStandardDeviation);
-                    dest.writeInt(result.distanceSpread);
-                    dest.writeInt(result.burstDuration);
-                    dest.writeInt(result.negotiatedBurstNum);
-                    dest.writeByte(result.LCI.id);
-                    if (result.LCI.id != (byte) 0xFF) {
-                        dest.writeByte((byte)result.LCI.data.length);
-                        dest.writeByteArray(result.LCI.data);
-                    }
-                    dest.writeByte(result.LCR.id);
-                    if (result.LCR.id != (byte) 0xFF) {
-                        dest.writeByte((byte) result.LCR.data.length);
-                        dest.writeByteArray(result.LCR.data);
-                    }
-                    dest.writeByte(result.secure ? (byte) 1 : 0);
-                }
-            } else {
-                dest.writeInt(0);
-            }
-        }
-
-        /** Implement the Parcelable interface {@hide} */
-        public static final @android.annotation.NonNull Creator<ParcelableRttResults> CREATOR =
-                new Creator<ParcelableRttResults>() {
-                    @Override
-                    public ParcelableRttResults createFromParcel(Parcel in) {
-
-                        int num = in.readInt();
-
-                        if (num == 0) {
-                            return new ParcelableRttResults(null);
-                        }
-
-                        RttResult results[] = new RttResult[num];
-                        for (int i = 0; i < num; i++) {
-                            results[i] = new RttResult();
-                            results[i].bssid = in.readString();
-                            results[i].burstNumber = in.readInt();
-                            results[i].measurementFrameNumber = in.readInt();
-                            results[i].successMeasurementFrameNumber = in.readInt();
-                            results[i].frameNumberPerBurstPeer = in.readInt();
-                            results[i].status = in.readInt();
-                            results[i].measurementType = in.readInt();
-                            results[i].retryAfterDuration = in.readInt();
-                            results[i].ts = in.readLong();
-                            results[i].rssi = in.readInt();
-                            results[i].rssiSpread = in.readInt();
-                            results[i].txRate = in.readInt();
-                            results[i].rtt = in.readLong();
-                            results[i].rttStandardDeviation = in.readLong();
-                            results[i].rttSpread = in.readLong();
-                            results[i].distance = in.readInt();
-                            results[i].distanceStandardDeviation = in.readInt();
-                            results[i].distanceSpread = in.readInt();
-                            results[i].burstDuration = in.readInt();
-                            results[i].negotiatedBurstNum = in.readInt();
-                            results[i].LCI = new WifiInformationElement();
-                            results[i].LCI.id = in.readByte();
-                            if (results[i].LCI.id != (byte) 0xFF) {
-                                byte length = in.readByte();
-                                results[i].LCI.data = new byte[length];
-                                in.readByteArray(results[i].LCI.data);
-                            }
-                            results[i].LCR = new WifiInformationElement();
-                            results[i].LCR.id = in.readByte();
-                            if (results[i].LCR.id != (byte) 0xFF) {
-                                byte length = in.readByte();
-                                results[i].LCR.data = new byte[length];
-                                in.readByteArray(results[i].LCR.data);
-                            }
-                            results[i].secure = (in.readByte() != 0);
-                        }
-
-                        ParcelableRttResults parcelableResults = new ParcelableRttResults(results);
-                        return parcelableResults;
-                    }
-
-                    @Override
-                    public ParcelableRttResults[] newArray(int size) {
-                        return new ParcelableRttResults[size];
-                    }
-                };
-    }
-
-    @Deprecated
-    public static interface RttListener {
-        public void onSuccess(RttResult[] results);
-        public void onFailure(int reason, String description);
-        public void onAborted();
-    }
-
-    /**
-     * Request to start an RTT ranging
-     * <p>
-     * This method is deprecated. Please use the
-     * {@link WifiRttManager#startRanging(RangingRequest, java.util.concurrent.Executor, RangingResultCallback)}
-     * API.
-     *
-     * @param params  -- RTT request Parameters
-     * @param listener -- Call back to inform RTT result
-     * @exception throw IllegalArgumentException when params are illegal
-     *            throw IllegalStateException when RttCapabilities do not exist
-     */
-    @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
-    public void startRanging(RttParams[] params, RttListener listener) {
-        Log.i(TAG, "Send RTT request to RTT Service");
-
-        if (!mNewService.isAvailable()) {
-            listener.onFailure(REASON_NOT_AVAILABLE, "");
-            return;
-        }
-
-        RangingRequest.Builder builder = new RangingRequest.Builder();
-        for (RttParams rttParams : params) {
-            if (rttParams.deviceType != RTT_PEER_TYPE_AP) {
-                listener.onFailure(REASON_INVALID_REQUEST, "Only AP peers are supported");
-                return;
-            }
-
-            ScanResult reconstructed = new ScanResult();
-            reconstructed.BSSID = rttParams.bssid;
-            if (rttParams.requestType == RTT_TYPE_TWO_SIDED) {
-                reconstructed.setFlag(ScanResult.FLAG_80211mc_RESPONDER);
-            }
-            reconstructed.channelWidth = rttParams.channelWidth;
-            reconstructed.frequency = rttParams.frequency;
-            reconstructed.centerFreq0 = rttParams.centerFreq0;
-            reconstructed.centerFreq1 = rttParams.centerFreq1;
-            builder.addResponder(
-                    android.net.wifi.rtt.ResponderConfig.fromScanResult(reconstructed));
-        }
-        try {
-            mNewService.startRanging(builder.build(),
-                    mContext.getMainExecutor(),
-                    new RangingResultCallback() {
-                @Override
-                public void onRangingFailure(int code) {
-                    int localCode = REASON_UNSPECIFIED;
-                    if (code == STATUS_CODE_FAIL_RTT_NOT_AVAILABLE) {
-                        localCode = REASON_NOT_AVAILABLE;
-                    }
-                    listener.onFailure(localCode, "");
-                }
-
-                @Override
-                public void onRangingResults(List<RangingResult> results) {
-                    RttResult[] legacyResults = new RttResult[results.size()];
-                    int i = 0;
-                    for (RangingResult result : results) {
-                        legacyResults[i] = new RttResult();
-                        legacyResults[i].status = result.getStatus();
-                        legacyResults[i].bssid = result.getMacAddress().toString();
-                        if (result.getStatus() == RangingResult.STATUS_SUCCESS) {
-                            legacyResults[i].distance = result.getDistanceMm() / 10;
-                            legacyResults[i].distanceStandardDeviation =
-                                    result.getDistanceStdDevMm() / 10;
-                            legacyResults[i].rssi = result.getRssi() * -2;
-                            legacyResults[i].ts = result.getRangingTimestampMillis() * 1000;
-                            legacyResults[i].measurementFrameNumber =
-                                    result.getNumAttemptedMeasurements();
-                            legacyResults[i].successMeasurementFrameNumber =
-                                    result.getNumSuccessfulMeasurements();
-                        } else {
-                            // just in case legacy API needed some relatively real timestamp
-                            legacyResults[i].ts = SystemClock.elapsedRealtime() * 1000;
-                        }
-                        i++;
-                    }
-                    listener.onSuccess(legacyResults);
-                }
-            });
-        } catch (IllegalArgumentException e) {
-            Log.e(TAG, "startRanging: invalid arguments - " + e);
-            listener.onFailure(REASON_INVALID_REQUEST, e.getMessage());
-        } catch (SecurityException e) {
-            Log.e(TAG, "startRanging: security exception - " + e);
-            listener.onFailure(REASON_PERMISSION_DENIED, e.getMessage());
-        }
-    }
-
-    /**
-     * This method is deprecated and performs no function. Please use the {@link WifiRttManager}
-     * API.
-     */
-    @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
-    public void stopRanging(RttListener listener) {
-        Log.e(TAG, "stopRanging: unsupported operation - nop");
-    }
-
-    /**
-     * Callbacks for responder operations.
-     * <p>
-     * A {@link ResponderCallback} is the handle to the calling client. {@link RttManager} will keep
-     * a reference to the callback for the entire period when responder is enabled. The same
-     * callback as used in enabling responder needs to be passed for disabling responder.
-     * The client can freely destroy or reuse the callback after {@link RttManager#disableResponder}
-     * is called.
-     */
-    @Deprecated
-    public abstract static class ResponderCallback {
-        /** Callback when responder is enabled. */
-        public abstract void onResponderEnabled(ResponderConfig config);
-        /** Callback when enabling responder failed. */
-        public abstract void onResponderEnableFailure(int reason);
-        // TODO: consider adding onResponderAborted once it's supported.
-    }
-
-    /**
-     * Enable Wi-Fi RTT responder mode on the device. The enabling result will be delivered via
-     * {@code callback}.
-     * <p>
-     * Note calling this method with the same callback when the responder is already enabled won't
-     * change the responder state, a cached {@link ResponderConfig} from the last enabling will be
-     * returned through the callback.
-     * <p>
-     * This method is deprecated and will throw an {@link UnsupportedOperationException}
-     * exception. Please use the {@link WifiRttManager} API to perform a Wi-Fi Aware peer-to-peer
-     * ranging.
-     *
-     * @param callback Callback for responder enabling/disabling result.
-     * @throws IllegalArgumentException If {@code callback} is null.
-     */
-    @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
-    public void enableResponder(ResponderCallback callback) {
-        throw new UnsupportedOperationException(
-                "enableResponder is not supported in the adaptation layer");
-    }
-
-    /**
-     * Disable Wi-Fi RTT responder mode on the device. The {@code callback} needs to be the
-     * same one used in {@link #enableResponder(ResponderCallback)}.
-     * <p>
-     * Calling this method when responder isn't enabled won't have any effect. The callback can be
-     * reused for enabling responder after this method is called.
-     * <p>
-     * This method is deprecated and will throw an {@link UnsupportedOperationException}
-     * exception. Please use the {@link WifiRttManager} API to perform a Wi-Fi Aware peer-to-peer
-     * ranging.
-     *
-     * @param callback The same callback used for enabling responder.
-     * @throws IllegalArgumentException If {@code callback} is null.
-     */
-    @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
-    public void disableResponder(ResponderCallback callback) {
-        throw new UnsupportedOperationException(
-                "disableResponder is not supported in the adaptation layer");
-    }
-
-    /**
-     * Configuration used for RTT responder mode. The configuration information can be used by a
-     * peer device to range the responder.
-     *
-     * @see ScanResult
-     */
-    @Deprecated
-    public static class ResponderConfig implements Parcelable {
-
-        // TODO: make all fields final once we can get mac address from responder HAL APIs.
-        /**
-         * Wi-Fi mac address used for responder mode.
-         */
-        public String macAddress = "";
-
-        /**
-         * The primary 20 MHz frequency (in MHz) of the channel where responder is enabled.
-         * @see ScanResult#frequency
-         */
-        public int frequency;
-
-        /**
-         * Center frequency of the channel where responder is enabled on. Only in use when channel
-         * width is at least 40MHz.
-         * @see ScanResult#centerFreq0
-         */
-        public int centerFreq0;
-
-        /**
-         * Center frequency of the second segment when channel width is 80 + 80 MHz.
-         * @see ScanResult#centerFreq1
-         */
-        public int centerFreq1;
-
-        /**
-         * Width of the channel where responder is enabled on.
-         * @see ScanResult#channelWidth
-         */
-        public int channelWidth;
-
-        /**
-         * Preamble supported by responder.
-         */
-        public int preamble;
-
-        @NonNull
-        @Override
-        public String toString() {
-            StringBuilder builder = new StringBuilder();
-            builder.append("macAddress = ").append(macAddress)
-                    .append(" frequency = ").append(frequency)
-                    .append(" centerFreq0 = ").append(centerFreq0)
-                    .append(" centerFreq1 = ").append(centerFreq1)
-                    .append(" channelWidth = ").append(channelWidth)
-                    .append(" preamble = ").append(preamble);
-            return builder.toString();
-        }
-
-        @Override
-        public int describeContents() {
-            return 0;
-        }
-
-        @Override
-        public void writeToParcel(Parcel dest, int flags) {
-            dest.writeString(macAddress);
-            dest.writeInt(frequency);
-            dest.writeInt(centerFreq0);
-            dest.writeInt(centerFreq1);
-            dest.writeInt(channelWidth);
-            dest.writeInt(preamble);
-        }
-
-        /** Implement {@link Parcelable} interface */
-        public static final @android.annotation.NonNull Parcelable.Creator<ResponderConfig> CREATOR =
-                new Parcelable.Creator<ResponderConfig>() {
-            @Override
-            public ResponderConfig createFromParcel(Parcel in) {
-                ResponderConfig config = new ResponderConfig();
-                config.macAddress = in.readString();
-                config.frequency = in.readInt();
-                config.centerFreq0 = in.readInt();
-                config.centerFreq1 = in.readInt();
-                config.channelWidth = in.readInt();
-                config.preamble = in.readInt();
-                return config;
-            }
-
-            @Override
-            public ResponderConfig[] newArray(int size) {
-                return new ResponderConfig[size];
-            }
-        };
-
-    }
-
-    /* private methods */
-    public static final int BASE = Protocol.BASE_WIFI_RTT_MANAGER;
-
-    public static final int CMD_OP_START_RANGING        = BASE + 0;
-    public static final int CMD_OP_STOP_RANGING         = BASE + 1;
-    public static final int CMD_OP_FAILED               = BASE + 2;
-    public static final int CMD_OP_SUCCEEDED            = BASE + 3;
-    public static final int CMD_OP_ABORTED              = BASE + 4;
-    public static final int CMD_OP_ENABLE_RESPONDER     = BASE + 5;
-    public static final int CMD_OP_DISABLE_RESPONDER    = BASE + 6;
-    public static final int
-            CMD_OP_ENALBE_RESPONDER_SUCCEEDED           = BASE + 7;
-    public static final int
-            CMD_OP_ENALBE_RESPONDER_FAILED              = BASE + 8;
-    /** @hide */
-    public static final int CMD_OP_REG_BINDER           = BASE + 9;
-
-    private final WifiRttManager mNewService;
-    private final Context mContext;
-    private RttCapabilities mRttCapabilities;
-
-    /**
-     * Create a new WifiScanner instance.
-     * Applications will almost always want to use
-     * {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve
-     * the standard {@link android.content.Context#WIFI_RTT_SERVICE Context.WIFI_RTT_SERVICE}.
-     * @param service the new WifiRttManager service
-     *
-     * @hide
-     */
-    public RttManager(@NonNull Context context, @NonNull WifiRttManager service) {
-        mNewService = service;
-        mContext = context;
-
-        boolean rttSupported = context.getPackageManager().hasSystemFeature(
-                PackageManager.FEATURE_WIFI_RTT);
-
-        mRttCapabilities = new RttCapabilities();
-        mRttCapabilities.oneSidedRttSupported = rttSupported;
-        mRttCapabilities.twoSided11McRttSupported = rttSupported;
-        mRttCapabilities.lciSupported = false;
-        mRttCapabilities.lcrSupported = false;
-        mRttCapabilities.preambleSupported = PREAMBLE_HT | PREAMBLE_VHT;
-        mRttCapabilities.bwSupported = RTT_BW_40_SUPPORT | RTT_BW_80_SUPPORT;
-        mRttCapabilities.responderSupported = false;
-        mRttCapabilities.secureRttSupported = false;
-    }
-}
-
diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java
deleted file mode 100644
index b276f2ed..0000000
--- a/wifi/java/android/net/wifi/ScanResult.java
+++ /dev/null
@@ -1,1159 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.net.wifi.WifiAnnotations.ChannelWidth;
-import android.net.wifi.WifiAnnotations.WifiStandard;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * Describes information about a detected access point. In addition
- * to the attributes described here, the supplicant keeps track of
- * {@code quality}, {@code noise}, and {@code maxbitrate} attributes,
- * but does not currently report them to external clients.
- */
-public final class ScanResult implements Parcelable {
-    /**
-     * The network name.
-     */
-    public String SSID;
-
-    /**
-     * Ascii encoded SSID. This will replace SSID when we deprecate it. @hide
-     */
-    @UnsupportedAppUsage
-    public WifiSsid wifiSsid;
-
-    /**
-     * The address of the access point.
-     */
-    public String BSSID;
-
-    /**
-     * The HESSID from the beacon.
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public long hessid;
-
-    /**
-     * The ANQP Domain ID from the Hotspot 2.0 Indication element, if present.
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public int anqpDomainId;
-
-    /*
-     * This field is equivalent to the |flags|, rather than the |capabilities| field
-     * of the per-BSS scan results returned by WPA supplicant. See the definition of
-     * |struct wpa_bss| in wpa_supplicant/bss.h for more details.
-     */
-    /**
-     * Describes the authentication, key management, and encryption schemes
-     * supported by the access point.
-     */
-    public String capabilities;
-
-    /**
-     * @hide
-     * No security protocol.
-     */
-    @SystemApi
-    public static final int PROTOCOL_NONE = 0;
-    /**
-     * @hide
-     * Security protocol type: WPA version 1.
-     */
-    @SystemApi
-    public static final int PROTOCOL_WPA = 1;
-    /**
-     * @hide
-     * Security protocol type: RSN, for WPA version 2, and version 3.
-     */
-    @SystemApi
-    public static final int PROTOCOL_RSN = 2;
-    /**
-     * @hide
-     * Security protocol type:
-     * OSU Server-only authenticated layer 2 Encryption Network.
-     * Used for Hotspot 2.0.
-     */
-    @SystemApi
-    public static final int PROTOCOL_OSEN = 3;
-
-    /**
-     * @hide
-     * Security protocol type: WAPI.
-     */
-    @SystemApi
-    public static final int PROTOCOL_WAPI = 4;
-
-    /**
-     * @hide
-     * No security key management scheme.
-     */
-    @SystemApi
-    public static final int KEY_MGMT_NONE = 0;
-    /**
-     * @hide
-     * Security key management scheme: PSK.
-     */
-    @SystemApi
-    public static final int KEY_MGMT_PSK = 1;
-    /**
-     * @hide
-     * Security key management scheme: EAP.
-     */
-    @SystemApi
-    public static final int KEY_MGMT_EAP = 2;
-    /**
-     * @hide
-     * Security key management scheme: FT_PSK.
-     */
-    @SystemApi
-    public static final int KEY_MGMT_FT_PSK = 3;
-    /**
-     * @hide
-     * Security key management scheme: FT_EAP.
-     */
-    @SystemApi
-    public static final int KEY_MGMT_FT_EAP = 4;
-    /**
-     * @hide
-     * Security key management scheme: PSK_SHA256
-     */
-    @SystemApi
-    public static final int KEY_MGMT_PSK_SHA256 = 5;
-    /**
-     * @hide
-     * Security key management scheme: EAP_SHA256.
-     */
-    @SystemApi
-    public static final int KEY_MGMT_EAP_SHA256 = 6;
-    /**
-     * @hide
-     * Security key management scheme: OSEN.
-     * Used for Hotspot 2.0.
-     */
-    @SystemApi
-    public static final int KEY_MGMT_OSEN = 7;
-     /**
-     * @hide
-     * Security key management scheme: SAE.
-     */
-    @SystemApi
-    public static final int KEY_MGMT_SAE = 8;
-    /**
-     * @hide
-     * Security key management scheme: OWE.
-     */
-    @SystemApi
-    public static final int KEY_MGMT_OWE = 9;
-    /**
-     * @hide
-     * Security key management scheme: SUITE_B_192.
-     */
-    @SystemApi
-    public static final int KEY_MGMT_EAP_SUITE_B_192 = 10;
-    /**
-     * @hide
-     * Security key management scheme: FT_SAE.
-     */
-    @SystemApi
-    public static final int KEY_MGMT_FT_SAE = 11;
-    /**
-     * @hide
-     * Security key management scheme: OWE in transition mode.
-     */
-    @SystemApi
-    public static final int KEY_MGMT_OWE_TRANSITION = 12;
-    /**
-     * @hide
-     * Security key management scheme: WAPI_PSK.
-     */
-    @SystemApi
-    public static final int KEY_MGMT_WAPI_PSK = 13;
-    /**
-     * @hide
-     * Security key management scheme: WAPI_CERT.
-     */
-    @SystemApi
-    public static final int KEY_MGMT_WAPI_CERT = 14;
-
-    /**
-     * @hide
-     * Security key management scheme: FILS_SHA256.
-     */
-    public static final int KEY_MGMT_FILS_SHA256 = 15;
-    /**
-     * @hide
-     * Security key management scheme: FILS_SHA384.
-     */
-    public static final int KEY_MGMT_FILS_SHA384 = 16;
-    /**
-     * @hide
-     * No cipher suite.
-     */
-    @SystemApi
-    public static final int CIPHER_NONE = 0;
-    /**
-     * @hide
-     * No group addressed, only used for group data cipher.
-     */
-    @SystemApi
-    public static final int CIPHER_NO_GROUP_ADDRESSED = 1;
-    /**
-     * @hide
-     * Cipher suite: TKIP
-     */
-    @SystemApi
-    public static final int CIPHER_TKIP = 2;
-    /**
-     * @hide
-     * Cipher suite: CCMP
-     */
-    @SystemApi
-    public static final int CIPHER_CCMP = 3;
-    /**
-     * @hide
-     * Cipher suite: GCMP
-     */
-    @SystemApi
-    public static final int CIPHER_GCMP_256 = 4;
-    /**
-     * @hide
-     * Cipher suite: SMS4
-     */
-    @SystemApi
-    public static final int CIPHER_SMS4 = 5;
-
-    /**
-     * The detected signal level in dBm, also known as the RSSI.
-     *
-     * <p>Use {@link android.net.wifi.WifiManager#calculateSignalLevel} to convert this number into
-     * an absolute signal level which can be displayed to a user.
-     */
-    public int level;
-    /**
-     * The primary 20 MHz frequency (in MHz) of the channel over which the client is communicating
-     * with the access point.
-     */
-    public int frequency;
-
-   /**
-    * AP Channel bandwidth is 20 MHZ
-    */
-    public static final int CHANNEL_WIDTH_20MHZ = 0;
-   /**
-    * AP Channel bandwidth is 40 MHZ
-    */
-    public static final int CHANNEL_WIDTH_40MHZ = 1;
-   /**
-    * AP Channel bandwidth is 80 MHZ
-    */
-    public static final int CHANNEL_WIDTH_80MHZ = 2;
-   /**
-    * AP Channel bandwidth is 160 MHZ
-    */
-    public static final int CHANNEL_WIDTH_160MHZ = 3;
-   /**
-    * AP Channel bandwidth is 160 MHZ, but 80MHZ + 80MHZ
-    */
-    public static final int CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 4;
-
-    /**
-     * Wi-Fi unknown standard
-     */
-    public static final int WIFI_STANDARD_UNKNOWN = 0;
-
-    /**
-     * Wi-Fi 802.11a/b/g
-     */
-    public static final int WIFI_STANDARD_LEGACY = 1;
-
-    /**
-     * Wi-Fi 802.11n
-     */
-    public static final int WIFI_STANDARD_11N = 4;
-
-    /**
-     * Wi-Fi 802.11ac
-     */
-    public static final int WIFI_STANDARD_11AC = 5;
-
-    /**
-     * Wi-Fi 802.11ax
-     */
-    public static final int WIFI_STANDARD_11AX = 6;
-
-    /**
-     * AP wifi standard.
-     */
-    private @WifiStandard int mWifiStandard;
-
-    /**
-     * return the AP wifi standard.
-     */
-    public @WifiStandard int getWifiStandard() {
-        return mWifiStandard;
-    }
-
-    /**
-     * sets the AP wifi standard.
-     * @hide
-     */
-    public void setWifiStandard(@WifiStandard int standard) {
-        mWifiStandard = standard;
-    }
-
-    /**
-     * Convert Wi-Fi standard to string
-     */
-    private static @Nullable String wifiStandardToString(@WifiStandard int standard) {
-        switch(standard) {
-            case WIFI_STANDARD_LEGACY:
-                return "legacy";
-            case WIFI_STANDARD_11N:
-                return "11n";
-            case WIFI_STANDARD_11AC:
-                return "11ac";
-            case WIFI_STANDARD_11AX:
-                return "11ax";
-            case WIFI_STANDARD_UNKNOWN:
-                return "unknown";
-        }
-        return null;
-    }
-
-    /**
-     * AP Channel bandwidth; one of {@link #CHANNEL_WIDTH_20MHZ}, {@link #CHANNEL_WIDTH_40MHZ},
-     * {@link #CHANNEL_WIDTH_80MHZ}, {@link #CHANNEL_WIDTH_160MHZ}
-     * or {@link #CHANNEL_WIDTH_80MHZ_PLUS_MHZ}.
-     */
-    public @ChannelWidth int channelWidth;
-
-    /**
-     * Not used if the AP bandwidth is 20 MHz
-     * If the AP use 40, 80 or 160 MHz, this is the center frequency (in MHz)
-     * if the AP use 80 + 80 MHz, this is the center frequency of the first segment (in MHz)
-     */
-    public int centerFreq0;
-
-    /**
-     * Only used if the AP bandwidth is 80 + 80 MHz
-     * if the AP use 80 + 80 MHz, this is the center frequency of the second segment (in MHz)
-     */
-    public int centerFreq1;
-
-    /**
-     * @deprecated use is80211mcResponder() instead
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public boolean is80211McRTTResponder;
-
-    /**
-     * timestamp in microseconds (since boot) when
-     * this result was last seen.
-     */
-    public long timestamp;
-
-    /**
-     * Timestamp representing date when this result was last seen, in milliseconds from 1970
-     * {@hide}
-     */
-    @UnsupportedAppUsage
-    public long seen;
-
-    /**
-     * On devices with multiple hardware radio chains, this class provides metadata about
-     * each radio chain that was used to receive this scan result (probe response or beacon).
-     * {@hide}
-     */
-    public static class RadioChainInfo {
-        /** Vendor defined id for a radio chain. */
-        public int id;
-        /** Detected signal level in dBm (also known as the RSSI) on this radio chain. */
-        public int level;
-
-        @Override
-        public String toString() {
-            return "RadioChainInfo: id=" + id + ", level=" + level;
-        }
-
-        @Override
-        public boolean equals(Object otherObj) {
-            if (this == otherObj) {
-                return true;
-            }
-            if (!(otherObj instanceof RadioChainInfo)) {
-                return false;
-            }
-            RadioChainInfo other = (RadioChainInfo) otherObj;
-            return id == other.id && level == other.level;
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(id, level);
-        }
-    };
-
-    /**
-     * Information about the list of the radio chains used to receive this scan result
-     * (probe response or beacon).
-     *
-     * For Example: On devices with 2 hardware radio chains, this list could hold 1 or 2
-     * entries based on whether this scan result was received using one or both the chains.
-     * {@hide}
-     */
-    public RadioChainInfo[] radioChainInfos;
-
-    /**
-     * Status indicating the scan result does not correspond to a user's saved configuration
-     * @hide
-     * @removed
-     */
-    @SystemApi
-    public boolean untrusted;
-
-    /**
-     * Number of time autojoin used it
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public int numUsage;
-
-    /**
-     * The approximate distance to the AP in centimeter, if available.  Else
-     * {@link UNSPECIFIED}.
-     * {@hide}
-     */
-    @UnsupportedAppUsage
-    public int distanceCm;
-
-    /**
-     * The standard deviation of the distance to the access point, if available.
-     * Else {@link UNSPECIFIED}.
-     * {@hide}
-     */
-    @UnsupportedAppUsage
-    public int distanceSdCm;
-
-    /** {@hide} */
-    public static final long FLAG_PASSPOINT_NETWORK               = 0x0000000000000001;
-
-    /** {@hide} */
-    public static final long FLAG_80211mc_RESPONDER               = 0x0000000000000002;
-
-    /*
-     * These flags are specific to the ScanResult class, and are not related to the |flags|
-     * field of the per-BSS scan results from WPA supplicant.
-     */
-    /**
-     * Defines flags; such as {@link #FLAG_PASSPOINT_NETWORK}.
-     * {@hide}
-     */
-    @UnsupportedAppUsage
-    public long flags;
-
-    /**
-     * sets a flag in {@link #flags} field
-     * @param flag flag to set
-     * @hide
-     */
-    public void setFlag(long flag) {
-        flags |= flag;
-    }
-
-    /**
-     * clears a flag in {@link #flags} field
-     * @param flag flag to set
-     * @hide
-     */
-    public void clearFlag(long flag) {
-        flags &= ~flag;
-    }
-
-    public boolean is80211mcResponder() {
-        return (flags & FLAG_80211mc_RESPONDER) != 0;
-    }
-
-    public boolean isPasspointNetwork() {
-        return (flags & FLAG_PASSPOINT_NETWORK) != 0;
-    }
-
-    /**
-     * Indicates venue name (such as 'San Francisco Airport') published by access point; only
-     * available on Passpoint network and if published by access point.
-     */
-    public CharSequence venueName;
-
-    /**
-     * Indicates Passpoint operator name published by access point.
-     */
-    public CharSequence operatorFriendlyName;
-
-    /**
-     * {@hide}
-     */
-    public final static int UNSPECIFIED = -1;
-
-    /**
-     * 2.4 GHz band first channel number
-     * @hide
-     */
-    public static final int BAND_24_GHZ_FIRST_CH_NUM = 1;
-    /**
-     * 2.4 GHz band last channel number
-     * @hide
-     */
-    public static final int BAND_24_GHZ_LAST_CH_NUM = 14;
-    /**
-     * 2.4 GHz band frequency of first channel in MHz
-     * @hide
-     */
-    public static final int BAND_24_GHZ_START_FREQ_MHZ = 2412;
-    /**
-     * 2.4 GHz band frequency of last channel in MHz
-     * @hide
-     */
-    public static final int BAND_24_GHZ_END_FREQ_MHZ = 2484;
-
-    /**
-     * 5 GHz band first channel number
-     * @hide
-     */
-    public static final int BAND_5_GHZ_FIRST_CH_NUM = 32;
-    /**
-     * 5 GHz band last channel number
-     * @hide
-     */
-    public static final int BAND_5_GHZ_LAST_CH_NUM = 173;
-    /**
-     * 5 GHz band frequency of first channel in MHz
-     * @hide
-     */
-    public static final int BAND_5_GHZ_START_FREQ_MHZ = 5160;
-    /**
-     * 5 GHz band frequency of last channel in MHz
-     * @hide
-     */
-    public static final int BAND_5_GHZ_END_FREQ_MHZ = 5865;
-
-    /**
-     * 6 GHz band first channel number
-     * @hide
-     */
-    public static final int BAND_6_GHZ_FIRST_CH_NUM = 1;
-    /**
-     * 6 GHz band last channel number
-     * @hide
-     */
-    public static final int BAND_6_GHZ_LAST_CH_NUM = 233;
-    /**
-     * 6 GHz band frequency of first channel in MHz
-     * @hide
-     */
-    public static final int BAND_6_GHZ_START_FREQ_MHZ = 5955;
-    /**
-     * 6 GHz band frequency of last channel in MHz
-     * @hide
-     */
-    public static final int BAND_6_GHZ_END_FREQ_MHZ = 7115;
-
-    /**
-     * 6 GHz band operating class 136 channel 2 center frequency in MHz
-     * @hide
-     */
-    public static final int BAND_6_GHZ_OP_CLASS_136_CH_2_FREQ_MHZ = 5935;
-
-    /**
-     * Utility function to check if a frequency within 2.4 GHz band
-     * @param freqMhz frequency in MHz
-     * @return true if within 2.4GHz, false otherwise
-     *
-     * @hide
-     */
-    public static boolean is24GHz(int freqMhz) {
-        return freqMhz >= BAND_24_GHZ_START_FREQ_MHZ && freqMhz <= BAND_24_GHZ_END_FREQ_MHZ;
-    }
-
-    /**
-     * Utility function to check if a frequency within 5 GHz band
-     * @param freqMhz frequency in MHz
-     * @return true if within 5GHz, false otherwise
-     *
-     * @hide
-     */
-    public static boolean is5GHz(int freqMhz) {
-        return freqMhz >=  BAND_5_GHZ_START_FREQ_MHZ && freqMhz <= BAND_5_GHZ_END_FREQ_MHZ;
-    }
-
-    /**
-     * Utility function to check if a frequency within 6 GHz band
-     * @param freqMhz
-     * @return true if within 6GHz, false otherwise
-     *
-     * @hide
-     */
-    public static boolean is6GHz(int freqMhz) {
-        if (freqMhz == BAND_6_GHZ_OP_CLASS_136_CH_2_FREQ_MHZ) {
-            return true;
-        }
-        return (freqMhz >= BAND_6_GHZ_START_FREQ_MHZ && freqMhz <= BAND_6_GHZ_END_FREQ_MHZ);
-    }
-
-    /**
-     * Utility function to convert channel number/band to frequency in MHz
-     * @param channel number to convert
-     * @param band of channel to convert
-     * @return center frequency in Mhz of the channel, {@link UNSPECIFIED} if no match
-     *
-     * @hide
-     */
-    public static int convertChannelToFrequencyMhz(int channel, @WifiScanner.WifiBand int band) {
-        if (band == WifiScanner.WIFI_BAND_24_GHZ) {
-            // Special case
-            if (channel == 14) {
-                return 2484;
-            } else if (channel >= BAND_24_GHZ_FIRST_CH_NUM && channel <= BAND_24_GHZ_LAST_CH_NUM) {
-                return ((channel - BAND_24_GHZ_FIRST_CH_NUM) * 5) + BAND_24_GHZ_START_FREQ_MHZ;
-            } else {
-                return UNSPECIFIED;
-            }
-        }
-        if (band == WifiScanner.WIFI_BAND_5_GHZ) {
-            if (channel >= BAND_5_GHZ_FIRST_CH_NUM && channel <= BAND_5_GHZ_LAST_CH_NUM) {
-                return ((channel - BAND_5_GHZ_FIRST_CH_NUM) * 5) + BAND_5_GHZ_START_FREQ_MHZ;
-            } else {
-                return UNSPECIFIED;
-            }
-        }
-        if (band == WifiScanner.WIFI_BAND_6_GHZ) {
-            if (channel >= BAND_6_GHZ_FIRST_CH_NUM && channel <= BAND_6_GHZ_LAST_CH_NUM) {
-                if (channel == 2) {
-                    return BAND_6_GHZ_OP_CLASS_136_CH_2_FREQ_MHZ;
-                }
-                return ((channel - BAND_6_GHZ_FIRST_CH_NUM) * 5) + BAND_6_GHZ_START_FREQ_MHZ;
-            } else {
-                return UNSPECIFIED;
-            }
-        }
-        return UNSPECIFIED;
-    }
-
-    /**
-     * Utility function to convert frequency in MHz to channel number
-     * @param freqMhz frequency in MHz
-     * @return channel number associated with given frequency, {@link UNSPECIFIED} if no match
-     *
-     * @hide
-     */
-    public static int convertFrequencyMhzToChannel(int freqMhz) {
-        // Special case
-        if (freqMhz == 2484) {
-            return 14;
-        } else if (is24GHz(freqMhz)) {
-            return (freqMhz - BAND_24_GHZ_START_FREQ_MHZ) / 5 + BAND_24_GHZ_FIRST_CH_NUM;
-        } else if (is5GHz(freqMhz)) {
-            return ((freqMhz - BAND_5_GHZ_START_FREQ_MHZ) / 5) + BAND_5_GHZ_FIRST_CH_NUM;
-        } else if (is6GHz(freqMhz)) {
-            if (freqMhz == BAND_6_GHZ_OP_CLASS_136_CH_2_FREQ_MHZ) {
-                return 2;
-            }
-            return ((freqMhz - BAND_6_GHZ_START_FREQ_MHZ) / 5) + BAND_6_GHZ_FIRST_CH_NUM;
-        }
-
-        return UNSPECIFIED;
-    }
-
-    /**
-     * @hide
-     */
-    public boolean is24GHz() {
-        return ScanResult.is24GHz(frequency);
-    }
-
-    /**
-     * @hide
-     */
-    public boolean is5GHz() {
-        return ScanResult.is5GHz(frequency);
-    }
-
-    /**
-     * @hide
-     */
-    public boolean is6GHz() {
-        return ScanResult.is6GHz(frequency);
-    }
-
-    /**
-     *  @hide
-     * anqp lines from supplicant BSS response
-     */
-    @UnsupportedAppUsage
-    public List<String> anqpLines;
-
-    /**
-     * information elements from beacon.
-     */
-    public static class InformationElement {
-        /** @hide */
-        @UnsupportedAppUsage
-        public static final int EID_SSID = 0;
-        /** @hide */
-        @UnsupportedAppUsage
-        public static final int EID_SUPPORTED_RATES = 1;
-        /** @hide */
-        @UnsupportedAppUsage
-        public static final int EID_TIM = 5;
-        /** @hide */
-        @UnsupportedAppUsage
-        public static final int EID_BSS_LOAD = 11;
-        /** @hide */
-        @UnsupportedAppUsage
-        public static final int EID_ERP = 42;
-        /** @hide */
-        public static final int EID_HT_CAPABILITIES = 45;
-        /** @hide */
-        @UnsupportedAppUsage
-        public static final int EID_RSN = 48;
-        /** @hide */
-        @UnsupportedAppUsage
-        public static final int EID_EXTENDED_SUPPORTED_RATES = 50;
-        /** @hide */
-        @UnsupportedAppUsage
-        public static final int EID_HT_OPERATION = 61;
-        /** @hide */
-        @UnsupportedAppUsage
-        public static final int EID_INTERWORKING = 107;
-        /** @hide */
-        @UnsupportedAppUsage
-        public static final int EID_ROAMING_CONSORTIUM = 111;
-        /** @hide */
-        @UnsupportedAppUsage
-        public static final int EID_EXTENDED_CAPS = 127;
-        /** @hide */
-        public static final int EID_VHT_CAPABILITIES = 191;
-        /** @hide */
-        @UnsupportedAppUsage
-        public static final int EID_VHT_OPERATION = 192;
-        /** @hide */
-        @UnsupportedAppUsage
-        public static final int EID_VSA = 221;
-        /** @hide */
-        public static final int EID_EXTENSION_PRESENT = 255;
-
-        // Extension IDs
-        /** @hide */
-        public static final int EID_EXT_HE_CAPABILITIES = 35;
-        /** @hide */
-        public static final int EID_EXT_HE_OPERATION = 36;
-
-        /** @hide */
-        @UnsupportedAppUsage
-        public int id;
-        /** @hide */
-        public int idExt;
-
-        /** @hide */
-        @UnsupportedAppUsage
-        public byte[] bytes;
-
-        /** @hide */
-        public InformationElement() {
-        }
-
-        public InformationElement(@NonNull InformationElement rhs) {
-            this.id = rhs.id;
-            this.idExt = rhs.idExt;
-            this.bytes = rhs.bytes.clone();
-        }
-
-        /**
-         * The element ID of the information element. Defined in the IEEE 802.11-2016 spec
-         * Table 9-77.
-         */
-        public int getId() {
-            return id;
-        }
-
-        /**
-         * The element ID Extension of the information element. Defined in the IEEE 802.11-2016 spec
-         * Table 9-77.
-         */
-        public int getIdExt() {
-            return idExt;
-        }
-
-        /**
-         * Get the specific content of the information element.
-         */
-        @NonNull
-        public ByteBuffer getBytes() {
-            return ByteBuffer.wrap(bytes).asReadOnlyBuffer();
-        }
-    }
-
-    /**
-     * information elements found in the beacon.
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public InformationElement[] informationElements;
-    /**
-     * Get all information elements found in the beacon.
-     */
-    @NonNull
-    public List<InformationElement> getInformationElements() {
-        return Collections.unmodifiableList(Arrays.asList(informationElements));
-    }
-
-    /** ANQP response elements.
-     * @hide
-     */
-    public AnqpInformationElement[] anqpElements;
-
-    /** {@hide} */
-    public ScanResult(WifiSsid wifiSsid, String BSSID, long hessid, int anqpDomainId,
-            byte[] osuProviders, String caps, int level, int frequency, long tsf) {
-        this.wifiSsid = wifiSsid;
-        this.SSID = (wifiSsid != null) ? wifiSsid.toString() : WifiManager.UNKNOWN_SSID;
-        this.BSSID = BSSID;
-        this.hessid = hessid;
-        this.anqpDomainId = anqpDomainId;
-        if (osuProviders != null) {
-            this.anqpElements = new AnqpInformationElement[1];
-            this.anqpElements[0] =
-                    new AnqpInformationElement(AnqpInformationElement.HOTSPOT20_VENDOR_ID,
-                            AnqpInformationElement.HS_OSU_PROVIDERS, osuProviders);
-        }
-        this.capabilities = caps;
-        this.level = level;
-        this.frequency = frequency;
-        this.timestamp = tsf;
-        this.distanceCm = UNSPECIFIED;
-        this.distanceSdCm = UNSPECIFIED;
-        this.channelWidth = UNSPECIFIED;
-        this.centerFreq0 = UNSPECIFIED;
-        this.centerFreq1 = UNSPECIFIED;
-        this.flags = 0;
-        this.radioChainInfos = null;
-        this.mWifiStandard = WIFI_STANDARD_UNKNOWN;
-    }
-
-    /** {@hide} */
-    public ScanResult(WifiSsid wifiSsid, String BSSID, String caps, int level, int frequency,
-            long tsf, int distCm, int distSdCm) {
-        this.wifiSsid = wifiSsid;
-        this.SSID = (wifiSsid != null) ? wifiSsid.toString() : WifiManager.UNKNOWN_SSID;
-        this.BSSID = BSSID;
-        this.capabilities = caps;
-        this.level = level;
-        this.frequency = frequency;
-        this.timestamp = tsf;
-        this.distanceCm = distCm;
-        this.distanceSdCm = distSdCm;
-        this.channelWidth = UNSPECIFIED;
-        this.centerFreq0 = UNSPECIFIED;
-        this.centerFreq1 = UNSPECIFIED;
-        this.flags = 0;
-        this.radioChainInfos = null;
-        this.mWifiStandard = WIFI_STANDARD_UNKNOWN;
-    }
-
-    /** {@hide} */
-    public ScanResult(String Ssid, String BSSID, long hessid, int anqpDomainId, String caps,
-            int level, int frequency,
-            long tsf, int distCm, int distSdCm, int channelWidth, int centerFreq0, int centerFreq1,
-            boolean is80211McRTTResponder) {
-        this.SSID = Ssid;
-        this.BSSID = BSSID;
-        this.hessid = hessid;
-        this.anqpDomainId = anqpDomainId;
-        this.capabilities = caps;
-        this.level = level;
-        this.frequency = frequency;
-        this.timestamp = tsf;
-        this.distanceCm = distCm;
-        this.distanceSdCm = distSdCm;
-        this.channelWidth = channelWidth;
-        this.centerFreq0 = centerFreq0;
-        this.centerFreq1 = centerFreq1;
-        if (is80211McRTTResponder) {
-            this.flags = FLAG_80211mc_RESPONDER;
-        } else {
-            this.flags = 0;
-        }
-        this.radioChainInfos = null;
-        this.mWifiStandard = WIFI_STANDARD_UNKNOWN;
-    }
-
-    /** {@hide} */
-    public ScanResult(WifiSsid wifiSsid, String Ssid, String BSSID, long hessid, int anqpDomainId,
-                  String caps, int level,
-                  int frequency, long tsf, int distCm, int distSdCm, int channelWidth,
-                  int centerFreq0, int centerFreq1, boolean is80211McRTTResponder) {
-        this(Ssid, BSSID, hessid, anqpDomainId, caps, level, frequency, tsf, distCm,
-                distSdCm, channelWidth, centerFreq0, centerFreq1, is80211McRTTResponder);
-        this.wifiSsid = wifiSsid;
-    }
-
-    /** copy constructor */
-    public ScanResult(@NonNull ScanResult source) {
-        if (source != null) {
-            wifiSsid = source.wifiSsid;
-            SSID = source.SSID;
-            BSSID = source.BSSID;
-            hessid = source.hessid;
-            anqpDomainId = source.anqpDomainId;
-            informationElements = source.informationElements;
-            anqpElements = source.anqpElements;
-            capabilities = source.capabilities;
-            level = source.level;
-            frequency = source.frequency;
-            channelWidth = source.channelWidth;
-            centerFreq0 = source.centerFreq0;
-            centerFreq1 = source.centerFreq1;
-            timestamp = source.timestamp;
-            distanceCm = source.distanceCm;
-            distanceSdCm = source.distanceSdCm;
-            seen = source.seen;
-            untrusted = source.untrusted;
-            numUsage = source.numUsage;
-            venueName = source.venueName;
-            operatorFriendlyName = source.operatorFriendlyName;
-            flags = source.flags;
-            radioChainInfos = source.radioChainInfos;
-            this.mWifiStandard = source.mWifiStandard;
-        }
-    }
-
-    /** Construct an empty scan result. */
-    public ScanResult() {
-    }
-
-    @Override
-    public String toString() {
-        StringBuffer sb = new StringBuffer();
-        String none = "<none>";
-
-        sb.append("SSID: ")
-                .append(wifiSsid == null ? WifiManager.UNKNOWN_SSID : wifiSsid)
-                .append(", BSSID: ")
-                .append(BSSID == null ? none : BSSID)
-                .append(", capabilities: ")
-                .append(capabilities == null ? none : capabilities)
-                .append(", level: ")
-                .append(level)
-                .append(", frequency: ")
-                .append(frequency)
-                .append(", timestamp: ")
-                .append(timestamp);
-        sb.append(", distance: ").append((distanceCm != UNSPECIFIED ? distanceCm : "?")).
-                append("(cm)");
-        sb.append(", distanceSd: ").append((distanceSdCm != UNSPECIFIED ? distanceSdCm : "?")).
-                append("(cm)");
-
-        sb.append(", passpoint: ");
-        sb.append(((flags & FLAG_PASSPOINT_NETWORK) != 0) ? "yes" : "no");
-        sb.append(", ChannelBandwidth: ").append(channelWidth);
-        sb.append(", centerFreq0: ").append(centerFreq0);
-        sb.append(", centerFreq1: ").append(centerFreq1);
-        sb.append(", standard: ").append(wifiStandardToString(mWifiStandard));
-        sb.append(", 80211mcResponder: ");
-        sb.append(((flags & FLAG_80211mc_RESPONDER) != 0) ? "is supported" : "is not supported");
-        sb.append(", Radio Chain Infos: ").append(Arrays.toString(radioChainInfos));
-        return sb.toString();
-    }
-
-    /** Implement the Parcelable interface {@hide} */
-    public int describeContents() {
-        return 0;
-    }
-
-    /** Implement the Parcelable interface {@hide} */
-    public void writeToParcel(Parcel dest, int flags) {
-        if (wifiSsid != null) {
-            dest.writeInt(1);
-            wifiSsid.writeToParcel(dest, flags);
-        } else {
-            dest.writeInt(0);
-        }
-        dest.writeString(SSID);
-        dest.writeString(BSSID);
-        dest.writeLong(hessid);
-        dest.writeInt(anqpDomainId);
-        dest.writeString(capabilities);
-        dest.writeInt(level);
-        dest.writeInt(frequency);
-        dest.writeLong(timestamp);
-        dest.writeInt(distanceCm);
-        dest.writeInt(distanceSdCm);
-        dest.writeInt(channelWidth);
-        dest.writeInt(centerFreq0);
-        dest.writeInt(centerFreq1);
-        dest.writeInt(mWifiStandard);
-        dest.writeLong(seen);
-        dest.writeInt(untrusted ? 1 : 0);
-        dest.writeInt(numUsage);
-        dest.writeString((venueName != null) ? venueName.toString() : "");
-        dest.writeString((operatorFriendlyName != null) ? operatorFriendlyName.toString() : "");
-        dest.writeLong(this.flags);
-
-        if (informationElements != null) {
-            dest.writeInt(informationElements.length);
-            for (int i = 0; i < informationElements.length; i++) {
-                dest.writeInt(informationElements[i].id);
-                dest.writeInt(informationElements[i].idExt);
-                dest.writeInt(informationElements[i].bytes.length);
-                dest.writeByteArray(informationElements[i].bytes);
-            }
-        } else {
-            dest.writeInt(0);
-        }
-
-        if (anqpLines != null) {
-            dest.writeInt(anqpLines.size());
-            for (int i = 0; i < anqpLines.size(); i++) {
-                dest.writeString(anqpLines.get(i));
-            }
-        }
-        else {
-            dest.writeInt(0);
-        }
-        if (anqpElements != null) {
-            dest.writeInt(anqpElements.length);
-            for (AnqpInformationElement element : anqpElements) {
-                dest.writeInt(element.getVendorId());
-                dest.writeInt(element.getElementId());
-                dest.writeInt(element.getPayload().length);
-                dest.writeByteArray(element.getPayload());
-            }
-        } else {
-            dest.writeInt(0);
-        }
-
-        if (radioChainInfos != null) {
-            dest.writeInt(radioChainInfos.length);
-            for (int i = 0; i < radioChainInfos.length; i++) {
-                dest.writeInt(radioChainInfos[i].id);
-                dest.writeInt(radioChainInfos[i].level);
-            }
-        } else {
-            dest.writeInt(0);
-        }
-    }
-
-    /** Implement the Parcelable interface */
-    public static final @NonNull Creator<ScanResult> CREATOR =
-        new Creator<ScanResult>() {
-            public ScanResult createFromParcel(Parcel in) {
-                WifiSsid wifiSsid = null;
-                if (in.readInt() == 1) {
-                    wifiSsid = WifiSsid.CREATOR.createFromParcel(in);
-                }
-                ScanResult sr = new ScanResult(
-                        wifiSsid,
-                        in.readString(),                    /* SSID  */
-                        in.readString(),                    /* BSSID */
-                        in.readLong(),                      /* HESSID */
-                        in.readInt(),                       /* ANQP Domain ID */
-                        in.readString(),                    /* capabilities */
-                        in.readInt(),                       /* level */
-                        in.readInt(),                       /* frequency */
-                        in.readLong(),                      /* timestamp */
-                        in.readInt(),                       /* distanceCm */
-                        in.readInt(),                       /* distanceSdCm */
-                        in.readInt(),                       /* channelWidth */
-                        in.readInt(),                       /* centerFreq0 */
-                        in.readInt(),                       /* centerFreq1 */
-                        false                               /* rtt responder,
-                                                               fixed with flags below */
-                );
-
-                sr.mWifiStandard = in.readInt();
-                sr.seen = in.readLong();
-                sr.untrusted = in.readInt() != 0;
-                sr.numUsage = in.readInt();
-                sr.venueName = in.readString();
-                sr.operatorFriendlyName = in.readString();
-                sr.flags = in.readLong();
-                int n = in.readInt();
-                if (n != 0) {
-                    sr.informationElements = new InformationElement[n];
-                    for (int i = 0; i < n; i++) {
-                        sr.informationElements[i] = new InformationElement();
-                        sr.informationElements[i].id = in.readInt();
-                        sr.informationElements[i].idExt = in.readInt();
-                        int len = in.readInt();
-                        sr.informationElements[i].bytes = new byte[len];
-                        in.readByteArray(sr.informationElements[i].bytes);
-                    }
-                }
-
-                n = in.readInt();
-                if (n != 0) {
-                    sr.anqpLines = new ArrayList<String>();
-                    for (int i = 0; i < n; i++) {
-                        sr.anqpLines.add(in.readString());
-                    }
-                }
-                n = in.readInt();
-                if (n != 0) {
-                    sr.anqpElements = new AnqpInformationElement[n];
-                    for (int i = 0; i < n; i++) {
-                        int vendorId = in.readInt();
-                        int elementId = in.readInt();
-                        int len = in.readInt();
-                        byte[] payload = new byte[len];
-                        in.readByteArray(payload);
-                        sr.anqpElements[i] =
-                                new AnqpInformationElement(vendorId, elementId, payload);
-                    }
-                }
-                n = in.readInt();
-                if (n != 0) {
-                    sr.radioChainInfos = new RadioChainInfo[n];
-                    for (int i = 0; i < n; i++) {
-                        sr.radioChainInfos[i] = new RadioChainInfo();
-                        sr.radioChainInfos[i].id = in.readInt();
-                        sr.radioChainInfos[i].level = in.readInt();
-                    }
-                }
-                return sr;
-            }
-
-            public ScanResult[] newArray(int size) {
-                return new ScanResult[size];
-            }
-        };
-}
diff --git a/wifi/java/android/net/wifi/SoftApCapability.java b/wifi/java/android/net/wifi/SoftApCapability.java
deleted file mode 100644
index dcb57ec..0000000
--- a/wifi/java/android/net/wifi/SoftApCapability.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import android.annotation.LongDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Objects;
-
-/**
- * A class representing capability of the SoftAp.
- * {@see WifiManager}
- *
- * @hide
- */
-@SystemApi
-public final class SoftApCapability implements Parcelable {
-
-    /**
-     * Support for automatic channel selection in driver (ACS).
-     * Driver will auto select best channel based on interference to optimize performance.
-     *
-     * flag when {@link R.bool.config_wifi_softap_acs_supported)} is true.
-     *
-     * <p>
-     * Use {@link WifiManager.SoftApCallback#onInfoChanged(SoftApInfo)} and
-     * {@link SoftApInfo#getFrequency} and {@link SoftApInfo#getBandwidth} to get
-     * driver channel selection result.
-     */
-    public static final long SOFTAP_FEATURE_ACS_OFFLOAD = 1 << 0;
-
-    /**
-     * Support for client force disconnect.
-     * flag when {@link R.bool.config_wifi_sofap_client_force_disconnect_supported)} is true
-     *
-     * <p>
-     * Several Soft AP client control features, e.g. specifying the maximum number of
-     * Soft AP clients, only work when this feature support is present.
-     * Check feature support before invoking
-     * {@link SoftApConfiguration.Builder#setMaxNumberOfClients(int)}
-     */
-    public static final long SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT = 1 << 1;
-
-
-    /**
-     * Support for WPA3 Simultaneous Authentication of Equals (WPA3-SAE).
-     *
-     * flag when {@link config_wifi_softap_sae_supported)} is true.
-     */
-    public static final long SOFTAP_FEATURE_WPA3_SAE = 1 << 2;
-
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @LongDef(flag = true, prefix = { "SOFTAP_FEATURE_" }, value = {
-            SOFTAP_FEATURE_ACS_OFFLOAD,
-            SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT,
-            SOFTAP_FEATURE_WPA3_SAE,
-    })
-    public @interface HotspotFeatures {}
-
-    private @HotspotFeatures long mSupportedFeatures = 0;
-
-    private int mMaximumSupportedClientNumber;
-
-    /**
-     * Get the maximum supported client numbers which AP resides on.
-     */
-    public int getMaxSupportedClients() {
-        return mMaximumSupportedClientNumber;
-    }
-
-    /**
-     * Set the maximum supported client numbers which AP resides on.
-     *
-     * @param maxClient maximum supported client numbers for the softap.
-     * @hide
-     */
-    public void setMaxSupportedClients(int maxClient) {
-        mMaximumSupportedClientNumber = maxClient;
-    }
-
-    /**
-     * Returns true when all of the queried features are supported, otherwise false.
-     *
-     * @param features One or combination of the following features:
-     * {@link #SOFTAP_FEATURE_ACS_OFFLOAD}, {@link #SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT} or
-     * {@link #SOFTAP_FEATURE_WPA3_SAE}.
-     */
-    public boolean areFeaturesSupported(@HotspotFeatures long features) {
-        return (mSupportedFeatures & features) == features;
-    }
-
-    /**
-     * @hide
-     */
-    public SoftApCapability(@Nullable SoftApCapability source) {
-        if (source != null) {
-            mSupportedFeatures = source.mSupportedFeatures;
-            mMaximumSupportedClientNumber = source.mMaximumSupportedClientNumber;
-        }
-    }
-
-    /**
-     * Constructor with combination of the feature.
-     * Zero to no supported feature.
-     *
-     * @param features One or combination of the following features:
-     * {@link #SOFTAP_FEATURE_ACS_OFFLOAD}, {@link #SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT} or
-     * {@link #SOFTAP_FEATURE_WPA3_SAE}.
-     * @hide
-     */
-    public SoftApCapability(@HotspotFeatures long features) {
-        mSupportedFeatures = features;
-    }
-
-    @Override
-    /** Implement the Parcelable interface. */
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    /** Implement the Parcelable interface */
-    public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeLong(mSupportedFeatures);
-        dest.writeInt(mMaximumSupportedClientNumber);
-    }
-
-    @NonNull
-    /** Implement the Parcelable interface */
-    public static final Creator<SoftApCapability> CREATOR = new Creator<SoftApCapability>() {
-        public SoftApCapability createFromParcel(Parcel in) {
-            long supportedFeatures = in.readLong();
-            SoftApCapability capability = new SoftApCapability(supportedFeatures);
-            capability.mMaximumSupportedClientNumber = in.readInt();
-            return capability;
-        }
-
-        public SoftApCapability[] newArray(int size) {
-            return new SoftApCapability[size];
-        }
-    };
-
-    @NonNull
-    @Override
-    public String toString() {
-        StringBuilder sbuf = new StringBuilder();
-        sbuf.append("SupportedFeatures=").append(mSupportedFeatures);
-        sbuf.append("MaximumSupportedClientNumber=").append(mMaximumSupportedClientNumber);
-        return sbuf.toString();
-    }
-
-    @Override
-    public boolean equals(@NonNull Object o) {
-        if (this == o) return true;
-        if (!(o instanceof SoftApCapability)) return false;
-        SoftApCapability capability = (SoftApCapability) o;
-        return mSupportedFeatures == capability.mSupportedFeatures
-                && mMaximumSupportedClientNumber == capability.mMaximumSupportedClientNumber;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(mSupportedFeatures, mMaximumSupportedClientNumber);
-    }
-}
diff --git a/wifi/java/android/net/wifi/SoftApConfiguration.java b/wifi/java/android/net/wifi/SoftApConfiguration.java
deleted file mode 100644
index 6086f68..0000000
--- a/wifi/java/android/net/wifi/SoftApConfiguration.java
+++ /dev/null
@@ -1,968 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import android.annotation.IntDef;
-import android.annotation.IntRange;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.net.MacAddress;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.Preconditions;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * Configuration for a soft access point (a.k.a. Soft AP, SAP, Hotspot).
- *
- * This is input for the framework provided by a client app, i.e. it exposes knobs to instruct the
- * framework how it should configure a hotspot.
- *
- * System apps can use this to configure a tethered hotspot using
- * {@code WifiManager#startTetheredHotspot(SoftApConfiguration)} and
- * {@code WifiManager#setSoftApConfiguration(SoftApConfiguration)}
- * or local-only hotspot using
- * {@code WifiManager#startLocalOnlyHotspot(SoftApConfiguration, Executor,
- * WifiManager.LocalOnlyHotspotCallback)}.
- *
- * Instances of this class are immutable; use {@link SoftApConfiguration.Builder} and its methods to
- * create a new instance.
- *
- */
-public final class SoftApConfiguration implements Parcelable {
-
-    private static final String TAG = "SoftApConfiguration";
-
-    @VisibleForTesting
-    static final int PSK_MIN_LEN = 8;
-
-    @VisibleForTesting
-    static final int PSK_MAX_LEN = 63;
-
-    /**
-     * 2GHz band.
-     * @hide
-     */
-    @SystemApi
-    public static final int BAND_2GHZ = 1 << 0;
-
-    /**
-     * 5GHz band.
-     * @hide
-     */
-    @SystemApi
-    public static final int BAND_5GHZ = 1 << 1;
-
-    /**
-     * 6GHz band.
-     * @hide
-     */
-    @SystemApi
-    public static final int BAND_6GHZ = 1 << 2;
-
-    /**
-     * Device is allowed to choose the optimal band (2Ghz, 5Ghz, 6Ghz) based on device capability,
-     * operating country code and current radio conditions.
-     * @hide
-     */
-    @SystemApi
-    public static final int BAND_ANY = BAND_2GHZ | BAND_5GHZ | BAND_6GHZ;
-
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(flag = true, prefix = { "BAND_TYPE_" }, value = {
-            BAND_2GHZ,
-            BAND_5GHZ,
-            BAND_6GHZ,
-    })
-    public @interface BandType {}
-
-    private static boolean isBandValid(@BandType int band) {
-        return ((band != 0) && ((band & ~BAND_ANY) == 0));
-    }
-
-    private static final int MIN_CH_2G_BAND = 1;
-    private static final int MAX_CH_2G_BAND = 14;
-    private static final int MIN_CH_5G_BAND = 34;
-    private static final int MAX_CH_5G_BAND = 196;
-    private static final int MIN_CH_6G_BAND = 1;
-    private static final int MAX_CH_6G_BAND = 253;
-
-
-
-    private static boolean isChannelBandPairValid(int channel, @BandType int band) {
-        switch (band) {
-            case BAND_2GHZ:
-                if (channel < MIN_CH_2G_BAND || channel >  MAX_CH_2G_BAND) {
-                    return false;
-                }
-                break;
-
-            case BAND_5GHZ:
-                if (channel < MIN_CH_5G_BAND || channel >  MAX_CH_5G_BAND) {
-                    return false;
-                }
-                break;
-
-            case BAND_6GHZ:
-                if (channel < MIN_CH_6G_BAND || channel >  MAX_CH_6G_BAND) {
-                    return false;
-                }
-                break;
-            default:
-                return false;
-        }
-        return true;
-    }
-
-    /**
-     * SSID for the AP, or null for a framework-determined SSID.
-     */
-    private final @Nullable String mSsid;
-
-    /**
-     * BSSID for the AP, or null to use a framework-determined BSSID.
-     */
-    private final @Nullable MacAddress mBssid;
-
-    /**
-     * Pre-shared key for WPA2-PSK or WPA3-SAE-Transition or WPA3-SAE encryption which depends on
-     * the security type.
-     */
-    private final @Nullable String mPassphrase;
-
-    /**
-     * This is a network that does not broadcast its SSID, so an
-     * SSID-specific probe request must be used for scans.
-     */
-    private final boolean mHiddenSsid;
-
-    /**
-     * The operating band of the AP.
-     * One or combination of the following band type:
-     * {@link #BAND_2GHZ}, {@link #BAND_5GHZ}, {@link #BAND_6GHZ}.
-     */
-    private final @BandType int mBand;
-
-    /**
-     * The operating channel of the AP.
-     */
-    private final int mChannel;
-
-    /**
-     * The maximim allowed number of clients that can associate to the AP.
-     */
-    private final int mMaxNumberOfClients;
-
-    /**
-     * The operating security type of the AP.
-     * One of the following security types:
-     * {@link #SECURITY_TYPE_OPEN},
-     * {@link #SECURITY_TYPE_WPA2_PSK},
-     * {@link #SECURITY_TYPE_WPA3_SAE_TRANSITION},
-     * {@link #SECURITY_TYPE_WPA3_SAE}
-     */
-    private final @SecurityType int mSecurityType;
-
-    /**
-     * The flag to indicate client need to authorize by user
-     * when client is connecting to AP.
-     */
-    private final boolean mClientControlByUser;
-
-    /**
-     * The list of blocked client that can't associate to the AP.
-     */
-    private final List<MacAddress> mBlockedClientList;
-
-    /**
-     * The list of allowed client that can associate to the AP.
-     */
-    private final List<MacAddress> mAllowedClientList;
-
-    /**
-     * Whether auto shutdown of soft AP is enabled or not.
-     */
-    private final boolean mAutoShutdownEnabled;
-
-    /**
-     * Delay in milliseconds before shutting down soft AP when
-     * there are no connected devices.
-     */
-    private final long mShutdownTimeoutMillis;
-
-    /**
-     * THe definition of security type OPEN.
-     */
-    public static final int SECURITY_TYPE_OPEN = 0;
-
-    /**
-     * The definition of security type WPA2-PSK.
-     */
-    public static final int SECURITY_TYPE_WPA2_PSK = 1;
-
-    /**
-     * The definition of security type WPA3-SAE Transition mode.
-     */
-    public static final int SECURITY_TYPE_WPA3_SAE_TRANSITION = 2;
-
-    /**
-     * The definition of security type WPA3-SAE.
-     */
-    public static final int SECURITY_TYPE_WPA3_SAE = 3;
-
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(prefix = { "SECURITY_TYPE_" }, value = {
-        SECURITY_TYPE_OPEN,
-        SECURITY_TYPE_WPA2_PSK,
-        SECURITY_TYPE_WPA3_SAE_TRANSITION,
-        SECURITY_TYPE_WPA3_SAE,
-    })
-    public @interface SecurityType {}
-
-    /** Private constructor for Builder and Parcelable implementation. */
-    private SoftApConfiguration(@Nullable String ssid, @Nullable MacAddress bssid,
-            @Nullable String passphrase, boolean hiddenSsid, @BandType int band, int channel,
-            @SecurityType int securityType, int maxNumberOfClients, boolean shutdownTimeoutEnabled,
-            long shutdownTimeoutMillis, boolean clientControlByUser,
-            @NonNull List<MacAddress> blockedList, @NonNull List<MacAddress> allowedList) {
-        mSsid = ssid;
-        mBssid = bssid;
-        mPassphrase = passphrase;
-        mHiddenSsid = hiddenSsid;
-        mBand = band;
-        mChannel = channel;
-        mSecurityType = securityType;
-        mMaxNumberOfClients = maxNumberOfClients;
-        mAutoShutdownEnabled = shutdownTimeoutEnabled;
-        mShutdownTimeoutMillis = shutdownTimeoutMillis;
-        mClientControlByUser = clientControlByUser;
-        mBlockedClientList = new ArrayList<>(blockedList);
-        mAllowedClientList = new ArrayList<>(allowedList);
-    }
-
-    @Override
-    public boolean equals(Object otherObj) {
-        if (this == otherObj) {
-            return true;
-        }
-        if (!(otherObj instanceof SoftApConfiguration)) {
-            return false;
-        }
-        SoftApConfiguration other = (SoftApConfiguration) otherObj;
-        return Objects.equals(mSsid, other.mSsid)
-                && Objects.equals(mBssid, other.mBssid)
-                && Objects.equals(mPassphrase, other.mPassphrase)
-                && mHiddenSsid == other.mHiddenSsid
-                && mBand == other.mBand
-                && mChannel == other.mChannel
-                && mSecurityType == other.mSecurityType
-                && mMaxNumberOfClients == other.mMaxNumberOfClients
-                && mAutoShutdownEnabled == other.mAutoShutdownEnabled
-                && mShutdownTimeoutMillis == other.mShutdownTimeoutMillis
-                && mClientControlByUser == other.mClientControlByUser
-                && Objects.equals(mBlockedClientList, other.mBlockedClientList)
-                && Objects.equals(mAllowedClientList, other.mAllowedClientList);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(mSsid, mBssid, mPassphrase, mHiddenSsid,
-                mBand, mChannel, mSecurityType, mMaxNumberOfClients, mAutoShutdownEnabled,
-                mShutdownTimeoutMillis, mClientControlByUser, mBlockedClientList,
-                mAllowedClientList);
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder sbuf = new StringBuilder();
-        sbuf.append("ssid=").append(mSsid);
-        if (mBssid != null) sbuf.append(" \n bssid=").append(mBssid.toString());
-        sbuf.append(" \n Passphrase =").append(
-                TextUtils.isEmpty(mPassphrase) ? "<empty>" : "<non-empty>");
-        sbuf.append(" \n HiddenSsid =").append(mHiddenSsid);
-        sbuf.append(" \n Band =").append(mBand);
-        sbuf.append(" \n Channel =").append(mChannel);
-        sbuf.append(" \n SecurityType=").append(getSecurityType());
-        sbuf.append(" \n MaxClient=").append(mMaxNumberOfClients);
-        sbuf.append(" \n AutoShutdownEnabled=").append(mAutoShutdownEnabled);
-        sbuf.append(" \n ShutdownTimeoutMillis=").append(mShutdownTimeoutMillis);
-        sbuf.append(" \n ClientControlByUser=").append(mClientControlByUser);
-        sbuf.append(" \n BlockedClientList=").append(mBlockedClientList);
-        sbuf.append(" \n AllowedClientList=").append(mAllowedClientList);
-        return sbuf.toString();
-    }
-
-    @Override
-    public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeString(mSsid);
-        dest.writeParcelable(mBssid, flags);
-        dest.writeString(mPassphrase);
-        dest.writeBoolean(mHiddenSsid);
-        dest.writeInt(mBand);
-        dest.writeInt(mChannel);
-        dest.writeInt(mSecurityType);
-        dest.writeInt(mMaxNumberOfClients);
-        dest.writeBoolean(mAutoShutdownEnabled);
-        dest.writeLong(mShutdownTimeoutMillis);
-        dest.writeBoolean(mClientControlByUser);
-        dest.writeTypedList(mBlockedClientList);
-        dest.writeTypedList(mAllowedClientList);
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @NonNull
-    public static final Creator<SoftApConfiguration> CREATOR = new Creator<SoftApConfiguration>() {
-        @Override
-        public SoftApConfiguration createFromParcel(Parcel in) {
-            return new SoftApConfiguration(
-                    in.readString(),
-                    in.readParcelable(MacAddress.class.getClassLoader()),
-                    in.readString(), in.readBoolean(), in.readInt(), in.readInt(), in.readInt(),
-                    in.readInt(), in.readBoolean(), in.readLong(), in.readBoolean(),
-                    in.createTypedArrayList(MacAddress.CREATOR),
-                    in.createTypedArrayList(MacAddress.CREATOR));
-        }
-
-        @Override
-        public SoftApConfiguration[] newArray(int size) {
-            return new SoftApConfiguration[size];
-        }
-    };
-
-    /**
-     * Return String set to be the SSID for the AP.
-     * {@link Builder#setSsid(String)}.
-     */
-    @Nullable
-    public String getSsid() {
-        return mSsid;
-    }
-
-    /**
-     * Returns MAC address set to be BSSID for the AP.
-     * {@link Builder#setBssid(MacAddress)}.
-     */
-    @Nullable
-    public MacAddress getBssid() {
-        return mBssid;
-    }
-
-    /**
-     * Returns String set to be passphrase for current AP.
-     * {@link Builder#setPassphrase(String, int)}.
-     */
-    @Nullable
-    public String getPassphrase() {
-        return mPassphrase;
-    }
-
-    /**
-     * Returns Boolean set to be indicate hidden (true: doesn't broadcast its SSID) or
-     * not (false: broadcasts its SSID) for the AP.
-     * {@link Builder#setHiddenSsid(boolean)}.
-     */
-    public boolean isHiddenSsid() {
-        return mHiddenSsid;
-    }
-
-    /**
-     * Returns band type set to be the band for the AP.
-     *
-     * One or combination of the following band type:
-     * {@link #BAND_2GHZ}, {@link #BAND_5GHZ}, {@link #BAND_6GHZ}.
-     *
-     * {@link Builder#setBand(int)}.
-     *
-     * @hide
-     */
-    @SystemApi
-    public @BandType int getBand() {
-        return mBand;
-    }
-
-    /**
-     * Returns Integer set to be the channel for the AP.
-     * {@link Builder#setChannel(int)}.
-     *
-     * @hide
-     */
-    @SystemApi
-    public int getChannel() {
-        return mChannel;
-    }
-
-    /**
-     * Get security type params which depends on which security passphrase to set.
-     *
-     * @return One of:
-     * {@link #SECURITY_TYPE_OPEN},
-     * {@link #SECURITY_TYPE_WPA2_PSK},
-     * {@link #SECURITY_TYPE_WPA3_SAE_TRANSITION},
-     * {@link #SECURITY_TYPE_WPA3_SAE}
-     */
-    public @SecurityType int getSecurityType() {
-        return mSecurityType;
-    }
-
-    /**
-     * Returns the maximum number of clients that can associate to the AP.
-     * {@link Builder#setMaxNumberOfClients(int)}.
-     *
-     * @hide
-     */
-    @SystemApi
-    public int getMaxNumberOfClients() {
-        return mMaxNumberOfClients;
-    }
-
-    /**
-     * Returns whether auto shutdown is enabled or not.
-     * The Soft AP will shutdown when there are no devices associated to it for
-     * the timeout duration. See {@link Builder#setAutoShutdownEnabled(boolean)}.
-     *
-     * @hide
-     */
-    @SystemApi
-    public boolean isAutoShutdownEnabled() {
-        return mAutoShutdownEnabled;
-    }
-
-    /**
-     * Returns the shutdown timeout in milliseconds.
-     * The Soft AP will shutdown when there are no devices associated to it for
-     * the timeout duration. See {@link Builder#setShutdownTimeoutMillis(long)}.
-     *
-     * @hide
-     */
-    @SystemApi
-    public long getShutdownTimeoutMillis() {
-        return mShutdownTimeoutMillis;
-    }
-
-    /**
-     * Returns a flag indicating whether clients need to be pre-approved by the user.
-     * (true: authorization required) or not (false: not required).
-     * {@link Builder#setClientControlByUserEnabled(Boolean)}.
-     *
-     * @hide
-     */
-    @SystemApi
-    public boolean isClientControlByUserEnabled() {
-        return mClientControlByUser;
-    }
-
-    /**
-     * Returns List of clients which aren't allowed to associate to the AP.
-     *
-     * Clients are configured using {@link Builder#setBlockedClientList(List)}
-     *
-     * @hide
-     */
-    @NonNull
-    @SystemApi
-    public List<MacAddress> getBlockedClientList() {
-        return mBlockedClientList;
-    }
-
-    /**
-     * List of clients which are allowed to associate to the AP.
-     * Clients are configured using {@link Builder#setAllowedClientList(List)}
-     *
-     * @hide
-     */
-    @NonNull
-    @SystemApi
-    public List<MacAddress> getAllowedClientList() {
-        return mAllowedClientList;
-    }
-
-    /**
-     * Returns a {@link WifiConfiguration} representation of this {@link SoftApConfiguration}.
-     * Note that SoftApConfiguration may contain configuration which is cannot be represented
-     * by the legacy WifiConfiguration, in such cases a null will be returned.
-     *
-     * <li> SoftAp band in {@link WifiConfiguration.apBand} only supports
-     * 2GHz, 5GHz, 2GHz+5GHz bands, so conversion is limited to these bands. </li>
-     *
-     * <li> SoftAp security type in {@link WifiConfiguration.KeyMgmt} only supports
-     * NONE, WPA2_PSK, so conversion is limited to these security type.</li>
-     * @hide
-     */
-    @Nullable
-    @SystemApi
-    public WifiConfiguration toWifiConfiguration() {
-        WifiConfiguration wifiConfig = new WifiConfiguration();
-        wifiConfig.SSID = mSsid;
-        wifiConfig.preSharedKey = mPassphrase;
-        wifiConfig.hiddenSSID = mHiddenSsid;
-        wifiConfig.apChannel = mChannel;
-        switch (mSecurityType) {
-            case SECURITY_TYPE_OPEN:
-                wifiConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
-                break;
-            case SECURITY_TYPE_WPA2_PSK:
-            case SECURITY_TYPE_WPA3_SAE_TRANSITION:
-                wifiConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA2_PSK);
-                break;
-            default:
-                Log.e(TAG, "Convert fail, unsupported security type :" + mSecurityType);
-                return null;
-        }
-
-        switch (mBand) {
-            case BAND_2GHZ:
-                wifiConfig.apBand  = WifiConfiguration.AP_BAND_2GHZ;
-                break;
-            case BAND_5GHZ:
-                wifiConfig.apBand  = WifiConfiguration.AP_BAND_5GHZ;
-                break;
-            case BAND_2GHZ | BAND_5GHZ:
-                wifiConfig.apBand  = WifiConfiguration.AP_BAND_ANY;
-                break;
-            case BAND_ANY:
-                wifiConfig.apBand  = WifiConfiguration.AP_BAND_ANY;
-                break;
-            default:
-                Log.e(TAG, "Convert fail, unsupported band setting :" + mBand);
-                return null;
-        }
-        return wifiConfig;
-    }
-
-    /**
-     * Builds a {@link SoftApConfiguration}, which allows an app to configure various aspects of a
-     * Soft AP.
-     *
-     * All fields are optional. By default, SSID and BSSID are automatically chosen by the
-     * framework, and an open network is created.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final class Builder {
-        private String mSsid;
-        private MacAddress mBssid;
-        private String mPassphrase;
-        private boolean mHiddenSsid;
-        private int mBand;
-        private int mChannel;
-        private int mMaxNumberOfClients;
-        private int mSecurityType;
-        private boolean mAutoShutdownEnabled;
-        private long mShutdownTimeoutMillis;
-        private boolean mClientControlByUser;
-        private List<MacAddress> mBlockedClientList;
-        private List<MacAddress> mAllowedClientList;
-
-        /**
-         * Constructs a Builder with default values (see {@link Builder}).
-         */
-        public Builder() {
-            mSsid = null;
-            mBssid = null;
-            mPassphrase = null;
-            mHiddenSsid = false;
-            mBand = BAND_2GHZ;
-            mChannel = 0;
-            mMaxNumberOfClients = 0;
-            mSecurityType = SECURITY_TYPE_OPEN;
-            mAutoShutdownEnabled = true; // enabled by default.
-            mShutdownTimeoutMillis = 0;
-            mClientControlByUser = false;
-            mBlockedClientList = new ArrayList<>();
-            mAllowedClientList = new ArrayList<>();
-        }
-
-        /**
-         * Constructs a Builder initialized from an existing {@link SoftApConfiguration} instance.
-         */
-        public Builder(@NonNull SoftApConfiguration other) {
-            Objects.requireNonNull(other);
-
-            mSsid = other.mSsid;
-            mBssid = other.mBssid;
-            mPassphrase = other.mPassphrase;
-            mHiddenSsid = other.mHiddenSsid;
-            mBand = other.mBand;
-            mChannel = other.mChannel;
-            mMaxNumberOfClients = other.mMaxNumberOfClients;
-            mSecurityType = other.mSecurityType;
-            mAutoShutdownEnabled = other.mAutoShutdownEnabled;
-            mShutdownTimeoutMillis = other.mShutdownTimeoutMillis;
-            mClientControlByUser = other.mClientControlByUser;
-            mBlockedClientList = new ArrayList<>(other.mBlockedClientList);
-            mAllowedClientList = new ArrayList<>(other.mAllowedClientList);
-        }
-
-        /**
-         * Builds the {@link SoftApConfiguration}.
-         *
-         * @return A new {@link SoftApConfiguration}, as configured by previous method calls.
-         */
-        @NonNull
-        public SoftApConfiguration build() {
-            for (MacAddress client : mAllowedClientList) {
-                if (mBlockedClientList.contains(client)) {
-                    throw new IllegalArgumentException("A MacAddress exist in both client list");
-                }
-            }
-            return new SoftApConfiguration(mSsid, mBssid, mPassphrase,
-                    mHiddenSsid, mBand, mChannel, mSecurityType, mMaxNumberOfClients,
-                    mAutoShutdownEnabled, mShutdownTimeoutMillis, mClientControlByUser,
-                    mBlockedClientList, mAllowedClientList);
-        }
-
-        /**
-         * Specifies an SSID for the AP.
-         * <p>
-         * Null SSID only support when configure a local-only hotspot.
-         * <p>
-         * <li>If not set, defaults to null.</li>
-         *
-         * @param ssid SSID of valid Unicode characters, or null to have the SSID automatically
-         *             chosen by the framework.
-         * @return Builder for chaining.
-         * @throws IllegalArgumentException when the SSID is empty or not valid Unicode.
-         */
-        @NonNull
-        public Builder setSsid(@Nullable String ssid) {
-            if (ssid != null) {
-                Preconditions.checkStringNotEmpty(ssid);
-                Preconditions.checkArgument(StandardCharsets.UTF_8.newEncoder().canEncode(ssid));
-            }
-            mSsid = ssid;
-            return this;
-        }
-
-        /**
-         * Specifies a BSSID for the AP.
-         * <p>
-         * <li>If not set, defaults to null.</li>
-         * @param bssid BSSID, or null to have the BSSID chosen by the framework. The caller is
-         *              responsible for avoiding collisions.
-         * @return Builder for chaining.
-         * @throws IllegalArgumentException when the given BSSID is the all-zero or broadcast MAC
-         *                                  address.
-         */
-        @NonNull
-        public Builder setBssid(@Nullable MacAddress bssid) {
-            if (bssid != null) {
-                Preconditions.checkArgument(!bssid.equals(WifiManager.ALL_ZEROS_MAC_ADDRESS));
-                Preconditions.checkArgument(!bssid.equals(MacAddress.BROADCAST_ADDRESS));
-            }
-            mBssid = bssid;
-            return this;
-        }
-
-        /**
-         * Specifies that this AP should use specific security type with the given ASCII passphrase.
-         *
-         * @param securityType One of the following security types:
-         * {@link #SECURITY_TYPE_OPEN},
-         * {@link #SECURITY_TYPE_WPA2_PSK},
-         * {@link #SECURITY_TYPE_WPA3_SAE_TRANSITION},
-         * {@link #SECURITY_TYPE_WPA3_SAE}.
-         * @param passphrase The passphrase to use for sepcific {@code securityType} configuration
-         * or null with {@link #SECURITY_TYPE_OPEN}.
-         *
-         * @return Builder for chaining.
-         * @throws IllegalArgumentException when the passphrase length is invalid and
-         *         {@code securityType} is not {@link #SECURITY_TYPE_OPEN}
-         *         or non-null passphrase and {@code securityType} is
-         *         {@link #SECURITY_TYPE_OPEN}.
-         */
-        @NonNull
-        public Builder setPassphrase(@Nullable String passphrase, @SecurityType int securityType) {
-            if (securityType == SECURITY_TYPE_OPEN) {
-                if (passphrase != null) {
-                    throw new IllegalArgumentException(
-                            "passphrase should be null when security type is open");
-                }
-            } else {
-                Preconditions.checkStringNotEmpty(passphrase);
-                if (securityType == SECURITY_TYPE_WPA2_PSK
-                        || securityType == SECURITY_TYPE_WPA3_SAE_TRANSITION) {
-                    if (passphrase.length() < PSK_MIN_LEN || passphrase.length() > PSK_MAX_LEN) {
-                        throw new IllegalArgumentException(
-                                "Password size must be at least " + PSK_MIN_LEN
-                                + " and no more than " + PSK_MAX_LEN
-                                + " for WPA2_PSK and WPA3_SAE_TRANSITION Mode");
-                    }
-                }
-            }
-            mSecurityType = securityType;
-            mPassphrase = passphrase;
-            return this;
-        }
-
-        /**
-         * Specifies whether the AP is hidden (doesn't broadcast its SSID) or
-         * not (broadcasts its SSID).
-         * <p>
-         * <li>If not set, defaults to false (i.e not a hidden network).</li>
-         *
-         * @param hiddenSsid true for a hidden SSID, false otherwise.
-         * @return Builder for chaining.
-         */
-        @NonNull
-        public Builder setHiddenSsid(boolean hiddenSsid) {
-            mHiddenSsid = hiddenSsid;
-            return this;
-        }
-
-        /**
-         * Specifies the band for the AP.
-         * <p>
-         * <li>If not set, defaults to {@link #BAND_2GHZ}.</li>
-         *
-         * @param band One or combination of the following band type:
-         * {@link #BAND_2GHZ}, {@link #BAND_5GHZ}, {@link #BAND_6GHZ}.
-         * @return Builder for chaining.
-         */
-        @NonNull
-        public Builder setBand(@BandType int band) {
-            if (!isBandValid(band)) {
-                throw new IllegalArgumentException("Invalid band type");
-            }
-            mBand = band;
-            // Since band preference is specified, no specific channel is selected.
-            mChannel = 0;
-            return this;
-        }
-
-        /**
-         * Specifies the channel and associated band for the AP.
-         *
-         * The channel which AP resides on. Valid channels are country dependent.
-         * <p>
-         * The default for the channel is a the special value 0 to have the framework
-         * auto-select a valid channel from the band configured with
-         * {@link #setBand(int)}.
-         *
-         * The channel auto selection will offload to driver when
-         * {@link SoftApCapability#areFeaturesSupported(
-         * SoftApCapability.SOFTAP_FEATURE_ACS_OFFLOAD)}
-         * return true. Driver will auto select best channel which based on environment
-         * interference to get best performance. Check {@link SoftApCapability} to get more detail.
-         *
-         * Note, since 6GHz band use the same channel numbering of 2.4GHz and 5GHZ bands,
-         * the caller needs to pass the band containing the selected channel.
-         *
-         * <p>
-         * <li>If not set, defaults to 0.</li>
-         * @param channel operating channel of the AP.
-         * @param band containing this channel.
-         * @return Builder for chaining.
-         */
-        @NonNull
-        public Builder setChannel(int channel, @BandType int band) {
-            if (!isChannelBandPairValid(channel, band)) {
-                throw new IllegalArgumentException("Invalid band type");
-            }
-            mBand = band;
-            mChannel = channel;
-            return this;
-        }
-
-        /**
-         * Specifies the maximum number of clients that can associate to the AP.
-         *
-         * The maximum number of clients (STAs) which can associate to the AP.
-         * The AP will reject association from any clients above this number.
-         * Specify a value of 0 to have the framework automatically use the maximum number
-         * which the device can support (based on hardware and carrier constraints).
-         * <p>
-         * Use {@link WifiManager.SoftApCallback#onCapabilityChanged(SoftApCapability)} and
-         * {@link SoftApCapability#getMaxSupportedClients} to get the maximum number of clients
-         * which the device supports (based on hardware and carrier constraints).
-         *
-         * <p>
-         * <li>If not set, defaults to 0.</li>
-         *
-         * This method requires hardware support. If the method is used to set a
-         * non-zero {@code maxNumberOfClients} value then
-         * {@link WifiManager#startTetheredHotspot} will report error code
-         * {@link WifiManager#SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION}.
-         *
-         * <p>
-         * Use {@link WifiManager.SoftApCallback#onCapabilityChanged(SoftApCapability)} and
-         * {@link SoftApCapability#areFeaturesSupported(int)}
-         * with {@link SoftApCapability.SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT} to determine whether
-         * or not this feature is supported.
-         *
-         * @param maxNumberOfClients maximum client number of the AP.
-         * @return Builder for chaining.
-         */
-        @NonNull
-        public Builder setMaxNumberOfClients(@IntRange(from = 0) int maxNumberOfClients) {
-            if (maxNumberOfClients < 0) {
-                throw new IllegalArgumentException("maxNumberOfClients should be not negative");
-            }
-            mMaxNumberOfClients = maxNumberOfClients;
-            return this;
-        }
-
-        /**
-         * Specifies whether auto shutdown is enabled or not.
-         * The Soft AP will shut down when there are no devices connected to it for
-         * the timeout duration.
-         *
-         * <p>
-         * <li>If not set, defaults to true</li>
-         *
-         * @param enable true to enable, false to disable.
-         * @return Builder for chaining.
-         *
-         * @see #setShutdownTimeoutMillis(long)
-         */
-        @NonNull
-        public Builder setAutoShutdownEnabled(boolean enable) {
-            mAutoShutdownEnabled = enable;
-            return this;
-        }
-
-        /**
-         * Specifies the shutdown timeout in milliseconds.
-         * The Soft AP will shut down when there are no devices connected to it for
-         * the timeout duration.
-         *
-         * Specify a value of 0 to have the framework automatically use default timeout
-         * setting which defined in {@link R.integer.config_wifi_framework_soft_ap_timeout_delay}
-         *
-         * <p>
-         * <li>If not set, defaults to 0</li>
-         * <li>The shut down timeout will apply when {@link #setAutoShutdownEnabled(boolean)} is
-         * set to true</li>
-         *
-         * @param timeoutMillis milliseconds of the timeout delay.
-         * @return Builder for chaining.
-         *
-         * @see #setAutoShutdownEnabled(boolean)
-         */
-        @NonNull
-        public Builder setShutdownTimeoutMillis(@IntRange(from = 0) long timeoutMillis) {
-            if (timeoutMillis < 0) {
-                throw new IllegalArgumentException("Invalid timeout value");
-            }
-            mShutdownTimeoutMillis = timeoutMillis;
-            return this;
-        }
-
-        /**
-         * Configure the Soft AP to require manual user control of client association.
-         * If disabled (the default) then any client which isn't in the blocked list
-         * {@link #getBlockedClientList()} can associate to this Soft AP using the
-         * correct credentials until the Soft AP capacity is reached (capacity is hardware, carrier,
-         * or user limited - using {@link #setMaxNumberOfClients(int)}).
-         *
-         * If manual user control is enabled then clients will be accepted, rejected, or require
-         * a user approval based on the configuration provided by
-         * {@link #setBlockedClientList(List)} and {@link #setAllowedClientList(List)}.
-         *
-         * <p>
-         * This method requires hardware support. Hardware support can be determined using
-         * {@link WifiManager.SoftApCallback#onCapabilityChanged(SoftApCapability)} and
-         * {@link SoftApCapability#areFeaturesSupported(int)}
-         * with {@link SoftApCapability.SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT}
-         *
-         * <p>
-         * If the method is called on a device without hardware support then starting the soft AP
-         * using {@link WifiManager#startTetheredHotspot(SoftApConfiguration)} will fail with
-         * {@link WifiManager#SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION}.
-         *
-         * <p>
-         * <li>If not set, defaults to false (i.e The authoriztion is not required).</li>
-         *
-         * @param enabled true for enabling the control by user, false otherwise.
-         * @return Builder for chaining.
-         */
-        @NonNull
-        public Builder setClientControlByUserEnabled(boolean enabled) {
-            mClientControlByUser = enabled;
-            return this;
-        }
-
-
-        /**
-         * This method together with {@link setClientControlByUserEnabled(boolean)} control client
-         * connections to the AP. If client control by user is disabled using the above method then
-         * this API has no effect and clients are allowed to associate to the AP (within limit of
-         * max number of clients).
-         *
-         * If client control by user is enabled then this API configures the list of clients
-         * which are explicitly allowed. These are auto-accepted.
-         *
-         * All other clients which attempt to associate, whose MAC addresses are on neither list,
-         * are:
-         * <ul>
-         * <li>Rejected</li>
-         * <li>A callback {@link WifiManager.SoftApCallback#onBlockedClientConnecting(WifiClient)}
-         * is issued (which allows the user to add them to the allowed client list if desired).<li>
-         * </ul>
-         *
-         * @param allowedClientList list of clients which are allowed to associate to the AP
-         *                          without user pre-approval.
-         * @return Builder for chaining.
-         */
-        @NonNull
-        public Builder setAllowedClientList(@NonNull List<MacAddress> allowedClientList) {
-            mAllowedClientList = new ArrayList<>(allowedClientList);
-            return this;
-        }
-
-        /**
-         * This API configures the list of clients which are blocked and cannot associate
-         * to the Soft AP.
-         *
-         * <p>
-         * This method requires hardware support. Hardware support can be determined using
-         * {@link WifiManager.SoftApCallback#onCapabilityChanged(SoftApCapability)} and
-         * {@link SoftApCapability#areFeaturesSupported(int)}
-         * with {@link SoftApCapability.SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT}
-         *
-         * <p>
-         * If the method is called on a device without hardware support then starting the soft AP
-         * using {@link WifiManager#startTetheredHotspot(SoftApConfiguration)} will fail with
-         * {@link WifiManager#SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION}.
-         *
-         * @param blockedClientList list of clients which are not allowed to associate to the AP.
-         * @return Builder for chaining.
-         */
-        @NonNull
-        public Builder setBlockedClientList(@NonNull List<MacAddress> blockedClientList) {
-            mBlockedClientList = new ArrayList<>(blockedClientList);
-            return this;
-        }
-    }
-}
diff --git a/wifi/java/android/net/wifi/SoftApInfo.java b/wifi/java/android/net/wifi/SoftApInfo.java
deleted file mode 100644
index 24ed8ef..0000000
--- a/wifi/java/android/net/wifi/SoftApInfo.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.Objects;
-
-/**
- * A class representing information about SoftAp.
- * {@see WifiManager}
- *
- * @hide
- */
-@SystemApi
-public final class SoftApInfo implements Parcelable {
-
-    /**
-     * AP Channel bandwidth is invalid.
-     *
-     * @see #getBandwidth()
-     */
-    public static final int CHANNEL_WIDTH_INVALID = 0;
-
-    /**
-     * AP Channel bandwidth is 20 MHZ but no HT.
-     *
-     * @see #getBandwidth()
-     */
-    public static final int CHANNEL_WIDTH_20MHZ_NOHT = 1;
-
-    /**
-     * AP Channel bandwidth is 20 MHZ.
-     *
-     * @see #getBandwidth()
-     */
-    public static final int CHANNEL_WIDTH_20MHZ = 2;
-
-    /**
-     * AP Channel bandwidth is 40 MHZ.
-     *
-     * @see #getBandwidth()
-     */
-    public static final int CHANNEL_WIDTH_40MHZ = 3;
-
-    /**
-     * AP Channel bandwidth is 80 MHZ.
-     *
-     * @see #getBandwidth()
-     */
-    public static final int CHANNEL_WIDTH_80MHZ = 4;
-
-    /**
-     * AP Channel bandwidth is 160 MHZ, but 80MHZ + 80MHZ.
-     *
-     * @see #getBandwidth()
-     */
-    public static final int CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 5;
-
-    /**
-     * AP Channel bandwidth is 160 MHZ.
-     *
-     * @see #getBandwidth()
-     */
-    public static final int CHANNEL_WIDTH_160MHZ = 6;
-
-
-
-    /** The frequency which AP resides on.  */
-    private int mFrequency = 0;
-
-    @WifiAnnotations.Bandwidth
-    private int mBandwidth = CHANNEL_WIDTH_INVALID;
-
-    /**
-     * Get the frequency which AP resides on.
-     */
-    public int getFrequency() {
-        return mFrequency;
-    }
-
-    /**
-     * Set the frequency which AP resides on.
-     * @hide
-     */
-    public void setFrequency(int freq) {
-        mFrequency = freq;
-    }
-
-    /**
-     * Get AP Channel bandwidth.
-     *
-     * @return One of {@link #CHANNEL_WIDTH_20MHZ}, {@link #CHANNEL_WIDTH_40MHZ},
-     * {@link #CHANNEL_WIDTH_80MHZ}, {@link #CHANNEL_WIDTH_160MHZ},
-     * {@link #CHANNEL_WIDTH_80MHZ_PLUS_MHZ} or {@link #CHANNEL_WIDTH_INVALID}.
-     */
-    @WifiAnnotations.Bandwidth
-    public int getBandwidth() {
-        return mBandwidth;
-    }
-
-    /**
-     * Set AP Channel bandwidth.
-     * @hide
-     */
-    public void setBandwidth(@WifiAnnotations.Bandwidth int bandwidth) {
-        mBandwidth = bandwidth;
-    }
-
-    /**
-     * @hide
-     */
-    public SoftApInfo(@Nullable SoftApInfo source) {
-        if (source != null) {
-            mFrequency = source.mFrequency;
-            mBandwidth = source.mBandwidth;
-        }
-    }
-
-    /**
-     * @hide
-     */
-    public SoftApInfo() {
-    }
-
-    @Override
-    /** Implement the Parcelable interface. */
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    /** Implement the Parcelable interface */
-    public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeInt(mFrequency);
-        dest.writeInt(mBandwidth);
-    }
-
-    @NonNull
-    /** Implement the Parcelable interface */
-    public static final Creator<SoftApInfo> CREATOR = new Creator<SoftApInfo>() {
-        public SoftApInfo createFromParcel(Parcel in) {
-            SoftApInfo info = new SoftApInfo();
-            info.mFrequency = in.readInt();
-            info.mBandwidth = in.readInt();
-            return info;
-        }
-
-        public SoftApInfo[] newArray(int size) {
-            return new SoftApInfo[size];
-        }
-    };
-
-    @NonNull
-    @Override
-    public String toString() {
-        return "SoftApInfo{"
-                + "bandwidth= " + mBandwidth
-                + ",frequency= " + mFrequency
-                + '}';
-    }
-
-    @Override
-    public boolean equals(@NonNull Object o) {
-        if (this == o) return true;
-        if (!(o instanceof SoftApInfo)) return false;
-        SoftApInfo softApInfo = (SoftApInfo) o;
-        return mFrequency == softApInfo.mFrequency
-                && mBandwidth == softApInfo.mBandwidth;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(mFrequency, mBandwidth);
-    }
-}
diff --git a/wifi/java/android/net/wifi/SupplicantState.java b/wifi/java/android/net/wifi/SupplicantState.java
deleted file mode 100644
index de7e2b5..0000000
--- a/wifi/java/android/net/wifi/SupplicantState.java
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * From <code>defs.h</code> in <code>wpa_supplicant</code>.
- * <p/>
- * These enumeration values are used to indicate the current wpa_supplicant
- * state. This is more fine-grained than most users will be interested in.
- * In general, it is better to use
- * {@link android.net.NetworkInfo.State NetworkInfo.State}.
- * <p/>
- * Note, the order of these enum constants must match the numerical values of the
- * state constants in <code>defs.h</code> in <code>wpa_supplicant</code>.
- */
-public enum SupplicantState implements Parcelable {
-    /**
-     * This state indicates that client is not associated, but is likely to
-     * start looking for an access point. This state is entered when a
-     * connection is lost.
-     */
-    DISCONNECTED,
-
-    /**
-     * Interface is disabled
-     * <p/>
-     * This state is entered if the network interface is disabled.
-     * wpa_supplicant refuses any new operations that would
-     * use the radio until the interface has been enabled.
-     */
-    INTERFACE_DISABLED,
-
-    /**
-     * Inactive state (wpa_supplicant disabled).
-     * <p/>
-     * This state is entered if there are no enabled networks in the
-     * configuration. wpa_supplicant is not trying to associate with a new
-     * network and external interaction (e.g., ctrl_iface call to add or
-     * enable a network) is needed to start association.
-     */
-    INACTIVE,
-
-    /**
-     * Scanning for a network.
-     * <p/>
-     * This state is entered when wpa_supplicant starts scanning for a
-     * network.
-     */
-    SCANNING,
-
-    /**
-     * Trying to authenticate with a BSS/SSID
-     * <p/>
-     * This state is entered when wpa_supplicant has found a suitable BSS
-     * to authenticate with and the driver is configured to try to
-     * authenticate with this BSS.
-     */
-    AUTHENTICATING,
-
-    /**
-     * Trying to associate with a BSS/SSID.
-     * <p/>
-     * This state is entered when wpa_supplicant has found a suitable BSS
-     * to associate with and the driver is configured to try to associate
-     * with this BSS in ap_scan=1 mode. When using ap_scan=2 mode, this
-     * state is entered when the driver is configured to try to associate
-     * with a network using the configured SSID and security policy.
-     */
-    ASSOCIATING,
-
-    /**
-     * Association completed.
-     * <p/>
-     * This state is entered when the driver reports that association has
-     * been successfully completed with an AP. If IEEE 802.1X is used
-     * (with or without WPA/WPA2), wpa_supplicant remains in this state
-     * until the IEEE 802.1X/EAPOL authentication has been completed.
-     */
-    ASSOCIATED,
-
-    /**
-     * WPA 4-Way Key Handshake in progress.
-     * <p/>
-     * This state is entered when WPA/WPA2 4-Way Handshake is started. In
-     * case of WPA-PSK, this happens when receiving the first EAPOL-Key
-     * frame after association. In case of WPA-EAP, this state is entered
-     * when the IEEE 802.1X/EAPOL authentication has been completed.
-     */
-    FOUR_WAY_HANDSHAKE,
-
-    /**
-     * WPA Group Key Handshake in progress.
-     * <p/>
-     * This state is entered when 4-Way Key Handshake has been completed
-     * (i.e., when the supplicant sends out message 4/4) and when Group
-     * Key rekeying is started by the AP (i.e., when supplicant receives
-     * message 1/2).
-     */
-    GROUP_HANDSHAKE,
-
-    /**
-     * All authentication completed.
-     * <p/>
-     * This state is entered when the full authentication process is
-     * completed. In case of WPA2, this happens when the 4-Way Handshake is
-     * successfully completed. With WPA, this state is entered after the
-     * Group Key Handshake; with IEEE 802.1X (non-WPA) connection is
-     * completed after dynamic keys are received (or if not used, after
-     * the EAP authentication has been completed). With static WEP keys and
-     * plaintext connections, this state is entered when an association
-     * has been completed.
-     * <p/>
-     * This state indicates that the supplicant has completed its
-     * processing for the association phase and that data connection is
-     * fully configured. Note, however, that there may not be any IP
-     * address associated with the connection yet. Typically, a DHCP
-     * request needs to be sent at this point to obtain an address.
-     */
-    COMPLETED,
-
-    /**
-     * An Android-added state that is reported when a client issues an
-     * explicit DISCONNECT command. In such a case, the supplicant is
-     * not only dissociated from the current access point (as for the
-     * DISCONNECTED state above), but it also does not attempt to connect
-     * to any access point until a RECONNECT or REASSOCIATE command
-     * is issued by the client.
-     */
-    DORMANT,
-
-    /**
-     * No connection to wpa_supplicant.
-     * <p/>
-     * This is an additional pseudo-state to handle the case where
-     * wpa_supplicant is not running and/or we have not been able
-     * to establish a connection to it.
-     */
-    UNINITIALIZED,
-
-    /**
-     * A pseudo-state that should normally never be seen.
-     */
-    INVALID;
-
-    /**
-     * Returns {@code true} if the supplicant state is valid and {@code false}
-     * otherwise.
-     * @param state The supplicant state
-     * @return {@code true} if the supplicant state is valid and {@code false}
-     * otherwise.
-     */
-    public static boolean isValidState(SupplicantState state) {
-        return state != UNINITIALIZED && state != INVALID;
-    }
-
-
-    /** Supplicant associating or authenticating is considered a handshake state {@hide} */
-    public static boolean isHandshakeState(SupplicantState state) {
-        switch(state) {
-            case AUTHENTICATING:
-            case ASSOCIATING:
-            case ASSOCIATED:
-            case FOUR_WAY_HANDSHAKE:
-            case GROUP_HANDSHAKE:
-                return true;
-            case COMPLETED:
-            case DISCONNECTED:
-            case INTERFACE_DISABLED:
-            case INACTIVE:
-            case SCANNING:
-            case DORMANT:
-            case UNINITIALIZED:
-            case INVALID:
-                return false;
-            default:
-                throw new IllegalArgumentException("Unknown supplicant state");
-        }
-    }
-
-    /** @hide */
-    public static boolean isConnecting(SupplicantState state) {
-        switch(state) {
-            case AUTHENTICATING:
-            case ASSOCIATING:
-            case ASSOCIATED:
-            case FOUR_WAY_HANDSHAKE:
-            case GROUP_HANDSHAKE:
-            case COMPLETED:
-                return true;
-            case DISCONNECTED:
-            case INTERFACE_DISABLED:
-            case INACTIVE:
-            case SCANNING:
-            case DORMANT:
-            case UNINITIALIZED:
-            case INVALID:
-                return false;
-            default:
-                throw new IllegalArgumentException("Unknown supplicant state");
-        }
-    }
-
-    /** @hide */
-    public static boolean isDriverActive(SupplicantState state) {
-        switch(state) {
-            case DISCONNECTED:
-            case DORMANT:
-            case INACTIVE:
-            case AUTHENTICATING:
-            case ASSOCIATING:
-            case ASSOCIATED:
-            case SCANNING:
-            case FOUR_WAY_HANDSHAKE:
-            case GROUP_HANDSHAKE:
-            case COMPLETED:
-                return true;
-            case INTERFACE_DISABLED:
-            case UNINITIALIZED:
-            case INVALID:
-                return false;
-            default:
-                throw new IllegalArgumentException("Unknown supplicant state");
-        }
-    }
-
-    /** Implement the Parcelable interface {@hide} */
-    public int describeContents() {
-        return 0;
-    }
-
-    /** Implement the Parcelable interface {@hide} */
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeString(name());
-    }
-
-    /** Implement the Parcelable interface {@hide} */
-    public static final @android.annotation.NonNull Creator<SupplicantState> CREATOR =
-        new Creator<SupplicantState>() {
-            public SupplicantState createFromParcel(Parcel in) {
-                return SupplicantState.valueOf(in.readString());
-            }
-
-            public SupplicantState[] newArray(int size) {
-                return new SupplicantState[size];
-            }
-        };
-
-}
diff --git a/wifi/java/android/net/wifi/SynchronousExecutor.java b/wifi/java/android/net/wifi/SynchronousExecutor.java
deleted file mode 100644
index 9926b1b..0000000
--- a/wifi/java/android/net/wifi/SynchronousExecutor.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.net.wifi;
-
-import java.util.concurrent.Executor;
-
-/**
- * An executor implementation that runs synchronously on the current thread.
- * @hide
- */
-public class SynchronousExecutor implements Executor {
-    @Override
-    public void execute(Runnable r) {
-        r.run();
-    }
-}
diff --git a/wifi/java/android/net/wifi/WifiAnnotations.java b/wifi/java/android/net/wifi/WifiAnnotations.java
deleted file mode 100644
index acda7e0..0000000
--- a/wifi/java/android/net/wifi/WifiAnnotations.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import android.annotation.IntDef;
-import android.annotation.StringDef;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Wifi annotations meant to be statically linked into client modules, since they cannot be
- * exposed as @SystemApi.
- *
- * e.g. {@link IntDef}, {@link StringDef}
- *
- * @hide
- */
-public final class WifiAnnotations {
-    private WifiAnnotations() {}
-
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(prefix = {"SCAN_TYPE_"}, value = {
-            WifiScanner.SCAN_TYPE_LOW_LATENCY,
-            WifiScanner.SCAN_TYPE_LOW_POWER,
-            WifiScanner.SCAN_TYPE_HIGH_ACCURACY})
-    public @interface ScanType {}
-
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(prefix = {"WIFI_BAND_"}, value = {
-            WifiScanner.WIFI_BAND_UNSPECIFIED,
-            WifiScanner.WIFI_BAND_24_GHZ,
-            WifiScanner.WIFI_BAND_5_GHZ,
-            WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY,
-            WifiScanner.WIFI_BAND_6_GHZ})
-    public @interface WifiBandBasic {}
-
-    @IntDef(prefix = { "CHANNEL_WIDTH_" }, value = {
-            SoftApInfo.CHANNEL_WIDTH_INVALID,
-            SoftApInfo.CHANNEL_WIDTH_20MHZ_NOHT,
-            SoftApInfo.CHANNEL_WIDTH_20MHZ,
-            SoftApInfo.CHANNEL_WIDTH_40MHZ,
-            SoftApInfo.CHANNEL_WIDTH_80MHZ,
-            SoftApInfo.CHANNEL_WIDTH_80MHZ_PLUS_MHZ,
-            SoftApInfo.CHANNEL_WIDTH_160MHZ,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface Bandwidth {}
-
-    @IntDef(prefix = { "CHANNEL_WIDTH_" }, value = {
-            ScanResult.CHANNEL_WIDTH_20MHZ,
-            ScanResult.CHANNEL_WIDTH_40MHZ,
-            ScanResult.CHANNEL_WIDTH_80MHZ,
-            ScanResult.CHANNEL_WIDTH_160MHZ,
-            ScanResult.CHANNEL_WIDTH_80MHZ_PLUS_MHZ,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface ChannelWidth{}
-
-    @IntDef(prefix = { "WIFI_STANDARD_" }, value = {
-            ScanResult.WIFI_STANDARD_UNKNOWN,
-            ScanResult.WIFI_STANDARD_LEGACY,
-            ScanResult.WIFI_STANDARD_11N,
-            ScanResult.WIFI_STANDARD_11AC,
-            ScanResult.WIFI_STANDARD_11AX,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface WifiStandard{}
-
-    @IntDef(prefix = { "PROTOCOL_" }, value = {
-            ScanResult.PROTOCOL_NONE,
-            ScanResult.PROTOCOL_WPA,
-            ScanResult.PROTOCOL_RSN,
-            ScanResult.PROTOCOL_OSEN,
-            ScanResult.PROTOCOL_WAPI
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface Protocol {}
-
-    @IntDef(prefix = { "KEY_MGMT_" }, value = {
-        ScanResult.KEY_MGMT_NONE,
-        ScanResult.KEY_MGMT_PSK,
-        ScanResult.KEY_MGMT_EAP,
-        ScanResult.KEY_MGMT_FT_PSK,
-        ScanResult.KEY_MGMT_FT_EAP,
-        ScanResult.KEY_MGMT_PSK_SHA256,
-        ScanResult.KEY_MGMT_EAP_SHA256,
-        ScanResult.KEY_MGMT_OSEN,
-        ScanResult.KEY_MGMT_SAE,
-        ScanResult.KEY_MGMT_OWE,
-        ScanResult.KEY_MGMT_EAP_SUITE_B_192,
-        ScanResult.KEY_MGMT_FT_SAE,
-        ScanResult.KEY_MGMT_OWE_TRANSITION,
-        ScanResult.KEY_MGMT_WAPI_PSK,
-        ScanResult.KEY_MGMT_WAPI_CERT
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface KeyMgmt {}
-
-    @IntDef(prefix = { "CIPHER_" }, value = {
-        ScanResult.CIPHER_NONE,
-        ScanResult.CIPHER_NO_GROUP_ADDRESSED,
-        ScanResult.CIPHER_TKIP,
-        ScanResult.CIPHER_CCMP,
-        ScanResult.CIPHER_GCMP_256,
-        ScanResult.CIPHER_SMS4
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface Cipher {}
-}
diff --git a/wifi/java/android/net/wifi/WifiClient.java b/wifi/java/android/net/wifi/WifiClient.java
deleted file mode 100644
index 3794566..0000000
--- a/wifi/java/android/net/wifi/WifiClient.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.net.MacAddress;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.Objects;
-
-/** @hide */
-@SystemApi
-public final class WifiClient implements Parcelable {
-
-    private final MacAddress mMacAddress;
-
-    /**
-     * The mac address of this client.
-     */
-    @NonNull
-    public MacAddress getMacAddress() {
-        return mMacAddress;
-    }
-
-    private WifiClient(Parcel in) {
-        mMacAddress = in.readParcelable(null);
-    }
-
-    /** @hide */
-    public WifiClient(@NonNull MacAddress macAddress) {
-        Objects.requireNonNull(macAddress, "mMacAddress must not be null.");
-
-        this.mMacAddress = macAddress;
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeParcelable(mMacAddress, flags);
-    }
-
-    @NonNull
-    public static final Creator<WifiClient> CREATOR = new Creator<WifiClient>() {
-        public WifiClient createFromParcel(Parcel in) {
-            return new WifiClient(in);
-        }
-
-        public WifiClient[] newArray(int size) {
-            return new WifiClient[size];
-        }
-    };
-
-    @NonNull
-    @Override
-    public String toString() {
-        return "WifiClient{"
-                + "mMacAddress=" + mMacAddress
-                + '}';
-    }
-
-    @Override
-    public boolean equals(@NonNull Object o) {
-        if (this == o) return true;
-        if (!(o instanceof WifiClient)) return false;
-        WifiClient client = (WifiClient) o;
-        return mMacAddress.equals(client.mMacAddress);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(mMacAddress);
-    }
-}
-
-
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
deleted file mode 100644
index 70885af..0000000
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ /dev/null
@@ -1,2998 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.content.pm.PackageManager;
-import android.net.IpConfiguration;
-import android.net.IpConfiguration.ProxySettings;
-import android.net.MacAddress;
-import android.net.NetworkSpecifier;
-import android.net.ProxyInfo;
-import android.net.StaticIpConfiguration;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.SystemClock;
-import android.os.UserHandle;
-import android.telephony.TelephonyManager;
-import android.text.TextUtils;
-import android.util.Log;
-import android.util.SparseArray;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.net.module.util.MacAddressUtils;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Arrays;
-import java.util.BitSet;
-import java.util.Calendar;
-import java.util.HashMap;
-
-/**
- * A class representing a configured Wi-Fi network, including the
- * security configuration.
- *
- * @deprecated Use {@link WifiNetworkSpecifier.Builder} to create {@link NetworkSpecifier} and
- * {@link WifiNetworkSuggestion.Builder} to create {@link WifiNetworkSuggestion}. This will become a
- * system use only object in the future.
- */
-@Deprecated
-public class WifiConfiguration implements Parcelable {
-    private static final String TAG = "WifiConfiguration";
-    /**
-     * Current Version of the Backup Serializer.
-    */
-    private static final int BACKUP_VERSION = 3;
-    /** {@hide} */
-    public static final String ssidVarName = "ssid";
-    /** {@hide} */
-    public static final String bssidVarName = "bssid";
-    /** {@hide} */
-    public static final String pskVarName = "psk";
-    /** {@hide} */
-    @Deprecated
-    @UnsupportedAppUsage
-    public static final String[] wepKeyVarNames = { "wep_key0", "wep_key1", "wep_key2", "wep_key3" };
-    /** {@hide} */
-    @Deprecated
-    public static final String wepTxKeyIdxVarName = "wep_tx_keyidx";
-    /** {@hide} */
-    public static final String priorityVarName = "priority";
-    /** {@hide} */
-    public static final String hiddenSSIDVarName = "scan_ssid";
-    /** {@hide} */
-    public static final String pmfVarName = "ieee80211w";
-    /** {@hide} */
-    public static final String updateIdentiferVarName = "update_identifier";
-    /**
-     * The network ID for an invalid network.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int INVALID_NETWORK_ID = -1;
-    /** {@hide} */
-    public static final int LOCAL_ONLY_NETWORK_ID = -2;
-
-    /** {@hide} */
-    private String mPasspointManagementObjectTree;
-    /** {@hide} */
-    private static final int MAXIMUM_RANDOM_MAC_GENERATION_RETRY = 3;
-
-    /**
-     * Recognized key management schemes.
-     */
-    public static class KeyMgmt {
-        private KeyMgmt() { }
-
-        /** @hide */
-        @Retention(RetentionPolicy.SOURCE)
-        @IntDef(value = {
-                NONE,
-                WPA_PSK,
-                WPA_EAP,
-                IEEE8021X,
-                WPA2_PSK,
-                OSEN,
-                FT_PSK,
-                FT_EAP,
-                SAE,
-                OWE,
-                SUITE_B_192,
-                WPA_PSK_SHA256,
-                WPA_EAP_SHA256,
-                WAPI_PSK,
-                WAPI_CERT,
-                FILS_SHA256,
-                FILS_SHA384})
-        public @interface KeyMgmtScheme {}
-
-        /** WPA is not used; plaintext or static WEP could be used. */
-        public static final int NONE = 0;
-        /** WPA pre-shared key (requires {@code preSharedKey} to be specified). */
-        public static final int WPA_PSK = 1;
-        /** WPA using EAP authentication. Generally used with an external authentication server. */
-        public static final int WPA_EAP = 2;
-        /**
-         * IEEE 802.1X using EAP authentication and (optionally) dynamically
-         * generated WEP keys.
-         */
-        public static final int IEEE8021X = 3;
-
-        /**
-         * WPA2 pre-shared key for use with soft access point
-         * (requires {@code preSharedKey} to be specified).
-         * @hide
-         */
-        @SystemApi
-        public static final int WPA2_PSK = 4;
-        /**
-         * Hotspot 2.0 r2 OSEN:
-         * @hide
-         */
-        public static final int OSEN = 5;
-
-        /**
-         * IEEE 802.11r Fast BSS Transition with PSK authentication.
-         * @hide
-         */
-        public static final int FT_PSK = 6;
-
-        /**
-         * IEEE 802.11r Fast BSS Transition with EAP authentication.
-         * @hide
-         */
-        public static final int FT_EAP = 7;
-
-        /**
-         * Simultaneous Authentication of Equals
-         */
-        public static final int SAE = 8;
-
-        /**
-         * Opportunististic Wireless Encryption
-         */
-        public static final int OWE = 9;
-
-        /**
-         * SUITE_B_192 192 bit level
-         */
-        public static final int SUITE_B_192 = 10;
-
-        /**
-         * WPA pre-shared key with stronger SHA256-based algorithms.
-         * @hide
-         */
-        public static final int WPA_PSK_SHA256 = 11;
-
-        /**
-         * WPA using EAP authentication with stronger SHA256-based algorithms.
-         * @hide
-         */
-        public static final int WPA_EAP_SHA256 = 12;
-
-        /**
-         * WAPI pre-shared key (requires {@code preSharedKey} to be specified).
-         * @hide
-         */
-        @SystemApi
-        public static final int WAPI_PSK = 13;
-
-        /**
-         * WAPI certificate to be specified.
-         * @hide
-         */
-        @SystemApi
-        public static final int WAPI_CERT = 14;
-
-        /**
-        * IEEE 802.11ai FILS SK with SHA256
-         * @hide
-        */
-        public static final int FILS_SHA256 = 15;
-        /**
-         * IEEE 802.11ai FILS SK with SHA384:
-         * @hide
-         */
-        public static final int FILS_SHA384 = 16;
-
-        public static final String varName = "key_mgmt";
-
-        public static final String[] strings = { "NONE", "WPA_PSK", "WPA_EAP",
-                "IEEE8021X", "WPA2_PSK", "OSEN", "FT_PSK", "FT_EAP",
-                "SAE", "OWE", "SUITE_B_192", "WPA_PSK_SHA256", "WPA_EAP_SHA256",
-                "WAPI_PSK", "WAPI_CERT", "FILS_SHA256", "FILS_SHA384" };
-    }
-
-    /**
-     * Recognized security protocols.
-     */
-    public static class Protocol {
-        private Protocol() { }
-
-        /** WPA/IEEE 802.11i/D3.0
-         * @deprecated Due to security and performance limitations, use of WPA-1 networks
-         * is discouraged. WPA-2 (RSN) should be used instead. */
-        @Deprecated
-        public static final int WPA = 0;
-        /** RSN WPA2/WPA3/IEEE 802.11i */
-        public static final int RSN = 1;
-        /** HS2.0 r2 OSEN
-         * @hide
-         */
-        public static final int OSEN = 2;
-
-        /**
-         * WAPI Protocol
-         */
-        public static final int WAPI = 3;
-
-        public static final String varName = "proto";
-
-        public static final String[] strings = { "WPA", "RSN", "OSEN", "WAPI" };
-    }
-
-    /**
-     * Recognized IEEE 802.11 authentication algorithms.
-     */
-    public static class AuthAlgorithm {
-        private AuthAlgorithm() { }
-
-        /** Open System authentication (required for WPA/WPA2) */
-        public static final int OPEN = 0;
-        /** Shared Key authentication (requires static WEP keys)
-         * @deprecated Due to security and performance limitations, use of WEP networks
-         * is discouraged. */
-        @Deprecated
-        public static final int SHARED = 1;
-        /** LEAP/Network EAP (only used with LEAP) */
-        public static final int LEAP = 2;
-
-        /** SAE (Used only for WPA3-Personal) */
-        public static final int SAE = 3;
-
-        public static final String varName = "auth_alg";
-
-        public static final String[] strings = { "OPEN", "SHARED", "LEAP", "SAE" };
-    }
-
-    /**
-     * Recognized pairwise ciphers for WPA.
-     */
-    public static class PairwiseCipher {
-        private PairwiseCipher() { }
-
-        /** Use only Group keys (deprecated) */
-        public static final int NONE = 0;
-        /** Temporal Key Integrity Protocol [IEEE 802.11i/D7.0]
-         * @deprecated Due to security and performance limitations, use of WPA-1 networks
-         * is discouraged. WPA-2 (RSN) should be used instead. */
-        @Deprecated
-        public static final int TKIP = 1;
-        /** AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i/D7.0] */
-        public static final int CCMP = 2;
-        /**
-         * AES in Galois/Counter Mode
-         */
-        public static final int GCMP_256 = 3;
-        /**
-         * SMS4 cipher for WAPI
-         */
-        public static final int SMS4 = 4;
-
-        public static final String varName = "pairwise";
-
-        public static final String[] strings = { "NONE", "TKIP", "CCMP", "GCMP_256", "SMS4" };
-    }
-
-    /**
-     * Recognized group ciphers.
-     * <pre>
-     * CCMP = AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i/D7.0]
-     * TKIP = Temporal Key Integrity Protocol [IEEE 802.11i/D7.0]
-     * WEP104 = WEP (Wired Equivalent Privacy) with 104-bit key
-     * WEP40 = WEP (Wired Equivalent Privacy) with 40-bit key (original 802.11)
-     * GCMP_256 = AES in Galois/Counter Mode
-     * </pre>
-     */
-    public static class GroupCipher {
-        private GroupCipher() { }
-
-        /** WEP40 = WEP (Wired Equivalent Privacy) with 40-bit key (original 802.11)
-         * @deprecated Due to security and performance limitations, use of WEP networks
-         * is discouraged. */
-        @Deprecated
-        public static final int WEP40 = 0;
-        /** WEP104 = WEP (Wired Equivalent Privacy) with 104-bit key
-         * @deprecated Due to security and performance limitations, use of WEP networks
-         * is discouraged. */
-        @Deprecated
-        public static final int WEP104 = 1;
-        /** Temporal Key Integrity Protocol [IEEE 802.11i/D7.0] */
-        public static final int TKIP = 2;
-        /** AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i/D7.0] */
-        public static final int CCMP = 3;
-        /** Hotspot 2.0 r2 OSEN
-         * @hide
-         */
-        public static final int GTK_NOT_USED = 4;
-        /**
-         * AES in Galois/Counter Mode
-         */
-        public static final int GCMP_256 = 5;
-        /**
-         * SMS4 cipher for WAPI
-         */
-        public static final int SMS4 = 6;
-
-        public static final String varName = "group";
-
-        public static final String[] strings =
-                { /* deprecated */ "WEP40", /* deprecated */ "WEP104",
-                        "TKIP", "CCMP", "GTK_NOT_USED", "GCMP_256",
-                        "SMS4" };
-    }
-
-    /**
-     * Recognized group management ciphers.
-     * <pre>
-     * BIP_CMAC_256 = Cipher-based Message Authentication Code 256 bits
-     * BIP_GMAC_128 = Galois Message Authentication Code 128 bits
-     * BIP_GMAC_256 = Galois Message Authentication Code 256 bits
-     * </pre>
-     */
-    public static class GroupMgmtCipher {
-        private GroupMgmtCipher() { }
-
-        /** CMAC-256 = Cipher-based Message Authentication Code */
-        public static final int BIP_CMAC_256 = 0;
-
-        /** GMAC-128 = Galois Message Authentication Code */
-        public static final int BIP_GMAC_128 = 1;
-
-        /** GMAC-256 = Galois Message Authentication Code */
-        public static final int BIP_GMAC_256 = 2;
-
-        private static final String varName = "groupMgmt";
-
-        private static final String[] strings = { "BIP_CMAC_256",
-                "BIP_GMAC_128", "BIP_GMAC_256"};
-    }
-
-    /**
-     * Recognized suiteB ciphers.
-     * <pre>
-     * ECDHE_ECDSA
-     * ECDHE_RSA
-     * </pre>
-     * @hide
-     */
-    public static class SuiteBCipher {
-        private SuiteBCipher() { }
-
-        /** Diffie-Hellman with Elliptic Curve_ECDSA signature */
-        public static final int ECDHE_ECDSA = 0;
-
-        /** Diffie-Hellman with_RSA signature */
-        public static final int ECDHE_RSA = 1;
-
-        private static final String varName = "SuiteB";
-
-        private static final String[] strings = { "ECDHE_ECDSA", "ECDHE_RSA" };
-    }
-
-    /** Possible status of a network configuration. */
-    public static class Status {
-        private Status() { }
-
-        /** this is the network we are currently connected to */
-        public static final int CURRENT = 0;
-        /** supplicant will not attempt to use this network */
-        public static final int DISABLED = 1;
-        /** supplicant will consider this network available for association */
-        public static final int ENABLED = 2;
-
-        public static final String[] strings = { "current", "disabled", "enabled" };
-    }
-
-    /** Security type for an open network. */
-    public static final int SECURITY_TYPE_OPEN = 0;
-    /** Security type for a WEP network. */
-    public static final int SECURITY_TYPE_WEP = 1;
-    /** Security type for a PSK network. */
-    public static final int SECURITY_TYPE_PSK = 2;
-    /** Security type for an EAP network. */
-    public static final int SECURITY_TYPE_EAP = 3;
-    /** Security type for an SAE network. */
-    public static final int SECURITY_TYPE_SAE = 4;
-    /** Security type for an EAP Suite B network. */
-    public static final int SECURITY_TYPE_EAP_SUITE_B = 5;
-    /** Security type for an OWE network. */
-    public static final int SECURITY_TYPE_OWE = 6;
-    /** Security type for a WAPI PSK network. */
-    public static final int SECURITY_TYPE_WAPI_PSK = 7;
-    /** Security type for a WAPI Certificate network. */
-    public static final int SECURITY_TYPE_WAPI_CERT = 8;
-
-    /**
-     * Security types we support.
-     * @hide
-     */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(prefix = { "SECURITY_TYPE_" }, value = {
-            SECURITY_TYPE_OPEN,
-            SECURITY_TYPE_WEP,
-            SECURITY_TYPE_PSK,
-            SECURITY_TYPE_EAP,
-            SECURITY_TYPE_SAE,
-            SECURITY_TYPE_EAP_SUITE_B,
-            SECURITY_TYPE_OWE,
-            SECURITY_TYPE_WAPI_PSK,
-            SECURITY_TYPE_WAPI_CERT
-    })
-    public @interface SecurityType {}
-
-    /**
-     * Set the various security params to correspond to the provided security type.
-     * This is accomplished by setting the various BitSets exposed in WifiConfiguration.
-     *
-     * @param securityType One of the following security types:
-     * {@link #SECURITY_TYPE_OPEN},
-     * {@link #SECURITY_TYPE_WEP},
-     * {@link #SECURITY_TYPE_PSK},
-     * {@link #SECURITY_TYPE_EAP},
-     * {@link #SECURITY_TYPE_SAE},
-     * {@link #SECURITY_TYPE_EAP_SUITE_B},
-     * {@link #SECURITY_TYPE_OWE},
-     * {@link #SECURITY_TYPE_WAPI_PSK}, or
-     * {@link #SECURITY_TYPE_WAPI_CERT}
-     */
-    public void setSecurityParams(@SecurityType int securityType) {
-        // Clear all the bitsets.
-        allowedKeyManagement.clear();
-        allowedProtocols.clear();
-        allowedAuthAlgorithms.clear();
-        allowedPairwiseCiphers.clear();
-        allowedGroupCiphers.clear();
-        allowedGroupManagementCiphers.clear();
-        allowedSuiteBCiphers.clear();
-
-        switch (securityType) {
-            case SECURITY_TYPE_OPEN:
-                allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
-                break;
-            case SECURITY_TYPE_WEP:
-                allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
-                allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
-                allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
-                break;
-            case SECURITY_TYPE_PSK:
-                allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
-                break;
-            case SECURITY_TYPE_EAP:
-                allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
-                allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X);
-                break;
-            case SECURITY_TYPE_SAE:
-                allowedProtocols.set(WifiConfiguration.Protocol.RSN);
-                allowedKeyManagement.set(WifiConfiguration.KeyMgmt.SAE);
-                allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
-                allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.GCMP_256);
-                allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
-                allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_256);
-                requirePmf = true;
-                break;
-            case SECURITY_TYPE_EAP_SUITE_B:
-                allowedProtocols.set(WifiConfiguration.Protocol.RSN);
-                allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
-                allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X);
-                allowedKeyManagement.set(WifiConfiguration.KeyMgmt.SUITE_B_192);
-                allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.GCMP_256);
-                allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_256);
-                allowedGroupManagementCiphers.set(WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256);
-                // Note: allowedSuiteBCiphers bitset will be set by the service once the
-                // certificates are attached to this profile
-                requirePmf = true;
-                break;
-            case SECURITY_TYPE_OWE:
-                allowedProtocols.set(WifiConfiguration.Protocol.RSN);
-                allowedKeyManagement.set(WifiConfiguration.KeyMgmt.OWE);
-                allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
-                allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.GCMP_256);
-                allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
-                allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_256);
-                requirePmf = true;
-                break;
-            case SECURITY_TYPE_WAPI_PSK:
-                allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WAPI_PSK);
-                allowedProtocols.set(WifiConfiguration.Protocol.WAPI);
-                allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.SMS4);
-                allowedGroupCiphers.set(WifiConfiguration.GroupCipher.SMS4);
-                break;
-            case SECURITY_TYPE_WAPI_CERT:
-                allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WAPI_CERT);
-                allowedProtocols.set(WifiConfiguration.Protocol.WAPI);
-                allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.SMS4);
-                allowedGroupCiphers.set(WifiConfiguration.GroupCipher.SMS4);
-                break;
-            default:
-                throw new IllegalArgumentException("unknown security type " + securityType);
-        }
-    }
-
-    /** @hide */
-    public static final int UNKNOWN_UID = -1;
-
-    /**
-     * The ID number that the supplicant uses to identify this
-     * network configuration entry. This must be passed as an argument
-     * to most calls into the supplicant.
-     */
-    public int networkId;
-
-    // Fixme We need remove this field to use only Quality network selection status only
-    /**
-     * The current status of this network configuration entry.
-     * @see Status
-     */
-    public int status;
-
-    /**
-     * The network's SSID. Can either be a UTF-8 string,
-     * which must be enclosed in double quotation marks
-     * (e.g., {@code "MyNetwork"}), or a string of
-     * hex digits, which are not enclosed in quotes
-     * (e.g., {@code 01a243f405}).
-     */
-    public String SSID;
-
-    /**
-     * When set, this network configuration entry should only be used when
-     * associating with the AP having the specified BSSID. The value is
-     * a string in the format of an Ethernet MAC address, e.g.,
-     * <code>XX:XX:XX:XX:XX:XX</code> where each <code>X</code> is a hex digit.
-     */
-    public String BSSID;
-
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(prefix = {"AP_BAND_"}, value = {
-            AP_BAND_2GHZ,
-            AP_BAND_5GHZ,
-            AP_BAND_ANY})
-    public @interface ApBand {}
-
-    /**
-     * 2GHz band.
-     * @hide
-     */
-    public static final int AP_BAND_2GHZ = 0;
-
-    /**
-     * 5GHz band.
-     * @hide
-     */
-    public static final int AP_BAND_5GHZ = 1;
-
-    /**
-     * Device is allowed to choose the optimal band (2Ghz or 5Ghz) based on device capability,
-     * operating country code and current radio conditions.
-     * @hide
-     */
-    public static final int AP_BAND_ANY = -1;
-
-    /**
-     * The band which the AP resides on.
-     * One of {@link #AP_BAND_2GHZ}, {@link #AP_BAND_5GHZ}, or {@link #AP_BAND_ANY}.
-     * By default, {@link #AP_BAND_2GHZ} is chosen.
-     *
-     * @hide
-     */
-    @UnsupportedAppUsage
-    @ApBand
-    public int apBand = AP_BAND_2GHZ;
-
-    /**
-     * The channel which AP resides on,currently, US only
-     * 2G  1-11
-     * 5G  36,40,44,48,149,153,157,161,165
-     * 0 - find a random available channel according to the apBand
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public int apChannel = 0;
-
-    /**
-     * Pre-shared key for use with WPA-PSK. Either an ASCII string enclosed in
-     * double quotation marks (e.g., {@code "abcdefghij"} for PSK passphrase or
-     * a string of 64 hex digits for raw PSK.
-     * <p/>
-     * When the value of this key is read, the actual key is
-     * not returned, just a "*" if the key has a value, or the null
-     * string otherwise.
-     */
-    public String preSharedKey;
-
-    /**
-     * Four WEP keys. For each of the four values, provide either an ASCII
-     * string enclosed in double quotation marks (e.g., {@code "abcdef"}),
-     * a string of hex digits (e.g., {@code 0102030405}), or an empty string
-     * (e.g., {@code ""}).
-     * <p/>
-     * When the value of one of these keys is read, the actual key is
-     * not returned, just a "*" if the key has a value, or the null
-     * string otherwise.
-     * @deprecated Due to security and performance limitations, use of WEP networks
-     * is discouraged.
-     */
-    @Deprecated
-    public String[] wepKeys;
-
-    /** Default WEP key index, ranging from 0 to 3.
-     * @deprecated Due to security and performance limitations, use of WEP networks
-     * is discouraged. */
-    @Deprecated
-    public int wepTxKeyIndex;
-
-    /**
-     * Priority determines the preference given to a network by {@code wpa_supplicant}
-     * when choosing an access point with which to associate.
-     * @deprecated This field does not exist anymore.
-     */
-    @Deprecated
-    public int priority;
-
-    /**
-     * This is a network that does not broadcast its SSID, so an
-     * SSID-specific probe request must be used for scans.
-     */
-    public boolean hiddenSSID;
-
-    /**
-     * True if the network requires Protected Management Frames (PMF), false otherwise.
-     * @hide
-     */
-    @SystemApi
-    public boolean requirePmf;
-
-    /**
-     * Update identifier, for Passpoint network.
-     * @hide
-     */
-    public String updateIdentifier;
-
-    /**
-     * The set of key management protocols supported by this configuration.
-     * See {@link KeyMgmt} for descriptions of the values.
-     * Defaults to WPA-PSK WPA-EAP.
-     */
-    @NonNull
-    public BitSet allowedKeyManagement;
-    /**
-     * The set of security protocols supported by this configuration.
-     * See {@link Protocol} for descriptions of the values.
-     * Defaults to WPA RSN.
-     */
-    @NonNull
-    public BitSet allowedProtocols;
-    /**
-     * The set of authentication protocols supported by this configuration.
-     * See {@link AuthAlgorithm} for descriptions of the values.
-     * Defaults to automatic selection.
-     */
-    @NonNull
-    public BitSet allowedAuthAlgorithms;
-    /**
-     * The set of pairwise ciphers for WPA supported by this configuration.
-     * See {@link PairwiseCipher} for descriptions of the values.
-     * Defaults to CCMP TKIP.
-     */
-    @NonNull
-    public BitSet allowedPairwiseCiphers;
-    /**
-     * The set of group ciphers supported by this configuration.
-     * See {@link GroupCipher} for descriptions of the values.
-     * Defaults to CCMP TKIP WEP104 WEP40.
-     */
-    @NonNull
-    public BitSet allowedGroupCiphers;
-    /**
-     * The set of group management ciphers supported by this configuration.
-     * See {@link GroupMgmtCipher} for descriptions of the values.
-     */
-    @NonNull
-    public BitSet allowedGroupManagementCiphers;
-    /**
-     * The set of SuiteB ciphers supported by this configuration.
-     * To be used for WPA3-Enterprise mode. Set automatically by the framework based on the
-     * certificate type that is used in this configuration.
-     */
-    @NonNull
-    public BitSet allowedSuiteBCiphers;
-    /**
-     * The enterprise configuration details specifying the EAP method,
-     * certificates and other settings associated with the EAP.
-     */
-    public WifiEnterpriseConfig enterpriseConfig;
-
-    /**
-     * Fully qualified domain name of a Passpoint configuration
-     */
-    public String FQDN;
-
-    /**
-     * Name of Passpoint credential provider
-     */
-    public String providerFriendlyName;
-
-    /**
-     * Flag indicating if this network is provided by a home Passpoint provider or a roaming
-     * Passpoint provider.  This flag will be {@code true} if this network is provided by
-     * a home Passpoint provider and {@code false} if is provided by a roaming Passpoint provider
-     * or is a non-Passpoint network.
-     */
-    public boolean isHomeProviderNetwork;
-
-    /**
-     * Roaming Consortium Id list for Passpoint credential; identifies a set of networks where
-     * Passpoint credential will be considered valid
-     */
-    public long[] roamingConsortiumIds;
-
-    /**
-     * True if this network configuration is visible to and usable by other users on the
-     * same device, false otherwise.
-     *
-     * @hide
-     */
-    @SystemApi
-    public boolean shared;
-
-    /**
-     * @hide
-     */
-    @NonNull
-    @UnsupportedAppUsage
-    private IpConfiguration mIpConfiguration;
-
-    /**
-     * @hide
-     * dhcp server MAC address if known
-     */
-    public String dhcpServer;
-
-    /**
-     * @hide
-     * default Gateway MAC address if known
-     */
-    @UnsupportedAppUsage
-    public String defaultGwMacAddress;
-
-    /**
-     * @hide
-     * last time we connected, this configuration had validated internet access
-     */
-    @UnsupportedAppUsage
-    public boolean validatedInternetAccess;
-
-    /**
-     * @hide
-     * The number of beacon intervals between Delivery Traffic Indication Maps (DTIM)
-     * This value is populated from scan results that contain Beacon Frames, which are infrequent.
-     * The value is not guaranteed to be set or current (Although it SHOULDNT change once set)
-     * Valid values are from 1 - 255. Initialized here as 0, use this to check if set.
-     */
-    public int dtimInterval = 0;
-
-    /**
-     * Flag indicating if this configuration represents a legacy Passpoint configuration
-     * (Release N or older).  This is used for migrating Passpoint configuration from N to O.
-     * This will no longer be needed after O.
-     * @hide
-     */
-    public boolean isLegacyPasspointConfig = false;
-    /**
-     * @hide
-     * Uid of app creating the configuration
-     */
-    @SystemApi
-    public int creatorUid;
-
-    /**
-     * @hide
-     * Uid of last app issuing a connection related command
-     */
-    @UnsupportedAppUsage
-    public int lastConnectUid;
-
-    /**
-     * @hide
-     * Uid of last app modifying the configuration
-     */
-    @SystemApi
-    public int lastUpdateUid;
-
-    /**
-     * @hide
-     * Universal name for app creating the configuration
-     *    see {@link PackageManager#getNameForUid(int)}
-     */
-    @SystemApi
-    public String creatorName;
-
-    /**
-     * @hide
-     * Universal name for app updating the configuration
-     *    see {@link PackageManager#getNameForUid(int)}
-     */
-    @SystemApi
-    public String lastUpdateName;
-
-    /**
-     * The carrier ID identifies the operator who provides this network configuration.
-     *    see {@link TelephonyManager#getSimCarrierId()}
-     * @hide
-     */
-    @SystemApi
-    public int carrierId = TelephonyManager.UNKNOWN_CARRIER_ID;
-
-    /**
-     * @hide
-     * Auto-join is allowed by user for this network.
-     * Default true.
-     */
-    @SystemApi
-    public boolean allowAutojoin = true;
-
-    /** @hide **/
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
-    public static int INVALID_RSSI = -127;
-
-    /**
-     * @hide
-     * Number of reports indicating no Internet Access
-     */
-    @UnsupportedAppUsage
-    public int numNoInternetAccessReports;
-
-    /**
-     * @hide
-     * The WiFi configuration is considered to have no internet access for purpose of autojoining
-     * if there has been a report of it having no internet access, and, it never have had
-     * internet access in the past.
-     */
-    @SystemApi
-    public boolean hasNoInternetAccess() {
-        return numNoInternetAccessReports > 0 && !validatedInternetAccess;
-    }
-
-    /**
-     * The WiFi configuration is expected not to have Internet access (e.g., a wireless printer, a
-     * Chromecast hotspot, etc.). This will be set if the user explicitly confirms a connection to
-     * this configuration and selects "don't ask again".
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public boolean noInternetAccessExpected;
-
-    /**
-     * The WiFi configuration is expected not to have Internet access (e.g., a wireless printer, a
-     * Chromecast hotspot, etc.). This will be set if the user explicitly confirms a connection to
-     * this configuration and selects "don't ask again".
-     * @hide
-     */
-    @SystemApi
-    public boolean isNoInternetAccessExpected() {
-        return noInternetAccessExpected;
-    }
-
-    /**
-     * This Wifi configuration is expected for OSU(Online Sign Up) of Passpoint Release 2.
-     * @hide
-     */
-    public boolean osu;
-
-    /**
-     * @hide
-     * Last time the system was connected to this configuration.
-     */
-    public long lastConnected;
-
-    /**
-     * @hide
-     * Last time the system was disconnected to this configuration.
-     */
-    public long lastDisconnected;
-
-    /**
-     * Set if the configuration was self added by the framework
-     * This boolean is cleared if we get a connect/save/ update or
-     * any wifiManager command that indicate the user interacted with the configuration
-     * since we will now consider that the configuration belong to him.
-     * @deprecated only kept for @UnsupportedAppUsage
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public boolean selfAdded;
-
-    /**
-     * Peer WifiConfiguration this WifiConfiguration was added for
-     * @hide
-     */
-    public String peerWifiConfiguration;
-
-    /**
-     * @hide
-     * Indicate that a WifiConfiguration is temporary and should not be saved
-     * nor considered by AutoJoin.
-     */
-    public boolean ephemeral;
-
-    /**
-     * @hide
-     * Indicate that a WifiConfiguration is temporary and should not be saved
-     * nor considered by AutoJoin.
-     */
-    @SystemApi
-    public boolean isEphemeral() {
-      return ephemeral;
-    }
-
-    /**
-     * Indicate whether the network is trusted or not. Networks are considered trusted
-     * if the user explicitly allowed this network connection.
-     * This bit can be used by suggestion network, see
-     * {@link WifiNetworkSuggestion.Builder#setUntrusted(boolean)}
-     * @hide
-     */
-    public boolean trusted;
-
-    /**
-     * True if this Wifi configuration is created from a {@link WifiNetworkSuggestion},
-     * false otherwise.
-     *
-     * @hide
-     */
-    @SystemApi
-    public boolean fromWifiNetworkSuggestion;
-
-    /**
-     * True if this Wifi configuration is created from a {@link WifiNetworkSpecifier},
-     * false otherwise.
-     *
-     * @hide
-     */
-    @SystemApi
-    public boolean fromWifiNetworkSpecifier;
-
-    /**
-     * True if the creator of this configuration has expressed that it
-     * should be considered metered, false otherwise.
-     *
-     * @see #isMetered(WifiConfiguration, WifiInfo)
-     *
-     * @hide
-     */
-    @SystemApi
-    public boolean meteredHint;
-
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(prefix = {"METERED_OVERRIDE_"}, value = {
-            METERED_OVERRIDE_NONE,
-            METERED_OVERRIDE_METERED,
-            METERED_OVERRIDE_NOT_METERED})
-    public @interface MeteredOverride {}
-
-    /**
-     * No metered override.
-     * @hide
-     */
-    @SystemApi
-    public static final int METERED_OVERRIDE_NONE = 0;
-    /**
-     * Override network to be metered.
-     * @hide
-     */
-    @SystemApi
-    public static final int METERED_OVERRIDE_METERED = 1;
-    /**
-     * Override network to be unmetered.
-     * @hide
-     */
-    @SystemApi
-    public static final int METERED_OVERRIDE_NOT_METERED = 2;
-
-    /**
-     * Indicates if the end user has expressed an explicit opinion about the
-     * meteredness of this network, such as through the Settings app.
-     * This value is one of {@link #METERED_OVERRIDE_NONE}, {@link #METERED_OVERRIDE_METERED},
-     * or {@link #METERED_OVERRIDE_NOT_METERED}.
-     * <p>
-     * This should always override any values from {@link #meteredHint} or
-     * {@link WifiInfo#getMeteredHint()}.
-     *
-     * By default this field is set to {@link #METERED_OVERRIDE_NONE}.
-     *
-     * @see #isMetered(WifiConfiguration, WifiInfo)
-     * @hide
-     */
-    @SystemApi
-    @MeteredOverride
-    public int meteredOverride = METERED_OVERRIDE_NONE;
-
-    /**
-     * Blend together all the various opinions to decide if the given network
-     * should be considered metered or not.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static boolean isMetered(@Nullable WifiConfiguration config, @Nullable WifiInfo info) {
-        boolean metered = false;
-        if (info != null && info.getMeteredHint()) {
-            metered = true;
-        }
-        if (config != null && config.meteredHint) {
-            metered = true;
-        }
-        if (config != null
-                && config.meteredOverride == WifiConfiguration.METERED_OVERRIDE_METERED) {
-            metered = true;
-        }
-        if (config != null
-                && config.meteredOverride == WifiConfiguration.METERED_OVERRIDE_NOT_METERED) {
-            metered = false;
-        }
-        return metered;
-    }
-
-    /**
-     * @hide
-     * Returns true if this WiFi config is for an open network.
-     */
-    public boolean isOpenNetwork() {
-        final int cardinality = allowedKeyManagement.cardinality();
-        final boolean hasNoKeyMgmt = cardinality == 0
-                || (cardinality == 1 && (allowedKeyManagement.get(KeyMgmt.NONE)
-                || allowedKeyManagement.get(KeyMgmt.OWE)));
-
-        boolean hasNoWepKeys = true;
-        if (wepKeys != null) {
-            for (int i = 0; i < wepKeys.length; i++) {
-                if (wepKeys[i] != null) {
-                    hasNoWepKeys = false;
-                    break;
-                }
-            }
-        }
-
-        return hasNoKeyMgmt && hasNoWepKeys;
-    }
-
-    /**
-     * @hide
-     * Setting this value will force scan results associated with this configuration to
-     * be included in the bucket of networks that are externally scored.
-     * If not set, associated scan results will be treated as legacy saved networks and
-     * will take precedence over networks in the scored category.
-     */
-    @SystemApi
-    public boolean useExternalScores;
-
-    /**
-     * @hide
-     * Number of time the scorer overrode a the priority based choice, when comparing two
-     * WifiConfigurations, note that since comparing WifiConfiguration happens very often
-     * potentially at every scan, this number might become very large, even on an idle
-     * system.
-     */
-    @SystemApi
-    public int numScorerOverride;
-
-    /**
-     * @hide
-     * Number of time the scorer overrode a the priority based choice, and the comparison
-     * triggered a network switch
-     */
-    @SystemApi
-    public int numScorerOverrideAndSwitchedNetwork;
-
-    /**
-     * @hide
-     * Number of time we associated to this configuration.
-     */
-    @SystemApi
-    public int numAssociation;
-
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(prefix = {"RANDOMIZATION_"}, value = {
-            RANDOMIZATION_NONE,
-            RANDOMIZATION_PERSISTENT})
-    public @interface MacRandomizationSetting {}
-
-    /**
-     * Use factory MAC when connecting to this network
-     * @hide
-     */
-    @SystemApi
-    public static final int RANDOMIZATION_NONE = 0;
-    /**
-     * Generate a randomized MAC once and reuse it for all connections to this network
-     * @hide
-     */
-    @SystemApi
-    public static final int RANDOMIZATION_PERSISTENT = 1;
-
-    /**
-     * Level of MAC randomization for this network.
-     * One of {@link #RANDOMIZATION_NONE} or {@link #RANDOMIZATION_PERSISTENT}.
-     * By default this field is set to {@link #RANDOMIZATION_PERSISTENT}.
-     * @hide
-     */
-    @SystemApi
-    @MacRandomizationSetting
-    public int macRandomizationSetting = RANDOMIZATION_PERSISTENT;
-
-    /**
-     * @hide
-     * Randomized MAC address to use with this particular network
-     */
-    @NonNull
-    private MacAddress mRandomizedMacAddress;
-
-    /**
-     * @hide
-     * The wall clock time of when |mRandomizedMacAddress| should be re-randomized in aggressive
-     * randomization mode.
-     */
-    public long randomizedMacExpirationTimeMs = 0;
-
-    /**
-     * @hide
-     * Checks if the given MAC address can be used for Connected Mac Randomization
-     * by verifying that it is non-null, unicast, locally assigned, and not default mac.
-     * @param mac MacAddress to check
-     * @return true if mac is good to use
-     */
-    public static boolean isValidMacAddressForRandomization(MacAddress mac) {
-        return mac != null && !MacAddressUtils.isMulticastAddress(mac) && mac.isLocallyAssigned()
-                && !MacAddress.fromString(WifiInfo.DEFAULT_MAC_ADDRESS).equals(mac);
-    }
-
-    /**
-     * Returns MAC address set to be the local randomized MAC address.
-     * Depending on user preference, the device may or may not use the returned MAC address for
-     * connections to this network.
-     * <p>
-     * Information is restricted to Device Owner, Profile Owner, and Carrier apps
-     * (which will only obtain addresses for configurations which they create). Other callers
-     * will receive a default "02:00:00:00:00:00" MAC address.
-     */
-    public @NonNull MacAddress getRandomizedMacAddress() {
-        return mRandomizedMacAddress;
-    }
-
-    /**
-     * @hide
-     * @param mac MacAddress to change into
-     */
-    public void setRandomizedMacAddress(@NonNull MacAddress mac) {
-        if (mac == null) {
-            Log.e(TAG, "setRandomizedMacAddress received null MacAddress.");
-            return;
-        }
-        mRandomizedMacAddress = mac;
-    }
-
-    /** @hide
-     * Boost given to RSSI on a home network for the purpose of calculating the score
-     * This adds stickiness to home networks, as defined by:
-     * - less than 4 known BSSIDs
-     * - PSK only
-     * - TODO: add a test to verify that all BSSIDs are behind same gateway
-     ***/
-    public static final int HOME_NETWORK_RSSI_BOOST = 5;
-
-    /**
-     * This class is used to contain all the information and API used for quality network selection.
-     * @hide
-     */
-    @SystemApi
-    public static class NetworkSelectionStatus {
-        /** @hide */
-        @Retention(RetentionPolicy.SOURCE)
-        @IntDef(prefix = "NETWORK_SELECTION_",
-                value = {
-                NETWORK_SELECTION_ENABLED,
-                NETWORK_SELECTION_TEMPORARY_DISABLED,
-                NETWORK_SELECTION_PERMANENTLY_DISABLED})
-        public @interface NetworkEnabledStatus {}
-        /**
-         * This network will be considered as a potential candidate to connect to during network
-         * selection.
-         */
-        public static final int NETWORK_SELECTION_ENABLED = 0;
-        /**
-         * This network was temporary disabled. May be re-enabled after a time out.
-         */
-        public static final int NETWORK_SELECTION_TEMPORARY_DISABLED = 1;
-        /**
-         * This network was permanently disabled.
-         */
-        public static final int NETWORK_SELECTION_PERMANENTLY_DISABLED = 2;
-        /**
-         * Maximum Network selection status
-         * @hide
-         */
-        public static final int NETWORK_SELECTION_STATUS_MAX = 3;
-
-        /**
-         * Quality network selection status String (for debug purpose). Use Quality network
-         * selection status value as index to extec the corresponding debug string
-         * @hide
-         */
-        public static final String[] QUALITY_NETWORK_SELECTION_STATUS = {
-                "NETWORK_SELECTION_ENABLED",
-                "NETWORK_SELECTION_TEMPORARY_DISABLED",
-                "NETWORK_SELECTION_PERMANENTLY_DISABLED"};
-
-        /** @hide */
-        @Retention(RetentionPolicy.SOURCE)
-        @IntDef(prefix = "DISABLED_", value = {
-                DISABLED_NONE,
-                DISABLED_ASSOCIATION_REJECTION,
-                DISABLED_AUTHENTICATION_FAILURE,
-                DISABLED_DHCP_FAILURE,
-                DISABLED_NO_INTERNET_TEMPORARY,
-                DISABLED_AUTHENTICATION_NO_CREDENTIALS,
-                DISABLED_NO_INTERNET_PERMANENT,
-                DISABLED_BY_WIFI_MANAGER,
-                DISABLED_BY_WRONG_PASSWORD,
-                DISABLED_AUTHENTICATION_NO_SUBSCRIPTION})
-        public @interface NetworkSelectionDisableReason {}
-
-        // Quality Network disabled reasons
-        /** Default value. Means not disabled. */
-        public static final int DISABLED_NONE = 0;
-        /**
-         * The starting index for network selection disabled reasons.
-         * @hide
-         */
-        public static final int NETWORK_SELECTION_DISABLED_STARTING_INDEX = 1;
-        /**
-         * The starting index for network selection temporarily disabled reasons.
-         * @hide
-         */
-        public static final int TEMPORARILY_DISABLED_STARTING_INDEX = 1;
-        /** This network is disabled because of multiple association rejections. */
-        public static final int DISABLED_ASSOCIATION_REJECTION = 1;
-        /** This network is disabled because of multiple authentication failure. */
-        public static final int DISABLED_AUTHENTICATION_FAILURE = 2;
-        /** This network is disabled because of multiple DHCP failure. */
-        public static final int DISABLED_DHCP_FAILURE = 3;
-        /** This network is temporarily disabled because it has no Internet access. */
-        public static final int DISABLED_NO_INTERNET_TEMPORARY = 4;
-        /**
-         * The starting index for network selection permanently disabled reasons.
-         * @hide
-         */
-        public static final int PERMANENTLY_DISABLED_STARTING_INDEX = 5;
-        /** This network is disabled due to absence of user credentials */
-        public static final int DISABLED_AUTHENTICATION_NO_CREDENTIALS = 5;
-        /**
-         * This network is permanently disabled because it has no Internet access and the user does
-         * not want to stay connected.
-         */
-        public static final int DISABLED_NO_INTERNET_PERMANENT = 6;
-        /** This network is disabled due to WifiManager disabling it explicitly. */
-        public static final int DISABLED_BY_WIFI_MANAGER = 7;
-        /** This network is disabled due to wrong password. */
-        public static final int DISABLED_BY_WRONG_PASSWORD = 8;
-        /** This network is disabled because service is not subscribed. */
-        public static final int DISABLED_AUTHENTICATION_NO_SUBSCRIPTION = 9;
-        /**
-         * All other disable reasons should be strictly less than this value.
-         * @hide
-         */
-        public static final int NETWORK_SELECTION_DISABLED_MAX = 10;
-
-        /**
-         * Get an integer that is equal to the maximum integer value of all the
-         * DISABLED_* reasons
-         * e.g. {@link #DISABLED_NONE}, {@link #DISABLED_ASSOCIATION_REJECTION}, etc.
-         *
-         * All DISABLED_* constants will be contiguous in the range
-         * 0, 1, 2, 3, ..., getMaxNetworkSelectionDisableReasons()
-         *
-         * <br />
-         * For example, this can be used to iterate through all the network selection
-         * disable reasons like so:
-         * <pre>{@code
-         * for (int reason = 0; reason <= getMaxNetworkSelectionDisableReasons(); reason++) {
-         *     ...
-         * }
-         * }</pre>
-         */
-        public static int getMaxNetworkSelectionDisableReason() {
-            return NETWORK_SELECTION_DISABLED_MAX - 1;
-        }
-
-        /**
-         * Contains info about disable reasons.
-         * @hide
-         */
-        public static final class DisableReasonInfo {
-            /**
-             * String representation for the disable reason.
-             * Note that these strings are persisted in
-             * {@link
-             * com.android.server.wifi.util.XmlUtil.NetworkSelectionStatusXmlUtil#writeToXml},
-             * so do not change the string values to maintain backwards compatibility.
-             */
-            public final String mReasonStr;
-            /**
-             * Network Selection disable reason threshold, used to debounce network failures before
-             * we disable them.
-             */
-            public final int mDisableThreshold;
-            /**
-             * Network Selection disable timeout for the error. After the timeout milliseconds,
-             * enable the network again.
-             */
-            public final int mDisableTimeoutMillis;
-
-            /**
-             * Constructor
-             * @param reasonStr string representation of the error
-             * @param disableThreshold number of failures before we disable the network
-             * @param disableTimeoutMillis the timeout, in milliseconds, before we re-enable the
-             *                             network after disabling it
-             */
-            public DisableReasonInfo(String reasonStr, int disableThreshold,
-                    int disableTimeoutMillis) {
-                mReasonStr = reasonStr;
-                mDisableThreshold = disableThreshold;
-                mDisableTimeoutMillis = disableTimeoutMillis;
-            }
-        }
-
-        /**
-         * Quality network selection disable reason infos.
-         * @hide
-         */
-        public static final SparseArray<DisableReasonInfo> DISABLE_REASON_INFOS =
-                buildDisableReasonInfos();
-
-        private static SparseArray<DisableReasonInfo> buildDisableReasonInfos() {
-            SparseArray<DisableReasonInfo> reasons = new SparseArray<>();
-
-            reasons.append(DISABLED_NONE,
-                    new DisableReasonInfo(
-                            // Note that these strings are persisted in
-                            // XmlUtil.NetworkSelectionStatusXmlUtil#writeToXml,
-                            // so do not change the string values to maintain backwards
-                            // compatibility.
-                            "NETWORK_SELECTION_ENABLE",
-                            -1,
-                            Integer.MAX_VALUE));
-
-            reasons.append(DISABLED_ASSOCIATION_REJECTION,
-                    new DisableReasonInfo(
-                            // Note that there is a space at the end of this string. Cannot fix
-                            // since this string is persisted.
-                            "NETWORK_SELECTION_DISABLED_ASSOCIATION_REJECTION ",
-                            5,
-                            5 * 60 * 1000));
-
-            reasons.append(DISABLED_AUTHENTICATION_FAILURE,
-                    new DisableReasonInfo(
-                            "NETWORK_SELECTION_DISABLED_AUTHENTICATION_FAILURE",
-                            5,
-                            5 * 60 * 1000));
-
-            reasons.append(DISABLED_DHCP_FAILURE,
-                    new DisableReasonInfo(
-                            "NETWORK_SELECTION_DISABLED_DHCP_FAILURE",
-                            5,
-                            5 * 60 * 1000));
-
-            reasons.append(DISABLED_NO_INTERNET_TEMPORARY,
-                    new DisableReasonInfo(
-                            "NETWORK_SELECTION_DISABLED_NO_INTERNET_TEMPORARY",
-                            1,
-                            10 * 60 * 1000));
-
-            reasons.append(DISABLED_AUTHENTICATION_NO_CREDENTIALS,
-                    new DisableReasonInfo(
-                            "NETWORK_SELECTION_DISABLED_AUTHENTICATION_NO_CREDENTIALS",
-                            1,
-                            Integer.MAX_VALUE));
-
-            reasons.append(DISABLED_NO_INTERNET_PERMANENT,
-                    new DisableReasonInfo(
-                            "NETWORK_SELECTION_DISABLED_NO_INTERNET_PERMANENT",
-                            1,
-                            Integer.MAX_VALUE));
-
-            reasons.append(DISABLED_BY_WIFI_MANAGER,
-                    new DisableReasonInfo(
-                            "NETWORK_SELECTION_DISABLED_BY_WIFI_MANAGER",
-                            1,
-                            Integer.MAX_VALUE));
-
-            reasons.append(DISABLED_BY_WRONG_PASSWORD,
-                    new DisableReasonInfo(
-                            "NETWORK_SELECTION_DISABLED_BY_WRONG_PASSWORD",
-                            1,
-                            Integer.MAX_VALUE));
-
-            reasons.append(DISABLED_AUTHENTICATION_NO_SUBSCRIPTION,
-                    new DisableReasonInfo(
-                            "NETWORK_SELECTION_DISABLED_AUTHENTICATION_NO_SUBSCRIPTION",
-                            1,
-                            Integer.MAX_VALUE));
-
-            return reasons;
-        }
-
-        /**
-         * Get the {@link NetworkSelectionDisableReason} int code by its string value.
-         * @return the NetworkSelectionDisableReason int code corresponding to the reason string,
-         * or -1 if the reason string is unrecognized.
-         * @hide
-         */
-        @NetworkSelectionDisableReason
-        public static int getDisableReasonByString(@NonNull String reasonString) {
-            for (int i = 0; i < DISABLE_REASON_INFOS.size(); i++) {
-                int key = DISABLE_REASON_INFOS.keyAt(i);
-                DisableReasonInfo value = DISABLE_REASON_INFOS.valueAt(i);
-                if (value != null && TextUtils.equals(reasonString, value.mReasonStr)) {
-                    return key;
-                }
-            }
-            Log.e(TAG, "Unrecognized network disable reason: " + reasonString);
-            return -1;
-        }
-
-        /**
-         * Invalid time stamp for network selection disable
-         * @hide
-         */
-        public static final long INVALID_NETWORK_SELECTION_DISABLE_TIMESTAMP = -1L;
-
-        /**
-         * This constant indicates the current configuration has connect choice set
-         */
-        private static final int CONNECT_CHOICE_EXISTS = 1;
-
-        /**
-         * This constant indicates the current configuration does not have connect choice set
-         */
-        private static final int CONNECT_CHOICE_NOT_EXISTS = -1;
-
-        // fields for QualityNetwork Selection
-        /**
-         * Network selection status, should be in one of three status: enable, temporaily disabled
-         * or permanently disabled
-         */
-        @NetworkEnabledStatus
-        private int mStatus;
-
-        /**
-         * Reason for disable this network
-         */
-        @NetworkSelectionDisableReason
-        private int mNetworkSelectionDisableReason;
-
-        /**
-         * Last time we temporarily disabled the configuration
-         */
-        private long mTemporarilyDisabledTimestamp = INVALID_NETWORK_SELECTION_DISABLE_TIMESTAMP;
-
-        /**
-         * counter for each Network selection disable reason
-         */
-        private int[] mNetworkSeclectionDisableCounter = new int[NETWORK_SELECTION_DISABLED_MAX];
-
-        /**
-         * Connect Choice over this configuration
-         *
-         * When current wifi configuration is visible to the user but user explicitly choose to
-         * connect to another network X, the another networks X's configure key will be stored here.
-         * We will consider user has a preference of X over this network. And in the future,
-         * network selection will always give X a higher preference over this configuration.
-         * configKey is : "SSID"-WEP-WPA_PSK-WPA_EAP
-         */
-        private String mConnectChoice;
-
-        /**
-         * Used to cache the temporary candidate during the network selection procedure. It will be
-         * kept updating once a new scan result has a higher score than current one
-         */
-        private ScanResult mCandidate;
-
-        /**
-         * Used to cache the score of the current temporary candidate during the network
-         * selection procedure.
-         */
-        private int mCandidateScore;
-
-        /**
-         * Indicate whether this network is visible in latest Qualified Network Selection. This
-         * means there is scan result found related to this Configuration and meet the minimum
-         * requirement. The saved network need not join latest Qualified Network Selection. For
-         * example, it is disabled. True means network is visible in latest Qualified Network
-         * Selection and false means network is invisible
-         */
-        private boolean mSeenInLastQualifiedNetworkSelection;
-
-        /**
-         * Boolean indicating if we have ever successfully connected to this network.
-         *
-         * This value will be set to true upon a successful connection.
-         * This value will be set to false if a previous value was not stored in the config or if
-         * the credentials are updated (ex. a password change).
-         */
-        private boolean mHasEverConnected;
-
-        /**
-         * set whether this network is visible in latest Qualified Network Selection
-         * @param seen value set to candidate
-         * @hide
-         */
-        public void setSeenInLastQualifiedNetworkSelection(boolean seen) {
-            mSeenInLastQualifiedNetworkSelection =  seen;
-        }
-
-        /**
-         * get whether this network is visible in latest Qualified Network Selection
-         * @return returns true -- network is visible in latest Qualified Network Selection
-         *         false -- network is invisible in latest Qualified Network Selection
-         * @hide
-         */
-        public boolean getSeenInLastQualifiedNetworkSelection() {
-            return mSeenInLastQualifiedNetworkSelection;
-        }
-        /**
-         * set the temporary candidate of current network selection procedure
-         * @param scanCandidate {@link ScanResult} the candidate set to mCandidate
-         * @hide
-         */
-        public void setCandidate(ScanResult scanCandidate) {
-            mCandidate = scanCandidate;
-        }
-
-        /**
-         * get the temporary candidate of current network selection procedure
-         * @return  returns {@link ScanResult} temporary candidate of current network selection
-         * procedure
-         * @hide
-         */
-        public ScanResult getCandidate() {
-            return mCandidate;
-        }
-
-        /**
-         * set the score of the temporary candidate of current network selection procedure
-         * @param score value set to mCandidateScore
-         * @hide
-         */
-        public void setCandidateScore(int score) {
-            mCandidateScore = score;
-        }
-
-        /**
-         * get the score of the temporary candidate of current network selection procedure
-         * @return returns score of the temporary candidate of current network selection procedure
-         * @hide
-         */
-        public int getCandidateScore() {
-            return mCandidateScore;
-        }
-
-        /**
-         * get user preferred choice over this configuration
-         * @return returns configKey of user preferred choice over this configuration
-         * @hide
-         */
-        public String getConnectChoice() {
-            return mConnectChoice;
-        }
-
-        /**
-         * set user preferred choice over this configuration
-         * @param newConnectChoice, the configKey of user preferred choice over this configuration
-         * @hide
-         */
-        public void setConnectChoice(String newConnectChoice) {
-            mConnectChoice = newConnectChoice;
-        }
-
-        /** Get the current Quality network selection status as a String (for debugging). */
-        @NonNull
-        public String getNetworkStatusString() {
-            return QUALITY_NETWORK_SELECTION_STATUS[mStatus];
-        }
-
-        /** @hide */
-        public void setHasEverConnected(boolean value) {
-            mHasEverConnected = value;
-        }
-
-        /** True if the device has ever connected to this network, false otherwise. */
-        public boolean hasEverConnected() {
-            return mHasEverConnected;
-        }
-
-        /** @hide */
-        public NetworkSelectionStatus() {
-            // previously stored configs will not have this parameter, so we default to false.
-            mHasEverConnected = false;
-        }
-
-        /**
-         * NetworkSelectionStatus exports an immutable public API.
-         * However, test code has a need to construct a NetworkSelectionStatus in a specific state.
-         * (Note that mocking using Mockito does not work if the object needs to be parceled and
-         * unparceled.)
-         * Export a @SystemApi Builder to allow tests to construct a NetworkSelectionStatus object
-         * in the desired state, without sacrificing NetworkSelectionStatus's immutability.
-         */
-        @VisibleForTesting
-        public static final class Builder {
-            private final NetworkSelectionStatus mNetworkSelectionStatus =
-                    new NetworkSelectionStatus();
-
-            /**
-             * Set the current network selection status.
-             * One of:
-             * {@link #NETWORK_SELECTION_ENABLED},
-             * {@link #NETWORK_SELECTION_TEMPORARY_DISABLED},
-             * {@link #NETWORK_SELECTION_PERMANENTLY_DISABLED}
-             * @see NetworkSelectionStatus#getNetworkSelectionStatus()
-             */
-            @NonNull
-            public Builder setNetworkSelectionStatus(@NetworkEnabledStatus int status) {
-                mNetworkSelectionStatus.setNetworkSelectionStatus(status);
-                return this;
-            }
-
-            /**
-             *
-             * Set the current network's disable reason.
-             * One of the {@link #DISABLED_NONE} or DISABLED_* constants.
-             * e.g. {@link #DISABLED_ASSOCIATION_REJECTION}.
-             * @see NetworkSelectionStatus#getNetworkSelectionDisableReason()
-             */
-            @NonNull
-            public Builder setNetworkSelectionDisableReason(
-                    @NetworkSelectionDisableReason int reason) {
-                mNetworkSelectionStatus.setNetworkSelectionDisableReason(reason);
-                return this;
-            }
-
-            /**
-             * Build a NetworkSelectionStatus object.
-             */
-            @NonNull
-            public NetworkSelectionStatus build() {
-                NetworkSelectionStatus status = new NetworkSelectionStatus();
-                status.copy(mNetworkSelectionStatus);
-                return status;
-            }
-        }
-
-        /**
-         * Get the network disable reason string for a reason code (for debugging).
-         * @param reason specific error reason. One of the {@link #DISABLED_NONE} or
-         *               DISABLED_* constants e.g. {@link #DISABLED_ASSOCIATION_REJECTION}.
-         * @return network disable reason string, or null if the reason is invalid.
-         */
-        @Nullable
-        public static String getNetworkSelectionDisableReasonString(
-                @NetworkSelectionDisableReason int reason) {
-            DisableReasonInfo info = DISABLE_REASON_INFOS.get(reason);
-            if (info == null) {
-                return null;
-            } else {
-                return info.mReasonStr;
-            }
-        }
-        /**
-         * get current network disable reason
-         * @return current network disable reason in String (for debug purpose)
-         * @hide
-         */
-        public String getNetworkSelectionDisableReasonString() {
-            return getNetworkSelectionDisableReasonString(mNetworkSelectionDisableReason);
-        }
-
-        /**
-         * Get the current network network selection status.
-         * One of:
-         * {@link #NETWORK_SELECTION_ENABLED},
-         * {@link #NETWORK_SELECTION_TEMPORARY_DISABLED},
-         * {@link #NETWORK_SELECTION_PERMANENTLY_DISABLED}
-         */
-        @NetworkEnabledStatus
-        public int getNetworkSelectionStatus() {
-            return mStatus;
-        }
-
-        /**
-         * True if the current network is enabled to join network selection, false otherwise.
-         * @hide
-         */
-        public boolean isNetworkEnabled() {
-            return mStatus == NETWORK_SELECTION_ENABLED;
-        }
-
-        /**
-         * @return whether current network is temporary disabled
-         * @hide
-         */
-        public boolean isNetworkTemporaryDisabled() {
-            return mStatus == NETWORK_SELECTION_TEMPORARY_DISABLED;
-        }
-
-        /**
-         * True if the current network is permanently disabled, false otherwise.
-         * @hide
-         */
-        public boolean isNetworkPermanentlyDisabled() {
-            return mStatus == NETWORK_SELECTION_PERMANENTLY_DISABLED;
-        }
-
-        /**
-         * set current network selection status
-         * @param status network selection status to set
-         * @hide
-         */
-        public void setNetworkSelectionStatus(int status) {
-            if (status >= 0 && status < NETWORK_SELECTION_STATUS_MAX) {
-                mStatus = status;
-            }
-        }
-
-        /**
-         * Returns the current network's disable reason.
-         * One of the {@link #DISABLED_NONE} or DISABLED_* constants
-         * e.g. {@link #DISABLED_ASSOCIATION_REJECTION}.
-         */
-        @NetworkSelectionDisableReason
-        public int getNetworkSelectionDisableReason() {
-            return mNetworkSelectionDisableReason;
-        }
-
-        /**
-         * set Network disable reason
-         * @param reason Network disable reason
-         * @hide
-         */
-        public void setNetworkSelectionDisableReason(@NetworkSelectionDisableReason int reason) {
-            if (reason >= 0 && reason < NETWORK_SELECTION_DISABLED_MAX) {
-                mNetworkSelectionDisableReason = reason;
-            } else {
-                throw new IllegalArgumentException("Illegal reason value: " + reason);
-            }
-        }
-
-        /**
-         * @param timeStamp Set when current network is disabled in millisecond since January 1,
-         * 1970 00:00:00.0 UTC
-         * @hide
-         */
-        public void setDisableTime(long timeStamp) {
-            mTemporarilyDisabledTimestamp = timeStamp;
-        }
-
-        /**
-         * Returns when the current network was disabled, in milliseconds since January 1,
-         * 1970 00:00:00.0 UTC.
-         */
-        public long getDisableTime() {
-            return mTemporarilyDisabledTimestamp;
-        }
-
-        /**
-         * Get the disable counter of a specific reason.
-         * @param reason specific failure reason. One of the {@link #DISABLED_NONE} or
-         *              DISABLED_* constants e.g. {@link #DISABLED_ASSOCIATION_REJECTION}.
-         * @exception IllegalArgumentException for invalid reason
-         * @return counter number for specific error reason.
-         */
-        public int getDisableReasonCounter(@NetworkSelectionDisableReason int reason) {
-            if (reason >= DISABLED_NONE && reason < NETWORK_SELECTION_DISABLED_MAX) {
-                return mNetworkSeclectionDisableCounter[reason];
-            } else {
-                throw new IllegalArgumentException("Illegal reason value: " + reason);
-            }
-        }
-
-        /**
-         * set the counter of a specific failure reason
-         * @param reason reason for disable error
-         * @param value the counter value for this specific reason
-         * @exception throw IllegalArgumentException for illegal input
-         * @hide
-         */
-        public void setDisableReasonCounter(int reason, int value) {
-            if (reason >= DISABLED_NONE && reason < NETWORK_SELECTION_DISABLED_MAX) {
-                mNetworkSeclectionDisableCounter[reason] = value;
-            } else {
-                throw new IllegalArgumentException("Illegal reason value: " + reason);
-            }
-        }
-
-        /**
-         * increment the counter of a specific failure reason
-         * @param reason a specific failure reason
-         * @exception throw IllegalArgumentException for illegal input
-         * @hide
-         */
-        public void incrementDisableReasonCounter(int reason) {
-            if (reason >= DISABLED_NONE && reason < NETWORK_SELECTION_DISABLED_MAX) {
-                mNetworkSeclectionDisableCounter[reason]++;
-            } else {
-                throw new IllegalArgumentException("Illegal reason value: " + reason);
-            }
-        }
-
-        /**
-         * clear the counter of a specific failure reason
-         * @param reason a specific failure reason
-         * @exception throw IllegalArgumentException for illegal input
-         * @hide
-         */
-        public void clearDisableReasonCounter(int reason) {
-            if (reason >= DISABLED_NONE && reason < NETWORK_SELECTION_DISABLED_MAX) {
-                mNetworkSeclectionDisableCounter[reason] = DISABLED_NONE;
-            } else {
-                throw new IllegalArgumentException("Illegal reason value: " + reason);
-            }
-        }
-
-        /**
-         * clear all the failure reason counters
-         * @hide
-         */
-        public void clearDisableReasonCounter() {
-            Arrays.fill(mNetworkSeclectionDisableCounter, DISABLED_NONE);
-        }
-
-        /**
-         * BSSID for connection to this network (through network selection procedure)
-         */
-        private String mNetworkSelectionBSSID;
-
-        /**
-         * get current network Selection BSSID
-         * @return current network Selection BSSID
-         * @hide
-         */
-        public String getNetworkSelectionBSSID() {
-            return mNetworkSelectionBSSID;
-        }
-
-        /**
-         * set network Selection BSSID
-         * @param bssid The target BSSID for assocaition
-         * @hide
-         */
-        public void setNetworkSelectionBSSID(String bssid) {
-            mNetworkSelectionBSSID = bssid;
-        }
-
-        /** @hide */
-        public void copy(NetworkSelectionStatus source) {
-            mStatus = source.mStatus;
-            mNetworkSelectionDisableReason = source.mNetworkSelectionDisableReason;
-            for (int index = DISABLED_NONE; index < NETWORK_SELECTION_DISABLED_MAX;
-                    index++) {
-                mNetworkSeclectionDisableCounter[index] =
-                        source.mNetworkSeclectionDisableCounter[index];
-            }
-            mTemporarilyDisabledTimestamp = source.mTemporarilyDisabledTimestamp;
-            mNetworkSelectionBSSID = source.mNetworkSelectionBSSID;
-            setSeenInLastQualifiedNetworkSelection(source.getSeenInLastQualifiedNetworkSelection());
-            setCandidate(source.getCandidate());
-            setCandidateScore(source.getCandidateScore());
-            setConnectChoice(source.getConnectChoice());
-            setHasEverConnected(source.hasEverConnected());
-        }
-
-        /** @hide */
-        public void writeToParcel(Parcel dest) {
-            dest.writeInt(getNetworkSelectionStatus());
-            dest.writeInt(getNetworkSelectionDisableReason());
-            for (int index = DISABLED_NONE; index < NETWORK_SELECTION_DISABLED_MAX;
-                    index++) {
-                dest.writeInt(getDisableReasonCounter(index));
-            }
-            dest.writeLong(getDisableTime());
-            dest.writeString(getNetworkSelectionBSSID());
-            if (getConnectChoice() != null) {
-                dest.writeInt(CONNECT_CHOICE_EXISTS);
-                dest.writeString(getConnectChoice());
-            } else {
-                dest.writeInt(CONNECT_CHOICE_NOT_EXISTS);
-            }
-            dest.writeInt(hasEverConnected() ? 1 : 0);
-        }
-
-        /** @hide */
-        public void readFromParcel(Parcel in) {
-            setNetworkSelectionStatus(in.readInt());
-            setNetworkSelectionDisableReason(in.readInt());
-            for (int index = DISABLED_NONE; index < NETWORK_SELECTION_DISABLED_MAX;
-                    index++) {
-                setDisableReasonCounter(index, in.readInt());
-            }
-            setDisableTime(in.readLong());
-            setNetworkSelectionBSSID(in.readString());
-            if (in.readInt() == CONNECT_CHOICE_EXISTS) {
-                setConnectChoice(in.readString());
-            } else {
-                setConnectChoice(null);
-            }
-            setHasEverConnected(in.readInt() != 0);
-        }
-    }
-
-    /**
-     * @hide
-     * network selection related member
-     */
-    private NetworkSelectionStatus mNetworkSelectionStatus = new NetworkSelectionStatus();
-
-    /**
-     * This class is intended to store extra failure reason information for the most recent
-     * connection attempt, so that it may be surfaced to the settings UI
-     * @hide
-     */
-    // TODO(b/148626966): called by SUW via reflection, remove once SUW is updated
-    public static class RecentFailure {
-
-        private RecentFailure() {}
-
-        /**
-         * Association Rejection Status code (NONE for success/non-association-rejection-fail)
-         */
-        @RecentFailureReason
-        private int mAssociationStatus = RECENT_FAILURE_NONE;
-
-        /**
-         * @param status the association status code for the recent failure
-         */
-        public void setAssociationStatus(@RecentFailureReason int status) {
-            mAssociationStatus = status;
-        }
-        /**
-         * Sets the RecentFailure to NONE
-         */
-        public void clear() {
-            mAssociationStatus = RECENT_FAILURE_NONE;
-        }
-        /**
-         * Get the recent failure code. One of {@link #RECENT_FAILURE_NONE} or
-         * {@link #RECENT_FAILURE_AP_UNABLE_TO_HANDLE_NEW_STA}.
-         */
-        @RecentFailureReason
-        public int getAssociationStatus() {
-            return mAssociationStatus;
-        }
-    }
-
-    /**
-     * RecentFailure member
-     * @hide
-     */
-    // TODO(b/148626966): called by SUW via reflection, once SUW is updated, make private and
-    //  rename to mRecentFailure
-    @NonNull
-    public final RecentFailure recentFailure = new RecentFailure();
-
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(prefix = "RECENT_FAILURE_", value = {
-            RECENT_FAILURE_NONE,
-            RECENT_FAILURE_AP_UNABLE_TO_HANDLE_NEW_STA})
-    public @interface RecentFailureReason {}
-
-    /**
-     * No recent failure, or no specific reason given for the recent connection failure
-     * @hide
-     */
-    @SystemApi
-    public static final int RECENT_FAILURE_NONE = 0;
-    /**
-     * Connection to this network recently failed due to Association Rejection Status 17
-     * (AP is full)
-     * @hide
-     */
-    @SystemApi
-    public static final int RECENT_FAILURE_AP_UNABLE_TO_HANDLE_NEW_STA = 17;
-
-    /**
-     * Get the failure reason for the most recent connection attempt, or
-     * {@link #RECENT_FAILURE_NONE} if there was no failure.
-     *
-     * Failure reasons include:
-     * {@link #RECENT_FAILURE_AP_UNABLE_TO_HANDLE_NEW_STA}
-     *
-     * @hide
-     */
-    @RecentFailureReason
-    @SystemApi
-    public int getRecentFailureReason() {
-        return recentFailure.getAssociationStatus();
-    }
-
-    /**
-     * Get the network selection status.
-     * @hide
-     */
-    @NonNull
-    @SystemApi
-    public NetworkSelectionStatus getNetworkSelectionStatus() {
-        return mNetworkSelectionStatus;
-    }
-
-    /**
-     * Set the network selection status.
-     * @hide
-     */
-    @SystemApi
-    public void setNetworkSelectionStatus(@NonNull NetworkSelectionStatus status) {
-        mNetworkSelectionStatus = status;
-    }
-
-    /**
-     * @hide
-     * Linked Configurations: represent the set of Wificonfigurations that are equivalent
-     * regarding roaming and auto-joining.
-     * The linked configuration may or may not have same SSID, and may or may not have same
-     * credentials.
-     * For instance, linked configurations will have same defaultGwMacAddress or same dhcp server.
-     */
-    public HashMap<String, Integer>  linkedConfigurations;
-
-    public WifiConfiguration() {
-        networkId = INVALID_NETWORK_ID;
-        SSID = null;
-        BSSID = null;
-        FQDN = null;
-        roamingConsortiumIds = new long[0];
-        priority = 0;
-        hiddenSSID = false;
-        allowedKeyManagement = new BitSet();
-        allowedProtocols = new BitSet();
-        allowedAuthAlgorithms = new BitSet();
-        allowedPairwiseCiphers = new BitSet();
-        allowedGroupCiphers = new BitSet();
-        allowedGroupManagementCiphers = new BitSet();
-        allowedSuiteBCiphers = new BitSet();
-        wepKeys = new String[4];
-        for (int i = 0; i < wepKeys.length; i++) {
-            wepKeys[i] = null;
-        }
-        enterpriseConfig = new WifiEnterpriseConfig();
-        ephemeral = false;
-        osu = false;
-        trusted = true; // Networks are considered trusted by default.
-        fromWifiNetworkSuggestion = false;
-        fromWifiNetworkSpecifier = false;
-        meteredHint = false;
-        meteredOverride = METERED_OVERRIDE_NONE;
-        useExternalScores = false;
-        validatedInternetAccess = false;
-        mIpConfiguration = new IpConfiguration();
-        lastUpdateUid = -1;
-        creatorUid = -1;
-        shared = true;
-        dtimInterval = 0;
-        mRandomizedMacAddress = MacAddress.fromString(WifiInfo.DEFAULT_MAC_ADDRESS);
-    }
-
-    /**
-     * Identify if this configuration represents a Passpoint network
-     */
-    public boolean isPasspoint() {
-        return !TextUtils.isEmpty(FQDN)
-                && !TextUtils.isEmpty(providerFriendlyName)
-                && enterpriseConfig != null
-                && enterpriseConfig.getEapMethod() != WifiEnterpriseConfig.Eap.NONE
-                && !TextUtils.isEmpty(mPasspointUniqueId);
-    }
-
-    /**
-     * Helper function, identify if a configuration is linked
-     * @hide
-     */
-    public boolean isLinked(WifiConfiguration config) {
-        if (config != null) {
-            if (config.linkedConfigurations != null && linkedConfigurations != null) {
-                if (config.linkedConfigurations.get(getKey()) != null
-                        && linkedConfigurations.get(config.getKey()) != null) {
-                    return true;
-                }
-            }
-        }
-        return  false;
-    }
-
-    /**
-     * Helper function, idenfity if a configuration should be treated as an enterprise network
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public boolean isEnterprise() {
-        return (allowedKeyManagement.get(KeyMgmt.WPA_EAP)
-                || allowedKeyManagement.get(KeyMgmt.IEEE8021X)
-                || allowedKeyManagement.get(KeyMgmt.SUITE_B_192)
-                || allowedKeyManagement.get(KeyMgmt.WAPI_CERT))
-                && enterpriseConfig != null
-                && enterpriseConfig.getEapMethod() != WifiEnterpriseConfig.Eap.NONE;
-    }
-
-    private static String logTimeOfDay(long millis) {
-        Calendar c = Calendar.getInstance();
-        if (millis >= 0) {
-            c.setTimeInMillis(millis);
-            return String.format("%tm-%td %tH:%tM:%tS.%tL", c, c, c, c, c, c);
-        } else {
-            return Long.toString(millis);
-        }
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder sbuf = new StringBuilder();
-        if (this.status == WifiConfiguration.Status.CURRENT) {
-            sbuf.append("* ");
-        } else if (this.status == WifiConfiguration.Status.DISABLED) {
-            sbuf.append("- DSBLE ");
-        }
-        sbuf.append("ID: ").append(this.networkId).append(" SSID: ").append(this.SSID).
-                append(" PROVIDER-NAME: ").append(this.providerFriendlyName).
-                append(" BSSID: ").append(this.BSSID).append(" FQDN: ").append(this.FQDN)
-                .append(" HOME-PROVIDER-NETWORK: ").append(this.isHomeProviderNetwork)
-                .append(" PRIO: ").append(this.priority)
-                .append(" HIDDEN: ").append(this.hiddenSSID)
-                .append(" PMF: ").append(this.requirePmf)
-                .append("CarrierId: ").append(this.carrierId)
-                .append('\n');
-
-
-        sbuf.append(" NetworkSelectionStatus ")
-                .append(mNetworkSelectionStatus.getNetworkStatusString())
-                .append("\n");
-        if (mNetworkSelectionStatus.getNetworkSelectionDisableReason() > 0) {
-            sbuf.append(" mNetworkSelectionDisableReason ")
-                    .append(mNetworkSelectionStatus.getNetworkSelectionDisableReasonString())
-                    .append("\n");
-
-            for (int index = NetworkSelectionStatus.DISABLED_NONE;
-                    index < NetworkSelectionStatus.NETWORK_SELECTION_DISABLED_MAX; index++) {
-                if (mNetworkSelectionStatus.getDisableReasonCounter(index) != 0) {
-                    sbuf.append(
-                            NetworkSelectionStatus.getNetworkSelectionDisableReasonString(index))
-                            .append(" counter:")
-                            .append(mNetworkSelectionStatus.getDisableReasonCounter(index))
-                            .append("\n");
-                }
-            }
-        }
-        if (mNetworkSelectionStatus.getConnectChoice() != null) {
-            sbuf.append(" connect choice: ").append(mNetworkSelectionStatus.getConnectChoice());
-        }
-        sbuf.append(" hasEverConnected: ")
-                .append(mNetworkSelectionStatus.hasEverConnected()).append("\n");
-
-        if (this.numAssociation > 0) {
-            sbuf.append(" numAssociation ").append(this.numAssociation).append("\n");
-        }
-        if (this.numNoInternetAccessReports > 0) {
-            sbuf.append(" numNoInternetAccessReports ");
-            sbuf.append(this.numNoInternetAccessReports).append("\n");
-        }
-        if (this.validatedInternetAccess) sbuf.append(" validatedInternetAccess");
-        if (this.ephemeral) sbuf.append(" ephemeral");
-        if (this.osu) sbuf.append(" osu");
-        if (this.trusted) sbuf.append(" trusted");
-        if (this.fromWifiNetworkSuggestion) sbuf.append(" fromWifiNetworkSuggestion");
-        if (this.fromWifiNetworkSpecifier) sbuf.append(" fromWifiNetworkSpecifier");
-        if (this.meteredHint) sbuf.append(" meteredHint");
-        if (this.useExternalScores) sbuf.append(" useExternalScores");
-        if (this.validatedInternetAccess || this.ephemeral || this.trusted
-                || this.fromWifiNetworkSuggestion || this.fromWifiNetworkSpecifier
-                || this.meteredHint || this.useExternalScores) {
-            sbuf.append("\n");
-        }
-        if (this.meteredOverride != METERED_OVERRIDE_NONE) {
-            sbuf.append(" meteredOverride ").append(meteredOverride).append("\n");
-        }
-        sbuf.append(" macRandomizationSetting: ").append(macRandomizationSetting).append("\n");
-        sbuf.append(" mRandomizedMacAddress: ").append(mRandomizedMacAddress).append("\n");
-        sbuf.append(" randomizedMacExpirationTimeMs: ")
-                .append(randomizedMacExpirationTimeMs == 0 ? "<none>"
-                        : logTimeOfDay(randomizedMacExpirationTimeMs)).append("\n");
-        sbuf.append(" KeyMgmt:");
-        for (int k = 0; k < this.allowedKeyManagement.size(); k++) {
-            if (this.allowedKeyManagement.get(k)) {
-                sbuf.append(" ");
-                if (k < KeyMgmt.strings.length) {
-                    sbuf.append(KeyMgmt.strings[k]);
-                } else {
-                    sbuf.append("??");
-                }
-            }
-        }
-        sbuf.append(" Protocols:");
-        for (int p = 0; p < this.allowedProtocols.size(); p++) {
-            if (this.allowedProtocols.get(p)) {
-                sbuf.append(" ");
-                if (p < Protocol.strings.length) {
-                    sbuf.append(Protocol.strings[p]);
-                } else {
-                    sbuf.append("??");
-                }
-            }
-        }
-        sbuf.append('\n');
-        sbuf.append(" AuthAlgorithms:");
-        for (int a = 0; a < this.allowedAuthAlgorithms.size(); a++) {
-            if (this.allowedAuthAlgorithms.get(a)) {
-                sbuf.append(" ");
-                if (a < AuthAlgorithm.strings.length) {
-                    sbuf.append(AuthAlgorithm.strings[a]);
-                } else {
-                    sbuf.append("??");
-                }
-            }
-        }
-        sbuf.append('\n');
-        sbuf.append(" PairwiseCiphers:");
-        for (int pc = 0; pc < this.allowedPairwiseCiphers.size(); pc++) {
-            if (this.allowedPairwiseCiphers.get(pc)) {
-                sbuf.append(" ");
-                if (pc < PairwiseCipher.strings.length) {
-                    sbuf.append(PairwiseCipher.strings[pc]);
-                } else {
-                    sbuf.append("??");
-                }
-            }
-        }
-        sbuf.append('\n');
-        sbuf.append(" GroupCiphers:");
-        for (int gc = 0; gc < this.allowedGroupCiphers.size(); gc++) {
-            if (this.allowedGroupCiphers.get(gc)) {
-                sbuf.append(" ");
-                if (gc < GroupCipher.strings.length) {
-                    sbuf.append(GroupCipher.strings[gc]);
-                } else {
-                    sbuf.append("??");
-                }
-            }
-        }
-        sbuf.append('\n');
-        sbuf.append(" GroupMgmtCiphers:");
-        for (int gmc = 0; gmc < this.allowedGroupManagementCiphers.size(); gmc++) {
-            if (this.allowedGroupManagementCiphers.get(gmc)) {
-                sbuf.append(" ");
-                if (gmc < GroupMgmtCipher.strings.length) {
-                    sbuf.append(GroupMgmtCipher.strings[gmc]);
-                } else {
-                    sbuf.append("??");
-                }
-            }
-        }
-        sbuf.append('\n');
-        sbuf.append(" SuiteBCiphers:");
-        for (int sbc = 0; sbc < this.allowedSuiteBCiphers.size(); sbc++) {
-            if (this.allowedSuiteBCiphers.get(sbc)) {
-                sbuf.append(" ");
-                if (sbc < SuiteBCipher.strings.length) {
-                    sbuf.append(SuiteBCipher.strings[sbc]);
-                } else {
-                    sbuf.append("??");
-                }
-            }
-        }
-        sbuf.append('\n').append(" PSK/SAE: ");
-        if (this.preSharedKey != null) {
-            sbuf.append('*');
-        }
-
-        sbuf.append("\nEnterprise config:\n");
-        sbuf.append(enterpriseConfig);
-
-        sbuf.append("IP config:\n");
-        sbuf.append(mIpConfiguration.toString());
-
-        if (mNetworkSelectionStatus.getNetworkSelectionBSSID() != null) {
-            sbuf.append(" networkSelectionBSSID="
-                    + mNetworkSelectionStatus.getNetworkSelectionBSSID());
-        }
-        long now_ms = SystemClock.elapsedRealtime();
-        if (mNetworkSelectionStatus.getDisableTime() != NetworkSelectionStatus
-                .INVALID_NETWORK_SELECTION_DISABLE_TIMESTAMP) {
-            sbuf.append('\n');
-            long diff = now_ms - mNetworkSelectionStatus.getDisableTime();
-            if (diff <= 0) {
-                sbuf.append(" blackListed since <incorrect>");
-            } else {
-                sbuf.append(" blackListed: ").append(Long.toString(diff / 1000)).append("sec ");
-            }
-        }
-        if (creatorUid != 0) sbuf.append(" cuid=" + creatorUid);
-        if (creatorName != null) sbuf.append(" cname=" + creatorName);
-        if (lastUpdateUid != 0) sbuf.append(" luid=" + lastUpdateUid);
-        if (lastUpdateName != null) sbuf.append(" lname=" + lastUpdateName);
-        if (updateIdentifier != null) sbuf.append(" updateIdentifier=" + updateIdentifier);
-        sbuf.append(" lcuid=" + lastConnectUid);
-        sbuf.append(" allowAutojoin=" + allowAutojoin);
-        sbuf.append(" noInternetAccessExpected=" + noInternetAccessExpected);
-        sbuf.append(" mostRecentlyConnected=" + isMostRecentlyConnected);
-
-        sbuf.append(" ");
-
-        if (this.lastConnected != 0) {
-            sbuf.append('\n');
-            sbuf.append("lastConnected: ").append(logTimeOfDay(this.lastConnected));
-            sbuf.append(" ");
-        }
-        sbuf.append('\n');
-        if (this.linkedConfigurations != null) {
-            for (String key : this.linkedConfigurations.keySet()) {
-                sbuf.append(" linked: ").append(key);
-                sbuf.append('\n');
-            }
-        }
-        sbuf.append("recentFailure: ").append("Association Rejection code: ")
-                .append(recentFailure.getAssociationStatus()).append("\n");
-        return sbuf.toString();
-    }
-
-    /**
-     * Get the SSID in a human-readable format, with all additional formatting removed
-     * e.g. quotation marks around the SSID, "P" prefix
-     * @hide
-     */
-    @NonNull
-    @SystemApi
-    public String getPrintableSsid() {
-        if (SSID == null) return "";
-        final int length = SSID.length();
-        if (length > 2 && (SSID.charAt(0) == '"') && SSID.charAt(length - 1) == '"') {
-            return SSID.substring(1, length - 1);
-        }
-
-        /* The ascii-encoded string format is P"<ascii-encoded-string>"
-         * The decoding is implemented in the supplicant for a newly configured
-         * network.
-         */
-        if (length > 3 && (SSID.charAt(0) == 'P') && (SSID.charAt(1) == '"') &&
-                (SSID.charAt(length-1) == '"')) {
-            WifiSsid wifiSsid = WifiSsid.createFromAsciiEncoded(
-                    SSID.substring(2, length - 1));
-            return wifiSsid.toString();
-        }
-        return SSID;
-    }
-
-    /**
-     * Get an identifier for associating credentials with this config
-     * @param current configuration contains values for additional fields
-     *                that are not part of this configuration. Used
-     *                when a config with some fields is passed by an application.
-     * @throws IllegalStateException if config is invalid for key id generation
-     * @hide
-     */
-    public String getKeyIdForCredentials(WifiConfiguration current) {
-        String keyMgmt = "";
-
-        try {
-            // Get current config details for fields that are not initialized
-            if (TextUtils.isEmpty(SSID)) SSID = current.SSID;
-            if (allowedKeyManagement.cardinality() == 0) {
-                allowedKeyManagement = current.allowedKeyManagement;
-            }
-            if (allowedKeyManagement.get(KeyMgmt.WPA_EAP)) {
-                keyMgmt += KeyMgmt.strings[KeyMgmt.WPA_EAP];
-            }
-            if (allowedKeyManagement.get(KeyMgmt.OSEN)) {
-                keyMgmt += KeyMgmt.strings[KeyMgmt.OSEN];
-            }
-            if (allowedKeyManagement.get(KeyMgmt.IEEE8021X)) {
-                keyMgmt += KeyMgmt.strings[KeyMgmt.IEEE8021X];
-            }
-            if (allowedKeyManagement.get(KeyMgmt.SUITE_B_192)) {
-                keyMgmt += KeyMgmt.strings[KeyMgmt.SUITE_B_192];
-            }
-            if (allowedKeyManagement.get(KeyMgmt.WAPI_CERT)) {
-                keyMgmt += KeyMgmt.strings[KeyMgmt.WAPI_CERT];
-            }
-
-            if (TextUtils.isEmpty(keyMgmt)) {
-                throw new IllegalStateException("Not an EAP network");
-            }
-            String keyId = trimStringForKeyId(SSID) + "_" + keyMgmt + "_"
-                    + trimStringForKeyId(enterpriseConfig.getKeyId(current != null
-                    ? current.enterpriseConfig : null));
-
-            if (!fromWifiNetworkSuggestion) {
-                return keyId;
-            }
-            return keyId + "_" + trimStringForKeyId(BSSID) + "_" + trimStringForKeyId(creatorName);
-        } catch (NullPointerException e) {
-            throw new IllegalStateException("Invalid config details");
-        }
-    }
-
-    private String trimStringForKeyId(String string) {
-        if (string == null) {
-            return "";
-        }
-        // Remove quotes and spaces
-        return string.replace("\"", "").replace(" ", "");
-    }
-
-    private static BitSet readBitSet(Parcel src) {
-        int cardinality = src.readInt();
-
-        BitSet set = new BitSet();
-        for (int i = 0; i < cardinality; i++) {
-            set.set(src.readInt());
-        }
-
-        return set;
-    }
-
-    private static void writeBitSet(Parcel dest, BitSet set) {
-        int nextSetBit = -1;
-
-        dest.writeInt(set.cardinality());
-
-        while ((nextSetBit = set.nextSetBit(nextSetBit + 1)) != -1) {
-            dest.writeInt(nextSetBit);
-        }
-    }
-
-    /**
-     * Get the authentication type of the network.
-     * @return One of the {@link KeyMgmt} constants. e.g. {@link KeyMgmt#WPA2_PSK}.
-     * @hide
-     */
-    @SystemApi
-    @KeyMgmt.KeyMgmtScheme
-    public int getAuthType() {
-        if (allowedKeyManagement.cardinality() > 1) {
-            if (allowedKeyManagement.get(KeyMgmt.WPA_EAP)) {
-                if (allowedKeyManagement.cardinality() == 2
-                        && allowedKeyManagement.get(KeyMgmt.IEEE8021X)) {
-                    return KeyMgmt.WPA_EAP;
-                }
-                if (allowedKeyManagement.cardinality() == 3
-                        && allowedKeyManagement.get(KeyMgmt.IEEE8021X)
-                        && allowedKeyManagement.get(KeyMgmt.SUITE_B_192)) {
-                    return KeyMgmt.SUITE_B_192;
-                }
-            }
-            throw new IllegalStateException("Invalid auth type set: " + allowedKeyManagement);
-        }
-        if (allowedKeyManagement.get(KeyMgmt.WPA_PSK)) {
-            return KeyMgmt.WPA_PSK;
-        } else if (allowedKeyManagement.get(KeyMgmt.WPA2_PSK)) {
-            return KeyMgmt.WPA2_PSK;
-        } else if (allowedKeyManagement.get(KeyMgmt.WPA_EAP)) {
-            return KeyMgmt.WPA_EAP;
-        } else if (allowedKeyManagement.get(KeyMgmt.IEEE8021X)) {
-            return KeyMgmt.IEEE8021X;
-        } else if (allowedKeyManagement.get(KeyMgmt.SAE)) {
-            return KeyMgmt.SAE;
-        } else if (allowedKeyManagement.get(KeyMgmt.OWE)) {
-            return KeyMgmt.OWE;
-        } else if (allowedKeyManagement.get(KeyMgmt.SUITE_B_192)) {
-            return KeyMgmt.SUITE_B_192;
-        } else if (allowedKeyManagement.get(KeyMgmt.WAPI_PSK)) {
-            return KeyMgmt.WAPI_PSK;
-        } else if (allowedKeyManagement.get(KeyMgmt.WAPI_CERT)) {
-            return KeyMgmt.WAPI_CERT;
-        }
-        return KeyMgmt.NONE;
-    }
-
-    /**
-     * Return a String that can be used to uniquely identify this WifiConfiguration.
-     * <br />
-     * Note: Do not persist this value! This value is not guaranteed to remain backwards compatible.
-     */
-    @NonNull
-    public String getKey() {
-        // Passpoint ephemeral networks have their unique identifier set. Return it as is to be
-        // able to match internally.
-        if (mPasspointUniqueId != null) {
-            return mPasspointUniqueId;
-        }
-
-        String key = getSsidAndSecurityTypeString();
-        if (!shared) {
-            key += "-" + UserHandle.getUserHandleForUid(creatorUid).getIdentifier();
-        }
-
-        return key;
-    }
-
-    /** @hide
-     *  return the SSID + security type in String format.
-     */
-    public String getSsidAndSecurityTypeString() {
-        String key;
-        if (allowedKeyManagement.get(KeyMgmt.WPA_PSK)) {
-            key = SSID + KeyMgmt.strings[KeyMgmt.WPA_PSK];
-        } else if (allowedKeyManagement.get(KeyMgmt.WPA_EAP)
-                || allowedKeyManagement.get(KeyMgmt.IEEE8021X)) {
-            key = SSID + KeyMgmt.strings[KeyMgmt.WPA_EAP];
-        } else if (wepTxKeyIndex >= 0 && wepTxKeyIndex < wepKeys.length
-                && wepKeys[wepTxKeyIndex] != null) {
-            key = SSID + "WEP";
-        } else if (allowedKeyManagement.get(KeyMgmt.OWE)) {
-            key = SSID + KeyMgmt.strings[KeyMgmt.OWE];
-        } else if (allowedKeyManagement.get(KeyMgmt.SAE)) {
-            key = SSID + KeyMgmt.strings[KeyMgmt.SAE];
-        } else if (allowedKeyManagement.get(KeyMgmt.SUITE_B_192)) {
-            key = SSID + KeyMgmt.strings[KeyMgmt.SUITE_B_192];
-        } else if (allowedKeyManagement.get(KeyMgmt.WAPI_PSK)) {
-            key = SSID + KeyMgmt.strings[KeyMgmt.WAPI_PSK];
-        } else if (allowedKeyManagement.get(KeyMgmt.WAPI_CERT)) {
-            key = SSID + KeyMgmt.strings[KeyMgmt.WAPI_CERT];
-        } else if (allowedKeyManagement.get(KeyMgmt.OSEN)) {
-            key = SSID + KeyMgmt.strings[KeyMgmt.OSEN];
-        } else {
-            key = SSID + KeyMgmt.strings[KeyMgmt.NONE];
-        }
-        return key;
-    }
-
-    /**
-     * Get the IpConfiguration object associated with this WifiConfiguration.
-     * @hide
-     */
-    @NonNull
-    @SystemApi
-    public IpConfiguration getIpConfiguration() {
-        return new IpConfiguration(mIpConfiguration);
-    }
-
-    /**
-     * Set the {@link IpConfiguration} for this network.
-     * @param ipConfiguration the {@link IpConfiguration} to set, or null to use the default
-     *                        constructor {@link IpConfiguration#IpConfiguration()}.
-     * @hide
-     */
-    @SystemApi
-    public void setIpConfiguration(@Nullable IpConfiguration ipConfiguration) {
-        if (ipConfiguration == null) ipConfiguration = new IpConfiguration();
-        mIpConfiguration = ipConfiguration;
-    }
-
-    /**
-     * Get the {@link StaticIpConfiguration} for this network.
-     * @return the {@link StaticIpConfiguration}, or null if unset.
-     * @hide
-     */
-    @Nullable
-    @UnsupportedAppUsage
-    public StaticIpConfiguration getStaticIpConfiguration() {
-        return mIpConfiguration.getStaticIpConfiguration();
-    }
-
-    /** @hide */
-    @UnsupportedAppUsage
-    public void setStaticIpConfiguration(StaticIpConfiguration staticIpConfiguration) {
-        mIpConfiguration.setStaticIpConfiguration(staticIpConfiguration);
-    }
-
-    /**
-     * Get the {@link IpConfiguration.IpAssignment} for this network.
-     * @hide
-     */
-    @NonNull
-    @UnsupportedAppUsage
-    public IpConfiguration.IpAssignment getIpAssignment() {
-        return mIpConfiguration.getIpAssignment();
-    }
-
-    /** @hide */
-    @UnsupportedAppUsage
-    public void setIpAssignment(IpConfiguration.IpAssignment ipAssignment) {
-        mIpConfiguration.setIpAssignment(ipAssignment);
-    }
-
-    /**
-     * Get the {@link IpConfiguration.ProxySettings} for this network.
-     * @hide
-     */
-    @NonNull
-    @UnsupportedAppUsage
-    public IpConfiguration.ProxySettings getProxySettings() {
-        return mIpConfiguration.getProxySettings();
-    }
-
-    /** @hide */
-    @UnsupportedAppUsage
-    public void setProxySettings(IpConfiguration.ProxySettings proxySettings) {
-        mIpConfiguration.setProxySettings(proxySettings);
-    }
-
-    /**
-     * Returns the HTTP proxy used by this object.
-     * @return a {@link ProxyInfo httpProxy} representing the proxy specified by this
-     *                  WifiConfiguration, or {@code null} if no proxy is specified.
-     */
-    public ProxyInfo getHttpProxy() {
-        if (mIpConfiguration.getProxySettings() == IpConfiguration.ProxySettings.NONE) {
-            return null;
-        }
-        return new ProxyInfo(mIpConfiguration.getHttpProxy());
-    }
-
-    /**
-     * Set the {@link ProxyInfo} for this WifiConfiguration. This method should only be used by a
-     * device owner or profile owner. When other apps attempt to save a {@link WifiConfiguration}
-     * with modified proxy settings, the methods {@link WifiManager#addNetwork} and
-     * {@link WifiManager#updateNetwork} fail and return {@code -1}.
-     *
-     * @param httpProxy {@link ProxyInfo} representing the httpProxy to be used by this
-     *                  WifiConfiguration. Setting this to {@code null} will explicitly set no
-     *                  proxy, removing any proxy that was previously set.
-     * @exception IllegalArgumentException for invalid httpProxy
-     */
-    public void setHttpProxy(ProxyInfo httpProxy) {
-        if (httpProxy == null) {
-            mIpConfiguration.setProxySettings(IpConfiguration.ProxySettings.NONE);
-            mIpConfiguration.setHttpProxy(null);
-            return;
-        }
-        ProxyInfo httpProxyCopy;
-        ProxySettings proxySettingCopy;
-        if (!Uri.EMPTY.equals(httpProxy.getPacFileUrl())) {
-            proxySettingCopy = IpConfiguration.ProxySettings.PAC;
-            // Construct a new PAC URL Proxy
-            httpProxyCopy = ProxyInfo.buildPacProxy(httpProxy.getPacFileUrl(), httpProxy.getPort());
-        } else {
-            proxySettingCopy = IpConfiguration.ProxySettings.STATIC;
-            // Construct a new HTTP Proxy
-            httpProxyCopy = ProxyInfo.buildDirectProxy(httpProxy.getHost(), httpProxy.getPort(),
-                    Arrays.asList(httpProxy.getExclusionList()));
-        }
-        if (!httpProxyCopy.isValid()) {
-            throw new IllegalArgumentException("Invalid ProxyInfo: " + httpProxyCopy.toString());
-        }
-        mIpConfiguration.setProxySettings(proxySettingCopy);
-        mIpConfiguration.setHttpProxy(httpProxyCopy);
-    }
-
-    /**
-     * Set the {@link ProxySettings} and {@link ProxyInfo} for this network.
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public void setProxy(@NonNull ProxySettings settings, @NonNull ProxyInfo proxy) {
-        mIpConfiguration.setProxySettings(settings);
-        mIpConfiguration.setHttpProxy(proxy);
-    }
-
-    /** Implement the Parcelable interface {@hide} */
-    public int describeContents() {
-        return 0;
-    }
-
-    /** @hide */
-    public void setPasspointManagementObjectTree(String passpointManagementObjectTree) {
-        mPasspointManagementObjectTree = passpointManagementObjectTree;
-    }
-
-    /** @hide */
-    public String getMoTree() {
-        return mPasspointManagementObjectTree;
-    }
-
-    /** Copy constructor */
-    public WifiConfiguration(@NonNull WifiConfiguration source) {
-        if (source != null) {
-            networkId = source.networkId;
-            status = source.status;
-            SSID = source.SSID;
-            BSSID = source.BSSID;
-            FQDN = source.FQDN;
-            roamingConsortiumIds = source.roamingConsortiumIds.clone();
-            providerFriendlyName = source.providerFriendlyName;
-            isHomeProviderNetwork = source.isHomeProviderNetwork;
-            preSharedKey = source.preSharedKey;
-
-            mNetworkSelectionStatus.copy(source.getNetworkSelectionStatus());
-            apBand = source.apBand;
-            apChannel = source.apChannel;
-
-            wepKeys = new String[4];
-            for (int i = 0; i < wepKeys.length; i++) {
-                wepKeys[i] = source.wepKeys[i];
-            }
-
-            wepTxKeyIndex = source.wepTxKeyIndex;
-            priority = source.priority;
-            hiddenSSID = source.hiddenSSID;
-            allowedKeyManagement   = (BitSet) source.allowedKeyManagement.clone();
-            allowedProtocols       = (BitSet) source.allowedProtocols.clone();
-            allowedAuthAlgorithms  = (BitSet) source.allowedAuthAlgorithms.clone();
-            allowedPairwiseCiphers = (BitSet) source.allowedPairwiseCiphers.clone();
-            allowedGroupCiphers    = (BitSet) source.allowedGroupCiphers.clone();
-            allowedGroupManagementCiphers = (BitSet) source.allowedGroupManagementCiphers.clone();
-            allowedSuiteBCiphers    = (BitSet) source.allowedSuiteBCiphers.clone();
-            enterpriseConfig = new WifiEnterpriseConfig(source.enterpriseConfig);
-
-            defaultGwMacAddress = source.defaultGwMacAddress;
-
-            mIpConfiguration = new IpConfiguration(source.mIpConfiguration);
-
-            if ((source.linkedConfigurations != null)
-                    && (source.linkedConfigurations.size() > 0)) {
-                linkedConfigurations = new HashMap<String, Integer>();
-                linkedConfigurations.putAll(source.linkedConfigurations);
-            }
-            validatedInternetAccess = source.validatedInternetAccess;
-            isLegacyPasspointConfig = source.isLegacyPasspointConfig;
-            ephemeral = source.ephemeral;
-            osu = source.osu;
-            trusted = source.trusted;
-            fromWifiNetworkSuggestion = source.fromWifiNetworkSuggestion;
-            fromWifiNetworkSpecifier = source.fromWifiNetworkSpecifier;
-            meteredHint = source.meteredHint;
-            meteredOverride = source.meteredOverride;
-            useExternalScores = source.useExternalScores;
-
-            lastConnectUid = source.lastConnectUid;
-            lastUpdateUid = source.lastUpdateUid;
-            creatorUid = source.creatorUid;
-            creatorName = source.creatorName;
-            lastUpdateName = source.lastUpdateName;
-            peerWifiConfiguration = source.peerWifiConfiguration;
-
-            lastConnected = source.lastConnected;
-            lastDisconnected = source.lastDisconnected;
-            numScorerOverride = source.numScorerOverride;
-            numScorerOverrideAndSwitchedNetwork = source.numScorerOverrideAndSwitchedNetwork;
-            numAssociation = source.numAssociation;
-            allowAutojoin = source.allowAutojoin;
-            numNoInternetAccessReports = source.numNoInternetAccessReports;
-            noInternetAccessExpected = source.noInternetAccessExpected;
-            shared = source.shared;
-            recentFailure.setAssociationStatus(source.recentFailure.getAssociationStatus());
-            mRandomizedMacAddress = source.mRandomizedMacAddress;
-            macRandomizationSetting = source.macRandomizationSetting;
-            randomizedMacExpirationTimeMs = source.randomizedMacExpirationTimeMs;
-            requirePmf = source.requirePmf;
-            updateIdentifier = source.updateIdentifier;
-            carrierId = source.carrierId;
-            mPasspointUniqueId = source.mPasspointUniqueId;
-        }
-    }
-
-    /** Implement the Parcelable interface {@hide} */
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(networkId);
-        dest.writeInt(status);
-        mNetworkSelectionStatus.writeToParcel(dest);
-        dest.writeString(SSID);
-        dest.writeString(BSSID);
-        dest.writeInt(apBand);
-        dest.writeInt(apChannel);
-        dest.writeString(FQDN);
-        dest.writeString(providerFriendlyName);
-        dest.writeInt(isHomeProviderNetwork ? 1 : 0);
-        dest.writeInt(roamingConsortiumIds.length);
-        for (long roamingConsortiumId : roamingConsortiumIds) {
-            dest.writeLong(roamingConsortiumId);
-        }
-        dest.writeString(preSharedKey);
-        for (String wepKey : wepKeys) {
-            dest.writeString(wepKey);
-        }
-        dest.writeInt(wepTxKeyIndex);
-        dest.writeInt(priority);
-        dest.writeInt(hiddenSSID ? 1 : 0);
-        dest.writeInt(requirePmf ? 1 : 0);
-        dest.writeString(updateIdentifier);
-
-        writeBitSet(dest, allowedKeyManagement);
-        writeBitSet(dest, allowedProtocols);
-        writeBitSet(dest, allowedAuthAlgorithms);
-        writeBitSet(dest, allowedPairwiseCiphers);
-        writeBitSet(dest, allowedGroupCiphers);
-        writeBitSet(dest, allowedGroupManagementCiphers);
-        writeBitSet(dest, allowedSuiteBCiphers);
-
-        dest.writeParcelable(enterpriseConfig, flags);
-
-        dest.writeParcelable(mIpConfiguration, flags);
-        dest.writeString(dhcpServer);
-        dest.writeString(defaultGwMacAddress);
-        dest.writeInt(validatedInternetAccess ? 1 : 0);
-        dest.writeInt(isLegacyPasspointConfig ? 1 : 0);
-        dest.writeInt(ephemeral ? 1 : 0);
-        dest.writeInt(trusted ? 1 : 0);
-        dest.writeInt(fromWifiNetworkSuggestion ? 1 : 0);
-        dest.writeInt(fromWifiNetworkSpecifier ? 1 : 0);
-        dest.writeInt(meteredHint ? 1 : 0);
-        dest.writeInt(meteredOverride);
-        dest.writeInt(useExternalScores ? 1 : 0);
-        dest.writeInt(creatorUid);
-        dest.writeInt(lastConnectUid);
-        dest.writeInt(lastUpdateUid);
-        dest.writeString(creatorName);
-        dest.writeString(lastUpdateName);
-        dest.writeInt(numScorerOverride);
-        dest.writeInt(numScorerOverrideAndSwitchedNetwork);
-        dest.writeInt(numAssociation);
-        dest.writeBoolean(allowAutojoin);
-        dest.writeInt(numNoInternetAccessReports);
-        dest.writeInt(noInternetAccessExpected ? 1 : 0);
-        dest.writeInt(shared ? 1 : 0);
-        dest.writeString(mPasspointManagementObjectTree);
-        dest.writeInt(recentFailure.getAssociationStatus());
-        dest.writeParcelable(mRandomizedMacAddress, flags);
-        dest.writeInt(macRandomizationSetting);
-        dest.writeInt(osu ? 1 : 0);
-        dest.writeLong(randomizedMacExpirationTimeMs);
-        dest.writeInt(carrierId);
-        dest.writeString(mPasspointUniqueId);
-    }
-
-    /** Implement the Parcelable interface {@hide} */
-    @UnsupportedAppUsage
-    public static final @android.annotation.NonNull Creator<WifiConfiguration> CREATOR =
-        new Creator<WifiConfiguration>() {
-            public WifiConfiguration createFromParcel(Parcel in) {
-                WifiConfiguration config = new WifiConfiguration();
-                config.networkId = in.readInt();
-                config.status = in.readInt();
-                config.mNetworkSelectionStatus.readFromParcel(in);
-                config.SSID = in.readString();
-                config.BSSID = in.readString();
-                config.apBand = in.readInt();
-                config.apChannel = in.readInt();
-                config.FQDN = in.readString();
-                config.providerFriendlyName = in.readString();
-                config.isHomeProviderNetwork = in.readInt() != 0;
-                int numRoamingConsortiumIds = in.readInt();
-                config.roamingConsortiumIds = new long[numRoamingConsortiumIds];
-                for (int i = 0; i < numRoamingConsortiumIds; i++) {
-                    config.roamingConsortiumIds[i] = in.readLong();
-                }
-                config.preSharedKey = in.readString();
-                for (int i = 0; i < config.wepKeys.length; i++) {
-                    config.wepKeys[i] = in.readString();
-                }
-                config.wepTxKeyIndex = in.readInt();
-                config.priority = in.readInt();
-                config.hiddenSSID = in.readInt() != 0;
-                config.requirePmf = in.readInt() != 0;
-                config.updateIdentifier = in.readString();
-
-                config.allowedKeyManagement   = readBitSet(in);
-                config.allowedProtocols       = readBitSet(in);
-                config.allowedAuthAlgorithms  = readBitSet(in);
-                config.allowedPairwiseCiphers = readBitSet(in);
-                config.allowedGroupCiphers    = readBitSet(in);
-                config.allowedGroupManagementCiphers = readBitSet(in);
-                config.allowedSuiteBCiphers   = readBitSet(in);
-
-                config.enterpriseConfig = in.readParcelable(null);
-                config.setIpConfiguration(in.readParcelable(null));
-                config.dhcpServer = in.readString();
-                config.defaultGwMacAddress = in.readString();
-                config.validatedInternetAccess = in.readInt() != 0;
-                config.isLegacyPasspointConfig = in.readInt() != 0;
-                config.ephemeral = in.readInt() != 0;
-                config.trusted = in.readInt() != 0;
-                config.fromWifiNetworkSuggestion =  in.readInt() != 0;
-                config.fromWifiNetworkSpecifier =  in.readInt() != 0;
-                config.meteredHint = in.readInt() != 0;
-                config.meteredOverride = in.readInt();
-                config.useExternalScores = in.readInt() != 0;
-                config.creatorUid = in.readInt();
-                config.lastConnectUid = in.readInt();
-                config.lastUpdateUid = in.readInt();
-                config.creatorName = in.readString();
-                config.lastUpdateName = in.readString();
-                config.numScorerOverride = in.readInt();
-                config.numScorerOverrideAndSwitchedNetwork = in.readInt();
-                config.numAssociation = in.readInt();
-                config.allowAutojoin = in.readBoolean();
-                config.numNoInternetAccessReports = in.readInt();
-                config.noInternetAccessExpected = in.readInt() != 0;
-                config.shared = in.readInt() != 0;
-                config.mPasspointManagementObjectTree = in.readString();
-                config.recentFailure.setAssociationStatus(in.readInt());
-                config.mRandomizedMacAddress = in.readParcelable(null);
-                config.macRandomizationSetting = in.readInt();
-                config.osu = in.readInt() != 0;
-                config.randomizedMacExpirationTimeMs = in.readLong();
-                config.carrierId = in.readInt();
-                config.mPasspointUniqueId = in.readString();
-                return config;
-            }
-
-            public WifiConfiguration[] newArray(int size) {
-                return new WifiConfiguration[size];
-            }
-        };
-
-    /**
-     * Passpoint Unique identifier
-     * @hide
-     */
-    private String mPasspointUniqueId = null;
-
-    /**
-     * Set the Passpoint unique identifier
-     * @param uniqueId Passpoint unique identifier to be set
-     * @hide
-     */
-    public void setPasspointUniqueId(String uniqueId) {
-        mPasspointUniqueId = uniqueId;
-    }
-
-    /**
-     * Set the Passpoint unique identifier
-     * @hide
-     */
-    public String getPasspointUniqueId() {
-        return mPasspointUniqueId;
-    }
-
-    /**
-     * If network is one of the most recently connected.
-     * For framework internal use only. Do not parcel.
-     * @hide
-     */
-    public boolean isMostRecentlyConnected = false;
-
-    /**
-     * Whether the key mgmt indicates if the WifiConfiguration needs a preSharedKey or not.
-     * @return true if preSharedKey is needed, false otherwise.
-     * @hide
-     */
-    public boolean needsPreSharedKey() {
-        return allowedKeyManagement.get(KeyMgmt.WPA_PSK)
-                || allowedKeyManagement.get(KeyMgmt.SAE)
-                || allowedKeyManagement.get(KeyMgmt.WAPI_PSK);
-    }
-
-}
diff --git a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
deleted file mode 100644
index e127ea9..0000000
--- a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
+++ /dev/null
@@ -1,1514 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.net.wifi;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-import android.util.Log;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.nio.charset.StandardCharsets;
-import java.security.PrivateKey;
-import java.security.cert.X509Certificate;
-import java.security.interfaces.ECPublicKey;
-import java.security.interfaces.RSAPublicKey;
-import java.security.spec.ECParameterSpec;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Enterprise configuration details for Wi-Fi. Stores details about the EAP method
- * and any associated credentials.
- */
-public class WifiEnterpriseConfig implements Parcelable {
-
-    /** Key prefix for WAPI AS certificates. */
-    public static final String WAPI_AS_CERTIFICATE = "WAPIAS_";
-
-    /** Key prefix for WAPI user certificates. */
-    public static final String WAPI_USER_CERTIFICATE = "WAPIUSR_";
-
-    /**
-     * Intent extra: name for WAPI AS certificates
-     */
-    public static final String EXTRA_WAPI_AS_CERTIFICATE_NAME =
-            "android.net.wifi.extra.WAPI_AS_CERTIFICATE_NAME";
-
-    /**
-     * Intent extra: data for WAPI AS certificates
-     */
-    public static final String EXTRA_WAPI_AS_CERTIFICATE_DATA =
-            "android.net.wifi.extra.WAPI_AS_CERTIFICATE_DATA";
-
-    /**
-     * Intent extra: name for WAPI USER certificates
-     */
-    public static final String EXTRA_WAPI_USER_CERTIFICATE_NAME =
-            "android.net.wifi.extra.WAPI_USER_CERTIFICATE_NAME";
-
-    /**
-     * Intent extra: data for WAPI USER certificates
-     */
-    public static final String EXTRA_WAPI_USER_CERTIFICATE_DATA =
-            "android.net.wifi.extra.WAPI_USER_CERTIFICATE_DATA";
-
-    /** @hide */
-    public static final String EMPTY_VALUE         = "NULL";
-    /** @hide */
-    public static final String EAP_KEY             = "eap";
-    /** @hide */
-    public static final String PHASE2_KEY          = "phase2";
-    /** @hide */
-    public static final String IDENTITY_KEY        = "identity";
-    /** @hide */
-    public static final String ANON_IDENTITY_KEY   = "anonymous_identity";
-    /** @hide */
-    public static final String PASSWORD_KEY        = "password";
-    /** @hide */
-    public static final String SUBJECT_MATCH_KEY   = "subject_match";
-    /** @hide */
-    public static final String ALTSUBJECT_MATCH_KEY = "altsubject_match";
-    /** @hide */
-    public static final String DOM_SUFFIX_MATCH_KEY = "domain_suffix_match";
-    /** @hide */
-    public static final String OPP_KEY_CACHING     = "proactive_key_caching";
-    /** @hide */
-    public static final String EAP_ERP             = "eap_erp";
-    /** @hide */
-    public static final String OCSP                = "ocsp";
-
-    /**
-     * String representing the keystore OpenSSL ENGINE's ID.
-     * @hide
-     */
-    public static final String ENGINE_ID_KEYSTORE = "keystore";
-
-    /**
-     * String representing the keystore URI used for wpa_supplicant.
-     * @hide
-     */
-    public static final String KEYSTORE_URI = "keystore://";
-
-    /**
-     * String representing the keystore URI used for wpa_supplicant,
-     * Unlike #KEYSTORE_URI, this supports a list of space-delimited aliases
-     * @hide
-     */
-    public static final String KEYSTORES_URI = "keystores://";
-
-    /**
-     * String to set the engine value to when it should be enabled.
-     * @hide
-     */
-    public static final String ENGINE_ENABLE = "1";
-
-    /**
-     * String to set the engine value to when it should be disabled.
-     * @hide
-     */
-    public static final String ENGINE_DISABLE = "0";
-
-    /**
-     * Key prefix for CA certificates.
-     * Note: copied from {@link android.security.Credentials#CA_CERTIFICATE} since it is @hide.
-     */
-    private static final String CA_CERTIFICATE = "CACERT_";
-    /**
-     * Key prefix for user certificates.
-     * Note: copied from {@link android.security.Credentials#USER_CERTIFICATE} since it is @hide.
-     */
-    private static final String USER_CERTIFICATE = "USRCERT_";
-    /**
-     * Key prefix for user private and secret keys.
-     * Note: copied from {@link android.security.Credentials#USER_PRIVATE_KEY} since it is @hide.
-     */
-    private static final String USER_PRIVATE_KEY = "USRPKEY_";
-
-    /** @hide */
-    public static final String CA_CERT_PREFIX = KEYSTORE_URI + CA_CERTIFICATE;
-    /** @hide */
-    public static final String CLIENT_CERT_PREFIX = KEYSTORE_URI + USER_CERTIFICATE;
-    /** @hide */
-    public static final String CLIENT_CERT_KEY     = "client_cert";
-    /** @hide */
-    public static final String CA_CERT_KEY         = "ca_cert";
-    /** @hide */
-    public static final String CA_PATH_KEY         = "ca_path";
-    /** @hide */
-    public static final String ENGINE_KEY          = "engine";
-    /** @hide */
-    public static final String ENGINE_ID_KEY       = "engine_id";
-    /** @hide */
-    public static final String PRIVATE_KEY_ID_KEY  = "key_id";
-    /** @hide */
-    public static final String REALM_KEY           = "realm";
-    /** @hide */
-    public static final String PLMN_KEY            = "plmn";
-    /** @hide */
-    public static final String CA_CERT_ALIAS_DELIMITER = " ";
-    /** @hide */
-    public static final String WAPI_CERT_SUITE_KEY = "wapi_cert_suite";
-
-    /**
-     * Do not use OCSP stapling (TLS certificate status extension)
-     * @hide
-     */
-    @SystemApi
-    public static final int OCSP_NONE = 0;
-
-    /**
-     * Try to use OCSP stapling, but not require response
-     * @hide
-     */
-    @SystemApi
-    public static final int OCSP_REQUEST_CERT_STATUS = 1;
-
-    /**
-     * Require valid OCSP stapling response
-     * @hide
-     */
-    @SystemApi
-    public static final int OCSP_REQUIRE_CERT_STATUS = 2;
-
-    /**
-     * Require valid OCSP stapling response for all not-trusted certificates in the server
-     * certificate chain
-     * @hide
-     */
-    @SystemApi
-    public static final int OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS = 3;
-
-    /** @hide */
-    @IntDef(prefix = {"OCSP_"}, value = {
-            OCSP_NONE,
-            OCSP_REQUEST_CERT_STATUS,
-            OCSP_REQUIRE_CERT_STATUS,
-            OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface Ocsp {}
-
-    /**
-     * Whether to use/require OCSP (Online Certificate Status Protocol) to check server certificate.
-     * @hide
-     */
-    private @Ocsp int mOcsp = OCSP_NONE;
-
-    // Fields to copy verbatim from wpa_supplicant.
-    private static final String[] SUPPLICANT_CONFIG_KEYS = new String[] {
-            IDENTITY_KEY,
-            ANON_IDENTITY_KEY,
-            PASSWORD_KEY,
-            CLIENT_CERT_KEY,
-            CA_CERT_KEY,
-            SUBJECT_MATCH_KEY,
-            ENGINE_KEY,
-            ENGINE_ID_KEY,
-            PRIVATE_KEY_ID_KEY,
-            ALTSUBJECT_MATCH_KEY,
-            DOM_SUFFIX_MATCH_KEY,
-            CA_PATH_KEY
-    };
-
-    /**
-     * Fields that have unquoted values in {@link #mFields}.
-     */
-    private static final List<String> UNQUOTED_KEYS = Arrays.asList(ENGINE_KEY, OPP_KEY_CACHING,
-                                                                    EAP_ERP);
-
-    @UnsupportedAppUsage
-    private HashMap<String, String> mFields = new HashMap<String, String>();
-    private X509Certificate[] mCaCerts;
-    private PrivateKey mClientPrivateKey;
-    private X509Certificate[] mClientCertificateChain;
-    private int mEapMethod = Eap.NONE;
-    private int mPhase2Method = Phase2.NONE;
-    private boolean mIsAppInstalledDeviceKeyAndCert = false;
-    private boolean mIsAppInstalledCaCert = false;
-
-    private static final String TAG = "WifiEnterpriseConfig";
-
-    public WifiEnterpriseConfig() {
-        // Do not set defaults so that the enterprise fields that are not changed
-        // by API are not changed underneath
-        // This is essential because an app may not have all fields like password
-        // available. It allows modification of subset of fields.
-
-    }
-
-    /**
-     * Copy over the contents of the source WifiEnterpriseConfig object over to this object.
-     *
-     * @param source Source WifiEnterpriseConfig object.
-     * @param ignoreMaskedPassword Set to true to ignore masked password field, false otherwise.
-     * @param mask if |ignoreMaskedPassword| is set, check if the incoming password field is set
-     *             to this value.
-     */
-    private void copyFrom(WifiEnterpriseConfig source, boolean ignoreMaskedPassword, String mask) {
-        for (String key : source.mFields.keySet()) {
-            if (ignoreMaskedPassword && key.equals(PASSWORD_KEY)
-                    && TextUtils.equals(source.mFields.get(key), mask)) {
-                continue;
-            }
-            mFields.put(key, source.mFields.get(key));
-        }
-        if (source.mCaCerts != null) {
-            mCaCerts = Arrays.copyOf(source.mCaCerts, source.mCaCerts.length);
-        } else {
-            mCaCerts = null;
-        }
-        mClientPrivateKey = source.mClientPrivateKey;
-        if (source.mClientCertificateChain != null) {
-            mClientCertificateChain = Arrays.copyOf(
-                    source.mClientCertificateChain,
-                    source.mClientCertificateChain.length);
-        } else {
-            mClientCertificateChain = null;
-        }
-        mEapMethod = source.mEapMethod;
-        mPhase2Method = source.mPhase2Method;
-        mIsAppInstalledDeviceKeyAndCert = source.mIsAppInstalledDeviceKeyAndCert;
-        mIsAppInstalledCaCert = source.mIsAppInstalledCaCert;
-        mOcsp = source.mOcsp;
-    }
-
-    /**
-     * Copy constructor.
-     * This copies over all the fields verbatim (does not ignore masked password fields).
-     *
-     * @param source Source WifiEnterpriseConfig object.
-     */
-    public WifiEnterpriseConfig(WifiEnterpriseConfig source) {
-        copyFrom(source, false, "");
-    }
-
-    /**
-     * Copy fields from the provided external WifiEnterpriseConfig.
-     * This is needed to handle the WifiEnterpriseConfig objects which were sent by apps with the
-     * password field masked.
-     *
-     * @param externalConfig External WifiEnterpriseConfig object.
-     * @param mask String mask to compare against.
-     * @hide
-     */
-    public void copyFromExternal(WifiEnterpriseConfig externalConfig, String mask) {
-        copyFrom(externalConfig, true, convertToQuotedString(mask));
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mFields.size());
-        for (Map.Entry<String, String> entry : mFields.entrySet()) {
-            dest.writeString(entry.getKey());
-            dest.writeString(entry.getValue());
-        }
-
-        dest.writeInt(mEapMethod);
-        dest.writeInt(mPhase2Method);
-        ParcelUtil.writeCertificates(dest, mCaCerts);
-        ParcelUtil.writePrivateKey(dest, mClientPrivateKey);
-        ParcelUtil.writeCertificates(dest, mClientCertificateChain);
-        dest.writeBoolean(mIsAppInstalledDeviceKeyAndCert);
-        dest.writeBoolean(mIsAppInstalledCaCert);
-        dest.writeInt(mOcsp);
-    }
-
-    public static final @android.annotation.NonNull Creator<WifiEnterpriseConfig> CREATOR =
-            new Creator<WifiEnterpriseConfig>() {
-                @Override
-                public WifiEnterpriseConfig createFromParcel(Parcel in) {
-                    WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
-                    int count = in.readInt();
-                    for (int i = 0; i < count; i++) {
-                        String key = in.readString();
-                        String value = in.readString();
-                        enterpriseConfig.mFields.put(key, value);
-                    }
-
-                    enterpriseConfig.mEapMethod = in.readInt();
-                    enterpriseConfig.mPhase2Method = in.readInt();
-                    enterpriseConfig.mCaCerts = ParcelUtil.readCertificates(in);
-                    enterpriseConfig.mClientPrivateKey = ParcelUtil.readPrivateKey(in);
-                    enterpriseConfig.mClientCertificateChain = ParcelUtil.readCertificates(in);
-                    enterpriseConfig.mIsAppInstalledDeviceKeyAndCert = in.readBoolean();
-                    enterpriseConfig.mIsAppInstalledCaCert = in.readBoolean();
-                    enterpriseConfig.mOcsp = in.readInt();
-                    return enterpriseConfig;
-                }
-
-                @Override
-                public WifiEnterpriseConfig[] newArray(int size) {
-                    return new WifiEnterpriseConfig[size];
-                }
-            };
-
-    /** The Extensible Authentication Protocol method used */
-    public static final class Eap {
-        /** No EAP method used. Represents an empty config */
-        public static final int NONE    = -1;
-        /** Protected EAP */
-        public static final int PEAP    = 0;
-        /** EAP-Transport Layer Security */
-        public static final int TLS     = 1;
-        /** EAP-Tunneled Transport Layer Security */
-        public static final int TTLS    = 2;
-        /** EAP-Password */
-        public static final int PWD     = 3;
-        /** EAP-Subscriber Identity Module [RFC-4186] */
-        public static final int SIM     = 4;
-        /** EAP-Authentication and Key Agreement [RFC-4187] */
-        public static final int AKA     = 5;
-        /** EAP-Authentication and Key Agreement Prime [RFC-5448] */
-        public static final int AKA_PRIME = 6;
-        /** Hotspot 2.0 r2 OSEN */
-        public static final int UNAUTH_TLS = 7;
-        /** WAPI Certificate */
-        public static final int WAPI_CERT = 8;
-        /** @hide */
-        public static final String[] strings =
-                { "PEAP", "TLS", "TTLS", "PWD", "SIM", "AKA", "AKA'", "WFA-UNAUTH-TLS",
-                        "WAPI_CERT" };
-
-        /** Prevent initialization */
-        private Eap() {}
-    }
-
-    /** The inner authentication method used */
-    public static final class Phase2 {
-        public static final int NONE        = 0;
-        /** Password Authentication Protocol */
-        public static final int PAP         = 1;
-        /** Microsoft Challenge Handshake Authentication Protocol */
-        public static final int MSCHAP      = 2;
-        /** Microsoft Challenge Handshake Authentication Protocol v2 */
-        public static final int MSCHAPV2    = 3;
-        /** Generic Token Card */
-        public static final int GTC         = 4;
-        /** EAP-Subscriber Identity Module [RFC-4186] */
-        public static final int SIM         = 5;
-        /** EAP-Authentication and Key Agreement [RFC-4187] */
-        public static final int AKA         = 6;
-        /** EAP-Authentication and Key Agreement Prime [RFC-5448] */
-        public static final int AKA_PRIME   = 7;
-        private static final String AUTH_PREFIX = "auth=";
-        private static final String AUTHEAP_PREFIX = "autheap=";
-        /** @hide */
-        public static final String[] strings = {EMPTY_VALUE, "PAP", "MSCHAP",
-                "MSCHAPV2", "GTC", "SIM", "AKA", "AKA'" };
-
-        /** Prevent initialization */
-        private Phase2() {}
-    }
-
-    // Loader and saver interfaces for exchanging data with wpa_supplicant.
-    // TODO: Decouple this object (which is just a placeholder of the configuration)
-    // from the implementation that knows what wpa_supplicant wants.
-    /**
-     * Interface used for retrieving supplicant configuration from WifiEnterpriseConfig
-     * @hide
-     */
-    public interface SupplicantSaver {
-        /**
-         * Set a value within wpa_supplicant configuration
-         * @param key index to set within wpa_supplciant
-         * @param value the value for the key
-         * @return true if successful; false otherwise
-         */
-        boolean saveValue(String key, String value);
-    }
-
-    /**
-     * Interface used for populating a WifiEnterpriseConfig from supplicant configuration
-     * @hide
-     */
-    public interface SupplicantLoader {
-        /**
-         * Returns a value within wpa_supplicant configuration
-         * @param key index to set within wpa_supplciant
-         * @return string value if successful; null otherwise
-         */
-        String loadValue(String key);
-    }
-
-    /**
-     * Internal use only; supply field values to wpa_supplicant config.  The configuration
-     * process aborts on the first failed call on {@code saver}.
-     * @param saver proxy for setting configuration in wpa_supplciant
-     * @return whether the save succeeded on all attempts
-     * @hide
-     */
-    public boolean saveToSupplicant(SupplicantSaver saver) {
-        if (!isEapMethodValid()) {
-            return false;
-        }
-
-        // wpa_supplicant can update the anonymous identity for these kinds of networks after
-        // framework reads them, so make sure the framework doesn't try to overwrite them.
-        boolean shouldNotWriteAnonIdentity = mEapMethod == WifiEnterpriseConfig.Eap.SIM
-                || mEapMethod == WifiEnterpriseConfig.Eap.AKA
-                || mEapMethod == WifiEnterpriseConfig.Eap.AKA_PRIME;
-        for (String key : mFields.keySet()) {
-            if (shouldNotWriteAnonIdentity && ANON_IDENTITY_KEY.equals(key)) {
-                continue;
-            }
-            if (!saver.saveValue(key, mFields.get(key))) {
-                return false;
-            }
-        }
-
-        if (!saver.saveValue(EAP_KEY, Eap.strings[mEapMethod])) {
-            return false;
-        }
-
-        if (mEapMethod != Eap.TLS && mEapMethod != Eap.UNAUTH_TLS && mPhase2Method != Phase2.NONE) {
-            boolean is_autheap = mEapMethod == Eap.TTLS && mPhase2Method == Phase2.GTC;
-            String prefix = is_autheap ? Phase2.AUTHEAP_PREFIX : Phase2.AUTH_PREFIX;
-            String value = convertToQuotedString(prefix + Phase2.strings[mPhase2Method]);
-            return saver.saveValue(PHASE2_KEY, value);
-        } else if (mPhase2Method == Phase2.NONE) {
-            // By default, send a null phase 2 to clear old configuration values.
-            return saver.saveValue(PHASE2_KEY, null);
-        } else {
-            Log.e(TAG, "WiFi enterprise configuration is invalid as it supplies a "
-                    + "phase 2 method but the phase1 method does not support it.");
-            return false;
-        }
-    }
-
-    /**
-     * Internal use only; retrieve configuration from wpa_supplicant config.
-     * @param loader proxy for retrieving configuration keys from wpa_supplicant
-     * @hide
-     */
-    public void loadFromSupplicant(SupplicantLoader loader) {
-        for (String key : SUPPLICANT_CONFIG_KEYS) {
-            String value = loader.loadValue(key);
-            if (value == null) {
-                mFields.put(key, EMPTY_VALUE);
-            } else {
-                mFields.put(key, value);
-            }
-        }
-        String eapMethod  = loader.loadValue(EAP_KEY);
-        mEapMethod = getStringIndex(Eap.strings, eapMethod, Eap.NONE);
-
-        String phase2Method = removeDoubleQuotes(loader.loadValue(PHASE2_KEY));
-        // Remove "auth=" or "autheap=" prefix.
-        if (phase2Method.startsWith(Phase2.AUTH_PREFIX)) {
-            phase2Method = phase2Method.substring(Phase2.AUTH_PREFIX.length());
-        } else if (phase2Method.startsWith(Phase2.AUTHEAP_PREFIX)) {
-            phase2Method = phase2Method.substring(Phase2.AUTHEAP_PREFIX.length());
-        }
-        mPhase2Method = getStringIndex(Phase2.strings, phase2Method, Phase2.NONE);
-    }
-
-    /**
-     * Set the EAP authentication method.
-     * @param  eapMethod is one {@link Eap#PEAP}, {@link Eap#TLS}, {@link Eap#TTLS} or
-     *                   {@link Eap#PWD}
-     * @throws IllegalArgumentException on an invalid eap method
-     */
-    public void setEapMethod(int eapMethod) {
-        switch (eapMethod) {
-            /** Valid methods */
-            case Eap.WAPI_CERT:
-                mEapMethod = eapMethod;
-                setPhase2Method(Phase2.NONE);
-                break;
-            case Eap.TLS:
-            case Eap.UNAUTH_TLS:
-                setPhase2Method(Phase2.NONE);
-                /* fall through */
-            case Eap.PEAP:
-            case Eap.PWD:
-            case Eap.TTLS:
-            case Eap.SIM:
-            case Eap.AKA:
-            case Eap.AKA_PRIME:
-                mEapMethod = eapMethod;
-                setFieldValue(OPP_KEY_CACHING, "1");
-                break;
-            default:
-                throw new IllegalArgumentException("Unknown EAP method");
-        }
-    }
-
-    /**
-     * Get the eap method.
-     * @return eap method configured
-     */
-    public int getEapMethod() {
-        return mEapMethod;
-    }
-
-    /**
-     * Set Phase 2 authentication method. Sets the inner authentication method to be used in
-     * phase 2 after setting up a secure channel
-     * @param phase2Method is the inner authentication method and can be one of {@link Phase2#NONE},
-     *                     {@link Phase2#PAP}, {@link Phase2#MSCHAP}, {@link Phase2#MSCHAPV2},
-     *                     {@link Phase2#GTC}
-     * @throws IllegalArgumentException on an invalid phase2 method
-     *
-     */
-    public void setPhase2Method(int phase2Method) {
-        switch (phase2Method) {
-            case Phase2.NONE:
-            case Phase2.PAP:
-            case Phase2.MSCHAP:
-            case Phase2.MSCHAPV2:
-            case Phase2.GTC:
-            case Phase2.SIM:
-            case Phase2.AKA:
-            case Phase2.AKA_PRIME:
-                mPhase2Method = phase2Method;
-                break;
-            default:
-                throw new IllegalArgumentException("Unknown Phase 2 method");
-        }
-    }
-
-    /**
-     * Get the phase 2 authentication method.
-     * @return a phase 2 method defined at {@link Phase2}
-     * */
-    public int getPhase2Method() {
-        return mPhase2Method;
-    }
-
-    /**
-     * Set the identity
-     * @param identity
-     */
-    public void setIdentity(String identity) {
-        setFieldValue(IDENTITY_KEY, identity, "");
-    }
-
-    /**
-     * Get the identity
-     * @return the identity
-     */
-    public String getIdentity() {
-        return getFieldValue(IDENTITY_KEY);
-    }
-
-    /**
-     * Set anonymous identity. This is used as the unencrypted identity with
-     * certain EAP types
-     * @param anonymousIdentity the anonymous identity
-     */
-    public void setAnonymousIdentity(String anonymousIdentity) {
-        setFieldValue(ANON_IDENTITY_KEY, anonymousIdentity);
-    }
-
-    /**
-     * Get the anonymous identity
-     * @return anonymous identity
-     */
-    public String getAnonymousIdentity() {
-        return getFieldValue(ANON_IDENTITY_KEY);
-    }
-
-    /**
-     * Set the password.
-     * @param password the password
-     */
-    public void setPassword(String password) {
-        setFieldValue(PASSWORD_KEY, password);
-    }
-
-    /**
-     * Get the password.
-     *
-     * Returns locally set password value. For networks fetched from
-     * framework, returns "*".
-     */
-    public String getPassword() {
-        return getFieldValue(PASSWORD_KEY);
-    }
-
-    /**
-     * Encode a CA certificate alias so it does not contain illegal character.
-     * @hide
-     */
-    public static String encodeCaCertificateAlias(String alias) {
-        byte[] bytes = alias.getBytes(StandardCharsets.UTF_8);
-        StringBuilder sb = new StringBuilder(bytes.length * 2);
-        for (byte o : bytes) {
-            sb.append(String.format("%02x", o & 0xFF));
-        }
-        return sb.toString();
-    }
-
-    /**
-     * Decode a previously-encoded CA certificate alias.
-     * @hide
-     */
-    public static String decodeCaCertificateAlias(String alias) {
-        byte[] data = new byte[alias.length() >> 1];
-        for (int n = 0, position = 0; n < alias.length(); n += 2, position++) {
-            data[position] = (byte) Integer.parseInt(alias.substring(n,  n + 2), 16);
-        }
-        try {
-            return new String(data, StandardCharsets.UTF_8);
-        } catch (NumberFormatException e) {
-            e.printStackTrace();
-            return alias;
-        }
-    }
-
-    /**
-     * Set CA certificate alias.
-     *
-     * <p> See the {@link android.security.KeyChain} for details on installing or choosing
-     * a certificate
-     * </p>
-     * @param alias identifies the certificate
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public void setCaCertificateAlias(String alias) {
-        setFieldValue(CA_CERT_KEY, alias, CA_CERT_PREFIX);
-    }
-
-    /**
-     * Set CA certificate aliases. When creating installing the corresponding certificate to
-     * the keystore, please use alias encoded by {@link #encodeCaCertificateAlias(String)}.
-     *
-     * <p> See the {@link android.security.KeyChain} for details on installing or choosing
-     * a certificate.
-     * </p>
-     * @param aliases identifies the certificate. Can be null to indicate the absence of a
-     *                certificate.
-     * @hide
-     */
-    @SystemApi
-    public void setCaCertificateAliases(@Nullable String[] aliases) {
-        if (aliases == null) {
-            setFieldValue(CA_CERT_KEY, null, CA_CERT_PREFIX);
-        } else if (aliases.length == 1) {
-            // Backwards compatibility: use the original cert prefix if setting only one alias.
-            setCaCertificateAlias(aliases[0]);
-        } else {
-            // Use KEYSTORES_URI which supports multiple aliases.
-            StringBuilder sb = new StringBuilder();
-            for (int i = 0; i < aliases.length; i++) {
-                if (i > 0) {
-                    sb.append(CA_CERT_ALIAS_DELIMITER);
-                }
-                sb.append(encodeCaCertificateAlias(CA_CERTIFICATE + aliases[i]));
-            }
-            setFieldValue(CA_CERT_KEY, sb.toString(), KEYSTORES_URI);
-        }
-    }
-
-    /**
-     * Get CA certificate alias
-     * @return alias to the CA certificate
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public String getCaCertificateAlias() {
-        return getFieldValue(CA_CERT_KEY, CA_CERT_PREFIX);
-    }
-
-    /**
-     * Get CA certificate aliases.
-     * @return alias to the CA certificate, or null if unset.
-     * @hide
-     */
-    @Nullable
-    @SystemApi
-    public String[] getCaCertificateAliases() {
-        String value = getFieldValue(CA_CERT_KEY);
-        if (value.startsWith(CA_CERT_PREFIX)) {
-            // Backwards compatibility: parse the original alias prefix.
-            return new String[] {getFieldValue(CA_CERT_KEY, CA_CERT_PREFIX)};
-        } else if (value.startsWith(KEYSTORES_URI)) {
-            String values = value.substring(KEYSTORES_URI.length());
-
-            String[] aliases = TextUtils.split(values, CA_CERT_ALIAS_DELIMITER);
-            for (int i = 0; i < aliases.length; i++) {
-                aliases[i] = decodeCaCertificateAlias(aliases[i]);
-                if (aliases[i].startsWith(CA_CERTIFICATE)) {
-                    aliases[i] = aliases[i].substring(CA_CERTIFICATE.length());
-                }
-            }
-            return aliases.length != 0 ? aliases : null;
-        } else {
-            return TextUtils.isEmpty(value) ? null : new String[] {value};
-        }
-    }
-
-    /**
-     * Specify a X.509 certificate that identifies the server.
-     *
-     * <p>A default name is automatically assigned to the certificate and used
-     * with this configuration. The framework takes care of installing the
-     * certificate when the config is saved and removing the certificate when
-     * the config is removed.
-     *
-     * Note: If no certificate is set for an Enterprise configuration, either by not calling this
-     * API (or the {@link #setCaCertificates(X509Certificate[])}, or by calling it with null, then
-     * the server certificate validation is skipped - which means that the connection is not secure.
-     *
-     * @param cert X.509 CA certificate
-     * @throws IllegalArgumentException if not a CA certificate
-     */
-    public void setCaCertificate(@Nullable X509Certificate cert) {
-        if (cert != null) {
-            if (cert.getBasicConstraints() >= 0) {
-                mIsAppInstalledCaCert = true;
-                mCaCerts = new X509Certificate[] {cert};
-            } else {
-                mCaCerts = null;
-                throw new IllegalArgumentException("Not a CA certificate");
-            }
-        } else {
-            mCaCerts = null;
-        }
-    }
-
-    /**
-     * Get CA certificate. If multiple CA certificates are configured previously,
-     * return the first one.
-     * @return X.509 CA certificate
-     */
-    @Nullable public X509Certificate getCaCertificate() {
-        if (mCaCerts != null && mCaCerts.length > 0) {
-            return mCaCerts[0];
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Specify a list of X.509 certificates that identifies the server. The validation
-     * passes if the CA of server certificate matches one of the given certificates.
-
-     * <p>Default names are automatically assigned to the certificates and used
-     * with this configuration. The framework takes care of installing the
-     * certificates when the config is saved and removing the certificates when
-     * the config is removed.
-     *
-     * Note: If no certificates are set for an Enterprise configuration, either by not calling this
-     * API (or the {@link #setCaCertificate(X509Certificate)}, or by calling it with null, then the
-     * server certificate validation is skipped - which means that the
-     * connection is not secure.
-     *
-     * @param certs X.509 CA certificates
-     * @throws IllegalArgumentException if any of the provided certificates is
-     *     not a CA certificate
-     */
-    public void setCaCertificates(@Nullable X509Certificate[] certs) {
-        if (certs != null) {
-            X509Certificate[] newCerts = new X509Certificate[certs.length];
-            for (int i = 0; i < certs.length; i++) {
-                if (certs[i].getBasicConstraints() >= 0) {
-                    newCerts[i] = certs[i];
-                } else {
-                    mCaCerts = null;
-                    throw new IllegalArgumentException("Not a CA certificate");
-                }
-            }
-            mCaCerts = newCerts;
-            mIsAppInstalledCaCert = true;
-        } else {
-            mCaCerts = null;
-        }
-    }
-
-    /**
-     * Get CA certificates.
-     */
-    @Nullable public X509Certificate[] getCaCertificates() {
-        if (mCaCerts != null && mCaCerts.length > 0) {
-            return mCaCerts;
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * @hide
-     */
-    public void resetCaCertificate() {
-        mCaCerts = null;
-    }
-
-    /**
-     * Set the ca_path directive on wpa_supplicant.
-     *
-     * From wpa_supplicant documentation:
-     *
-     * Directory path for CA certificate files (PEM). This path may contain
-     * multiple CA certificates in OpenSSL format. Common use for this is to
-     * point to system trusted CA list which is often installed into directory
-     * like /etc/ssl/certs. If configured, these certificates are added to the
-     * list of trusted CAs. ca_cert may also be included in that case, but it is
-     * not required.
-     *
-     * Note: If no certificate path is set for an Enterprise configuration, either by not calling
-     * this API, or by calling it with null, and no certificate is set by
-     * {@link #setCaCertificate(X509Certificate)} or {@link #setCaCertificates(X509Certificate[])},
-     * then the server certificate validation is skipped - which means that the connection is not
-     * secure.
-     *
-     * @param path The path for CA certificate files, or empty string to clear.
-     * @hide
-     */
-    @SystemApi
-    public void setCaPath(@NonNull String path) {
-        setFieldValue(CA_PATH_KEY, path);
-    }
-
-    /**
-     * Get the ca_path directive from wpa_supplicant.
-     * @return The path for CA certificate files, or an empty string if unset.
-     * @hide
-     */
-    @NonNull
-    @SystemApi
-    public String getCaPath() {
-        return getFieldValue(CA_PATH_KEY);
-    }
-
-    /**
-     * Set Client certificate alias.
-     *
-     * <p> See the {@link android.security.KeyChain} for details on installing or choosing
-     * a certificate
-     * </p>
-     * @param alias identifies the certificate, or empty string to clear.
-     * @hide
-     */
-    @SystemApi
-    public void setClientCertificateAlias(@NonNull String alias) {
-        setFieldValue(CLIENT_CERT_KEY, alias, CLIENT_CERT_PREFIX);
-        setFieldValue(PRIVATE_KEY_ID_KEY, alias, USER_PRIVATE_KEY);
-        // Also, set engine parameters
-        if (TextUtils.isEmpty(alias)) {
-            setFieldValue(ENGINE_KEY, ENGINE_DISABLE);
-            setFieldValue(ENGINE_ID_KEY, "");
-        } else {
-            setFieldValue(ENGINE_KEY, ENGINE_ENABLE);
-            setFieldValue(ENGINE_ID_KEY, ENGINE_ID_KEYSTORE);
-        }
-    }
-
-    /**
-     * Get client certificate alias.
-     * @return alias to the client certificate, or an empty string if unset.
-     * @hide
-     */
-    @NonNull
-    @SystemApi
-    public String getClientCertificateAlias() {
-        return getFieldValue(CLIENT_CERT_KEY, CLIENT_CERT_PREFIX);
-    }
-
-    /**
-     * Specify a private key and client certificate for client authorization.
-     *
-     * <p>A default name is automatically assigned to the key entry and used
-     * with this configuration.  The framework takes care of installing the
-     * key entry when the config is saved and removing the key entry when
-     * the config is removed.
-
-     * @param privateKey a PrivateKey instance for the end certificate.
-     * @param clientCertificate an X509Certificate representing the end certificate.
-     * @throws IllegalArgumentException for an invalid key or certificate.
-     */
-    public void setClientKeyEntry(PrivateKey privateKey, X509Certificate clientCertificate) {
-        X509Certificate[] clientCertificates = null;
-        if (clientCertificate != null) {
-            clientCertificates = new X509Certificate[] {clientCertificate};
-        }
-        setClientKeyEntryWithCertificateChain(privateKey, clientCertificates);
-    }
-
-    /**
-     * Specify a private key and client certificate chain for client authorization.
-     *
-     * <p>A default name is automatically assigned to the key entry and used
-     * with this configuration.  The framework takes care of installing the
-     * key entry when the config is saved and removing the key entry when
-     * the config is removed.
-     *
-     * @param privateKey a PrivateKey instance for the end certificate.
-     * @param clientCertificateChain an array of X509Certificate instances which starts with
-     *         end certificate and continues with additional CA certificates necessary to
-     *         link the end certificate with some root certificate known by the authenticator.
-     * @throws IllegalArgumentException for an invalid key or certificate.
-     */
-    public void setClientKeyEntryWithCertificateChain(PrivateKey privateKey,
-            X509Certificate[] clientCertificateChain) {
-        X509Certificate[] newCerts = null;
-        if (clientCertificateChain != null && clientCertificateChain.length > 0) {
-            // We validate that this is a well formed chain that starts
-            // with an end-certificate and is followed by CA certificates.
-            // We don't validate that each following certificate verifies
-            // the previous. https://en.wikipedia.org/wiki/Chain_of_trust
-            //
-            // Basic constraints is an X.509 extension type that defines
-            // whether a given certificate is allowed to sign additional
-            // certificates and what path length restrictions may exist.
-            // We use this to judge whether the certificate is an end
-            // certificate or a CA certificate.
-            // https://cryptography.io/en/latest/x509/reference/
-            if (clientCertificateChain[0].getBasicConstraints() != -1) {
-                throw new IllegalArgumentException(
-                        "First certificate in the chain must be a client end certificate");
-            }
-
-            for (int i = 1; i < clientCertificateChain.length; i++) {
-                if (clientCertificateChain[i].getBasicConstraints() == -1) {
-                    throw new IllegalArgumentException(
-                            "All certificates following the first must be CA certificates");
-                }
-            }
-            newCerts = Arrays.copyOf(clientCertificateChain,
-                    clientCertificateChain.length);
-
-            if (privateKey == null) {
-                throw new IllegalArgumentException("Client cert without a private key");
-            }
-            if (privateKey.getEncoded() == null) {
-                throw new IllegalArgumentException("Private key cannot be encoded");
-            }
-        }
-
-        mClientPrivateKey = privateKey;
-        mClientCertificateChain = newCerts;
-        mIsAppInstalledDeviceKeyAndCert = true;
-    }
-
-    /**
-     * Get client certificate
-     *
-     * @return X.509 client certificate
-     */
-    public X509Certificate getClientCertificate() {
-        if (mClientCertificateChain != null && mClientCertificateChain.length > 0) {
-            return mClientCertificateChain[0];
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Get the complete client certificate chain in the same order as it was last supplied.
-     *
-     * <p>If the chain was last supplied by a call to
-     * {@link #setClientKeyEntry(java.security.PrivateKey, java.security.cert.X509Certificate)}
-     * with a non-null * certificate instance, a single-element array containing the certificate
-     * will be * returned. If {@link #setClientKeyEntryWithCertificateChain(
-     * java.security.PrivateKey, java.security.cert.X509Certificate[])} was last called with a
-     * non-empty array, this array will be returned in the same order as it was supplied.
-     * Otherwise, {@code null} will be returned.
-     *
-     * @return X.509 client certificates
-     */
-    @Nullable public X509Certificate[] getClientCertificateChain() {
-        if (mClientCertificateChain != null && mClientCertificateChain.length > 0) {
-            return mClientCertificateChain;
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * @hide
-     */
-    public void resetClientKeyEntry() {
-        mClientPrivateKey = null;
-        mClientCertificateChain = null;
-    }
-
-    /**
-     * Get the client private key as supplied in {@link #setClientKeyEntryWithCertificateChain}, or
-     * null if unset.
-     */
-    @Nullable
-    public PrivateKey getClientPrivateKey() {
-        return mClientPrivateKey;
-    }
-
-    /**
-     * Set subject match (deprecated). This is the substring to be matched against the subject of
-     * the authentication server certificate.
-     * @param subjectMatch substring to be matched
-     * @deprecated in favor of altSubjectMatch
-     */
-    public void setSubjectMatch(String subjectMatch) {
-        setFieldValue(SUBJECT_MATCH_KEY, subjectMatch);
-    }
-
-    /**
-     * Get subject match (deprecated)
-     * @return the subject match string
-     * @deprecated in favor of altSubjectMatch
-     */
-    public String getSubjectMatch() {
-        return getFieldValue(SUBJECT_MATCH_KEY);
-    }
-
-    /**
-     * Set alternate subject match. This is the substring to be matched against the
-     * alternate subject of the authentication server certificate.
-     *
-     * Note: If no alternate subject is set for an Enterprise configuration, either by not calling
-     * this API, or by calling it with null, or not setting domain suffix match using the
-     * {@link #setDomainSuffixMatch(String)}, then the server certificate validation is incomplete -
-     * which means that the connection is not secure.
-     *
-     * @param altSubjectMatch substring to be matched, for example
-     *                     DNS:server.example.com;EMAIL:server@example.com
-     */
-    public void setAltSubjectMatch(String altSubjectMatch) {
-        setFieldValue(ALTSUBJECT_MATCH_KEY, altSubjectMatch);
-    }
-
-    /**
-     * Get alternate subject match
-     * @return the alternate subject match string
-     */
-    public String getAltSubjectMatch() {
-        return getFieldValue(ALTSUBJECT_MATCH_KEY);
-    }
-
-    /**
-     * Set the domain_suffix_match directive on wpa_supplicant. This is the parameter to use
-     * for Hotspot 2.0 defined matching of AAA server certs per WFA HS2.0 spec, section 7.3.3.2,
-     * second paragraph.
-     *
-     * <p>From wpa_supplicant documentation:
-     * <p>Constraint for server domain name. If set, this FQDN is used as a suffix match requirement
-     * for the AAAserver certificate in SubjectAltName dNSName element(s). If a matching dNSName is
-     * found, this constraint is met.
-     * <p>Suffix match here means that the host/domain name is compared one label at a time starting
-     * from the top-level domain and all the labels in domain_suffix_match shall be included in the
-     * certificate. The certificate may include additional sub-level labels in addition to the
-     * required labels.
-     * <p>More than one match string can be provided by using semicolons to separate the strings
-     * (e.g., example.org;example.com). When multiple strings are specified, a match with any one of
-     * the values is considered a sufficient match for the certificate, i.e., the conditions are
-     * ORed ogether.
-     * <p>For example, domain_suffix_match=example.com would match test.example.com but would not
-     * match test-example.com.
-     *
-     * Note: If no domain suffix is set for an Enterprise configuration, either by not calling this
-     * API, or by calling it with null, or not setting alternate subject match using the
-     * {@link #setAltSubjectMatch(String)}, then the server certificate
-     * validation is incomplete - which means that the connection is not secure.
-     *
-     * @param domain The domain value
-     */
-    public void setDomainSuffixMatch(String domain) {
-        setFieldValue(DOM_SUFFIX_MATCH_KEY, domain);
-    }
-
-    /**
-     * Get the domain_suffix_match value. See setDomSuffixMatch.
-     * @return The domain value.
-     */
-    public String getDomainSuffixMatch() {
-        return getFieldValue(DOM_SUFFIX_MATCH_KEY);
-    }
-
-    /**
-     * Set realm for Passpoint credential; realm identifies a set of networks where your
-     * Passpoint credential can be used
-     * @param realm the realm
-     */
-    public void setRealm(String realm) {
-        setFieldValue(REALM_KEY, realm);
-    }
-
-    /**
-     * Get realm for Passpoint credential; see {@link #setRealm(String)} for more information
-     * @return the realm
-     */
-    public String getRealm() {
-        return getFieldValue(REALM_KEY);
-    }
-
-    /**
-     * Set plmn (Public Land Mobile Network) of the provider of Passpoint credential
-     * @param plmn the plmn value derived from mcc (mobile country code) & mnc (mobile network code)
-     */
-    public void setPlmn(String plmn) {
-        setFieldValue(PLMN_KEY, plmn);
-    }
-
-    /**
-     * Get plmn (Public Land Mobile Network) for Passpoint credential; see {@link #setPlmn
-     * (String)} for more information
-     * @return the plmn
-     */
-    public String getPlmn() {
-        return getFieldValue(PLMN_KEY);
-    }
-
-    /** See {@link WifiConfiguration#getKeyIdForCredentials} @hide */
-    public String getKeyId(WifiEnterpriseConfig current) {
-        // If EAP method is not initialized, use current config details
-        if (mEapMethod == Eap.NONE) {
-            return (current != null) ? current.getKeyId(null) : EMPTY_VALUE;
-        }
-        if (!isEapMethodValid()) {
-            return EMPTY_VALUE;
-        }
-        return Eap.strings[mEapMethod] + "_" + Phase2.strings[mPhase2Method];
-    }
-
-    private String removeDoubleQuotes(String string) {
-        if (TextUtils.isEmpty(string)) return "";
-        int length = string.length();
-        if ((length > 1) && (string.charAt(0) == '"')
-                && (string.charAt(length - 1) == '"')) {
-            return string.substring(1, length - 1);
-        }
-        return string;
-    }
-
-    private String convertToQuotedString(String string) {
-        return "\"" + string + "\"";
-    }
-
-    /**
-     * Returns the index at which the toBeFound string is found in the array.
-     * @param arr array of strings
-     * @param toBeFound string to be found
-     * @param defaultIndex default index to be returned when string is not found
-     * @return the index into array
-     */
-    private int getStringIndex(String arr[], String toBeFound, int defaultIndex) {
-        if (TextUtils.isEmpty(toBeFound)) return defaultIndex;
-        for (int i = 0; i < arr.length; i++) {
-            if (toBeFound.equals(arr[i])) return i;
-        }
-        return defaultIndex;
-    }
-
-    /**
-     * Returns the field value for the key with prefix removed.
-     * @param key into the hash
-     * @param prefix is the prefix that the value may have
-     * @return value
-     * @hide
-     */
-    private String getFieldValue(String key, String prefix) {
-        // TODO: Should raise an exception if |key| is EAP_KEY or PHASE2_KEY since
-        // neither of these keys should be retrieved in this manner.
-        String value = mFields.get(key);
-        // Uninitialized or known to be empty after reading from supplicant
-        if (TextUtils.isEmpty(value) || EMPTY_VALUE.equals(value)) return "";
-
-        value = removeDoubleQuotes(value);
-        if (value.startsWith(prefix)) {
-            return value.substring(prefix.length());
-        } else {
-            return value;
-        }
-    }
-
-    /**
-     * Returns the field value for the key.
-     * @param key into the hash
-     * @return value
-     * @hide
-     */
-    public String getFieldValue(String key) {
-        return getFieldValue(key, "");
-    }
-
-    /**
-     * Set a value with an optional prefix at key
-     * @param key into the hash
-     * @param value to be set
-     * @param prefix an optional value to be prefixed to actual value
-     * @hide
-     */
-    private void setFieldValue(String key, String value, String prefix) {
-        // TODO: Should raise an exception if |key| is EAP_KEY or PHASE2_KEY since
-        // neither of these keys should be set in this manner.
-        if (TextUtils.isEmpty(value)) {
-            mFields.put(key, EMPTY_VALUE);
-        } else {
-            String valueToSet;
-            if (!UNQUOTED_KEYS.contains(key)) {
-                valueToSet = convertToQuotedString(prefix + value);
-            } else {
-                valueToSet = prefix + value;
-            }
-            mFields.put(key, valueToSet);
-        }
-    }
-
-    /**
-     * Set a value at key
-     * @param key into the hash
-     * @param value to be set
-     * @hide
-     */
-    public void setFieldValue(String key, String value) {
-        setFieldValue(key, value, "");
-    }
-
-    @Override
-    public String toString() {
-        StringBuffer sb = new StringBuffer();
-        for (String key : mFields.keySet()) {
-            // Don't display password in toString().
-            String value = PASSWORD_KEY.equals(key) ? "<removed>" : mFields.get(key);
-            sb.append(key).append(" ").append(value).append("\n");
-        }
-        if (mEapMethod >= 0 && mEapMethod < Eap.strings.length) {
-            sb.append("eap_method: ").append(Eap.strings[mEapMethod]).append("\n");
-        }
-        if (mPhase2Method > 0 && mPhase2Method < Phase2.strings.length) {
-            sb.append("phase2_method: ").append(Phase2.strings[mPhase2Method]).append("\n");
-        }
-        sb.append(" ocsp: ").append(mOcsp).append("\n");
-        return sb.toString();
-    }
-
-    /**
-     * Returns whether the EAP method data is valid, i.e., whether mEapMethod and mPhase2Method
-     * are valid indices into {@code Eap.strings[]} and {@code Phase2.strings[]} respectively.
-     */
-    private boolean isEapMethodValid() {
-        if (mEapMethod == Eap.NONE) {
-            Log.e(TAG, "WiFi enterprise configuration is invalid as it supplies no EAP method.");
-            return false;
-        }
-        if (mEapMethod < 0 || mEapMethod >= Eap.strings.length) {
-            Log.e(TAG, "mEapMethod is invald for WiFi enterprise configuration: " + mEapMethod);
-            return false;
-        }
-        if (mPhase2Method < 0 || mPhase2Method >= Phase2.strings.length) {
-            Log.e(TAG, "mPhase2Method is invald for WiFi enterprise configuration: "
-                    + mPhase2Method);
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Check if certificate was installed by an app, or manually (not by an app). If true,
-     * certificate and keys will be removed from key storage when this network is removed. If not,
-     * then certificates and keys remain persistent until the user manually removes them.
-     *
-     * @return true if certificate was installed by an app, false if certificate was installed
-     * manually by the user.
-     * @hide
-     */
-    public boolean isAppInstalledDeviceKeyAndCert() {
-        return mIsAppInstalledDeviceKeyAndCert;
-    }
-
-    /**
-     * Initialize the value of the app installed device key and cert flag.
-     *
-     * @param isAppInstalledDeviceKeyAndCert true or false
-     * @hide
-     */
-    public void initIsAppInstalledDeviceKeyAndCert(boolean isAppInstalledDeviceKeyAndCert) {
-        mIsAppInstalledDeviceKeyAndCert = isAppInstalledDeviceKeyAndCert;
-    }
-
-    /**
-     * Check if CA certificate was installed by an app, or manually (not by an app). If true,
-     * CA certificate will be removed from key storage when this network is removed. If not,
-     * then certificates and keys remain persistent until the user manually removes them.
-     *
-     * @return true if CA certificate was installed by an app, false if CA certificate was installed
-     * manually by the user.
-     * @hide
-     */
-    public boolean isAppInstalledCaCert() {
-        return mIsAppInstalledCaCert;
-    }
-
-    /**
-     * Initialize the value of the app installed root CA cert flag.
-     *
-     * @param isAppInstalledCaCert true or false
-     * @hide
-     */
-    public void initIsAppInstalledCaCert(boolean isAppInstalledCaCert) {
-        mIsAppInstalledCaCert = isAppInstalledCaCert;
-    }
-
-    /**
-     * Set the OCSP type.
-     * @param ocsp is one of {@link ##OCSP_NONE}, {@link #OCSP_REQUEST_CERT_STATUS},
-     *                   {@link #OCSP_REQUIRE_CERT_STATUS} or
-     *                   {@link #OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS}
-     * @throws IllegalArgumentException if the OCSP type is invalid
-     * @hide
-     */
-    @SystemApi
-    public void setOcsp(@Ocsp int ocsp) {
-        if (ocsp >= OCSP_NONE && ocsp <= OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS) {
-            mOcsp = ocsp;
-        } else {
-            throw new IllegalArgumentException("Invalid OCSP type.");
-        }
-    }
-
-    /**
-     * Get the OCSP type.
-     * @hide
-     */
-    @SystemApi
-    public @Ocsp int getOcsp() {
-        return mOcsp;
-    }
-
-    /**
-     * Utility method to determine whether the configuration's authentication method is SIM-based.
-     *
-     * @return true if the credential information requires SIM card for current authentication
-     * method, otherwise it returns false.
-     */
-    public boolean isAuthenticationSimBased() {
-        if (mEapMethod == Eap.SIM || mEapMethod == Eap.AKA || mEapMethod == Eap.AKA_PRIME) {
-            return true;
-        }
-        if (mEapMethod == Eap.PEAP) {
-            return mPhase2Method == Phase2.SIM || mPhase2Method == Phase2.AKA
-                    || mPhase2Method == Phase2.AKA_PRIME;
-        }
-        return false;
-    }
-
-    /**
-     * Set the WAPI certificate suite name on wpa_supplicant.
-     *
-     * If this field is not specified, WAPI-CERT uses ASU ID from WAI packet
-     * as the certificate suite name automatically.
-     *
-     * @param wapiCertSuite The name for WAPI certificate suite, or empty string to clear.
-     * @hide
-     */
-    @SystemApi
-    public void setWapiCertSuite(@NonNull String wapiCertSuite) {
-        setFieldValue(WAPI_CERT_SUITE_KEY, wapiCertSuite);
-    }
-
-    /**
-     * Get the WAPI certificate suite name
-     * @return the certificate suite name
-     * @hide
-     */
-    @NonNull
-    @SystemApi
-    public String getWapiCertSuite() {
-        return getFieldValue(WAPI_CERT_SUITE_KEY);
-    }
-
-    /**
-     * Method determines whether the Enterprise configuration is insecure. An insecure
-     * configuration is one where EAP method requires a CA certification, i.e. PEAP, TLS, or
-     * TTLS, and any of the following conditions are met:
-     * - Both certificate and CA path are not configured.
-     * - Both alternative subject match and domain suffix match are not set.
-     *
-     * Note: this method does not exhaustively check security of the configuration - i.e. a return
-     * value of {@code false} is not a guarantee that the configuration is secure.
-     * @hide
-     */
-    public boolean isInsecure() {
-        if (mEapMethod != Eap.PEAP && mEapMethod != Eap.TLS && mEapMethod != Eap.TTLS) {
-            return false;
-        }
-        if (TextUtils.isEmpty(getAltSubjectMatch())
-                && TextUtils.isEmpty(getDomainSuffixMatch())) {
-            // Both subject and domain match are not set, it's insecure.
-            return true;
-        }
-        if (mIsAppInstalledCaCert) {
-            // CA certificate is installed by App, it's secure.
-            return false;
-        }
-        if (getCaCertificateAliases() != null) {
-            // CA certificate alias from keyStore is set, it's secure.
-            return false;
-        }
-        return TextUtils.isEmpty(getCaPath());
-    }
-
-    /**
-     * Check if a given certificate Get the Suite-B cipher from the certificate
-     *
-     * @param x509Certificate Certificate to process
-     * @return true if the certificate OID matches the Suite-B requirements for RSA or ECDSA
-     * certificates, or false otherwise.
-     * @hide
-     */
-    public static boolean isSuiteBCipherCert(@Nullable X509Certificate x509Certificate) {
-        if (x509Certificate == null) {
-            return false;
-        }
-        final String sigAlgOid = x509Certificate.getSigAlgOID();
-
-        // Wi-Fi alliance requires the use of both ECDSA secp384r1 and RSA 3072 certificates
-        // in WPA3-Enterprise 192-bit security networks, which are also known as Suite-B-192
-        // networks, even though NSA Suite-B-192 mandates ECDSA only. The use of the term
-        // Suite-B was already coined in the IEEE 802.11-2016 specification for
-        // AKM 00-0F-AC but the test plan for WPA3-Enterprise 192-bit for APs mandates
-        // support for both RSA and ECDSA, and for STAs it mandates ECDSA and optionally
-        // RSA. In order to be compatible with all WPA3-Enterprise 192-bit deployments,
-        // we are supporting both types here.
-        if (sigAlgOid.equals("1.2.840.113549.1.1.12")) {
-            // sha384WithRSAEncryption
-            if (x509Certificate.getPublicKey() instanceof RSAPublicKey) {
-                final RSAPublicKey rsaPublicKey = (RSAPublicKey) x509Certificate.getPublicKey();
-                if (rsaPublicKey.getModulus() != null
-                        && rsaPublicKey.getModulus().bitLength() >= 3072) {
-                    return true;
-                }
-            }
-        } else if (sigAlgOid.equals("1.2.840.10045.4.3.3")) {
-            // ecdsa-with-SHA384
-            if (x509Certificate.getPublicKey() instanceof ECPublicKey) {
-                final ECPublicKey ecPublicKey = (ECPublicKey) x509Certificate.getPublicKey();
-                final ECParameterSpec ecParameterSpec = ecPublicKey.getParams();
-
-                if (ecParameterSpec != null && ecParameterSpec.getOrder() != null
-                        && ecParameterSpec.getOrder().bitLength() >= 384) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-}
diff --git a/wifi/java/android/net/wifi/WifiFrameworkInitializer.java b/wifi/java/android/net/wifi/WifiFrameworkInitializer.java
deleted file mode 100644
index 1507199..0000000
--- a/wifi/java/android/net/wifi/WifiFrameworkInitializer.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.net.wifi;
-
-import android.annotation.SystemApi;
-import android.app.SystemServiceRegistry;
-import android.content.Context;
-import android.net.wifi.aware.IWifiAwareManager;
-import android.net.wifi.aware.WifiAwareManager;
-import android.net.wifi.p2p.IWifiP2pManager;
-import android.net.wifi.p2p.WifiP2pManager;
-import android.net.wifi.rtt.IWifiRttManager;
-import android.net.wifi.rtt.WifiRttManager;
-import android.os.HandlerThread;
-import android.os.Looper;
-
-/**
- * Class for performing registration for all Wifi services.
- *
- * @hide
- */
-@SystemApi
-public class WifiFrameworkInitializer {
-
-    /**
-     * A class implementing the lazy holder idiom: the unique static instance
-     * of {@link #INSTANCE} is instantiated in a thread-safe way (guaranteed by
-     * the language specs) the first time that NoPreloadHolder is referenced in getInstanceLooper().
-     *
-     * This is necessary because we can't spawn a new thread in {@link #registerServiceWrappers()}.
-     * {@link #registerServiceWrappers()} is called during the Zygote phase, which disallows
-     * spawning new threads. Naming the class "NoPreloadHolder" ensures that the classloader will
-     * not preload this class, inadvertently spawning the thread too early.
-     */
-    private static class NoPreloadHolder {
-        private static final HandlerThread INSTANCE = createInstance();
-
-        private static HandlerThread createInstance() {
-            HandlerThread thread = new HandlerThread("WifiManagerThread");
-            thread.start();
-            return thread;
-        }
-    }
-
-    private static Looper getInstanceLooper() {
-        return NoPreloadHolder.INSTANCE.getLooper();
-    }
-
-    private WifiFrameworkInitializer() {}
-
-    /**
-     * Called by {@link SystemServiceRegistry}'s static initializer and registers all Wifi services
-     * to {@link Context}, so that {@link Context#getSystemService} can return them.
-     *
-     * @throws IllegalStateException if this is called from anywhere besides
-     * {@link SystemServiceRegistry}
-     */
-    public static void registerServiceWrappers() {
-        SystemServiceRegistry.registerContextAwareService(
-                Context.WIFI_SERVICE,
-                WifiManager.class,
-                (context, serviceBinder) -> {
-                    IWifiManager service = IWifiManager.Stub.asInterface(serviceBinder);
-                    return new WifiManager(context, service, getInstanceLooper());
-                }
-        );
-        SystemServiceRegistry.registerStaticService(
-                Context.WIFI_P2P_SERVICE,
-                WifiP2pManager.class,
-                serviceBinder -> {
-                    IWifiP2pManager service = IWifiP2pManager.Stub.asInterface(serviceBinder);
-                    return new WifiP2pManager(service);
-                }
-        );
-        SystemServiceRegistry.registerContextAwareService(
-                Context.WIFI_AWARE_SERVICE,
-                WifiAwareManager.class,
-                (context, serviceBinder) -> {
-                    IWifiAwareManager service = IWifiAwareManager.Stub.asInterface(serviceBinder);
-                    return new WifiAwareManager(context, service);
-                }
-        );
-        SystemServiceRegistry.registerContextAwareService(
-                Context.WIFI_SCANNING_SERVICE,
-                WifiScanner.class,
-                (context, serviceBinder) -> {
-                    IWifiScanner service = IWifiScanner.Stub.asInterface(serviceBinder);
-                    return new WifiScanner(context, service, getInstanceLooper());
-                }
-        );
-        SystemServiceRegistry.registerContextAwareService(
-                Context.WIFI_RTT_RANGING_SERVICE,
-                WifiRttManager.class,
-                (context, serviceBinder) -> {
-                    IWifiRttManager service = IWifiRttManager.Stub.asInterface(serviceBinder);
-                    return new WifiRttManager(context, service);
-                }
-        );
-        SystemServiceRegistry.registerContextAwareService(
-                Context.WIFI_RTT_SERVICE,
-                RttManager.class,
-                context -> {
-                    WifiRttManager wifiRttManager = context.getSystemService(WifiRttManager.class);
-                    return new RttManager(context, wifiRttManager);
-                }
-        );
-    }
-}
diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java
deleted file mode 100644
index 5388367..0000000
--- a/wifi/java/android/net/wifi/WifiInfo.java
+++ /dev/null
@@ -1,1051 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import android.annotation.IntRange;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.net.NetworkInfo.DetailedState;
-import android.os.Build;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-
-import com.android.net.module.util.Inet4AddressUtils;
-
-import java.net.Inet4Address;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.EnumMap;
-import java.util.Locale;
-
-/**
- * Describes the state of any Wi-Fi connection that is active or
- * is in the process of being set up.
- */
-public class WifiInfo implements Parcelable {
-    private static final String TAG = "WifiInfo";
-    /**
-     * This is the map described in the Javadoc comment above. The positions
-     * of the elements of the array must correspond to the ordinal values
-     * of <code>DetailedState</code>.
-     */
-    private static final EnumMap<SupplicantState, DetailedState> stateMap =
-            new EnumMap<SupplicantState, DetailedState>(SupplicantState.class);
-
-    /**
-     * Default MAC address reported to a client that does not have the
-     * android.permission.LOCAL_MAC_ADDRESS permission.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final String DEFAULT_MAC_ADDRESS = "02:00:00:00:00:00";
-
-    static {
-        stateMap.put(SupplicantState.DISCONNECTED, DetailedState.DISCONNECTED);
-        stateMap.put(SupplicantState.INTERFACE_DISABLED, DetailedState.DISCONNECTED);
-        stateMap.put(SupplicantState.INACTIVE, DetailedState.IDLE);
-        stateMap.put(SupplicantState.SCANNING, DetailedState.SCANNING);
-        stateMap.put(SupplicantState.AUTHENTICATING, DetailedState.CONNECTING);
-        stateMap.put(SupplicantState.ASSOCIATING, DetailedState.CONNECTING);
-        stateMap.put(SupplicantState.ASSOCIATED, DetailedState.CONNECTING);
-        stateMap.put(SupplicantState.FOUR_WAY_HANDSHAKE, DetailedState.AUTHENTICATING);
-        stateMap.put(SupplicantState.GROUP_HANDSHAKE, DetailedState.AUTHENTICATING);
-        stateMap.put(SupplicantState.COMPLETED, DetailedState.OBTAINING_IPADDR);
-        stateMap.put(SupplicantState.DORMANT, DetailedState.DISCONNECTED);
-        stateMap.put(SupplicantState.UNINITIALIZED, DetailedState.IDLE);
-        stateMap.put(SupplicantState.INVALID, DetailedState.FAILED);
-    }
-
-    private SupplicantState mSupplicantState;
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
-    private String mBSSID;
-    @UnsupportedAppUsage
-    private WifiSsid mWifiSsid;
-    private int mNetworkId;
-
-    /**
-     * Used to indicate that the RSSI is invalid, for example if no RSSI measurements are available
-     * yet.
-     * @hide
-     */
-    @SystemApi
-    public static final int INVALID_RSSI = -127;
-
-    /** @hide **/
-    public static final int MIN_RSSI = -126;
-
-    /** @hide **/
-    public static final int MAX_RSSI = 200;
-
-
-    /**
-     * Received Signal Strength Indicator
-     */
-    private int mRssi;
-
-    /**
-     * Wi-Fi standard for the connection
-     */
-    private @WifiAnnotations.WifiStandard int mWifiStandard;
-
-    /**
-     * The unit in which links speeds are expressed.
-     */
-    public static final String LINK_SPEED_UNITS = "Mbps";
-    private int mLinkSpeed;
-
-    /**
-     * Constant for unknown link speed.
-     */
-    public static final int LINK_SPEED_UNKNOWN = -1;
-
-    /**
-     * Tx(transmit) Link speed in Mbps
-     */
-    private int mTxLinkSpeed;
-
-    /**
-     * Max supported Tx(transmit) link speed in Mbps
-     */
-    private int mMaxSupportedTxLinkSpeed;
-
-    /**
-     * Rx(receive) Link speed in Mbps
-     */
-    private int mRxLinkSpeed;
-
-    /**
-     * Max supported Rx(receive) link speed in Mbps
-     */
-    private int mMaxSupportedRxLinkSpeed;
-
-    /**
-     * Frequency in MHz
-     */
-    public static final String FREQUENCY_UNITS = "MHz";
-    private int mFrequency;
-
-    @UnsupportedAppUsage
-    private InetAddress mIpAddress;
-    @UnsupportedAppUsage
-    private String mMacAddress = DEFAULT_MAC_ADDRESS;
-
-    /**
-     * Whether the network is ephemeral or not.
-     */
-    private boolean mEphemeral;
-
-    /**
-     * Whether the network is trusted or not.
-     */
-    private boolean mTrusted;
-
-    /**
-     * OSU (Online Sign Up) AP for Passpoint R2.
-     */
-    private boolean mOsuAp;
-
-    /**
-     * Fully qualified domain name of a Passpoint configuration
-     */
-    private String mFqdn;
-
-    /**
-     * Name of Passpoint credential provider
-     */
-    private String mProviderFriendlyName;
-
-    /**
-     * If connected to a network suggestion or specifier, store the package name of the app,
-     * else null.
-     */
-    private String mRequestingPackageName;
-
-    /**
-     * Running total count of lost (not ACKed) transmitted unicast data packets.
-     * @hide
-     */
-    public long txBad;
-    /**
-     * Running total count of transmitted unicast data retry packets.
-     * @hide
-     */
-    public long txRetries;
-    /**
-     * Running total count of successfully transmitted (ACKed) unicast data packets.
-     * @hide
-     */
-    public long txSuccess;
-    /**
-     * Running total count of received unicast data packets.
-     * @hide
-     */
-    public long rxSuccess;
-
-    private double mLostTxPacketsPerSecond;
-
-    /**
-     * Average rate of lost transmitted packets, in units of packets per second.
-     * @hide
-     */
-    @SystemApi
-    public double getLostTxPacketsPerSecond() {
-        return mLostTxPacketsPerSecond;
-    }
-
-    /** @hide */
-    public void setLostTxPacketsPerSecond(double lostTxPacketsPerSecond) {
-        mLostTxPacketsPerSecond = lostTxPacketsPerSecond;
-    }
-
-    private double mTxRetriedTxPacketsPerSecond;
-
-    /**
-     * Average rate of transmitted retry packets, in units of packets per second.
-     * @hide
-     */
-    @SystemApi
-    public double getRetriedTxPacketsPerSecond() {
-        return mTxRetriedTxPacketsPerSecond;
-    }
-
-    /** @hide */
-    public void setRetriedTxPacketsRate(double txRetriedTxPacketsPerSecond) {
-        mTxRetriedTxPacketsPerSecond = txRetriedTxPacketsPerSecond;
-    }
-
-    private double mSuccessfulTxPacketsPerSecond;
-
-    /**
-     * Average rate of successfully transmitted unicast packets, in units of packets per second.
-     * @hide
-     */
-    @SystemApi
-    public double getSuccessfulTxPacketsPerSecond() {
-        return mSuccessfulTxPacketsPerSecond;
-    }
-
-    /** @hide */
-    public void setSuccessfulTxPacketsPerSecond(double successfulTxPacketsPerSecond) {
-        mSuccessfulTxPacketsPerSecond = successfulTxPacketsPerSecond;
-    }
-
-    private double mSuccessfulRxPacketsPerSecond;
-
-    /**
-     * Average rate of received unicast data packets, in units of packets per second.
-     * @hide
-     */
-    @SystemApi
-    public double getSuccessfulRxPacketsPerSecond() {
-        return mSuccessfulRxPacketsPerSecond;
-    }
-
-    /** @hide */
-    public void setSuccessfulRxPacketsPerSecond(double successfulRxPacketsPerSecond) {
-        mSuccessfulRxPacketsPerSecond = successfulRxPacketsPerSecond;
-    }
-
-    /** @hide */
-    @UnsupportedAppUsage
-    public int score;
-
-    /**
-     * The current Wifi score.
-     * NOTE: this value should only be used for debugging purposes. Do not rely on this value for
-     * any computations. The meaning of this value can and will change at any time without warning.
-     * @hide
-     */
-    @SystemApi
-    public int getScore() {
-        return score;
-    }
-
-    /** @hide */
-    public void setScore(int score) {
-        this.score = score;
-    }
-
-    /**
-     * Flag indicating that AP has hinted that upstream connection is metered,
-     * and sensitive to heavy data transfers.
-     */
-    private boolean mMeteredHint;
-
-    /**
-     * Passpoint unique key
-     */
-    private String mPasspointUniqueId;
-
-    /** @hide */
-    @UnsupportedAppUsage
-    public WifiInfo() {
-        mWifiSsid = null;
-        mBSSID = null;
-        mNetworkId = -1;
-        mSupplicantState = SupplicantState.UNINITIALIZED;
-        mRssi = INVALID_RSSI;
-        mLinkSpeed = LINK_SPEED_UNKNOWN;
-        mFrequency = -1;
-    }
-
-    /** @hide */
-    public void reset() {
-        setInetAddress(null);
-        setBSSID(null);
-        setSSID(null);
-        setNetworkId(-1);
-        setRssi(INVALID_RSSI);
-        setLinkSpeed(LINK_SPEED_UNKNOWN);
-        setTxLinkSpeedMbps(LINK_SPEED_UNKNOWN);
-        setRxLinkSpeedMbps(LINK_SPEED_UNKNOWN);
-        setMaxSupportedTxLinkSpeedMbps(LINK_SPEED_UNKNOWN);
-        setMaxSupportedRxLinkSpeedMbps(LINK_SPEED_UNKNOWN);
-        setFrequency(-1);
-        setMeteredHint(false);
-        setEphemeral(false);
-        setOsuAp(false);
-        setRequestingPackageName(null);
-        setFQDN(null);
-        setProviderFriendlyName(null);
-        setPasspointUniqueId(null);
-        txBad = 0;
-        txSuccess = 0;
-        rxSuccess = 0;
-        txRetries = 0;
-        mLostTxPacketsPerSecond = 0;
-        mSuccessfulTxPacketsPerSecond = 0;
-        mSuccessfulRxPacketsPerSecond = 0;
-        mTxRetriedTxPacketsPerSecond = 0;
-        score = 0;
-    }
-
-    /**
-     * Copy constructor
-     * @hide
-     */
-    public WifiInfo(WifiInfo source) {
-        if (source != null) {
-            mSupplicantState = source.mSupplicantState;
-            mBSSID = source.mBSSID;
-            mWifiSsid = source.mWifiSsid;
-            mNetworkId = source.mNetworkId;
-            mRssi = source.mRssi;
-            mLinkSpeed = source.mLinkSpeed;
-            mTxLinkSpeed = source.mTxLinkSpeed;
-            mRxLinkSpeed = source.mRxLinkSpeed;
-            mFrequency = source.mFrequency;
-            mIpAddress = source.mIpAddress;
-            mMacAddress = source.mMacAddress;
-            mMeteredHint = source.mMeteredHint;
-            mEphemeral = source.mEphemeral;
-            mTrusted = source.mTrusted;
-            mRequestingPackageName =
-                    source.mRequestingPackageName;
-            mOsuAp = source.mOsuAp;
-            mFqdn = source.mFqdn;
-            mProviderFriendlyName = source.mProviderFriendlyName;
-            txBad = source.txBad;
-            txRetries = source.txRetries;
-            txSuccess = source.txSuccess;
-            rxSuccess = source.rxSuccess;
-            mLostTxPacketsPerSecond = source.mLostTxPacketsPerSecond;
-            mTxRetriedTxPacketsPerSecond = source.mTxRetriedTxPacketsPerSecond;
-            mSuccessfulTxPacketsPerSecond = source.mSuccessfulTxPacketsPerSecond;
-            mSuccessfulRxPacketsPerSecond = source.mSuccessfulRxPacketsPerSecond;
-            score = source.score;
-            mWifiStandard = source.mWifiStandard;
-            mMaxSupportedTxLinkSpeed = source.mMaxSupportedTxLinkSpeed;
-            mMaxSupportedRxLinkSpeed = source.mMaxSupportedRxLinkSpeed;
-            mPasspointUniqueId = source.mPasspointUniqueId;
-        }
-    }
-
-    /** Builder for WifiInfo */
-    public static final class Builder {
-        private final WifiInfo mWifiInfo = new WifiInfo();
-
-        /**
-         * Set the SSID, in the form of a raw byte array.
-         * @see WifiInfo#getSSID()
-         */
-        @NonNull
-        public Builder setSsid(@NonNull byte[] ssid) {
-            mWifiInfo.setSSID(WifiSsid.createFromByteArray(ssid));
-            return this;
-        }
-
-        /**
-         * Set the BSSID.
-         * @see WifiInfo#getBSSID()
-         */
-        @NonNull
-        public Builder setBssid(@NonNull String bssid) {
-            mWifiInfo.setBSSID(bssid);
-            return this;
-        }
-
-        /**
-         * Set the RSSI, in dBm.
-         * @see WifiInfo#getRssi()
-         */
-        @NonNull
-        public Builder setRssi(int rssi) {
-            mWifiInfo.setRssi(rssi);
-            return this;
-        }
-
-        /**
-         * Set the network ID.
-         * @see WifiInfo#getNetworkId()
-         */
-        @NonNull
-        public Builder setNetworkId(int networkId) {
-            mWifiInfo.setNetworkId(networkId);
-            return this;
-        }
-
-        /**
-         * Build a WifiInfo object.
-         */
-        @NonNull
-        public WifiInfo build() {
-            return new WifiInfo(mWifiInfo);
-        }
-    }
-
-    /** @hide */
-    public void setSSID(WifiSsid wifiSsid) {
-        mWifiSsid = wifiSsid;
-    }
-
-    /**
-     * Returns the service set identifier (SSID) of the current 802.11 network.
-     * <p>
-     * If the SSID can be decoded as UTF-8, it will be returned surrounded by double
-     * quotation marks. Otherwise, it is returned as a string of hex digits.
-     * The SSID may be {@link WifiManager#UNKNOWN_SSID}, if there is no network currently connected
-     * or if the caller has insufficient permissions to access the SSID.
-     * </p>
-     * <p>
-     * Prior to {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}, this method
-     * always returned the SSID with no quotes around it.
-     * </p>
-     *
-     * @return the SSID.
-     */
-    public String getSSID() {
-        if (mWifiSsid != null) {
-            String unicode = mWifiSsid.toString();
-            if (!TextUtils.isEmpty(unicode)) {
-                return "\"" + unicode + "\"";
-            } else {
-                String hex = mWifiSsid.getHexString();
-                return (hex != null) ? hex : WifiManager.UNKNOWN_SSID;
-            }
-        }
-        return WifiManager.UNKNOWN_SSID;
-    }
-
-    /** @hide */
-    @UnsupportedAppUsage
-    public WifiSsid getWifiSsid() {
-        return mWifiSsid;
-    }
-
-    /** @hide */
-    @UnsupportedAppUsage
-    public void setBSSID(String BSSID) {
-        mBSSID = BSSID;
-    }
-
-    /**
-     * Return the basic service set identifier (BSSID) of the current access point.
-     * <p>
-     * The BSSID may be
-     * <lt>{@code null}, if there is no network currently connected.</lt>
-     * <lt>{@code "02:00:00:00:00:00"}, if the caller has insufficient permissions to access the
-     * BSSID.<lt>
-     * </p>
-     *
-     * @return the BSSID, in the form of a six-byte MAC address: {@code XX:XX:XX:XX:XX:XX}
-     */
-    public String getBSSID() {
-        return mBSSID;
-    }
-
-    /**
-     * Returns the received signal strength indicator of the current 802.11
-     * network, in dBm.
-     *
-     * <p>Use {@link android.net.wifi.WifiManager#calculateSignalLevel} to convert this number into
-     * an absolute signal level which can be displayed to a user.
-     *
-     * @return the RSSI.
-     */
-    public int getRssi() {
-        return mRssi;
-    }
-
-    /** @hide */
-    @UnsupportedAppUsage
-    public void setRssi(int rssi) {
-        if (rssi < INVALID_RSSI)
-            rssi = INVALID_RSSI;
-        if (rssi > MAX_RSSI)
-            rssi = MAX_RSSI;
-        mRssi = rssi;
-    }
-
-    /**
-     * Sets the Wi-Fi standard
-     * @hide
-     */
-    public void setWifiStandard(@WifiAnnotations.WifiStandard int wifiStandard) {
-        mWifiStandard = wifiStandard;
-    }
-
-    /**
-     * Get connection Wi-Fi standard
-     * @return the connection Wi-Fi standard
-     */
-    public @WifiAnnotations.WifiStandard int getWifiStandard() {
-        return mWifiStandard;
-    }
-
-    /**
-     * Returns the current link speed in {@link #LINK_SPEED_UNITS}.
-     * @return the link speed or {@link #LINK_SPEED_UNKNOWN} if link speed is unknown.
-     * @see #LINK_SPEED_UNITS
-     * @see #LINK_SPEED_UNKNOWN
-     */
-    public int getLinkSpeed() {
-        return mLinkSpeed;
-    }
-
-    /** @hide */
-    @UnsupportedAppUsage
-    public void setLinkSpeed(int linkSpeed) {
-        mLinkSpeed = linkSpeed;
-    }
-
-    /**
-     * Returns the current transmit link speed in Mbps.
-     * @return the Tx link speed or {@link #LINK_SPEED_UNKNOWN} if link speed is unknown.
-     * @see #LINK_SPEED_UNKNOWN
-     */
-    @IntRange(from = -1)
-    public int getTxLinkSpeedMbps() {
-        return mTxLinkSpeed;
-    }
-
-    /**
-     * Returns the maximum supported transmit link speed in Mbps
-     * @return the max supported tx link speed or {@link #LINK_SPEED_UNKNOWN} if link speed is
-     * unknown. @see #LINK_SPEED_UNKNOWN
-     */
-    public int getMaxSupportedTxLinkSpeedMbps() {
-        return mMaxSupportedTxLinkSpeed;
-    }
-
-    /**
-     * Update the last transmitted packet bit rate in Mbps.
-     * @hide
-     */
-    public void setTxLinkSpeedMbps(int txLinkSpeed) {
-        mTxLinkSpeed = txLinkSpeed;
-    }
-
-    /**
-     * Set the maximum supported transmit link speed in Mbps
-     * @hide
-     */
-    public void setMaxSupportedTxLinkSpeedMbps(int maxSupportedTxLinkSpeed) {
-        mMaxSupportedTxLinkSpeed = maxSupportedTxLinkSpeed;
-    }
-
-    /**
-     * Returns the current receive link speed in Mbps.
-     * @return the Rx link speed or {@link #LINK_SPEED_UNKNOWN} if link speed is unknown.
-     * @see #LINK_SPEED_UNKNOWN
-     */
-    @IntRange(from = -1)
-    public int getRxLinkSpeedMbps() {
-        return mRxLinkSpeed;
-    }
-
-    /**
-     * Returns the maximum supported receive link speed in Mbps
-     * @return the max supported Rx link speed or {@link #LINK_SPEED_UNKNOWN} if link speed is
-     * unknown. @see #LINK_SPEED_UNKNOWN
-     */
-    public int getMaxSupportedRxLinkSpeedMbps() {
-        return mMaxSupportedRxLinkSpeed;
-    }
-
-    /**
-     * Update the last received packet bit rate in Mbps.
-     * @hide
-     */
-    public void setRxLinkSpeedMbps(int rxLinkSpeed) {
-        mRxLinkSpeed = rxLinkSpeed;
-    }
-
-    /**
-     * Set the maximum supported receive link speed in Mbps
-     * @hide
-     */
-    public void setMaxSupportedRxLinkSpeedMbps(int maxSupportedRxLinkSpeed) {
-        mMaxSupportedRxLinkSpeed = maxSupportedRxLinkSpeed;
-    }
-
-    /**
-     * Returns the current frequency in {@link #FREQUENCY_UNITS}.
-     * @return the frequency.
-     * @see #FREQUENCY_UNITS
-     */
-    public int getFrequency() {
-        return mFrequency;
-    }
-
-    /** @hide */
-    public void setFrequency(int frequency) {
-        this.mFrequency = frequency;
-    }
-
-    /**
-     * @hide
-     */
-    public boolean is24GHz() {
-        return ScanResult.is24GHz(mFrequency);
-    }
-
-    /**
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public boolean is5GHz() {
-        return ScanResult.is5GHz(mFrequency);
-    }
-
-    /**
-     * @hide
-     */
-    public boolean is6GHz() {
-        return ScanResult.is6GHz(mFrequency);
-    }
-
-    /**
-     * Record the MAC address of the WLAN interface
-     * @param macAddress the MAC address in {@code XX:XX:XX:XX:XX:XX} form
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public void setMacAddress(String macAddress) {
-        this.mMacAddress = macAddress;
-    }
-
-    public String getMacAddress() {
-        return mMacAddress;
-    }
-
-    /**
-     * @return true if {@link #getMacAddress()} has a real MAC address.
-     *
-     * @hide
-     */
-    public boolean hasRealMacAddress() {
-        return mMacAddress != null && !DEFAULT_MAC_ADDRESS.equals(mMacAddress);
-    }
-
-    /**
-     * Indicates if we've dynamically detected this active network connection as
-     * being metered.
-     *
-     * @see WifiConfiguration#isMetered(WifiConfiguration, WifiInfo)
-     * @hide
-     */
-    public void setMeteredHint(boolean meteredHint) {
-        mMeteredHint = meteredHint;
-    }
-
-    /** {@hide} */
-    @UnsupportedAppUsage
-    public boolean getMeteredHint() {
-        return mMeteredHint;
-    }
-
-    /** {@hide} */
-    public void setEphemeral(boolean ephemeral) {
-        mEphemeral = ephemeral;
-    }
-
-    /**
-     * Returns true if the current Wifi network is ephemeral, false otherwise.
-     * An ephemeral network is a network that is temporary and not persisted in the system.
-     * Ephemeral networks cannot be forgotten, only disabled with
-     * {@link WifiManager#disableEphemeralNetwork(String)}.
-     *
-     * @hide
-     */
-    @SystemApi
-    public boolean isEphemeral() {
-        return mEphemeral;
-    }
-
-    /** {@hide} */
-    public void setTrusted(boolean trusted) {
-        mTrusted = trusted;
-    }
-
-    /** {@hide} */
-    public boolean isTrusted() {
-        return mTrusted;
-    }
-
-    /** {@hide} */
-    public void setOsuAp(boolean osuAp) {
-        mOsuAp = osuAp;
-    }
-
-    /** {@hide} */
-    @SystemApi
-    public boolean isOsuAp() {
-        return mOsuAp;
-    }
-
-    /** {@hide} */
-    @SystemApi
-    public boolean isPasspointAp() {
-        return mFqdn != null && mProviderFriendlyName != null;
-    }
-
-    /** {@hide} */
-    public void setFQDN(@Nullable String fqdn) {
-        mFqdn = fqdn;
-    }
-
-    /**
-     * Returns the Fully Qualified Domain Name of the network if it is a Passpoint network.
-     * <p>
-     * The FQDN may be
-     * <lt>{@code null} if no network currently connected, currently connected network is not
-     * passpoint network or the caller has insufficient permissions to access the FQDN.</lt>
-     * </p>
-     */
-    public @Nullable String getPasspointFqdn() {
-        return mFqdn;
-    }
-
-    /** {@hide} */
-    public void setProviderFriendlyName(@Nullable String providerFriendlyName) {
-        mProviderFriendlyName = providerFriendlyName;
-    }
-
-    /**
-     * Returns the Provider Friendly Name of the network if it is a Passpoint network.
-     * <p>
-     * The Provider Friendly Name may be
-     * <lt>{@code null} if no network currently connected, currently connected network is not
-     * passpoint network or the caller has insufficient permissions to access the Provider Friendly
-     * Name. </lt>
-     * </p>
-     */
-    public @Nullable String getPasspointProviderFriendlyName() {
-        return mProviderFriendlyName;
-    }
-
-    /** {@hide} */
-    public void setRequestingPackageName(@Nullable String packageName) {
-        mRequestingPackageName = packageName;
-    }
-
-    /**
-     * If this network was created in response to an app request (e.g. through Network Suggestion
-     * or Network Specifier), return the package name of the app that made the request.
-     * Null otherwise.
-     * @hide
-     */
-    @SystemApi
-    public @Nullable String getRequestingPackageName() {
-        return mRequestingPackageName;
-    }
-
-
-    /** @hide */
-    @UnsupportedAppUsage
-    public void setNetworkId(int id) {
-        mNetworkId = id;
-    }
-
-    /**
-     * Each configured network has a unique small integer ID, used to identify
-     * the network. This method returns the ID for the currently connected network.
-     * <p>
-     * The networkId may be {@code -1} if there is no currently connected network or if the caller
-     * has insufficient permissions to access the network ID.
-     * </p>
-     *
-     * @return the network ID.
-     */
-    public int getNetworkId() {
-        return mNetworkId;
-    }
-
-    /**
-     * Return the detailed state of the supplicant's negotiation with an
-     * access point, in the form of a {@link SupplicantState SupplicantState} object.
-     * @return the current {@link SupplicantState SupplicantState}
-     */
-    public SupplicantState getSupplicantState() {
-        return mSupplicantState;
-    }
-
-    /** @hide */
-    @UnsupportedAppUsage
-    public void setSupplicantState(SupplicantState state) {
-        mSupplicantState = state;
-    }
-
-    /** @hide */
-    public void setInetAddress(InetAddress address) {
-        mIpAddress = address;
-    }
-
-    public int getIpAddress() {
-        int result = 0;
-        if (mIpAddress instanceof Inet4Address) {
-            result = Inet4AddressUtils.inet4AddressToIntHTL((Inet4Address) mIpAddress);
-        }
-        return result;
-    }
-
-    /**
-     * @return {@code true} if this network does not broadcast its SSID, so an
-     * SSID-specific probe request must be used for scans.
-     */
-    public boolean getHiddenSSID() {
-        if (mWifiSsid == null) return false;
-        return mWifiSsid.isHidden();
-    }
-
-    /**
-     * Map a supplicant state into a fine-grained network connectivity state.
-     * @param suppState the supplicant state
-     * @return the corresponding {@link DetailedState}
-     */
-    public static DetailedState getDetailedStateOf(SupplicantState suppState) {
-        return stateMap.get(suppState);
-    }
-
-    /**
-     * Set the <code>SupplicantState</code> from the string name
-     * of the state.
-     * @param stateName the name of the state, as a <code>String</code> returned
-     * in an event sent by {@code wpa_supplicant}.
-     */
-    @UnsupportedAppUsage
-    void setSupplicantState(String stateName) {
-        mSupplicantState = valueOf(stateName);
-    }
-
-    static SupplicantState valueOf(String stateName) {
-        if ("4WAY_HANDSHAKE".equalsIgnoreCase(stateName))
-            return SupplicantState.FOUR_WAY_HANDSHAKE;
-        else {
-            try {
-                return SupplicantState.valueOf(stateName.toUpperCase(Locale.ROOT));
-            } catch (IllegalArgumentException e) {
-                return SupplicantState.INVALID;
-            }
-        }
-    }
-
-    /**
-     * Remove double quotes (") surrounding a SSID string, if present. Otherwise, return the
-     * string unmodified. Return null if the input string was null.
-     * @hide
-     */
-    @Nullable
-    @SystemApi
-    public static String sanitizeSsid(@Nullable String string) {
-        return removeDoubleQuotes(string);
-    }
-
-    /** @hide */
-    @UnsupportedAppUsage
-    @Nullable
-    public static String removeDoubleQuotes(@Nullable String string) {
-        if (string == null) return null;
-        final int length = string.length();
-        if ((length > 1) && (string.charAt(0) == '"') && (string.charAt(length - 1) == '"')) {
-            return string.substring(1, length - 1);
-        }
-        return string;
-    }
-
-    @Override
-    public String toString() {
-        StringBuffer sb = new StringBuffer();
-        String none = "<none>";
-
-        sb.append("SSID: ").append(mWifiSsid == null ? WifiManager.UNKNOWN_SSID : mWifiSsid)
-                .append(", BSSID: ").append(mBSSID == null ? none : mBSSID)
-                .append(", MAC: ").append(mMacAddress == null ? none : mMacAddress)
-                .append(", Supplicant state: ")
-                .append(mSupplicantState == null ? none : mSupplicantState)
-                .append(", Wi-Fi standard: ").append(mWifiStandard)
-                .append(", RSSI: ").append(mRssi)
-                .append(", Link speed: ").append(mLinkSpeed).append(LINK_SPEED_UNITS)
-                .append(", Tx Link speed: ").append(mTxLinkSpeed).append(LINK_SPEED_UNITS)
-                .append(", Max Supported Tx Link speed: ")
-                .append(mMaxSupportedTxLinkSpeed).append(LINK_SPEED_UNITS)
-                .append(", Rx Link speed: ").append(mRxLinkSpeed).append(LINK_SPEED_UNITS)
-                .append(", Max Supported Rx Link speed: ")
-                .append(mMaxSupportedRxLinkSpeed).append(LINK_SPEED_UNITS)
-                .append(", Frequency: ").append(mFrequency).append(FREQUENCY_UNITS)
-                .append(", Net ID: ").append(mNetworkId)
-                .append(", Metered hint: ").append(mMeteredHint)
-                .append(", score: ").append(Integer.toString(score));
-        return sb.toString();
-    }
-
-    /** Implement the Parcelable interface {@hide} */
-    public int describeContents() {
-        return 0;
-    }
-
-    /** Implement the Parcelable interface {@hide} */
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mNetworkId);
-        dest.writeInt(mRssi);
-        dest.writeInt(mLinkSpeed);
-        dest.writeInt(mTxLinkSpeed);
-        dest.writeInt(mRxLinkSpeed);
-        dest.writeInt(mFrequency);
-        if (mIpAddress != null) {
-            dest.writeByte((byte)1);
-            dest.writeByteArray(mIpAddress.getAddress());
-        } else {
-            dest.writeByte((byte)0);
-        }
-        if (mWifiSsid != null) {
-            dest.writeInt(1);
-            mWifiSsid.writeToParcel(dest, flags);
-        } else {
-            dest.writeInt(0);
-        }
-        dest.writeString(mBSSID);
-        dest.writeString(mMacAddress);
-        dest.writeInt(mMeteredHint ? 1 : 0);
-        dest.writeInt(mEphemeral ? 1 : 0);
-        dest.writeInt(mTrusted ? 1 : 0);
-        dest.writeInt(score);
-        dest.writeLong(txSuccess);
-        dest.writeDouble(mSuccessfulTxPacketsPerSecond);
-        dest.writeLong(txRetries);
-        dest.writeDouble(mTxRetriedTxPacketsPerSecond);
-        dest.writeLong(txBad);
-        dest.writeDouble(mLostTxPacketsPerSecond);
-        dest.writeLong(rxSuccess);
-        dest.writeDouble(mSuccessfulRxPacketsPerSecond);
-        mSupplicantState.writeToParcel(dest, flags);
-        dest.writeInt(mOsuAp ? 1 : 0);
-        dest.writeString(mRequestingPackageName);
-        dest.writeString(mFqdn);
-        dest.writeString(mProviderFriendlyName);
-        dest.writeInt(mWifiStandard);
-        dest.writeInt(mMaxSupportedTxLinkSpeed);
-        dest.writeInt(mMaxSupportedRxLinkSpeed);
-        dest.writeString(mPasspointUniqueId);
-    }
-
-    /** Implement the Parcelable interface {@hide} */
-    @UnsupportedAppUsage
-    public static final @android.annotation.NonNull Creator<WifiInfo> CREATOR =
-        new Creator<WifiInfo>() {
-            public WifiInfo createFromParcel(Parcel in) {
-                WifiInfo info = new WifiInfo();
-                info.setNetworkId(in.readInt());
-                info.setRssi(in.readInt());
-                info.setLinkSpeed(in.readInt());
-                info.setTxLinkSpeedMbps(in.readInt());
-                info.setRxLinkSpeedMbps(in.readInt());
-                info.setFrequency(in.readInt());
-                if (in.readByte() == 1) {
-                    try {
-                        info.setInetAddress(InetAddress.getByAddress(in.createByteArray()));
-                    } catch (UnknownHostException e) {}
-                }
-                if (in.readInt() == 1) {
-                    info.mWifiSsid = WifiSsid.CREATOR.createFromParcel(in);
-                }
-                info.mBSSID = in.readString();
-                info.mMacAddress = in.readString();
-                info.mMeteredHint = in.readInt() != 0;
-                info.mEphemeral = in.readInt() != 0;
-                info.mTrusted = in.readInt() != 0;
-                info.score = in.readInt();
-                info.txSuccess = in.readLong();
-                info.mSuccessfulTxPacketsPerSecond = in.readDouble();
-                info.txRetries = in.readLong();
-                info.mTxRetriedTxPacketsPerSecond = in.readDouble();
-                info.txBad = in.readLong();
-                info.mLostTxPacketsPerSecond = in.readDouble();
-                info.rxSuccess = in.readLong();
-                info.mSuccessfulRxPacketsPerSecond = in.readDouble();
-                info.mSupplicantState = SupplicantState.CREATOR.createFromParcel(in);
-                info.mOsuAp = in.readInt() != 0;
-                info.mRequestingPackageName = in.readString();
-                info.mFqdn = in.readString();
-                info.mProviderFriendlyName = in.readString();
-                info.mWifiStandard = in.readInt();
-                info.mMaxSupportedTxLinkSpeed = in.readInt();
-                info.mMaxSupportedRxLinkSpeed = in.readInt();
-                info.mPasspointUniqueId = in.readString();
-                return info;
-            }
-
-            public WifiInfo[] newArray(int size) {
-                return new WifiInfo[size];
-            }
-        };
-
-    /**
-     * Set the Passpoint unique identifier for the current connection
-     *
-     * @param passpointUniqueId Unique identifier
-     * @hide
-     */
-    public void setPasspointUniqueId(@Nullable String passpointUniqueId) {
-        mPasspointUniqueId = passpointUniqueId;
-    }
-
-    /**
-     * Get the Passpoint unique identifier for the current connection
-     *
-     * @return Passpoint unique identifier
-     * @hide
-     */
-    public @Nullable String getPasspointUniqueId() {
-        return mPasspointUniqueId;
-    }
-}
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
deleted file mode 100644
index 4a61db8..0000000
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ /dev/null
@@ -1,6239 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import static android.Manifest.permission.ACCESS_FINE_LOCATION;
-import static android.Manifest.permission.ACCESS_WIFI_STATE;
-import static android.Manifest.permission.READ_WIFI_CREDENTIAL;
-
-import android.annotation.CallbackExecutor;
-import android.annotation.IntDef;
-import android.annotation.IntRange;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.annotation.SuppressLint;
-import android.annotation.SystemApi;
-import android.annotation.SystemService;
-import android.app.ActivityManager;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.content.Context;
-import android.content.pm.ParceledListSlice;
-import android.net.ConnectivityManager;
-import android.net.DhcpInfo;
-import android.net.MacAddress;
-import android.net.Network;
-import android.net.NetworkStack;
-import android.net.wifi.hotspot2.IProvisioningCallback;
-import android.net.wifi.hotspot2.OsuProvider;
-import android.net.wifi.hotspot2.PasspointConfiguration;
-import android.net.wifi.hotspot2.ProvisioningCallback;
-import android.os.Binder;
-import android.os.Build;
-import android.os.Handler;
-import android.os.HandlerExecutor;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.RemoteException;
-import android.os.WorkSource;
-import android.os.connectivity.WifiActivityEnergyInfo;
-import android.text.TextUtils;
-import android.util.CloseGuard;
-import android.util.Log;
-import android.util.Pair;
-import android.util.SparseArray;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.ref.Reference;
-import java.lang.ref.WeakReference;
-import java.net.InetAddress;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.StringTokenizer;
-import java.util.concurrent.Executor;
-
-/**
- * This class provides the primary API for managing all aspects of Wi-Fi
- * connectivity.
- * <p>
- * On releases before {@link android.os.Build.VERSION_CODES#N}, this object
- * should only be obtained from an {@linkplain Context#getApplicationContext()
- * application context}, and not from any other derived context to avoid memory
- * leaks within the calling process.
- * <p>
- * It deals with several categories of items:
- * </p>
- * <ul>
- * <li>The list of configured networks. The list can be viewed and updated, and
- * attributes of individual entries can be modified.</li>
- * <li>The currently active Wi-Fi network, if any. Connectivity can be
- * established or torn down, and dynamic information about the state of the
- * network can be queried.</li>
- * <li>Results of access point scans, containing enough information to make
- * decisions about what access point to connect to.</li>
- * <li>It defines the names of various Intent actions that are broadcast upon
- * any sort of change in Wi-Fi state.
- * </ul>
- * <p>
- * This is the API to use when performing Wi-Fi specific operations. To perform
- * operations that pertain to network connectivity at an abstract level, use
- * {@link android.net.ConnectivityManager}.
- * </p>
- */
-@SystemService(Context.WIFI_SERVICE)
-public class WifiManager {
-
-    private static final String TAG = "WifiManager";
-    // Supplicant error codes:
-    /**
-     * The error code if there was a problem authenticating.
-     * @deprecated This is no longer supported.
-     */
-    @Deprecated
-    public static final int ERROR_AUTHENTICATING = 1;
-
-    /**
-     * The reason code if there is no error during authentication.
-     * It could also imply that there no authentication in progress,
-     * this reason code also serves as a reset value.
-     * @deprecated This is no longer supported.
-     * @hide
-     */
-    @Deprecated
-    public static final int ERROR_AUTH_FAILURE_NONE = 0;
-
-    /**
-     * The reason code if there was a timeout authenticating.
-     * @deprecated This is no longer supported.
-     * @hide
-     */
-    @Deprecated
-    public static final int ERROR_AUTH_FAILURE_TIMEOUT = 1;
-
-    /**
-     * The reason code if there was a wrong password while
-     * authenticating.
-     * @deprecated This is no longer supported.
-     * @hide
-     */
-    @Deprecated
-    public static final int ERROR_AUTH_FAILURE_WRONG_PSWD = 2;
-
-    /**
-     * The reason code if there was EAP failure while
-     * authenticating.
-     * @deprecated This is no longer supported.
-     * @hide
-     */
-    @Deprecated
-    public static final int ERROR_AUTH_FAILURE_EAP_FAILURE = 3;
-
-    /** @hide */
-    public static final int NETWORK_SUGGESTIONS_MAX_PER_APP_LOW_RAM = 256;
-
-    /** @hide */
-    public static final int NETWORK_SUGGESTIONS_MAX_PER_APP_HIGH_RAM = 1024;
-
-    /**
-     * Reason code if all of the network suggestions were successfully added or removed.
-     */
-    public static final int STATUS_NETWORK_SUGGESTIONS_SUCCESS = 0;
-
-    /**
-     * Reason code if there was an internal error in the platform while processing the addition or
-     * removal of suggestions.
-     */
-    public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_INTERNAL = 1;
-
-    /**
-     * Reason code if the user has disallowed "android:change_wifi_state" app-ops from the app.
-     * @see android.app.AppOpsManager#unsafeCheckOp(String, int, String).
-     */
-    public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_APP_DISALLOWED = 2;
-
-    /**
-     * Reason code if one or more of the network suggestions added already exists in platform's
-     * database.
-     * Note: this code will not be returned with Android 11 as in-place modification is allowed,
-     * please check {@link #addNetworkSuggestions(List)}.
-     * @see WifiNetworkSuggestion#equals(Object)
-     */
-    public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_DUPLICATE = 3;
-
-    /**
-     * Reason code if the number of network suggestions provided by the app crosses the max
-     * threshold set per app.
-     * The framework will reject all suggestions provided by {@link #addNetworkSuggestions(List)} if
-     * the total size exceeds the limit.
-     * @see #getMaxNumberOfNetworkSuggestionsPerApp()
-     */
-    public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_EXCEEDS_MAX_PER_APP = 4;
-
-    /**
-     * Reason code if one or more of the network suggestions removed does not exist in platform's
-     * database.
-     * The framework won't remove any suggestions if one or more of suggestions provided
-     * by {@link #removeNetworkSuggestions(List)} does not exist in database.
-     * @see WifiNetworkSuggestion#equals(Object)
-     */
-    public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_REMOVE_INVALID = 5;
-
-    /**
-     * Reason code if one or more of the network suggestions added is not allowed.
-     * The framework will reject all suggestions provided by {@link #addNetworkSuggestions(List)}
-     * if one or more of them is not allowed.
-     * This error may be caused by suggestion is using SIM-based encryption method, but calling app
-     * is not carrier privileged.
-     */
-    public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_NOT_ALLOWED = 6;
-
-    /**
-     * Reason code if one or more of the network suggestions added is invalid. Framework will reject
-     * all the suggestions in the list.
-     * The framework will reject all suggestions provided by {@link #addNetworkSuggestions(List)}
-     * if one or more of them is invalid.
-     * Please use {@link WifiNetworkSuggestion.Builder} to create network suggestions.
-     */
-    public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_INVALID = 7;
-
-    /** @hide */
-    @IntDef(prefix = { "STATUS_NETWORK_SUGGESTIONS_" }, value = {
-            STATUS_NETWORK_SUGGESTIONS_SUCCESS,
-            STATUS_NETWORK_SUGGESTIONS_ERROR_INTERNAL,
-            STATUS_NETWORK_SUGGESTIONS_ERROR_APP_DISALLOWED,
-            STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_DUPLICATE,
-            STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_EXCEEDS_MAX_PER_APP,
-            STATUS_NETWORK_SUGGESTIONS_ERROR_REMOVE_INVALID,
-            STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_NOT_ALLOWED,
-            STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_INVALID,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface NetworkSuggestionsStatusCode {}
-
-    /**
-     * Reason code if suggested network connection attempt failed with an unknown failure.
-     */
-    public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_UNKNOWN = 0;
-    /**
-     * Reason code if suggested network connection attempt failed with association failure.
-     */
-    public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_ASSOCIATION = 1;
-    /**
-     * Reason code if suggested network connection attempt failed with an authentication failure.
-     */
-    public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION = 2;
-    /**
-     * Reason code if suggested network connection attempt failed with an IP provision failure.
-     */
-    public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_IP_PROVISIONING = 3;
-
-    /** @hide */
-    @IntDef(prefix = {"STATUS_SUGGESTION_CONNECTION_FAILURE_"},
-            value = {STATUS_SUGGESTION_CONNECTION_FAILURE_UNKNOWN,
-                    STATUS_SUGGESTION_CONNECTION_FAILURE_ASSOCIATION,
-                    STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION,
-                    STATUS_SUGGESTION_CONNECTION_FAILURE_IP_PROVISIONING
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface SuggestionConnectionStatusCode {}
-
-    /**
-     * Broadcast intent action indicating whether Wi-Fi scanning is currently available.
-     * Available extras:
-     * - {@link #EXTRA_SCAN_AVAILABLE}
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_WIFI_SCAN_AVAILABILITY_CHANGED =
-            "android.net.wifi.action.WIFI_SCAN_AVAILABILITY_CHANGED";
-
-    /**
-     * A boolean extra indicating whether scanning is currently available.
-     * Sent in the broadcast {@link #ACTION_WIFI_SCAN_AVAILABILITY_CHANGED}.
-     * Its value is true if scanning is currently available, false otherwise.
-     */
-    public static final String EXTRA_SCAN_AVAILABLE = "android.net.wifi.extra.SCAN_AVAILABLE";
-
-    /**
-     * Broadcast intent action indicating that the credential of a Wi-Fi network
-     * has been changed. One extra provides the ssid of the network. Another
-     * extra provides the event type, whether the credential is saved or forgot.
-     * @hide
-     */
-    @SystemApi
-    public static final String WIFI_CREDENTIAL_CHANGED_ACTION =
-            "android.net.wifi.WIFI_CREDENTIAL_CHANGED";
-    /** @hide */
-    @SystemApi
-    public static final String EXTRA_WIFI_CREDENTIAL_EVENT_TYPE = "et";
-    /** @hide */
-    @SystemApi
-    public static final String EXTRA_WIFI_CREDENTIAL_SSID = "ssid";
-    /** @hide */
-    @SystemApi
-    public static final int WIFI_CREDENTIAL_SAVED = 0;
-    /** @hide */
-    @SystemApi
-    public static final int WIFI_CREDENTIAL_FORGOT = 1;
-
-    /** @hide */
-    @SystemApi
-    public static final int PASSPOINT_HOME_NETWORK = 0;
-
-    /** @hide */
-    @SystemApi
-    public static final int PASSPOINT_ROAMING_NETWORK = 1;
-
-    /**
-     * Broadcast intent action indicating that a Passpoint provider icon has been received.
-     *
-     * Included extras:
-     * {@link #EXTRA_BSSID_LONG}
-     * {@link #EXTRA_FILENAME}
-     * {@link #EXTRA_ICON}
-     *
-     * Receiver Required Permission: android.Manifest.permission.ACCESS_WIFI_STATE
-     *
-     * <p>Note: The broadcast is only delivered to registered receivers - no manifest registered
-     * components will be launched.
-     *
-     * @hide
-     */
-    public static final String ACTION_PASSPOINT_ICON = "android.net.wifi.action.PASSPOINT_ICON";
-    /**
-     * BSSID of an AP in long representation.  The {@link #EXTRA_BSSID} contains BSSID in
-     * String representation.
-     *
-     * Retrieve with {@link android.content.Intent#getLongExtra(String, long)}.
-     *
-     * @hide
-     */
-    public static final String EXTRA_BSSID_LONG = "android.net.wifi.extra.BSSID_LONG";
-    /**
-     * Icon data.
-     *
-     * Retrieve with {@link android.content.Intent#getParcelableExtra(String)} and cast into
-     * {@link android.graphics.drawable.Icon}.
-     *
-     * @hide
-     */
-    public static final String EXTRA_ICON = "android.net.wifi.extra.ICON";
-    /**
-     * Name of a file.
-     *
-     * Retrieve with {@link android.content.Intent#getStringExtra(String)}.
-     *
-     * @hide
-     */
-    public static final String EXTRA_FILENAME = "android.net.wifi.extra.FILENAME";
-
-    /**
-     * Broadcast intent action indicating a Passpoint OSU Providers List element has been received.
-     *
-     * Included extras:
-     * {@link #EXTRA_BSSID_LONG}
-     * {@link #EXTRA_ANQP_ELEMENT_DATA}
-     *
-     * Receiver Required Permission: android.Manifest.permission.ACCESS_WIFI_STATE
-     *
-     * <p>Note: The broadcast is only delivered to registered receivers - no manifest registered
-     * components will be launched.
-     *
-     * @hide
-     */
-    public static final String ACTION_PASSPOINT_OSU_PROVIDERS_LIST =
-            "android.net.wifi.action.PASSPOINT_OSU_PROVIDERS_LIST";
-    /**
-     * Raw binary data of an ANQP (Access Network Query Protocol) element.
-     *
-     * Retrieve with {@link android.content.Intent#getByteArrayExtra(String)}.
-     *
-     * @hide
-     */
-    public static final String EXTRA_ANQP_ELEMENT_DATA =
-            "android.net.wifi.extra.ANQP_ELEMENT_DATA";
-
-    /**
-     * Broadcast intent action indicating that a Passpoint Deauth Imminent frame has been received.
-     *
-     * Included extras:
-     * {@link #EXTRA_BSSID_LONG}
-     * {@link #EXTRA_ESS}
-     * {@link #EXTRA_DELAY}
-     * {@link #EXTRA_URL}
-     *
-     * Receiver Required Permission: android.Manifest.permission.ACCESS_WIFI_STATE
-     *
-     * <p>Note: The broadcast is only delivered to registered receivers - no manifest registered
-     * components will be launched.
-     *
-     * @hide
-     */
-    public static final String ACTION_PASSPOINT_DEAUTH_IMMINENT =
-            "android.net.wifi.action.PASSPOINT_DEAUTH_IMMINENT";
-    /**
-     * Flag indicating BSS (Basic Service Set) or ESS (Extended Service Set). This will be set to
-     * {@code true} for ESS.
-     *
-     * Retrieve with {@link android.content.Intent#getBooleanExtra(String, boolean)}.
-     *
-     * @hide
-     */
-    public static final String EXTRA_ESS = "android.net.wifi.extra.ESS";
-    /**
-     * Delay in seconds.
-     *
-     * Retrieve with {@link android.content.Intent#getIntExtra(String, int)}.
-     *
-     * @hide
-     */
-    public static final String EXTRA_DELAY = "android.net.wifi.extra.DELAY";
-
-    /**
-     * Broadcast intent action indicating a Passpoint subscription remediation frame has been
-     * received.
-     *
-     * Included extras:
-     * {@link #EXTRA_BSSID_LONG}
-     * {@link #EXTRA_SUBSCRIPTION_REMEDIATION_METHOD}
-     * {@link #EXTRA_URL}
-     *
-     * Receiver Required Permission: android.Manifest.permission.ACCESS_WIFI_STATE
-     *
-     * <p>Note: The broadcast is only delivered to registered receivers - no manifest registered
-     * components will be launched.
-     *
-     * @hide
-     */
-    public static final String ACTION_PASSPOINT_SUBSCRIPTION_REMEDIATION =
-            "android.net.wifi.action.PASSPOINT_SUBSCRIPTION_REMEDIATION";
-    /**
-     * The protocol supported by the subscription remediation server. The possible values are:
-     * 0 - OMA DM
-     * 1 - SOAP XML SPP
-     *
-     * Retrieve with {@link android.content.Intent#getIntExtra(String, int)}.
-     *
-     * @hide
-     */
-    public static final String EXTRA_SUBSCRIPTION_REMEDIATION_METHOD =
-            "android.net.wifi.extra.SUBSCRIPTION_REMEDIATION_METHOD";
-
-    /**
-     * Activity Action: Receiver should launch Passpoint OSU (Online Sign Up) view.
-     * Included extras:
-     *
-     * {@link #EXTRA_OSU_NETWORK}: {@link Network} instance associated with OSU AP.
-     * {@link #EXTRA_URL}: String representation of a server URL used for OSU process.
-     *
-     * @hide
-     */
-    @SystemApi
-    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
-    public static final String ACTION_PASSPOINT_LAUNCH_OSU_VIEW =
-            "android.net.wifi.action.PASSPOINT_LAUNCH_OSU_VIEW";
-
-    /**
-     * The lookup key for a {@link android.net.Network} associated with a Passpoint OSU server.
-     * Included in the {@link #ACTION_PASSPOINT_LAUNCH_OSU_VIEW} broadcast.
-     *
-     * Retrieve with {@link android.content.Intent#getParcelableExtra(String)}.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final String EXTRA_OSU_NETWORK = "android.net.wifi.extra.OSU_NETWORK";
-
-    /**
-     * String representation of an URL for Passpoint OSU.
-     * Included in the {@link #ACTION_PASSPOINT_LAUNCH_OSU_VIEW} broadcast.
-     *
-     * Retrieve with {@link android.content.Intent#getStringExtra(String)}.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final String EXTRA_URL = "android.net.wifi.extra.URL";
-
-    /**
-     * Broadcast intent action indicating that Wi-Fi has been enabled, disabled,
-     * enabling, disabling, or unknown. One extra provides this state as an int.
-     * Another extra provides the previous state, if available.  No network-related
-     * permissions are required to subscribe to this broadcast.
-     *
-     * <p class="note">This broadcast is not delivered to manifest receivers in
-     * applications that target API version 26 or later.
-     *
-     * @see #EXTRA_WIFI_STATE
-     * @see #EXTRA_PREVIOUS_WIFI_STATE
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String WIFI_STATE_CHANGED_ACTION =
-        "android.net.wifi.WIFI_STATE_CHANGED";
-    /**
-     * The lookup key for an int that indicates whether Wi-Fi is enabled,
-     * disabled, enabling, disabling, or unknown.  Retrieve it with
-     * {@link android.content.Intent#getIntExtra(String,int)}.
-     *
-     * @see #WIFI_STATE_DISABLED
-     * @see #WIFI_STATE_DISABLING
-     * @see #WIFI_STATE_ENABLED
-     * @see #WIFI_STATE_ENABLING
-     * @see #WIFI_STATE_UNKNOWN
-     */
-    public static final String EXTRA_WIFI_STATE = "wifi_state";
-    /**
-     * The previous Wi-Fi state.
-     *
-     * @see #EXTRA_WIFI_STATE
-     */
-    public static final String EXTRA_PREVIOUS_WIFI_STATE = "previous_wifi_state";
-
-    /**
-     * Wi-Fi is currently being disabled. The state will change to {@link #WIFI_STATE_DISABLED} if
-     * it finishes successfully.
-     *
-     * @see #WIFI_STATE_CHANGED_ACTION
-     * @see #getWifiState()
-     */
-    public static final int WIFI_STATE_DISABLING = 0;
-    /**
-     * Wi-Fi is disabled.
-     *
-     * @see #WIFI_STATE_CHANGED_ACTION
-     * @see #getWifiState()
-     */
-    public static final int WIFI_STATE_DISABLED = 1;
-    /**
-     * Wi-Fi is currently being enabled. The state will change to {@link #WIFI_STATE_ENABLED} if
-     * it finishes successfully.
-     *
-     * @see #WIFI_STATE_CHANGED_ACTION
-     * @see #getWifiState()
-     */
-    public static final int WIFI_STATE_ENABLING = 2;
-    /**
-     * Wi-Fi is enabled.
-     *
-     * @see #WIFI_STATE_CHANGED_ACTION
-     * @see #getWifiState()
-     */
-    public static final int WIFI_STATE_ENABLED = 3;
-    /**
-     * Wi-Fi is in an unknown state. This state will occur when an error happens while enabling
-     * or disabling.
-     *
-     * @see #WIFI_STATE_CHANGED_ACTION
-     * @see #getWifiState()
-     */
-    public static final int WIFI_STATE_UNKNOWN = 4;
-
-    /**
-     * Broadcast intent action indicating that Wi-Fi AP has been enabled, disabled,
-     * enabling, disabling, or failed.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final String WIFI_AP_STATE_CHANGED_ACTION =
-        "android.net.wifi.WIFI_AP_STATE_CHANGED";
-
-    /**
-     * The lookup key for an int that indicates whether Wi-Fi AP is enabled,
-     * disabled, enabling, disabling, or failed.  Retrieve it with
-     * {@link android.content.Intent#getIntExtra(String,int)}.
-     *
-     * @see #WIFI_AP_STATE_DISABLED
-     * @see #WIFI_AP_STATE_DISABLING
-     * @see #WIFI_AP_STATE_ENABLED
-     * @see #WIFI_AP_STATE_ENABLING
-     * @see #WIFI_AP_STATE_FAILED
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final String EXTRA_WIFI_AP_STATE = "wifi_state";
-
-    /**
-     * An extra containing the int error code for Soft AP start failure.
-     * Can be obtained from the {@link #WIFI_AP_STATE_CHANGED_ACTION} using
-     * {@link android.content.Intent#getIntExtra}.
-     * This extra will only be attached if {@link #EXTRA_WIFI_AP_STATE} is
-     * attached and is equal to {@link #WIFI_AP_STATE_FAILED}.
-     *
-     * The error code will be one of:
-     * {@link #SAP_START_FAILURE_GENERAL},
-     * {@link #SAP_START_FAILURE_NO_CHANNEL},
-     * {@link #SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION}
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final String EXTRA_WIFI_AP_FAILURE_REASON =
-            "android.net.wifi.extra.WIFI_AP_FAILURE_REASON";
-    /**
-     * The previous Wi-Fi state.
-     *
-     * @see #EXTRA_WIFI_AP_STATE
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final String EXTRA_PREVIOUS_WIFI_AP_STATE = "previous_wifi_state";
-    /**
-     * The lookup key for a String extra that stores the interface name used for the Soft AP.
-     * This extra is included in the broadcast {@link #WIFI_AP_STATE_CHANGED_ACTION}.
-     * Retrieve its value with {@link android.content.Intent#getStringExtra(String)}.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final String EXTRA_WIFI_AP_INTERFACE_NAME =
-            "android.net.wifi.extra.WIFI_AP_INTERFACE_NAME";
-    /**
-     * The lookup key for an int extra that stores the intended IP mode for this Soft AP.
-     * One of {@link #IFACE_IP_MODE_TETHERED} or {@link #IFACE_IP_MODE_LOCAL_ONLY}.
-     * This extra is included in the broadcast {@link #WIFI_AP_STATE_CHANGED_ACTION}.
-     * Retrieve its value with {@link android.content.Intent#getIntExtra(String, int)}.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final String EXTRA_WIFI_AP_MODE = "android.net.wifi.extra.WIFI_AP_MODE";
-
-    /** @hide */
-    @IntDef(flag = false, prefix = { "WIFI_AP_STATE_" }, value = {
-        WIFI_AP_STATE_DISABLING,
-        WIFI_AP_STATE_DISABLED,
-        WIFI_AP_STATE_ENABLING,
-        WIFI_AP_STATE_ENABLED,
-        WIFI_AP_STATE_FAILED,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface WifiApState {}
-
-    /**
-     * Wi-Fi AP is currently being disabled. The state will change to
-     * {@link #WIFI_AP_STATE_DISABLED} if it finishes successfully.
-     *
-     * @see #WIFI_AP_STATE_CHANGED_ACTION
-     * @see #getWifiApState()
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int WIFI_AP_STATE_DISABLING = 10;
-    /**
-     * Wi-Fi AP is disabled.
-     *
-     * @see #WIFI_AP_STATE_CHANGED_ACTION
-     * @see #getWifiState()
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int WIFI_AP_STATE_DISABLED = 11;
-    /**
-     * Wi-Fi AP is currently being enabled. The state will change to
-     * {@link #WIFI_AP_STATE_ENABLED} if it finishes successfully.
-     *
-     * @see #WIFI_AP_STATE_CHANGED_ACTION
-     * @see #getWifiApState()
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int WIFI_AP_STATE_ENABLING = 12;
-    /**
-     * Wi-Fi AP is enabled.
-     *
-     * @see #WIFI_AP_STATE_CHANGED_ACTION
-     * @see #getWifiApState()
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int WIFI_AP_STATE_ENABLED = 13;
-    /**
-     * Wi-Fi AP is in a failed state. This state will occur when an error occurs during
-     * enabling or disabling
-     *
-     * @see #WIFI_AP_STATE_CHANGED_ACTION
-     * @see #getWifiApState()
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int WIFI_AP_STATE_FAILED = 14;
-
-    /** @hide */
-    @IntDef(flag = false, prefix = { "SAP_START_FAILURE_" }, value = {
-        SAP_START_FAILURE_GENERAL,
-        SAP_START_FAILURE_NO_CHANNEL,
-        SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface SapStartFailure {}
-
-    /**
-     *  All other reasons for AP start failure besides {@link #SAP_START_FAILURE_NO_CHANNEL} and
-     *  {@link #SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION}.
-     *
-     *  @hide
-     */
-    @SystemApi
-    public static final int SAP_START_FAILURE_GENERAL= 0;
-
-    /**
-     *  If Wi-Fi AP start failed, this reason code means that no legal channel exists on user
-     *  selected band due to regulatory constraints.
-     *
-     *  @hide
-     */
-    @SystemApi
-    public static final int SAP_START_FAILURE_NO_CHANNEL = 1;
-
-    /**
-     *  If Wi-Fi AP start failed, this reason code means that the specified configuration
-     *  is not supported by the current HAL version.
-     *
-     *  @hide
-     */
-    @SystemApi
-    public static final int SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION = 2;
-
-
-    /** @hide */
-    @IntDef(flag = false, prefix = { "SAP_CLIENT_BLOCKED_REASON_" }, value = {
-        SAP_CLIENT_BLOCK_REASON_CODE_BLOCKED_BY_USER,
-        SAP_CLIENT_BLOCK_REASON_CODE_NO_MORE_STAS,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface SapClientBlockedReason {}
-
-    /**
-     *  If Soft Ap client is blocked, this reason code means that client doesn't exist in the
-     *  specified configuration {@link SoftApConfiguration.Builder#setBlockedClientList(List)}
-     *  and {@link SoftApConfiguration.Builder#setAllowedClientList(List)}
-     *  and the {@link SoftApConfiguration.Builder#setClientControlByUserEnabled(boolean)}
-     *  is configured as well.
-     *  @hide
-     */
-    @SystemApi
-    public static final int SAP_CLIENT_BLOCK_REASON_CODE_BLOCKED_BY_USER = 0;
-
-    /**
-     *  If Soft Ap client is blocked, this reason code means that no more clients can be
-     *  associated to this AP since it reached maximum capacity. The maximum capacity is
-     *  the minimum of {@link SoftApConfiguration.Builder#setMaxNumberOfClients(int)} and
-     *  {@link SoftApCapability#getMaxSupportedClients} which get from
-     *  {@link WifiManager.SoftApCallback#onCapabilityChanged(SoftApCapability)}.
-     *
-     *  @hide
-     */
-    @SystemApi
-    public static final int SAP_CLIENT_BLOCK_REASON_CODE_NO_MORE_STAS = 1;
-
-    /**
-     * Client disconnected for unspecified reason. This could for example be because the AP is being
-     * shut down.
-     * @hide
-     */
-    public static final int SAP_CLIENT_DISCONNECT_REASON_CODE_UNSPECIFIED = 2;
-
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(prefix = {"IFACE_IP_MODE_"}, value = {
-            IFACE_IP_MODE_UNSPECIFIED,
-            IFACE_IP_MODE_CONFIGURATION_ERROR,
-            IFACE_IP_MODE_TETHERED,
-            IFACE_IP_MODE_LOCAL_ONLY})
-    public @interface IfaceIpMode {}
-
-    /**
-     * Interface IP mode unspecified.
-     *
-     * @see #updateInterfaceIpState(String, int)
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int IFACE_IP_MODE_UNSPECIFIED = -1;
-
-    /**
-     * Interface IP mode for configuration error.
-     *
-     * @see #updateInterfaceIpState(String, int)
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int IFACE_IP_MODE_CONFIGURATION_ERROR = 0;
-
-    /**
-     * Interface IP mode for tethering.
-     *
-     * @see #updateInterfaceIpState(String, int)
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int IFACE_IP_MODE_TETHERED = 1;
-
-    /**
-     * Interface IP mode for Local Only Hotspot.
-     *
-     * @see #updateInterfaceIpState(String, int)
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int IFACE_IP_MODE_LOCAL_ONLY = 2;
-
-    /**
-     * Broadcast intent action indicating that the wifi network settings
-     * had been reset.
-     *
-     * Note: This intent is sent as a directed broadcast to each manifest registered receiver.
-     * Intent will not be received by dynamically registered receivers.
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_CARRIER_PROVISIONING)
-    public static final String ACTION_NETWORK_SETTINGS_RESET =
-            "android.net.wifi.action.NETWORK_SETTINGS_RESET";
-
-    /**
-     * Broadcast intent action indicating that a connection to the supplicant has
-     * been established (and it is now possible
-     * to perform Wi-Fi operations) or the connection to the supplicant has been
-     * lost. One extra provides the connection state as a boolean, where {@code true}
-     * means CONNECTED.
-     * @deprecated This is no longer supported.
-     * @see #EXTRA_SUPPLICANT_CONNECTED
-     */
-    @Deprecated
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String SUPPLICANT_CONNECTION_CHANGE_ACTION =
-        "android.net.wifi.supplicant.CONNECTION_CHANGE";
-    /**
-     * The lookup key for a boolean that indicates whether a connection to
-     * the supplicant daemon has been gained or lost. {@code true} means
-     * a connection now exists.
-     * Retrieve it with {@link android.content.Intent#getBooleanExtra(String,boolean)}.
-     * @deprecated This is no longer supported.
-     */
-    @Deprecated
-    public static final String EXTRA_SUPPLICANT_CONNECTED = "connected";
-    /**
-     * Broadcast intent action indicating that the state of Wi-Fi connectivity
-     * has changed. An extra provides the new state
-     * in the form of a {@link android.net.NetworkInfo} object.  No network-related
-     * permissions are required to subscribe to this broadcast.
-     *
-     * <p class="note">This broadcast is not delivered to manifest receivers in
-     * applications that target API version 26 or later.
-     * @see #EXTRA_NETWORK_INFO
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String NETWORK_STATE_CHANGED_ACTION = "android.net.wifi.STATE_CHANGE";
-    /**
-     * The lookup key for a {@link android.net.NetworkInfo} object associated with the
-     * Wi-Fi network. Retrieve with
-     * {@link android.content.Intent#getParcelableExtra(String)}.
-     */
-    public static final String EXTRA_NETWORK_INFO = "networkInfo";
-    /**
-     * The lookup key for a String giving the BSSID of the access point to which
-     * we are connected. No longer used.
-     */
-    @Deprecated
-    public static final String EXTRA_BSSID = "bssid";
-    /**
-     * The lookup key for a {@link android.net.wifi.WifiInfo} object giving the
-     * information about the access point to which we are connected.
-     * No longer used.
-     */
-    @Deprecated
-    public static final String EXTRA_WIFI_INFO = "wifiInfo";
-    /**
-     * Broadcast intent action indicating that the state of establishing a connection to
-     * an access point has changed.One extra provides the new
-     * {@link SupplicantState}. Note that the supplicant state is Wi-Fi specific, and
-     * is not generally the most useful thing to look at if you are just interested in
-     * the overall state of connectivity.
-     * @see #EXTRA_NEW_STATE
-     * @see #EXTRA_SUPPLICANT_ERROR
-     * @deprecated This is no longer supported.
-     */
-    @Deprecated
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String SUPPLICANT_STATE_CHANGED_ACTION =
-        "android.net.wifi.supplicant.STATE_CHANGE";
-    /**
-     * The lookup key for a {@link SupplicantState} describing the new state
-     * Retrieve with
-     * {@link android.content.Intent#getParcelableExtra(String)}.
-     * @deprecated This is no longer supported.
-     */
-    @Deprecated
-    public static final String EXTRA_NEW_STATE = "newState";
-
-    /**
-     * The lookup key for a {@link SupplicantState} describing the supplicant
-     * error code if any
-     * Retrieve with
-     * {@link android.content.Intent#getIntExtra(String, int)}.
-     * @see #ERROR_AUTHENTICATING
-     * @deprecated This is no longer supported.
-     */
-    @Deprecated
-    public static final String EXTRA_SUPPLICANT_ERROR = "supplicantError";
-
-    /**
-     * The lookup key for a {@link SupplicantState} describing the supplicant
-     * error reason if any
-     * Retrieve with
-     * {@link android.content.Intent#getIntExtra(String, int)}.
-     * @see #ERROR_AUTH_FAILURE_#REASON_CODE
-     * @deprecated This is no longer supported.
-     * @hide
-     */
-    @Deprecated
-    public static final String EXTRA_SUPPLICANT_ERROR_REASON = "supplicantErrorReason";
-
-    /**
-     * Broadcast intent action indicating that the configured networks changed.
-     * This can be as a result of adding/updating/deleting a network.
-     * <br />
-     * {@link #EXTRA_CHANGE_REASON} contains whether the configuration was added/changed/removed.
-     * {@link #EXTRA_WIFI_CONFIGURATION} is never set starting in Android 11.
-     * {@link #EXTRA_MULTIPLE_NETWORKS_CHANGED} is set for backwards compatibility reasons, but
-     * its value is always true, even if only a single network changed.
-     * <br />
-     * The {@link android.Manifest.permission#ACCESS_WIFI_STATE ACCESS_WIFI_STATE} permission is
-     * required to receive this broadcast.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final String CONFIGURED_NETWORKS_CHANGED_ACTION =
-        "android.net.wifi.CONFIGURED_NETWORKS_CHANGE";
-    /**
-     * The lookup key for a {@link android.net.wifi.WifiConfiguration} object representing
-     * the changed Wi-Fi configuration when the {@link #CONFIGURED_NETWORKS_CHANGED_ACTION}
-     * broadcast is sent.
-     * Note: this extra is never set starting in Android 11.
-     * @hide
-     */
-    @SystemApi
-    public static final String EXTRA_WIFI_CONFIGURATION = "wifiConfiguration";
-    /**
-     * Multiple network configurations have changed.
-     * @see #CONFIGURED_NETWORKS_CHANGED_ACTION
-     * Note: this extra is always true starting in Android 11.
-     * @hide
-     */
-    @SystemApi
-    public static final String EXTRA_MULTIPLE_NETWORKS_CHANGED = "multipleChanges";
-    /**
-     * The lookup key for an integer indicating the reason a Wi-Fi network configuration
-     * has changed. One of {@link #CHANGE_REASON_ADDED}, {@link #CHANGE_REASON_REMOVED},
-     * {@link #CHANGE_REASON_CONFIG_CHANGE}.
-     *
-     * @see #CONFIGURED_NETWORKS_CHANGED_ACTION
-     * @hide
-     */
-    @SystemApi
-    public static final String EXTRA_CHANGE_REASON = "changeReason";
-    /**
-     * The configuration is new and was added.
-     * @hide
-     */
-    @SystemApi
-    public static final int CHANGE_REASON_ADDED = 0;
-    /**
-     * The configuration was removed and is no longer present in the system's list of
-     * configured networks.
-     * @hide
-     */
-    @SystemApi
-    public static final int CHANGE_REASON_REMOVED = 1;
-    /**
-     * The configuration has changed as a result of explicit action or because the system
-     * took an automated action such as disabling a malfunctioning configuration.
-     * @hide
-     */
-    @SystemApi
-    public static final int CHANGE_REASON_CONFIG_CHANGE = 2;
-    /**
-     * An access point scan has completed, and results are available.
-     * Call {@link #getScanResults()} to obtain the results.
-     * The broadcast intent may contain an extra field with the key {@link #EXTRA_RESULTS_UPDATED}
-     * and a {@code boolean} value indicating if the scan was successful.
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String SCAN_RESULTS_AVAILABLE_ACTION = "android.net.wifi.SCAN_RESULTS";
-
-    /**
-     * Lookup key for a {@code boolean} extra in intent {@link #SCAN_RESULTS_AVAILABLE_ACTION}
-     * representing if the scan was successful or not.
-     * Scans may fail for multiple reasons, these may include:
-     * <ol>
-     * <li>An app requested too many scans in a certain period of time.
-     * This may lead to additional scan request rejections via "scan throttling" for both
-     * foreground and background apps.
-     * Note: Apps holding android.Manifest.permission.NETWORK_SETTINGS permission are
-     * exempted from scan throttling.
-     * </li>
-     * <li>The device is idle and scanning is disabled.</li>
-     * <li>Wifi hardware reported a scan failure.</li>
-     * </ol>
-     * @return true scan was successful, results are updated
-     * @return false scan was not successful, results haven't been updated since previous scan
-     */
-    public static final String EXTRA_RESULTS_UPDATED = "resultsUpdated";
-
-    /**
-     * A batch of access point scans has been completed and the results areavailable.
-     * Call {@link #getBatchedScanResults()} to obtain the results.
-     * @deprecated This API is nolonger supported.
-     * Use {@link android.net.wifi.WifiScanner} API
-     * @hide
-     */
-    @Deprecated
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String BATCHED_SCAN_RESULTS_AVAILABLE_ACTION =
-            "android.net.wifi.BATCHED_RESULTS";
-
-    /**
-     * The RSSI (signal strength) has changed.
-     *
-     * Receiver Required Permission: android.Manifest.permission.ACCESS_WIFI_STATE
-     * @see #EXTRA_NEW_RSSI
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String RSSI_CHANGED_ACTION = "android.net.wifi.RSSI_CHANGED";
-    /**
-     * The lookup key for an {@code int} giving the new RSSI in dBm.
-     */
-    public static final String EXTRA_NEW_RSSI = "newRssi";
-
-    /**
-     * @see #ACTION_LINK_CONFIGURATION_CHANGED
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public static final String LINK_CONFIGURATION_CHANGED_ACTION =
-            "android.net.wifi.LINK_CONFIGURATION_CHANGED";
-
-    /**
-     * Broadcast intent action indicating that the link configuration changed on wifi.
-     * <br />Included Extras:
-     * <br />{@link #EXTRA_LINK_PROPERTIES}: may not be set starting in Android 11. Check for
-     * <br /> null before reading its value.
-     * <br /> No permissions are required to listen to this broadcast.
-     * @hide
-     */
-    @SystemApi
-    public static final String ACTION_LINK_CONFIGURATION_CHANGED =
-            // should be android.net.wifi.action.LINK_CONFIGURATION_CHANGED, but due to
-            // @UnsupportedAppUsage leaving it as android.net.wifi.LINK_CONFIGURATION_CHANGED.
-            LINK_CONFIGURATION_CHANGED_ACTION;
-
-    /**
-     * The lookup key for a {@link android.net.LinkProperties} object associated with the
-     * Wi-Fi network.
-     * Included in the {@link #ACTION_LINK_CONFIGURATION_CHANGED} broadcast.
-     *
-     * Retrieve with {@link android.content.Intent#getParcelableExtra(String)}.
-     *
-     * Note: this extra may not be set starting in Android 11. Check for null before reading its
-     * value.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final String EXTRA_LINK_PROPERTIES = "android.net.wifi.extra.LINK_PROPERTIES";
-
-    /**
-     * The lookup key for a {@link android.net.NetworkCapabilities} object associated with the
-     * Wi-Fi network. Retrieve with
-     * {@link android.content.Intent#getParcelableExtra(String)}.
-     * @hide
-     */
-    public static final String EXTRA_NETWORK_CAPABILITIES = "networkCapabilities";
-
-    /**
-     * The network IDs of the configured networks could have changed.
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String NETWORK_IDS_CHANGED_ACTION = "android.net.wifi.NETWORK_IDS_CHANGED";
-
-    /**
-     * Activity Action: Show a system activity that allows the user to enable
-     * scans to be available even with Wi-Fi turned off.
-     *
-     * <p>Notification of the result of this activity is posted using the
-     * {@link android.app.Activity#onActivityResult} callback. The
-     * <code>resultCode</code>
-     * will be {@link android.app.Activity#RESULT_OK} if scan always mode has
-     * been turned on or {@link android.app.Activity#RESULT_CANCELED} if the user
-     * has rejected the request or an error has occurred.
-     */
-    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
-    public static final String ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE =
-            "android.net.wifi.action.REQUEST_SCAN_ALWAYS_AVAILABLE";
-
-    /**
-     * Activity Action: Pick a Wi-Fi network to connect to.
-     * <p>Input: Nothing.
-     * <p>Output: Nothing.
-     */
-    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
-    public static final String ACTION_PICK_WIFI_NETWORK = "android.net.wifi.PICK_WIFI_NETWORK";
-
-    /**
-     * Activity Action: Receiver should show UI to get user approval to enable WiFi.
-     * <p>Input: {@link android.content.Intent#EXTRA_PACKAGE_NAME} string extra with
-     *           the name of the app requesting the action.
-     * <p>Output: Nothing.
-     * <p>No permissions are required to send this action.
-     * @hide
-     */
-    @SystemApi
-    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
-    public static final String ACTION_REQUEST_ENABLE = "android.net.wifi.action.REQUEST_ENABLE";
-
-    /**
-     * Activity Action: Receiver should show UI to get user approval to disable WiFi.
-     * <p>Input: {@link android.content.Intent#EXTRA_PACKAGE_NAME} string extra with
-     *           the name of the app requesting the action.
-     * <p>Output: Nothing.
-     * <p>No permissions are required to send this action.
-     * @hide
-     */
-    @SystemApi
-    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
-    public static final String ACTION_REQUEST_DISABLE = "android.net.wifi.action.REQUEST_DISABLE";
-
-    /**
-     * Directed broadcast intent action indicating that the device has connected to one of the
-     * network suggestions provided by the app. This will be sent post connection to a network
-     * which was created with {@link WifiNetworkSuggestion.Builder#setIsAppInteractionRequired(
-     * boolean)}
-     * flag set.
-     * <p>
-     * Note: The broadcast is sent to the app only if it holds
-     * {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission.
-     *
-     * @see #EXTRA_NETWORK_SUGGESTION
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION =
-            "android.net.wifi.action.WIFI_NETWORK_SUGGESTION_POST_CONNECTION";
-    /**
-     * Sent as as a part of {@link #ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION} that holds
-     * an instance of {@link WifiNetworkSuggestion} corresponding to the connected network.
-     */
-    public static final String EXTRA_NETWORK_SUGGESTION =
-            "android.net.wifi.extra.NETWORK_SUGGESTION";
-
-    /**
-     * Internally used Wi-Fi lock mode representing the case were no locks are held.
-     * @hide
-     */
-    public static final int WIFI_MODE_NO_LOCKS_HELD = 0;
-
-    /**
-     * In this Wi-Fi lock mode, Wi-Fi will be kept active,
-     * and will behave normally, i.e., it will attempt to automatically
-     * establish a connection to a remembered access point that is
-     * within range, and will do periodic scans if there are remembered
-     * access points but none are in range.
-     *
-     * @deprecated This API is non-functional and will have no impact.
-     */
-    @Deprecated
-    public static final int WIFI_MODE_FULL = 1;
-
-    /**
-     * In this Wi-Fi lock mode, Wi-Fi will be kept active,
-     * but the only operation that will be supported is initiation of
-     * scans, and the subsequent reporting of scan results. No attempts
-     * will be made to automatically connect to remembered access points,
-     * nor will periodic scans be automatically performed looking for
-     * remembered access points. Scans must be explicitly requested by
-     * an application in this mode.
-     *
-     * @deprecated This API is non-functional and will have no impact.
-     */
-    @Deprecated
-    public static final int WIFI_MODE_SCAN_ONLY = 2;
-
-    /**
-     * In this Wi-Fi lock mode, Wi-Fi will not go to power save.
-     * This results in operating with low packet latency.
-     * The lock is only active when the device is connected to an access point.
-     * The lock is active even when the device screen is off or the acquiring application is
-     * running in the background.
-     * This mode will consume more power and hence should be used only
-     * when there is a need for this tradeoff.
-     * <p>
-     * An example use case is when a voice connection needs to be
-     * kept active even after the device screen goes off.
-     * Holding a {@link #WIFI_MODE_FULL_HIGH_PERF} lock for the
-     * duration of the voice call may improve the call quality.
-     * <p>
-     * When there is no support from the hardware, the {@link #WIFI_MODE_FULL_HIGH_PERF}
-     * lock will have no impact.
-     */
-    public static final int WIFI_MODE_FULL_HIGH_PERF = 3;
-
-    /**
-     * In this Wi-Fi lock mode, Wi-Fi will operate with a priority to achieve low latency.
-     * {@link #WIFI_MODE_FULL_LOW_LATENCY} lock has the following limitations:
-     * <ol>
-     * <li>The lock is only active when the device is connected to an access point.</li>
-     * <li>The lock is only active when the screen is on.</li>
-     * <li>The lock is only active when the acquiring app is running in the foreground.</li>
-     * </ol>
-     * Low latency mode optimizes for reduced packet latency,
-     * and as a result other performance measures may suffer when there are trade-offs to make:
-     * <ol>
-     * <li>Battery life may be reduced.</li>
-     * <li>Throughput may be reduced.</li>
-     * <li>Frequency of Wi-Fi scanning may be reduced. This may result in: </li>
-     * <ul>
-     * <li>The device may not roam or switch to the AP with highest signal quality.</li>
-     * <li>Location accuracy may be reduced.</li>
-     * </ul>
-     * </ol>
-     * <p>
-     * Example use cases are real time gaming or virtual reality applications where
-     * low latency is a key factor for user experience.
-     * <p>
-     * Note: For an app which acquires both {@link #WIFI_MODE_FULL_LOW_LATENCY} and
-     * {@link #WIFI_MODE_FULL_HIGH_PERF} locks, {@link #WIFI_MODE_FULL_LOW_LATENCY}
-     * lock will be effective when app is running in foreground and screen is on,
-     * while the {@link #WIFI_MODE_FULL_HIGH_PERF} lock will take effect otherwise.
-     */
-    public static final int WIFI_MODE_FULL_LOW_LATENCY = 4;
-
-
-    /** Anything worse than or equal to this will show 0 bars. */
-    @UnsupportedAppUsage
-    private static final int MIN_RSSI = -100;
-
-    /** Anything better than or equal to this will show the max bars. */
-    @UnsupportedAppUsage
-    private static final int MAX_RSSI = -55;
-
-    /**
-     * Number of RSSI levels used in the framework to initiate {@link #RSSI_CHANGED_ACTION}
-     * broadcast, where each level corresponds to a range of RSSI values.
-     * The {@link #RSSI_CHANGED_ACTION} broadcast will only fire if the RSSI
-     * change is significant enough to change the RSSI signal level.
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public static final int RSSI_LEVELS = 5;
-
-    //TODO (b/146346676): This needs to be removed, not used in the code.
-    /**
-     * Auto settings in the driver. The driver could choose to operate on both
-     * 2.4 GHz and 5 GHz or make a dynamic decision on selecting the band.
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public static final int WIFI_FREQUENCY_BAND_AUTO = 0;
-
-    /**
-     * Operation on 5 GHz alone
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public static final int WIFI_FREQUENCY_BAND_5GHZ = 1;
-
-    /**
-     * Operation on 2.4 GHz alone
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public static final int WIFI_FREQUENCY_BAND_2GHZ = 2;
-
-    /** @hide */
-    public static final boolean DEFAULT_POOR_NETWORK_AVOIDANCE_ENABLED = false;
-
-    /**
-     * Maximum number of active locks we allow.
-     * This limit was added to prevent apps from creating a ridiculous number
-     * of locks and crashing the system by overflowing the global ref table.
-     */
-    private static final int MAX_ACTIVE_LOCKS = 50;
-
-    /** Indicates an invalid SSID. */
-    public static final String UNKNOWN_SSID = "<unknown ssid>";
-
-    /** @hide */
-    public static final MacAddress ALL_ZEROS_MAC_ADDRESS =
-            MacAddress.fromString("00:00:00:00:00:00");
-
-    /* Number of currently active WifiLocks and MulticastLocks */
-    @UnsupportedAppUsage
-    private int mActiveLockCount;
-
-    private Context mContext;
-    @UnsupportedAppUsage
-    IWifiManager mService;
-    private final int mTargetSdkVersion;
-
-    private Looper mLooper;
-    private boolean mVerboseLoggingEnabled = false;
-
-    private final Object mLock = new Object(); // lock guarding access to the following vars
-    @GuardedBy("mLock")
-    private LocalOnlyHotspotCallbackProxy mLOHSCallbackProxy;
-    @GuardedBy("mLock")
-    private LocalOnlyHotspotObserverProxy mLOHSObserverProxy;
-
-    /**
-     * Create a new WifiManager instance.
-     * Applications will almost always want to use
-     * {@link android.content.Context#getSystemService Context.getSystemService} to retrieve
-     * the standard {@link android.content.Context#WIFI_SERVICE Context.WIFI_SERVICE}.
-     *
-     * @param context the application context
-     * @param service the Binder interface
-     * @param looper the Looper used to deliver callbacks
-     * @hide - hide this because it takes in a parameter of type IWifiManager, which
-     * is a system private class.
-     */
-    public WifiManager(@NonNull Context context, @NonNull IWifiManager service,
-        @NonNull Looper looper) {
-        mContext = context;
-        mService = service;
-        mLooper = looper;
-        mTargetSdkVersion = context.getApplicationInfo().targetSdkVersion;
-        updateVerboseLoggingEnabledFromService();
-    }
-
-    /**
-     * Return a list of all the networks configured for the current foreground
-     * user.
-     *
-     * Not all fields of WifiConfiguration are returned. Only the following
-     * fields are filled in:
-     * <ul>
-     * <li>networkId</li>
-     * <li>SSID</li>
-     * <li>BSSID</li>
-     * <li>priority</li>
-     * <li>allowedProtocols</li>
-     * <li>allowedKeyManagement</li>
-     * <li>allowedAuthAlgorithms</li>
-     * <li>allowedPairwiseCiphers</li>
-     * <li>allowedGroupCiphers</li>
-     * <li>status</li>
-     * </ul>
-     * @return a list of network configurations in the form of a list
-     * of {@link WifiConfiguration} objects.
-     *
-     * @deprecated
-     * a) See {@link WifiNetworkSpecifier.Builder#build()} for new
-     * mechanism to trigger connection to a Wi-Fi network.
-     * b) See {@link #addNetworkSuggestions(List)},
-     * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration
-     * when auto-connecting to wifi.
-     * <b>Compatibility Note:</b> For applications targeting
-     * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always fail and return an
-     * empty list.
-     * <p>
-     * Deprecation Exemptions:
-     * <ul>
-     * <li>Device Owner (DO), Profile Owner (PO) and system apps will have access to the full list.
-     * <li>Callers with Carrier privilege will receive a restricted list only containing
-     * configurations which they created.
-     * </ul>
-     */
-    @Deprecated
-    @RequiresPermission(allOf = {ACCESS_FINE_LOCATION, ACCESS_WIFI_STATE})
-    public List<WifiConfiguration> getConfiguredNetworks() {
-        try {
-            ParceledListSlice<WifiConfiguration> parceledList =
-                    mService.getConfiguredNetworks(mContext.getOpPackageName(),
-                            mContext.getAttributionTag());
-            if (parceledList == null) {
-                return Collections.emptyList();
-            }
-            return parceledList.getList();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /** @hide */
-    @SystemApi
-    @RequiresPermission(allOf = {ACCESS_FINE_LOCATION, ACCESS_WIFI_STATE, READ_WIFI_CREDENTIAL})
-    public List<WifiConfiguration> getPrivilegedConfiguredNetworks() {
-        try {
-            ParceledListSlice<WifiConfiguration> parceledList =
-                    mService.getPrivilegedConfiguredNetworks(mContext.getOpPackageName(),
-                            mContext.getAttributionTag());
-            if (parceledList == null) {
-                return Collections.emptyList();
-            }
-            return parceledList.getList();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Returns a list of all matching WifiConfigurations for a given list of ScanResult.
-     *
-     * An empty list will be returned when no configurations are installed or if no configurations
-     * match the ScanResult.
-     *
-     * @param scanResults a list of scanResult that represents the BSSID
-     * @return List that consists of {@link WifiConfiguration} and corresponding scanResults per
-     * network type({@link #PASSPOINT_HOME_NETWORK} and {@link #PASSPOINT_ROAMING_NETWORK}).
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(anyOf = {
-            android.Manifest.permission.NETWORK_SETTINGS,
-            android.Manifest.permission.NETWORK_SETUP_WIZARD
-    })
-    @NonNull
-    public List<Pair<WifiConfiguration, Map<Integer, List<ScanResult>>>> getAllMatchingWifiConfigs(
-            @NonNull List<ScanResult> scanResults) {
-        List<Pair<WifiConfiguration, Map<Integer, List<ScanResult>>>> configs = new ArrayList<>();
-        try {
-            Map<String, Map<Integer, List<ScanResult>>> results =
-                    mService.getAllMatchingPasspointProfilesForScanResults(scanResults);
-            if (results.isEmpty()) {
-                return configs;
-            }
-            List<WifiConfiguration> wifiConfigurations =
-                    mService.getWifiConfigsForPasspointProfiles(
-                            new ArrayList<>(results.keySet()));
-            for (WifiConfiguration configuration : wifiConfigurations) {
-                Map<Integer, List<ScanResult>> scanResultsPerNetworkType =
-                        results.get(configuration.getKey());
-                if (scanResultsPerNetworkType != null) {
-                    configs.add(Pair.create(configuration, scanResultsPerNetworkType));
-                }
-            }
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-
-        return configs;
-    }
-
-    /**
-     * Retrieve a list of {@link WifiConfiguration} for available {@link WifiNetworkSuggestion}
-     * matching the given list of {@link ScanResult}.
-     *
-     * An available {@link WifiNetworkSuggestion} must satisfy:
-     * <ul>
-     * <li> Matching one of the {@link ScanResult} from the given list.
-     * <li> and {@link WifiNetworkSuggestion.Builder#setIsUserAllowedToManuallyConnect(boolean)} set
-     * to true.
-     * </ul>
-     *
-     * @param scanResults a list of scanResult.
-     * @return a list of @link WifiConfiguration} for available {@link WifiNetworkSuggestion}
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(anyOf = {
-            android.Manifest.permission.NETWORK_SETTINGS,
-            android.Manifest.permission.NETWORK_SETUP_WIZARD
-    })
-    @NonNull
-    public List<WifiConfiguration> getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(
-            @NonNull List<ScanResult> scanResults) {
-        try {
-            return mService.getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(scanResults);
-        } catch (RemoteException e) {
-            throw e.rethrowAsRuntimeException();
-        }
-    }
-
-    /**
-     * Returns a list of unique Hotspot 2.0 OSU (Online Sign-Up) providers associated with a given
-     * list of ScanResult.
-     *
-     * An empty list will be returned if no match is found.
-     *
-     * @param scanResults a list of ScanResult
-     * @return Map that consists {@link OsuProvider} and a list of matching {@link ScanResult}
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(anyOf = {
-            android.Manifest.permission.NETWORK_SETTINGS,
-            android.Manifest.permission.NETWORK_SETUP_WIZARD
-    })
-    @NonNull
-    public Map<OsuProvider, List<ScanResult>> getMatchingOsuProviders(
-            @Nullable List<ScanResult> scanResults) {
-        if (scanResults == null) {
-            return new HashMap<>();
-        }
-        try {
-            return mService.getMatchingOsuProviders(scanResults);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Returns the matching Passpoint R2 configurations for given OSU (Online Sign-Up) providers.
-     *
-     * Given a list of OSU providers, this only returns OSU providers that already have Passpoint R2
-     * configurations in the device.
-     * An empty map will be returned when there is no matching Passpoint R2 configuration for the
-     * given OsuProviders.
-     *
-     * @param osuProviders a set of {@link OsuProvider}
-     * @return Map that consists of {@link OsuProvider} and matching {@link PasspointConfiguration}.
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(anyOf = {
-            android.Manifest.permission.NETWORK_SETTINGS,
-            android.Manifest.permission.NETWORK_SETUP_WIZARD
-    })
-    @NonNull
-    public Map<OsuProvider, PasspointConfiguration> getMatchingPasspointConfigsForOsuProviders(
-            @NonNull Set<OsuProvider> osuProviders) {
-        try {
-            return mService.getMatchingPasspointConfigsForOsuProviders(
-                    new ArrayList<>(osuProviders));
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Add a new network description to the set of configured networks.
-     * The {@code networkId} field of the supplied configuration object
-     * is ignored.
-     * <p/>
-     * The new network will be marked DISABLED by default. To enable it,
-     * called {@link #enableNetwork}.
-     *
-     * @param config the set of variables that describe the configuration,
-     *            contained in a {@link WifiConfiguration} object.
-     *            If the {@link WifiConfiguration} has an Http Proxy set
-     *            the calling app must be System, or be provisioned as the Profile or Device Owner.
-     * @return the ID of the newly created network description. This is used in
-     *         other operations to specified the network to be acted upon.
-     *         Returns {@code -1} on failure.
-     *
-     * @deprecated
-     * a) See {@link WifiNetworkSpecifier.Builder#build()} for new
-     * mechanism to trigger connection to a Wi-Fi network.
-     * b) See {@link #addNetworkSuggestions(List)},
-     * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration
-     * when auto-connecting to wifi.
-     * <b>Compatibility Note:</b> For applications targeting
-     * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always fail and return
-     * {@code -1}.
-     * <p>
-     * Deprecation Exemptions:
-     * <ul>
-     * <li>Device Owner (DO), Profile Owner (PO) and system apps.
-     * </ul>
-     */
-    @Deprecated
-    public int addNetwork(WifiConfiguration config) {
-        if (config == null) {
-            return -1;
-        }
-        config.networkId = -1;
-        return addOrUpdateNetwork(config);
-    }
-
-    /**
-     * Update the network description of an existing configured network.
-     *
-     * @param config the set of variables that describe the configuration,
-     *            contained in a {@link WifiConfiguration} object. It may
-     *            be sparse, so that only the items that are being changed
-     *            are non-<code>null</code>. The {@code networkId} field
-     *            must be set to the ID of the existing network being updated.
-     *            If the {@link WifiConfiguration} has an Http Proxy set
-     *            the calling app must be System, or be provisioned as the Profile or Device Owner.
-     * @return Returns the {@code networkId} of the supplied
-     *         {@code WifiConfiguration} on success.
-     *         <br/>
-     *         Returns {@code -1} on failure, including when the {@code networkId}
-     *         field of the {@code WifiConfiguration} does not refer to an
-     *         existing network.
-     *
-     * @deprecated
-     * a) See {@link WifiNetworkSpecifier.Builder#build()} for new
-     * mechanism to trigger connection to a Wi-Fi network.
-     * b) See {@link #addNetworkSuggestions(List)},
-     * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration
-     * when auto-connecting to wifi.
-     * <b>Compatibility Note:</b> For applications targeting
-     * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always fail and return
-     * {@code -1}.
-     * <p>
-     * Deprecation Exemptions:
-     * <ul>
-     * <li>Device Owner (DO), Profile Owner (PO) and system apps.
-     * </ul>
-     */
-    @Deprecated
-    public int updateNetwork(WifiConfiguration config) {
-        if (config == null || config.networkId < 0) {
-            return -1;
-        }
-        return addOrUpdateNetwork(config);
-    }
-
-    /**
-     * Internal method for doing the RPC that creates a new network description
-     * or updates an existing one.
-     *
-     * @param config The possibly sparse object containing the variables that
-     *         are to set or updated in the network description.
-     * @return the ID of the network on success, {@code -1} on failure.
-     */
-    private int addOrUpdateNetwork(WifiConfiguration config) {
-        try {
-            return mService.addOrUpdateNetwork(config, mContext.getOpPackageName());
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Interface for indicating user selection from the list of networks presented in the
-     * {@link NetworkRequestMatchCallback#onMatch(List)}.
-     *
-     * The platform will implement this callback and pass it along with the
-     * {@link NetworkRequestMatchCallback#onUserSelectionCallbackRegistration(
-     * NetworkRequestUserSelectionCallback)}. The UI component handling
-     * {@link NetworkRequestMatchCallback} will invoke {@link #select(WifiConfiguration)} or
-     * {@link #reject()} to return the user's selection back to the platform via this callback.
-     * @hide
-     */
-    @SystemApi
-    public interface NetworkRequestUserSelectionCallback {
-        /**
-         * User selected this network to connect to.
-         * @param wifiConfiguration WifiConfiguration object corresponding to the network
-         *                          user selected.
-         */
-        @SuppressLint("CallbackMethodName")
-        default void select(@NonNull WifiConfiguration wifiConfiguration) {}
-
-        /**
-         * User rejected the app's request.
-         */
-        @SuppressLint("CallbackMethodName")
-        default void reject() {}
-    }
-
-    /**
-     * Interface for network request callback. Should be implemented by applications and passed when
-     * calling {@link #registerNetworkRequestMatchCallback(Executor,
-     * WifiManager.NetworkRequestMatchCallback)}.
-     *
-     * This is meant to be implemented by a UI component to present the user with a list of networks
-     * matching the app's request. The user is allowed to pick one of these networks to connect to
-     * or reject the request by the app.
-     * @hide
-     */
-    @SystemApi
-    public interface NetworkRequestMatchCallback {
-        /**
-         * Invoked to register a callback to be invoked to convey user selection. The callback
-         * object passed in this method is to be invoked by the UI component after the service sends
-         * a list of matching scan networks using {@link #onMatch(List)} and user picks a network
-         * from that list.
-         *
-         * @param userSelectionCallback Callback object to send back the user selection.
-         */
-        default void onUserSelectionCallbackRegistration(
-                @NonNull NetworkRequestUserSelectionCallback userSelectionCallback) {}
-
-        /**
-         * Invoked when the active network request is aborted, either because
-         * <li> The app released the request, OR</li>
-         * <li> Request was overridden by a new request</li>
-         * This signals the end of processing for the current request and should stop the UI
-         * component. No subsequent calls from the UI component will be handled by the platform.
-         */
-        default void onAbort() {}
-
-        /**
-         * Invoked when a network request initiated by an app matches some networks in scan results.
-         * This may be invoked multiple times for a single network request as the platform finds new
-         * matching networks in scan results.
-         *
-         * @param scanResults List of {@link ScanResult} objects corresponding to the networks
-         *                    matching the request.
-         */
-        default void onMatch(@NonNull List<ScanResult> scanResults) {}
-
-        /**
-         * Invoked on a successful connection with the network that the user selected
-         * via {@link NetworkRequestUserSelectionCallback}.
-         *
-         * @param wifiConfiguration WifiConfiguration object corresponding to the network that the
-         *                          user selected.
-         */
-        default void onUserSelectionConnectSuccess(@NonNull WifiConfiguration wifiConfiguration) {}
-
-        /**
-         * Invoked on failure to establish connection with the network that the user selected
-         * via {@link NetworkRequestUserSelectionCallback}.
-         *
-         * @param wifiConfiguration WifiConfiguration object corresponding to the network
-         *                          user selected.
-         */
-        default void onUserSelectionConnectFailure(@NonNull WifiConfiguration wifiConfiguration) {}
-    }
-
-    /**
-     * Callback proxy for NetworkRequestUserSelectionCallback objects.
-     * @hide
-     */
-    private class NetworkRequestUserSelectionCallbackProxy implements
-            NetworkRequestUserSelectionCallback {
-        private final INetworkRequestUserSelectionCallback mCallback;
-
-        NetworkRequestUserSelectionCallbackProxy(
-                INetworkRequestUserSelectionCallback callback) {
-            mCallback = callback;
-        }
-
-        @Override
-        public void select(@NonNull WifiConfiguration wifiConfiguration) {
-            if (mVerboseLoggingEnabled) {
-                Log.v(TAG, "NetworkRequestUserSelectionCallbackProxy: select "
-                        + "wificonfiguration: " + wifiConfiguration);
-            }
-            try {
-                mCallback.select(wifiConfiguration);
-            } catch (RemoteException e) {
-                Log.e(TAG, "Failed to invoke onSelected", e);
-                throw e.rethrowFromSystemServer();
-            }
-        }
-
-        @Override
-        public void reject() {
-            if (mVerboseLoggingEnabled) {
-                Log.v(TAG, "NetworkRequestUserSelectionCallbackProxy: reject");
-            }
-            try {
-                mCallback.reject();
-            } catch (RemoteException e) {
-                Log.e(TAG, "Failed to invoke onRejected", e);
-                throw e.rethrowFromSystemServer();
-            }
-        }
-    }
-
-    /**
-     * Callback proxy for NetworkRequestMatchCallback objects.
-     * @hide
-     */
-    private class NetworkRequestMatchCallbackProxy extends INetworkRequestMatchCallback.Stub {
-        private final Executor mExecutor;
-        private final NetworkRequestMatchCallback mCallback;
-
-        NetworkRequestMatchCallbackProxy(Executor executor, NetworkRequestMatchCallback callback) {
-            mExecutor = executor;
-            mCallback = callback;
-        }
-
-        @Override
-        public void onUserSelectionCallbackRegistration(
-                INetworkRequestUserSelectionCallback userSelectionCallback) {
-            if (mVerboseLoggingEnabled) {
-                Log.v(TAG, "NetworkRequestMatchCallbackProxy: "
-                        + "onUserSelectionCallbackRegistration callback: " + userSelectionCallback);
-            }
-            Binder.clearCallingIdentity();
-            mExecutor.execute(() -> {
-                mCallback.onUserSelectionCallbackRegistration(
-                        new NetworkRequestUserSelectionCallbackProxy(userSelectionCallback));
-            });
-        }
-
-        @Override
-        public void onAbort() {
-            if (mVerboseLoggingEnabled) {
-                Log.v(TAG, "NetworkRequestMatchCallbackProxy: onAbort");
-            }
-            Binder.clearCallingIdentity();
-            mExecutor.execute(() -> {
-                mCallback.onAbort();
-            });
-        }
-
-        @Override
-        public void onMatch(List<ScanResult> scanResults) {
-            if (mVerboseLoggingEnabled) {
-                Log.v(TAG, "NetworkRequestMatchCallbackProxy: onMatch scanResults: "
-                        + scanResults);
-            }
-            Binder.clearCallingIdentity();
-            mExecutor.execute(() -> {
-                mCallback.onMatch(scanResults);
-            });
-        }
-
-        @Override
-        public void onUserSelectionConnectSuccess(WifiConfiguration wifiConfiguration) {
-            if (mVerboseLoggingEnabled) {
-                Log.v(TAG, "NetworkRequestMatchCallbackProxy: onUserSelectionConnectSuccess "
-                        + " wificonfiguration: " + wifiConfiguration);
-            }
-            Binder.clearCallingIdentity();
-            mExecutor.execute(() -> {
-                mCallback.onUserSelectionConnectSuccess(wifiConfiguration);
-            });
-        }
-
-        @Override
-        public void onUserSelectionConnectFailure(WifiConfiguration wifiConfiguration) {
-            if (mVerboseLoggingEnabled) {
-                Log.v(TAG, "NetworkRequestMatchCallbackProxy: onUserSelectionConnectFailure"
-                        + " wificonfiguration: " + wifiConfiguration);
-            }
-            Binder.clearCallingIdentity();
-            mExecutor.execute(() -> {
-                mCallback.onUserSelectionConnectFailure(wifiConfiguration);
-            });
-        }
-    }
-
-    /**
-     * Registers a callback for NetworkRequest matches. See {@link NetworkRequestMatchCallback}.
-     * Caller can unregister a previously registered callback using
-     * {@link #unregisterNetworkRequestMatchCallback(NetworkRequestMatchCallback)}
-     * <p>
-     * Applications should have the
-     * {@link android.Manifest.permission#NETWORK_SETTINGS} permission. Callers
-     * without the permission will trigger a {@link java.lang.SecurityException}.
-     * <p>
-     *
-     * @param executor The Executor on whose thread to execute the callbacks of the {@code callback}
-     *                 object.
-     * @param callback Callback for network match events to register.
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public void registerNetworkRequestMatchCallback(@NonNull @CallbackExecutor Executor executor,
-            @NonNull NetworkRequestMatchCallback callback) {
-        if (executor == null) throw new IllegalArgumentException("executor cannot be null");
-        if (callback == null) throw new IllegalArgumentException("callback cannot be null");
-        Log.v(TAG, "registerNetworkRequestMatchCallback: callback=" + callback
-                + ", executor=" + executor);
-
-        Binder binder = new Binder();
-        try {
-            mService.registerNetworkRequestMatchCallback(
-                    binder, new NetworkRequestMatchCallbackProxy(executor, callback),
-                    callback.hashCode());
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Unregisters a callback for NetworkRequest matches. See {@link NetworkRequestMatchCallback}.
-     * <p>
-     * Applications should have the
-     * {@link android.Manifest.permission#NETWORK_SETTINGS} permission. Callers
-     * without the permission will trigger a {@link java.lang.SecurityException}.
-     * <p>
-     *
-     * @param callback Callback for network match events to unregister.
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public void unregisterNetworkRequestMatchCallback(
-            @NonNull NetworkRequestMatchCallback callback) {
-        if (callback == null) throw new IllegalArgumentException("callback cannot be null");
-        Log.v(TAG, "unregisterNetworkRequestMatchCallback: callback=" + callback);
-
-        try {
-            mService.unregisterNetworkRequestMatchCallback(callback.hashCode());
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Provide a list of network suggestions to the device. See {@link WifiNetworkSuggestion}
-     * for a detailed explanation of the parameters.
-     * When the device decides to connect to one of the provided network suggestions, platform sends
-     * a directed broadcast {@link #ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION} to the app if
-     * the network was created with
-     * {@link WifiNetworkSuggestion.Builder#setIsAppInteractionRequired(boolean)} flag set and the
-     * app holds {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION}
-     * permission.
-     *<p>
-     * NOTE:
-     * <li> These networks are just a suggestion to the platform. The platform will ultimately
-     * decide on which network the device connects to. </li>
-     * <li> When an app is uninstalled or disabled, all its suggested networks are discarded.
-     * If the device is currently connected to a suggested network which is being removed then the
-     * device will disconnect from that network.</li>
-     * <li> If user reset network settings, all added suggestions will be discarded. Apps can use
-     * {@link #getNetworkSuggestions()} to check if their suggestions are in the device.</li>
-     * <li> In-place modification of existing suggestions are allowed.
-     * <li> If the provided suggestions include any previously provided suggestions by the app,
-     * previous suggestions will be updated.</li>
-     * <li>If one of the provided suggestions marks a previously unmetered suggestion as metered and
-     * the device is currently connected to that suggested network, then the device will disconnect
-     * from that network. The system will immediately re-evaluate all the network candidates
-     * and possibly reconnect back to the same suggestion. This disconnect is to make sure that any
-     * traffic flowing over unmetered networks isn't accidentally continued over a metered network.
-     * </li>
-     * </li>
-     *
-     * @param networkSuggestions List of network suggestions provided by the app.
-     * @return Status code for the operation. One of the STATUS_NETWORK_SUGGESTIONS_ values.
-     * @throws {@link SecurityException} if the caller is missing required permissions.
-     * @see WifiNetworkSuggestion#equals(Object)
-     */
-    @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE)
-    public @NetworkSuggestionsStatusCode int addNetworkSuggestions(
-            @NonNull List<WifiNetworkSuggestion> networkSuggestions) {
-        try {
-            return mService.addNetworkSuggestions(
-                    networkSuggestions, mContext.getOpPackageName(), mContext.getAttributionTag());
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Remove some or all of the network suggestions that were previously provided by the app.
-     * If one of the suggestions being removed was used to establish connection to the current
-     * network, then the device will immediately disconnect from that network.
-     *
-     * See {@link WifiNetworkSuggestion} for a detailed explanation of the parameters.
-     * See {@link WifiNetworkSuggestion#equals(Object)} for the equivalence evaluation used.
-     *
-     * @param networkSuggestions List of network suggestions to be removed. Pass an empty list
-     *                           to remove all the previous suggestions provided by the app.
-     * @return Status code for the operation. One of the STATUS_NETWORK_SUGGESTIONS_ values.
-     * Any matching suggestions are removed from the device and will not be considered for any
-     * further connection attempts.
-     */
-    @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE)
-    public @NetworkSuggestionsStatusCode int removeNetworkSuggestions(
-            @NonNull List<WifiNetworkSuggestion> networkSuggestions) {
-        try {
-            return mService.removeNetworkSuggestions(
-                    networkSuggestions, mContext.getOpPackageName());
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Get all network suggestions provided by the calling app.
-     * See {@link #addNetworkSuggestions(List)}
-     * See {@link #removeNetworkSuggestions(List)}
-     * @return a list of {@link WifiNetworkSuggestion}
-     */
-    @RequiresPermission(ACCESS_WIFI_STATE)
-    public @NonNull List<WifiNetworkSuggestion> getNetworkSuggestions() {
-        try {
-            return mService.getNetworkSuggestions(mContext.getOpPackageName());
-        } catch (RemoteException e) {
-            throw e.rethrowAsRuntimeException();
-        }
-    }
-
-    /**
-     * Returns the max number of network suggestions that are allowed per app on the device.
-     * @see #addNetworkSuggestions(List)
-     * @see #removeNetworkSuggestions(List)
-     */
-    public int getMaxNumberOfNetworkSuggestionsPerApp() {
-        return getMaxNumberOfNetworkSuggestionsPerApp(
-                mContext.getSystemService(ActivityManager.class).isLowRamDevice());
-    }
-
-    /** @hide */
-    public static int getMaxNumberOfNetworkSuggestionsPerApp(boolean isLowRamDevice) {
-        return isLowRamDevice
-                ? NETWORK_SUGGESTIONS_MAX_PER_APP_LOW_RAM
-                : NETWORK_SUGGESTIONS_MAX_PER_APP_HIGH_RAM;
-    }
-
-    /**
-     * Add or update a Passpoint configuration.  The configuration provides a credential
-     * for connecting to Passpoint networks that are operated by the Passpoint
-     * service provider specified in the configuration.
-     *
-     * Each configuration is uniquely identified by a unique key which depends on the contents of
-     * the configuration. This allows the caller to install multiple profiles with the same FQDN
-     * (Fully qualified domain name). Therefore, in order to update an existing profile, it is
-     * first required to remove it using {@link WifiManager#removePasspointConfiguration(String)}.
-     * Otherwise, a new profile will be added with both configuration.
-     *
-     * @param config The Passpoint configuration to be added
-     * @throws IllegalArgumentException if configuration is invalid or Passpoint is not enabled on
-     *                                  the device.
-     *
-     * Deprecated for general app usage - except DO/PO apps.
-     * See {@link WifiNetworkSuggestion.Builder#setPasspointConfig(PasspointConfiguration)} to
-     * create a passpoint suggestion.
-     * See {@link #addNetworkSuggestions(List)}, {@link #removeNetworkSuggestions(List)} for new
-     * API to add Wi-Fi networks for consideration when auto-connecting to wifi.
-     * <b>Compatibility Note:</b> For applications targeting
-     * {@link android.os.Build.VERSION_CODES#R} or above, this API will always fail and throw
-     * {@link IllegalArgumentException}.
-     * <p>
-     * Deprecation Exemptions:
-     * <ul>
-     * <li>Device Owner (DO), Profile Owner (PO) and system apps.
-     * </ul>
-     */
-    public void addOrUpdatePasspointConfiguration(PasspointConfiguration config) {
-        try {
-            if (!mService.addOrUpdatePasspointConfiguration(config, mContext.getOpPackageName())) {
-                throw new IllegalArgumentException();
-            }
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Remove the Passpoint configuration identified by its FQDN (Fully Qualified Domain Name) added
-     * by the caller.
-     *
-     * @param fqdn The FQDN of the Passpoint configuration added by the caller to be removed
-     * @throws IllegalArgumentException if no configuration is associated with the given FQDN or
-     *                                  Passpoint is not enabled on the device.
-     * @deprecated This will be non-functional in a future release.
-     */
-    @Deprecated
-    @RequiresPermission(anyOf = {
-            android.Manifest.permission.NETWORK_SETTINGS,
-            android.Manifest.permission.NETWORK_CARRIER_PROVISIONING
-    })
-    public void removePasspointConfiguration(String fqdn) {
-        try {
-            if (!mService.removePasspointConfiguration(fqdn, mContext.getOpPackageName())) {
-                throw new IllegalArgumentException();
-            }
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Return the list of installed Passpoint configurations added by the caller.
-     *
-     * An empty list will be returned when no configurations are installed.
-     *
-     * @return A list of {@link PasspointConfiguration} added by the caller
-     * @deprecated This will be non-functional in a future release.
-     */
-    @Deprecated
-    @RequiresPermission(anyOf = {
-            android.Manifest.permission.NETWORK_SETTINGS,
-            android.Manifest.permission.NETWORK_SETUP_WIZARD
-    })
-    public List<PasspointConfiguration> getPasspointConfigurations() {
-        try {
-            return mService.getPasspointConfigurations(mContext.getOpPackageName());
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Query for a Hotspot 2.0 release 2 OSU icon file. An {@link #ACTION_PASSPOINT_ICON} intent
-     * will be broadcasted once the request is completed.  The presence of the intent extra
-     * {@link #EXTRA_ICON} will indicate the result of the request.
-     * A missing intent extra {@link #EXTRA_ICON} will indicate a failure.
-     *
-     * @param bssid The BSSID of the AP
-     * @param fileName Name of the icon file (remote file) to query from the AP
-     *
-     * @throws UnsupportedOperationException if Passpoint is not enabled on the device.
-     * @hide
-     */
-    public void queryPasspointIcon(long bssid, String fileName) {
-        try {
-            mService.queryPasspointIcon(bssid, fileName);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Match the currently associated network against the SP matching the given FQDN
-     * @param fqdn FQDN of the SP
-     * @return ordinal [HomeProvider, RoamingProvider, Incomplete, None, Declined]
-     * @hide
-     */
-    public int matchProviderWithCurrentNetwork(String fqdn) {
-        try {
-            return mService.matchProviderWithCurrentNetwork(fqdn);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Deauthenticate and set the re-authentication hold off time for the current network
-     * @param holdoff hold off time in milliseconds
-     * @param ess set if the hold off pertains to an ESS rather than a BSS
-     * @hide
-     *
-     * TODO (140167680): This needs to be removed, the implementation is empty!
-     */
-    public void deauthenticateNetwork(long holdoff, boolean ess) {
-        try {
-            mService.deauthenticateNetwork(holdoff, ess);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Remove the specified network from the list of configured networks.
-     * This may result in the asynchronous delivery of state change
-     * events.
-     *
-     * Applications are not allowed to remove networks created by other
-     * applications.
-     *
-     * @param netId the ID of the network as returned by {@link #addNetwork} or {@link
-     *        #getConfiguredNetworks}.
-     * @return {@code true} if the operation succeeded
-     *
-     * @deprecated
-     * a) See {@link WifiNetworkSpecifier.Builder#build()} for new
-     * mechanism to trigger connection to a Wi-Fi network.
-     * b) See {@link #addNetworkSuggestions(List)},
-     * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration
-     * when auto-connecting to wifi.
-     * <b>Compatibility Note:</b> For applications targeting
-     * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always fail and return
-     * {@code false}.
-     * <p>
-     * Deprecation Exemptions:
-     * <ul>
-     * <li>Device Owner (DO), Profile Owner (PO) and system apps.
-     * </ul>
-     */
-    @Deprecated
-    public boolean removeNetwork(int netId) {
-        try {
-            return mService.removeNetwork(netId, mContext.getOpPackageName());
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Allow a previously configured network to be associated with. If
-     * <code>attemptConnect</code> is true, an attempt to connect to the selected
-     * network is initiated. This may result in the asynchronous delivery
-     * of state change events.
-     * <p>
-     * <b>Note:</b> Network communication may not use Wi-Fi even if Wi-Fi is connected;
-     * traffic may instead be sent through another network, such as cellular data,
-     * Bluetooth tethering, or Ethernet. For example, traffic will never use a
-     * Wi-Fi network that does not provide Internet access (e.g. a wireless
-     * printer), if another network that does offer Internet access (e.g.
-     * cellular data) is available. Applications that need to ensure that their
-     * network traffic uses Wi-Fi should use APIs such as
-     * {@link Network#bindSocket(java.net.Socket)},
-     * {@link Network#openConnection(java.net.URL)}, or
-     * {@link ConnectivityManager#bindProcessToNetwork} to do so.
-     *
-     * Applications are not allowed to enable networks created by other
-     * applications.
-     *
-     * @param netId the ID of the network as returned by {@link #addNetwork} or {@link
-     *        #getConfiguredNetworks}.
-     * @param attemptConnect The way to select a particular network to connect to is specify
-     *        {@code true} for this parameter.
-     * @return {@code true} if the operation succeeded
-     *
-     * @deprecated
-     * a) See {@link WifiNetworkSpecifier.Builder#build()} for new
-     * mechanism to trigger connection to a Wi-Fi network.
-     * b) See {@link #addNetworkSuggestions(List)},
-     * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration
-     * when auto-connecting to wifi.
-     * <b>Compatibility Note:</b> For applications targeting
-     * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always fail and return
-     * {@code false}.
-     * Deprecation Exemptions:
-     * <ul>
-     * <li>Device Owner (DO), Profile Owner (PO) and system apps.
-     * </ul>
-     */
-    @Deprecated
-    public boolean enableNetwork(int netId, boolean attemptConnect) {
-        try {
-            return mService.enableNetwork(netId, attemptConnect, mContext.getOpPackageName());
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Disable a configured network. The specified network will not be
-     * a candidate for associating. This may result in the asynchronous
-     * delivery of state change events.
-     *
-     * Applications are not allowed to disable networks created by other
-     * applications.
-     *
-     * @param netId the ID of the network as returned by {@link #addNetwork} or {@link
-     *        #getConfiguredNetworks}.
-     * @return {@code true} if the operation succeeded
-     *
-     * @deprecated
-     * a) See {@link WifiNetworkSpecifier.Builder#build()} for new
-     * mechanism to trigger connection to a Wi-Fi network.
-     * b) See {@link #addNetworkSuggestions(List)},
-     * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration
-     * when auto-connecting to wifi.
-     * <b>Compatibility Note:</b> For applications targeting
-     * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always fail and return
-     * {@code false}.
-     * <p>
-     * Deprecation Exemptions:
-     * <ul>
-     * <li>Device Owner (DO), Profile Owner (PO) and system apps.
-     * </ul>
-     */
-    @Deprecated
-    public boolean disableNetwork(int netId) {
-        try {
-            return mService.disableNetwork(netId, mContext.getOpPackageName());
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Disassociate from the currently active access point. This may result
-     * in the asynchronous delivery of state change events.
-     * @return {@code true} if the operation succeeded
-     *
-     * @deprecated
-     * a) See {@link WifiNetworkSpecifier.Builder#build()} for new
-     * mechanism to trigger connection to a Wi-Fi network.
-     * b) See {@link #addNetworkSuggestions(List)},
-     * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration
-     * when auto-connecting to wifi.
-     * <b>Compatibility Note:</b> For applications targeting
-     * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always fail and return
-     * {@code false}.
-     * <p>
-     * Deprecation Exemptions:
-     * <ul>
-     * <li>Device Owner (DO), Profile Owner (PO) and system apps.
-     * </ul>
-     */
-    @Deprecated
-    public boolean disconnect() {
-        try {
-            return mService.disconnect(mContext.getOpPackageName());
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Reconnect to the currently active access point, if we are currently
-     * disconnected. This may result in the asynchronous delivery of state
-     * change events.
-     * @return {@code true} if the operation succeeded
-     *
-     * @deprecated
-     * a) See {@link WifiNetworkSpecifier.Builder#build()} for new
-     * mechanism to trigger connection to a Wi-Fi network.
-     * b) See {@link #addNetworkSuggestions(List)},
-     * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration
-     * when auto-connecting to wifi.
-     * <b>Compatibility Note:</b> For applications targeting
-     * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always fail and return
-     * {@code false}.
-     * <p>
-     * Deprecation Exemptions:
-     * <ul>
-     * <li>Device Owner (DO), Profile Owner (PO) and system apps.
-     * </ul>
-     */
-    @Deprecated
-    public boolean reconnect() {
-        try {
-            return mService.reconnect(mContext.getOpPackageName());
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Reconnect to the currently active access point, even if we are already
-     * connected. This may result in the asynchronous delivery of state
-     * change events.
-     * @return {@code true} if the operation succeeded
-     *
-     * @deprecated
-     * a) See {@link WifiNetworkSpecifier.Builder#build()} for new
-     * mechanism to trigger connection to a Wi-Fi network.
-     * b) See {@link #addNetworkSuggestions(List)},
-     * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration
-     * when auto-connecting to wifi.
-     * <b>Compatibility Note:</b> For applications targeting
-     * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always return false.
-     */
-    @Deprecated
-    public boolean reassociate() {
-        try {
-            return mService.reassociate(mContext.getOpPackageName());
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Check that the supplicant daemon is responding to requests.
-     * @return {@code true} if we were able to communicate with the supplicant and
-     * it returned the expected response to the PING message.
-     * @deprecated Will return the output of {@link #isWifiEnabled()} instead.
-     */
-    @Deprecated
-    public boolean pingSupplicant() {
-        return isWifiEnabled();
-    }
-
-    /** @hide */
-    public static final long WIFI_FEATURE_INFRA            = 0x0001L;  // Basic infrastructure mode
-    /** @hide */
-    public static final long WIFI_FEATURE_PASSPOINT        = 0x0004L;  // Support for GAS/ANQP
-    /** @hide */
-    public static final long WIFI_FEATURE_P2P              = 0x0008L;  // Wifi-Direct
-    /** @hide */
-    public static final long WIFI_FEATURE_MOBILE_HOTSPOT   = 0x0010L;  // Soft AP
-    /** @hide */
-    public static final long WIFI_FEATURE_SCANNER          = 0x0020L;  // WifiScanner APIs
-    /** @hide */
-    public static final long WIFI_FEATURE_AWARE            = 0x0040L;  // Wi-Fi AWare networking
-    /** @hide */
-    public static final long WIFI_FEATURE_D2D_RTT          = 0x0080L;  // Device-to-device RTT
-    /** @hide */
-    public static final long WIFI_FEATURE_D2AP_RTT         = 0x0100L;  // Device-to-AP RTT
-    /** @hide */
-    public static final long WIFI_FEATURE_BATCH_SCAN       = 0x0200L;  // Batched Scan (deprecated)
-    /** @hide */
-    public static final long WIFI_FEATURE_PNO              = 0x0400L;  // Preferred network offload
-    /** @hide */
-    public static final long WIFI_FEATURE_ADDITIONAL_STA   = 0x0800L;  // Support for two STAs
-    /** @hide */
-    public static final long WIFI_FEATURE_TDLS             = 0x1000L;  // Tunnel directed link setup
-    /** @hide */
-    public static final long WIFI_FEATURE_TDLS_OFFCHANNEL  = 0x2000L;  // TDLS off channel
-    /** @hide */
-    public static final long WIFI_FEATURE_EPR              = 0x4000L;  // Enhanced power reporting
-    /** @hide */
-    public static final long WIFI_FEATURE_AP_STA           = 0x8000L;  // AP STA Concurrency
-    /** @hide */
-    public static final long WIFI_FEATURE_LINK_LAYER_STATS = 0x10000L; // Link layer stats
-    /** @hide */
-    public static final long WIFI_FEATURE_LOGGER           = 0x20000L; // WiFi Logger
-    /** @hide */
-    public static final long WIFI_FEATURE_HAL_EPNO         = 0x40000L; // Enhanced PNO
-    /** @hide */
-    public static final long WIFI_FEATURE_RSSI_MONITOR     = 0x80000L; // RSSI Monitor
-    /** @hide */
-    public static final long WIFI_FEATURE_MKEEP_ALIVE      = 0x100000L; // mkeep_alive
-    /** @hide */
-    public static final long WIFI_FEATURE_CONFIG_NDO       = 0x200000L; // ND offload
-    /** @hide */
-    public static final long WIFI_FEATURE_TRANSMIT_POWER   = 0x400000L; // Capture transmit power
-    /** @hide */
-    public static final long WIFI_FEATURE_CONTROL_ROAMING  = 0x800000L; // Control firmware roaming
-    /** @hide */
-    public static final long WIFI_FEATURE_IE_WHITELIST     = 0x1000000L; // Probe IE white listing
-    /** @hide */
-    public static final long WIFI_FEATURE_SCAN_RAND        = 0x2000000L; // Random MAC & Probe seq
-    /** @hide */
-    public static final long WIFI_FEATURE_TX_POWER_LIMIT   = 0x4000000L; // Set Tx power limit
-    /** @hide */
-    public static final long WIFI_FEATURE_WPA3_SAE         = 0x8000000L; // WPA3-Personal SAE
-    /** @hide */
-    public static final long WIFI_FEATURE_WPA3_SUITE_B     = 0x10000000L; // WPA3-Enterprise Suite-B
-    /** @hide */
-    public static final long WIFI_FEATURE_OWE              = 0x20000000L; // Enhanced Open
-    /** @hide */
-    public static final long WIFI_FEATURE_LOW_LATENCY      = 0x40000000L; // Low Latency modes
-    /** @hide */
-    public static final long WIFI_FEATURE_DPP              = 0x80000000L; // DPP (Easy-Connect)
-    /** @hide */
-    public static final long WIFI_FEATURE_P2P_RAND_MAC     = 0x100000000L; // Random P2P MAC
-    /** @hide */
-    public static final long WIFI_FEATURE_CONNECTED_RAND_MAC    = 0x200000000L; // Random STA MAC
-    /** @hide */
-    public static final long WIFI_FEATURE_AP_RAND_MAC      = 0x400000000L; // Random AP MAC
-    /** @hide */
-    public static final long WIFI_FEATURE_MBO              = 0x800000000L; // MBO Support
-    /** @hide */
-    public static final long WIFI_FEATURE_OCE              = 0x1000000000L; // OCE Support
-    /** @hide */
-    public static final long WIFI_FEATURE_WAPI             = 0x2000000000L; // WAPI
-
-    /** @hide */
-    public static final long WIFI_FEATURE_FILS_SHA256     = 0x4000000000L; // FILS-SHA256
-
-    /** @hide */
-    public static final long WIFI_FEATURE_FILS_SHA384     = 0x8000000000L; // FILS-SHA384
-
-    private long getSupportedFeatures() {
-        try {
-            return mService.getSupportedFeatures();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    private boolean isFeatureSupported(long feature) {
-        return (getSupportedFeatures() & feature) == feature;
-    }
-
-    /**
-     * @return true if this adapter supports Passpoint
-     * @hide
-     */
-    public boolean isPasspointSupported() {
-        return isFeatureSupported(WIFI_FEATURE_PASSPOINT);
-    }
-
-    /**
-     * @return true if this adapter supports WifiP2pManager (Wi-Fi Direct)
-     */
-    public boolean isP2pSupported() {
-        return isFeatureSupported(WIFI_FEATURE_P2P);
-    }
-
-    /**
-     * @return true if this adapter supports portable Wi-Fi hotspot
-     * @hide
-     */
-    @SystemApi
-    public boolean isPortableHotspotSupported() {
-        return isFeatureSupported(WIFI_FEATURE_MOBILE_HOTSPOT);
-    }
-
-    /**
-     * @return true if this adapter supports WifiScanner APIs
-     * @hide
-     */
-    @SystemApi
-    public boolean isWifiScannerSupported() {
-        return isFeatureSupported(WIFI_FEATURE_SCANNER);
-    }
-
-    /**
-     * @return true if this adapter supports Neighbour Awareness Network APIs
-     * @hide
-     */
-    public boolean isWifiAwareSupported() {
-        return isFeatureSupported(WIFI_FEATURE_AWARE);
-    }
-
-    /**
-     * Query whether the device supports Station (STA) + Access point (AP) concurrency or not.
-     *
-     * @return true if this device supports STA + AP concurrency, false otherwise.
-     */
-    public boolean isStaApConcurrencySupported() {
-        return isFeatureSupported(WIFI_FEATURE_AP_STA);
-    }
-
-    /**
-     * @deprecated Please use {@link android.content.pm.PackageManager#hasSystemFeature(String)}
-     * with {@link android.content.pm.PackageManager#FEATURE_WIFI_RTT} and
-     * {@link android.content.pm.PackageManager#FEATURE_WIFI_AWARE}.
-     *
-     * @return true if this adapter supports Device-to-device RTT
-     * @hide
-     */
-    @Deprecated
-    @SystemApi
-    public boolean isDeviceToDeviceRttSupported() {
-        return isFeatureSupported(WIFI_FEATURE_D2D_RTT);
-    }
-
-    /**
-     * @deprecated Please use {@link android.content.pm.PackageManager#hasSystemFeature(String)}
-     * with {@link android.content.pm.PackageManager#FEATURE_WIFI_RTT}.
-     *
-     * @return true if this adapter supports Device-to-AP RTT
-     */
-    @Deprecated
-    public boolean isDeviceToApRttSupported() {
-        return isFeatureSupported(WIFI_FEATURE_D2AP_RTT);
-    }
-
-    /**
-     * @return true if this adapter supports offloaded connectivity scan
-     */
-    public boolean isPreferredNetworkOffloadSupported() {
-        return isFeatureSupported(WIFI_FEATURE_PNO);
-    }
-
-    /**
-     * @return true if this adapter supports multiple simultaneous connections
-     * @hide
-     */
-    public boolean isAdditionalStaSupported() {
-        return isFeatureSupported(WIFI_FEATURE_ADDITIONAL_STA);
-    }
-
-    /**
-     * @return true if this adapter supports Tunnel Directed Link Setup
-     */
-    public boolean isTdlsSupported() {
-        return isFeatureSupported(WIFI_FEATURE_TDLS);
-    }
-
-    /**
-     * @return true if this adapter supports Off Channel Tunnel Directed Link Setup
-     * @hide
-     */
-    public boolean isOffChannelTdlsSupported() {
-        return isFeatureSupported(WIFI_FEATURE_TDLS_OFFCHANNEL);
-    }
-
-    /**
-     * @return true if this adapter supports advanced power/performance counters
-     */
-    public boolean isEnhancedPowerReportingSupported() {
-        return isFeatureSupported(WIFI_FEATURE_LINK_LAYER_STATS);
-    }
-
-    /**
-     * @return true if this device supports connected MAC randomization.
-     * @hide
-     */
-    @SystemApi
-    public boolean isConnectedMacRandomizationSupported() {
-        return isFeatureSupported(WIFI_FEATURE_CONNECTED_RAND_MAC);
-    }
-
-    /**
-     * @return true if this device supports connected MAC randomization.
-     * @hide
-     */
-    @SystemApi
-    public boolean isApMacRandomizationSupported() {
-        return isFeatureSupported(WIFI_FEATURE_AP_RAND_MAC);
-    }
-
-    /**
-     * Check if the chipset supports 5GHz band.
-     * @return {@code true} if supported, {@code false} otherwise.
-     */
-    public boolean is5GHzBandSupported() {
-        try {
-            return mService.is5GHzBandSupported();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Check if the chipset supports 6GHz band.
-     * @return {@code true} if supported, {@code false} otherwise.
-     */
-    public boolean is6GHzBandSupported() {
-        try {
-            return mService.is6GHzBandSupported();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Check if the chipset supports a certain Wi-Fi standard.
-     * @param standard the IEEE 802.11 standard to check on.
-     *        valid values from {@link ScanResult}'s {@code WIFI_STANDARD_}
-     * @return {@code true} if supported, {@code false} otherwise.
-     */
-    public boolean isWifiStandardSupported(@WifiAnnotations.WifiStandard int standard) {
-        try {
-            return mService.isWifiStandardSupported(standard);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Interface for Wi-Fi activity energy info listener. Should be implemented by applications and
-     * set when calling {@link WifiManager#getWifiActivityEnergyInfoAsync}.
-     *
-     * @hide
-     */
-    @SystemApi
-    public interface OnWifiActivityEnergyInfoListener {
-        /**
-         * Called when Wi-Fi activity energy info is available.
-         * Note: this listener is triggered at most once for each call to
-         * {@link #getWifiActivityEnergyInfoAsync}.
-         *
-         * @param info the latest {@link WifiActivityEnergyInfo}, or null if unavailable.
-         */
-        void onWifiActivityEnergyInfo(@Nullable WifiActivityEnergyInfo info);
-    }
-
-    private static class OnWifiActivityEnergyInfoProxy
-            extends IOnWifiActivityEnergyInfoListener.Stub {
-        private final Object mLock = new Object();
-        @Nullable @GuardedBy("mLock") private Executor mExecutor;
-        @Nullable @GuardedBy("mLock") private OnWifiActivityEnergyInfoListener mListener;
-
-        OnWifiActivityEnergyInfoProxy(Executor executor,
-                OnWifiActivityEnergyInfoListener listener) {
-            mExecutor = executor;
-            mListener = listener;
-        }
-
-        @Override
-        public void onWifiActivityEnergyInfo(WifiActivityEnergyInfo info) {
-            Executor executor;
-            OnWifiActivityEnergyInfoListener listener;
-            synchronized (mLock) {
-                if (mExecutor == null || mListener == null) {
-                    return;
-                }
-                executor = mExecutor;
-                listener = mListener;
-                // null out to allow garbage collection, prevent triggering listener more than once
-                mExecutor = null;
-                mListener = null;
-            }
-            Binder.clearCallingIdentity();
-            executor.execute(() -> listener.onWifiActivityEnergyInfo(info));
-        }
-    }
-
-    /**
-     * Request to get the current {@link WifiActivityEnergyInfo} asynchronously.
-     * Note: This method will return null if {@link #isEnhancedPowerReportingSupported()} returns
-     * false.
-     *
-     * @param executor the executor that the listener will be invoked on
-     * @param listener the listener that will receive the {@link WifiActivityEnergyInfo} object
-     *                 when it becomes available. The listener will be triggered at most once for
-     *                 each call to this method.
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(ACCESS_WIFI_STATE)
-    public void getWifiActivityEnergyInfoAsync(
-            @NonNull @CallbackExecutor Executor executor,
-            @NonNull OnWifiActivityEnergyInfoListener listener) {
-        Objects.requireNonNull(executor, "executor cannot be null");
-        Objects.requireNonNull(listener, "listener cannot be null");
-        try {
-            mService.getWifiActivityEnergyInfoAsync(
-                    new OnWifiActivityEnergyInfoProxy(executor, listener));
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Request a scan for access points. Returns immediately. The availability
-     * of the results is made known later by means of an asynchronous event sent
-     * on completion of the scan.
-     * <p>
-     * To initiate a Wi-Fi scan, declare the
-     * {@link android.Manifest.permission#CHANGE_WIFI_STATE}
-     * permission in the manifest, and perform these steps:
-     * </p>
-     * <ol style="1">
-     * <li>Invoke the following method:
-     * {@code ((WifiManager) getSystemService(WIFI_SERVICE)).startScan()}</li>
-     * <li>
-     * Register a BroadcastReceiver to listen to
-     * {@code SCAN_RESULTS_AVAILABLE_ACTION}.</li>
-     * <li>When a broadcast is received, call:
-     * {@code ((WifiManager) getSystemService(WIFI_SERVICE)).getScanResults()}</li>
-     * </ol>
-     * @return {@code true} if the operation succeeded, i.e., the scan was initiated.
-     * @deprecated The ability for apps to trigger scan requests will be removed in a future
-     * release.
-     */
-    @Deprecated
-    public boolean startScan() {
-        return startScan(null);
-    }
-
-    /** @hide */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS)
-    public boolean startScan(WorkSource workSource) {
-        try {
-            String packageName = mContext.getOpPackageName();
-            String attributionTag = mContext.getAttributionTag();
-            return mService.startScan(packageName, attributionTag);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * WPS has been deprecated from Client mode operation.
-     *
-     * @return null
-     * @hide
-     * @deprecated This API is deprecated
-     */
-    public String getCurrentNetworkWpsNfcConfigurationToken() {
-        return null;
-    }
-
-    /**
-     * Return dynamic information about the current Wi-Fi connection, if any is active.
-     * <p>
-     * In the connected state, access to the SSID and BSSID requires
-     * the same permissions as {@link #getScanResults}. If such access is not allowed,
-     * {@link WifiInfo#getSSID} will return {@link #UNKNOWN_SSID} and
-     * {@link WifiInfo#getBSSID} will return {@code "02:00:00:00:00:00"}.
-     * {@link WifiInfo#getPasspointFqdn()} will return null.
-     * {@link WifiInfo#getPasspointProviderFriendlyName()} will return null.
-     *
-     * @return the Wi-Fi information, contained in {@link WifiInfo}.
-     */
-    public WifiInfo getConnectionInfo() {
-        try {
-            return mService.getConnectionInfo(mContext.getOpPackageName(),
-                    mContext.getAttributionTag());
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Return the results of the latest access point scan.
-     * @return the list of access points found in the most recent scan. An app must hold
-     * {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission
-     * in order to get valid results.
-     */
-    public List<ScanResult> getScanResults() {
-        try {
-            return mService.getScanResults(mContext.getOpPackageName(),
-                    mContext.getAttributionTag());
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Get the filtered ScanResults which match the network configurations specified by the
-     * {@code networkSuggestionsToMatch}. Suggestions which use {@link WifiConfiguration} use
-     * SSID and the security type to match. Suggestions which use {@link PasspointConfigration}
-     * use the matching rules of Hotspot 2.0.
-     * @param networkSuggestionsToMatch The list of {@link WifiNetworkSuggestion} to match against.
-     * These may or may not be suggestions which are installed on the device.
-     * @param scanResults The scan results to be filtered. Optional - if not provided(empty list),
-     * the Wi-Fi service will use the most recent scan results which the system has.
-     * @return The map of {@link WifiNetworkSuggestion} to the list of {@link ScanResult}
-     * corresponding to networks which match them.
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(allOf = {ACCESS_FINE_LOCATION, ACCESS_WIFI_STATE})
-    @NonNull
-    public Map<WifiNetworkSuggestion, List<ScanResult>> getMatchingScanResults(
-            @NonNull List<WifiNetworkSuggestion> networkSuggestionsToMatch,
-            @Nullable List<ScanResult> scanResults) {
-        if (networkSuggestionsToMatch == null) {
-            throw new IllegalArgumentException("networkSuggestions must not be null.");
-        }
-        try {
-            return mService.getMatchingScanResults(
-                    networkSuggestionsToMatch, scanResults,
-                    mContext.getOpPackageName(), mContext.getAttributionTag());
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Set if scanning is always available.
-     *
-     * If set to {@code true}, apps can issue {@link #startScan} and fetch scan results
-     * even when Wi-Fi is turned off.
-     *
-     * @param isAvailable true to enable, false to disable.
-     * @hide
-     * @see #isScanAlwaysAvailable()
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public void setScanAlwaysAvailable(boolean isAvailable) {
-        try {
-            mService.setScanAlwaysAvailable(isAvailable);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Check if scanning is always available.
-     *
-     * If this return {@code true}, apps can issue {@link #startScan} and fetch scan results
-     * even when Wi-Fi is turned off.
-     *
-     * To change this setting, see {@link #ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE}.
-     * @deprecated The ability for apps to trigger scan requests will be removed in a future
-     * release.
-     */
-    @Deprecated
-    public boolean isScanAlwaysAvailable() {
-        try {
-            return mService.isScanAlwaysAvailable();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Tell the device to persist the current list of configured networks.
-     * <p>
-     * Note: It is possible for this method to change the network IDs of
-     * existing networks. You should assume the network IDs can be different
-     * after calling this method.
-     *
-     * @return {@code false}.
-     * @deprecated There is no need to call this method -
-     * {@link #addNetwork(WifiConfiguration)}, {@link #updateNetwork(WifiConfiguration)}
-     * and {@link #removeNetwork(int)} already persist the configurations automatically.
-     */
-    @Deprecated
-    public boolean saveConfiguration() {
-        return false;
-    }
-
-    /**
-     * Get the country code.
-     * @return the country code in ISO 3166 alpha-2 (2-letter) uppercase format, or null if
-     * there is no country code configured.
-     * @hide
-     */
-    @Nullable
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public String getCountryCode() {
-        try {
-            return mService.getCountryCode();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Return the DHCP-assigned addresses from the last successful DHCP request,
-     * if any.
-     * @return the DHCP information
-     */
-    public DhcpInfo getDhcpInfo() {
-        try {
-            return mService.getDhcpInfo();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Enable or disable Wi-Fi.
-     * <p>
-     * Applications must have the {@link android.Manifest.permission#CHANGE_WIFI_STATE}
-     * permission to toggle wifi.
-     *
-     * @param enabled {@code true} to enable, {@code false} to disable.
-     * @return {@code false} if the request cannot be satisfied; {@code true} indicates that wifi is
-     *         either already in the requested state, or in progress toward the requested state.
-     * @throws  {@link java.lang.SecurityException} if the caller is missing required permissions.
-     *
-     * @deprecated Starting with Build.VERSION_CODES#Q, applications are not allowed to
-     * enable/disable Wi-Fi.
-     * <b>Compatibility Note:</b> For applications targeting
-     * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always fail and return
-     * {@code false}. If apps are targeting an older SDK ({@link android.os.Build.VERSION_CODES#P}
-     * or below), they can continue to use this API.
-     * <p>
-     * Deprecation Exemptions:
-     * <ul>
-     * <li>Device Owner (DO), Profile Owner (PO) and system apps.
-     * </ul>
-     */
-    @Deprecated
-    public boolean setWifiEnabled(boolean enabled) {
-        try {
-            return mService.setWifiEnabled(mContext.getOpPackageName(), enabled);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Gets the Wi-Fi enabled state.
-     * @return One of {@link #WIFI_STATE_DISABLED},
-     *         {@link #WIFI_STATE_DISABLING}, {@link #WIFI_STATE_ENABLED},
-     *         {@link #WIFI_STATE_ENABLING}, {@link #WIFI_STATE_UNKNOWN}
-     * @see #isWifiEnabled()
-     */
-    public int getWifiState() {
-        try {
-            return mService.getWifiEnabledState();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Return whether Wi-Fi is enabled or disabled.
-     * @return {@code true} if Wi-Fi is enabled
-     * @see #getWifiState()
-     */
-    public boolean isWifiEnabled() {
-        return getWifiState() == WIFI_STATE_ENABLED;
-    }
-
-    /**
-     * Calculates the level of the signal. This should be used any time a signal
-     * is being shown.
-     *
-     * @param rssi The power of the signal measured in RSSI.
-     * @param numLevels The number of levels to consider in the calculated level.
-     * @return A level of the signal, given in the range of 0 to numLevels-1 (both inclusive).
-     * @deprecated Callers should use {@link #calculateSignalLevel(int)} instead to get the
-     * signal level using the system default RSSI thresholds, or otherwise compute the RSSI level
-     * themselves using their own formula.
-     */
-    @Deprecated
-    public static int calculateSignalLevel(int rssi, int numLevels) {
-        if (rssi <= MIN_RSSI) {
-            return 0;
-        } else if (rssi >= MAX_RSSI) {
-            return numLevels - 1;
-        } else {
-            float inputRange = (MAX_RSSI - MIN_RSSI);
-            float outputRange = (numLevels - 1);
-            return (int)((float)(rssi - MIN_RSSI) * outputRange / inputRange);
-        }
-    }
-
-    /**
-     * Given a raw RSSI, return the RSSI signal quality rating using the system default RSSI
-     * quality rating thresholds.
-     * @param rssi a raw RSSI value, in dBm, usually between -55 and -90
-     * @return the RSSI signal quality rating, in the range
-     * [0, {@link #getMaxSignalLevel()}], where 0 is the lowest (worst signal) RSSI
-     * rating and {@link #getMaxSignalLevel()} is the highest (best signal) RSSI rating.
-     */
-    @IntRange(from = 0)
-    public int calculateSignalLevel(int rssi) {
-        try {
-            return mService.calculateSignalLevel(rssi);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Get the system default maximum signal level.
-     * This is the maximum RSSI level returned by {@link #calculateSignalLevel(int)}.
-     */
-    @IntRange(from = 0)
-    public int getMaxSignalLevel() {
-        return calculateSignalLevel(Integer.MAX_VALUE);
-    }
-
-    /**
-     * Compares two signal strengths.
-     *
-     * @param rssiA The power of the first signal measured in RSSI.
-     * @param rssiB The power of the second signal measured in RSSI.
-     * @return Returns <0 if the first signal is weaker than the second signal,
-     *         0 if the two signals have the same strength, and >0 if the first
-     *         signal is stronger than the second signal.
-     */
-    public static int compareSignalLevel(int rssiA, int rssiB) {
-        return rssiA - rssiB;
-    }
-
-    /**
-     * Call allowing ConnectivityService to update WifiService with interface mode changes.
-     *
-     * @param ifaceName String name of the updated interface, or null to represent all interfaces
-     * @param mode int representing the new mode, one of:
-     *             {@link #IFACE_IP_MODE_TETHERED},
-     *             {@link #IFACE_IP_MODE_LOCAL_ONLY},
-     *             {@link #IFACE_IP_MODE_CONFIGURATION_ERROR},
-     *             {@link #IFACE_IP_MODE_UNSPECIFIED}
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(anyOf = {
-            android.Manifest.permission.NETWORK_STACK,
-            NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK
-    })
-    public void updateInterfaceIpState(@Nullable String ifaceName, @IfaceIpMode int mode) {
-        try {
-            mService.updateInterfaceIpState(ifaceName, mode);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Start Soft AP (hotspot) mode for tethering purposes with the specified configuration.
-     * Note that starting Soft AP mode may disable station mode operation if the device does not
-     * support concurrency.
-     * @param wifiConfig SSID, security and channel details as part of WifiConfiguration, or null to
-     *                   use the persisted Soft AP configuration that was previously set using
-     *                   {@link #setWifiApConfiguration(WifiConfiguration)}.
-     * @return {@code true} if the operation succeeded, {@code false} otherwise
-     *
-     * @hide
-     */
-    @RequiresPermission(anyOf = {
-            android.Manifest.permission.NETWORK_STACK,
-            NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK
-    })
-    public boolean startSoftAp(@Nullable WifiConfiguration wifiConfig) {
-        try {
-            return mService.startSoftAp(wifiConfig);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Start Soft AP (hotspot) mode for tethering purposes with the specified configuration.
-     * Note that starting Soft AP mode may disable station mode operation if the device does not
-     * support concurrency.
-     * @param softApConfig A valid SoftApConfiguration specifying the configuration of the SAP,
-     *                     or null to use the persisted Soft AP configuration that was previously
-     *                     set using {@link #setSoftApConfiguration(softApConfiguration)}.
-     * @return {@code true} if the operation succeeded, {@code false} otherwise
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(anyOf = {
-            android.Manifest.permission.NETWORK_STACK,
-            NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK
-    })
-    public boolean startTetheredHotspot(@Nullable SoftApConfiguration softApConfig) {
-        try {
-            return mService.startTetheredHotspot(softApConfig);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-
-    /**
-     * Stop SoftAp mode.
-     * Note that stopping softap mode will restore the previous wifi mode.
-     * @return {@code true} if the operation succeeds, {@code false} otherwise
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(anyOf = {
-            android.Manifest.permission.NETWORK_STACK,
-            NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK
-    })
-    public boolean stopSoftAp() {
-        try {
-            return mService.stopSoftAp();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Request a local only hotspot that an application can use to communicate between co-located
-     * devices connected to the created WiFi hotspot.  The network created by this method will not
-     * have Internet access.  Each application can make a single request for the hotspot, but
-     * multiple applications could be requesting the hotspot at the same time.  When multiple
-     * applications have successfully registered concurrently, they will be sharing the underlying
-     * hotspot. {@link LocalOnlyHotspotCallback#onStarted(LocalOnlyHotspotReservation)} is called
-     * when the hotspot is ready for use by the application.
-     * <p>
-     * Each application can make a single active call to this method. The {@link
-     * LocalOnlyHotspotCallback#onStarted(LocalOnlyHotspotReservation)} callback supplies the
-     * requestor with a {@link LocalOnlyHotspotReservation} that contains a
-     * {@link SoftApConfiguration} with the SSID, security type and credentials needed to connect
-     * to the hotspot.  Communicating this information is up to the application.
-     * <p>
-     * If the LocalOnlyHotspot cannot be created, the {@link LocalOnlyHotspotCallback#onFailed(int)}
-     * method will be called. Example failures include errors bringing up the network or if
-     * there is an incompatible operating mode.  For example, if the user is currently using Wifi
-     * Tethering to provide an upstream to another device, LocalOnlyHotspot will not start due to
-     * an incompatible mode. The possible error codes include:
-     * {@link LocalOnlyHotspotCallback#ERROR_NO_CHANNEL},
-     * {@link LocalOnlyHotspotCallback#ERROR_GENERIC},
-     * {@link LocalOnlyHotspotCallback#ERROR_INCOMPATIBLE_MODE} and
-     * {@link LocalOnlyHotspotCallback#ERROR_TETHERING_DISALLOWED}.
-     * <p>
-     * Internally, requests will be tracked to prevent the hotspot from being torn down while apps
-     * are still using it.  The {@link LocalOnlyHotspotReservation} object passed in the  {@link
-     * LocalOnlyHotspotCallback#onStarted(LocalOnlyHotspotReservation)} call should be closed when
-     * the LocalOnlyHotspot is no longer needed using {@link LocalOnlyHotspotReservation#close()}.
-     * Since the hotspot may be shared among multiple applications, removing the final registered
-     * application request will trigger the hotspot teardown.  This means that applications should
-     * not listen to broadcasts containing wifi state to determine if the hotspot was stopped after
-     * they are done using it. Additionally, once {@link LocalOnlyHotspotReservation#close()} is
-     * called, applications will not receive callbacks of any kind.
-     * <p>
-     * Applications should be aware that the user may also stop the LocalOnlyHotspot through the
-     * Settings UI; it is not guaranteed to stay up as long as there is a requesting application.
-     * The requestors will be notified of this case via
-     * {@link LocalOnlyHotspotCallback#onStopped()}.  Other cases may arise where the hotspot is
-     * torn down (Emergency mode, etc).  Application developers should be aware that it can stop
-     * unexpectedly, but they will receive a notification if they have properly registered.
-     * <p>
-     * Applications should also be aware that this network will be shared with other applications.
-     * Applications are responsible for protecting their data on this network (e.g., TLS).
-     * <p>
-     * Applications need to have the following permissions to start LocalOnlyHotspot: {@link
-     * android.Manifest.permission#CHANGE_WIFI_STATE} and {@link
-     * android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION}.  Callers without
-     * the permissions will trigger a {@link java.lang.SecurityException}.
-     * <p>
-     * @param callback LocalOnlyHotspotCallback for the application to receive updates about
-     * operating status.
-     * @param handler Handler to be used for callbacks.  If the caller passes a null Handler, the
-     * main thread will be used.
-     */
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.CHANGE_WIFI_STATE,
-            android.Manifest.permission.ACCESS_FINE_LOCATION})
-    public void startLocalOnlyHotspot(LocalOnlyHotspotCallback callback,
-            @Nullable Handler handler) {
-        Executor executor = handler == null ? null : new HandlerExecutor(handler);
-        startLocalOnlyHotspotInternal(null, executor, callback);
-    }
-
-    /**
-     * Starts a local-only hotspot with a specific configuration applied. See
-     * {@link #startLocalOnlyHotspot(LocalOnlyHotspotCallback, Handler)}.
-     *
-     * Applications need either {@link android.Manifest.permission#NETWORK_SETUP_WIZARD} or
-     * {@link android.Manifest.permission#NETWORK_SETTINGS} to call this method.
-     *
-     * Since custom configuration settings may be incompatible with each other, the hotspot started
-     * through this method cannot coexist with another hotspot created through
-     * startLocalOnlyHotspot. If this is attempted, the first hotspot request wins and others
-     * receive {@link LocalOnlyHotspotCallback#ERROR_GENERIC} through
-     * {@link LocalOnlyHotspotCallback#onFailed}.
-     *
-     * @param config Custom configuration for the hotspot. See {@link SoftApConfiguration}.
-     * @param executor Executor to run callback methods on, or null to use the main thread.
-     * @param callback Callback object for updates about hotspot status, or null for no updates.
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(anyOf = {
-            android.Manifest.permission.NETWORK_SETTINGS,
-            android.Manifest.permission.NETWORK_SETUP_WIZARD})
-    public void startLocalOnlyHotspot(@NonNull SoftApConfiguration config,
-            @Nullable Executor executor,
-            @Nullable LocalOnlyHotspotCallback callback) {
-        Objects.requireNonNull(config);
-        startLocalOnlyHotspotInternal(config, executor, callback);
-    }
-
-    /**
-     * Common implementation of both configurable and non-configurable LOHS.
-     *
-     * @param config App-specified configuration, or null. When present, additional privileges are
-     *               required, and the hotspot cannot be shared with other clients.
-     * @param executor Executor to run callback methods on, or null to use the main thread.
-     * @param callback Callback object for updates about hotspot status, or null for no updates.
-     */
-    private void startLocalOnlyHotspotInternal(
-            @Nullable SoftApConfiguration config,
-            @Nullable Executor executor,
-            @Nullable LocalOnlyHotspotCallback callback) {
-        if (executor == null) {
-            executor = mContext.getMainExecutor();
-        }
-        synchronized (mLock) {
-            LocalOnlyHotspotCallbackProxy proxy =
-                    new LocalOnlyHotspotCallbackProxy(this, executor, callback);
-            try {
-                String packageName = mContext.getOpPackageName();
-                String featureId = mContext.getAttributionTag();
-                int returnCode = mService.startLocalOnlyHotspot(proxy, packageName, featureId,
-                        config);
-                if (returnCode != LocalOnlyHotspotCallback.REQUEST_REGISTERED) {
-                    // Send message to the proxy to make sure we call back on the correct thread
-                    proxy.onHotspotFailed(returnCode);
-                    return;
-                }
-                mLOHSCallbackProxy = proxy;
-            } catch (RemoteException e) {
-                throw e.rethrowFromSystemServer();
-            }
-        }
-    }
-
-    /**
-     * Cancels a pending local only hotspot request.  This can be used by the calling application to
-     * cancel the existing request if the provided callback has not been triggered.  Calling this
-     * method will be equivalent to closing the returned LocalOnlyHotspotReservation, but it is not
-     * explicitly required.
-     * <p>
-     * When cancelling this request, application developers should be aware that there may still be
-     * outstanding local only hotspot requests and the hotspot may still start, or continue running.
-     * Additionally, if a callback was registered, it will no longer be triggered after calling
-     * cancel.
-     *
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public void cancelLocalOnlyHotspotRequest() {
-        synchronized (mLock) {
-            stopLocalOnlyHotspot();
-        }
-    }
-
-    /**
-     *  Method used to inform WifiService that the LocalOnlyHotspot is no longer needed.  This
-     *  method is used by WifiManager to release LocalOnlyHotspotReservations held by calling
-     *  applications and removes the internal tracking for the hotspot request.  When all requesting
-     *  applications are finished using the hotspot, it will be stopped and WiFi will return to the
-     *  previous operational mode.
-     *
-     *  This method should not be called by applications.  Instead, they should call the close()
-     *  method on their LocalOnlyHotspotReservation.
-     */
-    private void stopLocalOnlyHotspot() {
-        synchronized (mLock) {
-            if (mLOHSCallbackProxy == null) {
-                // nothing to do, the callback was already cleaned up.
-                return;
-            }
-            mLOHSCallbackProxy = null;
-            try {
-                mService.stopLocalOnlyHotspot();
-            } catch (RemoteException e) {
-                throw e.rethrowFromSystemServer();
-            }
-        }
-    }
-
-    /**
-     * Allow callers (Settings UI) to watch LocalOnlyHotspot state changes.  Callers will
-     * receive a {@link LocalOnlyHotspotSubscription} object as a parameter of the
-     * {@link LocalOnlyHotspotObserver#onRegistered(LocalOnlyHotspotSubscription)}. The registered
-     * callers will receive the {@link LocalOnlyHotspotObserver#onStarted(SoftApConfiguration)} and
-     * {@link LocalOnlyHotspotObserver#onStopped()} callbacks.
-     * <p>
-     * Applications should have the
-     * {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION}
-     * permission.  Callers without the permission will trigger a
-     * {@link java.lang.SecurityException}.
-     * <p>
-     * @param observer LocalOnlyHotspotObserver callback.
-     * @param handler Handler to use for callbacks
-     *
-     * @hide
-     */
-    public void watchLocalOnlyHotspot(LocalOnlyHotspotObserver observer,
-            @Nullable Handler handler) {
-        Executor executor = handler == null ? mContext.getMainExecutor()
-                : new HandlerExecutor(handler);
-        synchronized (mLock) {
-            mLOHSObserverProxy =
-                    new LocalOnlyHotspotObserverProxy(this, executor, observer);
-            try {
-                mService.startWatchLocalOnlyHotspot(mLOHSObserverProxy);
-                mLOHSObserverProxy.registered();
-            } catch (RemoteException e) {
-                mLOHSObserverProxy = null;
-                throw e.rethrowFromSystemServer();
-            }
-        }
-    }
-
-    /**
-     * Allow callers to stop watching LocalOnlyHotspot state changes.  After calling this method,
-     * applications will no longer receive callbacks.
-     *
-     * @hide
-     */
-    public void unregisterLocalOnlyHotspotObserver() {
-        synchronized (mLock) {
-            if (mLOHSObserverProxy == null) {
-                // nothing to do, the callback was already cleaned up
-                return;
-            }
-            mLOHSObserverProxy = null;
-            try {
-                mService.stopWatchLocalOnlyHotspot();
-            } catch (RemoteException e) {
-                throw e.rethrowFromSystemServer();
-            }
-        }
-    }
-
-    /**
-     * Gets the tethered Wi-Fi hotspot enabled state.
-     * @return One of {@link #WIFI_AP_STATE_DISABLED},
-     *         {@link #WIFI_AP_STATE_DISABLING}, {@link #WIFI_AP_STATE_ENABLED},
-     *         {@link #WIFI_AP_STATE_ENABLING}, {@link #WIFI_AP_STATE_FAILED}
-     * @see #isWifiApEnabled()
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE)
-    public int getWifiApState() {
-        try {
-            return mService.getWifiApEnabledState();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Return whether tethered Wi-Fi AP is enabled or disabled.
-     * @return {@code true} if tethered  Wi-Fi AP is enabled
-     * @see #getWifiApState()
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE)
-    public boolean isWifiApEnabled() {
-        return getWifiApState() == WIFI_AP_STATE_ENABLED;
-    }
-
-    /**
-     * Gets the tethered Wi-Fi AP Configuration.
-     * @return AP details in WifiConfiguration
-     *
-     * Note that AP detail may contain configuration which is cannot be represented
-     * by the legacy WifiConfiguration, in such cases a null will be returned.
-     *
-     * @deprecated This API is deprecated. Use {@link #getSoftApConfiguration()} instead.
-     * @hide
-     */
-    @Nullable
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE)
-    @Deprecated
-    public WifiConfiguration getWifiApConfiguration() {
-        try {
-            return mService.getWifiApConfiguration();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Gets the Wi-Fi tethered AP Configuration.
-     * @return AP details in {@link SoftApConfiguration}
-     *
-     * @hide
-     */
-    @NonNull
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public SoftApConfiguration getSoftApConfiguration() {
-        try {
-            return mService.getSoftApConfiguration();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Sets the tethered Wi-Fi AP Configuration.
-     * @return {@code true} if the operation succeeded, {@code false} otherwise
-     *
-     * @deprecated This API is deprecated. Use {@link #setSoftApConfiguration(SoftApConfiguration)}
-     * instead.
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE)
-    @Deprecated
-    public boolean setWifiApConfiguration(WifiConfiguration wifiConfig) {
-        try {
-            return mService.setWifiApConfiguration(wifiConfig, mContext.getOpPackageName());
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Sets the tethered Wi-Fi AP Configuration.
-     *
-     * If the API is called while the tethered soft AP is enabled, the configuration will apply to
-     * the current soft AP if the new configuration only includes
-     * {@link SoftApConfiguration.Builder#setMaxNumberOfClients(int)}
-     * or {@link SoftApConfiguration.Builder#setShutdownTimeoutMillis(long)}
-     * or {@link SoftApConfiguration.Builder#setClientControlByUserEnabled(boolean)}
-     * or {@link SoftApConfiguration.Builder#setBlockedClientList(List)}
-     * or {@link SoftApConfiguration.Builder#setAllowedClientList(List)}
-     *
-     * Otherwise, the configuration changes will be applied when the Soft AP is next started
-     * (the framework will not stop/start the AP).
-     *
-     * @param softApConfig  A valid SoftApConfiguration specifying the configuration of the SAP.
-     * @return {@code true} if the operation succeeded, {@code false} otherwise
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public boolean setSoftApConfiguration(@NonNull SoftApConfiguration softApConfig) {
-        try {
-            return mService.setSoftApConfiguration(
-                    softApConfig, mContext.getOpPackageName());
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Enable/Disable TDLS on a specific local route.
-     *
-     * <p>
-     * TDLS enables two wireless endpoints to talk to each other directly
-     * without going through the access point that is managing the local
-     * network. It saves bandwidth and improves quality of the link.
-     * </p>
-     * <p>
-     * This API enables/disables the option of using TDLS. If enabled, the
-     * underlying hardware is free to use TDLS or a hop through the access
-     * point. If disabled, existing TDLS session is torn down and
-     * hardware is restricted to use access point for transferring wireless
-     * packets. Default value for all routes is 'disabled', meaning restricted
-     * to use access point for transferring packets.
-     * </p>
-     *
-     * @param remoteIPAddress IP address of the endpoint to setup TDLS with
-     * @param enable true = setup and false = tear down TDLS
-     */
-    public void setTdlsEnabled(InetAddress remoteIPAddress, boolean enable) {
-        try {
-            mService.enableTdls(remoteIPAddress.getHostAddress(), enable);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Similar to {@link #setTdlsEnabled(InetAddress, boolean) }, except
-     * this version allows you to specify remote endpoint with a MAC address.
-     * @param remoteMacAddress MAC address of the remote endpoint such as 00:00:0c:9f:f2:ab
-     * @param enable true = setup and false = tear down TDLS
-     */
-    public void setTdlsEnabledWithMacAddress(String remoteMacAddress, boolean enable) {
-        try {
-            mService.enableTdlsWithMacAddress(remoteMacAddress, enable);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Passed with {@link ActionListener#onFailure}.
-     * Indicates that the operation failed due to an internal error.
-     * @hide
-     */
-    public static final int ERROR                       = 0;
-
-    /**
-     * Passed with {@link ActionListener#onFailure}.
-     * Indicates that the operation is already in progress
-     * @hide
-     */
-    public static final int IN_PROGRESS                 = 1;
-
-    /**
-     * Passed with {@link ActionListener#onFailure}.
-     * Indicates that the operation failed because the framework is busy and
-     * unable to service the request
-     * @hide
-     */
-    public static final int BUSY                        = 2;
-
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({ERROR, IN_PROGRESS, BUSY})
-    public @interface ActionListenerFailureReason {}
-
-    /* WPS specific errors */
-    /** WPS overlap detected
-     * @deprecated This is deprecated
-     */
-    public static final int WPS_OVERLAP_ERROR           = 3;
-    /** WEP on WPS is prohibited
-     * @deprecated This is deprecated
-     */
-    public static final int WPS_WEP_PROHIBITED          = 4;
-    /** TKIP only prohibited
-     * @deprecated This is deprecated
-     */
-    public static final int WPS_TKIP_ONLY_PROHIBITED    = 5;
-    /** Authentication failure on WPS
-     * @deprecated This is deprecated
-     */
-    public static final int WPS_AUTH_FAILURE            = 6;
-    /** WPS timed out
-     * @deprecated This is deprecated
-     */
-    public static final int WPS_TIMED_OUT               = 7;
-
-    /**
-     * Passed with {@link ActionListener#onFailure}.
-     * Indicates that the operation failed due to invalid inputs
-     * @hide
-     */
-    public static final int INVALID_ARGS                = 8;
-
-    /**
-     * Passed with {@link ActionListener#onFailure}.
-     * Indicates that the operation failed due to user permissions.
-     * @hide
-     */
-    public static final int NOT_AUTHORIZED              = 9;
-
-    /**
-     * Interface for callback invocation on an application action
-     * @hide
-     */
-    @SystemApi
-    public interface ActionListener {
-        /**
-         * The operation succeeded.
-         */
-        void onSuccess();
-        /**
-         * The operation failed.
-         * @param reason The reason for failure depends on the operation.
-         */
-        void onFailure(@ActionListenerFailureReason int reason);
-    }
-
-    /** Interface for callback invocation on a start WPS action
-     * @deprecated This is deprecated
-     */
-    public static abstract class WpsCallback {
-
-        /** WPS start succeeded
-         * @deprecated This API is deprecated
-         */
-        public abstract void onStarted(String pin);
-
-        /** WPS operation completed successfully
-         * @deprecated This API is deprecated
-         */
-        public abstract void onSucceeded();
-
-        /**
-         * WPS operation failed
-         * @param reason The reason for failure could be one of
-         * {@link #WPS_TKIP_ONLY_PROHIBITED}, {@link #WPS_OVERLAP_ERROR},
-         * {@link #WPS_WEP_PROHIBITED}, {@link #WPS_TIMED_OUT} or {@link #WPS_AUTH_FAILURE}
-         * and some generic errors.
-         * @deprecated This API is deprecated
-         */
-        public abstract void onFailed(int reason);
-    }
-
-    /**
-     * Base class for soft AP callback. Should be extended by applications and set when calling
-     * {@link WifiManager#registerSoftApCallback(Executor, SoftApCallback)}.
-     *
-     * @hide
-     */
-    @SystemApi
-    public interface SoftApCallback {
-        /**
-         * Called when soft AP state changes.
-         *
-         * @param state         the new AP state. One of {@link #WIFI_AP_STATE_DISABLED},
-         *                      {@link #WIFI_AP_STATE_DISABLING}, {@link #WIFI_AP_STATE_ENABLED},
-         *                      {@link #WIFI_AP_STATE_ENABLING}, {@link #WIFI_AP_STATE_FAILED}
-         * @param failureReason reason when in failed state. One of
-         *                      {@link #SAP_START_FAILURE_GENERAL},
-         *                      {@link #SAP_START_FAILURE_NO_CHANNEL},
-         *                      {@link #SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION}
-         */
-        default void onStateChanged(@WifiApState int state, @SapStartFailure int failureReason) {}
-
-        /**
-         * Called when the connected clients to soft AP changes.
-         *
-         * @param clients the currently connected clients
-         */
-        default void onConnectedClientsChanged(@NonNull List<WifiClient> clients) {}
-
-        /**
-         * Called when information of softap changes.
-         *
-         * @param softApInfo is the softap information. {@link SoftApInfo}
-         */
-        default void onInfoChanged(@NonNull SoftApInfo softApInfo) {
-            // Do nothing: can be updated to add SoftApInfo details (e.g. channel) to the UI.
-        }
-
-        /**
-         * Called when capability of softap changes.
-         *
-         * @param softApCapability is the softap capability. {@link SoftApCapability}
-         */
-        default void onCapabilityChanged(@NonNull SoftApCapability softApCapability) {
-            // Do nothing: can be updated to add SoftApCapability details (e.g. meximum supported
-            // client number) to the UI.
-        }
-
-        /**
-         * Called when client trying to connect but device blocked the client with specific reason.
-         *
-         * Can be used to ask user to update client to allowed list or blocked list
-         * when reason is {@link SAP_CLIENT_BLOCK_REASON_CODE_BLOCKED_BY_USER}, or
-         * indicate the block due to maximum supported client number limitation when reason is
-         * {@link SAP_CLIENT_BLOCK_REASON_CODE_NO_MORE_STAS}.
-         *
-         * @param client the currently blocked client.
-         * @param blockedReason one of blocked reason from {@link SapClientBlockedReason}
-         */
-        default void onBlockedClientConnecting(@NonNull WifiClient client,
-                @SapClientBlockedReason int blockedReason) {
-            // Do nothing: can be used to ask user to update client to allowed list or blocked list.
-        }
-    }
-
-    /**
-     * Callback proxy for SoftApCallback objects.
-     *
-     * @hide
-     */
-    private class SoftApCallbackProxy extends ISoftApCallback.Stub {
-        private final Executor mExecutor;
-        private final SoftApCallback mCallback;
-
-        SoftApCallbackProxy(Executor executor, SoftApCallback callback) {
-            mExecutor = executor;
-            mCallback = callback;
-        }
-
-        @Override
-        public void onStateChanged(int state, int failureReason) {
-            if (mVerboseLoggingEnabled) {
-                Log.v(TAG, "SoftApCallbackProxy: onStateChanged: state=" + state
-                        + ", failureReason=" + failureReason);
-            }
-
-            Binder.clearCallingIdentity();
-            mExecutor.execute(() -> {
-                mCallback.onStateChanged(state, failureReason);
-            });
-        }
-
-        @Override
-        public void onConnectedClientsChanged(List<WifiClient> clients) {
-            if (mVerboseLoggingEnabled) {
-                Log.v(TAG, "SoftApCallbackProxy: onConnectedClientsChanged: clients="
-                        + clients.size() + " clients");
-            }
-
-            Binder.clearCallingIdentity();
-            mExecutor.execute(() -> {
-                mCallback.onConnectedClientsChanged(clients);
-            });
-        }
-
-        @Override
-        public void onInfoChanged(SoftApInfo softApInfo) {
-            if (mVerboseLoggingEnabled) {
-                Log.v(TAG, "SoftApCallbackProxy: onInfoChange: softApInfo=" + softApInfo);
-            }
-
-            Binder.clearCallingIdentity();
-            mExecutor.execute(() -> {
-                mCallback.onInfoChanged(softApInfo);
-            });
-        }
-
-        @Override
-        public void onCapabilityChanged(SoftApCapability capability) {
-            if (mVerboseLoggingEnabled) {
-                Log.v(TAG, "SoftApCallbackProxy: onCapabilityChanged: SoftApCapability="
-                        + capability);
-            }
-
-            Binder.clearCallingIdentity();
-            mExecutor.execute(() -> {
-                mCallback.onCapabilityChanged(capability);
-            });
-        }
-
-        @Override
-        public void onBlockedClientConnecting(@NonNull WifiClient client, int blockedReason) {
-            if (mVerboseLoggingEnabled) {
-                Log.v(TAG, "SoftApCallbackProxy: onBlockedClientConnecting: client=" + client
-                        + " with reason = " + blockedReason);
-            }
-
-            Binder.clearCallingIdentity();
-            mExecutor.execute(() -> {
-                mCallback.onBlockedClientConnecting(client, blockedReason);
-            });
-        }
-    }
-
-    /**
-     * Registers a callback for Soft AP. See {@link SoftApCallback}. Caller will receive the
-     * following callbacks on registration:
-     * <ul>
-     * <li> {@link SoftApCallback#onStateChanged(int, int)}</li>
-     * <li> {@link SoftApCallback#onConnectedClientsChanged(List<WifiClient>)}</li>
-     * <li> {@link SoftApCallback#onInfoChanged(SoftApInfo)}</li>
-     * <li> {@link SoftApCallback#onCapabilityChanged(SoftApCapability)}</li>
-     * </ul>
-     * These will be dispatched on registration to provide the caller with the current state
-     * (and are not an indication of any current change). Note that receiving an immediate
-     * WIFI_AP_STATE_FAILED value for soft AP state indicates that the latest attempt to start
-     * soft AP has failed. Caller can unregister a previously registered callback using
-     * {@link #unregisterSoftApCallback}
-     * <p>
-     * Applications should have the
-     * {@link android.Manifest.permission#NETWORK_SETTINGS NETWORK_SETTINGS} permission. Callers
-     * without the permission will trigger a {@link java.lang.SecurityException}.
-     * <p>
-     *
-     * @param executor The Executor on whose thread to execute the callbacks of the {@code callback}
-     *                 object.
-     * @param callback Callback for soft AP events
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public void registerSoftApCallback(@NonNull @CallbackExecutor Executor executor,
-            @NonNull SoftApCallback callback) {
-        if (executor == null) throw new IllegalArgumentException("executor cannot be null");
-        if (callback == null) throw new IllegalArgumentException("callback cannot be null");
-        Log.v(TAG, "registerSoftApCallback: callback=" + callback + ", executor=" + executor);
-
-        Binder binder = new Binder();
-        try {
-            mService.registerSoftApCallback(
-                    binder, new SoftApCallbackProxy(executor, callback), callback.hashCode());
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Allow callers to unregister a previously registered callback. After calling this method,
-     * applications will no longer receive soft AP events.
-     *
-     * @param callback Callback to unregister for soft AP events
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public void unregisterSoftApCallback(@NonNull SoftApCallback callback) {
-        if (callback == null) throw new IllegalArgumentException("callback cannot be null");
-        Log.v(TAG, "unregisterSoftApCallback: callback=" + callback);
-
-        try {
-            mService.unregisterSoftApCallback(callback.hashCode());
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * LocalOnlyHotspotReservation that contains the {@link SoftApConfiguration} for the active
-     * LocalOnlyHotspot request.
-     * <p>
-     * Applications requesting LocalOnlyHotspot for sharing will receive an instance of the
-     * LocalOnlyHotspotReservation in the
-     * {@link LocalOnlyHotspotCallback#onStarted(LocalOnlyHotspotReservation)} call.  This
-     * reservation contains the relevant {@link SoftApConfiguration}.
-     * When an application is done with the LocalOnlyHotspot, they should call {@link
-     * LocalOnlyHotspotReservation#close()}.  Once this happens, the application will not receive
-     * any further callbacks. If the LocalOnlyHotspot is stopped due to a
-     * user triggered mode change, applications will be notified via the {@link
-     * LocalOnlyHotspotCallback#onStopped()} callback.
-     */
-    public class LocalOnlyHotspotReservation implements AutoCloseable {
-
-        private final CloseGuard mCloseGuard = new CloseGuard();
-        private final SoftApConfiguration mSoftApConfig;
-        private final WifiConfiguration mWifiConfig;
-        private boolean mClosed = false;
-
-        /** @hide */
-        @VisibleForTesting
-        public LocalOnlyHotspotReservation(SoftApConfiguration config) {
-            mSoftApConfig = config;
-            mWifiConfig = config.toWifiConfiguration();
-            mCloseGuard.open("close");
-        }
-
-        /**
-         * Returns the {@link WifiConfiguration} of the current Local Only Hotspot (LOHS).
-         * May be null if hotspot enabled and security type is not
-         * {@code WifiConfiguration.KeyMgmt.None} or {@code WifiConfiguration.KeyMgmt.WPA2_PSK}.
-         *
-         * @deprecated Use {@code WifiManager#getSoftApConfiguration()} to get the
-         * LOHS configuration.
-         */
-        @Deprecated
-        @Nullable
-        public WifiConfiguration getWifiConfiguration() {
-            return mWifiConfig;
-        }
-
-        /**
-         * Returns the {@link SoftApConfiguration} of the current Local Only Hotspot (LOHS).
-         */
-        @NonNull
-        public SoftApConfiguration getSoftApConfiguration() {
-            return mSoftApConfig;
-        }
-
-        @Override
-        public void close() {
-            try {
-                synchronized (mLock) {
-                    if (!mClosed) {
-                        mClosed = true;
-                        stopLocalOnlyHotspot();
-                        mCloseGuard.close();
-                    }
-                }
-            } catch (Exception e) {
-                Log.e(TAG, "Failed to stop Local Only Hotspot.");
-            } finally {
-                Reference.reachabilityFence(this);
-            }
-        }
-
-        @Override
-        protected void finalize() throws Throwable {
-            try {
-                if (mCloseGuard != null) {
-                    mCloseGuard.warnIfOpen();
-                }
-                close();
-            } finally {
-                super.finalize();
-            }
-        }
-    }
-
-    /**
-     * Callback class for applications to receive updates about the LocalOnlyHotspot status.
-     */
-    public static class LocalOnlyHotspotCallback {
-        /** @hide */
-        public static final int REQUEST_REGISTERED = 0;
-
-        public static final int ERROR_NO_CHANNEL = 1;
-        public static final int ERROR_GENERIC = 2;
-        public static final int ERROR_INCOMPATIBLE_MODE = 3;
-        public static final int ERROR_TETHERING_DISALLOWED = 4;
-
-        /** LocalOnlyHotspot start succeeded. */
-        public void onStarted(LocalOnlyHotspotReservation reservation) {};
-
-        /**
-         * LocalOnlyHotspot stopped.
-         * <p>
-         * The LocalOnlyHotspot can be disabled at any time by the user.  When this happens,
-         * applications will be notified that it was stopped. This will not be invoked when an
-         * application calls {@link LocalOnlyHotspotReservation#close()}.
-         */
-        public void onStopped() {};
-
-        /**
-         * LocalOnlyHotspot failed to start.
-         * <p>
-         * Applications can attempt to call
-         * {@link WifiManager#startLocalOnlyHotspot(LocalOnlyHotspotCallback, Handler)} again at
-         * a later time.
-         * <p>
-         * @param reason The reason for failure could be one of: {@link
-         * #ERROR_TETHERING_DISALLOWED}, {@link #ERROR_INCOMPATIBLE_MODE},
-         * {@link #ERROR_NO_CHANNEL}, or {@link #ERROR_GENERIC}.
-         */
-        public void onFailed(int reason) { };
-    }
-
-    /**
-     * Callback proxy for LocalOnlyHotspotCallback objects.
-     */
-    private static class LocalOnlyHotspotCallbackProxy extends ILocalOnlyHotspotCallback.Stub {
-        private final WeakReference<WifiManager> mWifiManager;
-        private final Executor mExecutor;
-        private final LocalOnlyHotspotCallback mCallback;
-
-        /**
-         * Constructs a {@link LocalOnlyHotspotCallbackProxy} using the specified executor.  All
-         * callbacks will run using the given executor.
-         *
-         * @param manager WifiManager
-         * @param executor Executor for delivering callbacks.
-         * @param callback LocalOnlyHotspotCallback to notify the calling application, or null.
-         */
-        LocalOnlyHotspotCallbackProxy(
-                @NonNull WifiManager manager,
-                @NonNull Executor executor,
-                @Nullable LocalOnlyHotspotCallback callback) {
-            mWifiManager = new WeakReference<>(manager);
-            mExecutor = executor;
-            mCallback = callback;
-        }
-
-        @Override
-        public void onHotspotStarted(SoftApConfiguration config) {
-            WifiManager manager = mWifiManager.get();
-            if (manager == null) return;
-
-            if (config == null) {
-                Log.e(TAG, "LocalOnlyHotspotCallbackProxy: config cannot be null.");
-                onHotspotFailed(LocalOnlyHotspotCallback.ERROR_GENERIC);
-                return;
-            }
-            final LocalOnlyHotspotReservation reservation =
-                    manager.new LocalOnlyHotspotReservation(config);
-            if (mCallback == null) return;
-            mExecutor.execute(() -> mCallback.onStarted(reservation));
-        }
-
-        @Override
-        public void onHotspotStopped() {
-            WifiManager manager = mWifiManager.get();
-            if (manager == null) return;
-
-            Log.w(TAG, "LocalOnlyHotspotCallbackProxy: hotspot stopped");
-            if (mCallback == null) return;
-            mExecutor.execute(() -> mCallback.onStopped());
-        }
-
-        @Override
-        public void onHotspotFailed(int reason) {
-            WifiManager manager = mWifiManager.get();
-            if (manager == null) return;
-
-            Log.w(TAG, "LocalOnlyHotspotCallbackProxy: failed to start.  reason: "
-                    + reason);
-            if (mCallback == null) return;
-            mExecutor.execute(() -> mCallback.onFailed(reason));
-        }
-    }
-
-    /**
-     * LocalOnlyHotspotSubscription that is an AutoCloseable object for tracking applications
-     * watching for LocalOnlyHotspot changes.
-     *
-     * @hide
-     */
-    public class LocalOnlyHotspotSubscription implements AutoCloseable {
-        private final CloseGuard mCloseGuard = new CloseGuard();
-
-        /** @hide */
-        @VisibleForTesting
-        public LocalOnlyHotspotSubscription() {
-            mCloseGuard.open("close");
-        }
-
-        @Override
-        public void close() {
-            try {
-                unregisterLocalOnlyHotspotObserver();
-                mCloseGuard.close();
-            } catch (Exception e) {
-                Log.e(TAG, "Failed to unregister LocalOnlyHotspotObserver.");
-            } finally {
-                Reference.reachabilityFence(this);
-            }
-        }
-
-        @Override
-        protected void finalize() throws Throwable {
-            try {
-                if (mCloseGuard != null) {
-                    mCloseGuard.warnIfOpen();
-                }
-                close();
-            } finally {
-                super.finalize();
-            }
-        }
-    }
-
-    /**
-     * Class to notify calling applications that watch for changes in LocalOnlyHotspot of updates.
-     *
-     * @hide
-     */
-    public static class LocalOnlyHotspotObserver {
-        /**
-         * Confirm registration for LocalOnlyHotspotChanges by returning a
-         * LocalOnlyHotspotSubscription.
-         */
-        public void onRegistered(LocalOnlyHotspotSubscription subscription) {};
-
-        /**
-         * LocalOnlyHotspot started with the supplied config.
-         */
-        public void onStarted(SoftApConfiguration config) {};
-
-        /**
-         * LocalOnlyHotspot stopped.
-         */
-        public void onStopped() {};
-    }
-
-    /**
-     * Callback proxy for LocalOnlyHotspotObserver objects.
-     */
-    private static class LocalOnlyHotspotObserverProxy extends ILocalOnlyHotspotCallback.Stub {
-        private final WeakReference<WifiManager> mWifiManager;
-        private final Executor mExecutor;
-        private final LocalOnlyHotspotObserver mObserver;
-
-        /**
-         * Constructs a {@link LocalOnlyHotspotObserverProxy} using the specified looper.
-         * All callbacks will be delivered on the thread of the specified looper.
-         *
-         * @param manager WifiManager
-         * @param executor Executor for delivering callbacks
-         * @param observer LocalOnlyHotspotObserver to notify the calling application.
-         */
-        LocalOnlyHotspotObserverProxy(WifiManager manager, Executor executor,
-                final LocalOnlyHotspotObserver observer) {
-            mWifiManager = new WeakReference<>(manager);
-            mExecutor = executor;
-            mObserver = observer;
-        }
-
-        public void registered() throws RemoteException {
-            WifiManager manager = mWifiManager.get();
-            if (manager == null) return;
-
-            mExecutor.execute(() ->
-                    mObserver.onRegistered(manager.new LocalOnlyHotspotSubscription()));
-        }
-
-        @Override
-        public void onHotspotStarted(SoftApConfiguration config) {
-            WifiManager manager = mWifiManager.get();
-            if (manager == null) return;
-
-            if (config == null) {
-                Log.e(TAG, "LocalOnlyHotspotObserverProxy: config cannot be null.");
-                return;
-            }
-            mExecutor.execute(() -> mObserver.onStarted(config));
-        }
-
-        @Override
-        public void onHotspotStopped() {
-            WifiManager manager = mWifiManager.get();
-            if (manager == null) return;
-
-            mExecutor.execute(() -> mObserver.onStopped());
-        }
-
-        @Override
-        public void onHotspotFailed(int reason) {
-            // do nothing
-        }
-    }
-
-    /**
-     * Callback proxy for ActionListener objects.
-     */
-    private class ActionListenerProxy extends IActionListener.Stub {
-        private final String mActionTag;
-        private final Handler mHandler;
-        private final ActionListener mCallback;
-
-        ActionListenerProxy(String actionTag, Looper looper, ActionListener callback) {
-            mActionTag = actionTag;
-            mHandler = new Handler(looper);
-            mCallback = callback;
-        }
-
-        @Override
-        public void onSuccess() {
-            if (mVerboseLoggingEnabled) {
-                Log.v(TAG, "ActionListenerProxy:" + mActionTag + ": onSuccess");
-            }
-            mHandler.post(() -> {
-                mCallback.onSuccess();
-            });
-        }
-
-        @Override
-        public void onFailure(@ActionListenerFailureReason int reason) {
-            if (mVerboseLoggingEnabled) {
-                Log.v(TAG, "ActionListenerProxy:" + mActionTag + ": onFailure=" + reason);
-            }
-            mHandler.post(() -> {
-                mCallback.onFailure(reason);
-            });
-        }
-    }
-
-    private void connectInternal(@Nullable WifiConfiguration config, int networkId,
-            @Nullable ActionListener listener) {
-        ActionListenerProxy listenerProxy = null;
-        Binder binder = null;
-        if (listener != null) {
-            listenerProxy = new ActionListenerProxy("connect", mLooper, listener);
-            binder = new Binder();
-        }
-        try {
-            mService.connect(config, networkId, binder, listenerProxy,
-                    listener == null ? 0 : listener.hashCode());
-        } catch (RemoteException e) {
-            if (listenerProxy != null) listenerProxy.onFailure(ERROR);
-        } catch (SecurityException e) {
-            if (listenerProxy != null) listenerProxy.onFailure(NOT_AUTHORIZED);
-        }
-    }
-
-    /**
-     * Connect to a network with the given configuration. The network also
-     * gets added to the list of configured networks for the foreground user.
-     *
-     * For a new network, this function is used instead of a
-     * sequence of addNetwork(), enableNetwork(), and reconnect()
-     *
-     * @param config the set of variables that describe the configuration,
-     *            contained in a {@link WifiConfiguration} object.
-     * @param listener for callbacks on success or failure. Can be null.
-     * @throws IllegalStateException if the WifiManager instance needs to be
-     * initialized again
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(anyOf = {
-            android.Manifest.permission.NETWORK_SETTINGS,
-            android.Manifest.permission.NETWORK_SETUP_WIZARD,
-            android.Manifest.permission.NETWORK_STACK
-    })
-    public void connect(@NonNull WifiConfiguration config, @Nullable ActionListener listener) {
-        if (config == null) throw new IllegalArgumentException("config cannot be null");
-        connectInternal(config, WifiConfiguration.INVALID_NETWORK_ID, listener);
-    }
-
-    /**
-     * Connect to a network with the given networkId.
-     *
-     * This function is used instead of a enableNetwork() and reconnect()
-     *
-     * <li> This API will cause reconnect if the credentials of the current active
-     * connection has been changed.</li>
-     * <li> This API will cause reconnect if the current active connection is marked metered.</li>
-     *
-     * @param networkId the ID of the network as returned by {@link #addNetwork} or {@link
-     *        getConfiguredNetworks}.
-     * @param listener for callbacks on success or failure. Can be null.
-     * @throws IllegalStateException if the WifiManager instance needs to be
-     * initialized again
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(anyOf = {
-            android.Manifest.permission.NETWORK_SETTINGS,
-            android.Manifest.permission.NETWORK_SETUP_WIZARD,
-            android.Manifest.permission.NETWORK_STACK
-    })
-    public void connect(int networkId, @Nullable ActionListener listener) {
-        if (networkId < 0) throw new IllegalArgumentException("Network id cannot be negative");
-        connectInternal(null, networkId, listener);
-    }
-
-    /**
-     * Save the given network to the list of configured networks for the
-     * foreground user. If the network already exists, the configuration
-     * is updated. Any new network is enabled by default.
-     *
-     * For a new network, this function is used instead of a
-     * sequence of addNetwork() and enableNetwork().
-     *
-     * For an existing network, it accomplishes the task of updateNetwork()
-     *
-     * <li> This API will cause reconnect if the credentials of the current active
-     * connection has been changed.</li>
-     * <li> This API will cause disconnect if the current active connection is marked metered.</li>
-     *
-     * @param config the set of variables that describe the configuration,
-     *            contained in a {@link WifiConfiguration} object.
-     * @param listener for callbacks on success or failure. Can be null.
-     * @throws IllegalStateException if the WifiManager instance needs to be
-     * initialized again
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(anyOf = {
-            android.Manifest.permission.NETWORK_SETTINGS,
-            android.Manifest.permission.NETWORK_SETUP_WIZARD,
-            android.Manifest.permission.NETWORK_STACK
-    })
-    public void save(@NonNull WifiConfiguration config, @Nullable ActionListener listener) {
-        if (config == null) throw new IllegalArgumentException("config cannot be null");
-        ActionListenerProxy listenerProxy = null;
-        Binder binder = null;
-        if (listener != null) {
-            listenerProxy = new ActionListenerProxy("save", mLooper, listener);
-            binder = new Binder();
-        }
-        try {
-            mService.save(config, binder, listenerProxy,
-                    listener == null ? 0 : listener.hashCode());
-        } catch (RemoteException e) {
-            if (listenerProxy != null) listenerProxy.onFailure(ERROR);
-        } catch (SecurityException e) {
-            if (listenerProxy != null) listenerProxy.onFailure(NOT_AUTHORIZED);
-        }
-    }
-
-    /**
-     * Delete the network from the list of configured networks for the
-     * foreground user.
-     *
-     * This function is used instead of a sequence of removeNetwork()
-     *
-     * @param config the set of variables that describe the configuration,
-     *            contained in a {@link WifiConfiguration} object.
-     * @param listener for callbacks on success or failure. Can be null.
-     * @throws IllegalStateException if the WifiManager instance needs to be
-     * initialized again
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(anyOf = {
-            android.Manifest.permission.NETWORK_SETTINGS,
-            android.Manifest.permission.NETWORK_SETUP_WIZARD,
-            android.Manifest.permission.NETWORK_STACK
-    })
-    public void forget(int netId, @Nullable ActionListener listener) {
-        if (netId < 0) throw new IllegalArgumentException("Network id cannot be negative");
-        ActionListenerProxy listenerProxy = null;
-        Binder binder = null;
-        if (listener != null) {
-            listenerProxy = new ActionListenerProxy("forget", mLooper, listener);
-            binder = new Binder();
-        }
-        try {
-            mService.forget(netId, binder, listenerProxy,
-                    listener == null ? 0 : listener.hashCode());
-        } catch (RemoteException e) {
-            if (listenerProxy != null) listenerProxy.onFailure(ERROR);
-        } catch (SecurityException e) {
-            if (listenerProxy != null) listenerProxy.onFailure(NOT_AUTHORIZED);
-        }
-    }
-
-    /**
-     * Disable network
-     *
-     * @param netId is the network Id
-     * @param listener for callbacks on success or failure. Can be null.
-     * @throws IllegalStateException if the WifiManager instance needs to be
-     * initialized again
-     * @deprecated This API is deprecated. Use {@link #disableNetwork(int)} instead.
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(anyOf = {
-            android.Manifest.permission.NETWORK_SETTINGS,
-            android.Manifest.permission.NETWORK_SETUP_WIZARD,
-            android.Manifest.permission.NETWORK_STACK
-    })
-    @Deprecated
-    public void disable(int netId, @Nullable ActionListener listener) {
-        if (netId < 0) throw new IllegalArgumentException("Network id cannot be negative");
-        // Simple wrapper which forwards the call to disableNetwork. This is a temporary
-        // implementation until we can remove this API completely.
-        boolean status = disableNetwork(netId);
-        if (listener != null) {
-            if (status) {
-                listener.onSuccess();
-            } else {
-                listener.onFailure(ERROR);
-            }
-        }
-    }
-
-    /**
-     * Enable/disable auto-join globally.
-     *
-     * @param allowAutojoin true to allow auto-join, false to disallow auto-join
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public void allowAutojoinGlobal(boolean allowAutojoin) {
-        try {
-            mService.allowAutojoinGlobal(allowAutojoin);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-
-    /**
-     * Sets the user choice for allowing auto-join to a network.
-     * The updated choice will be made available through the updated config supplied by the
-     * CONFIGURED_NETWORKS_CHANGED broadcast.
-     *
-     * @param netId the id of the network to allow/disallow auto-join for.
-     * @param allowAutojoin true to allow auto-join, false to disallow auto-join
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public void allowAutojoin(int netId, boolean allowAutojoin) {
-        try {
-            mService.allowAutojoin(netId, allowAutojoin);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Configure auto-join settings for a Passpoint profile.
-     *
-     * @param fqdn the FQDN (fully qualified domain name) of the passpoint profile.
-     * @param allowAutojoin true to enable auto-join, false to disable auto-join.
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public void allowAutojoinPasspoint(@NonNull String fqdn, boolean allowAutojoin) {
-        try {
-            mService.allowAutojoinPasspoint(fqdn, allowAutojoin);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Configure MAC randomization setting for a Passpoint profile.
-     * MAC randomization is enabled by default.
-     *
-     * @param fqdn the FQDN (fully qualified domain name) of the passpoint profile.
-     * @param enable true to enable MAC randomization, false to disable MAC randomization.
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public void setMacRandomizationSettingPasspointEnabled(@NonNull String fqdn, boolean enable) {
-        try {
-            mService.setMacRandomizationSettingPasspointEnabled(fqdn, enable);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Sets the user's choice of metered override for a Passpoint profile.
-     *
-     * @param fqdn the FQDN (fully qualified domain name) of the passpoint profile.
-     * @param meteredOverride One of three values: {@link WifiConfiguration#METERED_OVERRIDE_NONE},
-     *                        {@link WifiConfiguration#METERED_OVERRIDE_METERED},
-     *                        {@link WifiConfiguration#METERED_OVERRIDE_NOT_METERED}
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public void setPasspointMeteredOverride(@NonNull String fqdn,
-            @WifiConfiguration.MeteredOverride int meteredOverride) {
-        try {
-            mService.setPasspointMeteredOverride(fqdn, meteredOverride);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Temporarily disable a network. Should always trigger with user disconnect network.
-     *
-     * @param network Input can be SSID or FQDN. And caller must ensure that the SSID passed thru
-     *                this API matched the WifiConfiguration.SSID rules, and thus be surrounded by
-     *                quotes.
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(anyOf = {
-            android.Manifest.permission.NETWORK_SETTINGS,
-            android.Manifest.permission.NETWORK_STACK
-    })
-    public void disableEphemeralNetwork(@NonNull String network) {
-        if (TextUtils.isEmpty(network)) {
-            throw new IllegalArgumentException("SSID cannot be null or empty!");
-        }
-        try {
-            mService.disableEphemeralNetwork(network, mContext.getOpPackageName());
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * WPS suport has been deprecated from Client mode and this method will immediately trigger
-     * {@link WpsCallback#onFailed(int)} with a generic error.
-     *
-     * @param config WPS configuration (does not support {@link WpsInfo#LABEL})
-     * @param listener for callbacks on success or failure. Can be null.
-     * @throws IllegalStateException if the WifiManager instance needs to be initialized again
-     * @deprecated This API is deprecated
-     */
-    public void startWps(WpsInfo config, WpsCallback listener) {
-        if (listener != null ) {
-            listener.onFailed(ERROR);
-        }
-    }
-
-    /**
-     * WPS support has been deprecated from Client mode and this method will immediately trigger
-     * {@link WpsCallback#onFailed(int)} with a generic error.
-     *
-     * @param listener for callbacks on success or failure. Can be null.
-     * @throws IllegalStateException if the WifiManager instance needs to be initialized again
-     * @deprecated This API is deprecated
-     */
-    public void cancelWps(WpsCallback listener) {
-        if (listener != null) {
-            listener.onFailed(ERROR);
-        }
-    }
-
-    /**
-     * Allows an application to keep the Wi-Fi radio awake.
-     * Normally the Wi-Fi radio may turn off when the user has not used the device in a while.
-     * Acquiring a WifiLock will keep the radio on until the lock is released.  Multiple
-     * applications may hold WifiLocks, and the radio will only be allowed to turn off when no
-     * WifiLocks are held in any application.
-     * <p>
-     * Before using a WifiLock, consider carefully if your application requires Wi-Fi access, or
-     * could function over a mobile network, if available.  A program that needs to download large
-     * files should hold a WifiLock to ensure that the download will complete, but a program whose
-     * network usage is occasional or low-bandwidth should not hold a WifiLock to avoid adversely
-     * affecting battery life.
-     * <p>
-     * Note that WifiLocks cannot override the user-level "Wi-Fi Enabled" setting, nor Airplane
-     * Mode.  They simply keep the radio from turning off when Wi-Fi is already on but the device
-     * is idle.
-     * <p>
-     * Any application using a WifiLock must request the {@code android.permission.WAKE_LOCK}
-     * permission in an {@code <uses-permission>} element of the application's manifest.
-     */
-    public class WifiLock {
-        private String mTag;
-        private final IBinder mBinder;
-        private int mRefCount;
-        int mLockType;
-        private boolean mRefCounted;
-        private boolean mHeld;
-        private WorkSource mWorkSource;
-
-        private WifiLock(int lockType, String tag) {
-            mTag = tag;
-            mLockType = lockType;
-            mBinder = new Binder();
-            mRefCount = 0;
-            mRefCounted = true;
-            mHeld = false;
-        }
-
-        /**
-         * Locks the Wi-Fi radio on until {@link #release} is called.
-         *
-         * If this WifiLock is reference-counted, each call to {@code acquire} will increment the
-         * reference count, and the radio will remain locked as long as the reference count is
-         * above zero.
-         *
-         * If this WifiLock is not reference-counted, the first call to {@code acquire} will lock
-         * the radio, but subsequent calls will be ignored.  Only one call to {@link #release}
-         * will be required, regardless of the number of times that {@code acquire} is called.
-         */
-        public void acquire() {
-            synchronized (mBinder) {
-                if (mRefCounted ? (++mRefCount == 1) : (!mHeld)) {
-                    try {
-                        mService.acquireWifiLock(mBinder, mLockType, mTag, mWorkSource);
-                        synchronized (WifiManager.this) {
-                            if (mActiveLockCount >= MAX_ACTIVE_LOCKS) {
-                                mService.releaseWifiLock(mBinder);
-                                throw new UnsupportedOperationException(
-                                            "Exceeded maximum number of wifi locks");
-                            }
-                            mActiveLockCount++;
-                        }
-                    } catch (RemoteException e) {
-                        throw e.rethrowFromSystemServer();
-                    }
-                    mHeld = true;
-                }
-            }
-        }
-
-        /**
-         * Unlocks the Wi-Fi radio, allowing it to turn off when the device is idle.
-         *
-         * If this WifiLock is reference-counted, each call to {@code release} will decrement the
-         * reference count, and the radio will be unlocked only when the reference count reaches
-         * zero.  If the reference count goes below zero (that is, if {@code release} is called
-         * a greater number of times than {@link #acquire}), an exception is thrown.
-         *
-         * If this WifiLock is not reference-counted, the first call to {@code release} (after
-         * the radio was locked using {@link #acquire}) will unlock the radio, and subsequent
-         * calls will be ignored.
-         */
-        public void release() {
-            synchronized (mBinder) {
-                if (mRefCounted ? (--mRefCount == 0) : (mHeld)) {
-                    try {
-                        mService.releaseWifiLock(mBinder);
-                        synchronized (WifiManager.this) {
-                            mActiveLockCount--;
-                        }
-                    } catch (RemoteException e) {
-                        throw e.rethrowFromSystemServer();
-                    }
-                    mHeld = false;
-                }
-                if (mRefCount < 0) {
-                    throw new RuntimeException("WifiLock under-locked " + mTag);
-                }
-            }
-        }
-
-        /**
-         * Controls whether this is a reference-counted or non-reference-counted WifiLock.
-         *
-         * Reference-counted WifiLocks keep track of the number of calls to {@link #acquire} and
-         * {@link #release}, and only allow the radio to sleep when every call to {@link #acquire}
-         * has been balanced with a call to {@link #release}.  Non-reference-counted WifiLocks
-         * lock the radio whenever {@link #acquire} is called and it is unlocked, and unlock the
-         * radio whenever {@link #release} is called and it is locked.
-         *
-         * @param refCounted true if this WifiLock should keep a reference count
-         */
-        public void setReferenceCounted(boolean refCounted) {
-            mRefCounted = refCounted;
-        }
-
-        /**
-         * Checks whether this WifiLock is currently held.
-         *
-         * @return true if this WifiLock is held, false otherwise
-         */
-        public boolean isHeld() {
-            synchronized (mBinder) {
-                return mHeld;
-            }
-        }
-
-        public void setWorkSource(WorkSource ws) {
-            synchronized (mBinder) {
-                if (ws != null && ws.isEmpty()) {
-                    ws = null;
-                }
-                boolean changed = true;
-                if (ws == null) {
-                    mWorkSource = null;
-                } else {
-                    ws = ws.withoutNames();
-                    if (mWorkSource == null) {
-                        changed = mWorkSource != null;
-                        mWorkSource = new WorkSource(ws);
-                    } else {
-                        changed = !mWorkSource.equals(ws);
-                        if (changed) {
-                            mWorkSource.set(ws);
-                        }
-                    }
-                }
-                if (changed && mHeld) {
-                    try {
-                        mService.updateWifiLockWorkSource(mBinder, mWorkSource);
-                    } catch (RemoteException e) {
-                        throw e.rethrowFromSystemServer();
-                    }
-                }
-            }
-        }
-
-        public String toString() {
-            String s1, s2, s3;
-            synchronized (mBinder) {
-                s1 = Integer.toHexString(System.identityHashCode(this));
-                s2 = mHeld ? "held; " : "";
-                if (mRefCounted) {
-                    s3 = "refcounted: refcount = " + mRefCount;
-                } else {
-                    s3 = "not refcounted";
-                }
-                return "WifiLock{ " + s1 + "; " + s2 + s3 + " }";
-            }
-        }
-
-        @Override
-        protected void finalize() throws Throwable {
-            super.finalize();
-            synchronized (mBinder) {
-                if (mHeld) {
-                    try {
-                        mService.releaseWifiLock(mBinder);
-                        synchronized (WifiManager.this) {
-                            mActiveLockCount--;
-                        }
-                    } catch (RemoteException e) {
-                        throw e.rethrowFromSystemServer();
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Creates a new WifiLock.
-     *
-     * @param lockType the type of lock to create. See {@link #WIFI_MODE_FULL_HIGH_PERF}
-     * and {@link #WIFI_MODE_FULL_LOW_LATENCY} for descriptions of the types of Wi-Fi locks.
-     * @param tag a tag for the WifiLock to identify it in debugging messages.  This string is
-     *            never shown to the user under normal conditions, but should be descriptive
-     *            enough to identify your application and the specific WifiLock within it, if it
-     *            holds multiple WifiLocks.
-     *
-     * @return a new, unacquired WifiLock with the given tag.
-     *
-     * @see WifiLock
-     */
-    public WifiLock createWifiLock(int lockType, String tag) {
-        return new WifiLock(lockType, tag);
-    }
-
-    /**
-     * Creates a new WifiLock.
-     *
-     * @param tag a tag for the WifiLock to identify it in debugging messages.  This string is
-     *            never shown to the user under normal conditions, but should be descriptive
-     *            enough to identify your application and the specific WifiLock within it, if it
-     *            holds multiple WifiLocks.
-     *
-     * @return a new, unacquired WifiLock with the given tag.
-     *
-     * @see WifiLock
-     *
-     * @deprecated This API is non-functional.
-     */
-    @Deprecated
-    public WifiLock createWifiLock(String tag) {
-        return new WifiLock(WIFI_MODE_FULL, tag);
-    }
-
-    /**
-     * Create a new MulticastLock
-     *
-     * @param tag a tag for the MulticastLock to identify it in debugging
-     *            messages.  This string is never shown to the user under
-     *            normal conditions, but should be descriptive enough to
-     *            identify your application and the specific MulticastLock
-     *            within it, if it holds multiple MulticastLocks.
-     *
-     * @return a new, unacquired MulticastLock with the given tag.
-     *
-     * @see MulticastLock
-     */
-    public MulticastLock createMulticastLock(String tag) {
-        return new MulticastLock(tag);
-    }
-
-    /**
-     * Allows an application to receive Wifi Multicast packets.
-     * Normally the Wifi stack filters out packets not explicitly
-     * addressed to this device.  Acquring a MulticastLock will
-     * cause the stack to receive packets addressed to multicast
-     * addresses.  Processing these extra packets can cause a noticeable
-     * battery drain and should be disabled when not needed.
-     */
-    public class MulticastLock {
-        private String mTag;
-        private final IBinder mBinder;
-        private int mRefCount;
-        private boolean mRefCounted;
-        private boolean mHeld;
-
-        private MulticastLock(String tag) {
-            mTag = tag;
-            mBinder = new Binder();
-            mRefCount = 0;
-            mRefCounted = true;
-            mHeld = false;
-        }
-
-        /**
-         * Locks Wifi Multicast on until {@link #release} is called.
-         *
-         * If this MulticastLock is reference-counted each call to
-         * {@code acquire} will increment the reference count, and the
-         * wifi interface will receive multicast packets as long as the
-         * reference count is above zero.
-         *
-         * If this MulticastLock is not reference-counted, the first call to
-         * {@code acquire} will turn on the multicast packets, but subsequent
-         * calls will be ignored.  Only one call to {@link #release} will
-         * be required, regardless of the number of times that {@code acquire}
-         * is called.
-         *
-         * Note that other applications may also lock Wifi Multicast on.
-         * Only they can relinquish their lock.
-         *
-         * Also note that applications cannot leave Multicast locked on.
-         * When an app exits or crashes, any Multicast locks will be released.
-         */
-        public void acquire() {
-            synchronized (mBinder) {
-                if (mRefCounted ? (++mRefCount == 1) : (!mHeld)) {
-                    try {
-                        mService.acquireMulticastLock(mBinder, mTag);
-                        synchronized (WifiManager.this) {
-                            if (mActiveLockCount >= MAX_ACTIVE_LOCKS) {
-                                mService.releaseMulticastLock(mTag);
-                                throw new UnsupportedOperationException(
-                                        "Exceeded maximum number of wifi locks");
-                            }
-                            mActiveLockCount++;
-                        }
-                    } catch (RemoteException e) {
-                        throw e.rethrowFromSystemServer();
-                    }
-                    mHeld = true;
-                }
-            }
-        }
-
-        /**
-         * Unlocks Wifi Multicast, restoring the filter of packets
-         * not addressed specifically to this device and saving power.
-         *
-         * If this MulticastLock is reference-counted, each call to
-         * {@code release} will decrement the reference count, and the
-         * multicast packets will only stop being received when the reference
-         * count reaches zero.  If the reference count goes below zero (that
-         * is, if {@code release} is called a greater number of times than
-         * {@link #acquire}), an exception is thrown.
-         *
-         * If this MulticastLock is not reference-counted, the first call to
-         * {@code release} (after the radio was multicast locked using
-         * {@link #acquire}) will unlock the multicast, and subsequent calls
-         * will be ignored.
-         *
-         * Note that if any other Wifi Multicast Locks are still outstanding
-         * this {@code release} call will not have an immediate effect.  Only
-         * when all applications have released all their Multicast Locks will
-         * the Multicast filter be turned back on.
-         *
-         * Also note that when an app exits or crashes all of its Multicast
-         * Locks will be automatically released.
-         */
-        public void release() {
-            synchronized (mBinder) {
-                if (mRefCounted ? (--mRefCount == 0) : (mHeld)) {
-                    try {
-                        mService.releaseMulticastLock(mTag);
-                        synchronized (WifiManager.this) {
-                            mActiveLockCount--;
-                        }
-                    } catch (RemoteException e) {
-                        throw e.rethrowFromSystemServer();
-                    }
-                    mHeld = false;
-                }
-                if (mRefCount < 0) {
-                    throw new RuntimeException("MulticastLock under-locked "
-                            + mTag);
-                }
-            }
-        }
-
-        /**
-         * Controls whether this is a reference-counted or non-reference-
-         * counted MulticastLock.
-         *
-         * Reference-counted MulticastLocks keep track of the number of calls
-         * to {@link #acquire} and {@link #release}, and only stop the
-         * reception of multicast packets when every call to {@link #acquire}
-         * has been balanced with a call to {@link #release}.  Non-reference-
-         * counted MulticastLocks allow the reception of multicast packets
-         * whenever {@link #acquire} is called and stop accepting multicast
-         * packets whenever {@link #release} is called.
-         *
-         * @param refCounted true if this MulticastLock should keep a reference
-         * count
-         */
-        public void setReferenceCounted(boolean refCounted) {
-            mRefCounted = refCounted;
-        }
-
-        /**
-         * Checks whether this MulticastLock is currently held.
-         *
-         * @return true if this MulticastLock is held, false otherwise
-         */
-        public boolean isHeld() {
-            synchronized (mBinder) {
-                return mHeld;
-            }
-        }
-
-        public String toString() {
-            String s1, s2, s3;
-            synchronized (mBinder) {
-                s1 = Integer.toHexString(System.identityHashCode(this));
-                s2 = mHeld ? "held; " : "";
-                if (mRefCounted) {
-                    s3 = "refcounted: refcount = " + mRefCount;
-                } else {
-                    s3 = "not refcounted";
-                }
-                return "MulticastLock{ " + s1 + "; " + s2 + s3 + " }";
-            }
-        }
-
-        @Override
-        protected void finalize() throws Throwable {
-            super.finalize();
-            setReferenceCounted(false);
-            release();
-        }
-    }
-
-    /**
-     * Check multicast filter status.
-     *
-     * @return true if multicast packets are allowed.
-     *
-     * @hide pending API council approval
-     */
-    public boolean isMulticastEnabled() {
-        try {
-            return mService.isMulticastEnabled();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Initialize the multicast filtering to 'on'
-     * @hide no intent to publish
-     */
-    @UnsupportedAppUsage
-    public boolean initializeMulticastFiltering() {
-        try {
-            mService.initializeMulticastFiltering();
-            return true;
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Set Wi-Fi verbose logging level from developer settings.
-     *
-     * @param enable true to enable verbose logging, false to disable.
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public void setVerboseLoggingEnabled(boolean enable) {
-        enableVerboseLogging(enable ? 1 : 0);
-    }
-
-    /** @hide */
-    @UnsupportedAppUsage(
-            maxTargetSdk = Build.VERSION_CODES.Q,
-            publicAlternatives = "Use {@code #setVerboseLoggingEnabled(boolean)} instead."
-    )
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public void enableVerboseLogging (int verbose) {
-        try {
-            mService.enableVerboseLogging(verbose);
-        } catch (Exception e) {
-            //ignore any failure here
-            Log.e(TAG, "enableVerboseLogging " + e.toString());
-        }
-    }
-
-    /**
-     * Get the persisted Wi-Fi verbose logging level, set by
-     * {@link #setVerboseLoggingEnabled(boolean)}.
-     * No permissions are required to call this method.
-     *
-     * @return true to indicate that verbose logging is enabled, false to indicate that verbose
-     * logging is disabled.
-     *
-     * @hide
-     */
-    @SystemApi
-    public boolean isVerboseLoggingEnabled() {
-        return getVerboseLoggingLevel() > 0;
-    }
-
-    /** @hide */
-    // TODO(b/145484145): remove once SUW stops calling this via reflection
-    @UnsupportedAppUsage(
-            maxTargetSdk = Build.VERSION_CODES.Q,
-            publicAlternatives = "Use {@code #isVerboseLoggingEnabled()} instead."
-    )
-    public int getVerboseLoggingLevel() {
-        try {
-            return mService.getVerboseLoggingLevel();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Removes all saved Wi-Fi networks, Passpoint configurations, ephemeral networks, Network
-     * Requests, and Network Suggestions.
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public void factoryReset() {
-        try {
-            mService.factoryReset(mContext.getOpPackageName());
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Get {@link Network} object of current wifi network, or null if not connected.
-     * @hide
-     */
-    @Nullable
-    @SystemApi
-    @RequiresPermission(anyOf = {
-            android.Manifest.permission.NETWORK_SETTINGS,
-            android.Manifest.permission.NETWORK_SETUP_WIZARD
-    })
-    public Network getCurrentNetwork() {
-        try {
-            return mService.getCurrentNetwork();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Deprecated
-     * returns false
-     * @hide
-     * @deprecated
-     */
-    public boolean setEnableAutoJoinWhenAssociated(boolean enabled) {
-        return false;
-    }
-
-    /**
-     * Deprecated
-     * returns false
-     * @hide
-     * @deprecated
-     */
-    public boolean getEnableAutoJoinWhenAssociated() {
-        return false;
-    }
-
-    /**
-     * Returns a byte stream representing the data that needs to be backed up to save the
-     * current Wifi state.
-     * This Wifi state can be restored by calling {@link #restoreBackupData(byte[])}.
-     * @hide
-     */
-    @NonNull
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public byte[] retrieveBackupData() {
-        try {
-            return mService.retrieveBackupData();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Restore state from the backed up data.
-     * @param data byte stream in the same format produced by {@link #retrieveBackupData()}
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public void restoreBackupData(@NonNull byte[] data) {
-        try {
-            mService.restoreBackupData(data);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Returns a byte stream representing the data that needs to be backed up to save the
-     * current soft ap config data.
-     *
-     * This soft ap config can be restored by calling {@link #restoreSoftApBackupData(byte[])}
-     * @hide
-     */
-    @NonNull
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public byte[] retrieveSoftApBackupData() {
-        try {
-            return mService.retrieveSoftApBackupData();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Returns soft ap config from the backed up data or null if data is invalid.
-     * @param data byte stream in the same format produced by {@link #retrieveSoftApBackupData()}
-     *
-     * @hide
-     */
-    @Nullable
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public SoftApConfiguration restoreSoftApBackupData(@NonNull byte[] data) {
-        try {
-            return mService.restoreSoftApBackupData(data);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Restore state from the older version of back up data.
-     * The old backup data was essentially a backup of wpa_supplicant.conf
-     * and ipconfig.txt file.
-     * @param supplicantData bytes representing wpa_supplicant.conf
-     * @param ipConfigData bytes representing ipconfig.txt
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public void restoreSupplicantBackupData(
-            @NonNull byte[] supplicantData, @NonNull byte[] ipConfigData) {
-        try {
-            mService.restoreSupplicantBackupData(supplicantData, ipConfigData);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Start subscription provisioning flow
-     *
-     * @param provider {@link OsuProvider} to provision with
-     * @param executor the Executor on which to run the callback.
-     * @param callback {@link ProvisioningCallback} for updates regarding provisioning flow
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(anyOf = {
-            android.Manifest.permission.NETWORK_SETTINGS,
-            android.Manifest.permission.NETWORK_SETUP_WIZARD
-    })
-    public void startSubscriptionProvisioning(@NonNull OsuProvider provider,
-            @NonNull @CallbackExecutor Executor executor, @NonNull ProvisioningCallback callback) {
-        // Verify arguments
-        if (executor == null) {
-            throw new IllegalArgumentException("executor must not be null");
-        }
-        if (callback == null) {
-            throw new IllegalArgumentException("callback must not be null");
-        }
-        try {
-            mService.startSubscriptionProvisioning(provider,
-                    new ProvisioningCallbackProxy(executor, callback));
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Helper class to support OSU Provisioning callbacks
-     */
-    private static class ProvisioningCallbackProxy extends IProvisioningCallback.Stub {
-        private final Executor mExecutor;
-        private final ProvisioningCallback mCallback;
-
-        ProvisioningCallbackProxy(Executor executor, ProvisioningCallback callback) {
-            mExecutor = executor;
-            mCallback = callback;
-        }
-
-        @Override
-        public void onProvisioningStatus(int status) {
-            mExecutor.execute(() -> mCallback.onProvisioningStatus(status));
-        }
-
-        @Override
-        public void onProvisioningFailure(int status) {
-            mExecutor.execute(() -> mCallback.onProvisioningFailure(status));
-        }
-
-        @Override
-        public void onProvisioningComplete() {
-            mExecutor.execute(() -> mCallback.onProvisioningComplete());
-        }
-    }
-
-    /**
-     * Interface for Traffic state callback. Should be extended by applications and set when
-     * calling {@link #registerTrafficStateCallback(Executor, WifiManager.TrafficStateCallback)}.
-     * @hide
-     */
-    @SystemApi
-    public interface TrafficStateCallback {
-        /** @hide */
-        @Retention(RetentionPolicy.SOURCE)
-        @IntDef(prefix = {"DATA_ACTIVITY_"}, value = {
-                DATA_ACTIVITY_NONE,
-                DATA_ACTIVITY_IN,
-                DATA_ACTIVITY_OUT,
-                DATA_ACTIVITY_INOUT})
-        @interface DataActivity {}
-
-        // Lowest bit indicates data reception and the second lowest bit indicates data transmitted
-        /** No data in or out */
-        int DATA_ACTIVITY_NONE         = 0x00;
-        /** Data in, no data out */
-        int DATA_ACTIVITY_IN           = 0x01;
-        /** Data out, no data in */
-        int DATA_ACTIVITY_OUT          = 0x02;
-        /** Data in and out */
-        int DATA_ACTIVITY_INOUT        = 0x03;
-
-        /**
-         * Callback invoked to inform clients about the current traffic state.
-         *
-         * @param state One of the values: {@link #DATA_ACTIVITY_NONE}, {@link #DATA_ACTIVITY_IN},
-         * {@link #DATA_ACTIVITY_OUT} & {@link #DATA_ACTIVITY_INOUT}.
-         */
-        void onStateChanged(@DataActivity int state);
-    }
-
-    /**
-     * Callback proxy for TrafficStateCallback objects.
-     *
-     * @hide
-     */
-    private class TrafficStateCallbackProxy extends ITrafficStateCallback.Stub {
-        private final Executor mExecutor;
-        private final TrafficStateCallback mCallback;
-
-        TrafficStateCallbackProxy(Executor executor, TrafficStateCallback callback) {
-            mExecutor = executor;
-            mCallback = callback;
-        }
-
-        @Override
-        public void onStateChanged(int state) {
-            if (mVerboseLoggingEnabled) {
-                Log.v(TAG, "TrafficStateCallbackProxy: onStateChanged state=" + state);
-            }
-            Binder.clearCallingIdentity();
-            mExecutor.execute(() -> {
-                mCallback.onStateChanged(state);
-            });
-        }
-    }
-
-    /**
-     * Registers a callback for monitoring traffic state. See {@link TrafficStateCallback}. These
-     * callbacks will be invoked periodically by platform to inform clients about the current
-     * traffic state. Caller can unregister a previously registered callback using
-     * {@link #unregisterTrafficStateCallback(TrafficStateCallback)}
-     * <p>
-     * Applications should have the
-     * {@link android.Manifest.permission#NETWORK_SETTINGS NETWORK_SETTINGS} permission. Callers
-     * without the permission will trigger a {@link java.lang.SecurityException}.
-     * <p>
-     *
-     * @param executor The Executor on whose thread to execute the callbacks of the {@code callback}
-     *                 object.
-     * @param callback Callback for traffic state events
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public void registerTrafficStateCallback(@NonNull @CallbackExecutor Executor executor,
-                                             @NonNull TrafficStateCallback callback) {
-        if (executor == null) throw new IllegalArgumentException("executor cannot be null");
-        if (callback == null) throw new IllegalArgumentException("callback cannot be null");
-        Log.v(TAG, "registerTrafficStateCallback: callback=" + callback + ", executor=" + executor);
-
-        Binder binder = new Binder();
-        try {
-            mService.registerTrafficStateCallback(
-                    binder, new TrafficStateCallbackProxy(executor, callback), callback.hashCode());
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Allow callers to unregister a previously registered callback. After calling this method,
-     * applications will no longer receive traffic state notifications.
-     *
-     * @param callback Callback to unregister for traffic state events
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public void unregisterTrafficStateCallback(@NonNull TrafficStateCallback callback) {
-        if (callback == null) throw new IllegalArgumentException("callback cannot be null");
-        Log.v(TAG, "unregisterTrafficStateCallback: callback=" + callback);
-
-        try {
-            mService.unregisterTrafficStateCallback(callback.hashCode());
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Helper method to update the local verbose logging flag based on the verbose logging
-     * level from wifi service.
-     */
-    private void updateVerboseLoggingEnabledFromService() {
-        mVerboseLoggingEnabled = isVerboseLoggingEnabled();
-    }
-
-    /**
-     * @return true if this device supports WPA3-Personal SAE
-     */
-    public boolean isWpa3SaeSupported() {
-        return isFeatureSupported(WIFI_FEATURE_WPA3_SAE);
-    }
-
-    /**
-     * @return true if this device supports WPA3-Enterprise Suite-B-192
-     */
-    public boolean isWpa3SuiteBSupported() {
-        return isFeatureSupported(WIFI_FEATURE_WPA3_SUITE_B);
-    }
-
-    /**
-     * @return true if this device supports Wi-Fi Enhanced Open (OWE)
-     */
-    public boolean isEnhancedOpenSupported() {
-        return isFeatureSupported(WIFI_FEATURE_OWE);
-    }
-
-    /**
-     * Wi-Fi Easy Connect (DPP) introduces standardized mechanisms to simplify the provisioning and
-     * configuration of Wi-Fi devices.
-     * For more details, visit <a href="https://www.wi-fi.org/">https://www.wi-fi.org/</a> and
-     * search for "Easy Connect" or "Device Provisioning Protocol specification".
-     *
-     * @return true if this device supports Wi-Fi Easy-connect (Device Provisioning Protocol)
-     */
-    public boolean isEasyConnectSupported() {
-        return isFeatureSupported(WIFI_FEATURE_DPP);
-    }
-
-    /**
-     * @return true if this device supports WAPI.
-     */
-    public boolean isWapiSupported() {
-        return isFeatureSupported(WIFI_FEATURE_WAPI);
-    }
-
-    /**
-     * Gets the factory Wi-Fi MAC addresses.
-     * @return Array of String representing Wi-Fi MAC addresses sorted lexically or an empty Array
-     * if failed.
-     * @hide
-     */
-    @NonNull
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public String[] getFactoryMacAddresses() {
-        try {
-            return mService.getFactoryMacAddresses();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(prefix = {"DEVICE_MOBILITY_STATE_"}, value = {
-            DEVICE_MOBILITY_STATE_UNKNOWN,
-            DEVICE_MOBILITY_STATE_HIGH_MVMT,
-            DEVICE_MOBILITY_STATE_LOW_MVMT,
-            DEVICE_MOBILITY_STATE_STATIONARY})
-    public @interface DeviceMobilityState {}
-
-    /**
-     * Unknown device mobility state
-     *
-     * @see #setDeviceMobilityState(int)
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int DEVICE_MOBILITY_STATE_UNKNOWN = 0;
-
-    /**
-     * High movement device mobility state.
-     * e.g. on a bike, in a motor vehicle
-     *
-     * @see #setDeviceMobilityState(int)
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int DEVICE_MOBILITY_STATE_HIGH_MVMT = 1;
-
-    /**
-     * Low movement device mobility state.
-     * e.g. walking, running
-     *
-     * @see #setDeviceMobilityState(int)
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int DEVICE_MOBILITY_STATE_LOW_MVMT = 2;
-
-    /**
-     * Stationary device mobility state
-     *
-     * @see #setDeviceMobilityState(int)
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int DEVICE_MOBILITY_STATE_STATIONARY = 3;
-
-    /**
-     * Updates the device mobility state. Wifi uses this information to adjust the interval between
-     * Wifi scans in order to balance power consumption with scan accuracy.
-     * The default mobility state when the device boots is {@link #DEVICE_MOBILITY_STATE_UNKNOWN}.
-     * This API should be called whenever there is a change in the mobility state.
-     * @param state the updated device mobility state
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.WIFI_SET_DEVICE_MOBILITY_STATE)
-    public void setDeviceMobilityState(@DeviceMobilityState int state) {
-        try {
-            mService.setDeviceMobilityState(state);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /* Easy Connect - AKA Device Provisioning Protocol (DPP) */
-
-    /**
-     * Easy Connect Network role: Station.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int EASY_CONNECT_NETWORK_ROLE_STA = 0;
-
-    /**
-     * Easy Connect Network role: Access Point.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int EASY_CONNECT_NETWORK_ROLE_AP = 1;
-
-    /** @hide */
-    @IntDef(prefix = {"EASY_CONNECT_NETWORK_ROLE_"}, value = {
-            EASY_CONNECT_NETWORK_ROLE_STA,
-            EASY_CONNECT_NETWORK_ROLE_AP,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface EasyConnectNetworkRole {
-    }
-
-    /**
-     * Start Easy Connect (DPP) in Configurator-Initiator role. The current device will initiate
-     * Easy Connect bootstrapping with a peer, and configure the peer with the SSID and password of
-     * the specified network using the Easy Connect protocol on an encrypted link.
-     *
-     * @param enrolleeUri         URI of the Enrollee obtained separately (e.g. QR code scanning)
-     * @param selectedNetworkId   Selected network ID to be sent to the peer
-     * @param enrolleeNetworkRole The network role of the enrollee
-     * @param callback            Callback for status updates
-     * @param executor            The Executor on which to run the callback.
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(anyOf = {
-            android.Manifest.permission.NETWORK_SETTINGS,
-            android.Manifest.permission.NETWORK_SETUP_WIZARD})
-    public void startEasyConnectAsConfiguratorInitiator(@NonNull String enrolleeUri,
-            int selectedNetworkId, @EasyConnectNetworkRole int enrolleeNetworkRole,
-            @NonNull @CallbackExecutor Executor executor,
-            @NonNull EasyConnectStatusCallback callback) {
-        Binder binder = new Binder();
-        try {
-            mService.startDppAsConfiguratorInitiator(binder, enrolleeUri, selectedNetworkId,
-                    enrolleeNetworkRole, new EasyConnectCallbackProxy(executor, callback));
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Start Easy Connect (DPP) in Enrollee-Initiator role. The current device will initiate Easy
-     * Connect bootstrapping with a peer, and receive the SSID and password from the peer
-     * configurator.
-     *
-     * @param configuratorUri URI of the Configurator obtained separately (e.g. QR code scanning)
-     * @param callback        Callback for status updates
-     * @param executor        The Executor on which to run the callback.
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(anyOf = {
-            android.Manifest.permission.NETWORK_SETTINGS,
-            android.Manifest.permission.NETWORK_SETUP_WIZARD})
-    public void startEasyConnectAsEnrolleeInitiator(@NonNull String configuratorUri,
-            @NonNull @CallbackExecutor Executor executor,
-            @NonNull EasyConnectStatusCallback callback) {
-        Binder binder = new Binder();
-        try {
-            mService.startDppAsEnrolleeInitiator(binder, configuratorUri,
-                    new EasyConnectCallbackProxy(executor, callback));
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Stop or abort a current Easy Connect (DPP) session. This call, once processed, will
-     * terminate any ongoing transaction, and clean up all associated resources. Caller should not
-     * expect any callbacks once this call is made. However, due to the asynchronous nature of
-     * this call, a callback may be fired if it was already pending in the queue.
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(anyOf = {
-            android.Manifest.permission.NETWORK_SETTINGS,
-            android.Manifest.permission.NETWORK_SETUP_WIZARD})
-    public void stopEasyConnectSession() {
-        try {
-            /* Request lower layers to stop/abort and clear resources */
-            mService.stopDppSession();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Helper class to support Easy Connect (DPP) callbacks
-     *
-     * @hide
-     */
-    private static class EasyConnectCallbackProxy extends IDppCallback.Stub {
-        private final Executor mExecutor;
-        private final EasyConnectStatusCallback mEasyConnectStatusCallback;
-
-        EasyConnectCallbackProxy(Executor executor,
-                EasyConnectStatusCallback easyConnectStatusCallback) {
-            mExecutor = executor;
-            mEasyConnectStatusCallback = easyConnectStatusCallback;
-        }
-
-        @Override
-        public void onSuccessConfigReceived(int newNetworkId) {
-            Log.d(TAG, "Easy Connect onSuccessConfigReceived callback");
-            Binder.clearCallingIdentity();
-            mExecutor.execute(() -> {
-                mEasyConnectStatusCallback.onEnrolleeSuccess(newNetworkId);
-            });
-        }
-
-        @Override
-        public void onSuccess(int status) {
-            Log.d(TAG, "Easy Connect onSuccess callback");
-            Binder.clearCallingIdentity();
-            mExecutor.execute(() -> {
-                mEasyConnectStatusCallback.onConfiguratorSuccess(status);
-            });
-        }
-
-        @Override
-        public void onFailure(int status, String ssid, String channelList,
-                int[] operatingClassArray) {
-            Log.d(TAG, "Easy Connect onFailure callback");
-            Binder.clearCallingIdentity();
-            mExecutor.execute(() -> {
-                SparseArray<int[]> channelListArray = parseDppChannelList(channelList);
-                mEasyConnectStatusCallback.onFailure(status, ssid, channelListArray,
-                        operatingClassArray);
-            });
-        }
-
-        @Override
-        public void onProgress(int status) {
-            Log.d(TAG, "Easy Connect onProgress callback");
-            Binder.clearCallingIdentity();
-            mExecutor.execute(() -> {
-                mEasyConnectStatusCallback.onProgress(status);
-            });
-        }
-    }
-
-    /**
-     * Interface for Wi-Fi usability statistics listener. Should be implemented by applications and
-     * set when calling {@link WifiManager#addOnWifiUsabilityStatsListener(Executor,
-     * OnWifiUsabilityStatsListener)}.
-     *
-     * @hide
-     */
-    @SystemApi
-    public interface OnWifiUsabilityStatsListener {
-        /**
-         * Called when Wi-Fi usability statistics is updated.
-         *
-         * @param seqNum The sequence number of statistics, used to derive the timing of updated
-         *               Wi-Fi usability statistics, set by framework and incremented by one after
-         *               each update.
-         * @param isSameBssidAndFreq The flag to indicate whether the BSSID and the frequency of
-         *                           network stays the same or not relative to the last update of
-         *                           Wi-Fi usability stats.
-         * @param stats The updated Wi-Fi usability statistics.
-         */
-        void onWifiUsabilityStats(int seqNum, boolean isSameBssidAndFreq,
-                @NonNull WifiUsabilityStatsEntry stats);
-    }
-
-    /**
-     * Adds a listener for Wi-Fi usability statistics. See {@link OnWifiUsabilityStatsListener}.
-     * Multiple listeners can be added. Callers will be invoked periodically by framework to
-     * inform clients about the current Wi-Fi usability statistics. Callers can remove a previously
-     * added listener using {@link removeOnWifiUsabilityStatsListener}.
-     *
-     * @param executor The executor on which callback will be invoked.
-     * @param listener Listener for Wifi usability statistics.
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE)
-    public void addOnWifiUsabilityStatsListener(@NonNull @CallbackExecutor Executor executor,
-            @NonNull OnWifiUsabilityStatsListener listener) {
-        if (executor == null) throw new IllegalArgumentException("executor cannot be null");
-        if (listener == null) throw new IllegalArgumentException("listener cannot be null");
-        if (mVerboseLoggingEnabled) {
-            Log.v(TAG, "addOnWifiUsabilityStatsListener: listener=" + listener);
-        }
-        try {
-            mService.addOnWifiUsabilityStatsListener(new Binder(),
-                    new IOnWifiUsabilityStatsListener.Stub() {
-                        @Override
-                        public void onWifiUsabilityStats(int seqNum, boolean isSameBssidAndFreq,
-                                WifiUsabilityStatsEntry stats) {
-                            if (mVerboseLoggingEnabled) {
-                                Log.v(TAG, "OnWifiUsabilityStatsListener: "
-                                        + "onWifiUsabilityStats: seqNum=" + seqNum);
-                            }
-                            Binder.clearCallingIdentity();
-                            executor.execute(() -> listener.onWifiUsabilityStats(
-                                    seqNum, isSameBssidAndFreq, stats));
-                        }
-                    },
-                    listener.hashCode()
-            );
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Allow callers to remove a previously registered listener. After calling this method,
-     * applications will no longer receive Wi-Fi usability statistics.
-     *
-     * @param listener Listener to remove the Wi-Fi usability statistics.
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE)
-    public void removeOnWifiUsabilityStatsListener(@NonNull OnWifiUsabilityStatsListener listener) {
-        if (listener == null) throw new IllegalArgumentException("listener cannot be null");
-        if (mVerboseLoggingEnabled) {
-            Log.v(TAG, "removeOnWifiUsabilityStatsListener: listener=" + listener);
-        }
-        try {
-            mService.removeOnWifiUsabilityStatsListener(listener.hashCode());
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Provide a Wi-Fi usability score information to be recorded (but not acted upon) by the
-     * framework. The Wi-Fi usability score is derived from {@link OnWifiUsabilityStatsListener}
-     * where a score is matched to Wi-Fi usability statistics using the sequence number. The score
-     * is used to quantify whether Wi-Fi is usable in a future time.
-     *
-     * @param seqNum Sequence number of the Wi-Fi usability score.
-     * @param score The Wi-Fi usability score, expected range: [0, 100].
-     * @param predictionHorizonSec Prediction horizon of the Wi-Fi usability score in second,
-     *                             expected range: [0, 30].
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE)
-    public void updateWifiUsabilityScore(int seqNum, int score, int predictionHorizonSec) {
-        try {
-            mService.updateWifiUsabilityScore(seqNum, score, predictionHorizonSec);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Abstract class for scan results callback. Should be extended by applications and set when
-     * calling {@link WifiManager#registerScanResultsCallback(Executor, ScanResultsCallback)}.
-     */
-    public abstract static class ScanResultsCallback {
-        private final ScanResultsCallbackProxy mScanResultsCallbackProxy;
-
-        public ScanResultsCallback() {
-            mScanResultsCallbackProxy = new ScanResultsCallbackProxy();
-        }
-
-        /**
-         * Called when new scan results are available.
-         * Clients should use {@link WifiManager#getScanResults()} to get the scan results.
-         */
-        public abstract void onScanResultsAvailable();
-
-        /*package*/ @NonNull ScanResultsCallbackProxy getProxy() {
-            return mScanResultsCallbackProxy;
-        }
-
-        private static class ScanResultsCallbackProxy extends IScanResultsCallback.Stub {
-            private final Object mLock = new Object();
-            @Nullable @GuardedBy("mLock") private Executor mExecutor;
-            @Nullable @GuardedBy("mLock") private ScanResultsCallback mCallback;
-
-            ScanResultsCallbackProxy() {
-                mCallback = null;
-                mExecutor = null;
-            }
-
-            /*package*/ void initProxy(@NonNull Executor executor,
-                    @NonNull ScanResultsCallback callback) {
-                synchronized (mLock) {
-                    mExecutor = executor;
-                    mCallback = callback;
-                }
-            }
-
-            /*package*/ void cleanUpProxy() {
-                synchronized (mLock) {
-                    mExecutor = null;
-                    mCallback = null;
-                }
-            }
-
-            @Override
-            public void onScanResultsAvailable() {
-                ScanResultsCallback callback;
-                Executor executor;
-                synchronized (mLock) {
-                    executor = mExecutor;
-                    callback = mCallback;
-                }
-                if (callback == null || executor == null) {
-                    return;
-                }
-                Binder.clearCallingIdentity();
-                executor.execute(callback::onScanResultsAvailable);
-            }
-        }
-
-    }
-
-    /**
-     * Register a callback for Scan Results. See {@link ScanResultsCallback}.
-     * Caller will receive the event when scan results are available.
-     * Caller should use {@link WifiManager#getScanResults()} requires
-     * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} to get the scan results.
-     * Caller can remove a previously registered callback using
-     * {@link WifiManager#unregisterScanResultsCallback(ScanResultsCallback)}
-     * Same caller can add multiple listeners.
-     * <p>
-     * Applications should have the
-     * {@link android.Manifest.permission#ACCESS_WIFI_STATE} permission. Callers
-     * without the permission will trigger a {@link java.lang.SecurityException}.
-     * <p>
-     *
-     * @param executor The executor to execute the callback of the {@code callback} object.
-     * @param callback callback for Scan Results events
-     */
-
-    @RequiresPermission(ACCESS_WIFI_STATE)
-    public void registerScanResultsCallback(@NonNull @CallbackExecutor Executor executor,
-            @NonNull ScanResultsCallback callback) {
-        if (executor == null) throw new IllegalArgumentException("executor cannot be null");
-        if (callback == null) throw new IllegalArgumentException("callback cannot be null");
-
-        Log.v(TAG, "registerScanResultsCallback: callback=" + callback
-                + ", executor=" + executor);
-        ScanResultsCallback.ScanResultsCallbackProxy proxy = callback.getProxy();
-        proxy.initProxy(executor, callback);
-        try {
-            mService.registerScanResultsCallback(proxy);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Allow callers to unregister a previously registered callback. After calling this method,
-     * applications will no longer receive Scan Results events.
-     *
-     * @param callback callback to unregister for Scan Results events
-     */
-    @RequiresPermission(ACCESS_WIFI_STATE)
-    public void unregisterScanResultsCallback(@NonNull ScanResultsCallback callback) {
-        if (callback == null) throw new IllegalArgumentException("callback cannot be null");
-        Log.v(TAG, "unregisterScanResultsCallback: Callback=" + callback);
-        ScanResultsCallback.ScanResultsCallbackProxy proxy = callback.getProxy();
-        try {
-            mService.unregisterScanResultsCallback(proxy);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        } finally {
-            proxy.cleanUpProxy();
-        }
-    }
-
-    /**
-     * Interface for suggestion connection status listener.
-     * Should be implemented by applications and set when calling
-     * {@link WifiManager#addSuggestionConnectionStatusListener(
-     * Executor, SuggestionConnectionStatusListener)}.
-     */
-    public interface SuggestionConnectionStatusListener {
-
-        /**
-         * Called when the framework attempted to connect to a suggestion provided by the
-         * registering app, but the connection to the suggestion failed.
-         * @param wifiNetworkSuggestion The suggestion which failed to connect.
-         * @param failureReason the connection failure reason code. One of
-         * {@link #STATUS_SUGGESTION_CONNECTION_FAILURE_ASSOCIATION},
-         * {@link #STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION},
-         * {@link #STATUS_SUGGESTION_CONNECTION_FAILURE_IP_PROVISIONING}
-         * {@link #STATUS_SUGGESTION_CONNECTION_FAILURE_UNKNOWN}
-         */
-        void onConnectionStatus(
-                @NonNull WifiNetworkSuggestion wifiNetworkSuggestion,
-                @SuggestionConnectionStatusCode int failureReason);
-    }
-
-    private class SuggestionConnectionStatusListenerProxy extends
-            ISuggestionConnectionStatusListener.Stub {
-        private final Executor mExecutor;
-        private final SuggestionConnectionStatusListener mListener;
-
-        SuggestionConnectionStatusListenerProxy(@NonNull Executor executor,
-                @NonNull SuggestionConnectionStatusListener listener) {
-            mExecutor = executor;
-            mListener = listener;
-        }
-
-        @Override
-        public void onConnectionStatus(@NonNull WifiNetworkSuggestion wifiNetworkSuggestion,
-                int failureReason) {
-            mExecutor.execute(() ->
-                    mListener.onConnectionStatus(wifiNetworkSuggestion, failureReason));
-        }
-
-    }
-
-    /**
-     * Add a listener for suggestion networks. See {@link SuggestionConnectionStatusListener}.
-     * Caller will receive the event when suggested network have connection failure.
-     * Caller can remove a previously registered listener using
-     * {@link WifiManager#removeSuggestionConnectionStatusListener(
-     * SuggestionConnectionStatusListener)}
-     * Same caller can add multiple listeners to monitor the event.
-     * <p>
-     * Applications should have the
-     * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} and
-     * {@link android.Manifest.permission#ACCESS_WIFI_STATE} permissions.
-     * Callers without the permission will trigger a {@link java.lang.SecurityException}.
-     * <p>
-     *
-     * @param executor The executor to execute the listener of the {@code listener} object.
-     * @param listener listener for suggestion network connection failure.
-     */
-    @RequiresPermission(allOf = {ACCESS_FINE_LOCATION, ACCESS_WIFI_STATE})
-    public void addSuggestionConnectionStatusListener(@NonNull @CallbackExecutor Executor executor,
-            @NonNull SuggestionConnectionStatusListener listener) {
-        if (listener == null) throw new IllegalArgumentException("Listener cannot be null");
-        if (executor == null) throw new IllegalArgumentException("Executor cannot be null");
-        Log.v(TAG, "addSuggestionConnectionStatusListener listener=" + listener
-                + ", executor=" + executor);
-        try {
-            mService.registerSuggestionConnectionStatusListener(new Binder(),
-                    new SuggestionConnectionStatusListenerProxy(executor, listener),
-                    listener.hashCode(), mContext.getOpPackageName(), mContext.getAttributionTag());
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-
-    }
-
-    /**
-     * Allow callers to remove a previously registered listener. After calling this method,
-     * applications will no longer receive suggestion connection events through that listener.
-     *
-     * @param listener listener to remove.
-     */
-    @RequiresPermission(ACCESS_WIFI_STATE)
-    public void removeSuggestionConnectionStatusListener(
-            @NonNull SuggestionConnectionStatusListener listener) {
-        if (listener == null) throw new IllegalArgumentException("Listener cannot be null");
-        Log.v(TAG, "removeSuggestionConnectionStatusListener: listener=" + listener);
-        try {
-            mService.unregisterSuggestionConnectionStatusListener(listener.hashCode(),
-                    mContext.getOpPackageName());
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Parse the list of channels the DPP enrollee reports when it fails to find an AP.
-     *
-     * @param channelList List of channels in the format defined in the DPP specification.
-     * @return A parsed sparse array, where the operating class is the key.
-     * @hide
-     */
-    @VisibleForTesting
-    public static SparseArray<int[]> parseDppChannelList(String channelList) {
-        SparseArray<int[]> channelListArray = new SparseArray<>();
-
-        if (TextUtils.isEmpty(channelList)) {
-            return channelListArray;
-        }
-        StringTokenizer str = new StringTokenizer(channelList, ",");
-        String classStr = null;
-        List<Integer> channelsInClass = new ArrayList<>();
-
-        try {
-            while (str.hasMoreElements()) {
-                String cur = str.nextToken();
-
-                /**
-                 * Example for a channel list:
-                 *
-                 * 81/1,2,3,4,5,6,7,8,9,10,11,115/36,40,44,48,118/52,56,60,64,121/100,104,108,112,
-                 * 116,120,124,128,132,136,140,0/144,124/149,153,157,161,125/165
-                 *
-                 * Detect operating class by the delimiter of '/' and use a string tokenizer with
-                 * ',' as a delimiter.
-                 */
-                int classDelim = cur.indexOf('/');
-                if (classDelim != -1) {
-                    if (classStr != null) {
-                        // Store the last channel array in the sparse array, where the operating
-                        // class is the key (as an integer).
-                        int[] channelsArray = new int[channelsInClass.size()];
-                        for (int i = 0; i < channelsInClass.size(); i++) {
-                            channelsArray[i] = channelsInClass.get(i);
-                        }
-                        channelListArray.append(Integer.parseInt(classStr), channelsArray);
-                        channelsInClass = new ArrayList<>();
-                    }
-
-                    // Init a new operating class and store the first channel
-                    classStr = cur.substring(0, classDelim);
-                    String channelStr = cur.substring(classDelim + 1);
-                    channelsInClass.add(Integer.parseInt(channelStr));
-                } else {
-                    if (classStr == null) {
-                        // Invalid format
-                        Log.e(TAG, "Cannot parse DPP channel list");
-                        return new SparseArray<>();
-                    }
-                    channelsInClass.add(Integer.parseInt(cur));
-                }
-            }
-
-            // Store the last array
-            if (classStr != null) {
-                int[] channelsArray = new int[channelsInClass.size()];
-                for (int i = 0; i < channelsInClass.size(); i++) {
-                    channelsArray[i] = channelsInClass.get(i);
-                }
-                channelListArray.append(Integer.parseInt(classStr), channelsArray);
-            }
-            return channelListArray;
-        } catch (NumberFormatException e) {
-            Log.e(TAG, "Cannot parse DPP channel list");
-            return new SparseArray<>();
-        }
-    }
-
-    /**
-     * Callback interface for framework to receive network status updates and trigger of updating
-     * {@link WifiUsabilityStatsEntry}.
-     *
-     * @hide
-     */
-    @SystemApi
-    public interface ScoreUpdateObserver {
-        /**
-         * Called by applications to indicate network status.
-         *
-         * @param sessionId The ID to indicate current Wi-Fi network connection obtained from
-         *                  {@link WifiConnectedNetworkScorer#onStart(int)}.
-         * @param score The score representing link quality of current Wi-Fi network connection.
-         *              Populated by connected network scorer in applications..
-         */
-        void notifyScoreUpdate(int sessionId, int score);
-
-        /**
-         * Called by applications to trigger an update of {@link WifiUsabilityStatsEntry}.
-         * To receive update applications need to add WifiUsabilityStatsEntry listener. See
-         * {@link addOnWifiUsabilityStatsListener(Executor, OnWifiUsabilityStatsListener)}.
-         *
-         * @param sessionId The ID to indicate current Wi-Fi network connection obtained from
-         *                  {@link WifiConnectedNetworkScorer#onStart(int)}.
-         */
-        void triggerUpdateOfWifiUsabilityStats(int sessionId);
-    }
-
-    /**
-     * Callback proxy for {@link ScoreUpdateObserver} objects.
-     *
-     * @hide
-     */
-    private class ScoreUpdateObserverProxy implements ScoreUpdateObserver {
-        private final IScoreUpdateObserver mScoreUpdateObserver;
-
-        private ScoreUpdateObserverProxy(IScoreUpdateObserver observer) {
-            mScoreUpdateObserver = observer;
-        }
-
-        @Override
-        public void notifyScoreUpdate(int sessionId, int score) {
-            try {
-                mScoreUpdateObserver.notifyScoreUpdate(sessionId, score);
-            } catch (RemoteException e) {
-                throw e.rethrowFromSystemServer();
-            }
-        }
-
-        @Override
-        public void triggerUpdateOfWifiUsabilityStats(int sessionId) {
-            try {
-                mScoreUpdateObserver.triggerUpdateOfWifiUsabilityStats(sessionId);
-            } catch (RemoteException e) {
-                throw e.rethrowFromSystemServer();
-            }
-        }
-    }
-
-    /**
-     * Interface for Wi-Fi connected network scorer. Should be implemented by applications and set
-     * when calling
-     * {@link WifiManager#setWifiConnectedNetworkScorer(Executor, WifiConnectedNetworkScorer)}.
-     *
-     * @hide
-     */
-    @SystemApi
-    public interface WifiConnectedNetworkScorer {
-        /**
-         * Called by framework to indicate the start of a network connection.
-         * @param sessionId The ID to indicate current Wi-Fi network connection.
-         */
-        void onStart(int sessionId);
-
-        /**
-         * Called by framework to indicate the end of a network connection.
-         * @param sessionId The ID to indicate current Wi-Fi network connection obtained from
-         *                  {@link WifiConnectedNetworkScorer#onStart(int)}.
-         */
-        void onStop(int sessionId);
-
-        /**
-         * Framework sets callback for score change events after application sets its scorer.
-         * @param observerImpl The instance for {@link WifiManager#ScoreUpdateObserver}. Should be
-         * implemented and instantiated by framework.
-         */
-        void onSetScoreUpdateObserver(@NonNull ScoreUpdateObserver observerImpl);
-    }
-
-    /**
-     * Callback proxy for {@link WifiConnectedNetworkScorer} objects.
-     *
-     * @hide
-     */
-    private class WifiConnectedNetworkScorerProxy extends IWifiConnectedNetworkScorer.Stub {
-        private Executor mExecutor;
-        private WifiConnectedNetworkScorer mScorer;
-
-        WifiConnectedNetworkScorerProxy(Executor executor, WifiConnectedNetworkScorer scorer) {
-            mExecutor = executor;
-            mScorer = scorer;
-        }
-
-        @Override
-        public void onStart(int sessionId) {
-            if (mVerboseLoggingEnabled) {
-                Log.v(TAG, "WifiConnectedNetworkScorer: " + "onStart: sessionId=" + sessionId);
-            }
-            Binder.clearCallingIdentity();
-            mExecutor.execute(() -> mScorer.onStart(sessionId));
-        }
-
-        @Override
-        public void onStop(int sessionId) {
-            if (mVerboseLoggingEnabled) {
-                Log.v(TAG, "WifiConnectedNetworkScorer: " + "onStop: sessionId=" + sessionId);
-            }
-            Binder.clearCallingIdentity();
-            mExecutor.execute(() -> mScorer.onStop(sessionId));
-        }
-
-        @Override
-        public void onSetScoreUpdateObserver(IScoreUpdateObserver observerImpl) {
-            if (mVerboseLoggingEnabled) {
-                Log.v(TAG, "WifiConnectedNetworkScorer: "
-                        + "onSetScoreUpdateObserver: observerImpl=" + observerImpl);
-            }
-            Binder.clearCallingIdentity();
-            mExecutor.execute(() -> mScorer.onSetScoreUpdateObserver(
-                    new ScoreUpdateObserverProxy(observerImpl)));
-        }
-    }
-
-    /**
-     * Set a callback for Wi-Fi connected network scorer.  See {@link WifiConnectedNetworkScorer}.
-     * Only a single scorer can be set. Caller will be invoked periodically by framework to inform
-     * client about start and stop of Wi-Fi connection. Caller can clear a previously set scorer
-     * using {@link clearWifiConnectedNetworkScorer()}.
-     *
-     * @param executor The executor on which callback will be invoked.
-     * @param scorer Scorer for Wi-Fi network implemented by application.
-     * @return true Scorer is set successfully.
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE)
-    public boolean setWifiConnectedNetworkScorer(@NonNull @CallbackExecutor Executor executor,
-            @NonNull WifiConnectedNetworkScorer scorer) {
-        if (executor == null) throw new IllegalArgumentException("executor cannot be null");
-        if (scorer == null) throw new IllegalArgumentException("scorer cannot be null");
-        if (mVerboseLoggingEnabled) {
-            Log.v(TAG, "setWifiConnectedNetworkScorer: scorer=" + scorer);
-        }
-        try {
-            return mService.setWifiConnectedNetworkScorer(new Binder(),
-                    new WifiConnectedNetworkScorerProxy(executor, scorer));
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Allow caller to clear a previously set scorer. After calling this method,
-     * client will no longer receive information about start and stop of Wi-Fi connection.
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE)
-    public void clearWifiConnectedNetworkScorer() {
-        if (mVerboseLoggingEnabled) {
-            Log.v(TAG, "clearWifiConnectedNetworkScorer");
-        }
-        try {
-            mService.clearWifiConnectedNetworkScorer();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Enable/disable wifi scan throttling from 3rd party apps.
-     *
-     * <p>
-     * The throttling limits for apps are described in
-     * <a href="Wi-Fi Scan Throttling">
-     * https://developer.android.com/guide/topics/connectivity/wifi-scan#wifi-scan-throttling</a>
-     * </p>
-     *
-     * @param enable true to allow scan throttling, false to disallow scan throttling.
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public void setScanThrottleEnabled(boolean enable) {
-        try {
-            mService.setScanThrottleEnabled(enable);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Get the persisted Wi-Fi scan throttle state. Defaults to true, unless changed by the user via
-     * Developer options.
-     *
-     * <p>
-     * The throttling limits for apps are described in
-     * <a href="Wi-Fi Scan Throttling">
-     * https://developer.android.com/guide/topics/connectivity/wifi-scan#wifi-scan-throttling</a>
-     * </p>
-     *
-     * @return true to indicate that scan throttling is enabled, false to indicate that scan
-     * throttling is disabled.
-     */
-    @RequiresPermission(ACCESS_WIFI_STATE)
-    public boolean isScanThrottleEnabled() {
-        try {
-            return mService.isScanThrottleEnabled();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Enable/disable wifi auto wakeup feature.
-     *
-     * <p>
-     * The feature is described in
-     * <a href="Wi-Fi Turn on automatically">
-     * https://source.android.com/devices/tech/connect/wifi-infrastructure
-     * #turn_on_wi-fi_automatically
-     * </a>
-     *
-     * @param enable true to enable, false to disable.
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public void setAutoWakeupEnabled(boolean enable) {
-        try {
-            mService.setAutoWakeupEnabled(enable);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Get the persisted Wi-Fi auto wakeup feature state. Defaults to false, unless changed by the
-     * user via Settings.
-     *
-     * <p>
-     * The feature is described in
-     * <a href="Wi-Fi Turn on automatically">
-     * https://source.android.com/devices/tech/connect/wifi-infrastructure
-     * #turn_on_wi-fi_automatically
-     * </a>
-     *
-     * @return true to indicate that wakeup feature is enabled, false to indicate that wakeup
-     * feature is disabled.
-     */
-    @RequiresPermission(ACCESS_WIFI_STATE)
-    public boolean isAutoWakeupEnabled() {
-        try {
-            return mService.isAutoWakeupEnabled();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-}
diff --git a/wifi/java/android/net/wifi/WifiNetworkAgentSpecifier.java b/wifi/java/android/net/wifi/WifiNetworkAgentSpecifier.java
deleted file mode 100644
index 0d13805..0000000
--- a/wifi/java/android/net/wifi/WifiNetworkAgentSpecifier.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import static com.android.internal.util.Preconditions.checkNotNull;
-import static com.android.internal.util.Preconditions.checkState;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.MacAddress;
-import android.net.MatchAllNetworkSpecifier;
-import android.net.NetworkRequest;
-import android.net.NetworkSpecifier;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.Objects;
-
-/**
- * Network specifier object used by wifi's {@link android.net.NetworkAgent}.
- * @hide
- */
-public final class WifiNetworkAgentSpecifier extends NetworkSpecifier implements Parcelable {
-    /**
-     * Security credentials for the currently connected network.
-     */
-    private final WifiConfiguration mWifiConfiguration;
-
-    public WifiNetworkAgentSpecifier(@NonNull WifiConfiguration wifiConfiguration) {
-        checkNotNull(wifiConfiguration);
-
-        mWifiConfiguration = wifiConfiguration;
-    }
-
-    /**
-     * @hide
-     */
-    public static final @android.annotation.NonNull Creator<WifiNetworkAgentSpecifier> CREATOR =
-            new Creator<WifiNetworkAgentSpecifier>() {
-                @Override
-                public WifiNetworkAgentSpecifier createFromParcel(@NonNull Parcel in) {
-                    WifiConfiguration wifiConfiguration = in.readParcelable(null);
-                    return new WifiNetworkAgentSpecifier(wifiConfiguration);
-                }
-
-                @Override
-                public WifiNetworkAgentSpecifier[] newArray(int size) {
-                    return new WifiNetworkAgentSpecifier[size];
-                }
-            };
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeParcelable(mWifiConfiguration, flags);
-    }
-
-    @Override
-    public boolean canBeSatisfiedBy(@Nullable NetworkSpecifier other) {
-        if (this == other) {
-            return true;
-        }
-        // Any generic requests should be satisifed by a specific wifi network.
-        if (other == null || other instanceof MatchAllNetworkSpecifier) {
-            return true;
-        }
-        if (other instanceof WifiNetworkSpecifier) {
-            return satisfiesNetworkSpecifier((WifiNetworkSpecifier) other);
-        }
-        return equals(other);
-    }
-
-    /**
-     * Match {@link WifiNetworkSpecifier} in app's {@link NetworkRequest} with the
-     * {@link WifiNetworkAgentSpecifier} in wifi platform's {@link android.net.NetworkAgent}.
-     */
-    public boolean satisfiesNetworkSpecifier(@NonNull WifiNetworkSpecifier ns) {
-        // None of these should be null by construction.
-        // {@link WifiNetworkSpecifier.Builder} enforces non-null in {@link WifiNetworkSpecifier}.
-        // {@link WifiNetworkFactory} ensures non-null in {@link WifiNetworkAgentSpecifier}.
-        checkNotNull(ns);
-        checkNotNull(ns.ssidPatternMatcher);
-        checkNotNull(ns.bssidPatternMatcher);
-        checkNotNull(ns.wifiConfiguration.allowedKeyManagement);
-        checkNotNull(this.mWifiConfiguration.SSID);
-        checkNotNull(this.mWifiConfiguration.BSSID);
-        checkNotNull(this.mWifiConfiguration.allowedKeyManagement);
-
-        final String ssidWithQuotes = this.mWifiConfiguration.SSID;
-        checkState(ssidWithQuotes.startsWith("\"") && ssidWithQuotes.endsWith("\""));
-        final String ssidWithoutQuotes = ssidWithQuotes.substring(1, ssidWithQuotes.length() - 1);
-        if (!ns.ssidPatternMatcher.match(ssidWithoutQuotes)) {
-            return false;
-        }
-        final MacAddress bssid = MacAddress.fromString(this.mWifiConfiguration.BSSID);
-        final MacAddress matchBaseAddress = ns.bssidPatternMatcher.first;
-        final MacAddress matchMask = ns.bssidPatternMatcher.second;
-        if (!bssid.matches(matchBaseAddress, matchMask))  {
-            return false;
-        }
-        if (!ns.wifiConfiguration.allowedKeyManagement.equals(
-                this.mWifiConfiguration.allowedKeyManagement)) {
-            return false;
-        }
-        return true;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(
-                mWifiConfiguration.SSID,
-                mWifiConfiguration.BSSID,
-                mWifiConfiguration.allowedKeyManagement);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (!(obj instanceof WifiNetworkAgentSpecifier)) {
-            return false;
-        }
-        WifiNetworkAgentSpecifier lhs = (WifiNetworkAgentSpecifier) obj;
-        return Objects.equals(this.mWifiConfiguration.SSID, lhs.mWifiConfiguration.SSID)
-                && Objects.equals(this.mWifiConfiguration.BSSID, lhs.mWifiConfiguration.BSSID)
-                && Objects.equals(this.mWifiConfiguration.allowedKeyManagement,
-                    lhs.mWifiConfiguration.allowedKeyManagement);
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder("WifiNetworkAgentSpecifier [");
-        sb.append("WifiConfiguration=")
-                .append(", SSID=").append(mWifiConfiguration.SSID)
-                .append(", BSSID=").append(mWifiConfiguration.BSSID)
-                .append("]");
-        return sb.toString();
-    }
-
-    @Override
-    public NetworkSpecifier redact() {
-        return null;
-    }
-}
diff --git a/wifi/java/android/net/wifi/WifiNetworkConnectionStatistics.java b/wifi/java/android/net/wifi/WifiNetworkConnectionStatistics.java
deleted file mode 100644
index 95b2e77..0000000
--- a/wifi/java/android/net/wifi/WifiNetworkConnectionStatistics.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Connection Statistics For a WiFi Network.
- * @hide
- */
-@SystemApi
-public class WifiNetworkConnectionStatistics implements Parcelable {
-    private static final String TAG = "WifiNetworkConnnectionStatistics";
-
-    public int numConnection;
-    public int numUsage;
-
-    public WifiNetworkConnectionStatistics(int connection, int usage) {
-        numConnection = connection;
-        numUsage = usage;
-    }
-
-    public WifiNetworkConnectionStatistics() { }
-
-    @NonNull
-    @Override
-    public String toString() {
-        StringBuilder sbuf = new StringBuilder();
-        sbuf.append("c=").append(numConnection);
-        sbuf.append(" u=").append(numUsage);
-        return sbuf.toString();
-    }
-
-
-    /** copy constructor*/
-    public WifiNetworkConnectionStatistics(WifiNetworkConnectionStatistics source) {
-        numConnection = source.numConnection;
-        numUsage = source.numUsage;
-    }
-
-    /** Implement the Parcelable interface */
-    public int describeContents() {
-        return 0;
-    }
-
-    /** Implement the Parcelable interface */
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(numConnection);
-        dest.writeInt(numUsage);
-    }
-
-    /** Implement the Parcelable interface */
-    public static final @android.annotation.NonNull Creator<WifiNetworkConnectionStatistics> CREATOR =
-        new Creator<WifiNetworkConnectionStatistics>() {
-            public WifiNetworkConnectionStatistics createFromParcel(Parcel in) {
-                int numConnection = in.readInt();
-                int numUsage = in.readInt();
-                WifiNetworkConnectionStatistics stats =
-                        new WifiNetworkConnectionStatistics(numConnection, numUsage);
-                return stats;
-            }
-
-            public WifiNetworkConnectionStatistics[] newArray(int size) {
-                return new WifiNetworkConnectionStatistics[size];
-            }
-        };
-}
diff --git a/wifi/java/android/net/wifi/WifiNetworkSpecifier.java b/wifi/java/android/net/wifi/WifiNetworkSpecifier.java
deleted file mode 100644
index e12bb91..0000000
--- a/wifi/java/android/net/wifi/WifiNetworkSpecifier.java
+++ /dev/null
@@ -1,584 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import static com.android.internal.util.Preconditions.checkNotNull;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.MacAddress;
-import android.net.NetworkRequest;
-import android.net.NetworkSpecifier;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.PatternMatcher;
-import android.text.TextUtils;
-import android.util.Pair;
-
-import java.nio.charset.CharsetEncoder;
-import java.nio.charset.StandardCharsets;
-import java.util.Objects;
-
-/**
- * Network specifier object used to request a local Wi-Fi network. Apps should use the
- * {@link WifiNetworkSpecifier.Builder} class to create an instance.
- */
-public final class WifiNetworkSpecifier extends NetworkSpecifier implements Parcelable {
-    private static final String TAG = "WifiNetworkSpecifier";
-
-    /**
-     * Builder used to create {@link WifiNetworkSpecifier} objects.
-     */
-    public static final class Builder {
-        private static final String MATCH_ALL_SSID_PATTERN_PATH = ".*";
-        private static final String MATCH_EMPTY_SSID_PATTERN_PATH = "";
-        private static final Pair<MacAddress, MacAddress> MATCH_NO_BSSID_PATTERN1 =
-                new Pair<>(MacAddress.BROADCAST_ADDRESS, MacAddress.BROADCAST_ADDRESS);
-        private static final Pair<MacAddress, MacAddress> MATCH_NO_BSSID_PATTERN2 =
-                new Pair<>(WifiManager.ALL_ZEROS_MAC_ADDRESS, MacAddress.BROADCAST_ADDRESS);
-        private static final Pair<MacAddress, MacAddress> MATCH_ALL_BSSID_PATTERN =
-                new Pair<>(WifiManager.ALL_ZEROS_MAC_ADDRESS, WifiManager.ALL_ZEROS_MAC_ADDRESS);
-        private static final MacAddress MATCH_EXACT_BSSID_PATTERN_MASK =
-                MacAddress.BROADCAST_ADDRESS;
-
-        /**
-         * SSID pattern match specified by the app.
-         */
-        private @Nullable PatternMatcher mSsidPatternMatcher;
-        /**
-         * BSSID pattern match specified by the app.
-         * Pair of <BaseAddress, Mask>.
-         */
-        private @Nullable Pair<MacAddress, MacAddress> mBssidPatternMatcher;
-        /**
-         * Whether this is an OWE network or not.
-         */
-        private boolean mIsEnhancedOpen;
-        /**
-         * Pre-shared key for use with WPA-PSK networks.
-         */
-        private @Nullable String mWpa2PskPassphrase;
-        /**
-         * Pre-shared key for use with WPA3-SAE networks.
-         */
-        private @Nullable String mWpa3SaePassphrase;
-        /**
-         * The enterprise configuration details specifying the EAP method,
-         * certificates and other settings associated with the WPA/WPA2-Enterprise networks.
-         */
-        private @Nullable WifiEnterpriseConfig mWpa2EnterpriseConfig;
-        /**
-         * The enterprise configuration details specifying the EAP method,
-         * certificates and other settings associated with the WPA3-Enterprise networks.
-         */
-        private @Nullable WifiEnterpriseConfig mWpa3EnterpriseConfig;
-        /**
-         * This is a network that does not broadcast its SSID, so an
-         * SSID-specific probe request must be used for scans.
-         */
-        private boolean mIsHiddenSSID;
-
-        public Builder() {
-            mSsidPatternMatcher = null;
-            mBssidPatternMatcher = null;
-            mIsEnhancedOpen = false;
-            mWpa2PskPassphrase = null;
-            mWpa3SaePassphrase = null;
-            mWpa2EnterpriseConfig = null;
-            mWpa3EnterpriseConfig = null;
-            mIsHiddenSSID = false;
-        }
-
-        /**
-         * Set the unicode SSID match pattern to use for filtering networks from scan results.
-         * <p>
-         * <li>Overrides any previous value set using {@link #setSsid(String)} or
-         * {@link #setSsidPattern(PatternMatcher)}.</li>
-         *
-         * @param ssidPattern Instance of {@link PatternMatcher} containing the UTF-8 encoded
-         *                    string pattern to use for matching the network's SSID.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         */
-        public @NonNull Builder setSsidPattern(@NonNull PatternMatcher ssidPattern) {
-            checkNotNull(ssidPattern);
-            mSsidPatternMatcher = ssidPattern;
-            return this;
-        }
-
-        /**
-         * Set the unicode SSID for the network.
-         * <p>
-         * <li>Sets the SSID to use for filtering networks from scan results. Will only match
-         * networks whose SSID is identical to the UTF-8 encoding of the specified value.</li>
-         * <li>Overrides any previous value set using {@link #setSsid(String)} or
-         * {@link #setSsidPattern(PatternMatcher)}.</li>
-         *
-         * @param ssid The SSID of the network. It must be valid Unicode.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         * @throws IllegalArgumentException if the SSID is not valid unicode.
-         */
-        public @NonNull Builder setSsid(@NonNull String ssid) {
-            checkNotNull(ssid);
-            final CharsetEncoder unicodeEncoder = StandardCharsets.UTF_8.newEncoder();
-            if (!unicodeEncoder.canEncode(ssid)) {
-                throw new IllegalArgumentException("SSID is not a valid unicode string");
-            }
-            mSsidPatternMatcher = new PatternMatcher(ssid, PatternMatcher.PATTERN_LITERAL);
-            return this;
-        }
-
-        /**
-         * Set the BSSID match pattern to use for filtering networks from scan results.
-         * Will match all networks with BSSID which satisfies the following:
-         * {@code BSSID & mask == baseAddress}.
-         * <p>
-         * <li>Overrides any previous value set using {@link #setBssid(MacAddress)} or
-         * {@link #setBssidPattern(MacAddress, MacAddress)}.</li>
-         *
-         * @param baseAddress Base address for BSSID pattern.
-         * @param mask Mask for BSSID pattern.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         */
-        public @NonNull Builder setBssidPattern(
-                @NonNull MacAddress baseAddress, @NonNull MacAddress mask) {
-            checkNotNull(baseAddress);
-            checkNotNull(mask);
-            mBssidPatternMatcher = Pair.create(baseAddress, mask);
-            return this;
-        }
-
-        /**
-         * Set the BSSID to use for filtering networks from scan results. Will only match network
-         * whose BSSID is identical to the specified value.
-         * <p>
-         * <li>Sets the BSSID to use for filtering networks from scan results. Will only match
-         * networks whose BSSID is identical to specified value.</li>
-         * <li>Overrides any previous value set using {@link #setBssid(MacAddress)} or
-         * {@link #setBssidPattern(MacAddress, MacAddress)}.</li>
-         *
-         * @param bssid BSSID of the network.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         */
-        public @NonNull Builder setBssid(@NonNull MacAddress bssid) {
-            checkNotNull(bssid);
-            mBssidPatternMatcher = Pair.create(bssid, MATCH_EXACT_BSSID_PATTERN_MASK);
-            return this;
-        }
-
-        /**
-         * Specifies whether this represents an Enhanced Open (OWE) network.
-         *
-         * @param isEnhancedOpen {@code true} to indicate that the network uses enhanced open,
-         *                       {@code false} otherwise.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         */
-        public @NonNull Builder setIsEnhancedOpen(boolean isEnhancedOpen) {
-            mIsEnhancedOpen = isEnhancedOpen;
-            return this;
-        }
-
-        /**
-         * Set the ASCII WPA2 passphrase for this network. Needed for authenticating to
-         * WPA2-PSK networks.
-         *
-         * @param passphrase passphrase of the network.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         * @throws IllegalArgumentException if the passphrase is not ASCII encodable.
-         */
-        public @NonNull Builder setWpa2Passphrase(@NonNull String passphrase) {
-            checkNotNull(passphrase);
-            final CharsetEncoder asciiEncoder = StandardCharsets.US_ASCII.newEncoder();
-            if (!asciiEncoder.canEncode(passphrase)) {
-                throw new IllegalArgumentException("passphrase not ASCII encodable");
-            }
-            mWpa2PskPassphrase = passphrase;
-            return this;
-        }
-
-        /**
-         * Set the ASCII WPA3 passphrase for this network. Needed for authenticating to WPA3-SAE
-         * networks.
-         *
-         * @param passphrase passphrase of the network.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         * @throws IllegalArgumentException if the passphrase is not ASCII encodable.
-         */
-        public @NonNull Builder setWpa3Passphrase(@NonNull String passphrase) {
-            checkNotNull(passphrase);
-            final CharsetEncoder asciiEncoder = StandardCharsets.US_ASCII.newEncoder();
-            if (!asciiEncoder.canEncode(passphrase)) {
-                throw new IllegalArgumentException("passphrase not ASCII encodable");
-            }
-            mWpa3SaePassphrase = passphrase;
-            return this;
-        }
-
-        /**
-         * Set the associated enterprise configuration for this network. Needed for authenticating
-         * to WPA2-EAP networks. See {@link WifiEnterpriseConfig} for description.
-         *
-         * @param enterpriseConfig Instance of {@link WifiEnterpriseConfig}.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         */
-        public @NonNull Builder setWpa2EnterpriseConfig(
-                @NonNull WifiEnterpriseConfig enterpriseConfig) {
-            checkNotNull(enterpriseConfig);
-            mWpa2EnterpriseConfig = new WifiEnterpriseConfig(enterpriseConfig);
-            return this;
-        }
-
-        /**
-         * Set the associated enterprise configuration for this network. Needed for authenticating
-         * to WPA3-Enterprise networks (standard and 192-bit security). See
-         * {@link WifiEnterpriseConfig} for description. For 192-bit security networks, both the
-         * client and CA certificates must be provided, and must be of type of either
-         * sha384WithRSAEncryption (OID 1.2.840.113549.1.1.12) or ecdsa-with-SHA384
-         * (OID 1.2.840.10045.4.3.3).
-         *
-         * @param enterpriseConfig Instance of {@link WifiEnterpriseConfig}.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         */
-        public @NonNull Builder setWpa3EnterpriseConfig(
-                @NonNull WifiEnterpriseConfig enterpriseConfig) {
-            checkNotNull(enterpriseConfig);
-            mWpa3EnterpriseConfig = new WifiEnterpriseConfig(enterpriseConfig);
-            return this;
-        }
-
-        /**
-         * Specifies whether this represents a hidden network.
-         * <p>
-         * <li>Setting this disallows the usage of {@link #setSsidPattern(PatternMatcher)} since
-         * hidden networks need to be explicitly probed for.</li>
-         * <li>If not set, defaults to false (i.e not a hidden network).</li>
-         *
-         * @param isHiddenSsid {@code true} to indicate that the network is hidden, {@code false}
-         *                     otherwise.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         */
-        public @NonNull Builder setIsHiddenSsid(boolean isHiddenSsid) {
-            mIsHiddenSSID = isHiddenSsid;
-            return this;
-        }
-
-        private void setSecurityParamsInWifiConfiguration(
-                @NonNull WifiConfiguration configuration) {
-            if (!TextUtils.isEmpty(mWpa2PskPassphrase)) { // WPA-PSK network.
-                configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_PSK);
-                // WifiConfiguration.preSharedKey needs quotes around ASCII password.
-                configuration.preSharedKey = "\"" + mWpa2PskPassphrase + "\"";
-            } else if (!TextUtils.isEmpty(mWpa3SaePassphrase)) { // WPA3-SAE network.
-                configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_SAE);
-                // WifiConfiguration.preSharedKey needs quotes around ASCII password.
-                configuration.preSharedKey = "\"" + mWpa3SaePassphrase + "\"";
-            } else if (mWpa2EnterpriseConfig != null) { // WPA-EAP network
-                configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP);
-                configuration.enterpriseConfig = mWpa2EnterpriseConfig;
-            } else if (mWpa3EnterpriseConfig != null) { // WPA3-Enterprise
-                if (mWpa3EnterpriseConfig.getEapMethod() == WifiEnterpriseConfig.Eap.TLS
-                        && WifiEnterpriseConfig.isSuiteBCipherCert(
-                        mWpa3EnterpriseConfig.getClientCertificate())
-                        && WifiEnterpriseConfig.isSuiteBCipherCert(
-                        mWpa3EnterpriseConfig.getCaCertificate())) {
-                    // WPA3-Enterprise in 192-bit security mode (Suite-B)
-                    configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP_SUITE_B);
-                } else {
-                    // WPA3-Enterprise
-                    configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP);
-                    configuration.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
-                    configuration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
-                    configuration.allowedPairwiseCiphers.set(
-                            WifiConfiguration.PairwiseCipher.GCMP_256);
-                    configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
-                    configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_256);
-                    configuration.requirePmf = true;
-                }
-                configuration.enterpriseConfig = mWpa3EnterpriseConfig;
-            } else if (mIsEnhancedOpen) { // OWE network
-                configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_OWE);
-            } else { // Open network
-                configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_OPEN);
-            }
-        }
-
-        /**
-         * Helper method to build WifiConfiguration object from the builder.
-         * @return Instance of {@link WifiConfiguration}.
-         */
-        private WifiConfiguration buildWifiConfiguration() {
-            final WifiConfiguration wifiConfiguration = new WifiConfiguration();
-            // WifiConfiguration.SSID needs quotes around unicode SSID.
-            if (mSsidPatternMatcher.getType() == PatternMatcher.PATTERN_LITERAL) {
-                wifiConfiguration.SSID = "\"" + mSsidPatternMatcher.getPath() + "\"";
-            }
-            if (mBssidPatternMatcher.second == MATCH_EXACT_BSSID_PATTERN_MASK) {
-                wifiConfiguration.BSSID = mBssidPatternMatcher.first.toString();
-            }
-            setSecurityParamsInWifiConfiguration(wifiConfiguration);
-            wifiConfiguration.hiddenSSID = mIsHiddenSSID;
-            return wifiConfiguration;
-        }
-
-        private boolean hasSetAnyPattern() {
-            return mSsidPatternMatcher != null || mBssidPatternMatcher != null;
-        }
-
-        private void setMatchAnyPatternIfUnset() {
-            if (mSsidPatternMatcher == null) {
-                mSsidPatternMatcher = new PatternMatcher(MATCH_ALL_SSID_PATTERN_PATH,
-                        PatternMatcher.PATTERN_SIMPLE_GLOB);
-            }
-            if (mBssidPatternMatcher == null) {
-                mBssidPatternMatcher = MATCH_ALL_BSSID_PATTERN;
-            }
-        }
-
-        private boolean hasSetMatchNonePattern() {
-            if (mSsidPatternMatcher.getType() != PatternMatcher.PATTERN_PREFIX
-                    && mSsidPatternMatcher.getPath().equals(MATCH_EMPTY_SSID_PATTERN_PATH)) {
-                return true;
-            }
-            if (mBssidPatternMatcher.equals(MATCH_NO_BSSID_PATTERN1)) {
-                return true;
-            }
-            if (mBssidPatternMatcher.equals(MATCH_NO_BSSID_PATTERN2)) {
-                return true;
-            }
-            return false;
-        }
-
-        private boolean hasSetMatchAllPattern() {
-            if ((mSsidPatternMatcher.match(MATCH_EMPTY_SSID_PATTERN_PATH))
-                    && mBssidPatternMatcher.equals(MATCH_ALL_BSSID_PATTERN)) {
-                return true;
-            }
-            return false;
-        }
-
-        private void validateSecurityParams() {
-            int numSecurityTypes = 0;
-            numSecurityTypes += mIsEnhancedOpen ? 1 : 0;
-            numSecurityTypes += !TextUtils.isEmpty(mWpa2PskPassphrase) ? 1 : 0;
-            numSecurityTypes += !TextUtils.isEmpty(mWpa3SaePassphrase) ? 1 : 0;
-            numSecurityTypes += mWpa2EnterpriseConfig != null ? 1 : 0;
-            numSecurityTypes += mWpa3EnterpriseConfig != null ? 1 : 0;
-            if (numSecurityTypes > 1) {
-                throw new IllegalStateException("only one of setIsEnhancedOpen, setWpa2Passphrase,"
-                        + "setWpa3Passphrase, setWpa2EnterpriseConfig or setWpa3EnterpriseConfig"
-                        + " can be invoked for network specifier");
-            }
-        }
-
-        /**
-         * Create a specifier object used to request a local Wi-Fi network. The generated
-         * {@link NetworkSpecifier} should be used in
-         * {@link NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} when building
-         * the {@link NetworkRequest}. These specifiers can only be used to request a local wifi
-         * network (i.e no internet capability). So, the device will not switch it's default route
-         * to wifi if there are other transports (cellular for example) available.
-         *<p>
-         * Note: Apps can set a combination of network match params:
-         * <li> SSID Pattern using {@link #setSsidPattern(PatternMatcher)} OR Specific SSID using
-         * {@link #setSsid(String)}. </li>
-         * AND/OR
-         * <li> BSSID Pattern using {@link #setBssidPattern(MacAddress, MacAddress)} OR Specific
-         * BSSID using {@link #setBssid(MacAddress)} </li>
-         * to trigger connection to a network that matches the set params.
-         * The system will find the set of networks matching the request and present the user
-         * with a system dialog which will allow the user to select a specific Wi-Fi network to
-         * connect to or to deny the request.
-         *</p>
-         *
-         * For example:
-         * To connect to an open network with a SSID prefix of "test" and a BSSID OUI of "10:03:23":
-         *
-         * <pre>{@code
-         * final NetworkSpecifier specifier =
-         *      new Builder()
-         *      .setSsidPattern(new PatternMatcher("test", PatterMatcher.PATTERN_PREFIX))
-         *      .setBssidPattern(MacAddress.fromString("10:03:23:00:00:00"),
-         *                       MacAddress.fromString("ff:ff:ff:00:00:00"))
-         *      .build()
-         * final NetworkRequest request =
-         *      new NetworkRequest.Builder()
-         *      .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
-         *      .removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-         *      .setNetworkSpecifier(specifier)
-         *      .build();
-         * final ConnectivityManager connectivityManager =
-         *      context.getSystemService(Context.CONNECTIVITY_SERVICE);
-         * final NetworkCallback networkCallback = new NetworkCallback() {
-         *      ...
-         *      {@literal @}Override
-         *      void onAvailable(...) {}
-         *      // etc.
-         * };
-         * connectivityManager.requestNetwork(request, networkCallback);
-         * }</pre>
-         *
-         * @return Instance of {@link NetworkSpecifier}.
-         * @throws IllegalStateException on invalid params set.
-         */
-        public @NonNull WifiNetworkSpecifier build() {
-            if (!hasSetAnyPattern()) {
-                throw new IllegalStateException("one of setSsidPattern/setSsid/setBssidPattern/"
-                        + "setBssid should be invoked for specifier");
-            }
-            setMatchAnyPatternIfUnset();
-            if (hasSetMatchNonePattern()) {
-                throw new IllegalStateException("cannot set match-none pattern for specifier");
-            }
-            if (hasSetMatchAllPattern()) {
-                throw new IllegalStateException("cannot set match-all pattern for specifier");
-            }
-            if (mIsHiddenSSID && mSsidPatternMatcher.getType() != PatternMatcher.PATTERN_LITERAL) {
-                throw new IllegalStateException("setSsid should also be invoked when "
-                        + "setIsHiddenSsid is invoked for network specifier");
-            }
-            validateSecurityParams();
-
-            return new WifiNetworkSpecifier(
-                    mSsidPatternMatcher,
-                    mBssidPatternMatcher,
-                    buildWifiConfiguration());
-        }
-    }
-
-    /**
-     * SSID pattern match specified by the app.
-     * @hide
-     */
-    public final PatternMatcher ssidPatternMatcher;
-
-    /**
-     * BSSID pattern match specified by the app.
-     * Pair of <BaseAddress, Mask>.
-     * @hide
-     */
-    public final Pair<MacAddress, MacAddress> bssidPatternMatcher;
-
-    /**
-     * Security credentials for the network.
-     * <p>
-     * Note: {@link WifiConfiguration#SSID} & {@link WifiConfiguration#BSSID} fields from
-     * WifiConfiguration are not used. Instead we use the {@link #ssidPatternMatcher} &
-     * {@link #bssidPatternMatcher} fields embedded directly
-     * within {@link WifiNetworkSpecifier}.
-     * @hide
-     */
-    public final WifiConfiguration wifiConfiguration;
-
-    /** @hide */
-    public WifiNetworkSpecifier() throws IllegalAccessException {
-        throw new IllegalAccessException("Use the builder to create an instance");
-    }
-
-    /** @hide */
-    public WifiNetworkSpecifier(@NonNull PatternMatcher ssidPatternMatcher,
-                                @NonNull Pair<MacAddress, MacAddress> bssidPatternMatcher,
-                                @NonNull WifiConfiguration wifiConfiguration) {
-        checkNotNull(ssidPatternMatcher);
-        checkNotNull(bssidPatternMatcher);
-        checkNotNull(wifiConfiguration);
-
-        this.ssidPatternMatcher = ssidPatternMatcher;
-        this.bssidPatternMatcher = bssidPatternMatcher;
-        this.wifiConfiguration = wifiConfiguration;
-    }
-
-    public static final @NonNull Creator<WifiNetworkSpecifier> CREATOR =
-            new Creator<WifiNetworkSpecifier>() {
-                @Override
-                public WifiNetworkSpecifier createFromParcel(Parcel in) {
-                    PatternMatcher ssidPatternMatcher = in.readParcelable(/* classLoader */null);
-                    MacAddress baseAddress = in.readParcelable(null);
-                    MacAddress mask = in.readParcelable(null);
-                    Pair<MacAddress, MacAddress> bssidPatternMatcher =
-                            Pair.create(baseAddress, mask);
-                    WifiConfiguration wifiConfiguration = in.readParcelable(null);
-                    return new WifiNetworkSpecifier(ssidPatternMatcher, bssidPatternMatcher,
-                            wifiConfiguration);
-                }
-
-                @Override
-                public WifiNetworkSpecifier[] newArray(int size) {
-                    return new WifiNetworkSpecifier[size];
-                }
-            };
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeParcelable(ssidPatternMatcher, flags);
-        dest.writeParcelable(bssidPatternMatcher.first, flags);
-        dest.writeParcelable(bssidPatternMatcher.second, flags);
-        dest.writeParcelable(wifiConfiguration, flags);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(
-                ssidPatternMatcher.getPath(), ssidPatternMatcher.getType(), bssidPatternMatcher,
-                wifiConfiguration.allowedKeyManagement);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (!(obj instanceof WifiNetworkSpecifier)) {
-            return false;
-        }
-        WifiNetworkSpecifier lhs = (WifiNetworkSpecifier) obj;
-        return Objects.equals(this.ssidPatternMatcher.getPath(),
-                    lhs.ssidPatternMatcher.getPath())
-                && Objects.equals(this.ssidPatternMatcher.getType(),
-                    lhs.ssidPatternMatcher.getType())
-                && Objects.equals(this.bssidPatternMatcher,
-                    lhs.bssidPatternMatcher)
-                && Objects.equals(this.wifiConfiguration.allowedKeyManagement,
-                    lhs.wifiConfiguration.allowedKeyManagement);
-    }
-
-    @Override
-    public String toString() {
-        return new StringBuilder()
-                .append("WifiNetworkSpecifier [")
-                .append(", SSID Match pattern=").append(ssidPatternMatcher)
-                .append(", BSSID Match pattern=").append(bssidPatternMatcher)
-                .append(", SSID=").append(wifiConfiguration.SSID)
-                .append(", BSSID=").append(wifiConfiguration.BSSID)
-                .append("]")
-                .toString();
-    }
-
-    /** @hide */
-    @Override
-    public boolean canBeSatisfiedBy(NetworkSpecifier other) {
-        if (other instanceof WifiNetworkAgentSpecifier) {
-            return ((WifiNetworkAgentSpecifier) other).satisfiesNetworkSpecifier(this);
-        }
-        // Specific requests are checked for equality although testing for equality of 2 patterns do
-        // not make much sense!
-        return equals(other);
-    }
-}
diff --git a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
deleted file mode 100644
index d8be1d2..0000000
--- a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
+++ /dev/null
@@ -1,986 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import static com.android.internal.util.Preconditions.checkNotNull;
-
-import android.annotation.IntRange;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
-import android.annotation.SystemApi;
-import android.net.MacAddress;
-import android.net.wifi.hotspot2.PasspointConfiguration;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.telephony.TelephonyManager;
-import android.text.TextUtils;
-
-import java.nio.charset.CharsetEncoder;
-import java.nio.charset.StandardCharsets;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * The Network Suggestion object is used to provide a Wi-Fi network for consideration when
- * auto-connecting to networks. Apps cannot directly create this object, they must use
- * {@link WifiNetworkSuggestion.Builder#build()} to obtain an instance of this object.
- *<p>
- * Apps can provide a list of such networks to the platform using
- * {@link WifiManager#addNetworkSuggestions(List)}.
- */
-public final class WifiNetworkSuggestion implements Parcelable {
-    /**
-     * Builder used to create {@link WifiNetworkSuggestion} objects.
-     */
-    public static final class Builder {
-        private static final int UNASSIGNED_PRIORITY = -1;
-
-        /**
-         * SSID of the network.
-         */
-        private String mSsid;
-        /**
-         * Optional BSSID within the network.
-         */
-        private MacAddress mBssid;
-        /**
-         * Whether this is an OWE network or not.
-         */
-        private boolean mIsEnhancedOpen;
-        /**
-         * Pre-shared key for use with WPA-PSK networks.
-         */
-        private @Nullable String mWpa2PskPassphrase;
-        /**
-         * Pre-shared key for use with WPA3-SAE networks.
-         */
-        private @Nullable String mWpa3SaePassphrase;
-        /**
-         * The enterprise configuration details specifying the EAP method,
-         * certificates and other settings associated with the WPA/WPA2-Enterprise networks.
-         */
-        private @Nullable WifiEnterpriseConfig mWpa2EnterpriseConfig;
-        /**
-         * The enterprise configuration details specifying the EAP method,
-         * certificates and other settings associated with the WPA3-Enterprise networks.
-         */
-        private @Nullable WifiEnterpriseConfig mWpa3EnterpriseConfig;
-        /**
-         * The passpoint config for use with Hotspot 2.0 network
-         */
-        private @Nullable PasspointConfiguration mPasspointConfiguration;
-        /**
-         * This is a network that does not broadcast its SSID, so an
-         * SSID-specific probe request must be used for scans.
-         */
-        private boolean mIsHiddenSSID;
-        /**
-         * Whether app needs to log in to captive portal to obtain Internet access.
-         */
-        private boolean mIsAppInteractionRequired;
-        /**
-         * Whether user needs to log in to captive portal to obtain Internet access.
-         */
-        private boolean mIsUserInteractionRequired;
-        /**
-         * Whether this network is metered or not.
-         */
-        private int mMeteredOverride;
-        /**
-         * Priority of this network among other network suggestions provided by the app.
-         * The lower the number, the higher the priority (i.e value of 0 = highest priority).
-         */
-        private int mPriority;
-
-        /**
-         * The carrier ID identifies the operator who provides this network configuration.
-         *    see {@link TelephonyManager#getSimCarrierId()}
-         */
-        private int mCarrierId;
-
-        /**
-         * Whether this network is shared credential with user to allow user manually connect.
-         */
-        private boolean mIsSharedWithUser;
-
-        /**
-         * Whether the setCredentialSharedWithUser have been called.
-         */
-        private boolean mIsSharedWithUserSet;
-
-        /**
-         * Whether this network is initialized with auto-join enabled (the default) or not.
-         */
-        private boolean mIsInitialAutojoinEnabled;
-
-        /**
-         * Pre-shared key for use with WAPI-PSK networks.
-         */
-        private @Nullable String mWapiPskPassphrase;
-
-        /**
-         * The enterprise configuration details specifying the EAP method,
-         * certificates and other settings associated with the WAPI networks.
-         */
-        private @Nullable WifiEnterpriseConfig mWapiEnterpriseConfig;
-
-        /**
-         * Whether this network will be brought up as untrusted (TRUSTED capability bit removed).
-         */
-        private boolean mIsNetworkUntrusted;
-
-        public Builder() {
-            mSsid = null;
-            mBssid =  null;
-            mIsEnhancedOpen = false;
-            mWpa2PskPassphrase = null;
-            mWpa3SaePassphrase = null;
-            mWpa2EnterpriseConfig = null;
-            mWpa3EnterpriseConfig = null;
-            mPasspointConfiguration = null;
-            mIsHiddenSSID = false;
-            mIsAppInteractionRequired = false;
-            mIsUserInteractionRequired = false;
-            mMeteredOverride = WifiConfiguration.METERED_OVERRIDE_NONE;
-            mIsSharedWithUser = true;
-            mIsSharedWithUserSet = false;
-            mIsInitialAutojoinEnabled = true;
-            mPriority = UNASSIGNED_PRIORITY;
-            mCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID;
-            mWapiPskPassphrase = null;
-            mWapiEnterpriseConfig = null;
-            mIsNetworkUntrusted = false;
-        }
-
-        /**
-         * Set the unicode SSID for the network.
-         * <p>
-         * <li>Overrides any previous value set using {@link #setSsid(String)}.</li>
-         *
-         * @param ssid The SSID of the network. It must be valid Unicode.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         * @throws IllegalArgumentException if the SSID is not valid unicode.
-         */
-        public @NonNull Builder setSsid(@NonNull String ssid) {
-            checkNotNull(ssid);
-            final CharsetEncoder unicodeEncoder = StandardCharsets.UTF_8.newEncoder();
-            if (!unicodeEncoder.canEncode(ssid)) {
-                throw new IllegalArgumentException("SSID is not a valid unicode string");
-            }
-            mSsid = new String(ssid);
-            return this;
-        }
-
-        /**
-         * Set the BSSID to use for filtering networks from scan results. Will only match network
-         * whose BSSID is identical to the specified value.
-         * <p>
-         * <li Sets a specific BSSID for the network suggestion. If set, only the specified BSSID
-         * with the specified SSID will be considered for connection.
-         * <li>If set, only the specified BSSID with the specified SSID will be considered for
-         * connection.</li>
-         * <li>If not set, all BSSIDs with the specified SSID will be considered for connection.
-         * </li>
-         * <li>Overrides any previous value set using {@link #setBssid(MacAddress)}.</li>
-         *
-         * @param bssid BSSID of the network.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         */
-        public @NonNull Builder setBssid(@NonNull MacAddress bssid) {
-            checkNotNull(bssid);
-            mBssid = MacAddress.fromBytes(bssid.toByteArray());
-            return this;
-        }
-
-        /**
-         * Specifies whether this represents an Enhanced Open (OWE) network.
-         *
-         * @param isEnhancedOpen {@code true} to indicate that the network used enhanced open,
-         *                       {@code false} otherwise.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         */
-        public @NonNull Builder setIsEnhancedOpen(boolean isEnhancedOpen) {
-            mIsEnhancedOpen = isEnhancedOpen;
-            return this;
-        }
-
-        /**
-         * Set the ASCII WPA2 passphrase for this network. Needed for authenticating to
-         * WPA2-PSK networks.
-         *
-         * @param passphrase passphrase of the network.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         * @throws IllegalArgumentException if the passphrase is not ASCII encodable.
-         */
-        public @NonNull Builder setWpa2Passphrase(@NonNull String passphrase) {
-            checkNotNull(passphrase);
-            final CharsetEncoder asciiEncoder = StandardCharsets.US_ASCII.newEncoder();
-            if (!asciiEncoder.canEncode(passphrase)) {
-                throw new IllegalArgumentException("passphrase not ASCII encodable");
-            }
-            mWpa2PskPassphrase = passphrase;
-            return this;
-        }
-
-        /**
-         * Set the ASCII WPA3 passphrase for this network. Needed for authenticating to WPA3-SAE
-         * networks.
-         *
-         * @param passphrase passphrase of the network.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         * @throws IllegalArgumentException if the passphrase is not ASCII encodable.
-         */
-        public @NonNull Builder setWpa3Passphrase(@NonNull String passphrase) {
-            checkNotNull(passphrase);
-            final CharsetEncoder asciiEncoder = StandardCharsets.US_ASCII.newEncoder();
-            if (!asciiEncoder.canEncode(passphrase)) {
-                throw new IllegalArgumentException("passphrase not ASCII encodable");
-            }
-            mWpa3SaePassphrase = passphrase;
-            return this;
-        }
-
-        /**
-         * Set the associated enterprise configuration for this network. Needed for authenticating
-         * to WPA2 enterprise networks. See {@link WifiEnterpriseConfig} for description.
-         *
-         * @param enterpriseConfig Instance of {@link WifiEnterpriseConfig}.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         * @throws IllegalArgumentException if configuration CA certificate or
-         *                                  AltSubjectMatch/DomainSuffixMatch is not set.
-         */
-        public @NonNull Builder setWpa2EnterpriseConfig(
-                @NonNull WifiEnterpriseConfig enterpriseConfig) {
-            checkNotNull(enterpriseConfig);
-            if (enterpriseConfig.isInsecure()) {
-                throw new IllegalArgumentException("Enterprise configuration is insecure");
-            }
-            mWpa2EnterpriseConfig = new WifiEnterpriseConfig(enterpriseConfig);
-            return this;
-        }
-
-        /**
-         * Set the associated enterprise configuration for this network. Needed for authenticating
-         * to WPA3-Enterprise networks (standard and 192-bit security). See
-         * {@link WifiEnterpriseConfig} for description. For 192-bit security networks, both the
-         * client and CA certificates must be provided, and must be of type of either
-         * sha384WithRSAEncryption (OID 1.2.840.113549.1.1.12) or ecdsa-with-SHA384
-         * (OID 1.2.840.10045.4.3.3).
-         *
-         * @param enterpriseConfig Instance of {@link WifiEnterpriseConfig}.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         * @throws IllegalArgumentException if configuration CA certificate or
-         *                                  AltSubjectMatch/DomainSuffixMatch is not set.
-         */
-        public @NonNull Builder setWpa3EnterpriseConfig(
-                @NonNull WifiEnterpriseConfig enterpriseConfig) {
-            checkNotNull(enterpriseConfig);
-            if (enterpriseConfig.isInsecure()) {
-                throw new IllegalArgumentException("Enterprise configuration is insecure");
-            }
-            mWpa3EnterpriseConfig = new WifiEnterpriseConfig(enterpriseConfig);
-            return this;
-        }
-
-        /**
-         * Set the associated Passpoint configuration for this network. Needed for authenticating
-         * to Hotspot 2.0 networks. See {@link PasspointConfiguration} for description.
-         *
-         * @param passpointConfig Instance of {@link PasspointConfiguration}.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         * @throws IllegalArgumentException if passpoint configuration is invalid.
-         */
-        public @NonNull Builder setPasspointConfig(
-                @NonNull PasspointConfiguration passpointConfig) {
-            checkNotNull(passpointConfig);
-            if (!passpointConfig.validate()) {
-                throw new IllegalArgumentException("Passpoint configuration is invalid");
-            }
-            mPasspointConfiguration = passpointConfig;
-            return this;
-        }
-
-        /**
-         * Set the carrier ID of the network operator. The carrier ID associates a Suggested
-         * network with a specific carrier (and therefore SIM). The carrier ID must be provided
-         * for any network which uses the SIM-based authentication: e.g. EAP-SIM, EAP-AKA,
-         * EAP-AKA', and EAP-PEAP with SIM-based phase 2 authentication.
-         * @param carrierId see {@link TelephonyManager#getSimCarrierId()}.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         *
-         * @hide
-         */
-        @SystemApi
-        @RequiresPermission(android.Manifest.permission.NETWORK_CARRIER_PROVISIONING)
-        public @NonNull Builder setCarrierId(int carrierId) {
-            mCarrierId = carrierId;
-            return this;
-        }
-
-        /**
-         * Set the ASCII WAPI passphrase for this network. Needed for authenticating to
-         * WAPI-PSK networks.
-         *
-         * @param passphrase passphrase of the network.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         * @throws IllegalArgumentException if the passphrase is not ASCII encodable.
-         *
-         */
-        public @NonNull Builder setWapiPassphrase(@NonNull String passphrase) {
-            checkNotNull(passphrase);
-            final CharsetEncoder asciiEncoder = StandardCharsets.US_ASCII.newEncoder();
-            if (!asciiEncoder.canEncode(passphrase)) {
-                throw new IllegalArgumentException("passphrase not ASCII encodable");
-            }
-            mWapiPskPassphrase = passphrase;
-            return this;
-        }
-
-        /**
-         * Set the associated enterprise configuration for this network. Needed for authenticating
-         * to WAPI-CERT networks. See {@link WifiEnterpriseConfig} for description.
-         *
-         * @param enterpriseConfig Instance of {@link WifiEnterpriseConfig}.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         */
-        public @NonNull Builder setWapiEnterpriseConfig(
-                @NonNull WifiEnterpriseConfig enterpriseConfig) {
-            checkNotNull(enterpriseConfig);
-            mWapiEnterpriseConfig = new WifiEnterpriseConfig(enterpriseConfig);
-            return this;
-        }
-
-        /**
-         * Specifies whether this represents a hidden network.
-         * <p>
-         * <li>If not set, defaults to false (i.e not a hidden network).</li>
-         *
-         * @param isHiddenSsid {@code true} to indicate that the network is hidden, {@code false}
-         *                     otherwise.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         */
-        public @NonNull Builder setIsHiddenSsid(boolean isHiddenSsid) {
-            mIsHiddenSSID = isHiddenSsid;
-            return this;
-        }
-
-        /**
-         * Specifies whether the app needs to log in to a captive portal to obtain Internet access.
-         * <p>
-         * This will dictate if the directed broadcast
-         * {@link WifiManager#ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION} will be sent to the
-         * app after successfully connecting to the network.
-         * Use this for captive portal type networks where the app needs to authenticate the user
-         * before the device can access the network.
-         * <p>
-         * <li>If not set, defaults to false (i.e no app interaction required).</li>
-         *
-         * @param isAppInteractionRequired {@code true} to indicate that app interaction is
-         *                                 required, {@code false} otherwise.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         */
-        public @NonNull Builder setIsAppInteractionRequired(boolean isAppInteractionRequired) {
-            mIsAppInteractionRequired = isAppInteractionRequired;
-            return this;
-        }
-
-        /**
-         * Specifies whether the user needs to log in to a captive portal to obtain Internet access.
-         * <p>
-         * <li>If not set, defaults to false (i.e no user interaction required).</li>
-         *
-         * @param isUserInteractionRequired {@code true} to indicate that user interaction is
-         *                                  required, {@code false} otherwise.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         */
-        public @NonNull Builder setIsUserInteractionRequired(boolean isUserInteractionRequired) {
-            mIsUserInteractionRequired = isUserInteractionRequired;
-            return this;
-        }
-
-        /**
-         * Specify the priority of this network among other network suggestions provided by the same
-         * app (priorities have no impact on suggestions by different apps). The higher the number,
-         * the higher the priority (i.e value of 0 = lowest priority).
-         * <p>
-         * <li>If not set, defaults a lower priority than any assigned priority.</li>
-         *
-         * @param priority Integer number representing the priority among suggestions by the app.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         * @throws IllegalArgumentException if the priority value is negative.
-         */
-        public @NonNull Builder setPriority(@IntRange(from = 0) int priority) {
-            if (priority < 0) {
-                throw new IllegalArgumentException("Invalid priority value " + priority);
-            }
-            mPriority = priority;
-            return this;
-        }
-
-        /**
-         * Specifies whether this network is metered.
-         * <p>
-         * <li>If not set, defaults to detect automatically.</li>
-         *
-         * @param isMetered {@code true} to indicate that the network is metered, {@code false}
-         *                  for not metered.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         */
-        public @NonNull Builder setIsMetered(boolean isMetered) {
-            if (isMetered) {
-                mMeteredOverride = WifiConfiguration.METERED_OVERRIDE_METERED;
-            } else {
-                mMeteredOverride = WifiConfiguration.METERED_OVERRIDE_NOT_METERED;
-            }
-            return this;
-        }
-
-        /**
-         * Specifies whether the network credentials provided with this suggestion can be used by
-         * the user to explicitly (manually) connect to this network. If true this network will
-         * appear in the Wi-Fi Picker (in Settings) and the user will be able to select and connect
-         * to it with the provided credentials. If false, the user will need to enter network
-         * credentials and the resulting configuration will become a user saved network.
-         * <p>
-         * <li>Note: Only valid for secure (non-open) networks.
-         * <li>If not set, defaults to true (i.e. allow user to manually connect) for secure
-         * networks and false for open networks.</li>
-         *
-         * @param isShared {@code true} to indicate that the credentials may be used by the user to
-         *                              manually connect to the network, {@code false} otherwise.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         */
-        public @NonNull Builder setCredentialSharedWithUser(boolean isShared) {
-            mIsSharedWithUser = isShared;
-            mIsSharedWithUserSet = true;
-            return this;
-        }
-
-        /**
-         * Specifies whether the suggestion is created with auto-join enabled or disabled. The
-         * user may modify the auto-join configuration of a suggestion directly once the device
-         * associates to the network.
-         * <p>
-         * If auto-join is initialized as disabled the user may still be able to manually connect
-         * to the network. Therefore, disabling auto-join only makes sense if
-         * {@link #setCredentialSharedWithUser(boolean)} is set to true (the default) which
-         * itself implies a secure (non-open) network.
-         * <p>
-         * If not set, defaults to true (i.e. auto-join is initialized as enabled).
-         *
-         * @param enabled true for initializing with auto-join enabled (the default), false to
-         *                initializing with auto-join disabled.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         */
-        public @NonNull Builder setIsInitialAutojoinEnabled(boolean enabled) {
-            mIsInitialAutojoinEnabled = enabled;
-            return this;
-        }
-
-        /**
-         * Specifies whether the system will bring up the network (if selected) as untrusted. An
-         * untrusted network has its {@link android.net.NetworkCapabilities#NET_CAPABILITY_TRUSTED}
-         * capability removed. The Wi-Fi network selection process may use this information to
-         * influence priority of the suggested network for Wi-Fi network selection (most likely to
-         * reduce it). The connectivity service may use this information to influence the overall
-         * network configuration of the device.
-         * <p>
-         * <li> An untrusted network's credentials may not be shared with the user using
-         * {@link #setCredentialSharedWithUser(boolean)}.</li>
-         * <li> If not set, defaults to false (i.e. network is trusted).</li>
-         *
-         * @param isUntrusted Boolean indicating whether the network should be brought up untrusted
-         *                    (if true) or trusted (if false).
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         */
-        public @NonNull Builder setUntrusted(boolean isUntrusted) {
-            mIsNetworkUntrusted = isUntrusted;
-            return this;
-        }
-
-        private void setSecurityParamsInWifiConfiguration(
-                @NonNull WifiConfiguration configuration) {
-            if (!TextUtils.isEmpty(mWpa2PskPassphrase)) { // WPA-PSK network.
-                configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_PSK);
-                // WifiConfiguration.preSharedKey needs quotes around ASCII password.
-                configuration.preSharedKey = "\"" + mWpa2PskPassphrase + "\"";
-            } else if (!TextUtils.isEmpty(mWpa3SaePassphrase)) { // WPA3-SAE network.
-                configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_SAE);
-                // WifiConfiguration.preSharedKey needs quotes around ASCII password.
-                configuration.preSharedKey = "\"" + mWpa3SaePassphrase + "\"";
-            } else if (mWpa2EnterpriseConfig != null) { // WPA-EAP network
-                configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP);
-                configuration.enterpriseConfig = mWpa2EnterpriseConfig;
-            } else if (mWpa3EnterpriseConfig != null) { // WPA3-Enterprise
-                if (mWpa3EnterpriseConfig.getEapMethod() == WifiEnterpriseConfig.Eap.TLS
-                        && WifiEnterpriseConfig.isSuiteBCipherCert(
-                        mWpa3EnterpriseConfig.getClientCertificate())
-                        && WifiEnterpriseConfig.isSuiteBCipherCert(
-                        mWpa3EnterpriseConfig.getCaCertificate())) {
-                    // WPA3-Enterprise in 192-bit security mode (Suite-B)
-                    configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP_SUITE_B);
-                } else {
-                    // WPA3-Enterprise
-                    configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP);
-                    configuration.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
-                    configuration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
-                    configuration.allowedPairwiseCiphers.set(
-                            WifiConfiguration.PairwiseCipher.GCMP_256);
-                    configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
-                    configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_256);
-                    configuration.requirePmf = true;
-                }
-                configuration.enterpriseConfig = mWpa3EnterpriseConfig;
-            } else if (mIsEnhancedOpen) { // OWE network
-                configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_OWE);
-            } else if (!TextUtils.isEmpty(mWapiPskPassphrase)) { // WAPI-PSK network.
-                configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_WAPI_PSK);
-                // WifiConfiguration.preSharedKey needs quotes around ASCII password.
-                configuration.preSharedKey = "\"" + mWapiPskPassphrase + "\"";
-            } else if (mWapiEnterpriseConfig != null) { // WAPI-CERT network
-                configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_WAPI_CERT);
-                configuration.enterpriseConfig = mWapiEnterpriseConfig;
-            } else { // Open network
-                configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_OPEN);
-            }
-        }
-
-        /**
-         * Helper method to build WifiConfiguration object from the builder.
-         * @return Instance of {@link WifiConfiguration}.
-         */
-        private WifiConfiguration buildWifiConfiguration() {
-            final WifiConfiguration wifiConfiguration = new WifiConfiguration();
-            // WifiConfiguration.SSID needs quotes around unicode SSID.
-            wifiConfiguration.SSID = "\"" + mSsid + "\"";
-            if (mBssid != null) {
-                wifiConfiguration.BSSID = mBssid.toString();
-            }
-
-            setSecurityParamsInWifiConfiguration(wifiConfiguration);
-
-            wifiConfiguration.hiddenSSID = mIsHiddenSSID;
-            wifiConfiguration.priority = mPriority;
-            wifiConfiguration.meteredOverride = mMeteredOverride;
-            wifiConfiguration.carrierId = mCarrierId;
-            wifiConfiguration.trusted = !mIsNetworkUntrusted;
-            return wifiConfiguration;
-        }
-
-        private void validateSecurityParams() {
-            int numSecurityTypes = 0;
-            numSecurityTypes += mIsEnhancedOpen ? 1 : 0;
-            numSecurityTypes += !TextUtils.isEmpty(mWpa2PskPassphrase) ? 1 : 0;
-            numSecurityTypes += !TextUtils.isEmpty(mWpa3SaePassphrase) ? 1 : 0;
-            numSecurityTypes += !TextUtils.isEmpty(mWapiPskPassphrase) ? 1 : 0;
-            numSecurityTypes += mWpa2EnterpriseConfig != null ? 1 : 0;
-            numSecurityTypes += mWpa3EnterpriseConfig != null ? 1 : 0;
-            numSecurityTypes += mWapiEnterpriseConfig != null ? 1 : 0;
-            numSecurityTypes += mPasspointConfiguration != null ? 1 : 0;
-            if (numSecurityTypes > 1) {
-                throw new IllegalStateException("only one of setIsEnhancedOpen, setWpa2Passphrase,"
-                        + " setWpa3Passphrase, setWpa2EnterpriseConfig, setWpa3EnterpriseConfig"
-                        + " setWapiPassphrase, setWapiCertSuite, setIsWapiCertSuiteAuto"
-                        + " or setPasspointConfig can be invoked for network suggestion");
-            }
-        }
-
-        private WifiConfiguration buildWifiConfigurationForPasspoint() {
-            WifiConfiguration wifiConfiguration = new WifiConfiguration();
-            wifiConfiguration.FQDN = mPasspointConfiguration.getHomeSp().getFqdn();
-            wifiConfiguration.setPasspointUniqueId(mPasspointConfiguration.getUniqueId());
-            wifiConfiguration.priority = mPriority;
-            wifiConfiguration.meteredOverride = mMeteredOverride;
-            wifiConfiguration.trusted = !mIsNetworkUntrusted;
-            mPasspointConfiguration.setCarrierId(mCarrierId);
-            mPasspointConfiguration.setMeteredOverride(wifiConfiguration.meteredOverride);
-            return wifiConfiguration;
-        }
-
-        /**
-         * Create a network suggestion object for use in
-         * {@link WifiManager#addNetworkSuggestions(List)}.
-         *
-         *<p class="note">
-         * <b>Note:</b> Apps can set a combination of SSID using {@link #setSsid(String)} and BSSID
-         * using {@link #setBssid(MacAddress)} to provide more fine grained network suggestions to
-         * the platform.
-         * </p>
-         *
-         * For example:
-         * To provide credentials for one open, one WPA2, one WPA3 network with their
-         * corresponding SSID's and one with Passpoint config:
-         *
-         * <pre>{@code
-         * final WifiNetworkSuggestion suggestion1 =
-         *      new Builder()
-         *      .setSsid("test111111")
-         *      .build();
-         * final WifiNetworkSuggestion suggestion2 =
-         *      new Builder()
-         *      .setSsid("test222222")
-         *      .setWpa2Passphrase("test123456")
-         *      .build();
-         * final WifiNetworkSuggestion suggestion3 =
-         *      new Builder()
-         *      .setSsid("test333333")
-         *      .setWpa3Passphrase("test6789")
-         *      .build();
-         * final PasspointConfiguration passpointConfig= new PasspointConfiguration();
-         * // configure passpointConfig to include a valid Passpoint configuration
-         * final WifiNetworkSuggestion suggestion4 =
-         *      new Builder()
-         *      .setPasspointConfig(passpointConfig)
-         *      .build();
-         * final List<WifiNetworkSuggestion> suggestionsList =
-         *      new ArrayList<WifiNetworkSuggestion> { {
-         *          add(suggestion1);
-         *          add(suggestion2);
-         *          add(suggestion3);
-         *          add(suggestion4);
-         *      } };
-         * final WifiManager wifiManager =
-         *      context.getSystemService(Context.WIFI_SERVICE);
-         * wifiManager.addNetworkSuggestions(suggestionsList);
-         * // ...
-         * }</pre>
-         *
-         * @return Instance of {@link WifiNetworkSuggestion}
-         * @throws IllegalStateException on invalid params set
-         * @see WifiNetworkSuggestion
-         */
-        public @NonNull WifiNetworkSuggestion build() {
-            validateSecurityParams();
-            WifiConfiguration wifiConfiguration;
-            if (mPasspointConfiguration != null) {
-                if (mSsid != null) {
-                    throw new IllegalStateException("setSsid should not be invoked for suggestion "
-                            + "with Passpoint configuration");
-                }
-                if (mIsHiddenSSID) {
-                    throw new IllegalStateException("setIsHiddenSsid should not be invoked for "
-                            + "suggestion with Passpoint configuration");
-                }
-                wifiConfiguration = buildWifiConfigurationForPasspoint();
-            } else {
-                if (mSsid == null) {
-                    throw new IllegalStateException("setSsid should be invoked for suggestion");
-                }
-                if (TextUtils.isEmpty(mSsid)) {
-                    throw new IllegalStateException("invalid ssid for suggestion");
-                }
-                if (mBssid != null
-                        && (mBssid.equals(MacAddress.BROADCAST_ADDRESS)
-                        || mBssid.equals(WifiManager.ALL_ZEROS_MAC_ADDRESS))) {
-                    throw new IllegalStateException("invalid bssid for suggestion");
-                }
-                wifiConfiguration = buildWifiConfiguration();
-                if (wifiConfiguration.isOpenNetwork()) {
-                    if (mIsSharedWithUserSet && mIsSharedWithUser) {
-                        throw new IllegalStateException("Open network should not be "
-                                + "setCredentialSharedWithUser to true");
-                    }
-                    mIsSharedWithUser = false;
-                }
-            }
-            if (!mIsSharedWithUser && !mIsInitialAutojoinEnabled) {
-                throw new IllegalStateException("Should have not a network with both "
-                        + "setCredentialSharedWithUser and "
-                        + "setIsAutojoinEnabled set to false");
-            }
-            if (mIsNetworkUntrusted) {
-                if (mIsSharedWithUserSet && mIsSharedWithUser) {
-                    throw new IllegalStateException("Should not be both"
-                            + "setCredentialSharedWithUser and +"
-                            + "setIsNetworkAsUntrusted to true");
-                }
-                mIsSharedWithUser = false;
-            }
-            return new WifiNetworkSuggestion(
-                    wifiConfiguration,
-                    mPasspointConfiguration,
-                    mIsAppInteractionRequired,
-                    mIsUserInteractionRequired,
-                    mIsSharedWithUser,
-                    mIsInitialAutojoinEnabled);
-        }
-    }
-
-    /**
-     * Network configuration for the provided network.
-     * @hide
-     */
-    @NonNull
-    public final WifiConfiguration wifiConfiguration;
-
-    /**
-     * Passpoint configuration for the provided network.
-     * @hide
-     */
-    @Nullable
-    public final PasspointConfiguration passpointConfiguration;
-
-    /**
-     * Whether app needs to log in to captive portal to obtain Internet access.
-     * @hide
-     */
-    public final boolean isAppInteractionRequired;
-
-    /**
-     * Whether user needs to log in to captive portal to obtain Internet access.
-     * @hide
-     */
-    public final boolean isUserInteractionRequired;
-
-    /**
-     * Whether app share credential with the user, allow user use provided credential to
-     * connect network manually.
-     * @hide
-     */
-    public final boolean isUserAllowedToManuallyConnect;
-
-    /**
-     * Whether the suggestion will be initialized as auto-joined or not.
-     * @hide
-     */
-    public final boolean isInitialAutoJoinEnabled;
-
-    /** @hide */
-    public WifiNetworkSuggestion() {
-        this.wifiConfiguration = new WifiConfiguration();
-        this.passpointConfiguration = null;
-        this.isAppInteractionRequired = false;
-        this.isUserInteractionRequired = false;
-        this.isUserAllowedToManuallyConnect = true;
-        this.isInitialAutoJoinEnabled = true;
-    }
-
-    /** @hide */
-    public WifiNetworkSuggestion(@NonNull WifiConfiguration networkConfiguration,
-                                 @Nullable PasspointConfiguration passpointConfiguration,
-                                 boolean isAppInteractionRequired,
-                                 boolean isUserInteractionRequired,
-                                 boolean isUserAllowedToManuallyConnect,
-                                 boolean isInitialAutoJoinEnabled) {
-        checkNotNull(networkConfiguration);
-        this.wifiConfiguration = networkConfiguration;
-        this.passpointConfiguration = passpointConfiguration;
-
-        this.isAppInteractionRequired = isAppInteractionRequired;
-        this.isUserInteractionRequired = isUserInteractionRequired;
-        this.isUserAllowedToManuallyConnect = isUserAllowedToManuallyConnect;
-        this.isInitialAutoJoinEnabled = isInitialAutoJoinEnabled;
-    }
-
-    public static final @NonNull Creator<WifiNetworkSuggestion> CREATOR =
-            new Creator<WifiNetworkSuggestion>() {
-                @Override
-                public WifiNetworkSuggestion createFromParcel(Parcel in) {
-                    return new WifiNetworkSuggestion(
-                            in.readParcelable(null), // wifiConfiguration
-                            in.readParcelable(null), // PasspointConfiguration
-                            in.readBoolean(), // isAppInteractionRequired
-                            in.readBoolean(), // isUserInteractionRequired
-                            in.readBoolean(), // isSharedCredentialWithUser
-                            in.readBoolean()  // isAutojoinEnabled
-                    );
-                }
-
-                @Override
-                public WifiNetworkSuggestion[] newArray(int size) {
-                    return new WifiNetworkSuggestion[size];
-                }
-            };
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeParcelable(wifiConfiguration, flags);
-        dest.writeParcelable(passpointConfiguration, flags);
-        dest.writeBoolean(isAppInteractionRequired);
-        dest.writeBoolean(isUserInteractionRequired);
-        dest.writeBoolean(isUserAllowedToManuallyConnect);
-        dest.writeBoolean(isInitialAutoJoinEnabled);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(wifiConfiguration.SSID, wifiConfiguration.BSSID,
-                wifiConfiguration.allowedKeyManagement, wifiConfiguration.getKey());
-    }
-
-    /**
-     * Equals for network suggestions.
-     */
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (!(obj instanceof WifiNetworkSuggestion)) {
-            return false;
-        }
-        WifiNetworkSuggestion lhs = (WifiNetworkSuggestion) obj;
-        if (this.passpointConfiguration == null ^ lhs.passpointConfiguration == null) {
-            return false;
-        }
-
-        return TextUtils.equals(this.wifiConfiguration.SSID, lhs.wifiConfiguration.SSID)
-                && TextUtils.equals(this.wifiConfiguration.BSSID, lhs.wifiConfiguration.BSSID)
-                && Objects.equals(this.wifiConfiguration.allowedKeyManagement,
-                lhs.wifiConfiguration.allowedKeyManagement)
-                && TextUtils.equals(this.wifiConfiguration.getKey(),
-                lhs.wifiConfiguration.getKey());
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder("WifiNetworkSuggestion[ ")
-                .append("SSID=").append(wifiConfiguration.SSID)
-                .append(", BSSID=").append(wifiConfiguration.BSSID)
-                .append(", FQDN=").append(wifiConfiguration.FQDN)
-                .append(", isAppInteractionRequired=").append(isAppInteractionRequired)
-                .append(", isUserInteractionRequired=").append(isUserInteractionRequired)
-                .append(", isCredentialSharedWithUser=").append(isUserAllowedToManuallyConnect)
-                .append(", isInitialAutoJoinEnabled=").append(isInitialAutoJoinEnabled)
-                .append(", isUnTrusted=").append(!wifiConfiguration.trusted)
-                .append(" ]");
-        return sb.toString();
-    }
-
-    /**
-     * Get the {@link WifiConfiguration} associated with this Suggestion.
-     * @hide
-     */
-    @SystemApi
-    @NonNull
-    public WifiConfiguration getWifiConfiguration() {
-        return wifiConfiguration;
-    }
-
-    /**
-     * Get the BSSID, or null if unset.
-     * @see Builder#setBssid(MacAddress)
-     */
-    @Nullable
-    public MacAddress getBssid() {
-        if (wifiConfiguration.BSSID == null) {
-            return null;
-        }
-        return MacAddress.fromString(wifiConfiguration.BSSID);
-    }
-
-    /** @see Builder#setCredentialSharedWithUser(boolean) */
-    public boolean isCredentialSharedWithUser() {
-        return isUserAllowedToManuallyConnect;
-    }
-
-    /** @see Builder#setIsAppInteractionRequired(boolean) */
-    public boolean isAppInteractionRequired() {
-        return isAppInteractionRequired;
-    }
-
-    /** @see Builder#setIsEnhancedOpen(boolean)  */
-    public boolean isEnhancedOpen() {
-        return wifiConfiguration.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.OWE);
-    }
-
-    /** @see Builder#setIsHiddenSsid(boolean)  */
-    public boolean isHiddenSsid() {
-        return wifiConfiguration.hiddenSSID;
-    }
-
-    /** @see Builder#setIsInitialAutojoinEnabled(boolean)  */
-    public boolean isInitialAutojoinEnabled() {
-        return isInitialAutoJoinEnabled;
-    }
-
-    /** @see Builder#setIsMetered(boolean)  */
-    public boolean isMetered() {
-        return wifiConfiguration.meteredOverride == WifiConfiguration.METERED_OVERRIDE_METERED;
-    }
-
-    /** @see Builder#setIsUserInteractionRequired(boolean)  */
-    public boolean isUserInteractionRequired() {
-        return isUserInteractionRequired;
-    }
-
-    /**
-     * Get the {@link PasspointConfiguration} associated with this Suggestion, or null if this
-     * Suggestion is not for a Passpoint network.
-     */
-    @Nullable
-    public PasspointConfiguration getPasspointConfig() {
-        return passpointConfiguration;
-    }
-
-    /** @see Builder#setPriority(int)  */
-    @IntRange(from = 0)
-    public int getPriority() {
-        return wifiConfiguration.priority;
-    }
-
-    /**
-     * Return the SSID of the network, or null if this is a Passpoint network.
-     * @see Builder#setSsid(String)
-     */
-    @Nullable
-    public String getSsid() {
-        if (wifiConfiguration.SSID == null) {
-            return null;
-        }
-        return WifiInfo.sanitizeSsid(wifiConfiguration.SSID);
-    }
-
-    /** @see Builder#setUntrusted(boolean)  */
-    public boolean isUntrusted() {
-        return !wifiConfiguration.trusted;
-    }
-
-    /**
-     * Get the WifiEnterpriseConfig, or null if unset.
-     * @see Builder#setWapiEnterpriseConfig(WifiEnterpriseConfig)
-     * @see Builder#setWpa2EnterpriseConfig(WifiEnterpriseConfig)
-     * @see Builder#setWpa3EnterpriseConfig(WifiEnterpriseConfig)
-     */
-    @Nullable
-    public WifiEnterpriseConfig getEnterpriseConfig() {
-        if (!wifiConfiguration.isEnterprise()) {
-            return null;
-        }
-        return wifiConfiguration.enterpriseConfig;
-    }
-
-    /**
-     * Get the passphrase, or null if unset.
-     * @see Builder#setWapiPassphrase(String)
-     * @see Builder#setWpa2Passphrase(String)
-     * @see Builder#setWpa3Passphrase(String)
-     */
-    @Nullable
-    public String getPassphrase() {
-        if (wifiConfiguration.preSharedKey == null) {
-            return null;
-        }
-        return WifiInfo.removeDoubleQuotes(wifiConfiguration.preSharedKey);
-    }
-}
diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java
deleted file mode 100644
index 94771ac..0000000
--- a/wifi/java/android/net/wifi/WifiScanner.java
+++ /dev/null
@@ -1,1676 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import android.Manifest;
-import android.annotation.CallbackExecutor;
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
-import android.annotation.SuppressLint;
-import android.annotation.SystemApi;
-import android.annotation.SystemService;
-import android.content.Context;
-import android.os.Binder;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.RemoteException;
-import android.os.WorkSource;
-import android.text.TextUtils;
-import android.util.Log;
-import android.util.SparseArray;
-
-import com.android.internal.util.AsyncChannel;
-import com.android.internal.util.Protocol;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Objects;
-import java.util.concurrent.Executor;
-
-/**
- * This class provides a way to scan the Wifi universe around the device
- * @hide
- */
-@SystemApi
-@SystemService(Context.WIFI_SCANNING_SERVICE)
-public class WifiScanner {
-
-    /** @hide */
-    public static final int WIFI_BAND_INDEX_24_GHZ = 0;
-    /** @hide */
-    public static final int WIFI_BAND_INDEX_5_GHZ = 1;
-    /** @hide */
-    public static final int WIFI_BAND_INDEX_5_GHZ_DFS_ONLY = 2;
-    /** @hide */
-    public static final int WIFI_BAND_INDEX_6_GHZ = 3;
-    /** @hide */
-    public static final int WIFI_BAND_COUNT = 4;
-
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(prefix = {"WIFI_BAND_INDEX_"}, value = {
-            WIFI_BAND_INDEX_24_GHZ,
-            WIFI_BAND_INDEX_5_GHZ,
-            WIFI_BAND_INDEX_5_GHZ_DFS_ONLY,
-            WIFI_BAND_INDEX_6_GHZ})
-    public @interface WifiBandIndex {}
-
-    /** no band specified; use channel list instead */
-    public static final int WIFI_BAND_UNSPECIFIED = 0;
-    /** 2.4 GHz band */
-    public static final int WIFI_BAND_24_GHZ = 1 << WIFI_BAND_INDEX_24_GHZ;
-    /** 5 GHz band excluding DFS channels */
-    public static final int WIFI_BAND_5_GHZ = 1 << WIFI_BAND_INDEX_5_GHZ;
-    /** DFS channels from 5 GHz band only */
-    public static final int WIFI_BAND_5_GHZ_DFS_ONLY  = 1 << WIFI_BAND_INDEX_5_GHZ_DFS_ONLY;
-    /** 6 GHz band */
-    public static final int WIFI_BAND_6_GHZ = 1 << WIFI_BAND_INDEX_6_GHZ;
-
-    /**
-     * Combination of bands
-     * Note that those are only the common band combinations,
-     * other combinations can be created by combining any of the basic bands above
-     */
-    /** Both 2.4 GHz band and 5 GHz band; no DFS channels */
-    public static final int WIFI_BAND_BOTH = WIFI_BAND_24_GHZ | WIFI_BAND_5_GHZ;
-    /**
-     * 2.4Ghz band + DFS channels from 5 GHz band only
-     * @hide
-     */
-    public static final int WIFI_BAND_24_GHZ_WITH_5GHZ_DFS  =
-            WIFI_BAND_24_GHZ | WIFI_BAND_5_GHZ_DFS_ONLY;
-    /** 5 GHz band including DFS channels */
-    public static final int WIFI_BAND_5_GHZ_WITH_DFS  = WIFI_BAND_5_GHZ | WIFI_BAND_5_GHZ_DFS_ONLY;
-    /** Both 2.4 GHz band and 5 GHz band; with DFS channels */
-    public static final int WIFI_BAND_BOTH_WITH_DFS =
-            WIFI_BAND_24_GHZ | WIFI_BAND_5_GHZ | WIFI_BAND_5_GHZ_DFS_ONLY;
-    /** 2.4 GHz band and 5 GHz band (no DFS channels) and 6 GHz */
-    public static final int WIFI_BAND_24_5_6_GHZ = WIFI_BAND_BOTH | WIFI_BAND_6_GHZ;
-    /** 2.4 GHz band and 5 GHz band; with DFS channels and 6 GHz */
-    public static final int WIFI_BAND_24_5_WITH_DFS_6_GHZ =
-            WIFI_BAND_BOTH_WITH_DFS | WIFI_BAND_6_GHZ;
-
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(prefix = {"WIFI_BAND_"}, value = {
-            WIFI_BAND_UNSPECIFIED,
-            WIFI_BAND_24_GHZ,
-            WIFI_BAND_5_GHZ,
-            WIFI_BAND_BOTH,
-            WIFI_BAND_5_GHZ_DFS_ONLY,
-            WIFI_BAND_24_GHZ_WITH_5GHZ_DFS,
-            WIFI_BAND_5_GHZ_WITH_DFS,
-            WIFI_BAND_BOTH_WITH_DFS,
-            WIFI_BAND_6_GHZ,
-            WIFI_BAND_24_5_6_GHZ,
-            WIFI_BAND_24_5_WITH_DFS_6_GHZ})
-    public @interface WifiBand {}
-
-    /**
-     * All bands
-     * @hide
-     */
-    public static final int WIFI_BAND_ALL = (1 << WIFI_BAND_COUNT) - 1;
-
-    /** Minimum supported scanning period */
-    public static final int MIN_SCAN_PERIOD_MS = 1000;
-    /** Maximum supported scanning period */
-    public static final int MAX_SCAN_PERIOD_MS = 1024000;
-
-    /** No Error */
-    public static final int REASON_SUCCEEDED = 0;
-    /** Unknown error */
-    public static final int REASON_UNSPECIFIED = -1;
-    /** Invalid listener */
-    public static final int REASON_INVALID_LISTENER = -2;
-    /** Invalid request */
-    public static final int REASON_INVALID_REQUEST = -3;
-    /** Invalid request */
-    public static final int REASON_NOT_AUTHORIZED = -4;
-    /** An outstanding request with the same listener hasn't finished yet. */
-    public static final int REASON_DUPLICATE_REQEUST = -5;
-
-    /** @hide */
-    public static final String GET_AVAILABLE_CHANNELS_EXTRA = "Channels";
-
-    /**
-     * Generic action callback invocation interface
-     *  @hide
-     */
-    @SystemApi
-    public static interface ActionListener {
-        public void onSuccess();
-        public void onFailure(int reason, String description);
-    }
-
-    /**
-     * Test if scan is a full scan. i.e. scanning all available bands.
-     * For backward compatibility, since some apps don't include 6GHz in their requests yet,
-     * lacking 6GHz band does not cause the result to be false.
-     *
-     * @param bandScanned bands that are fully scanned
-     * @param excludeDfs when true, DFS band is excluded from the check
-     * @return true if all bands are scanned, false otherwise
-     *
-     * @hide
-     */
-    public static boolean isFullBandScan(@WifiBand int bandScanned, boolean excludeDfs) {
-        return (bandScanned | WIFI_BAND_6_GHZ | (excludeDfs ? WIFI_BAND_5_GHZ_DFS_ONLY : 0))
-                == WIFI_BAND_ALL;
-    }
-
-    /**
-     * Returns a list of all the possible channels for the given band(s).
-     *
-     * @param band one of the WifiScanner#WIFI_BAND_* constants, e.g. {@link #WIFI_BAND_24_GHZ}
-     * @return a list of all the frequencies, in MHz, for the given band(s) e.g. channel 1 is
-     * 2412, or null if an error occurred.
-     *
-     * @hide
-     */
-    @SystemApi
-    @NonNull
-    @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
-    public List<Integer> getAvailableChannels(int band) {
-        try {
-            Bundle bundle = mService.getAvailableChannels(band, mContext.getOpPackageName(),
-                    mContext.getAttributionTag());
-            List<Integer> channels = bundle.getIntegerArrayList(GET_AVAILABLE_CHANNELS_EXTRA);
-            return channels == null ? new ArrayList<>() : channels;
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * provides channel specification for scanning
-     */
-    public static class ChannelSpec {
-        /**
-         * channel frequency in MHz; for example channel 1 is specified as 2412
-         */
-        public int frequency;
-        /**
-         * if true, scan this channel in passive fashion.
-         * This flag is ignored on DFS channel specification.
-         * @hide
-         */
-        public boolean passive;                                    /* ignored on DFS channels */
-        /**
-         * how long to dwell on this channel
-         * @hide
-         */
-        public int dwellTimeMS;                                    /* not supported for now */
-
-        /**
-         * default constructor for channel spec
-         */
-        public ChannelSpec(int frequency) {
-            this.frequency = frequency;
-            passive = false;
-            dwellTimeMS = 0;
-        }
-    }
-
-    /**
-     * reports {@link ScanListener#onResults} when underlying buffers are full
-     * this is simply the lack of the {@link #REPORT_EVENT_AFTER_EACH_SCAN} flag
-     * @deprecated It is not supported anymore.
-     */
-    @Deprecated
-    public static final int REPORT_EVENT_AFTER_BUFFER_FULL = 0;
-    /**
-     * reports {@link ScanListener#onResults} after each scan
-     */
-    public static final int REPORT_EVENT_AFTER_EACH_SCAN = (1 << 0);
-    /**
-     * reports {@link ScanListener#onFullResult} whenever each beacon is discovered
-     */
-    public static final int REPORT_EVENT_FULL_SCAN_RESULT = (1 << 1);
-    /**
-     * Do not place scans in the chip's scan history buffer
-     */
-    public static final int REPORT_EVENT_NO_BATCH = (1 << 2);
-
-    /**
-     * Optimize the scan for lower latency.
-     * @see ScanSettings#type
-     */
-    public static final int SCAN_TYPE_LOW_LATENCY = 0;
-    /**
-     * Optimize the scan for lower power usage.
-     * @see ScanSettings#type
-     */
-    public static final int SCAN_TYPE_LOW_POWER = 1;
-    /**
-     * Optimize the scan for higher accuracy.
-     * @see ScanSettings#type
-     */
-    public static final int SCAN_TYPE_HIGH_ACCURACY = 2;
-
-    /** {@hide} */
-    public static final String SCAN_PARAMS_SCAN_SETTINGS_KEY = "ScanSettings";
-    /** {@hide} */
-    public static final String SCAN_PARAMS_WORK_SOURCE_KEY = "WorkSource";
-    /** {@hide} */
-    public static final String REQUEST_PACKAGE_NAME_KEY = "PackageName";
-    /** {@hide} */
-    public static final String REQUEST_FEATURE_ID_KEY = "FeatureId";
-
-    /**
-     * scan configuration parameters to be sent to {@link #startBackgroundScan}
-     */
-    public static class ScanSettings implements Parcelable {
-        /** Hidden network to be scanned for. */
-        public static class HiddenNetwork {
-            /** SSID of the network */
-            @NonNull
-            public final String ssid;
-
-            /** Default constructor for HiddenNetwork. */
-            public HiddenNetwork(@NonNull String ssid) {
-                this.ssid = ssid;
-            }
-        }
-
-        /** one of the WIFI_BAND values */
-        public int band;
-        /** list of channels; used when band is set to WIFI_BAND_UNSPECIFIED */
-        public ChannelSpec[] channels;
-        /**
-         * List of hidden networks to scan for. Explicit probe requests are sent out for such
-         * networks during scan. Only valid for single scan requests.
-         */
-        @NonNull
-        @RequiresPermission(android.Manifest.permission.NETWORK_STACK)
-        public final List<HiddenNetwork> hiddenNetworks = new ArrayList<>();
-        /**
-         * period of background scan; in millisecond, 0 => single shot scan
-         * @deprecated Background scan support has always been hardware vendor dependent. This
-         * support may not be present on newer devices. Use {@link #startScan(ScanSettings,
-         * ScanListener)} instead for single scans.
-         */
-        @Deprecated
-        public int periodInMs;
-        /**
-         * must have a valid REPORT_EVENT value
-         * @deprecated Background scan support has always been hardware vendor dependent. This
-         * support may not be present on newer devices. Use {@link #startScan(ScanSettings,
-         * ScanListener)} instead for single scans.
-         */
-        @Deprecated
-        public int reportEvents;
-        /**
-         * defines number of bssids to cache from each scan
-         * @deprecated Background scan support has always been hardware vendor dependent. This
-         * support may not be present on newer devices. Use {@link #startScan(ScanSettings,
-         * ScanListener)} instead for single scans.
-         */
-        @Deprecated
-        public int numBssidsPerScan;
-        /**
-         * defines number of scans to cache; use it with REPORT_EVENT_AFTER_BUFFER_FULL
-         * to wake up at fixed interval
-         * @deprecated Background scan support has always been hardware vendor dependent. This
-         * support may not be present on newer devices. Use {@link #startScan(ScanSettings,
-         * ScanListener)} instead for single scans.
-         */
-        @Deprecated
-        public int maxScansToCache;
-        /**
-         * if maxPeriodInMs is non zero or different than period, then this bucket is
-         * a truncated binary exponential backoff bucket and the scan period will grow
-         * exponentially as per formula: actual_period(N) = period * (2 ^ (N/stepCount))
-         * to maxPeriodInMs
-         * @deprecated Background scan support has always been hardware vendor dependent. This
-         * support may not be present on newer devices. Use {@link #startScan(ScanSettings,
-         * ScanListener)} instead for single scans.
-         */
-        @Deprecated
-        public int maxPeriodInMs;
-        /**
-         * for truncated binary exponential back off bucket, number of scans to perform
-         * for a given period
-         * @deprecated Background scan support has always been hardware vendor dependent. This
-         * support may not be present on newer devices. Use {@link #startScan(ScanSettings,
-         * ScanListener)} instead for single scans.
-         */
-        @Deprecated
-        public int stepCount;
-        /**
-         * Flag to indicate if the scan settings are targeted for PNO scan.
-         * {@hide}
-         */
-        public boolean isPnoScan;
-        /**
-         * Indicate the type of scan to be performed by the wifi chip.
-         *
-         * On devices with multiple hardware radio chains (and hence different modes of scan),
-         * this type serves as an indication to the hardware on what mode of scan to perform.
-         * Only apps holding {@link android.Manifest.permission.NETWORK_STACK} permission can set
-         * this value.
-         *
-         * Note: This serves as an intent and not as a stipulation, the wifi chip
-         * might honor or ignore the indication based on the current radio conditions. Always
-         * use the {@link ScanResult#radioChainInfos} to figure out the radio chain configuration
-         * used to receive the corresponding scan result.
-         *
-         * One of {@link #SCAN_TYPE_LOW_LATENCY}, {@link #SCAN_TYPE_LOW_POWER},
-         * {@link #SCAN_TYPE_HIGH_ACCURACY}.
-         * Default value: {@link #SCAN_TYPE_LOW_LATENCY}.
-         */
-        @WifiAnnotations.ScanType
-        @RequiresPermission(android.Manifest.permission.NETWORK_STACK)
-        public int type = SCAN_TYPE_LOW_LATENCY;
-        /**
-         * This scan request may ignore location settings while receiving scans. This should only
-         * be used in emergency situations.
-         * {@hide}
-         */
-        @SystemApi
-        public boolean ignoreLocationSettings;
-        /**
-         * This scan request will be hidden from app-ops noting for location information. This
-         * should only be used by FLP/NLP module on the device which is using the scan results to
-         * compute results for behalf on their clients. FLP/NLP module using this flag should ensure
-         * that they note in app-ops the eventual delivery of location information computed using
-         * these results to their client .
-         * {@hide}
-         */
-        @SystemApi
-        public boolean hideFromAppOps;
-
-        /** Implement the Parcelable interface {@hide} */
-        public int describeContents() {
-            return 0;
-        }
-
-        /** Implement the Parcelable interface {@hide} */
-        public void writeToParcel(Parcel dest, int flags) {
-            dest.writeInt(band);
-            dest.writeInt(periodInMs);
-            dest.writeInt(reportEvents);
-            dest.writeInt(numBssidsPerScan);
-            dest.writeInt(maxScansToCache);
-            dest.writeInt(maxPeriodInMs);
-            dest.writeInt(stepCount);
-            dest.writeInt(isPnoScan ? 1 : 0);
-            dest.writeInt(type);
-            dest.writeInt(ignoreLocationSettings ? 1 : 0);
-            dest.writeInt(hideFromAppOps ? 1 : 0);
-            if (channels != null) {
-                dest.writeInt(channels.length);
-                for (int i = 0; i < channels.length; i++) {
-                    dest.writeInt(channels[i].frequency);
-                    dest.writeInt(channels[i].dwellTimeMS);
-                    dest.writeInt(channels[i].passive ? 1 : 0);
-                }
-            } else {
-                dest.writeInt(0);
-            }
-            dest.writeInt(hiddenNetworks.size());
-            for (HiddenNetwork hiddenNetwork : hiddenNetworks) {
-                dest.writeString(hiddenNetwork.ssid);
-            }
-        }
-
-        /** Implement the Parcelable interface {@hide} */
-        public static final @NonNull Creator<ScanSettings> CREATOR =
-                new Creator<ScanSettings>() {
-                    public ScanSettings createFromParcel(Parcel in) {
-                        ScanSettings settings = new ScanSettings();
-                        settings.band = in.readInt();
-                        settings.periodInMs = in.readInt();
-                        settings.reportEvents = in.readInt();
-                        settings.numBssidsPerScan = in.readInt();
-                        settings.maxScansToCache = in.readInt();
-                        settings.maxPeriodInMs = in.readInt();
-                        settings.stepCount = in.readInt();
-                        settings.isPnoScan = in.readInt() == 1;
-                        settings.type = in.readInt();
-                        settings.ignoreLocationSettings = in.readInt() == 1;
-                        settings.hideFromAppOps = in.readInt() == 1;
-                        int num_channels = in.readInt();
-                        settings.channels = new ChannelSpec[num_channels];
-                        for (int i = 0; i < num_channels; i++) {
-                            int frequency = in.readInt();
-                            ChannelSpec spec = new ChannelSpec(frequency);
-                            spec.dwellTimeMS = in.readInt();
-                            spec.passive = in.readInt() == 1;
-                            settings.channels[i] = spec;
-                        }
-                        int numNetworks = in.readInt();
-                        settings.hiddenNetworks.clear();
-                        for (int i = 0; i < numNetworks; i++) {
-                            String ssid = in.readString();
-                            settings.hiddenNetworks.add(new HiddenNetwork(ssid));
-                        }
-                        return settings;
-                    }
-
-                    public ScanSettings[] newArray(int size) {
-                        return new ScanSettings[size];
-                    }
-                };
-    }
-
-    /**
-     * all the information garnered from a single scan
-     */
-    public static class ScanData implements Parcelable {
-        /** scan identifier */
-        private int mId;
-        /** additional information about scan
-         * 0 => no special issues encountered in the scan
-         * non-zero => scan was truncated, so results may not be complete
-         */
-        private int mFlags;
-        /**
-         * Indicates the buckets that were scanned to generate these results.
-         * This is not relevant to WifiScanner API users and is used internally.
-         * {@hide}
-         */
-        private int mBucketsScanned;
-        /**
-         * Bands scanned. One of the WIFI_BAND values.
-         * Will be {@link #WIFI_BAND_UNSPECIFIED} if the list of channels do not fully cover
-         * any of the bands.
-         * {@hide}
-         */
-        private int mBandScanned;
-        /** all scan results discovered in this scan, sorted by timestamp in ascending order */
-        private final List<ScanResult> mResults;
-
-        ScanData() {
-            mResults = new ArrayList<>();
-        }
-
-        public ScanData(int id, int flags, ScanResult[] results) {
-            mId = id;
-            mFlags = flags;
-            mResults = new ArrayList<>(Arrays.asList(results));
-        }
-
-        /** {@hide} */
-        public ScanData(int id, int flags, int bucketsScanned, int bandScanned,
-                        ScanResult[] results) {
-            this(id, flags, bucketsScanned, bandScanned, new ArrayList<>(Arrays.asList(results)));
-        }
-
-        /** {@hide} */
-        public ScanData(int id, int flags, int bucketsScanned, int bandScanned,
-                        List<ScanResult> results) {
-            mId = id;
-            mFlags = flags;
-            mBucketsScanned = bucketsScanned;
-            mBandScanned = bandScanned;
-            mResults = results;
-        }
-
-        public ScanData(ScanData s) {
-            mId = s.mId;
-            mFlags = s.mFlags;
-            mBucketsScanned = s.mBucketsScanned;
-            mBandScanned = s.mBandScanned;
-            mResults = new ArrayList<>();
-            for (ScanResult scanResult : s.mResults) {
-                mResults.add(new ScanResult(scanResult));
-            }
-        }
-
-        public int getId() {
-            return mId;
-        }
-
-        public int getFlags() {
-            return mFlags;
-        }
-
-        /** {@hide} */
-        public int getBucketsScanned() {
-            return mBucketsScanned;
-        }
-
-        /** {@hide} */
-        public int getBandScanned() {
-            return mBandScanned;
-        }
-
-        public ScanResult[] getResults() {
-            return mResults.toArray(new ScanResult[0]);
-        }
-
-        /** {@hide} */
-        public void addResults(@NonNull ScanResult[] newResults) {
-            for (ScanResult result : newResults) {
-                mResults.add(new ScanResult(result));
-            }
-        }
-
-        /** Implement the Parcelable interface {@hide} */
-        public int describeContents() {
-            return 0;
-        }
-
-        /** Implement the Parcelable interface {@hide} */
-        public void writeToParcel(Parcel dest, int flags) {
-            dest.writeInt(mId);
-            dest.writeInt(mFlags);
-            dest.writeInt(mBucketsScanned);
-            dest.writeInt(mBandScanned);
-            dest.writeParcelableList(mResults, 0);
-        }
-
-        /** Implement the Parcelable interface {@hide} */
-        public static final @NonNull Creator<ScanData> CREATOR =
-                new Creator<ScanData>() {
-                    public ScanData createFromParcel(Parcel in) {
-                        int id = in.readInt();
-                        int flags = in.readInt();
-                        int bucketsScanned = in.readInt();
-                        int bandScanned = in.readInt();
-                        List<ScanResult> results = new ArrayList<>();
-                        in.readParcelableList(results, ScanResult.class.getClassLoader());
-                        return new ScanData(id, flags, bucketsScanned, bandScanned, results);
-                    }
-
-                    public ScanData[] newArray(int size) {
-                        return new ScanData[size];
-                    }
-                };
-    }
-
-    public static class ParcelableScanData implements Parcelable {
-
-        public ScanData mResults[];
-
-        public ParcelableScanData(ScanData[] results) {
-            mResults = results;
-        }
-
-        public ScanData[] getResults() {
-            return mResults;
-        }
-
-        /** Implement the Parcelable interface {@hide} */
-        public int describeContents() {
-            return 0;
-        }
-
-        /** Implement the Parcelable interface {@hide} */
-        public void writeToParcel(Parcel dest, int flags) {
-            if (mResults != null) {
-                dest.writeInt(mResults.length);
-                for (int i = 0; i < mResults.length; i++) {
-                    ScanData result = mResults[i];
-                    result.writeToParcel(dest, flags);
-                }
-            } else {
-                dest.writeInt(0);
-            }
-        }
-
-        /** Implement the Parcelable interface {@hide} */
-        public static final @NonNull Creator<ParcelableScanData> CREATOR =
-                new Creator<ParcelableScanData>() {
-                    public ParcelableScanData createFromParcel(Parcel in) {
-                        int n = in.readInt();
-                        ScanData results[] = new ScanData[n];
-                        for (int i = 0; i < n; i++) {
-                            results[i] = ScanData.CREATOR.createFromParcel(in);
-                        }
-                        return new ParcelableScanData(results);
-                    }
-
-                    public ParcelableScanData[] newArray(int size) {
-                        return new ParcelableScanData[size];
-                    }
-                };
-    }
-
-    public static class ParcelableScanResults implements Parcelable {
-
-        public ScanResult mResults[];
-
-        public ParcelableScanResults(ScanResult[] results) {
-            mResults = results;
-        }
-
-        public ScanResult[] getResults() {
-            return mResults;
-        }
-
-        /** Implement the Parcelable interface {@hide} */
-        public int describeContents() {
-            return 0;
-        }
-
-        /** Implement the Parcelable interface {@hide} */
-        public void writeToParcel(Parcel dest, int flags) {
-            if (mResults != null) {
-                dest.writeInt(mResults.length);
-                for (int i = 0; i < mResults.length; i++) {
-                    ScanResult result = mResults[i];
-                    result.writeToParcel(dest, flags);
-                }
-            } else {
-                dest.writeInt(0);
-            }
-        }
-
-        /** Implement the Parcelable interface {@hide} */
-        public static final @NonNull Creator<ParcelableScanResults> CREATOR =
-                new Creator<ParcelableScanResults>() {
-                    public ParcelableScanResults createFromParcel(Parcel in) {
-                        int n = in.readInt();
-                        ScanResult results[] = new ScanResult[n];
-                        for (int i = 0; i < n; i++) {
-                            results[i] = ScanResult.CREATOR.createFromParcel(in);
-                        }
-                        return new ParcelableScanResults(results);
-                    }
-
-                    public ParcelableScanResults[] newArray(int size) {
-                        return new ParcelableScanResults[size];
-                    }
-                };
-    }
-
-    /** {@hide} */
-    public static final String PNO_PARAMS_PNO_SETTINGS_KEY = "PnoSettings";
-    /** {@hide} */
-    public static final String PNO_PARAMS_SCAN_SETTINGS_KEY = "ScanSettings";
-    /**
-     * PNO scan configuration parameters to be sent to {@link #startPnoScan}.
-     * Note: This structure needs to be in sync with |wifi_epno_params| struct in gscan HAL API.
-     * {@hide}
-     */
-    public static class PnoSettings implements Parcelable {
-        /**
-         * Pno network to be added to the PNO scan filtering.
-         * {@hide}
-         */
-        public static class PnoNetwork {
-            /*
-             * Pno flags bitmask to be set in {@link #PnoNetwork.flags}
-             */
-            /** Whether directed scan needs to be performed (for hidden SSIDs) */
-            public static final byte FLAG_DIRECTED_SCAN = (1 << 0);
-            /** Whether PNO event shall be triggered if the network is found on A band */
-            public static final byte FLAG_A_BAND = (1 << 1);
-            /** Whether PNO event shall be triggered if the network is found on G band */
-            public static final byte FLAG_G_BAND = (1 << 2);
-            /**
-             * Whether strict matching is required
-             * If required then the firmware must store the network's SSID and not just a hash
-             */
-            public static final byte FLAG_STRICT_MATCH = (1 << 3);
-            /**
-             * If this SSID should be considered the same network as the currently connected
-             * one for scoring.
-             */
-            public static final byte FLAG_SAME_NETWORK = (1 << 4);
-
-            /*
-             * Code for matching the beacon AUTH IE - additional codes. Bitmask to be set in
-             * {@link #PnoNetwork.authBitField}
-             */
-            /** Open Network */
-            public static final byte AUTH_CODE_OPEN = (1 << 0);
-            /** WPA_PSK or WPA2PSK */
-            public static final byte AUTH_CODE_PSK = (1 << 1);
-            /** any EAPOL */
-            public static final byte AUTH_CODE_EAPOL = (1 << 2);
-
-            /** SSID of the network */
-            public String ssid;
-            /** Bitmask of the FLAG_XXX */
-            public byte flags = 0;
-            /** Bitmask of the ATUH_XXX */
-            public byte authBitField = 0;
-            /** frequencies on which the particular network needs to be scanned for */
-            public int[] frequencies = {};
-
-            /**
-             * default constructor for PnoNetwork
-             */
-            public PnoNetwork(String ssid) {
-                this.ssid = ssid;
-            }
-
-            @Override
-            public int hashCode() {
-                return Objects.hash(ssid, flags, authBitField);
-            }
-
-            @Override
-            public boolean equals(Object obj) {
-                if (this == obj) {
-                    return true;
-                }
-                if (!(obj instanceof PnoNetwork)) {
-                    return false;
-                }
-                PnoNetwork lhs = (PnoNetwork) obj;
-                return TextUtils.equals(this.ssid, lhs.ssid)
-                        && this.flags == lhs.flags
-                        && this.authBitField == lhs.authBitField;
-            }
-        }
-
-        /** Connected vs Disconnected PNO flag {@hide} */
-        public boolean isConnected;
-        /** Minimum 5GHz RSSI for a BSSID to be considered */
-        public int min5GHzRssi;
-        /** Minimum 2.4GHz RSSI for a BSSID to be considered */
-        public int min24GHzRssi;
-        /** Minimum 6GHz RSSI for a BSSID to be considered */
-        public int min6GHzRssi;
-        /** Pno Network filter list */
-        public PnoNetwork[] networkList;
-
-        /** Implement the Parcelable interface {@hide} */
-        public int describeContents() {
-            return 0;
-        }
-
-        /** Implement the Parcelable interface {@hide} */
-        public void writeToParcel(Parcel dest, int flags) {
-            dest.writeInt(isConnected ? 1 : 0);
-            dest.writeInt(min5GHzRssi);
-            dest.writeInt(min24GHzRssi);
-            dest.writeInt(min6GHzRssi);
-            if (networkList != null) {
-                dest.writeInt(networkList.length);
-                for (int i = 0; i < networkList.length; i++) {
-                    dest.writeString(networkList[i].ssid);
-                    dest.writeByte(networkList[i].flags);
-                    dest.writeByte(networkList[i].authBitField);
-                    dest.writeIntArray(networkList[i].frequencies);
-                }
-            } else {
-                dest.writeInt(0);
-            }
-        }
-
-        /** Implement the Parcelable interface {@hide} */
-        public static final @NonNull Creator<PnoSettings> CREATOR =
-                new Creator<PnoSettings>() {
-                    public PnoSettings createFromParcel(Parcel in) {
-                        PnoSettings settings = new PnoSettings();
-                        settings.isConnected = in.readInt() == 1;
-                        settings.min5GHzRssi = in.readInt();
-                        settings.min24GHzRssi = in.readInt();
-                        settings.min6GHzRssi = in.readInt();
-                        int numNetworks = in.readInt();
-                        settings.networkList = new PnoNetwork[numNetworks];
-                        for (int i = 0; i < numNetworks; i++) {
-                            String ssid = in.readString();
-                            PnoNetwork network = new PnoNetwork(ssid);
-                            network.flags = in.readByte();
-                            network.authBitField = in.readByte();
-                            network.frequencies = in.createIntArray();
-                            settings.networkList[i] = network;
-                        }
-                        return settings;
-                    }
-
-                    public PnoSettings[] newArray(int size) {
-                        return new PnoSettings[size];
-                    }
-                };
-
-    }
-
-    /**
-     * interface to get scan events on; specify this on {@link #startBackgroundScan} or
-     * {@link #startScan}
-     */
-    public interface ScanListener extends ActionListener {
-        /**
-         * Framework co-ordinates scans across multiple apps; so it may not give exactly the
-         * same period requested. If period of a scan is changed; it is reported by this event.
-         * @deprecated Background scan support has always been hardware vendor dependent. This
-         * support may not be present on newer devices. Use {@link #startScan(ScanSettings,
-         * ScanListener)} instead for single scans.
-         */
-        @Deprecated
-        public void onPeriodChanged(int periodInMs);
-        /**
-         * reports results retrieved from background scan and single shot scans
-         */
-        public void onResults(ScanData[] results);
-        /**
-         * reports full scan result for each access point found in scan
-         */
-        public void onFullResult(ScanResult fullScanResult);
-    }
-
-    /**
-     * interface to get PNO scan events on; specify this on {@link #startDisconnectedPnoScan} and
-     * {@link #startConnectedPnoScan}.
-     * {@hide}
-     */
-    public interface PnoScanListener extends ScanListener {
-        /**
-         * Invoked when one of the PNO networks are found in scan results.
-         */
-        void onPnoNetworkFound(ScanResult[] results);
-    }
-
-    /**
-     * Enable/Disable wifi scanning.
-     *
-     * @param enable set to true to enable scanning, set to false to disable all types of scanning.
-     *
-     * @see WifiManager#ACTION_WIFI_SCAN_AVAILABILITY_CHANGED
-     * {@hide}
-     */
-    @SystemApi
-    @RequiresPermission(Manifest.permission.NETWORK_STACK)
-    public void setScanningEnabled(boolean enable) {
-        validateChannel();
-        mAsyncChannel.sendMessage(enable ? CMD_ENABLE : CMD_DISABLE);
-    }
-
-    /**
-     * Register a listener that will receive results from all single scans.
-     * Either the {@link ScanListener#onSuccess()} or  {@link ScanListener#onFailure(int, String)}
-     * method will be called once when the listener is registered.
-     * Afterwards (assuming onSuccess was called), all subsequent single scan results will be
-     * delivered to the listener. It is possible that onFullResult will not be called for all
-     * results of the first scan if the listener was registered during the scan.
-     *
-     * @param executor the Executor on which to run the callback.
-     * @param listener specifies the object to report events to. This object is also treated as a
-     *                 key for this request, and must also be specified to cancel the request.
-     *                 Multiple requests should also not share this object.
-     */
-    @RequiresPermission(Manifest.permission.NETWORK_STACK)
-    public void registerScanListener(@NonNull @CallbackExecutor Executor executor,
-            @NonNull ScanListener listener) {
-        Objects.requireNonNull(executor, "executor cannot be null");
-        Objects.requireNonNull(listener, "listener cannot be null");
-        int key = addListener(listener, executor);
-        if (key == INVALID_KEY) return;
-        validateChannel();
-        mAsyncChannel.sendMessage(CMD_REGISTER_SCAN_LISTENER, 0, key);
-    }
-
-    /**
-     * Overload of {@link #registerScanListener(Executor, ScanListener)} that executes the callback
-     * synchronously.
-     * @hide
-     */
-    @RequiresPermission(Manifest.permission.NETWORK_STACK)
-    public void registerScanListener(@NonNull ScanListener listener) {
-        registerScanListener(new SynchronousExecutor(), listener);
-    }
-
-    /**
-     * Deregister a listener for ongoing single scans
-     * @param listener specifies which scan to cancel; must be same object as passed in {@link
-     *  #registerScanListener}
-     */
-    public void unregisterScanListener(@NonNull ScanListener listener) {
-        Objects.requireNonNull(listener, "listener cannot be null");
-        int key = removeListener(listener);
-        if (key == INVALID_KEY) return;
-        validateChannel();
-        mAsyncChannel.sendMessage(CMD_DEREGISTER_SCAN_LISTENER, 0, key);
-    }
-
-    /** start wifi scan in background
-     * @param settings specifies various parameters for the scan; for more information look at
-     * {@link ScanSettings}
-     * @param listener specifies the object to report events to. This object is also treated as a
-     *                 key for this scan, and must also be specified to cancel the scan. Multiple
-     *                 scans should also not share this object.
-     */
-    @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
-    public void startBackgroundScan(ScanSettings settings, ScanListener listener) {
-        startBackgroundScan(settings, listener, null);
-    }
-
-    /** start wifi scan in background
-     * @param settings specifies various parameters for the scan; for more information look at
-     * {@link ScanSettings}
-     * @param workSource WorkSource to blame for power usage
-     * @param listener specifies the object to report events to. This object is also treated as a
-     *                 key for this scan, and must also be specified to cancel the scan. Multiple
-     *                 scans should also not share this object.
-     * @deprecated Background scan support has always been hardware vendor dependent. This support
-     * may not be present on newer devices. Use {@link #startScan(ScanSettings, ScanListener)}
-     * instead for single scans.
-     */
-    @Deprecated
-    @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
-    public void startBackgroundScan(ScanSettings settings, ScanListener listener,
-            WorkSource workSource) {
-        Objects.requireNonNull(listener, "listener cannot be null");
-        int key = addListener(listener);
-        if (key == INVALID_KEY) return;
-        validateChannel();
-        Bundle scanParams = new Bundle();
-        scanParams.putParcelable(SCAN_PARAMS_SCAN_SETTINGS_KEY, settings);
-        scanParams.putParcelable(SCAN_PARAMS_WORK_SOURCE_KEY, workSource);
-        scanParams.putString(REQUEST_PACKAGE_NAME_KEY, mContext.getOpPackageName());
-        scanParams.putString(REQUEST_FEATURE_ID_KEY, mContext.getAttributionTag());
-        mAsyncChannel.sendMessage(CMD_START_BACKGROUND_SCAN, 0, key, scanParams);
-    }
-
-    /**
-     * stop an ongoing wifi scan
-     * @param listener specifies which scan to cancel; must be same object as passed in {@link
-     *  #startBackgroundScan}
-     * @deprecated Background scan support has always been hardware vendor dependent. This support
-     * may not be present on newer devices. Use {@link #startScan(ScanSettings, ScanListener)}
-     * instead for single scans.
-     */
-    @Deprecated
-    @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
-    public void stopBackgroundScan(ScanListener listener) {
-        Objects.requireNonNull(listener, "listener cannot be null");
-        int key = removeListener(listener);
-        if (key == INVALID_KEY) return;
-        validateChannel();
-        Bundle scanParams = new Bundle();
-        scanParams.putString(REQUEST_PACKAGE_NAME_KEY, mContext.getOpPackageName());
-        scanParams.putString(REQUEST_FEATURE_ID_KEY, mContext.getAttributionTag());
-        mAsyncChannel.sendMessage(CMD_STOP_BACKGROUND_SCAN, 0, key, scanParams);
-    }
-
-    /**
-     * reports currently available scan results on appropriate listeners
-     * @return true if all scan results were reported correctly
-     * @deprecated Background scan support has always been hardware vendor dependent. This support
-     * may not be present on newer devices. Use {@link #startScan(ScanSettings, ScanListener)}
-     * instead for single scans.
-     */
-    @Deprecated
-    @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
-    public boolean getScanResults() {
-        validateChannel();
-        Bundle scanParams = new Bundle();
-        scanParams.putString(REQUEST_PACKAGE_NAME_KEY, mContext.getOpPackageName());
-        scanParams.putString(REQUEST_FEATURE_ID_KEY, mContext.getAttributionTag());
-        Message reply =
-                mAsyncChannel.sendMessageSynchronously(CMD_GET_SCAN_RESULTS, 0, 0, scanParams);
-        return reply.what == CMD_OP_SUCCEEDED;
-    }
-
-    /**
-     * starts a single scan and reports results asynchronously
-     * @param settings specifies various parameters for the scan; for more information look at
-     * {@link ScanSettings}
-     * @param listener specifies the object to report events to. This object is also treated as a
-     *                 key for this scan, and must also be specified to cancel the scan. Multiple
-     *                 scans should also not share this object.
-     */
-    @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
-    public void startScan(ScanSettings settings, ScanListener listener) {
-        startScan(settings, listener, null);
-    }
-
-    /**
-     * starts a single scan and reports results asynchronously
-     * @param settings specifies various parameters for the scan; for more information look at
-     * {@link ScanSettings}
-     * @param listener specifies the object to report events to. This object is also treated as a
-     *                 key for this scan, and must also be specified to cancel the scan. Multiple
-     *                 scans should also not share this object.
-     * @param workSource WorkSource to blame for power usage
-     */
-    @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
-    public void startScan(ScanSettings settings, ScanListener listener, WorkSource workSource) {
-        startScan(settings, null, listener, workSource);
-    }
-
-    /**
-     * starts a single scan and reports results asynchronously
-     * @param settings specifies various parameters for the scan; for more information look at
-     * {@link ScanSettings}
-     * @param executor the Executor on which to run the callback.
-     * @param listener specifies the object to report events to. This object is also treated as a
-     *                 key for this scan, and must also be specified to cancel the scan. Multiple
-     *                 scans should also not share this object.
-     * @param workSource WorkSource to blame for power usage
-     * @hide
-     */
-    @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
-    public void startScan(ScanSettings settings, @Nullable @CallbackExecutor Executor executor,
-            ScanListener listener, WorkSource workSource) {
-        Objects.requireNonNull(listener, "listener cannot be null");
-        int key = addListener(listener, executor);
-        if (key == INVALID_KEY) return;
-        validateChannel();
-        Bundle scanParams = new Bundle();
-        scanParams.putParcelable(SCAN_PARAMS_SCAN_SETTINGS_KEY, settings);
-        scanParams.putParcelable(SCAN_PARAMS_WORK_SOURCE_KEY, workSource);
-        scanParams.putString(REQUEST_PACKAGE_NAME_KEY, mContext.getOpPackageName());
-        scanParams.putString(REQUEST_FEATURE_ID_KEY, mContext.getAttributionTag());
-        mAsyncChannel.sendMessage(CMD_START_SINGLE_SCAN, 0, key, scanParams);
-    }
-
-    /**
-     * stops an ongoing single shot scan; only useful after {@link #startScan} if onResults()
-     * hasn't been called on the listener, ignored otherwise
-     * @param listener
-     */
-    @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
-    public void stopScan(ScanListener listener) {
-        Objects.requireNonNull(listener, "listener cannot be null");
-        int key = removeListener(listener);
-        if (key == INVALID_KEY) return;
-        validateChannel();
-        Bundle scanParams = new Bundle();
-        scanParams.putString(REQUEST_PACKAGE_NAME_KEY, mContext.getOpPackageName());
-        scanParams.putString(REQUEST_FEATURE_ID_KEY, mContext.getAttributionTag());
-        mAsyncChannel.sendMessage(CMD_STOP_SINGLE_SCAN, 0, key, scanParams);
-    }
-
-    /**
-     * Retrieve the most recent scan results from a single scan request.
-     */
-    @NonNull
-    @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
-    public List<ScanResult> getSingleScanResults() {
-        validateChannel();
-        Bundle scanParams = new Bundle();
-        scanParams.putString(REQUEST_PACKAGE_NAME_KEY, mContext.getOpPackageName());
-        scanParams.putString(REQUEST_FEATURE_ID_KEY, mContext.getAttributionTag());
-        Message reply = mAsyncChannel.sendMessageSynchronously(CMD_GET_SINGLE_SCAN_RESULTS, 0, 0,
-                scanParams);
-        if (reply.what == WifiScanner.CMD_OP_SUCCEEDED) {
-            return Arrays.asList(((ParcelableScanResults) reply.obj).getResults());
-        }
-        OperationResult result = (OperationResult) reply.obj;
-        Log.e(TAG, "Error retrieving SingleScan results reason: " + result.reason
-                + " description: " + result.description);
-        return new ArrayList<>();
-    }
-
-    private void startPnoScan(ScanSettings scanSettings, PnoSettings pnoSettings, int key) {
-        // Bundle up both the settings and send it across.
-        Bundle pnoParams = new Bundle();
-        // Set the PNO scan flag.
-        scanSettings.isPnoScan = true;
-        pnoParams.putParcelable(PNO_PARAMS_SCAN_SETTINGS_KEY, scanSettings);
-        pnoParams.putParcelable(PNO_PARAMS_PNO_SETTINGS_KEY, pnoSettings);
-        mAsyncChannel.sendMessage(CMD_START_PNO_SCAN, 0, key, pnoParams);
-    }
-    /**
-     * Start wifi connected PNO scan
-     * @param scanSettings specifies various parameters for the scan; for more information look at
-     * {@link ScanSettings}
-     * @param pnoSettings specifies various parameters for PNO; for more information look at
-     * {@link PnoSettings}
-     * @param executor the Executor on which to run the callback.
-     * @param listener specifies the object to report events to. This object is also treated as a
-     *                 key for this scan, and must also be specified to cancel the scan. Multiple
-     *                 scans should also not share this object.
-     * {@hide}
-     */
-    public void startConnectedPnoScan(ScanSettings scanSettings, PnoSettings pnoSettings,
-            @NonNull @CallbackExecutor Executor executor, PnoScanListener listener) {
-        Objects.requireNonNull(listener, "listener cannot be null");
-        Objects.requireNonNull(pnoSettings, "pnoSettings cannot be null");
-        int key = addListener(listener, executor);
-        if (key == INVALID_KEY) return;
-        validateChannel();
-        pnoSettings.isConnected = true;
-        startPnoScan(scanSettings, pnoSettings, key);
-    }
-    /**
-     * Start wifi disconnected PNO scan
-     * @param scanSettings specifies various parameters for the scan; for more information look at
-     * {@link ScanSettings}
-     * @param pnoSettings specifies various parameters for PNO; for more information look at
-     * {@link PnoSettings}
-     * @param listener specifies the object to report events to. This object is also treated as a
-     *                 key for this scan, and must also be specified to cancel the scan. Multiple
-     *                 scans should also not share this object.
-     * {@hide}
-     */
-    @RequiresPermission(android.Manifest.permission.NETWORK_STACK)
-    public void startDisconnectedPnoScan(ScanSettings scanSettings, PnoSettings pnoSettings,
-            @NonNull @CallbackExecutor Executor executor, PnoScanListener listener) {
-        Objects.requireNonNull(listener, "listener cannot be null");
-        Objects.requireNonNull(pnoSettings, "pnoSettings cannot be null");
-        int key = addListener(listener, executor);
-        if (key == INVALID_KEY) return;
-        validateChannel();
-        pnoSettings.isConnected = false;
-        startPnoScan(scanSettings, pnoSettings, key);
-    }
-    /**
-     * Stop an ongoing wifi PNO scan
-     * @param listener specifies which scan to cancel; must be same object as passed in {@link
-     *  #startPnoScan}
-     * {@hide}
-     */
-    @RequiresPermission(android.Manifest.permission.NETWORK_STACK)
-    public void stopPnoScan(ScanListener listener) {
-        Objects.requireNonNull(listener, "listener cannot be null");
-        int key = removeListener(listener);
-        if (key == INVALID_KEY) return;
-        validateChannel();
-        mAsyncChannel.sendMessage(CMD_STOP_PNO_SCAN, 0, key);
-    }
-
-    /** specifies information about an access point of interest */
-    @Deprecated
-    public static class BssidInfo {
-        /** bssid of the access point; in XX:XX:XX:XX:XX:XX format */
-        public String bssid;
-        /** low signal strength threshold; more information at {@link ScanResult#level} */
-        public int low;                                            /* minimum RSSI */
-        /** high signal threshold; more information at {@link ScanResult#level} */
-        public int high;                                           /* maximum RSSI */
-        /** channel frequency (in KHz) where you may find this BSSID */
-        public int frequencyHint;
-    }
-
-    /** @hide */
-    @SystemApi
-    @Deprecated
-    public static class WifiChangeSettings implements Parcelable {
-        public int rssiSampleSize;                          /* sample size for RSSI averaging */
-        public int lostApSampleSize;                        /* samples to confirm AP's loss */
-        public int unchangedSampleSize;                     /* samples to confirm no change */
-        public int minApsBreachingThreshold;                /* change threshold to trigger event */
-        public int periodInMs;                              /* scan period in millisecond */
-        public BssidInfo[] bssidInfos;
-
-        /** Implement the Parcelable interface {@hide} */
-        public int describeContents() {
-            return 0;
-        }
-
-        /** Implement the Parcelable interface {@hide} */
-        public void writeToParcel(Parcel dest, int flags) {
-        }
-
-        /** Implement the Parcelable interface {@hide} */
-        public static final @NonNull Creator<WifiChangeSettings> CREATOR =
-                new Creator<WifiChangeSettings>() {
-                    public WifiChangeSettings createFromParcel(Parcel in) {
-                        return new WifiChangeSettings();
-                    }
-
-                    public WifiChangeSettings[] newArray(int size) {
-                        return new WifiChangeSettings[size];
-                    }
-                };
-
-    }
-
-    /** configure WifiChange detection
-     * @param rssiSampleSize number of samples used for RSSI averaging
-     * @param lostApSampleSize number of samples to confirm an access point's loss
-     * @param unchangedSampleSize number of samples to confirm there are no changes
-     * @param minApsBreachingThreshold minimum number of access points that need to be
-     *                                 out of range to detect WifiChange
-     * @param periodInMs indicates period of scan to find changes
-     * @param bssidInfos access points to watch
-     */
-    @Deprecated
-    @SuppressLint("Doclava125")
-    public void configureWifiChange(
-            int rssiSampleSize,                             /* sample size for RSSI averaging */
-            int lostApSampleSize,                           /* samples to confirm AP's loss */
-            int unchangedSampleSize,                        /* samples to confirm no change */
-            int minApsBreachingThreshold,                   /* change threshold to trigger event */
-            int periodInMs,                                 /* period of scan */
-            BssidInfo[] bssidInfos                          /* signal thresholds to cross */
-            )
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * interface to get wifi change events on; use this on {@link #startTrackingWifiChange}
-     */
-    @Deprecated
-    public interface WifiChangeListener extends ActionListener {
-        /** indicates that changes were detected in wifi environment
-         * @param results indicate the access points that exhibited change
-         */
-        public void onChanging(ScanResult[] results);           /* changes are found */
-        /** indicates that no wifi changes are being detected for a while
-         * @param results indicate the access points that are bing monitored for change
-         */
-        public void onQuiescence(ScanResult[] results);         /* changes settled down */
-    }
-
-    /**
-     * track changes in wifi environment
-     * @param listener object to report events on; this object must be unique and must also be
-     *                 provided on {@link #stopTrackingWifiChange}
-     */
-    @Deprecated
-    @SuppressLint("Doclava125")
-    public void startTrackingWifiChange(WifiChangeListener listener) {
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * stop tracking changes in wifi environment
-     * @param listener object that was provided to report events on {@link
-     * #stopTrackingWifiChange}
-     */
-    @Deprecated
-    @SuppressLint("Doclava125")
-    public void stopTrackingWifiChange(WifiChangeListener listener) {
-        throw new UnsupportedOperationException();
-    }
-
-    /** @hide */
-    @SystemApi
-    @Deprecated
-    @SuppressLint("Doclava125")
-    public void configureWifiChange(WifiChangeSettings settings) {
-        throw new UnsupportedOperationException();
-    }
-
-    /** interface to receive hotlist events on; use this on {@link #setHotlist} */
-    @Deprecated
-    public static interface BssidListener extends ActionListener {
-        /** indicates that access points were found by on going scans
-         * @param results list of scan results, one for each access point visible currently
-         */
-        public void onFound(ScanResult[] results);
-        /** indicates that access points were missed by on going scans
-         * @param results list of scan results, for each access point that is not visible anymore
-         */
-        public void onLost(ScanResult[] results);
-    }
-
-    /** @hide */
-    @SystemApi
-    @Deprecated
-    public static class HotlistSettings implements Parcelable {
-        public BssidInfo[] bssidInfos;
-        public int apLostThreshold;
-
-        /** Implement the Parcelable interface {@hide} */
-        public int describeContents() {
-            return 0;
-        }
-
-        /** Implement the Parcelable interface {@hide} */
-        public void writeToParcel(Parcel dest, int flags) {
-        }
-
-        /** Implement the Parcelable interface {@hide} */
-        public static final @NonNull Creator<HotlistSettings> CREATOR =
-                new Creator<HotlistSettings>() {
-                    public HotlistSettings createFromParcel(Parcel in) {
-                        HotlistSettings settings = new HotlistSettings();
-                        return settings;
-                    }
-
-                    public HotlistSettings[] newArray(int size) {
-                        return new HotlistSettings[size];
-                    }
-                };
-    }
-
-    /**
-     * set interesting access points to find
-     * @param bssidInfos access points of interest
-     * @param apLostThreshold number of scans needed to indicate that AP is lost
-     * @param listener object provided to report events on; this object must be unique and must
-     *                 also be provided on {@link #stopTrackingBssids}
-     */
-    @Deprecated
-    @SuppressLint("Doclava125")
-    public void startTrackingBssids(BssidInfo[] bssidInfos,
-                                    int apLostThreshold, BssidListener listener) {
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * remove tracking of interesting access points
-     * @param listener same object provided in {@link #startTrackingBssids}
-     */
-    @Deprecated
-    @SuppressLint("Doclava125")
-    public void stopTrackingBssids(BssidListener listener) {
-        throw new UnsupportedOperationException();
-    }
-
-
-    /* private members and methods */
-
-    private static final String TAG = "WifiScanner";
-    private static final boolean DBG = false;
-
-    /* commands for Wifi Service */
-    private static final int BASE = Protocol.BASE_WIFI_SCANNER;
-
-    /** @hide */
-    public static final int CMD_START_BACKGROUND_SCAN       = BASE + 2;
-    /** @hide */
-    public static final int CMD_STOP_BACKGROUND_SCAN        = BASE + 3;
-    /** @hide */
-    public static final int CMD_GET_SCAN_RESULTS            = BASE + 4;
-    /** @hide */
-    public static final int CMD_SCAN_RESULT                 = BASE + 5;
-    /** @hide */
-    public static final int CMD_OP_SUCCEEDED                = BASE + 17;
-    /** @hide */
-    public static final int CMD_OP_FAILED                   = BASE + 18;
-    /** @hide */
-    public static final int CMD_FULL_SCAN_RESULT            = BASE + 20;
-    /** @hide */
-    public static final int CMD_START_SINGLE_SCAN           = BASE + 21;
-    /** @hide */
-    public static final int CMD_STOP_SINGLE_SCAN            = BASE + 22;
-    /** @hide */
-    public static final int CMD_SINGLE_SCAN_COMPLETED       = BASE + 23;
-    /** @hide */
-    public static final int CMD_START_PNO_SCAN              = BASE + 24;
-    /** @hide */
-    public static final int CMD_STOP_PNO_SCAN               = BASE + 25;
-    /** @hide */
-    public static final int CMD_PNO_NETWORK_FOUND           = BASE + 26;
-    /** @hide */
-    public static final int CMD_REGISTER_SCAN_LISTENER      = BASE + 27;
-    /** @hide */
-    public static final int CMD_DEREGISTER_SCAN_LISTENER    = BASE + 28;
-    /** @hide */
-    public static final int CMD_GET_SINGLE_SCAN_RESULTS     = BASE + 29;
-    /** @hide */
-    public static final int CMD_ENABLE                      = BASE + 30;
-    /** @hide */
-    public static final int CMD_DISABLE                     = BASE + 31;
-
-    private Context mContext;
-    private IWifiScanner mService;
-
-    private static final int INVALID_KEY = 0;
-    private int mListenerKey = 1;
-
-    private final SparseArray mListenerMap = new SparseArray();
-    private final SparseArray<Executor> mExecutorMap = new SparseArray<>();
-    private final Object mListenerMapLock = new Object();
-
-    private AsyncChannel mAsyncChannel;
-    private final Handler mInternalHandler;
-
-    /**
-     * Create a new WifiScanner instance.
-     * Applications will almost always want to use
-     * {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve
-     * the standard {@link android.content.Context#WIFI_SERVICE Context.WIFI_SERVICE}.
-     *
-     * @param context the application context
-     * @param service the Binder interface for {@link Context#WIFI_SCANNING_SERVICE}
-     * @param looper the Looper used to deliver callbacks
-     *
-     * @hide
-     */
-    public WifiScanner(@NonNull Context context, @NonNull IWifiScanner service,
-            @NonNull Looper looper) {
-        mContext = context;
-        mService = service;
-
-        Messenger messenger = null;
-        try {
-            messenger = mService.getMessenger();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-
-        if (messenger == null) {
-            throw new IllegalStateException("getMessenger() returned null!  This is invalid.");
-        }
-
-        mAsyncChannel = new AsyncChannel();
-
-        mInternalHandler = new ServiceHandler(looper);
-        mAsyncChannel.connectSync(mContext, mInternalHandler, messenger);
-        // We cannot use fullyConnectSync because it sends the FULL_CONNECTION message
-        // synchronously, which causes WifiScanningService to receive the wrong replyTo value.
-        mAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
-    }
-
-    private void validateChannel() {
-        if (mAsyncChannel == null) throw new IllegalStateException(
-                "No permission to access and change wifi or a bad initialization");
-    }
-
-    private int addListener(ActionListener listener) {
-        return addListener(listener, null);
-    }
-
-    // Add a listener into listener map. If the listener already exists, return INVALID_KEY and
-    // send an error message to internal handler; Otherwise add the listener to the listener map and
-    // return the key of the listener.
-    private int addListener(ActionListener listener, Executor executor) {
-        synchronized (mListenerMapLock) {
-            boolean keyExists = (getListenerKey(listener) != INVALID_KEY);
-            // Note we need to put the listener into listener map even if it's a duplicate as the
-            // internal handler will need the key to find the listener. In case of duplicates,
-            // removing duplicate key logic will be handled in internal handler.
-            int key = putListener(listener);
-            if (keyExists) {
-                if (DBG) Log.d(TAG, "listener key already exists");
-                OperationResult operationResult = new OperationResult(REASON_DUPLICATE_REQEUST,
-                        "Outstanding request with same key not stopped yet");
-                Message message = Message.obtain(mInternalHandler, CMD_OP_FAILED, 0, key,
-                        operationResult);
-                message.sendToTarget();
-                return INVALID_KEY;
-            } else {
-                mExecutorMap.put(key, executor);
-                return key;
-            }
-        }
-    }
-
-    private int putListener(Object listener) {
-        if (listener == null) return INVALID_KEY;
-        int key;
-        synchronized (mListenerMapLock) {
-            do {
-                key = mListenerKey++;
-            } while (key == INVALID_KEY);
-            mListenerMap.put(key, listener);
-        }
-        return key;
-    }
-
-    private static class ListenerWithExecutor {
-        @Nullable final Object mListener;
-        @Nullable final Executor mExecutor;
-
-        ListenerWithExecutor(@Nullable Object listener, @Nullable Executor executor) {
-            mListener = listener;
-            mExecutor = executor;
-        }
-    }
-
-    private ListenerWithExecutor getListenerWithExecutor(int key) {
-        if (key == INVALID_KEY) return new ListenerWithExecutor(null, null);
-        synchronized (mListenerMapLock) {
-            Object listener = mListenerMap.get(key);
-            Executor executor = mExecutorMap.get(key);
-            return new ListenerWithExecutor(listener, executor);
-        }
-    }
-
-    private int getListenerKey(Object listener) {
-        if (listener == null) return INVALID_KEY;
-        synchronized (mListenerMapLock) {
-            int index = mListenerMap.indexOfValue(listener);
-            if (index == -1) {
-                return INVALID_KEY;
-            } else {
-                return mListenerMap.keyAt(index);
-            }
-        }
-    }
-
-    private Object removeListener(int key) {
-        if (key == INVALID_KEY) return null;
-        synchronized (mListenerMapLock) {
-            Object listener = mListenerMap.get(key);
-            mListenerMap.remove(key);
-            mExecutorMap.remove(key);
-            return listener;
-        }
-    }
-
-    private int removeListener(Object listener) {
-        int key = getListenerKey(listener);
-        if (key == INVALID_KEY) {
-            Log.e(TAG, "listener cannot be found");
-            return key;
-        }
-        synchronized (mListenerMapLock) {
-            mListenerMap.remove(key);
-            mExecutorMap.remove(key);
-            return key;
-        }
-    }
-
-    /** @hide */
-    public static class OperationResult implements Parcelable {
-        public int reason;
-        public String description;
-
-        public OperationResult(int reason, String description) {
-            this.reason = reason;
-            this.description = description;
-        }
-
-        /** Implement the Parcelable interface {@hide} */
-        public int describeContents() {
-            return 0;
-        }
-
-        /** Implement the Parcelable interface {@hide} */
-        public void writeToParcel(Parcel dest, int flags) {
-            dest.writeInt(reason);
-            dest.writeString(description);
-        }
-
-        /** Implement the Parcelable interface {@hide} */
-        public static final @NonNull Creator<OperationResult> CREATOR =
-                new Creator<OperationResult>() {
-                    public OperationResult createFromParcel(Parcel in) {
-                        int reason = in.readInt();
-                        String description = in.readString();
-                        return new OperationResult(reason, description);
-                    }
-
-                    public OperationResult[] newArray(int size) {
-                        return new OperationResult[size];
-                    }
-                };
-    }
-
-    private class ServiceHandler extends Handler {
-        ServiceHandler(Looper looper) {
-            super(looper);
-        }
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED:
-                    return;
-                case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
-                    Log.e(TAG, "Channel connection lost");
-                    // This will cause all further async API calls on the WifiManager
-                    // to fail and throw an exception
-                    mAsyncChannel = null;
-                    getLooper().quit();
-                    return;
-            }
-
-            ListenerWithExecutor listenerWithExecutor = getListenerWithExecutor(msg.arg2);
-            Object listener = listenerWithExecutor.mListener;
-
-            if (listener == null) {
-                if (DBG) Log.d(TAG, "invalid listener key = " + msg.arg2);
-                return;
-            } else {
-                if (DBG) Log.d(TAG, "listener key = " + msg.arg2);
-            }
-
-            Executor executor = listenerWithExecutor.mExecutor;
-            if (executor == null) {
-                executor = new SynchronousExecutor();
-            }
-
-            switch (msg.what) {
-                /* ActionListeners grouped together */
-                case CMD_OP_SUCCEEDED: {
-                    ActionListener actionListener = (ActionListener) listener;
-                    Binder.clearCallingIdentity();
-                    executor.execute(actionListener::onSuccess);
-                } break;
-                case CMD_OP_FAILED: {
-                    OperationResult result = (OperationResult) msg.obj;
-                    ActionListener actionListener = (ActionListener) listener;
-                    removeListener(msg.arg2);
-                    Binder.clearCallingIdentity();
-                    executor.execute(() ->
-                            actionListener.onFailure(result.reason, result.description));
-                } break;
-                case CMD_SCAN_RESULT: {
-                    ScanListener scanListener = (ScanListener) listener;
-                    ParcelableScanData parcelableScanData = (ParcelableScanData) msg.obj;
-                    Binder.clearCallingIdentity();
-                    executor.execute(() -> scanListener.onResults(parcelableScanData.getResults()));
-                } break;
-                case CMD_FULL_SCAN_RESULT: {
-                    ScanResult result = (ScanResult) msg.obj;
-                    ScanListener scanListener = ((ScanListener) listener);
-                    Binder.clearCallingIdentity();
-                    executor.execute(() -> scanListener.onFullResult(result));
-                } break;
-                case CMD_SINGLE_SCAN_COMPLETED: {
-                    if (DBG) Log.d(TAG, "removing listener for single scan");
-                    removeListener(msg.arg2);
-                } break;
-                case CMD_PNO_NETWORK_FOUND: {
-                    PnoScanListener pnoScanListener = (PnoScanListener) listener;
-                    ParcelableScanResults parcelableScanResults = (ParcelableScanResults) msg.obj;
-                    Binder.clearCallingIdentity();
-                    executor.execute(() ->
-                            pnoScanListener.onPnoNetworkFound(parcelableScanResults.getResults()));
-                } break;
-                default: {
-                    if (DBG) Log.d(TAG, "Ignoring message " + msg.what);
-                } break;
-            }
-        }
-    }
-}
diff --git a/wifi/java/android/net/wifi/WifiSsid.java b/wifi/java/android/net/wifi/WifiSsid.java
deleted file mode 100644
index 704ae81..0000000
--- a/wifi/java/android/net/wifi/WifiSsid.java
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.io.ByteArrayOutputStream;
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
-import java.nio.charset.Charset;
-import java.nio.charset.CharsetDecoder;
-import java.nio.charset.CoderResult;
-import java.nio.charset.CodingErrorAction;
-import java.util.Arrays;
-import java.util.Locale;
-
-/**
- * Stores SSID octets and handles conversion.
- *
- * For Ascii encoded string, any octet < 32 or > 127 is encoded as
- * a "\x" followed by the hex representation of the octet.
- * Exception chars are ", \, \e, \n, \r, \t which are escaped by a \
- * See src/utils/common.c for the implementation in the supplicant.
- *
- * @hide
- */
-public final class WifiSsid implements Parcelable {
-    private static final String TAG = "WifiSsid";
-
-    @UnsupportedAppUsage
-    public final ByteArrayOutputStream octets = new ByteArrayOutputStream(32);
-
-    private static final int HEX_RADIX = 16;
-
-    @UnsupportedAppUsage
-    public static final String NONE = WifiManager.UNKNOWN_SSID;
-
-    private WifiSsid() {
-    }
-
-    /**
-     * Create a WifiSsid from a raw byte array. If the byte array is null, return an empty WifiSsid
-     * object.
-     */
-    @NonNull
-    public static WifiSsid createFromByteArray(@Nullable byte[] ssid) {
-        WifiSsid wifiSsid = new WifiSsid();
-        if (ssid != null) {
-            wifiSsid.octets.write(ssid, 0 /* the start offset */, ssid.length);
-        }
-        return wifiSsid;
-    }
-
-    @UnsupportedAppUsage
-    public static WifiSsid createFromAsciiEncoded(String asciiEncoded) {
-        WifiSsid a = new WifiSsid();
-        a.convertToBytes(asciiEncoded);
-        return a;
-    }
-
-    public static WifiSsid createFromHex(String hexStr) {
-        WifiSsid a = new WifiSsid();
-        if (hexStr == null) return a;
-
-        if (hexStr.startsWith("0x") || hexStr.startsWith("0X")) {
-            hexStr = hexStr.substring(2);
-        }
-
-        for (int i = 0; i < hexStr.length()-1; i += 2) {
-            int val;
-            try {
-                val = Integer.parseInt(hexStr.substring(i, i + 2), HEX_RADIX);
-            } catch(NumberFormatException e) {
-                val = 0;
-            }
-            a.octets.write(val);
-        }
-        return a;
-    }
-
-    /* This function is equivalent to printf_decode() at src/utils/common.c in
-     * the supplicant */
-    private void convertToBytes(String asciiEncoded) {
-        int i = 0;
-        int val = 0;
-        while (i< asciiEncoded.length()) {
-            char c = asciiEncoded.charAt(i);
-            switch (c) {
-                case '\\':
-                    i++;
-                    switch(asciiEncoded.charAt(i)) {
-                        case '\\':
-                            octets.write('\\');
-                            i++;
-                            break;
-                        case '"':
-                            octets.write('"');
-                            i++;
-                            break;
-                        case 'n':
-                            octets.write('\n');
-                            i++;
-                            break;
-                        case 'r':
-                            octets.write('\r');
-                            i++;
-                            break;
-                        case 't':
-                            octets.write('\t');
-                            i++;
-                            break;
-                        case 'e':
-                            octets.write(27); //escape char
-                            i++;
-                            break;
-                        case 'x':
-                            i++;
-                            try {
-                                val = Integer.parseInt(asciiEncoded.substring(i, i + 2), HEX_RADIX);
-                            } catch (NumberFormatException e) {
-                                val = -1;
-                            } catch (StringIndexOutOfBoundsException e) {
-                                val = -1;
-                            }
-                            if (val < 0) {
-                                val = Character.digit(asciiEncoded.charAt(i), HEX_RADIX);
-                                if (val < 0) break;
-                                octets.write(val);
-                                i++;
-                            } else {
-                                octets.write(val);
-                                i += 2;
-                            }
-                            break;
-                        case '0':
-                        case '1':
-                        case '2':
-                        case '3':
-                        case '4':
-                        case '5':
-                        case '6':
-                        case '7':
-                            val = asciiEncoded.charAt(i) - '0';
-                            i++;
-                            if (asciiEncoded.charAt(i) >= '0' && asciiEncoded.charAt(i) <= '7') {
-                                val = val * 8 + asciiEncoded.charAt(i) - '0';
-                                i++;
-                            }
-                            if (asciiEncoded.charAt(i) >= '0' && asciiEncoded.charAt(i) <= '7') {
-                                val = val * 8 + asciiEncoded.charAt(i) - '0';
-                                i++;
-                            }
-                            octets.write(val);
-                            break;
-                        default:
-                            break;
-                    }
-                    break;
-                default:
-                    octets.write(c);
-                    i++;
-                    break;
-            }
-        }
-    }
-
-    /**
-     * Converts this SSID to an unquoted UTF-8 String representation.
-     * @return the SSID string, or {@link WifiManager#UNKNOWN_SSID} if there was an error.
-     */
-    @Override
-    public String toString() {
-        byte[] ssidBytes = octets.toByteArray();
-        // Supplicant returns \x00\x00\x00\x00\x00\x00\x00\x00 hex string
-        // for a hidden access point. Make sure we maintain the previous
-        // behavior of returning empty string for this case.
-        if (octets.size() <= 0 || isArrayAllZeroes(ssidBytes)) return "";
-        // TODO: Handle conversion to other charsets upon failure
-        Charset charset = Charset.forName("UTF-8");
-        CharsetDecoder decoder = charset.newDecoder()
-                .onMalformedInput(CodingErrorAction.REPLACE)
-                .onUnmappableCharacter(CodingErrorAction.REPLACE);
-        CharBuffer out = CharBuffer.allocate(32);
-
-        CoderResult result = decoder.decode(ByteBuffer.wrap(ssidBytes), out, true);
-        out.flip();
-        if (result.isError()) {
-            return WifiManager.UNKNOWN_SSID;
-        }
-        return out.toString();
-    }
-
-    @Override
-    public boolean equals(Object thatObject) {
-        if (this == thatObject) {
-            return true;
-        }
-        if (!(thatObject instanceof WifiSsid)) {
-            return false;
-        }
-        WifiSsid that = (WifiSsid) thatObject;
-        return Arrays.equals(octets.toByteArray(), that.octets.toByteArray());
-    }
-
-    @Override
-    public int hashCode() {
-        return Arrays.hashCode(octets.toByteArray());
-    }
-
-    private boolean isArrayAllZeroes(byte[] ssidBytes) {
-        for (int i = 0; i< ssidBytes.length; i++) {
-            if (ssidBytes[i] != 0) return false;
-        }
-        return true;
-    }
-
-    /** @hide */
-    public boolean isHidden() {
-        return isArrayAllZeroes(octets.toByteArray());
-    }
-
-    /** @hide */
-    @UnsupportedAppUsage
-    public byte[] getOctets() {
-        return octets.toByteArray();
-    }
-
-    /** @hide */
-    public String getHexString() {
-        String out = "0x";
-        byte[] ssidbytes = getOctets();
-        for (int i = 0; i < octets.size(); i++) {
-            out += String.format(Locale.US, "%02x", ssidbytes[i]);
-        }
-        return (octets.size() > 0) ? out : null;
-    }
-
-    /** Implement the Parcelable interface */
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    /** Implement the Parcelable interface */
-    @Override
-    public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeInt(octets.size());
-        dest.writeByteArray(octets.toByteArray());
-    }
-
-    /** Implement the Parcelable interface */
-    @UnsupportedAppUsage
-    public static final @NonNull Creator<WifiSsid> CREATOR =
-            new Creator<WifiSsid>() {
-                @Override
-                public WifiSsid createFromParcel(Parcel in) {
-                    WifiSsid ssid = new WifiSsid();
-                    int length = in.readInt();
-                    byte[] b = new byte[length];
-                    in.readByteArray(b);
-                    ssid.octets.write(b, 0, length);
-                    return ssid;
-                }
-
-                @Override
-                public WifiSsid[] newArray(int size) {
-                    return new WifiSsid[size];
-                }
-            };
-}
diff --git a/wifi/java/android/net/wifi/WifiUsabilityStatsEntry.java b/wifi/java/android/net/wifi/WifiUsabilityStatsEntry.java
deleted file mode 100644
index 8f3635f..0000000
--- a/wifi/java/android/net/wifi/WifiUsabilityStatsEntry.java
+++ /dev/null
@@ -1,351 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import android.annotation.IntDef;
-import android.annotation.SystemApi;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import android.telephony.Annotation.NetworkType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * This class makes a subset of
- * com.android.server.wifi.nano.WifiMetricsProto.WifiUsabilityStatsEntry parcelable.
- *
- * @hide
- */
-@SystemApi
-public final class WifiUsabilityStatsEntry implements Parcelable {
-    /** {@hide} */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(prefix = {"PROBE_STATUS_"}, value = {
-            PROBE_STATUS_UNKNOWN,
-            PROBE_STATUS_NO_PROBE,
-            PROBE_STATUS_SUCCESS,
-            PROBE_STATUS_FAILURE})
-    public @interface ProbeStatus {}
-
-    /** Link probe status is unknown */
-    public static final int PROBE_STATUS_UNKNOWN = 0;
-    /** Link probe is not triggered */
-    public static final int PROBE_STATUS_NO_PROBE = 1;
-    /** Link probe is triggered and the result is success */
-    public static final int PROBE_STATUS_SUCCESS = 2;
-    /** Link probe is triggered and the result is failure */
-    public static final int PROBE_STATUS_FAILURE = 3;
-
-    /** Absolute milliseconds from device boot when these stats were sampled */
-    private final long mTimeStampMillis;
-    /** The RSSI (in dBm) at the sample time */
-    private final int mRssi;
-    /** Link speed at the sample time in Mbps */
-    private final int mLinkSpeedMbps;
-    /** The total number of tx success counted from the last radio chip reset */
-    private final long mTotalTxSuccess;
-    /** The total number of MPDU data packet retries counted from the last radio chip reset */
-    private final long mTotalTxRetries;
-    /** The total number of tx bad counted from the last radio chip reset */
-    private final long mTotalTxBad;
-    /** The total number of rx success counted from the last radio chip reset */
-    private final long mTotalRxSuccess;
-    /** The total time the wifi radio is on in ms counted from the last radio chip reset */
-    private final long mTotalRadioOnTimeMillis;
-    /** The total time the wifi radio is doing tx in ms counted from the last radio chip reset */
-    private final long mTotalRadioTxTimeMillis;
-    /** The total time the wifi radio is doing rx in ms counted from the last radio chip reset */
-    private final long mTotalRadioRxTimeMillis;
-    /** The total time spent on all types of scans in ms counted from the last radio chip reset */
-    private final long mTotalScanTimeMillis;
-    /** The total time spent on nan scans in ms counted from the last radio chip reset */
-    private final long mTotalNanScanTimeMillis;
-    /** The total time spent on background scans in ms counted from the last radio chip reset */
-    private final long mTotalBackgroundScanTimeMillis;
-    /** The total time spent on roam scans in ms counted from the last radio chip reset */
-    private final long mTotalRoamScanTimeMillis;
-    /** The total time spent on pno scans in ms counted from the last radio chip reset */
-    private final long mTotalPnoScanTimeMillis;
-    /** The total time spent on hotspot2.0 scans and GAS exchange in ms counted from the last radio
-     * chip reset */
-    private final long mTotalHotspot2ScanTimeMillis;
-    /** The total time CCA is on busy status on the current frequency in ms counted from the last
-     * radio chip reset */
-    private final long mTotalCcaBusyFreqTimeMillis;
-    /** The total radio on time on the current frequency from the last radio chip reset */
-    private final long mTotalRadioOnFreqTimeMillis;
-    /** The total number of beacons received from the last radio chip reset */
-    private final long mTotalBeaconRx;
-    /** The status of link probe since last stats update */
-    @ProbeStatus private final int mProbeStatusSinceLastUpdate;
-    /** The elapsed time of the most recent link probe since last stats update */
-    private final int mProbeElapsedTimeSinceLastUpdateMillis;
-    /** The MCS rate of the most recent link probe since last stats update */
-    private final int mProbeMcsRateSinceLastUpdate;
-    /** Rx link speed at the sample time in Mbps */
-    private final int mRxLinkSpeedMbps;
-    private final @NetworkType int mCellularDataNetworkType;
-    private final int mCellularSignalStrengthDbm;
-    private final int mCellularSignalStrengthDb;
-    private final boolean mIsSameRegisteredCell;
-
-    /** Constructor function {@hide} */
-    public WifiUsabilityStatsEntry(long timeStampMillis, int rssi, int linkSpeedMbps,
-            long totalTxSuccess, long totalTxRetries, long totalTxBad, long totalRxSuccess,
-            long totalRadioOnTimeMillis, long totalRadioTxTimeMillis, long totalRadioRxTimeMillis,
-            long totalScanTimeMillis, long totalNanScanTimeMillis,
-            long totalBackgroundScanTimeMillis,
-            long totalRoamScanTimeMillis, long totalPnoScanTimeMillis,
-            long totalHotspot2ScanTimeMillis,
-            long totalCcaBusyFreqTimeMillis, long totalRadioOnFreqTimeMillis, long totalBeaconRx,
-            @ProbeStatus int probeStatusSinceLastUpdate, int probeElapsedTimeSinceLastUpdateMillis,
-            int probeMcsRateSinceLastUpdate, int rxLinkSpeedMbps,
-            @NetworkType int cellularDataNetworkType,
-            int cellularSignalStrengthDbm, int cellularSignalStrengthDb,
-            boolean isSameRegisteredCell) {
-        mTimeStampMillis = timeStampMillis;
-        mRssi = rssi;
-        mLinkSpeedMbps = linkSpeedMbps;
-        mTotalTxSuccess = totalTxSuccess;
-        mTotalTxRetries = totalTxRetries;
-        mTotalTxBad = totalTxBad;
-        mTotalRxSuccess = totalRxSuccess;
-        mTotalRadioOnTimeMillis = totalRadioOnTimeMillis;
-        mTotalRadioTxTimeMillis = totalRadioTxTimeMillis;
-        mTotalRadioRxTimeMillis = totalRadioRxTimeMillis;
-        mTotalScanTimeMillis = totalScanTimeMillis;
-        mTotalNanScanTimeMillis = totalNanScanTimeMillis;
-        mTotalBackgroundScanTimeMillis = totalBackgroundScanTimeMillis;
-        mTotalRoamScanTimeMillis = totalRoamScanTimeMillis;
-        mTotalPnoScanTimeMillis = totalPnoScanTimeMillis;
-        mTotalHotspot2ScanTimeMillis = totalHotspot2ScanTimeMillis;
-        mTotalCcaBusyFreqTimeMillis = totalCcaBusyFreqTimeMillis;
-        mTotalRadioOnFreqTimeMillis = totalRadioOnFreqTimeMillis;
-        mTotalBeaconRx = totalBeaconRx;
-        mProbeStatusSinceLastUpdate = probeStatusSinceLastUpdate;
-        mProbeElapsedTimeSinceLastUpdateMillis = probeElapsedTimeSinceLastUpdateMillis;
-        mProbeMcsRateSinceLastUpdate = probeMcsRateSinceLastUpdate;
-        mRxLinkSpeedMbps = rxLinkSpeedMbps;
-        mCellularDataNetworkType = cellularDataNetworkType;
-        mCellularSignalStrengthDbm = cellularSignalStrengthDbm;
-        mCellularSignalStrengthDb = cellularSignalStrengthDb;
-        mIsSameRegisteredCell = isSameRegisteredCell;
-    }
-
-    /** Implement the Parcelable interface */
-    public int describeContents() {
-        return 0;
-    }
-
-    /** Implement the Parcelable interface */
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeLong(mTimeStampMillis);
-        dest.writeInt(mRssi);
-        dest.writeInt(mLinkSpeedMbps);
-        dest.writeLong(mTotalTxSuccess);
-        dest.writeLong(mTotalTxRetries);
-        dest.writeLong(mTotalTxBad);
-        dest.writeLong(mTotalRxSuccess);
-        dest.writeLong(mTotalRadioOnTimeMillis);
-        dest.writeLong(mTotalRadioTxTimeMillis);
-        dest.writeLong(mTotalRadioRxTimeMillis);
-        dest.writeLong(mTotalScanTimeMillis);
-        dest.writeLong(mTotalNanScanTimeMillis);
-        dest.writeLong(mTotalBackgroundScanTimeMillis);
-        dest.writeLong(mTotalRoamScanTimeMillis);
-        dest.writeLong(mTotalPnoScanTimeMillis);
-        dest.writeLong(mTotalHotspot2ScanTimeMillis);
-        dest.writeLong(mTotalCcaBusyFreqTimeMillis);
-        dest.writeLong(mTotalRadioOnFreqTimeMillis);
-        dest.writeLong(mTotalBeaconRx);
-        dest.writeInt(mProbeStatusSinceLastUpdate);
-        dest.writeInt(mProbeElapsedTimeSinceLastUpdateMillis);
-        dest.writeInt(mProbeMcsRateSinceLastUpdate);
-        dest.writeInt(mRxLinkSpeedMbps);
-        dest.writeInt(mCellularDataNetworkType);
-        dest.writeInt(mCellularSignalStrengthDbm);
-        dest.writeInt(mCellularSignalStrengthDb);
-        dest.writeBoolean(mIsSameRegisteredCell);
-    }
-
-    /** Implement the Parcelable interface */
-    public static final @android.annotation.NonNull Creator<WifiUsabilityStatsEntry> CREATOR =
-            new Creator<WifiUsabilityStatsEntry>() {
-        public WifiUsabilityStatsEntry createFromParcel(Parcel in) {
-            return new WifiUsabilityStatsEntry(
-                    in.readLong(), in.readInt(),
-                    in.readInt(), in.readLong(), in.readLong(),
-                    in.readLong(), in.readLong(), in.readLong(),
-                    in.readLong(), in.readLong(), in.readLong(),
-                    in.readLong(), in.readLong(), in.readLong(),
-                    in.readLong(), in.readLong(), in.readLong(),
-                    in.readLong(), in.readLong(), in.readInt(),
-                    in.readInt(), in.readInt(), in.readInt(),
-                    in.readInt(), in.readInt(), in.readInt(),
-                    in.readBoolean()
-            );
-        }
-
-        public WifiUsabilityStatsEntry[] newArray(int size) {
-            return new WifiUsabilityStatsEntry[size];
-        }
-    };
-
-    /** Absolute milliseconds from device boot when these stats were sampled */
-    public long getTimeStampMillis() {
-        return mTimeStampMillis;
-    }
-
-    /** The RSSI (in dBm) at the sample time */
-    public int getRssi() {
-        return mRssi;
-    }
-
-    /** Link speed at the sample time in Mbps */
-    public int getLinkSpeedMbps() {
-        return mLinkSpeedMbps;
-    }
-
-    /** The total number of tx success counted from the last radio chip reset */
-    public long getTotalTxSuccess() {
-        return mTotalTxSuccess;
-    }
-
-    /** The total number of MPDU data packet retries counted from the last radio chip reset */
-    public long getTotalTxRetries() {
-        return mTotalTxRetries;
-    }
-
-    /** The total number of tx bad counted from the last radio chip reset */
-    public long getTotalTxBad() {
-        return mTotalTxBad;
-    }
-
-    /** The total number of rx success counted from the last radio chip reset */
-    public long getTotalRxSuccess() {
-        return mTotalRxSuccess;
-    }
-
-    /** The total time the wifi radio is on in ms counted from the last radio chip reset */
-    public long getTotalRadioOnTimeMillis() {
-        return mTotalRadioOnTimeMillis;
-    }
-
-    /** The total time the wifi radio is doing tx in ms counted from the last radio chip reset */
-    public long getTotalRadioTxTimeMillis() {
-        return mTotalRadioTxTimeMillis;
-    }
-
-    /** The total time the wifi radio is doing rx in ms counted from the last radio chip reset */
-    public long getTotalRadioRxTimeMillis() {
-        return mTotalRadioRxTimeMillis;
-    }
-
-    /** The total time spent on all types of scans in ms counted from the last radio chip reset */
-    public long getTotalScanTimeMillis() {
-        return mTotalScanTimeMillis;
-    }
-
-    /** The total time spent on nan scans in ms counted from the last radio chip reset */
-    public long getTotalNanScanTimeMillis() {
-        return mTotalNanScanTimeMillis;
-    }
-
-    /** The total time spent on background scans in ms counted from the last radio chip reset */
-    public long getTotalBackgroundScanTimeMillis() {
-        return mTotalBackgroundScanTimeMillis;
-    }
-
-    /** The total time spent on roam scans in ms counted from the last radio chip reset */
-    public long getTotalRoamScanTimeMillis() {
-        return mTotalRoamScanTimeMillis;
-    }
-
-    /** The total time spent on pno scans in ms counted from the last radio chip reset */
-    public long getTotalPnoScanTimeMillis() {
-        return mTotalPnoScanTimeMillis;
-    }
-
-    /** The total time spent on hotspot2.0 scans and GAS exchange in ms counted from the last radio
-     * chip reset */
-    public long getTotalHotspot2ScanTimeMillis() {
-        return mTotalHotspot2ScanTimeMillis;
-    }
-
-    /** The total time CCA is on busy status on the current frequency in ms counted from the last
-     * radio chip reset */
-    public long getTotalCcaBusyFreqTimeMillis() {
-        return mTotalCcaBusyFreqTimeMillis;
-    }
-
-    /** The total radio on time on the current frequency from the last radio chip reset */
-    public long getTotalRadioOnFreqTimeMillis() {
-        return mTotalRadioOnFreqTimeMillis;
-    }
-
-    /** The total number of beacons received from the last radio chip reset */
-    public long getTotalBeaconRx() {
-        return mTotalBeaconRx;
-    }
-
-    /** The status of link probe since last stats update */
-    @ProbeStatus public int getProbeStatusSinceLastUpdate() {
-        return mProbeStatusSinceLastUpdate;
-    }
-
-    /** The elapsed time of the most recent link probe since last stats update */
-    public int getProbeElapsedTimeSinceLastUpdateMillis() {
-        return mProbeElapsedTimeSinceLastUpdateMillis;
-    }
-
-    /** The MCS rate of the most recent link probe since last stats update */
-    public int getProbeMcsRateSinceLastUpdate() {
-        return mProbeMcsRateSinceLastUpdate;
-    }
-
-    /** Rx link speed at the sample time in Mbps */
-    public int getRxLinkSpeedMbps() {
-        return mRxLinkSpeedMbps;
-    }
-
-    /** Cellular data network type currently in use on the device for data transmission */
-    @NetworkType public int getCellularDataNetworkType() {
-        return mCellularDataNetworkType;
-    }
-
-    /**
-     * Cellular signal strength in dBm, NR: CsiRsrp, LTE: Rsrp, WCDMA/TDSCDMA: Rscp,
-     * CDMA: Rssi, EVDO: Rssi, GSM: Rssi
-     */
-    public int getCellularSignalStrengthDbm() {
-        return mCellularSignalStrengthDbm;
-    }
-
-    /**
-     * Cellular signal strength in dB, NR: CsiSinr, LTE: Rsrq, WCDMA: EcNo, TDSCDMA: invalid,
-     * CDMA: Ecio, EVDO: SNR, GSM: invalid
-     */
-    public int getCellularSignalStrengthDb() {
-        return mCellularSignalStrengthDb;
-    }
-
-    /** Whether the primary registered cell of current entry is same as that of previous entry */
-    public boolean isSameRegisteredCell() {
-        return mIsSameRegisteredCell;
-    }
-}
diff --git a/wifi/java/android/net/wifi/WpsInfo.java b/wifi/java/android/net/wifi/WpsInfo.java
deleted file mode 100644
index 689ace5b..0000000
--- a/wifi/java/android/net/wifi/WpsInfo.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * A class representing Wi-Fi Protected Setup
- *
- * {@see android.net.wifi.p2p.WifiP2pConfig}
- */
-public class WpsInfo implements Parcelable {
-
-    /** Push button configuration */
-    public static final int PBC     = 0;
-    /** Display pin method configuration - pin is generated and displayed on device */
-    public static final int DISPLAY = 1;
-    /** Keypad pin method configuration - pin is entered on device */
-    public static final int KEYPAD  = 2;
-    /** Label pin method configuration - pin is labelled on device */
-    public static final int LABEL   = 3;
-    /** Invalid configuration */
-    public static final int INVALID = 4;
-
-    /** Wi-Fi Protected Setup. www.wi-fi.org/wifi-protected-setup has details */
-    public int setup;
-
-    /** Passed with pin method KEYPAD */
-    public String BSSID;
-
-    /** Passed with pin method configuration */
-    public String pin;
-
-    public WpsInfo() {
-        setup = INVALID;
-        BSSID = null;
-        pin = null;
-    }
-
-    public String toString() {
-        StringBuffer sbuf = new StringBuffer();
-        sbuf.append(" setup: ").append(setup);
-        sbuf.append('\n');
-        sbuf.append(" BSSID: ").append(BSSID);
-        sbuf.append('\n');
-        sbuf.append(" pin: ").append(pin);
-        sbuf.append('\n');
-        return sbuf.toString();
-    }
-
-    /** Implement the Parcelable interface */
-    public int describeContents() {
-        return 0;
-    }
-
-    /* Copy constructor */
-    public WpsInfo(WpsInfo source) {
-        if (source != null) {
-            setup = source.setup;
-            BSSID = source.BSSID;
-            pin = source.pin;
-        }
-    }
-
-    /** Implement the Parcelable interface */
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(setup);
-        dest.writeString(BSSID);
-        dest.writeString(pin);
-    }
-
-    /** Implement the Parcelable interface */
-    public static final @android.annotation.NonNull Creator<WpsInfo> CREATOR =
-        new Creator<WpsInfo>() {
-            public WpsInfo createFromParcel(Parcel in) {
-                WpsInfo config = new WpsInfo();
-                config.setup = in.readInt();
-                config.BSSID = in.readString();
-                config.pin = in.readString();
-                return config;
-            }
-
-            public WpsInfo[] newArray(int size) {
-                return new WpsInfo[size];
-            }
-        };
-}
diff --git a/wifi/java/android/net/wifi/aware/AttachCallback.java b/wifi/java/android/net/wifi/aware/AttachCallback.java
deleted file mode 100644
index c368b46..0000000
--- a/wifi/java/android/net/wifi/aware/AttachCallback.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.aware;
-
-/**
- * Base class for Aware attach callbacks. Should be extended by applications and set when calling
- * {@link WifiAwareManager#attach(AttachCallback, android.os.Handler)}. These are callbacks
- * applying to the Aware connection as a whole - not to specific publish or subscribe sessions -
- * for that see {@link DiscoverySessionCallback}.
- */
-public class AttachCallback {
-    /**
-     * Called when Aware attach operation
-     * {@link WifiAwareManager#attach(AttachCallback, android.os.Handler)}
-     * is completed and that we can now start discovery sessions or connections.
-     *
-     * @param session The Aware object on which we can execute further Aware operations - e.g.
-     *                discovery, connections.
-     */
-    public void onAttached(WifiAwareSession session) {
-        /* empty */
-    }
-
-    /**
-     * Called when Aware attach operation
-     * {@link WifiAwareManager#attach(AttachCallback, android.os.Handler)} failed.
-     */
-    public void onAttachFailed() {
-        /* empty */
-    }
-}
diff --git a/wifi/java/android/net/wifi/aware/Characteristics.java b/wifi/java/android/net/wifi/aware/Characteristics.java
deleted file mode 100644
index d5fd48e..0000000
--- a/wifi/java/android/net/wifi/aware/Characteristics.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.aware;
-
-import android.annotation.IntDef;
-import android.os.Bundle;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * The characteristics of the Wi-Fi Aware implementation.
- */
-public final class Characteristics implements Parcelable {
-    /** @hide */
-    public static final String KEY_MAX_SERVICE_NAME_LENGTH = "key_max_service_name_length";
-    /** @hide */
-    public static final String KEY_MAX_SERVICE_SPECIFIC_INFO_LENGTH =
-            "key_max_service_specific_info_length";
-    /** @hide */
-    public static final String KEY_MAX_MATCH_FILTER_LENGTH = "key_max_match_filter_length";
-    /** @hide */
-    public static final String KEY_SUPPORTED_CIPHER_SUITES = "key_supported_cipher_suites";
-
-    private Bundle mCharacteristics = new Bundle();
-
-    /** @hide : should not be created by apps */
-    public Characteristics(Bundle characteristics) {
-        mCharacteristics = characteristics;
-    }
-
-    /**
-     * Returns the maximum string length that can be used to specify a Aware service name. Restricts
-     * the parameters of the {@link PublishConfig.Builder#setServiceName(String)} and
-     * {@link SubscribeConfig.Builder#setServiceName(String)}.
-     *
-     * @return A positive integer, maximum string length of Aware service name.
-     */
-    public int getMaxServiceNameLength() {
-        return mCharacteristics.getInt(KEY_MAX_SERVICE_NAME_LENGTH);
-    }
-
-    /**
-     * Returns the maximum length of byte array that can be used to specify a Aware service specific
-     * information field: the arbitrary load used in discovery or the message length of Aware
-     * message exchange. Restricts the parameters of the
-     * {@link PublishConfig.Builder#setServiceSpecificInfo(byte[])},
-     * {@link SubscribeConfig.Builder#setServiceSpecificInfo(byte[])}, and
-     * {@link DiscoverySession#sendMessage(PeerHandle, int, byte[])}
-     * variants.
-     *
-     * @return A positive integer, maximum length of byte array for Aware messaging.
-     */
-    public int getMaxServiceSpecificInfoLength() {
-        return mCharacteristics.getInt(KEY_MAX_SERVICE_SPECIFIC_INFO_LENGTH);
-    }
-
-    /**
-     * Returns the maximum length of byte array that can be used to specify a Aware match filter.
-     * Restricts the parameters of the
-     * {@link PublishConfig.Builder#setMatchFilter(java.util.List)} and
-     * {@link SubscribeConfig.Builder#setMatchFilter(java.util.List)}.
-     *
-     * @return A positive integer, maximum length of byte array for Aware discovery match filter.
-     */
-    public int getMaxMatchFilterLength() {
-        return mCharacteristics.getInt(KEY_MAX_MATCH_FILTER_LENGTH);
-    }
-
-    /** @hide */
-    @IntDef(flag = true, prefix = { "WIFI_AWARE_CIPHER_SUITE_" }, value = {
-            WIFI_AWARE_CIPHER_SUITE_NCS_SK_128,
-            WIFI_AWARE_CIPHER_SUITE_NCS_SK_256,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface WifiAwareCipherSuites {}
-
-    /**
-     * Wi-Fi Aware supported ciphier suite representing NCS SK 128: 128 bit shared-key.
-     */
-    public static final int WIFI_AWARE_CIPHER_SUITE_NCS_SK_128 = 1 << 0;
-
-    /**
-     * Wi-Fi Aware supported ciphier suite representing NCS SK 256: 256 bit shared-key.
-     */
-    public static final int WIFI_AWARE_CIPHER_SUITE_NCS_SK_256 = 1 << 1;
-
-    /**
-     * Returns the set of cipher suites supported by the device for use in Wi-Fi Aware data-paths.
-     * The device automatically picks the strongest cipher suite when initiating a data-path setup.
-     *
-     * @return A set of flags from {@link #WIFI_AWARE_CIPHER_SUITE_NCS_SK_128}, or
-     * {@link #WIFI_AWARE_CIPHER_SUITE_NCS_SK_256}.
-     */
-    public @WifiAwareCipherSuites int getSupportedCipherSuites() {
-        return mCharacteristics.getInt(KEY_SUPPORTED_CIPHER_SUITES);
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeBundle(mCharacteristics);
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final @android.annotation.NonNull Creator<Characteristics> CREATOR =
-            new Creator<Characteristics>() {
-                @Override
-                public Characteristics createFromParcel(Parcel in) {
-                    Characteristics c = new Characteristics(in.readBundle());
-                    return c;
-                }
-
-                @Override
-                public Characteristics[] newArray(int size) {
-                    return new Characteristics[size];
-                }
-            };
-}
diff --git a/wifi/java/android/net/wifi/aware/ConfigRequest.aidl b/wifi/java/android/net/wifi/aware/ConfigRequest.aidl
deleted file mode 100644
index 68a7c85..0000000
--- a/wifi/java/android/net/wifi/aware/ConfigRequest.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.aware;
-
-parcelable ConfigRequest;
diff --git a/wifi/java/android/net/wifi/aware/ConfigRequest.java b/wifi/java/android/net/wifi/aware/ConfigRequest.java
deleted file mode 100644
index 61ab92c..0000000
--- a/wifi/java/android/net/wifi/aware/ConfigRequest.java
+++ /dev/null
@@ -1,385 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.aware;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.Arrays;
-
-/**
- * Defines a request object to configure a Wi-Fi Aware network. Built using
- * {@link ConfigRequest.Builder}. Configuration is requested using
- * {@link WifiAwareManager#attach(AttachCallback, android.os.Handler)}.
- * Note that the actual achieved configuration may be different from the
- * requested configuration - since different applications may request different
- * configurations.
- *
- * @hide
- */
-public final class ConfigRequest implements Parcelable {
-    /**
-     * Lower range of possible cluster ID.
-     */
-    public static final int CLUSTER_ID_MIN = 0;
-
-    /**
-     * Upper range of possible cluster ID.
-     */
-    public static final int CLUSTER_ID_MAX = 0xFFFF;
-
-    /**
-     * Indices for configuration variables which are specified per band.
-     */
-    public static final int NAN_BAND_24GHZ = 0;
-    public static final int NAN_BAND_5GHZ = 1;
-    public static final int NAN_BAND_6GHZ = 2;
-
-    /**
-     * Magic values for Discovery Window (DW) interval configuration
-     */
-    public static final int DW_INTERVAL_NOT_INIT = -1;
-    public static final int DW_DISABLE = 0; // only valid for 5GHz
-
-    /**
-     * Indicates whether 5G band support is requested.
-     */
-    public final boolean mSupport5gBand;
-
-    /**
-     * Indicates whether 6G band support is requested.
-     */
-    public final boolean mSupport6gBand;
-
-    /**
-     * Specifies the desired master preference.
-     */
-    public final int mMasterPreference;
-
-    /**
-     * Specifies the desired lower range of the cluster ID. Must be lower then
-     * {@link ConfigRequest#mClusterHigh}.
-     */
-    public final int mClusterLow;
-
-    /**
-     * Specifies the desired higher range of the cluster ID. Must be higher then
-     * {@link ConfigRequest#mClusterLow}.
-     */
-    public final int mClusterHigh;
-
-    /**
-     * Specifies the discovery window interval for the device on NAN_BAND_*.
-     */
-    public final int mDiscoveryWindowInterval[];
-
-    private ConfigRequest(boolean support5gBand, boolean support6gBand, int masterPreference,
-            int clusterLow, int clusterHigh, int[] discoveryWindowInterval) {
-        mSupport5gBand = support5gBand;
-        mSupport6gBand = support6gBand;
-        mMasterPreference = masterPreference;
-        mClusterLow = clusterLow;
-        mClusterHigh = clusterHigh;
-        mDiscoveryWindowInterval = discoveryWindowInterval;
-    }
-
-    @Override
-    public String toString() {
-        return "ConfigRequest [mSupport5gBand=" + mSupport5gBand
-                + ", mSupport6gBand=" + mSupport6gBand
-                + ", mMasterPreference=" + mMasterPreference
-                + ", mClusterLow=" + mClusterLow
-                + ", mClusterHigh=" + mClusterHigh
-                + ", mDiscoveryWindowInterval=" + Arrays.toString(mDiscoveryWindowInterval) + "]";
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mSupport5gBand ? 1 : 0);
-        dest.writeInt(mSupport6gBand ? 1 : 0);
-        dest.writeInt(mMasterPreference);
-        dest.writeInt(mClusterLow);
-        dest.writeInt(mClusterHigh);
-        dest.writeIntArray(mDiscoveryWindowInterval);
-    }
-
-    public static final @android.annotation.NonNull Creator<ConfigRequest> CREATOR = new Creator<ConfigRequest>() {
-        @Override
-        public ConfigRequest[] newArray(int size) {
-            return new ConfigRequest[size];
-        }
-
-        @Override
-        public ConfigRequest createFromParcel(Parcel in) {
-            boolean support5gBand = in.readInt() != 0;
-            boolean support6gBand = in.readInt() != 0;
-            int masterPreference = in.readInt();
-            int clusterLow = in.readInt();
-            int clusterHigh = in.readInt();
-            int discoveryWindowInterval[] = in.createIntArray();
-
-            return new ConfigRequest(support5gBand, support6gBand, masterPreference, clusterLow,
-                    clusterHigh, discoveryWindowInterval);
-        }
-    };
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) {
-            return true;
-        }
-
-        if (!(o instanceof ConfigRequest)) {
-            return false;
-        }
-
-        ConfigRequest lhs = (ConfigRequest) o;
-
-        return mSupport5gBand == lhs.mSupport5gBand
-                && mSupport6gBand == lhs.mSupport6gBand
-                && mMasterPreference == lhs.mMasterPreference
-                && mClusterLow == lhs.mClusterLow && mClusterHigh == lhs.mClusterHigh
-                && Arrays.equals(mDiscoveryWindowInterval, lhs.mDiscoveryWindowInterval);
-    }
-
-    @Override
-    public int hashCode() {
-        int result = 17;
-
-        result = 31 * result + (mSupport5gBand ? 1 : 0);
-        result = 31 * result + (mSupport6gBand ? 1 : 0);
-        result = 31 * result + mMasterPreference;
-        result = 31 * result + mClusterLow;
-        result = 31 * result + mClusterHigh;
-        result = 31 * result + Arrays.hashCode(mDiscoveryWindowInterval);
-
-        return result;
-    }
-
-    /**
-     * Verifies that the contents of the ConfigRequest are valid. Otherwise
-     * throws an IllegalArgumentException.
-     */
-    public void validate() throws IllegalArgumentException {
-        if (mMasterPreference < 0) {
-            throw new IllegalArgumentException(
-                    "Master Preference specification must be non-negative");
-        }
-        if (mMasterPreference == 1 || mMasterPreference == 255 || mMasterPreference > 255) {
-            throw new IllegalArgumentException("Master Preference specification must not "
-                    + "exceed 255 or use 1 or 255 (reserved values)");
-        }
-        if (mClusterLow < CLUSTER_ID_MIN) {
-            throw new IllegalArgumentException("Cluster specification must be non-negative");
-        }
-        if (mClusterLow > CLUSTER_ID_MAX) {
-            throw new IllegalArgumentException("Cluster specification must not exceed 0xFFFF");
-        }
-        if (mClusterHigh < CLUSTER_ID_MIN) {
-            throw new IllegalArgumentException("Cluster specification must be non-negative");
-        }
-        if (mClusterHigh > CLUSTER_ID_MAX) {
-            throw new IllegalArgumentException("Cluster specification must not exceed 0xFFFF");
-        }
-        if (mClusterLow > mClusterHigh) {
-            throw new IllegalArgumentException(
-                    "Invalid argument combination - must have Cluster Low <= Cluster High");
-        }
-        if (mDiscoveryWindowInterval.length != 3) {
-            throw new IllegalArgumentException(
-                    "Invalid discovery window interval: must have 3 elements (2.4 & 5 & 6");
-        }
-        if (mDiscoveryWindowInterval[NAN_BAND_24GHZ] != DW_INTERVAL_NOT_INIT &&
-                (mDiscoveryWindowInterval[NAN_BAND_24GHZ] < 1 // valid for 2.4GHz: [1-5]
-                || mDiscoveryWindowInterval[NAN_BAND_24GHZ] > 5)) {
-            throw new IllegalArgumentException(
-                    "Invalid discovery window interval for 2.4GHz: valid is UNSET or [1,5]");
-        }
-        if (mDiscoveryWindowInterval[NAN_BAND_5GHZ] != DW_INTERVAL_NOT_INIT &&
-                (mDiscoveryWindowInterval[NAN_BAND_5GHZ] < 0 // valid for 5GHz: [0-5]
-                || mDiscoveryWindowInterval[NAN_BAND_5GHZ] > 5)) {
-            throw new IllegalArgumentException(
-                "Invalid discovery window interval for 5GHz: valid is UNSET or [0,5]");
-        }
-        if (mDiscoveryWindowInterval[NAN_BAND_6GHZ] != DW_INTERVAL_NOT_INIT
-                && (mDiscoveryWindowInterval[NAN_BAND_6GHZ] < 0 // valid for 6GHz: [0-5]
-                || mDiscoveryWindowInterval[NAN_BAND_6GHZ] > 5)) {
-            throw new IllegalArgumentException(
-                "Invalid discovery window interval for 6GHz: valid is UNSET or [0,5]");
-        }
-    }
-
-    /**
-     * Builder used to build {@link ConfigRequest} objects.
-     */
-    public static final class Builder {
-        private boolean mSupport5gBand = true;
-        private boolean mSupport6gBand = false;
-        private int mMasterPreference = 0;
-        private int mClusterLow = CLUSTER_ID_MIN;
-        private int mClusterHigh = CLUSTER_ID_MAX;
-        private int[] mDiscoveryWindowInterval = {DW_INTERVAL_NOT_INIT, DW_INTERVAL_NOT_INIT,
-                DW_INTERVAL_NOT_INIT};
-
-        /**
-         * Specify whether 5G band support is required in this request. Disabled by default.
-         *
-         * @param support5gBand Support for 5G band is required.
-         *
-         * @return The builder to facilitate chaining
-         *         {@code builder.setXXX(..).setXXX(..)}.
-         */
-        public Builder setSupport5gBand(boolean support5gBand) {
-            mSupport5gBand = support5gBand;
-            return this;
-        }
-
-        /**
-         * Specify whether 6G band support is required in this request. Disabled by default.
-         *
-         * @param support6gBand Support for 6G band is required.
-         *
-         * @return The builder to facilitate chaining
-         *         {@code builder.setXXX(..).setXXX(..)}.
-         */
-        public Builder setSupport6gBand(boolean support6gBand) {
-            mSupport6gBand = support6gBand;
-            return this;
-        }
-
-        /**
-         * Specify the Master Preference requested. The permitted range is 0 (the default) to
-         * 255 with 1 and 255 excluded (reserved).
-         *
-         * @param masterPreference The requested master preference
-         *
-         * @return The builder to facilitate chaining
-         *         {@code builder.setXXX(..).setXXX(..)}.
-         */
-        public Builder setMasterPreference(int masterPreference) {
-            if (masterPreference < 0) {
-                throw new IllegalArgumentException(
-                        "Master Preference specification must be non-negative");
-            }
-            if (masterPreference == 1 || masterPreference == 255 || masterPreference > 255) {
-                throw new IllegalArgumentException("Master Preference specification must not "
-                        + "exceed 255 or use 1 or 255 (reserved values)");
-            }
-
-            mMasterPreference = masterPreference;
-            return this;
-        }
-
-        /**
-         * The Cluster ID is generated randomly for new Aware networks. Specify
-         * the lower range of the cluster ID. The upper range is specified using
-         * the {@link ConfigRequest.Builder#setClusterHigh(int)}. The permitted
-         * range is 0 (the default) to the value specified by
-         * {@link ConfigRequest.Builder#setClusterHigh(int)}. Equality of Low and High is
-         * permitted which restricts the Cluster ID to the specified value.
-         *
-         * @param clusterLow The lower range of the generated cluster ID.
-         *
-         * @return The builder to facilitate chaining
-         *         {@code builder.setClusterLow(..).setClusterHigh(..)}.
-         */
-        public Builder setClusterLow(int clusterLow) {
-            if (clusterLow < CLUSTER_ID_MIN) {
-                throw new IllegalArgumentException("Cluster specification must be non-negative");
-            }
-            if (clusterLow > CLUSTER_ID_MAX) {
-                throw new IllegalArgumentException("Cluster specification must not exceed 0xFFFF");
-            }
-
-            mClusterLow = clusterLow;
-            return this;
-        }
-
-        /**
-         * The Cluster ID is generated randomly for new Aware networks. Specify
-         * the lower upper of the cluster ID. The lower range is specified using
-         * the {@link ConfigRequest.Builder#setClusterLow(int)}. The permitted
-         * range is the value specified by
-         * {@link ConfigRequest.Builder#setClusterLow(int)} to 0xFFFF (the default). Equality of
-         * Low and High is permitted which restricts the Cluster ID to the specified value.
-         *
-         * @param clusterHigh The upper range of the generated cluster ID.
-         *
-         * @return The builder to facilitate chaining
-         *         {@code builder.setClusterLow(..).setClusterHigh(..)}.
-         */
-        public Builder setClusterHigh(int clusterHigh) {
-            if (clusterHigh < CLUSTER_ID_MIN) {
-                throw new IllegalArgumentException("Cluster specification must be non-negative");
-            }
-            if (clusterHigh > CLUSTER_ID_MAX) {
-                throw new IllegalArgumentException("Cluster specification must not exceed 0xFFFF");
-            }
-
-            mClusterHigh = clusterHigh;
-            return this;
-        }
-
-        /**
-         * The discovery window interval specifies the discovery windows in which the device will be
-         * awake. The configuration enables trading off latency vs. power (higher interval means
-         * higher discovery latency but lower power).
-         *
-         * @param band Either {@link #NAN_BAND_24GHZ} or {@link #NAN_BAND_5GHZ} or
-         *        {@link #NAN_BAND_6GHZ}.
-         * @param interval A value of 1, 2, 3, 4, or 5 indicating an interval of 2^(interval-1). For
-         *                 the 5GHz band a value of 0 indicates that the device will not be awake
-         *                 for any discovery windows.
-         *
-         * @return The builder itself to facilitate chaining operations
-         *         {@code builder.setDiscoveryWindowInterval(...).setMasterPreference(...)}.
-         */
-        public Builder setDiscoveryWindowInterval(int band, int interval) {
-            if (band != NAN_BAND_24GHZ && band != NAN_BAND_5GHZ && band != NAN_BAND_6GHZ) {
-                throw new IllegalArgumentException("Invalid band value");
-            }
-            if ((band == NAN_BAND_24GHZ && (interval < 1 || interval > 5))
-                    || (band == NAN_BAND_5GHZ && (interval < 0 || interval > 5))
-                    || (band == NAN_BAND_6GHZ && (interval < 0 || interval > 5))) {
-                throw new IllegalArgumentException(
-                        "Invalid interval value: 2.4 GHz [1,5] or 5GHz/6GHz [0,5]");
-            }
-
-            mDiscoveryWindowInterval[band] = interval;
-            return this;
-        }
-
-        /**
-         * Build {@link ConfigRequest} given the current requests made on the
-         * builder.
-         */
-        public ConfigRequest build() {
-            if (mClusterLow > mClusterHigh) {
-                throw new IllegalArgumentException(
-                        "Invalid argument combination - must have Cluster Low <= Cluster High");
-            }
-
-            return new ConfigRequest(mSupport5gBand, mSupport6gBand, mMasterPreference, mClusterLow,
-                    mClusterHigh, mDiscoveryWindowInterval);
-        }
-    }
-}
diff --git a/wifi/java/android/net/wifi/aware/DiscoverySession.java b/wifi/java/android/net/wifi/aware/DiscoverySession.java
deleted file mode 100644
index 4d92ae1..0000000
--- a/wifi/java/android/net/wifi/aware/DiscoverySession.java
+++ /dev/null
@@ -1,431 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.aware;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.net.NetworkSpecifier;
-import android.util.CloseGuard;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.lang.ref.Reference;
-import java.lang.ref.WeakReference;
-
-/**
- * A class representing a single publish or subscribe Aware session. This object
- * will not be created directly - only its child classes are available:
- * {@link PublishDiscoverySession} and {@link SubscribeDiscoverySession}. This
- * class provides functionality common to both publish and subscribe discovery sessions:
- * <ul>
- *      <li>Sending messages: {@link #sendMessage(PeerHandle, int, byte[])} method.
- *      <li>Creating a network-specifier when requesting a Aware connection using
- *      {@link WifiAwareNetworkSpecifier.Builder}.
- * </ul>
- * <p>
- * The {@link #close()} method must be called to destroy discovery sessions once they are
- * no longer needed.
- */
-public class DiscoverySession implements AutoCloseable {
-    private static final String TAG = "DiscoverySession";
-    private static final boolean DBG = false;
-    private static final boolean VDBG = false; // STOPSHIP if true
-
-    private static final int MAX_SEND_RETRY_COUNT = 5;
-
-    /** @hide */
-    protected WeakReference<WifiAwareManager> mMgr;
-    /** @hide */
-    protected final int mClientId;
-    /** @hide */
-    protected final int mSessionId;
-    /** @hide */
-    protected boolean mTerminated = false;
-
-    private final CloseGuard mCloseGuard = new CloseGuard();
-
-    /**
-     * Return the maximum permitted retry count when sending messages using
-     * {@link #sendMessage(PeerHandle, int, byte[], int)}.
-     *
-     * @return Maximum retry count when sending messages.
-     *
-     * @hide
-     */
-    public static int getMaxSendRetryCount() {
-        return MAX_SEND_RETRY_COUNT;
-    }
-
-    /** @hide */
-    public DiscoverySession(WifiAwareManager manager, int clientId, int sessionId) {
-        if (VDBG) {
-            Log.v(TAG, "New discovery session created: manager=" + manager + ", clientId="
-                    + clientId + ", sessionId=" + sessionId);
-        }
-
-        mMgr = new WeakReference<>(manager);
-        mClientId = clientId;
-        mSessionId = sessionId;
-
-        mCloseGuard.open("close");
-    }
-
-    /**
-     * Destroy the publish or subscribe session - free any resources, and stop
-     * transmitting packets on-air (for an active session) or listening for
-     * matches (for a passive session). The session may not be used for any
-     * additional operations after its destruction.
-     * <p>
-     *     This operation must be done on a session which is no longer needed. Otherwise system
-     *     resources will continue to be utilized until the application exits. The only
-     *     exception is a session for which we received a termination callback,
-     *     {@link DiscoverySessionCallback#onSessionTerminated()}.
-     */
-    @Override
-    public void close() {
-        WifiAwareManager mgr = mMgr.get();
-        if (mgr == null) {
-            Log.w(TAG, "destroy: called post GC on WifiAwareManager");
-            return;
-        }
-        mgr.terminateSession(mClientId, mSessionId);
-        mTerminated = true;
-        mMgr.clear();
-        mCloseGuard.close();
-        Reference.reachabilityFence(this);
-    }
-
-    /**
-     * Sets the status of the session to terminated - i.e. an indication that
-     * already terminated rather than executing a termination.
-     *
-     * @hide
-     */
-    public void setTerminated() {
-        if (mTerminated) {
-            Log.w(TAG, "terminate: already terminated.");
-            return;
-        }
-
-        mTerminated = true;
-        mMgr.clear();
-        mCloseGuard.close();
-    }
-
-    /** @hide */
-    @Override
-    protected void finalize() throws Throwable {
-        try {
-            if (mCloseGuard != null) {
-                mCloseGuard.warnIfOpen();
-            }
-
-            if (!mTerminated) {
-                close();
-            }
-        } finally {
-            super.finalize();
-        }
-    }
-
-    /**
-     * Access the client ID of the Aware session.
-     *
-     * Note: internal visibility for testing.
-     *
-     * @return The internal client ID.
-     *
-     * @hide
-     */
-    @VisibleForTesting
-    public int getClientId() {
-        return mClientId;
-    }
-
-    /**
-     * Access the discovery session ID of the Aware session.
-     *
-     * Note: internal visibility for testing.
-     *
-     * @return The internal discovery session ID.
-     *
-     * @hide
-     */
-    @VisibleForTesting
-    public int getSessionId() {
-        return mSessionId;
-    }
-
-    /**
-     * Sends a message to the specified destination. Aware messages are transmitted in the context
-     * of a discovery session - executed subsequent to a publish/subscribe
-     * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle,
-     * byte[], java.util.List)} event.
-     * <p>
-     *     Aware messages are not guaranteed delivery. Callbacks on
-     *     {@link DiscoverySessionCallback} indicate message was transmitted successfully,
-     *     {@link DiscoverySessionCallback#onMessageSendSucceeded(int)}, or transmission
-     *     failed (possibly after several retries) -
-     *     {@link DiscoverySessionCallback#onMessageSendFailed(int)}.
-     * <p>
-     *     The peer will get a callback indicating a message was received using
-     *     {@link DiscoverySessionCallback#onMessageReceived(PeerHandle,
-     *     byte[])}.
-     *
-     * @param peerHandle The peer's handle for the message. Must be a result of an
-     * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle,
-     * byte[], java.util.List)} or
-     * {@link DiscoverySessionCallback#onMessageReceived(PeerHandle,
-     * byte[])} events.
-     * @param messageId An arbitrary integer used by the caller to identify the message. The same
-     *            integer ID will be returned in the callbacks indicating message send success or
-     *            failure. The {@code messageId} is not used internally by the Aware service - it
-     *                  can be arbitrary and non-unique.
-     * @param message The message to be transmitted.
-     * @param retryCount An integer specifying how many additional service-level (as opposed to PHY
-     *            or MAC level) retries should be attempted if there is no ACK from the receiver
-     *            (note: no retransmissions are attempted in other failure cases). A value of 0
-     *            indicates no retries. Max permitted value is {@link #getMaxSendRetryCount()}.
-     *
-     * @hide
-     */
-    public void sendMessage(@NonNull PeerHandle peerHandle, int messageId,
-            @Nullable byte[] message, int retryCount) {
-        if (mTerminated) {
-            Log.w(TAG, "sendMessage: called on terminated session");
-            return;
-        }
-
-        WifiAwareManager mgr = mMgr.get();
-        if (mgr == null) {
-            Log.w(TAG, "sendMessage: called post GC on WifiAwareManager");
-            return;
-        }
-
-        mgr.sendMessage(mClientId, mSessionId, peerHandle, message, messageId, retryCount);
-    }
-
-    /**
-     * Sends a message to the specified destination. Aware messages are transmitted in the context
-     * of a discovery session - executed subsequent to a publish/subscribe
-     * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle,
-     * byte[], java.util.List)} event.
-     * <p>
-     *     Aware messages are not guaranteed delivery. Callbacks on
-     *     {@link DiscoverySessionCallback} indicate message was transmitted successfully,
-     *     {@link DiscoverySessionCallback#onMessageSendSucceeded(int)}, or transmission
-     *     failed (possibly after several retries) -
-     *     {@link DiscoverySessionCallback#onMessageSendFailed(int)}.
-     * <p>
-     * The peer will get a callback indicating a message was received using
-     * {@link DiscoverySessionCallback#onMessageReceived(PeerHandle,
-     * byte[])}.
-     *
-     * @param peerHandle The peer's handle for the message. Must be a result of an
-     * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle,
-     * byte[], java.util.List)} or
-     * {@link DiscoverySessionCallback#onMessageReceived(PeerHandle,
-     * byte[])} events.
-     * @param messageId An arbitrary integer used by the caller to identify the message. The same
-     *            integer ID will be returned in the callbacks indicating message send success or
-     *            failure. The {@code messageId} is not used internally by the Aware service - it
-     *                  can be arbitrary and non-unique.
-     * @param message The message to be transmitted.
-     */
-    public void sendMessage(@NonNull PeerHandle peerHandle, int messageId,
-            @Nullable byte[] message) {
-        sendMessage(peerHandle, messageId, message, 0);
-    }
-
-    /**
-     * Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} for
-     * an unencrypted WiFi Aware connection (link) to the specified peer. The
-     * {@link android.net.NetworkRequest.Builder#addTransportType(int)} should be set to
-     * {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}.
-     * <p>
-     * This method should be used when setting up a connection with a peer discovered through Aware
-     * discovery or communication (in such scenarios the MAC address of the peer is shielded by
-     * an opaque peer ID handle). If an Aware connection is needed to a peer discovered using other
-     * OOB (out-of-band) mechanism then use the alternative
-     * {@link WifiAwareSession#createNetworkSpecifierOpen(int, byte[])} method - which uses the
-     * peer's MAC address.
-     * <p>
-     * Note: per the Wi-Fi Aware specification the roles are fixed - a Subscriber is an INITIATOR
-     * and a Publisher is a RESPONDER.
-     * <p>
-     * To set up an encrypted link use the
-     * {@link #createNetworkSpecifierPassphrase(PeerHandle, String)} API.
-     * @deprecated Use the replacement {@link WifiAwareNetworkSpecifier.Builder}.
-     *
-     * @param peerHandle The peer's handle obtained through
-     * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle, byte[], java.util.List)}
-     *                   or
-     *                   {@link DiscoverySessionCallback#onMessageReceived(PeerHandle, byte[])}.
-     *                   On a RESPONDER this value is used to gate the acceptance of a connection
-     *                   request from only that peer.
-     *
-     * @return A {@link NetworkSpecifier} to be used to construct
-     * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} to pass to
-     * {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest,
-     * android.net.ConnectivityManager.NetworkCallback)}
-     * [or other varieties of that API].
-     */
-    @Deprecated
-    public NetworkSpecifier createNetworkSpecifierOpen(@NonNull PeerHandle peerHandle) {
-        if (mTerminated) {
-            Log.w(TAG, "createNetworkSpecifierOpen: called on terminated session");
-            return null;
-        }
-
-        WifiAwareManager mgr = mMgr.get();
-        if (mgr == null) {
-            Log.w(TAG, "createNetworkSpecifierOpen: called post GC on WifiAwareManager");
-            return null;
-        }
-
-        int role = this instanceof SubscribeDiscoverySession
-                ? WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR
-                : WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER;
-
-        return mgr.createNetworkSpecifier(mClientId, role, mSessionId, peerHandle, null, null);
-    }
-
-    /**
-     * Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} for
-     * an encrypted WiFi Aware connection (link) to the specified peer. The
-     * {@link android.net.NetworkRequest.Builder#addTransportType(int)} should be set to
-     * {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}.
-     * <p>
-     * This method should be used when setting up a connection with a peer discovered through Aware
-     * discovery or communication (in such scenarios the MAC address of the peer is shielded by
-     * an opaque peer ID handle). If an Aware connection is needed to a peer discovered using other
-     * OOB (out-of-band) mechanism then use the alternative
-     * {@link WifiAwareSession#createNetworkSpecifierPassphrase(int, byte[], String)} method -
-     * which uses the peer's MAC address.
-     * <p>
-     * Note: per the Wi-Fi Aware specification the roles are fixed - a Subscriber is an INITIATOR
-     * and a Publisher is a RESPONDER.
-     * @deprecated Use the replacement {@link WifiAwareNetworkSpecifier.Builder}.
-     *
-     * @param peerHandle The peer's handle obtained through
-     * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle,
-     * byte[], java.util.List)} or
-     * {@link DiscoverySessionCallback#onMessageReceived(PeerHandle,
-     * byte[])}. On a RESPONDER this value is used to gate the acceptance of a connection request
-     *                   from only that peer.
-     * @param passphrase The passphrase to be used to encrypt the link. The PMK is generated from
-     *                   the passphrase. Use the
-     *                   {@link #createNetworkSpecifierOpen(PeerHandle)} API to
-     *                   specify an open (unencrypted) link.
-     *
-     * @return A {@link NetworkSpecifier} to be used to construct
-     * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} to pass to
-     * {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest,
-     * android.net.ConnectivityManager.NetworkCallback)}
-     * [or other varieties of that API].
-     */
-    @Deprecated
-    public NetworkSpecifier createNetworkSpecifierPassphrase(
-            @NonNull PeerHandle peerHandle, @NonNull String passphrase) {
-        if (!WifiAwareUtils.validatePassphrase(passphrase)) {
-            throw new IllegalArgumentException("Passphrase must meet length requirements");
-        }
-
-        if (mTerminated) {
-            Log.w(TAG, "createNetworkSpecifierPassphrase: called on terminated session");
-            return null;
-        }
-
-        WifiAwareManager mgr = mMgr.get();
-        if (mgr == null) {
-            Log.w(TAG, "createNetworkSpecifierPassphrase: called post GC on WifiAwareManager");
-            return null;
-        }
-
-        int role = this instanceof SubscribeDiscoverySession
-                ? WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR
-                : WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER;
-
-        return mgr.createNetworkSpecifier(mClientId, role, mSessionId, peerHandle, null,
-                passphrase);
-    }
-
-    /**
-     * Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} for
-     * an encrypted WiFi Aware connection (link) to the specified peer. The
-     * {@link android.net.NetworkRequest.Builder#addTransportType(int)} should be set to
-     * {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}.
-     * <p>
-     * This method should be used when setting up a connection with a peer discovered through Aware
-     * discovery or communication (in such scenarios the MAC address of the peer is shielded by
-     * an opaque peer ID handle). If an Aware connection is needed to a peer discovered using other
-     * OOB (out-of-band) mechanism then use the alternative
-     * {@link WifiAwareSession#createNetworkSpecifierPmk(int, byte[], byte[])} method - which uses
-     * the peer's MAC address.
-     * <p>
-     * Note: per the Wi-Fi Aware specification the roles are fixed - a Subscriber is an INITIATOR
-     * and a Publisher is a RESPONDER.
-     * @deprecated Use the replacement {@link WifiAwareNetworkSpecifier.Builder}.
-     *
-     * @param peerHandle The peer's handle obtained through
-     * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle,
-     * byte[], java.util.List)} or
-     * {@link DiscoverySessionCallback#onMessageReceived(PeerHandle,
-     * byte[])}. On a RESPONDER this value is used to gate the acceptance of a connection request
-     *                   from only that peer.
-     * @param pmk A PMK (pairwise master key, see IEEE 802.11i) specifying the key to use for
-     *            encrypting the data-path. Use the
-     *            {@link #createNetworkSpecifierPassphrase(PeerHandle, String)} to specify a
-     *            Passphrase or {@link #createNetworkSpecifierOpen(PeerHandle)} to specify an
-     *            open (unencrypted) link.
-     *
-     * @return A {@link NetworkSpecifier} to be used to construct
-     * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} to pass to
-     * {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest,
-     * android.net.ConnectivityManager.NetworkCallback)}
-     * [or other varieties of that API].
-     *
-     * @hide
-     */
-    @Deprecated
-    @SystemApi
-    public NetworkSpecifier createNetworkSpecifierPmk(@NonNull PeerHandle peerHandle,
-            @NonNull byte[] pmk) {
-        if (!WifiAwareUtils.validatePmk(pmk)) {
-            throw new IllegalArgumentException("PMK must 32 bytes");
-        }
-
-        if (mTerminated) {
-            Log.w(TAG, "createNetworkSpecifierPmk: called on terminated session");
-            return null;
-        }
-
-        WifiAwareManager mgr = mMgr.get();
-        if (mgr == null) {
-            Log.w(TAG, "createNetworkSpecifierPmk: called post GC on WifiAwareManager");
-            return null;
-        }
-
-        int role = this instanceof SubscribeDiscoverySession
-                ? WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR
-                : WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER;
-
-        return mgr.createNetworkSpecifier(mClientId, role, mSessionId, peerHandle, pmk, null);
-    }
-}
diff --git a/wifi/java/android/net/wifi/aware/DiscoverySessionCallback.java b/wifi/java/android/net/wifi/aware/DiscoverySessionCallback.java
deleted file mode 100644
index bfb0462..0000000
--- a/wifi/java/android/net/wifi/aware/DiscoverySessionCallback.java
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.aware;
-
-import android.annotation.NonNull;
-
-import java.util.List;
-
-/**
- * Base class for Aware session events callbacks. Should be extended by
- * applications wanting notifications. The callbacks are set when a
- * publish or subscribe session is created using
- * {@link WifiAwareSession#publish(PublishConfig, DiscoverySessionCallback,
- * android.os.Handler)} or
- * {@link WifiAwareSession#subscribe(SubscribeConfig, DiscoverySessionCallback,
- * android.os.Handler)}.
- * <p>
- * A single callback is set at session creation - it cannot be replaced.
- */
-public class DiscoverySessionCallback {
-    /**
-     * Called when a publish operation is started successfully in response to a
-     * {@link WifiAwareSession#publish(PublishConfig, DiscoverySessionCallback,
-     * android.os.Handler)} operation.
-     *
-     * @param session The {@link PublishDiscoverySession} used to control the
-     *            discovery session.
-     */
-    public void onPublishStarted(@NonNull PublishDiscoverySession session) {
-        /* empty */
-    }
-
-    /**
-     * Called when a subscribe operation is started successfully in response to a
-     * {@link WifiAwareSession#subscribe(SubscribeConfig, DiscoverySessionCallback,
-     * android.os.Handler)} operation.
-     *
-     * @param session The {@link SubscribeDiscoverySession} used to control the
-     *            discovery session.
-     */
-    public void onSubscribeStarted(@NonNull SubscribeDiscoverySession session) {
-        /* empty */
-    }
-
-    /**
-     * Called when a publish or subscribe discovery session configuration update request
-     * succeeds. Called in response to
-     * {@link PublishDiscoverySession#updatePublish(PublishConfig)} or
-     * {@link SubscribeDiscoverySession#updateSubscribe(SubscribeConfig)}.
-     */
-    public void onSessionConfigUpdated() {
-        /* empty */
-    }
-
-    /**
-     * Called when a publish or subscribe discovery session cannot be created:
-     * {@link WifiAwareSession#publish(PublishConfig, DiscoverySessionCallback,
-     * android.os.Handler)} or
-     * {@link WifiAwareSession#subscribe(SubscribeConfig, DiscoverySessionCallback,
-     * android.os.Handler)}, or when a configuration update fails:
-     * {@link PublishDiscoverySession#updatePublish(PublishConfig)} or
-     * {@link SubscribeDiscoverySession#updateSubscribe(SubscribeConfig)}.
-     * <p>
-     *     For discovery session updates failure leaves the session running with its previous
-     *     configuration - the discovery session is not terminated.
-     */
-    public void onSessionConfigFailed() {
-        /* empty */
-    }
-
-    /**
-     * Called when a discovery session (publish or subscribe) terminates. Termination may be due
-     * to user-request (either directly through {@link DiscoverySession#close()} or
-     * application-specified expiration, e.g. {@link PublishConfig.Builder#setTtlSec(int)}
-     * or {@link SubscribeConfig.Builder#setTtlSec(int)}).
-     */
-    public void onSessionTerminated() {
-        /* empty */
-    }
-
-    /**
-     * Called when a discovery (publish or subscribe) operation results in a
-     * service discovery.
-     * <p>
-     * Note that this method and
-     * {@link #onServiceDiscoveredWithinRange(PeerHandle, byte[], List, int)} may be called
-     * multiple times per service discovery.
-     *
-     * @param peerHandle An opaque handle to the peer matching our discovery operation.
-     * @param serviceSpecificInfo The service specific information (arbitrary
-     *            byte array) provided by the peer as part of its discovery
-     *            configuration.
-     * @param matchFilter The filter which resulted in this service discovery. For
-     * {@link PublishConfig#PUBLISH_TYPE_UNSOLICITED},
-     * {@link SubscribeConfig#SUBSCRIBE_TYPE_PASSIVE} discovery sessions this is the publisher's
-     *                    match filter. For {@link PublishConfig#PUBLISH_TYPE_SOLICITED},
-     *                    {@link SubscribeConfig#SUBSCRIBE_TYPE_ACTIVE} discovery sessions this
-     *                    is the subscriber's match filter.
-     */
-    public void onServiceDiscovered(PeerHandle peerHandle,
-            byte[] serviceSpecificInfo, List<byte[]> matchFilter) {
-        /* empty */
-    }
-
-    /**
-     * Called when a discovery (publish or subscribe) operation results in a
-     * service discovery. Called when a Subscribe service was configured with a range requirement
-     * {@link SubscribeConfig.Builder#setMinDistanceMm(int)} and/or
-     * {@link SubscribeConfig.Builder#setMaxDistanceMm(int)} and the Publish service was configured
-     * with {@link PublishConfig.Builder#setRangingEnabled(boolean)}.
-     * <p>
-     * If either Publisher or Subscriber does not enable Ranging, or if Ranging is temporarily
-     * disabled by the underlying device, service discovery proceeds without ranging and the
-     * {@link #onServiceDiscovered(PeerHandle, byte[], List)} is called.
-     * <p>
-     * Note that this method and {@link #onServiceDiscovered(PeerHandle, byte[], List)} may be
-     * called multiple times per service discovery.
-     *
-     * @param peerHandle An opaque handle to the peer matching our discovery operation.
-     * @param serviceSpecificInfo The service specific information (arbitrary
-     *            byte array) provided by the peer as part of its discovery
-     *            configuration.
-     * @param matchFilter The filter which resulted in this service discovery. For
-     * {@link PublishConfig#PUBLISH_TYPE_UNSOLICITED},
-     * {@link SubscribeConfig#SUBSCRIBE_TYPE_PASSIVE} discovery sessions this is the publisher's
-     *                    match filter. For {@link PublishConfig#PUBLISH_TYPE_SOLICITED},
-     *                    {@link SubscribeConfig#SUBSCRIBE_TYPE_ACTIVE} discovery sessions this
-     *                    is the subscriber's match filter.
-     * @param distanceMm The measured distance to the Publisher in mm. Note: the measured distance
-     *                   may be negative for very close devices.
-     */
-    public void onServiceDiscoveredWithinRange(PeerHandle peerHandle,
-        byte[] serviceSpecificInfo, List<byte[]> matchFilter, int distanceMm) {
-        /* empty */
-    }
-
-    /**
-     * Called in response to
-     * {@link DiscoverySession#sendMessage(PeerHandle, int, byte[])}
-     * when a message is transmitted successfully - i.e. when it was received successfully by the
-     * peer (corresponds to an ACK being received).
-     * <p>
-     * Note that either this callback or
-     * {@link DiscoverySessionCallback#onMessageSendFailed(int)} will be
-     * received - never both.
-     *
-     * @param messageId The arbitrary message ID specified when sending the message.
-     */
-    public void onMessageSendSucceeded(@SuppressWarnings("unused") int messageId) {
-        /* empty */
-    }
-
-    /**
-     * Called when message transmission initiated with
-     * {@link DiscoverySession#sendMessage(PeerHandle, int, byte[])} fails. E.g. when no ACK is
-     * received from the peer.
-     * <p>
-     * Note that either this callback or
-     * {@link DiscoverySessionCallback#onMessageSendSucceeded(int)} will be received
-     * - never both.
-     *
-     * @param messageId The arbitrary message ID specified when sending the message.
-     */
-    public void onMessageSendFailed(@SuppressWarnings("unused") int messageId) {
-        /* empty */
-    }
-
-    /**
-     * Called when a message is received from a discovery session peer - in response to the
-     * peer's {@link DiscoverySession#sendMessage(PeerHandle, int, byte[])}.
-     *
-     * @param peerHandle An opaque handle to the peer matching our discovery operation.
-     * @param message A byte array containing the message.
-     */
-    public void onMessageReceived(PeerHandle peerHandle, byte[] message) {
-        /* empty */
-    }
-}
diff --git a/wifi/java/android/net/wifi/aware/IWifiAwareDiscoverySessionCallback.aidl b/wifi/java/android/net/wifi/aware/IWifiAwareDiscoverySessionCallback.aidl
deleted file mode 100644
index 421a8af..0000000
--- a/wifi/java/android/net/wifi/aware/IWifiAwareDiscoverySessionCallback.aidl
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.aware;
-
-/**
- * Callback interface that WifiAwareManager implements
- *
- * {@hide}
- */
-oneway interface IWifiAwareDiscoverySessionCallback
-{
-    void onSessionStarted(int discoverySessionId);
-    void onSessionConfigSuccess();
-    void onSessionConfigFail(int reason);
-    void onSessionTerminated(int reason);
-
-    void onMatch(int peerId, in byte[] serviceSpecificInfo, in byte[] matchFilter);
-    void onMatchWithDistance(int peerId, in byte[] serviceSpecificInfo, in byte[] matchFilter,
-            int distanceMm);
-
-    void onMessageSendSuccess(int messageId);
-    void onMessageSendFail(int messageId, int reason);
-    void onMessageReceived(int peerId, in byte[] message);
-}
diff --git a/wifi/java/android/net/wifi/aware/IWifiAwareEventCallback.aidl b/wifi/java/android/net/wifi/aware/IWifiAwareEventCallback.aidl
deleted file mode 100644
index b646567..0000000
--- a/wifi/java/android/net/wifi/aware/IWifiAwareEventCallback.aidl
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.aware;
-
-import android.net.wifi.aware.ConfigRequest;
-
-/**
- * Callback interface that WifiAwareManager implements
- *
- * {@hide}
- */
-oneway interface IWifiAwareEventCallback
-{
-    void onConnectSuccess(int clientId);
-    void onConnectFail(int reason);
-    void onIdentityChanged(in byte[] mac);
-}
diff --git a/wifi/java/android/net/wifi/aware/IWifiAwareMacAddressProvider.aidl b/wifi/java/android/net/wifi/aware/IWifiAwareMacAddressProvider.aidl
deleted file mode 100644
index 0e7289c..0000000
--- a/wifi/java/android/net/wifi/aware/IWifiAwareMacAddressProvider.aidl
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.aware;
-
-/**
- * Callback for IWifiAwareManager.getMacAddressFromPeerHandle
- *
- * @hide
- */
-oneway interface IWifiAwareMacAddressProvider
-{
-    void macAddress(in Map peerIdToMacMap);
-}
diff --git a/wifi/java/android/net/wifi/aware/IWifiAwareManager.aidl b/wifi/java/android/net/wifi/aware/IWifiAwareManager.aidl
deleted file mode 100644
index 88f95ad..0000000
--- a/wifi/java/android/net/wifi/aware/IWifiAwareManager.aidl
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.aware;
-
-import android.app.PendingIntent;
-
-import android.net.wifi.aware.ConfigRequest;
-import android.net.wifi.aware.IWifiAwareDiscoverySessionCallback;
-import android.net.wifi.aware.IWifiAwareEventCallback;
-import android.net.wifi.aware.IWifiAwareMacAddressProvider;
-import android.net.wifi.aware.PublishConfig;
-import android.net.wifi.aware.SubscribeConfig;
-import android.net.wifi.aware.Characteristics;
-
-/**
- * Interface that WifiAwareService implements
- *
- * {@hide}
- */
-interface IWifiAwareManager
-{
-    // Aware API
-    boolean isUsageEnabled();
-    Characteristics getCharacteristics();
-
-    // client API
-    void connect(in IBinder binder, in String callingPackage, in String callingFeatureId,
-            in IWifiAwareEventCallback callback, in ConfigRequest configRequest,
-            boolean notifyOnIdentityChanged);
-    void disconnect(int clientId, in IBinder binder);
-
-    void publish(in String callingPackage, in String callingFeatureId, int clientId,
-            in PublishConfig publishConfig, in IWifiAwareDiscoverySessionCallback callback);
-    void subscribe(in String callingPackage, in String callingFeatureId, int clientId,
-            in SubscribeConfig subscribeConfig, in IWifiAwareDiscoverySessionCallback callback);
-
-    // session API
-    void updatePublish(int clientId, int discoverySessionId, in PublishConfig publishConfig);
-    void updateSubscribe(int clientId, int discoverySessionId, in SubscribeConfig subscribeConfig);
-    void sendMessage(int clientId, int discoverySessionId, int peerId, in byte[] message,
-        int messageId, int retryCount);
-    void terminateSession(int clientId, int discoverySessionId);
-
-    // internal APIs: intended to be used between System Services (restricted permissions)
-    void requestMacAddresses(int uid, in List peerIds, in IWifiAwareMacAddressProvider callback);
-}
diff --git a/wifi/java/android/net/wifi/aware/IdentityChangedListener.java b/wifi/java/android/net/wifi/aware/IdentityChangedListener.java
deleted file mode 100644
index a8b19b3..0000000
--- a/wifi/java/android/net/wifi/aware/IdentityChangedListener.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.aware;
-
-/**
- * Base class for a listener which is called with the MAC address of the Aware interface whenever
- * it is changed. Change may be due to device joining a cluster, starting a cluster, or discovery
- * interface change (addresses are randomized at regular intervals). The implication is that
- * peers you've been communicating with may no longer recognize you and you need to re-establish
- * your identity - e.g. by starting a discovery session. This actual MAC address of the
- * interface may also be useful if the application uses alternative (non-Aware) discovery but needs
- * to set up a Aware connection. The provided Aware discovery interface MAC address can then be used
- * in {@link WifiAwareSession#createNetworkSpecifierOpen(int, byte[])} or
- * {@link WifiAwareSession#createNetworkSpecifierPassphrase(int, byte[], String)}.
- */
-public class IdentityChangedListener {
-    /**
-     * @param mac The MAC address of the Aware discovery interface. The application must have the
-     * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} to get the actual MAC address,
-     *            otherwise all 0's will be provided.
-     */
-    public void onIdentityChanged(byte[] mac) {
-        /* empty */
-    }
-}
diff --git a/wifi/java/android/net/wifi/aware/ParcelablePeerHandle.java b/wifi/java/android/net/wifi/aware/ParcelablePeerHandle.java
deleted file mode 100644
index ca473db..0000000
--- a/wifi/java/android/net/wifi/aware/ParcelablePeerHandle.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.aware;
-
-import android.annotation.NonNull;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * A Parcelable {@link PeerHandle}. Can be constructed from a {@code PeerHandle} and then passed
- * to any of the APIs which take a {@code PeerHandle} as inputs.
- */
-public final class ParcelablePeerHandle extends PeerHandle implements Parcelable {
-    /**
-     * Construct a parcelable version of {@link PeerHandle}.
-     *
-     * @param peerHandle The {@link PeerHandle} to be made parcelable.
-     */
-    public ParcelablePeerHandle(@NonNull PeerHandle peerHandle) {
-        super(peerHandle.peerId);
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(peerId);
-    }
-
-    public static final @android.annotation.NonNull Creator<ParcelablePeerHandle> CREATOR =
-            new Creator<ParcelablePeerHandle>() {
-                @Override
-                public ParcelablePeerHandle[] newArray(int size) {
-                    return new ParcelablePeerHandle[size];
-                }
-
-                @Override
-                public ParcelablePeerHandle createFromParcel(Parcel in) {
-                    int peerHandle = in.readInt();
-                    return new ParcelablePeerHandle(new PeerHandle(peerHandle));
-                }
-            };
-}
diff --git a/wifi/java/android/net/wifi/aware/PeerHandle.java b/wifi/java/android/net/wifi/aware/PeerHandle.java
deleted file mode 100644
index 422e177..0000000
--- a/wifi/java/android/net/wifi/aware/PeerHandle.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.aware;
-
-/**
- * Opaque object used to represent a Wi-Fi Aware peer. Obtained from discovery sessions in
- * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle, byte[], java.util.List)} or
- * received messages in {@link DiscoverySessionCallback#onMessageReceived(PeerHandle, byte[])}, and
- * used when sending messages e,g, {@link DiscoverySession#sendMessage(PeerHandle, int, byte[])},
- * or when configuring a network link to a peer, e.g.
- * {@link DiscoverySession#createNetworkSpecifierOpen(PeerHandle)} or
- * {@link DiscoverySession#createNetworkSpecifierPassphrase(PeerHandle, String)}.
- * <p>
- * Note that while a {@code PeerHandle} can be used to track a particular peer (i.e. you can compare
- * the values received from subsequent messages) - it is good practice not to rely on it. Instead
- * use an application level peer identifier encoded in the message,
- * {@link DiscoverySession#sendMessage(PeerHandle, int, byte[])}, and/or in the Publish
- * configuration's service-specific information field,
- * {@link PublishConfig.Builder#setServiceSpecificInfo(byte[])}, or match filter,
- * {@link PublishConfig.Builder#setMatchFilter(java.util.List)}.
- * <p>A parcelable handle object is available with {@link ParcelablePeerHandle}.
- */
-public class PeerHandle {
-    /** @hide */
-    public PeerHandle(int peerId) {
-        this.peerId = peerId;
-    }
-
-    /** @hide */
-    public int peerId;
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) {
-            return true;
-        }
-
-        if (!(o instanceof PeerHandle)) {
-            return false;
-        }
-
-        return peerId == ((PeerHandle) o).peerId;
-    }
-
-    @Override
-    public int hashCode() {
-        return peerId;
-    }
-}
diff --git a/wifi/java/android/net/wifi/aware/PublishConfig.java b/wifi/java/android/net/wifi/aware/PublishConfig.java
deleted file mode 100644
index a8844c1..0000000
--- a/wifi/java/android/net/wifi/aware/PublishConfig.java
+++ /dev/null
@@ -1,393 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.aware;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.wifi.util.HexEncoding;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * Defines the configuration of a Aware publish session. Built using
- * {@link PublishConfig.Builder}. A publish session is created using
- * {@link WifiAwareSession#publish(PublishConfig, DiscoverySessionCallback,
- * android.os.Handler)} or updated using
- * {@link PublishDiscoverySession#updatePublish(PublishConfig)}.
- */
-public final class PublishConfig implements Parcelable {
-    /** @hide */
-    @IntDef({
-            PUBLISH_TYPE_UNSOLICITED, PUBLISH_TYPE_SOLICITED })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface PublishTypes {
-    }
-
-    /**
-     * Defines an unsolicited publish session - a publish session where the publisher is
-     * advertising itself by broadcasting on-the-air. An unsolicited publish session is paired
-     * with an passive subscribe session {@link SubscribeConfig#SUBSCRIBE_TYPE_PASSIVE}.
-     * Configuration is done using {@link PublishConfig.Builder#setPublishType(int)}.
-     */
-    public static final int PUBLISH_TYPE_UNSOLICITED = 0;
-
-    /**
-     * Defines a solicited publish session - a publish session which is silent, waiting for a
-     * matching active subscribe session - and responding to it in unicast. A
-     * solicited publish session is paired with an active subscribe session
-     * {@link SubscribeConfig#SUBSCRIBE_TYPE_ACTIVE}. Configuration is done using
-     * {@link PublishConfig.Builder#setPublishType(int)}.
-     */
-    public static final int PUBLISH_TYPE_SOLICITED = 1;
-
-    /** @hide */
-    public final byte[] mServiceName;
-
-    /** @hide */
-    public final byte[] mServiceSpecificInfo;
-
-    /** @hide */
-    public final byte[] mMatchFilter;
-
-    /** @hide */
-    public final int mPublishType;
-
-    /** @hide */
-    public final int mTtlSec;
-
-    /** @hide */
-    public final boolean mEnableTerminateNotification;
-
-    /** @hide */
-    public final boolean mEnableRanging;
-
-    /** @hide */
-    public PublishConfig(byte[] serviceName, byte[] serviceSpecificInfo, byte[] matchFilter,
-            int publishType, int ttlSec, boolean enableTerminateNotification,
-            boolean enableRanging) {
-        mServiceName = serviceName;
-        mServiceSpecificInfo = serviceSpecificInfo;
-        mMatchFilter = matchFilter;
-        mPublishType = publishType;
-        mTtlSec = ttlSec;
-        mEnableTerminateNotification = enableTerminateNotification;
-        mEnableRanging = enableRanging;
-    }
-
-    @Override
-    public String toString() {
-        return "PublishConfig [mServiceName='" + (mServiceName == null ? "<null>" : String.valueOf(
-                HexEncoding.encode(mServiceName))) + ", mServiceName.length=" + (
-                mServiceName == null ? 0 : mServiceName.length) + ", mServiceSpecificInfo='" + (
-                (mServiceSpecificInfo == null) ? "<null>" : String.valueOf(
-                        HexEncoding.encode(mServiceSpecificInfo)))
-                + ", mServiceSpecificInfo.length=" + (mServiceSpecificInfo == null ? 0
-                : mServiceSpecificInfo.length) + ", mMatchFilter="
-                + (new TlvBufferUtils.TlvIterable(0, 1, mMatchFilter)).toString()
-                + ", mMatchFilter.length=" + (mMatchFilter == null ? 0 : mMatchFilter.length)
-                + ", mPublishType=" + mPublishType + ", mTtlSec=" + mTtlSec
-                + ", mEnableTerminateNotification=" + mEnableTerminateNotification
-                + ", mEnableRanging=" + mEnableRanging + "]";
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeByteArray(mServiceName);
-        dest.writeByteArray(mServiceSpecificInfo);
-        dest.writeByteArray(mMatchFilter);
-        dest.writeInt(mPublishType);
-        dest.writeInt(mTtlSec);
-        dest.writeInt(mEnableTerminateNotification ? 1 : 0);
-        dest.writeInt(mEnableRanging ? 1 : 0);
-    }
-
-    public static final @android.annotation.NonNull Creator<PublishConfig> CREATOR = new Creator<PublishConfig>() {
-        @Override
-        public PublishConfig[] newArray(int size) {
-            return new PublishConfig[size];
-        }
-
-        @Override
-        public PublishConfig createFromParcel(Parcel in) {
-            byte[] serviceName = in.createByteArray();
-            byte[] ssi = in.createByteArray();
-            byte[] matchFilter = in.createByteArray();
-            int publishType = in.readInt();
-            int ttlSec = in.readInt();
-            boolean enableTerminateNotification = in.readInt() != 0;
-            boolean enableRanging = in.readInt() != 0;
-
-            return new PublishConfig(serviceName, ssi, matchFilter, publishType,
-                    ttlSec, enableTerminateNotification, enableRanging);
-        }
-    };
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) {
-            return true;
-        }
-
-        if (!(o instanceof PublishConfig)) {
-            return false;
-        }
-
-        PublishConfig lhs = (PublishConfig) o;
-
-        return Arrays.equals(mServiceName, lhs.mServiceName) && Arrays.equals(mServiceSpecificInfo,
-                lhs.mServiceSpecificInfo) && Arrays.equals(mMatchFilter, lhs.mMatchFilter)
-                && mPublishType == lhs.mPublishType
-                && mTtlSec == lhs.mTtlSec
-                && mEnableTerminateNotification == lhs.mEnableTerminateNotification
-                && mEnableRanging == lhs.mEnableRanging;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(Arrays.hashCode(mServiceName), Arrays.hashCode(mServiceSpecificInfo),
-                Arrays.hashCode(mMatchFilter), mPublishType, mTtlSec, mEnableTerminateNotification,
-                mEnableRanging);
-    }
-
-    /**
-     * Verifies that the contents of the PublishConfig are valid. Otherwise
-     * throws an IllegalArgumentException.
-     *
-     * @hide
-     */
-    public void assertValid(Characteristics characteristics, boolean rttSupported)
-            throws IllegalArgumentException {
-        WifiAwareUtils.validateServiceName(mServiceName);
-
-        if (!TlvBufferUtils.isValid(mMatchFilter, 0, 1)) {
-            throw new IllegalArgumentException(
-                    "Invalid txFilter configuration - LV fields do not match up to length");
-        }
-        if (mPublishType < PUBLISH_TYPE_UNSOLICITED || mPublishType > PUBLISH_TYPE_SOLICITED) {
-            throw new IllegalArgumentException("Invalid publishType - " + mPublishType);
-        }
-        if (mTtlSec < 0) {
-            throw new IllegalArgumentException("Invalid ttlSec - must be non-negative");
-        }
-
-        if (characteristics != null) {
-            int maxServiceNameLength = characteristics.getMaxServiceNameLength();
-            if (maxServiceNameLength != 0 && mServiceName.length > maxServiceNameLength) {
-                throw new IllegalArgumentException(
-                        "Service name longer than supported by device characteristics");
-            }
-            int maxServiceSpecificInfoLength = characteristics.getMaxServiceSpecificInfoLength();
-            if (maxServiceSpecificInfoLength != 0 && mServiceSpecificInfo != null
-                    && mServiceSpecificInfo.length > maxServiceSpecificInfoLength) {
-                throw new IllegalArgumentException(
-                        "Service specific info longer than supported by device characteristics");
-            }
-            int maxMatchFilterLength = characteristics.getMaxMatchFilterLength();
-            if (maxMatchFilterLength != 0 && mMatchFilter != null
-                    && mMatchFilter.length > maxMatchFilterLength) {
-                throw new IllegalArgumentException(
-                        "Match filter longer than supported by device characteristics");
-            }
-        }
-
-        if (!rttSupported && mEnableRanging) {
-            throw new IllegalArgumentException("Ranging is not supported");
-        }
-    }
-
-    /**
-     * Builder used to build {@link PublishConfig} objects.
-     */
-    public static final class Builder {
-        private byte[] mServiceName;
-        private byte[] mServiceSpecificInfo;
-        private byte[] mMatchFilter;
-        private int mPublishType = PUBLISH_TYPE_UNSOLICITED;
-        private int mTtlSec = 0;
-        private boolean mEnableTerminateNotification = true;
-        private boolean mEnableRanging = false;
-
-        /**
-         * Specify the service name of the publish session. The actual on-air
-         * value is a 6 byte hashed representation of this string.
-         * <p>
-         * The Service Name is a UTF-8 encoded string from 1 to 255 bytes in length.
-         * The only acceptable single-byte UTF-8 symbols for a Service Name are alphanumeric
-         * values (A-Z, a-z, 0-9), the hyphen ('-'), and the period ('.'). All valid multi-byte
-         * UTF-8 characters are acceptable in a Service Name.
-         * <p>
-         * Must be called - an empty ServiceName is not valid.
-         *
-         * @param serviceName The service name for the publish session.
-         *
-         * @return The builder to facilitate chaining
-         *         {@code builder.setXXX(..).setXXX(..)}.
-         */
-        public Builder setServiceName(@NonNull String serviceName) {
-            if (serviceName == null) {
-                throw new IllegalArgumentException("Invalid service name - must be non-null");
-            }
-            mServiceName = serviceName.getBytes(StandardCharsets.UTF_8);
-            return this;
-        }
-
-        /**
-         * Specify service specific information for the publish session. This is
-         * a free-form byte array available to the application to send
-         * additional information as part of the discovery operation - it
-         * will not be used to determine whether a publish/subscribe match
-         * occurs.
-         * <p>
-         *     Optional. Empty by default.
-         *
-         * @param serviceSpecificInfo A byte-array for the service-specific
-         *            information field.
-         *
-         * @return The builder to facilitate chaining
-         *         {@code builder.setXXX(..).setXXX(..)}.
-         */
-        public Builder setServiceSpecificInfo(@Nullable byte[] serviceSpecificInfo) {
-            mServiceSpecificInfo = serviceSpecificInfo;
-            return this;
-        }
-
-        /**
-         * The match filter for a publish session. Used to determine whether a service
-         * discovery occurred - in addition to relying on the service name.
-         * <p>
-         *     Optional. Empty by default.
-         *
-         * @param matchFilter A list of match filter entries (each of which is an arbitrary byte
-         *                    array).
-         *
-         * @return The builder to facilitate chaining
-         *         {@code builder.setXXX(..).setXXX(..)}.
-         */
-        public Builder setMatchFilter(@Nullable List<byte[]> matchFilter) {
-            mMatchFilter = new TlvBufferUtils.TlvConstructor(0, 1).allocateAndPut(
-                    matchFilter).getArray();
-            return this;
-        }
-
-        /**
-         * Specify the type of the publish session: solicited (aka active - publish
-         * packets are transmitted over-the-air), or unsolicited (aka passive -
-         * no publish packets are transmitted, a match is made against an active
-         * subscribe session whose packets are transmitted over-the-air).
-         *
-         * @param publishType Publish session type:
-         *            {@link PublishConfig#PUBLISH_TYPE_SOLICITED} or
-         *            {@link PublishConfig#PUBLISH_TYPE_UNSOLICITED} (the default).
-         *
-         * @return The builder to facilitate chaining
-         *         {@code builder.setXXX(..).setXXX(..)}.
-         */
-        public Builder setPublishType(@PublishTypes int publishType) {
-            if (publishType < PUBLISH_TYPE_UNSOLICITED || publishType > PUBLISH_TYPE_SOLICITED) {
-                throw new IllegalArgumentException("Invalid publishType - " + publishType);
-            }
-            mPublishType = publishType;
-            return this;
-        }
-
-        /**
-         * Sets the time interval (in seconds) an unsolicited (
-         * {@link PublishConfig.Builder#setPublishType(int)}) publish session
-         * will be alive - broadcasting a packet. When the TTL is reached
-         * an event will be generated for
-         * {@link DiscoverySessionCallback#onSessionTerminated()} [unless
-         * {@link #setTerminateNotificationEnabled(boolean)} disables the callback].
-         * <p>
-         *     Optional. 0 by default - indicating the session doesn't terminate on its own.
-         *     Session will be terminated when {@link DiscoverySession#close()} is
-         *     called.
-         *
-         * @param ttlSec Lifetime of a publish session in seconds.
-         *
-         * @return The builder to facilitate chaining
-         *         {@code builder.setXXX(..).setXXX(..)}.
-         */
-        public Builder setTtlSec(int ttlSec) {
-            if (ttlSec < 0) {
-                throw new IllegalArgumentException("Invalid ttlSec - must be non-negative");
-            }
-            mTtlSec = ttlSec;
-            return this;
-        }
-
-        /**
-         * Configure whether a publish terminate notification
-         * {@link DiscoverySessionCallback#onSessionTerminated()} is reported
-         * back to the callback.
-         *
-         * @param enable If true the terminate callback will be called when the
-         *            publish is terminated. Otherwise it will not be called.
-         *
-         * @return The builder to facilitate chaining
-         *         {@code builder.setXXX(..).setXXX(..)}.
-         */
-        public Builder setTerminateNotificationEnabled(boolean enable) {
-            mEnableTerminateNotification = enable;
-            return this;
-        }
-
-        /**
-         * Configure whether the publish discovery session supports ranging and allows peers to
-         * measure distance to it. This API is used in conjunction with
-         * {@link SubscribeConfig.Builder#setMinDistanceMm(int)} and
-         * {@link SubscribeConfig.Builder#setMaxDistanceMm(int)} to specify a minimum and/or
-         * maximum distance at which discovery will be triggered.
-         * <p>
-         * Optional. Disabled by default - i.e. any peer attempt to measure distance to this device
-         * will be refused and discovery will proceed without ranging constraints.
-         * <p>
-         * The device must support Wi-Fi RTT for this feature to be used. Feature support is checked
-         * as described in {@link android.net.wifi.rtt}.
-         *
-         * @param enable If true, ranging is supported on request of the peer.
-         *
-         * @return The builder to facilitate chaining
-         *         {@code builder.setXXX(..).setXXX(..)}.
-         */
-        public Builder setRangingEnabled(boolean enable) {
-            mEnableRanging = enable;
-            return this;
-        }
-
-        /**
-         * Build {@link PublishConfig} given the current requests made on the
-         * builder.
-         */
-        public PublishConfig build() {
-            return new PublishConfig(mServiceName, mServiceSpecificInfo, mMatchFilter, mPublishType,
-                    mTtlSec, mEnableTerminateNotification, mEnableRanging);
-        }
-    }
-}
diff --git a/wifi/java/android/net/wifi/aware/PublishDiscoverySession.java b/wifi/java/android/net/wifi/aware/PublishDiscoverySession.java
deleted file mode 100644
index 1c99c87..0000000
--- a/wifi/java/android/net/wifi/aware/PublishDiscoverySession.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.aware;
-
-import android.annotation.NonNull;
-import android.util.Log;
-
-/**
- * A class representing a Aware publish session. Created when
- * {@link WifiAwareSession#publish(PublishConfig, DiscoverySessionCallback,
- * android.os.Handler)} is called and a discovery session is created and returned in
- * {@link DiscoverySessionCallback#onPublishStarted(PublishDiscoverySession)}. See
- * baseline functionality of all discovery sessions in {@link DiscoverySession}. This
- * object allows updating an existing/running publish discovery session using
- * {@link #updatePublish(PublishConfig)}.
- */
-public class PublishDiscoverySession extends DiscoverySession {
-    private static final String TAG = "PublishDiscoverySession";
-
-    /** @hide */
-    public PublishDiscoverySession(WifiAwareManager manager, int clientId, int sessionId) {
-        super(manager, clientId, sessionId);
-    }
-
-    /**
-     * Re-configure the currently active publish session. The
-     * {@link DiscoverySessionCallback} is not replaced - the same listener used
-     * at creation is still used. The results of the configuration are returned using
-     * {@link DiscoverySessionCallback}:
-     * <ul>
-     *     <li>{@link DiscoverySessionCallback#onSessionConfigUpdated()}: configuration
-     *     update succeeded.
-     *     <li>{@link DiscoverySessionCallback#onSessionConfigFailed()}: configuration
-     *     update failed. The publish discovery session is still running using its previous
-     *     configuration (i.e. update failure does not terminate the session).
-     * </ul>
-     *
-     * @param publishConfig The new discovery publish session configuration ({@link PublishConfig}).
-     */
-    public void updatePublish(@NonNull PublishConfig publishConfig) {
-        if (mTerminated) {
-            Log.w(TAG, "updatePublish: called on terminated session");
-            return;
-        } else {
-            WifiAwareManager mgr = mMgr.get();
-            if (mgr == null) {
-                Log.w(TAG, "updatePublish: called post GC on WifiAwareManager");
-                return;
-            }
-
-            mgr.updatePublish(mClientId, mSessionId, publishConfig);
-        }
-    }
-}
diff --git a/wifi/java/android/net/wifi/aware/SubscribeConfig.java b/wifi/java/android/net/wifi/aware/SubscribeConfig.java
deleted file mode 100644
index 76780f4..0000000
--- a/wifi/java/android/net/wifi/aware/SubscribeConfig.java
+++ /dev/null
@@ -1,497 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.aware;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.wifi.util.HexEncoding;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * Defines the configuration of a Aware subscribe session. Built using
- * {@link SubscribeConfig.Builder}. Subscribe is done using
- * {@link WifiAwareSession#subscribe(SubscribeConfig, DiscoverySessionCallback,
- * android.os.Handler)} or
- * {@link SubscribeDiscoverySession#updateSubscribe(SubscribeConfig)}.
- */
-public final class SubscribeConfig implements Parcelable {
-    /** @hide */
-    @IntDef({
-            SUBSCRIBE_TYPE_PASSIVE, SUBSCRIBE_TYPE_ACTIVE })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface SubscribeTypes {
-    }
-
-    /**
-     * Defines a passive subscribe session - a subscribe session where
-     * subscribe packets are not transmitted over-the-air and the device listens
-     * and matches to transmitted publish packets. Configuration is done using
-     * {@link SubscribeConfig.Builder#setSubscribeType(int)}.
-     */
-    public static final int SUBSCRIBE_TYPE_PASSIVE = 0;
-
-    /**
-     * Defines an active subscribe session - a subscribe session where
-     * subscribe packets are transmitted over-the-air. Configuration is done
-     * using {@link SubscribeConfig.Builder#setSubscribeType(int)}.
-     */
-    public static final int SUBSCRIBE_TYPE_ACTIVE = 1;
-
-    /** @hide */
-    public final byte[] mServiceName;
-
-    /** @hide */
-    public final byte[] mServiceSpecificInfo;
-
-    /** @hide */
-    public final byte[] mMatchFilter;
-
-    /** @hide */
-    public final int mSubscribeType;
-
-    /** @hide */
-    public final int mTtlSec;
-
-    /** @hide */
-    public final boolean mEnableTerminateNotification;
-
-    /** @hide */
-    public final boolean mMinDistanceMmSet;
-
-    /** @hide */
-    public final int mMinDistanceMm;
-
-    /** @hide */
-    public final boolean mMaxDistanceMmSet;
-
-    /** @hide */
-    public final int mMaxDistanceMm;
-
-    /** @hide */
-    public SubscribeConfig(byte[] serviceName, byte[] serviceSpecificInfo, byte[] matchFilter,
-            int subscribeType, int ttlSec, boolean enableTerminateNotification,
-            boolean minDistanceMmSet, int minDistanceMm, boolean maxDistanceMmSet,
-            int maxDistanceMm) {
-        mServiceName = serviceName;
-        mServiceSpecificInfo = serviceSpecificInfo;
-        mMatchFilter = matchFilter;
-        mSubscribeType = subscribeType;
-        mTtlSec = ttlSec;
-        mEnableTerminateNotification = enableTerminateNotification;
-        mMinDistanceMm = minDistanceMm;
-        mMinDistanceMmSet = minDistanceMmSet;
-        mMaxDistanceMm = maxDistanceMm;
-        mMaxDistanceMmSet = maxDistanceMmSet;
-    }
-
-    @Override
-    public String toString() {
-        return "SubscribeConfig [mServiceName='" + (mServiceName == null ? "<null>"
-                : String.valueOf(HexEncoding.encode(mServiceName))) + ", mServiceName.length=" + (
-                mServiceName == null ? 0 : mServiceName.length) + ", mServiceSpecificInfo='" + (
-                (mServiceSpecificInfo == null) ? "<null>" : String.valueOf(
-                        HexEncoding.encode(mServiceSpecificInfo)))
-                + ", mServiceSpecificInfo.length=" + (mServiceSpecificInfo == null ? 0
-                : mServiceSpecificInfo.length) + ", mMatchFilter="
-                + (new TlvBufferUtils.TlvIterable(0, 1, mMatchFilter)).toString()
-                + ", mMatchFilter.length=" + (mMatchFilter == null ? 0 : mMatchFilter.length)
-                + ", mSubscribeType=" + mSubscribeType + ", mTtlSec=" + mTtlSec
-                + ", mEnableTerminateNotification=" + mEnableTerminateNotification
-                + ", mMinDistanceMm=" + mMinDistanceMm
-                + ", mMinDistanceMmSet=" + mMinDistanceMmSet
-                + ", mMaxDistanceMm=" + mMaxDistanceMm
-                + ", mMaxDistanceMmSet=" + mMaxDistanceMmSet + "]";
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeByteArray(mServiceName);
-        dest.writeByteArray(mServiceSpecificInfo);
-        dest.writeByteArray(mMatchFilter);
-        dest.writeInt(mSubscribeType);
-        dest.writeInt(mTtlSec);
-        dest.writeInt(mEnableTerminateNotification ? 1 : 0);
-        dest.writeInt(mMinDistanceMm);
-        dest.writeInt(mMinDistanceMmSet ? 1 : 0);
-        dest.writeInt(mMaxDistanceMm);
-        dest.writeInt(mMaxDistanceMmSet ? 1 : 0);
-    }
-
-    public static final @android.annotation.NonNull Creator<SubscribeConfig> CREATOR = new Creator<SubscribeConfig>() {
-        @Override
-        public SubscribeConfig[] newArray(int size) {
-            return new SubscribeConfig[size];
-        }
-
-        @Override
-        public SubscribeConfig createFromParcel(Parcel in) {
-            byte[] serviceName = in.createByteArray();
-            byte[] ssi = in.createByteArray();
-            byte[] matchFilter = in.createByteArray();
-            int subscribeType = in.readInt();
-            int ttlSec = in.readInt();
-            boolean enableTerminateNotification = in.readInt() != 0;
-            int minDistanceMm = in.readInt();
-            boolean minDistanceMmSet = in.readInt() != 0;
-            int maxDistanceMm = in.readInt();
-            boolean maxDistanceMmSet = in.readInt() != 0;
-
-            return new SubscribeConfig(serviceName, ssi, matchFilter, subscribeType, ttlSec,
-                    enableTerminateNotification, minDistanceMmSet, minDistanceMm, maxDistanceMmSet,
-                    maxDistanceMm);
-        }
-    };
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) {
-            return true;
-        }
-
-        if (!(o instanceof SubscribeConfig)) {
-            return false;
-        }
-
-        SubscribeConfig lhs = (SubscribeConfig) o;
-
-        if (!(Arrays.equals(mServiceName, lhs.mServiceName) && Arrays.equals(
-                mServiceSpecificInfo, lhs.mServiceSpecificInfo) && Arrays.equals(mMatchFilter,
-                lhs.mMatchFilter) && mSubscribeType == lhs.mSubscribeType && mTtlSec == lhs.mTtlSec
-                && mEnableTerminateNotification == lhs.mEnableTerminateNotification
-                && mMinDistanceMmSet == lhs.mMinDistanceMmSet
-                && mMaxDistanceMmSet == lhs.mMaxDistanceMmSet)) {
-            return false;
-        }
-
-        if (mMinDistanceMmSet && mMinDistanceMm != lhs.mMinDistanceMm) {
-            return false;
-        }
-
-        if (mMaxDistanceMmSet && mMaxDistanceMm != lhs.mMaxDistanceMm) {
-            return false;
-        }
-
-        return true;
-    }
-
-    @Override
-    public int hashCode() {
-        int result = Objects.hash(Arrays.hashCode(mServiceName),
-                Arrays.hashCode(mServiceSpecificInfo), Arrays.hashCode(mMatchFilter),
-                mSubscribeType, mTtlSec, mEnableTerminateNotification, mMinDistanceMmSet,
-                mMaxDistanceMmSet);
-
-        if (mMinDistanceMmSet) {
-            result = Objects.hash(result, mMinDistanceMm);
-        }
-        if (mMaxDistanceMmSet) {
-            result = Objects.hash(result, mMaxDistanceMm);
-        }
-
-        return result;
-    }
-
-    /**
-     * Verifies that the contents of the SubscribeConfig are valid. Otherwise
-     * throws an IllegalArgumentException.
-     *
-     * @hide
-     */
-    public void assertValid(Characteristics characteristics, boolean rttSupported)
-            throws IllegalArgumentException {
-        WifiAwareUtils.validateServiceName(mServiceName);
-
-        if (!TlvBufferUtils.isValid(mMatchFilter, 0, 1)) {
-            throw new IllegalArgumentException(
-                    "Invalid matchFilter configuration - LV fields do not match up to length");
-        }
-        if (mSubscribeType < SUBSCRIBE_TYPE_PASSIVE || mSubscribeType > SUBSCRIBE_TYPE_ACTIVE) {
-            throw new IllegalArgumentException("Invalid subscribeType - " + mSubscribeType);
-        }
-        if (mTtlSec < 0) {
-            throw new IllegalArgumentException("Invalid ttlSec - must be non-negative");
-        }
-
-        if (characteristics != null) {
-            int maxServiceNameLength = characteristics.getMaxServiceNameLength();
-            if (maxServiceNameLength != 0 && mServiceName.length > maxServiceNameLength) {
-                throw new IllegalArgumentException(
-                        "Service name longer than supported by device characteristics");
-            }
-            int maxServiceSpecificInfoLength = characteristics.getMaxServiceSpecificInfoLength();
-            if (maxServiceSpecificInfoLength != 0 && mServiceSpecificInfo != null
-                    && mServiceSpecificInfo.length > maxServiceSpecificInfoLength) {
-                throw new IllegalArgumentException(
-                        "Service specific info longer than supported by device characteristics");
-            }
-            int maxMatchFilterLength = characteristics.getMaxMatchFilterLength();
-            if (maxMatchFilterLength != 0 && mMatchFilter != null
-                    && mMatchFilter.length > maxMatchFilterLength) {
-                throw new IllegalArgumentException(
-                        "Match filter longer than supported by device characteristics");
-            }
-        }
-
-        if (mMinDistanceMmSet && mMinDistanceMm < 0) {
-            throw new IllegalArgumentException("Minimum distance must be non-negative");
-        }
-        if (mMaxDistanceMmSet && mMaxDistanceMm < 0) {
-            throw new IllegalArgumentException("Maximum distance must be non-negative");
-        }
-        if (mMinDistanceMmSet && mMaxDistanceMmSet && mMaxDistanceMm <= mMinDistanceMm) {
-            throw new IllegalArgumentException(
-                    "Maximum distance must be greater than minimum distance");
-        }
-
-        if (!rttSupported && (mMinDistanceMmSet || mMaxDistanceMmSet)) {
-            throw new IllegalArgumentException("Ranging is not supported");
-        }
-    }
-
-    /**
-     * Builder used to build {@link SubscribeConfig} objects.
-     */
-    public static final class Builder {
-        private byte[] mServiceName;
-        private byte[] mServiceSpecificInfo;
-        private byte[] mMatchFilter;
-        private int mSubscribeType = SUBSCRIBE_TYPE_PASSIVE;
-        private int mTtlSec = 0;
-        private boolean mEnableTerminateNotification = true;
-        private boolean mMinDistanceMmSet = false;
-        private int mMinDistanceMm;
-        private boolean mMaxDistanceMmSet = false;
-        private int mMaxDistanceMm;
-
-        /**
-         * Specify the service name of the subscribe session. The actual on-air
-         * value is a 6 byte hashed representation of this string.
-         * <p>
-         * The Service Name is a UTF-8 encoded string from 1 to 255 bytes in length.
-         * The only acceptable single-byte UTF-8 symbols for a Service Name are alphanumeric
-         * values (A-Z, a-z, 0-9), the hyphen ('-'), and the period ('.'). All valid multi-byte
-         * UTF-8 characters are acceptable in a Service Name.
-         * <p>
-         * Must be called - an empty ServiceName is not valid.
-         *
-         * @param serviceName The service name for the subscribe session.
-         *
-         * @return The builder to facilitate chaining
-         *         {@code builder.setXXX(..).setXXX(..)}.
-         */
-        public Builder setServiceName(@NonNull String serviceName) {
-            if (serviceName == null) {
-                throw new IllegalArgumentException("Invalid service name - must be non-null");
-            }
-            mServiceName = serviceName.getBytes(StandardCharsets.UTF_8);
-            return this;
-        }
-
-        /**
-         * Specify service specific information for the subscribe session. This is
-         * a free-form byte array available to the application to send
-         * additional information as part of the discovery operation - i.e. it
-         * will not be used to determine whether a publish/subscribe match
-         * occurs.
-         * <p>
-         *     Optional. Empty by default.
-         *
-         * @param serviceSpecificInfo A byte-array for the service-specific
-         *            information field.
-         *
-         * @return The builder to facilitate chaining
-         *         {@code builder.setXXX(..).setXXX(..)}.
-         */
-        public Builder setServiceSpecificInfo(@Nullable byte[] serviceSpecificInfo) {
-            mServiceSpecificInfo = serviceSpecificInfo;
-            return this;
-        }
-
-        /**
-         * The match filter for a subscribe session. Used to determine whether a service
-         * discovery occurred - in addition to relying on the service name.
-         * <p>
-         *     Optional. Empty by default.
-         *
-         * @param matchFilter A list of match filter entries (each of which is an arbitrary byte
-         *                    array).
-         *
-         * @return The builder to facilitate chaining
-         *         {@code builder.setXXX(..).setXXX(..)}.
-         */
-        public Builder setMatchFilter(@Nullable List<byte[]> matchFilter) {
-            mMatchFilter = new TlvBufferUtils.TlvConstructor(0, 1).allocateAndPut(
-                    matchFilter).getArray();
-            return this;
-        }
-
-        /**
-         * Sets the type of the subscribe session: active (subscribe packets are
-         * transmitted over-the-air), or passive (no subscribe packets are
-         * transmitted, a match is made against a solicited/active publish
-         * session whose packets are transmitted over-the-air).
-         *
-         * @param subscribeType Subscribe session type:
-         *            {@link SubscribeConfig#SUBSCRIBE_TYPE_ACTIVE} or
-         *            {@link SubscribeConfig#SUBSCRIBE_TYPE_PASSIVE}.
-         *
-         * @return The builder to facilitate chaining
-         *         {@code builder.setXXX(..).setXXX(..)}.
-         */
-        public Builder setSubscribeType(@SubscribeTypes int subscribeType) {
-            if (subscribeType < SUBSCRIBE_TYPE_PASSIVE || subscribeType > SUBSCRIBE_TYPE_ACTIVE) {
-                throw new IllegalArgumentException("Invalid subscribeType - " + subscribeType);
-            }
-            mSubscribeType = subscribeType;
-            return this;
-        }
-
-        /**
-         * Sets the time interval (in seconds) an active (
-         * {@link SubscribeConfig.Builder#setSubscribeType(int)}) subscribe session
-         * will be alive - i.e. broadcasting a packet. When the TTL is reached
-         * an event will be generated for
-         * {@link DiscoverySessionCallback#onSessionTerminated()}.
-         * <p>
-         *     Optional. 0 by default - indicating the session doesn't terminate on its own.
-         *     Session will be terminated when {@link DiscoverySession#close()} is
-         *     called.
-         *
-         * @param ttlSec Lifetime of a subscribe session in seconds.
-         *
-         * @return The builder to facilitate chaining
-         *         {@code builder.setXXX(..).setXXX(..)}.
-         */
-        public Builder setTtlSec(int ttlSec) {
-            if (ttlSec < 0) {
-                throw new IllegalArgumentException("Invalid ttlSec - must be non-negative");
-            }
-            mTtlSec = ttlSec;
-            return this;
-        }
-
-        /**
-         * Configure whether a subscribe terminate notification
-         * {@link DiscoverySessionCallback#onSessionTerminated()} is reported
-         * back to the callback.
-         *
-         * @param enable If true the terminate callback will be called when the
-         *            subscribe is terminated. Otherwise it will not be called.
-         *
-         * @return The builder to facilitate chaining
-         *         {@code builder.setXXX(..).setXXX(..)}.
-         */
-        public Builder setTerminateNotificationEnabled(boolean enable) {
-            mEnableTerminateNotification = enable;
-            return this;
-        }
-
-        /**
-         * Configure the minimum distance to a discovered publisher at which to trigger a discovery
-         * notification. I.e. discovery will be triggered if we've found a matching publisher
-         * (based on the other criteria in this configuration) <b>and</b> the distance to the
-         * publisher is larger than the value specified in this API. Can be used in conjunction with
-         * {@link #setMaxDistanceMm(int)} to specify a geofence, i.e. discovery with min <=
-         * distance <= max.
-         * <p>
-         * For ranging to be used in discovery it must also be enabled on the publisher using
-         * {@link PublishConfig.Builder#setRangingEnabled(boolean)}. However, ranging may
-         * not be available or enabled on the publisher or may be temporarily disabled on either
-         * subscriber or publisher - in such cases discovery will proceed without ranging.
-         * <p>
-         * When ranging is enabled and available on both publisher and subscriber and a service
-         * is discovered based on geofence constraints the
-         * {@link DiscoverySessionCallback#onServiceDiscoveredWithinRange(PeerHandle, byte[], List, int)}
-         * is called, otherwise the
-         * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle, byte[], List)}
-         * is called.
-         * <p>
-         * The device must support Wi-Fi RTT for this feature to be used. Feature support is checked
-         * as described in {@link android.net.wifi.rtt}.
-         *
-         * @param minDistanceMm Minimum distance, in mm, to the publisher above which to trigger
-         *                      discovery.
-         *
-         * @return The builder to facilitate chaining
-         *         {@code builder.setXXX(..).setXXX(..)}.
-         */
-        public Builder setMinDistanceMm(int minDistanceMm) {
-            mMinDistanceMm = minDistanceMm;
-            mMinDistanceMmSet = true;
-            return this;
-        }
-
-        /**
-         * Configure the maximum distance to a discovered publisher at which to trigger a discovery
-         * notification. I.e. discovery will be triggered if we've found a matching publisher
-         * (based on the other criteria in this configuration) <b>and</b> the distance to the
-         * publisher is smaller than the value specified in this API. Can be used in conjunction
-         * with {@link #setMinDistanceMm(int)} to specify a geofence, i.e. discovery with min <=
-         * distance <= max.
-         * <p>
-         * For ranging to be used in discovery it must also be enabled on the publisher using
-         * {@link PublishConfig.Builder#setRangingEnabled(boolean)}. However, ranging may
-         * not be available or enabled on the publisher or may be temporarily disabled on either
-         * subscriber or publisher - in such cases discovery will proceed without ranging.
-         * <p>
-         * When ranging is enabled and available on both publisher and subscriber and a service
-         * is discovered based on geofence constraints the
-         * {@link DiscoverySessionCallback#onServiceDiscoveredWithinRange(PeerHandle, byte[], List, int)}
-         * is called, otherwise the
-         * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle, byte[], List)}
-         * is called.
-         * <p>
-         * The device must support Wi-Fi RTT for this feature to be used. Feature support is checked
-         * as described in {@link android.net.wifi.rtt}.
-         *
-         * @param maxDistanceMm Maximum distance, in mm, to the publisher below which to trigger
-         *                      discovery.
-         *
-         * @return The builder to facilitate chaining
-         *         {@code builder.setXXX(..).setXXX(..)}.
-         */
-        public Builder setMaxDistanceMm(int maxDistanceMm) {
-            mMaxDistanceMm = maxDistanceMm;
-            mMaxDistanceMmSet = true;
-            return this;
-        }
-
-        /**
-         * Build {@link SubscribeConfig} given the current requests made on the
-         * builder.
-         */
-        public SubscribeConfig build() {
-            return new SubscribeConfig(mServiceName, mServiceSpecificInfo, mMatchFilter,
-                    mSubscribeType, mTtlSec, mEnableTerminateNotification,
-                    mMinDistanceMmSet, mMinDistanceMm, mMaxDistanceMmSet, mMaxDistanceMm);
-        }
-    }
-}
diff --git a/wifi/java/android/net/wifi/aware/SubscribeDiscoverySession.java b/wifi/java/android/net/wifi/aware/SubscribeDiscoverySession.java
deleted file mode 100644
index ca88a90..0000000
--- a/wifi/java/android/net/wifi/aware/SubscribeDiscoverySession.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.aware;
-
-import android.annotation.NonNull;
-import android.util.Log;
-
-/**
- * A class representing a Aware subscribe session. Created when
- * {@link WifiAwareSession#subscribe(SubscribeConfig,
- * DiscoverySessionCallback, android.os.Handler)}
- * is called and a discovery session is created and returned in
- * {@link DiscoverySessionCallback#onSubscribeStarted(SubscribeDiscoverySession)}.
- * See baseline functionality of all discovery sessions in {@link DiscoverySession}.
- * This object allows updating an existing/running subscribe discovery session using
- * {@link #updateSubscribe(SubscribeConfig)}.
- */
-public class SubscribeDiscoverySession extends DiscoverySession {
-    private static final String TAG = "SubscribeDiscSession";
-
-    /**
-     * {@hide}
-     */
-    public SubscribeDiscoverySession(WifiAwareManager manager, int clientId,
-            int sessionId) {
-        super(manager, clientId, sessionId);
-    }
-
-    /**
-     * Re-configure the currently active subscribe session. The
-     * {@link DiscoverySessionCallback} is not replaced - the same listener used
-     * at creation is still used. The results of the configuration are returned using
-     * {@link DiscoverySessionCallback}:
-     * <ul>
-     *     <li>{@link DiscoverySessionCallback#onSessionConfigUpdated()}: configuration
-     *     update succeeded.
-     *     <li>{@link DiscoverySessionCallback#onSessionConfigFailed()}: configuration
-     *     update failed. The subscribe discovery session is still running using its previous
-     *     configuration (i.e. update failure does not terminate the session).
-     * </ul>
-     *
-     * @param subscribeConfig The new discovery subscribe session configuration
-     *                        ({@link SubscribeConfig}).
-     */
-    public void updateSubscribe(@NonNull SubscribeConfig subscribeConfig) {
-        if (mTerminated) {
-            Log.w(TAG, "updateSubscribe: called on terminated session");
-            return;
-        } else {
-            WifiAwareManager mgr = mMgr.get();
-            if (mgr == null) {
-                Log.w(TAG, "updateSubscribe: called post GC on WifiAwareManager");
-                return;
-            }
-
-            mgr.updateSubscribe(mClientId, mSessionId, subscribeConfig);
-        }
-    }
-}
diff --git a/wifi/java/android/net/wifi/aware/TlvBufferUtils.java b/wifi/java/android/net/wifi/aware/TlvBufferUtils.java
deleted file mode 100644
index 2d3cc1e..0000000
--- a/wifi/java/android/net/wifi/aware/TlvBufferUtils.java
+++ /dev/null
@@ -1,714 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.aware;
-
-import android.annotation.Nullable;
-
-import java.nio.BufferOverflowException;
-import java.nio.ByteOrder;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-import java.util.NoSuchElementException;
-
-/**
- * Utility class to construct and parse byte arrays using the TLV format -
- * Type/Length/Value format. The utilities accept a configuration of the size of
- * the Type field and the Length field. A Type field size of 0 is allowed -
- * allowing usage for LV (no T) array formats.
- *
- * @hide
- */
-public class TlvBufferUtils {
-    private TlvBufferUtils() {
-        // no reason to ever create this class
-    }
-
-    /**
-     * Utility class to construct byte arrays using the TLV format -
-     * Type/Length/Value.
-     * <p>
-     * A constructor is created specifying the size of the Type (T) and Length
-     * (L) fields. A specification of zero size T field is allowed - resulting
-     * in LV type format.
-     * <p>
-     * The byte array is either provided (using
-     * {@link TlvConstructor#wrap(byte[])}) or allocated (using
-     * {@link TlvConstructor#allocate(int)}).
-     * <p>
-     * Values are added to the structure using the {@code TlvConstructor.put*()}
-     * methods.
-     * <p>
-     * The final byte array is obtained using {@link TlvConstructor#getArray()}.
-     */
-    public static class TlvConstructor {
-        private int mTypeSize;
-        private int mLengthSize;
-        private ByteOrder mByteOrder = ByteOrder.BIG_ENDIAN;
-
-        private byte[] mArray;
-        private int mArrayLength;
-        private int mPosition;
-
-        /**
-         * Define a TLV constructor with the specified size of the Type (T) and
-         * Length (L) fields.
-         *
-         * @param typeSize Number of bytes used for the Type (T) field. Values
-         *            of 0, 1, or 2 bytes are allowed. A specification of 0
-         *            bytes implies that the field being constructed has the LV
-         *            format rather than the TLV format.
-         * @param lengthSize Number of bytes used for the Length (L) field.
-         *            Values of 1 or 2 bytes are allowed.
-         */
-        public TlvConstructor(int typeSize, int lengthSize) {
-            if (typeSize < 0 || typeSize > 2 || lengthSize <= 0 || lengthSize > 2) {
-                throw new IllegalArgumentException(
-                        "Invalid sizes - typeSize=" + typeSize + ", lengthSize=" + lengthSize);
-            }
-            mTypeSize = typeSize;
-            mLengthSize = lengthSize;
-            mPosition = 0;
-        }
-
-        /**
-         * Configure the TLV constructor to use a particular byte order. Should be
-         * {@link ByteOrder#BIG_ENDIAN} (the default at construction) or
-         * {@link ByteOrder#LITTLE_ENDIAN}.
-         *
-         * @return The constructor to facilitate chaining
-         *         {@code ctr.putXXX(..).putXXX(..)}.
-         */
-        public TlvConstructor setByteOrder(ByteOrder byteOrder) {
-            mByteOrder = byteOrder;
-            return this;
-        }
-
-        /**
-         * Set the byte array to be used to construct the TLV.
-         *
-         * @param array Byte array to be formatted.
-         * @return The constructor to facilitate chaining
-         *         {@code ctr.putXXX(..).putXXX(..)}.
-         */
-        public TlvConstructor wrap(@Nullable byte[] array) {
-            mArray = array;
-            mArrayLength = (array == null) ? 0 : array.length;
-            mPosition = 0;
-            return this;
-        }
-
-        /**
-         * Allocates a new byte array to be used ot construct a TLV.
-         *
-         * @param capacity The size of the byte array to be allocated.
-         * @return The constructor to facilitate chaining
-         *         {@code ctr.putXXX(..).putXXX(..)}.
-         */
-        public TlvConstructor allocate(int capacity) {
-            mArray = new byte[capacity];
-            mArrayLength = capacity;
-            mPosition = 0;
-            return this;
-        }
-
-        /**
-         * Creates a TLV array (of the previously specified Type and Length sizes) from the input
-         * list. Allocates an array matching the contents (and required Type and Length
-         * fields), copies the contents, and set the Length fields. The Type field is set to 0.
-         *
-         * @param list A list of fields to be added to the TLV buffer.
-         * @return The constructor of the TLV.
-         */
-        public TlvConstructor allocateAndPut(@Nullable List<byte[]> list) {
-            if (list != null) {
-                int size = 0;
-                for (byte[] field : list) {
-                    size += mTypeSize + mLengthSize;
-                    if (field != null) {
-                        size += field.length;
-                    }
-                }
-                allocate(size);
-                for (byte[] field : list) {
-                    putByteArray(0, field);
-                }
-            }
-            return this;
-        }
-
-        /**
-         * Copies a byte into the TLV with the indicated type. For an LV
-         * formatted structure (i.e. typeLength=0 in {@link TlvConstructor
-         * TlvConstructor(int, int)} ) the type field is ignored.
-         *
-         * @param type The value to be placed into the Type field.
-         * @param b The byte to be inserted into the structure.
-         * @return The constructor to facilitate chaining
-         *         {@code ctr.putXXX(..).putXXX(..)}.
-         */
-        public TlvConstructor putByte(int type, byte b) {
-            checkLength(1);
-            addHeader(type, 1);
-            mArray[mPosition++] = b;
-            return this;
-        }
-
-        /**
-         * Copies a raw byte into the TLV buffer - without a type or a length.
-         *
-         * @param b The byte to be inserted into the structure.
-         * @return The constructor to facilitate chaining {@code cts.putXXX(..).putXXX(..)}.
-         */
-        public TlvConstructor putRawByte(byte b) {
-            checkRawLength(1);
-            mArray[mPosition++] = b;
-            return this;
-        }
-
-        /**
-         * Copies a byte array into the TLV with the indicated type. For an LV
-         * formatted structure (i.e. typeLength=0 in {@link TlvConstructor
-         * TlvConstructor(int, int)} ) the type field is ignored.
-         *
-         * @param type The value to be placed into the Type field.
-         * @param array The array to be copied into the TLV structure.
-         * @param offset Start copying from the array at the specified offset.
-         * @param length Copy the specified number (length) of bytes from the
-         *            array.
-         * @return The constructor to facilitate chaining
-         *         {@code ctr.putXXX(..).putXXX(..)}.
-         */
-        public TlvConstructor putByteArray(int type, @Nullable byte[] array, int offset,
-                int length) {
-            checkLength(length);
-            addHeader(type, length);
-            if (length != 0) {
-                System.arraycopy(array, offset, mArray, mPosition, length);
-            }
-            mPosition += length;
-            return this;
-        }
-
-        /**
-         * Copies a byte array into the TLV with the indicated type. For an LV
-         * formatted structure (i.e. typeLength=0 in {@link TlvConstructor
-         * TlvConstructor(int, int)} ) the type field is ignored.
-         *
-         * @param type The value to be placed into the Type field.
-         * @param array The array to be copied (in full) into the TLV structure.
-         * @return The constructor to facilitate chaining
-         *         {@code ctr.putXXX(..).putXXX(..)}.
-         */
-        public TlvConstructor putByteArray(int type, @Nullable byte[] array) {
-            return putByteArray(type, array, 0, (array == null) ? 0 : array.length);
-        }
-
-        /**
-         * Copies a byte array into the TLV - without a type or a length.
-         *
-         * @param array The array to be copied (in full) into the TLV structure.
-         * @return The constructor to facilitate chaining
-         *         {@code ctr.putXXX(..).putXXX(..)}.
-         */
-        public TlvConstructor putRawByteArray(@Nullable byte[] array) {
-            if (array == null) return this;
-
-            checkRawLength(array.length);
-            System.arraycopy(array, 0, mArray, mPosition, array.length);
-            mPosition += array.length;
-            return this;
-        }
-
-        /**
-         * Places a zero length element (i.e. Length field = 0) into the TLV.
-         * For an LV formatted structure (i.e. typeLength=0 in
-         * {@link TlvConstructor TlvConstructor(int, int)} ) the type field is
-         * ignored.
-         *
-         * @param type The value to be placed into the Type field.
-         * @return The constructor to facilitate chaining
-         *         {@code ctr.putXXX(..).putXXX(..)}.
-         */
-        public TlvConstructor putZeroLengthElement(int type) {
-            checkLength(0);
-            addHeader(type, 0);
-            return this;
-        }
-
-        /**
-         * Copies short into the TLV with the indicated type. For an LV
-         * formatted structure (i.e. typeLength=0 in {@link TlvConstructor
-         * TlvConstructor(int, int)} ) the type field is ignored.
-         *
-         * @param type The value to be placed into the Type field.
-         * @param data The short to be inserted into the structure.
-         * @return The constructor to facilitate chaining
-         *         {@code ctr.putXXX(..).putXXX(..)}.
-         */
-        public TlvConstructor putShort(int type, short data) {
-            checkLength(2);
-            addHeader(type, 2);
-            pokeShort(mArray, mPosition, data, mByteOrder);
-            mPosition += 2;
-            return this;
-        }
-
-        /**
-         * Copies integer into the TLV with the indicated type. For an LV
-         * formatted structure (i.e. typeLength=0 in {@link TlvConstructor
-         * TlvConstructor(int, int)} ) the type field is ignored.
-         *
-         * @param type The value to be placed into the Type field.
-         * @param data The integer to be inserted into the structure.
-         * @return The constructor to facilitate chaining
-         *         {@code ctr.putXXX(..).putXXX(..)}.
-         */
-        public TlvConstructor putInt(int type, int data) {
-            checkLength(4);
-            addHeader(type, 4);
-            pokeInt(mArray, mPosition, data, mByteOrder);
-            mPosition += 4;
-            return this;
-        }
-
-        /**
-         * Copies a String's byte representation into the TLV with the indicated
-         * type. For an LV formatted structure (i.e. typeLength=0 in
-         * {@link TlvConstructor TlvConstructor(int, int)} ) the type field is
-         * ignored.
-         *
-         * @param type The value to be placed into the Type field.
-         * @param data The string whose bytes are to be inserted into the
-         *            structure.
-         * @return The constructor to facilitate chaining
-         *         {@code ctr.putXXX(..).putXXX(..)}.
-         */
-        public TlvConstructor putString(int type, @Nullable String data) {
-            byte[] bytes = null;
-            int length = 0;
-            if (data != null) {
-                bytes = data.getBytes();
-                length = bytes.length;
-            }
-            return putByteArray(type, bytes, 0, length);
-        }
-
-        /**
-         * Returns the constructed TLV formatted byte-array. This array is a copy of the wrapped
-         * or allocated array - truncated to just the significant bytes - i.e. those written into
-         * the (T)LV.
-         *
-         * @return The byte array containing the TLV formatted structure.
-         */
-        public byte[] getArray() {
-            return Arrays.copyOf(mArray, getActualLength());
-        }
-
-        /**
-         * Returns the size of the TLV formatted portion of the wrapped or
-         * allocated byte array. The array itself is returned with
-         * {@link TlvConstructor#getArray()}.
-         *
-         * @return The size of the TLV formatted portion of the byte array.
-         */
-        private int getActualLength() {
-            return mPosition;
-        }
-
-        private void checkLength(int dataLength) {
-            if (mPosition + mTypeSize + mLengthSize + dataLength > mArrayLength) {
-                throw new BufferOverflowException();
-            }
-        }
-
-        private void checkRawLength(int dataLength) {
-            if (mPosition + dataLength > mArrayLength) {
-                throw new BufferOverflowException();
-            }
-        }
-
-        private void addHeader(int type, int length) {
-            if (mTypeSize == 1) {
-                mArray[mPosition] = (byte) type;
-            } else if (mTypeSize == 2) {
-                pokeShort(mArray, mPosition, (short) type, mByteOrder);
-            }
-            mPosition += mTypeSize;
-
-            if (mLengthSize == 1) {
-                mArray[mPosition] = (byte) length;
-            } else if (mLengthSize == 2) {
-                pokeShort(mArray, mPosition, (short) length, mByteOrder);
-            }
-            mPosition += mLengthSize;
-        }
-    }
-
-    /**
-     * Utility class used when iterating over a TLV formatted byte-array. Use
-     * {@link TlvIterable} to iterate over array. A {@link TlvElement}
-     * represents each entry in a TLV formatted byte-array.
-     */
-    public static class TlvElement {
-        /**
-         * The Type (T) field of the current TLV element. Note that for LV
-         * formatted byte-arrays (i.e. TLV whose Type/T size is 0) the value of
-         * this field is undefined.
-         */
-        public int type;
-
-        /**
-         * The Length (L) field of the current TLV element.
-         */
-        public int length;
-
-        /**
-         * Control of the endianess of the TLV element - true for big-endian, false for little-
-         * endian.
-         */
-        public ByteOrder byteOrder = ByteOrder.BIG_ENDIAN;
-
-        /**
-         * The Value (V) field - a raw byte array representing the current TLV
-         * element where the entry starts at {@link TlvElement#offset}.
-         */
-        private byte[] mRefArray;
-
-        /**
-         * The offset to be used into {@link TlvElement#mRefArray} to access the
-         * raw data representing the current TLV element.
-         */
-        public int offset;
-
-        private TlvElement(int type, int length, @Nullable byte[] refArray, int offset) {
-            this.type = type;
-            this.length = length;
-            mRefArray = refArray;
-            this.offset = offset;
-
-            if (offset + length > refArray.length) {
-                throw new BufferOverflowException();
-            }
-        }
-
-        /**
-         * Return the raw byte array of the Value (V) field.
-         *
-         * @return The Value (V) field as a byte array.
-         */
-        public byte[] getRawData() {
-            return Arrays.copyOfRange(mRefArray, offset, offset + length);
-        }
-
-        /**
-         * Utility function to return a byte representation of a TLV element of
-         * length 1. Note: an attempt to call this function on a TLV item whose
-         * {@link TlvElement#length} is != 1 will result in an exception.
-         *
-         * @return byte representation of current TLV element.
-         */
-        public byte getByte() {
-            if (length != 1) {
-                throw new IllegalArgumentException(
-                        "Accesing a byte from a TLV element of length " + length);
-            }
-            return mRefArray[offset];
-        }
-
-        /**
-         * Utility function to return a short representation of a TLV element of
-         * length 2. Note: an attempt to call this function on a TLV item whose
-         * {@link TlvElement#length} is != 2 will result in an exception.
-         *
-         * @return short representation of current TLV element.
-         */
-        public short getShort() {
-            if (length != 2) {
-                throw new IllegalArgumentException(
-                        "Accesing a short from a TLV element of length " + length);
-            }
-            return peekShort(mRefArray, offset, byteOrder);
-        }
-
-        /**
-         * Utility function to return an integer representation of a TLV element
-         * of length 4. Note: an attempt to call this function on a TLV item
-         * whose {@link TlvElement#length} is != 4 will result in an exception.
-         *
-         * @return integer representation of current TLV element.
-         */
-        public int getInt() {
-            if (length != 4) {
-                throw new IllegalArgumentException(
-                        "Accesing an int from a TLV element of length " + length);
-            }
-            return peekInt(mRefArray, offset, byteOrder);
-        }
-
-        /**
-         * Utility function to return a String representation of a TLV element.
-         *
-         * @return String repersentation of the current TLV element.
-         */
-        public String getString() {
-            return new String(mRefArray, offset, length);
-        }
-    }
-
-    /**
-     * Utility class to iterate over a TLV formatted byte-array.
-     */
-    public static class TlvIterable implements Iterable<TlvElement> {
-        private int mTypeSize;
-        private int mLengthSize;
-        private ByteOrder mByteOrder = ByteOrder.BIG_ENDIAN;
-        private byte[] mArray;
-        private int mArrayLength;
-
-        /**
-         * Constructs a TlvIterable object - specifying the format of the TLV
-         * (the sizes of the Type and Length fields), and the byte array whose
-         * data is to be parsed.
-         *
-         * @param typeSize Number of bytes used for the Type (T) field. Valid
-         *            values are 0 (i.e. indicating the format is LV rather than
-         *            TLV), 1, and 2 bytes.
-         * @param lengthSize Number of bytes used for the Length (L) field.
-         *            Values values are 1 or 2 bytes.
-         * @param array The TLV formatted byte-array to parse.
-         */
-        public TlvIterable(int typeSize, int lengthSize, @Nullable byte[] array) {
-            if (typeSize < 0 || typeSize > 2 || lengthSize <= 0 || lengthSize > 2) {
-                throw new IllegalArgumentException(
-                        "Invalid sizes - typeSize=" + typeSize + ", lengthSize=" + lengthSize);
-            }
-            mTypeSize = typeSize;
-            mLengthSize = lengthSize;
-            mArray = array;
-            mArrayLength = (array == null) ? 0 : array.length;
-        }
-
-        /**
-         * Configure the TLV iterator to use little-endian byte ordering.
-         */
-        public void setByteOrder(ByteOrder byteOrder) {
-            mByteOrder = byteOrder;
-        }
-
-        /**
-         * Prints out a parsed representation of the TLV-formatted byte array.
-         * Whenever possible bytes, shorts, and integer are printed out (for
-         * fields whose length is 1, 2, or 4 respectively).
-         */
-        @Override
-        public String toString() {
-            StringBuilder builder = new StringBuilder();
-
-            builder.append("[");
-            boolean first = true;
-            for (TlvElement tlv : this) {
-                if (!first) {
-                    builder.append(",");
-                }
-                first = false;
-                builder.append(" (");
-                if (mTypeSize != 0) {
-                    builder.append("T=" + tlv.type + ",");
-                }
-                builder.append("L=" + tlv.length + ") ");
-                if (tlv.length == 0) {
-                    builder.append("<null>");
-                } else if (tlv.length == 1) {
-                    builder.append(tlv.getByte());
-                } else if (tlv.length == 2) {
-                    builder.append(tlv.getShort());
-                } else if (tlv.length == 4) {
-                    builder.append(tlv.getInt());
-                } else {
-                    builder.append("<bytes>");
-                }
-                if (tlv.length != 0) {
-                    builder.append(" (S='" + tlv.getString() + "')");
-                }
-            }
-            builder.append("]");
-
-            return builder.toString();
-        }
-
-        /**
-         * Returns a List with the raw contents (no types) of the iterator.
-         */
-        public List<byte[]> toList() {
-            List<byte[]> list = new ArrayList<>();
-            for (TlvElement tlv : this) {
-                list.add(Arrays.copyOfRange(tlv.mRefArray, tlv.offset, tlv.offset + tlv.length));
-            }
-
-            return list;
-        }
-
-        /**
-         * Returns an iterator to step through a TLV formatted byte-array. The
-         * individual elements returned by the iterator are {@link TlvElement}.
-         */
-        @Override
-        public Iterator<TlvElement> iterator() {
-            return new Iterator<TlvElement>() {
-                private int mOffset = 0;
-
-                @Override
-                public boolean hasNext() {
-                    return mOffset < mArrayLength;
-                }
-
-                @Override
-                public TlvElement next() {
-                    if (!hasNext()) {
-                        throw new NoSuchElementException();
-                    }
-
-                    int type = 0;
-                    if (mTypeSize == 1) {
-                        type = mArray[mOffset];
-                    } else if (mTypeSize == 2) {
-                        type = peekShort(mArray, mOffset, mByteOrder);
-                    }
-                    mOffset += mTypeSize;
-
-                    int length = 0;
-                    if (mLengthSize == 1) {
-                        length = mArray[mOffset];
-                    } else if (mLengthSize == 2) {
-                        length = peekShort(mArray, mOffset, mByteOrder);
-                    }
-                    mOffset += mLengthSize;
-
-                    TlvElement tlv = new TlvElement(type, length, mArray, mOffset);
-                    tlv.byteOrder = mByteOrder;
-                    mOffset += length;
-                    return tlv;
-                }
-
-                @Override
-                public void remove() {
-                    throw new UnsupportedOperationException();
-                }
-            };
-        }
-    }
-
-    /**
-     * Validates that a (T)LV array is constructed correctly. I.e. that its specified Length
-     * fields correctly fill the specified length (and do not overshoot). Uses big-endian
-     * byte ordering.
-     *
-     * @param array The (T)LV array to verify.
-     * @param typeSize The size (in bytes) of the type field. Valid values are 0, 1, or 2.
-     * @param lengthSize The size (in bytes) of the length field. Valid values are 1 or 2.
-     * @return A boolean indicating whether the array is valid (true) or invalid (false).
-     */
-    public static boolean isValid(@Nullable byte[] array, int typeSize, int lengthSize) {
-        return isValidEndian(array, typeSize, lengthSize, ByteOrder.BIG_ENDIAN);
-    }
-
-    /**
-     * Validates that a (T)LV array is constructed correctly. I.e. that its specified Length
-     * fields correctly fill the specified length (and do not overshoot).
-     *
-     * @param array The (T)LV array to verify.
-     * @param typeSize The size (in bytes) of the type field. Valid values are 0, 1, or 2.
-     * @param lengthSize The size (in bytes) of the length field. Valid values are 1 or 2.
-     * @param byteOrder The endianness of the byte array: {@link ByteOrder#BIG_ENDIAN} or
-     *                  {@link ByteOrder#LITTLE_ENDIAN}.
-     * @return A boolean indicating whether the array is valid (true) or invalid (false).
-     */
-    public static boolean isValidEndian(@Nullable byte[] array, int typeSize, int lengthSize,
-            ByteOrder byteOrder) {
-        if (typeSize < 0 || typeSize > 2) {
-            throw new IllegalArgumentException(
-                    "Invalid arguments - typeSize must be 0, 1, or 2: typeSize=" + typeSize);
-        }
-        if (lengthSize <= 0 || lengthSize > 2) {
-            throw new IllegalArgumentException(
-                    "Invalid arguments - lengthSize must be 1 or 2: lengthSize=" + lengthSize);
-        }
-        if (array == null) {
-            return true;
-        }
-
-        int nextTlvIndex = 0;
-        while (nextTlvIndex + typeSize + lengthSize <= array.length) {
-            nextTlvIndex += typeSize;
-            if (lengthSize == 1) {
-                nextTlvIndex += lengthSize + array[nextTlvIndex];
-            } else {
-                nextTlvIndex += lengthSize + peekShort(array, nextTlvIndex, byteOrder);
-            }
-        }
-
-        return nextTlvIndex == array.length;
-    }
-
-    private static void pokeShort(byte[] dst, int offset, short value, ByteOrder order) {
-        if (order == ByteOrder.BIG_ENDIAN) {
-            dst[offset++] = (byte) ((value >> 8) & 0xff);
-            dst[offset  ] = (byte) ((value >> 0) & 0xff);
-        } else {
-            dst[offset++] = (byte) ((value >> 0) & 0xff);
-            dst[offset  ] = (byte) ((value >> 8) & 0xff);
-        }
-    }
-
-    private static void pokeInt(byte[] dst, int offset, int value, ByteOrder order) {
-        if (order == ByteOrder.BIG_ENDIAN) {
-            dst[offset++] = (byte) ((value >> 24) & 0xff);
-            dst[offset++] = (byte) ((value >> 16) & 0xff);
-            dst[offset++] = (byte) ((value >>  8) & 0xff);
-            dst[offset  ] = (byte) ((value >>  0) & 0xff);
-        } else {
-            dst[offset++] = (byte) ((value >>  0) & 0xff);
-            dst[offset++] = (byte) ((value >>  8) & 0xff);
-            dst[offset++] = (byte) ((value >> 16) & 0xff);
-            dst[offset  ] = (byte) ((value >> 24) & 0xff);
-        }
-    }
-
-    private static short peekShort(byte[] src, int offset, ByteOrder order) {
-        if (order == ByteOrder.BIG_ENDIAN) {
-            return (short) ((src[offset] << 8) | (src[offset + 1] & 0xff));
-        } else {
-            return (short) ((src[offset + 1] << 8) | (src[offset] & 0xff));
-        }
-    }
-
-    private static int peekInt(byte[] src, int offset, ByteOrder order) {
-        if (order == ByteOrder.BIG_ENDIAN) {
-            return ((src[offset++] & 0xff) << 24)
-                    | ((src[offset++] & 0xff) << 16)
-                    | ((src[offset++] & 0xff) <<  8)
-                    | ((src[offset  ] & 0xff) <<  0);
-        } else {
-            return ((src[offset++] & 0xff) <<  0)
-                    | ((src[offset++] & 0xff) <<  8)
-                    | ((src[offset++] & 0xff) << 16)
-                    | ((src[offset  ] & 0xff) << 24);
-        }
-    }
-}
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareAgentNetworkSpecifier.java b/wifi/java/android/net/wifi/aware/WifiAwareAgentNetworkSpecifier.java
deleted file mode 100644
index 9ae3bd0..0000000
--- a/wifi/java/android/net/wifi/aware/WifiAwareAgentNetworkSpecifier.java
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.aware;
-
-import android.net.NetworkSpecifier;
-import android.net.wifi.util.HexEncoding;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.Log;
-
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.StringJoiner;
-
-/**
- * A network specifier object used to represent the capabilities of an network agent. A collection
- * of multiple WifiAwareNetworkSpecifier objects whose matching critiera (satisfiedBy) is an OR:
- * a match on any of the network specifiers in the collection is a match.
- *
- * This class is not intended for use in network requests.
- *
- * @hide
- */
-public class WifiAwareAgentNetworkSpecifier extends NetworkSpecifier implements Parcelable {
-    private static final String TAG = "WifiAwareAgentNs";
-
-    private static final boolean VDBG = false; // STOPSHIP if true
-
-    private Set<ByteArrayWrapper> mNetworkSpecifiers = new HashSet<>();
-    private MessageDigest mDigester;
-
-    public WifiAwareAgentNetworkSpecifier() {
-        initialize();
-    }
-
-    public WifiAwareAgentNetworkSpecifier(WifiAwareNetworkSpecifier ns) {
-        initialize();
-        mNetworkSpecifiers.add(convert(ns));
-    }
-
-    public WifiAwareAgentNetworkSpecifier(WifiAwareNetworkSpecifier[] nss) {
-        initialize();
-        for (WifiAwareNetworkSpecifier ns : nss) {
-            mNetworkSpecifiers.add(convert(ns));
-        }
-    }
-
-    public boolean isEmpty() {
-        return mNetworkSpecifiers.isEmpty();
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeArray(mNetworkSpecifiers.toArray());
-    }
-
-    public static final @android.annotation.NonNull Creator<WifiAwareAgentNetworkSpecifier> CREATOR =
-            new Creator<WifiAwareAgentNetworkSpecifier>() {
-                @Override
-                public WifiAwareAgentNetworkSpecifier createFromParcel(Parcel in) {
-                    WifiAwareAgentNetworkSpecifier agentNs = new WifiAwareAgentNetworkSpecifier();
-                    Object[] objs = in.readArray(null);
-                    for (Object obj : objs) {
-                        agentNs.mNetworkSpecifiers.add((ByteArrayWrapper) obj);
-                    }
-                    return agentNs;
-                }
-
-                @Override
-                public WifiAwareAgentNetworkSpecifier[] newArray(int size) {
-                    return new WifiAwareAgentNetworkSpecifier[size];
-                }
-            };
-
-    @Override
-    public int hashCode() {
-        return mNetworkSpecifiers.hashCode();
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == this) {
-            return true;
-        }
-        if (!(obj instanceof WifiAwareAgentNetworkSpecifier)) {
-            return false;
-        }
-        return mNetworkSpecifiers.equals(((WifiAwareAgentNetworkSpecifier) obj).mNetworkSpecifiers);
-    }
-
-    @Override
-    public String toString() {
-        StringJoiner sj = new StringJoiner(",");
-        for (ByteArrayWrapper baw: mNetworkSpecifiers) {
-            sj.add(baw.toString());
-        }
-        return sj.toString();
-    }
-
-    @Override
-    public boolean canBeSatisfiedBy(NetworkSpecifier other) {
-        if (!(other instanceof WifiAwareAgentNetworkSpecifier)) {
-            return false;
-        }
-        WifiAwareAgentNetworkSpecifier otherNs = (WifiAwareAgentNetworkSpecifier) other;
-
-        // called as old.satifiedBy(new): satisfied if old contained in new
-        for (ByteArrayWrapper baw: mNetworkSpecifiers) {
-            if (!otherNs.mNetworkSpecifiers.contains(baw)) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    public boolean satisfiesAwareNetworkSpecifier(WifiAwareNetworkSpecifier ns) {
-        if (VDBG) Log.v(TAG, "satisfiesAwareNetworkSpecifier: ns=" + ns);
-        ByteArrayWrapper nsBytes = convert(ns);
-        return mNetworkSpecifiers.contains(nsBytes);
-    }
-
-    @Override
-    public NetworkSpecifier redact() {
-        return null;
-    }
-
-    private void initialize() {
-        try {
-            mDigester = MessageDigest.getInstance("SHA-256");
-        } catch (NoSuchAlgorithmException e) {
-            Log.e(TAG, "Can not instantiate a SHA-256 digester!? Will match nothing.");
-            return;
-        }
-    }
-
-    private ByteArrayWrapper convert(WifiAwareNetworkSpecifier ns) {
-        if (mDigester == null) {
-            return null;
-        }
-
-        Parcel parcel = Parcel.obtain();
-        ns.writeToParcel(parcel, 0);
-        byte[] bytes = parcel.marshall();
-
-        mDigester.reset();
-        mDigester.update(bytes);
-        return new ByteArrayWrapper(mDigester.digest());
-    }
-
-    private static class ByteArrayWrapper implements Parcelable {
-        private byte[] mData;
-
-        ByteArrayWrapper(byte[] data) {
-            mData = data;
-        }
-
-        @Override
-        public int hashCode() {
-            return Arrays.hashCode(mData);
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (obj == this) {
-                return true;
-            }
-            if (!(obj instanceof ByteArrayWrapper)) {
-                return false;
-            }
-            return Arrays.equals(((ByteArrayWrapper) obj).mData, mData);
-        }
-
-        @Override
-        public int describeContents() {
-            return 0;
-        }
-
-        @Override
-        public void writeToParcel(Parcel dest, int flags) {
-            dest.writeByteArray(mData);
-        }
-
-        public static final @android.annotation.NonNull Creator<ByteArrayWrapper> CREATOR =
-                new Creator<ByteArrayWrapper>() {
-                    @Override
-                    public ByteArrayWrapper createFromParcel(Parcel in) {
-                        return new ByteArrayWrapper(in.createByteArray());
-                    }
-
-                    @Override
-                    public ByteArrayWrapper[] newArray(int size) {
-                        return new ByteArrayWrapper[size];
-                    }
-                };
-
-        @Override
-        public String toString() {
-            return new String(HexEncoding.encode(mData));
-        }
-    }
-}
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareManager.java b/wifi/java/android/net/wifi/aware/WifiAwareManager.java
deleted file mode 100644
index c2ae17c..0000000
--- a/wifi/java/android/net/wifi/aware/WifiAwareManager.java
+++ /dev/null
@@ -1,824 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.aware;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.annotation.SystemService;
-import android.content.Context;
-import android.net.ConnectivityManager;
-import android.net.NetworkRequest;
-import android.net.NetworkSpecifier;
-import android.net.wifi.util.HexEncoding;
-import android.os.Binder;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.ref.WeakReference;
-import java.nio.BufferOverflowException;
-import java.util.List;
-
-/**
- * This class provides the primary API for managing Wi-Fi Aware operations:
- * discovery and peer-to-peer data connections.
- * <p>
- * The class provides access to:
- * <ul>
- * <li>Initialize a Aware cluster (peer-to-peer synchronization). Refer to
- * {@link #attach(AttachCallback, Handler)}.
- * <li>Create discovery sessions (publish or subscribe sessions). Refer to
- * {@link WifiAwareSession#publish(PublishConfig, DiscoverySessionCallback, Handler)} and
- * {@link WifiAwareSession#subscribe(SubscribeConfig, DiscoverySessionCallback, Handler)}.
- * <li>Create a Aware network specifier to be used with
- * {@link ConnectivityManager#requestNetwork(NetworkRequest, ConnectivityManager.NetworkCallback)}
- * to set-up a Aware connection with a peer. Refer to {@link WifiAwareNetworkSpecifier.Builder}.
- * </ul>
- * <p>
- *     Aware may not be usable when Wi-Fi is disabled (and other conditions). To validate that
- *     the functionality is available use the {@link #isAvailable()} function. To track
- *     changes in Aware usability register for the {@link #ACTION_WIFI_AWARE_STATE_CHANGED}
- *     broadcast. Note that this broadcast is not sticky - you should register for it and then
- *     check the above API to avoid a race condition.
- * <p>
- *     An application must use {@link #attach(AttachCallback, Handler)} to initialize a
- *     Aware cluster - before making any other Aware operation. Aware cluster membership is a
- *     device-wide operation - the API guarantees that the device is in a cluster or joins a
- *     Aware cluster (or starts one if none can be found). Information about attach success (or
- *     failure) are returned in callbacks of {@link AttachCallback}. Proceed with Aware
- *     discovery or connection setup only after receiving confirmation that Aware attach
- *     succeeded - {@link AttachCallback#onAttached(WifiAwareSession)}. When an
- *     application is finished using Aware it <b>must</b> use the
- *     {@link WifiAwareSession#close()} API to indicate to the Aware service that the device
- *     may detach from the Aware cluster. The device will actually disable Aware once the last
- *     application detaches.
- * <p>
- *     Once a Aware attach is confirmed use the
- *     {@link WifiAwareSession#publish(PublishConfig, DiscoverySessionCallback, Handler)}
- *     or
- *     {@link WifiAwareSession#subscribe(SubscribeConfig, DiscoverySessionCallback,
- *     Handler)} to create publish or subscribe Aware discovery sessions. Events are called on the
- *     provided callback object {@link DiscoverySessionCallback}. Specifically, the
- *     {@link DiscoverySessionCallback#onPublishStarted(PublishDiscoverySession)}
- *     and
- *     {@link DiscoverySessionCallback#onSubscribeStarted(
- *SubscribeDiscoverySession)}
- *     return {@link PublishDiscoverySession} and
- *     {@link SubscribeDiscoverySession}
- *     objects respectively on which additional session operations can be performed, e.g. updating
- *     the session {@link PublishDiscoverySession#updatePublish(PublishConfig)} and
- *     {@link SubscribeDiscoverySession#updateSubscribe(SubscribeConfig)}. Sessions can
- *     also be used to send messages using the
- *     {@link DiscoverySession#sendMessage(PeerHandle, int, byte[])} APIs. When an
- *     application is finished with a discovery session it <b>must</b> terminate it using the
- *     {@link DiscoverySession#close()} API.
- * <p>
- *    Creating connections between Aware devices is managed by the standard
- *    {@link ConnectivityManager#requestNetwork(NetworkRequest,
- *    ConnectivityManager.NetworkCallback)}.
- *    The {@link NetworkRequest} object should be constructed with:
- *    <ul>
- *        <li>{@link NetworkRequest.Builder#addTransportType(int)} of
- *        {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}.
- *        <li>{@link NetworkRequest.Builder#setNetworkSpecifier(String)} using
- *        {@link WifiAwareNetworkSpecifier.Builder}.
- *    </ul>
- */
-@SystemService(Context.WIFI_AWARE_SERVICE)
-public class WifiAwareManager {
-    private static final String TAG = "WifiAwareManager";
-    private static final boolean DBG = false;
-    private static final boolean VDBG = false; // STOPSHIP if true
-
-    /**
-     * Broadcast intent action to indicate that the state of Wi-Fi Aware availability has changed.
-     * Use the {@link #isAvailable()} to query the current status.
-     * This broadcast is <b>not</b> sticky, use the {@link #isAvailable()} API after registering
-     * the broadcast to check the current state of Wi-Fi Aware.
-     * <p>Note: The broadcast is only delivered to registered receivers - no manifest registered
-     * components will be launched.
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_WIFI_AWARE_STATE_CHANGED =
-            "android.net.wifi.aware.action.WIFI_AWARE_STATE_CHANGED";
-
-    /** @hide */
-    @IntDef({
-            WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, WIFI_AWARE_DATA_PATH_ROLE_RESPONDER})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface DataPathRole {
-    }
-
-    /**
-     * Connection creation role is that of INITIATOR. Used to create a network specifier string
-     * when requesting a Aware network.
-     *
-     * @see WifiAwareSession#createNetworkSpecifierOpen(int, byte[])
-     * @see WifiAwareSession#createNetworkSpecifierPassphrase(int, byte[], String)
-     */
-    public static final int WIFI_AWARE_DATA_PATH_ROLE_INITIATOR = 0;
-
-    /**
-     * Connection creation role is that of RESPONDER. Used to create a network specifier string
-     * when requesting a Aware network.
-     *
-     * @see WifiAwareSession#createNetworkSpecifierOpen(int, byte[])
-     * @see WifiAwareSession#createNetworkSpecifierPassphrase(int, byte[], String)
-     */
-    public static final int WIFI_AWARE_DATA_PATH_ROLE_RESPONDER = 1;
-
-    private final Context mContext;
-    private final IWifiAwareManager mService;
-
-    private final Object mLock = new Object(); // lock access to the following vars
-
-    /** @hide */
-    public WifiAwareManager(@NonNull Context context, @NonNull IWifiAwareManager service) {
-        mContext = context;
-        mService = service;
-    }
-
-    /**
-     * Returns the current status of Aware API: whether or not Aware is available. To track
-     * changes in the state of Aware API register for the
-     * {@link #ACTION_WIFI_AWARE_STATE_CHANGED} broadcast.
-     *
-     * @return A boolean indicating whether the app can use the Aware API at this time (true) or
-     * not (false).
-     */
-    public boolean isAvailable() {
-        try {
-            return mService.isUsageEnabled();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Returns the characteristics of the Wi-Fi Aware interface: a set of parameters which specify
-     * limitations on configurations, e.g. the maximum service name length.
-     *
-     * @return An object specifying configuration limitations of Aware.
-     */
-    public Characteristics getCharacteristics() {
-        try {
-            return mService.getCharacteristics();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Attach to the Wi-Fi Aware service - enabling the application to create discovery sessions or
-     * create connections to peers. The device will attach to an existing cluster if it can find
-     * one or create a new cluster (if it is the first to enable Aware in its vicinity). Results
-     * (e.g. successful attach to a cluster) are provided to the {@code attachCallback} object.
-     * An application <b>must</b> call {@link WifiAwareSession#close()} when done with the
-     * Wi-Fi Aware object.
-     * <p>
-     * Note: a Aware cluster is a shared resource - if the device is already attached to a cluster
-     * then this function will simply indicate success immediately using the same {@code
-     * attachCallback}.
-     *
-     * @param attachCallback A callback for attach events, extended from
-     * {@link AttachCallback}.
-     * @param handler The Handler on whose thread to execute the callbacks of the {@code
-     * attachCallback} object. If a null is provided then the application's main thread will be
-     *                used.
-     */
-    public void attach(@NonNull AttachCallback attachCallback, @Nullable Handler handler) {
-        attach(handler, null, attachCallback, null);
-    }
-
-    /**
-     * Attach to the Wi-Fi Aware service - enabling the application to create discovery sessions or
-     * create connections to peers. The device will attach to an existing cluster if it can find
-     * one or create a new cluster (if it is the first to enable Aware in its vicinity). Results
-     * (e.g. successful attach to a cluster) are provided to the {@code attachCallback} object.
-     * An application <b>must</b> call {@link WifiAwareSession#close()} when done with the
-     * Wi-Fi Aware object.
-     * <p>
-     * Note: a Aware cluster is a shared resource - if the device is already attached to a cluster
-     * then this function will simply indicate success immediately using the same {@code
-     * attachCallback}.
-     * <p>
-     * This version of the API attaches a listener to receive the MAC address of the Aware interface
-     * on startup and whenever it is updated (it is randomized at regular intervals for privacy).
-     * The application must have the {@link android.Manifest.permission#ACCESS_FINE_LOCATION}
-     * permission to execute this attach request. Otherwise, use the
-     * {@link #attach(AttachCallback, Handler)} version. Note that aside from permission
-     * requirements this listener will wake up the host at regular intervals causing higher power
-     * consumption, do not use it unless the information is necessary (e.g. for OOB discovery).
-     *
-     * @param attachCallback A callback for attach events, extended from
-     * {@link AttachCallback}.
-     * @param identityChangedListener A listener for changed identity, extended from
-     * {@link IdentityChangedListener}.
-     * @param handler The Handler on whose thread to execute the callbacks of the {@code
-     * attachCallback} and {@code identityChangedListener} objects. If a null is provided then the
-     *                application's main thread will be used.
-     */
-    public void attach(@NonNull AttachCallback attachCallback,
-            @NonNull IdentityChangedListener identityChangedListener,
-            @Nullable Handler handler) {
-        attach(handler, null, attachCallback, identityChangedListener);
-    }
-
-    /** @hide */
-    public void attach(Handler handler, ConfigRequest configRequest,
-            AttachCallback attachCallback,
-            IdentityChangedListener identityChangedListener) {
-        if (VDBG) {
-            Log.v(TAG, "attach(): handler=" + handler + ", callback=" + attachCallback
-                    + ", configRequest=" + configRequest + ", identityChangedListener="
-                    + identityChangedListener);
-        }
-
-        if (attachCallback == null) {
-            throw new IllegalArgumentException("Null callback provided");
-        }
-
-        synchronized (mLock) {
-            Looper looper = (handler == null) ? Looper.getMainLooper() : handler.getLooper();
-
-            try {
-                Binder binder = new Binder();
-                mService.connect(binder, mContext.getOpPackageName(), mContext.getAttributionTag(),
-                        new WifiAwareEventCallbackProxy(this, looper, binder, attachCallback,
-                                identityChangedListener), configRequest,
-                        identityChangedListener != null);
-            } catch (RemoteException e) {
-                throw e.rethrowFromSystemServer();
-            }
-        }
-    }
-
-    /** @hide */
-    public void disconnect(int clientId, Binder binder) {
-        if (VDBG) Log.v(TAG, "disconnect()");
-
-        try {
-            mService.disconnect(clientId, binder);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /** @hide */
-    public void publish(int clientId, Looper looper, PublishConfig publishConfig,
-            DiscoverySessionCallback callback) {
-        if (VDBG) Log.v(TAG, "publish(): clientId=" + clientId + ", config=" + publishConfig);
-
-        if (callback == null) {
-            throw new IllegalArgumentException("Null callback provided");
-        }
-
-        try {
-            mService.publish(mContext.getOpPackageName(), mContext.getAttributionTag(), clientId,
-                    publishConfig,
-                    new WifiAwareDiscoverySessionCallbackProxy(this, looper, true, callback,
-                            clientId));
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /** @hide */
-    public void updatePublish(int clientId, int sessionId, PublishConfig publishConfig) {
-        if (VDBG) {
-            Log.v(TAG, "updatePublish(): clientId=" + clientId + ",sessionId=" + sessionId
-                    + ", config=" + publishConfig);
-        }
-
-        try {
-            mService.updatePublish(clientId, sessionId, publishConfig);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /** @hide */
-    public void subscribe(int clientId, Looper looper, SubscribeConfig subscribeConfig,
-            DiscoverySessionCallback callback) {
-        if (VDBG) {
-            if (VDBG) {
-                Log.v(TAG,
-                        "subscribe(): clientId=" + clientId + ", config=" + subscribeConfig);
-            }
-        }
-
-        if (callback == null) {
-            throw new IllegalArgumentException("Null callback provided");
-        }
-
-        try {
-            mService.subscribe(mContext.getOpPackageName(), mContext.getAttributionTag(), clientId,
-                    subscribeConfig,
-                    new WifiAwareDiscoverySessionCallbackProxy(this, looper, false, callback,
-                            clientId));
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /** @hide */
-    public void updateSubscribe(int clientId, int sessionId, SubscribeConfig subscribeConfig) {
-        if (VDBG) {
-            Log.v(TAG, "updateSubscribe(): clientId=" + clientId + ",sessionId=" + sessionId
-                    + ", config=" + subscribeConfig);
-        }
-
-        try {
-            mService.updateSubscribe(clientId, sessionId, subscribeConfig);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /** @hide */
-    public void terminateSession(int clientId, int sessionId) {
-        if (VDBG) {
-            Log.d(TAG,
-                    "terminateSession(): clientId=" + clientId + ", sessionId=" + sessionId);
-        }
-
-        try {
-            mService.terminateSession(clientId, sessionId);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /** @hide */
-    public void sendMessage(int clientId, int sessionId, PeerHandle peerHandle, byte[] message,
-            int messageId, int retryCount) {
-        if (peerHandle == null) {
-            throw new IllegalArgumentException(
-                    "sendMessage: invalid peerHandle - must be non-null");
-        }
-
-        if (VDBG) {
-            Log.v(TAG, "sendMessage(): clientId=" + clientId + ", sessionId=" + sessionId
-                    + ", peerHandle=" + peerHandle.peerId + ", messageId="
-                    + messageId + ", retryCount=" + retryCount);
-        }
-
-        try {
-            mService.sendMessage(clientId, sessionId, peerHandle.peerId, message, messageId,
-                    retryCount);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /** @hide */
-    @RequiresPermission(android.Manifest.permission.NETWORK_STACK)
-    public void requestMacAddresses(int uid, List<Integer> peerIds,
-            IWifiAwareMacAddressProvider callback) {
-        try {
-            mService.requestMacAddresses(uid, peerIds, callback);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /** @hide */
-    public NetworkSpecifier createNetworkSpecifier(int clientId, int role, int sessionId,
-            @NonNull PeerHandle peerHandle, @Nullable byte[] pmk, @Nullable String passphrase) {
-        if (VDBG) {
-            Log.v(TAG, "createNetworkSpecifier: role=" + role + ", sessionId=" + sessionId
-                    + ", peerHandle=" + ((peerHandle == null) ? peerHandle : peerHandle.peerId)
-                    + ", pmk=" + ((pmk == null) ? "null" : "non-null")
-                    + ", passphrase=" + ((passphrase == null) ? "null" : "non-null"));
-        }
-
-        if (!WifiAwareUtils.isLegacyVersion(mContext, Build.VERSION_CODES.Q)) {
-            throw new UnsupportedOperationException(
-                    "API deprecated - use WifiAwareNetworkSpecifier.Builder");
-        }
-
-        if (role != WIFI_AWARE_DATA_PATH_ROLE_INITIATOR
-                && role != WIFI_AWARE_DATA_PATH_ROLE_RESPONDER) {
-            throw new IllegalArgumentException(
-                    "createNetworkSpecifier: Invalid 'role' argument when creating a network "
-                            + "specifier");
-        }
-        if (role == WIFI_AWARE_DATA_PATH_ROLE_INITIATOR || !WifiAwareUtils.isLegacyVersion(mContext,
-                Build.VERSION_CODES.P)) {
-            if (peerHandle == null) {
-                throw new IllegalArgumentException(
-                        "createNetworkSpecifier: Invalid peer handle - cannot be null");
-            }
-        }
-
-        return new WifiAwareNetworkSpecifier(
-                (peerHandle == null) ? WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_IB_ANY_PEER
-                        : WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_IB,
-                role,
-                clientId,
-                sessionId,
-                peerHandle != null ? peerHandle.peerId : 0, // 0 is an invalid peer ID
-                null, // peerMac (not used in this method)
-                pmk,
-                passphrase,
-                0, // no port info for deprecated IB APIs
-                -1); // no transport info for deprecated IB APIs
-    }
-
-    /** @hide */
-    public NetworkSpecifier createNetworkSpecifier(int clientId, @DataPathRole int role,
-            @NonNull byte[] peer, @Nullable byte[] pmk, @Nullable String passphrase) {
-        if (VDBG) {
-            Log.v(TAG, "createNetworkSpecifier: role=" + role
-                    + ", pmk=" + ((pmk == null) ? "null" : "non-null")
-                    + ", passphrase=" + ((passphrase == null) ? "null" : "non-null"));
-        }
-
-        if (role != WIFI_AWARE_DATA_PATH_ROLE_INITIATOR
-                && role != WIFI_AWARE_DATA_PATH_ROLE_RESPONDER) {
-            throw new IllegalArgumentException(
-                    "createNetworkSpecifier: Invalid 'role' argument when creating a network "
-                            + "specifier");
-        }
-        if (role == WIFI_AWARE_DATA_PATH_ROLE_INITIATOR || !WifiAwareUtils.isLegacyVersion(mContext,
-                Build.VERSION_CODES.P)) {
-            if (peer == null) {
-                throw new IllegalArgumentException(
-                        "createNetworkSpecifier: Invalid peer MAC - cannot be null");
-            }
-        }
-        if (peer != null && peer.length != 6) {
-            throw new IllegalArgumentException("createNetworkSpecifier: Invalid peer MAC address");
-        }
-
-        return new WifiAwareNetworkSpecifier(
-                (peer == null) ? WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_OOB_ANY_PEER
-                        : WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_OOB,
-                role,
-                clientId,
-                0, // 0 is an invalid session ID
-                0, // 0 is an invalid peer ID
-                peer,
-                pmk,
-                passphrase,
-                0, // no port info for OOB APIs
-                -1); // no transport protocol info for OOB APIs
-    }
-
-    private static class WifiAwareEventCallbackProxy extends IWifiAwareEventCallback.Stub {
-        private static final int CALLBACK_CONNECT_SUCCESS = 0;
-        private static final int CALLBACK_CONNECT_FAIL = 1;
-        private static final int CALLBACK_IDENTITY_CHANGED = 2;
-
-        private final Handler mHandler;
-        private final WeakReference<WifiAwareManager> mAwareManager;
-        private final Binder mBinder;
-        private final Looper mLooper;
-
-        /**
-         * Constructs a {@link AttachCallback} using the specified looper.
-         * All callbacks will delivered on the thread of the specified looper.
-         *
-         * @param looper The looper on which to execute the callbacks.
-         */
-        WifiAwareEventCallbackProxy(WifiAwareManager mgr, Looper looper, Binder binder,
-                final AttachCallback attachCallback,
-                final IdentityChangedListener identityChangedListener) {
-            mAwareManager = new WeakReference<>(mgr);
-            mLooper = looper;
-            mBinder = binder;
-
-            if (VDBG) Log.v(TAG, "WifiAwareEventCallbackProxy ctor: looper=" + looper);
-            mHandler = new Handler(looper) {
-                @Override
-                public void handleMessage(Message msg) {
-                    if (DBG) {
-                        Log.d(TAG, "WifiAwareEventCallbackProxy: What=" + msg.what + ", msg="
-                                + msg);
-                    }
-
-                    WifiAwareManager mgr = mAwareManager.get();
-                    if (mgr == null) {
-                        Log.w(TAG, "WifiAwareEventCallbackProxy: handleMessage post GC");
-                        return;
-                    }
-
-                    switch (msg.what) {
-                        case CALLBACK_CONNECT_SUCCESS:
-                            attachCallback.onAttached(
-                                    new WifiAwareSession(mgr, mBinder, msg.arg1));
-                            break;
-                        case CALLBACK_CONNECT_FAIL:
-                            mAwareManager.clear();
-                            attachCallback.onAttachFailed();
-                            break;
-                        case CALLBACK_IDENTITY_CHANGED:
-                            if (identityChangedListener == null) {
-                                Log.e(TAG, "CALLBACK_IDENTITY_CHANGED: null listener.");
-                            } else {
-                                identityChangedListener.onIdentityChanged((byte[]) msg.obj);
-                            }
-                            break;
-                    }
-                }
-            };
-        }
-
-        @Override
-        public void onConnectSuccess(int clientId) {
-            if (VDBG) Log.v(TAG, "onConnectSuccess");
-
-            Message msg = mHandler.obtainMessage(CALLBACK_CONNECT_SUCCESS);
-            msg.arg1 = clientId;
-            mHandler.sendMessage(msg);
-        }
-
-        @Override
-        public void onConnectFail(int reason) {
-            if (VDBG) Log.v(TAG, "onConnectFail: reason=" + reason);
-
-            Message msg = mHandler.obtainMessage(CALLBACK_CONNECT_FAIL);
-            msg.arg1 = reason;
-            mHandler.sendMessage(msg);
-        }
-
-        @Override
-        public void onIdentityChanged(byte[] mac) {
-            if (VDBG) Log.v(TAG, "onIdentityChanged: mac=" + new String(HexEncoding.encode(mac)));
-
-            Message msg = mHandler.obtainMessage(CALLBACK_IDENTITY_CHANGED);
-            msg.obj = mac;
-            mHandler.sendMessage(msg);
-        }
-    }
-
-    private static class WifiAwareDiscoverySessionCallbackProxy extends
-            IWifiAwareDiscoverySessionCallback.Stub {
-        private static final int CALLBACK_SESSION_STARTED = 0;
-        private static final int CALLBACK_SESSION_CONFIG_SUCCESS = 1;
-        private static final int CALLBACK_SESSION_CONFIG_FAIL = 2;
-        private static final int CALLBACK_SESSION_TERMINATED = 3;
-        private static final int CALLBACK_MATCH = 4;
-        private static final int CALLBACK_MESSAGE_SEND_SUCCESS = 5;
-        private static final int CALLBACK_MESSAGE_SEND_FAIL = 6;
-        private static final int CALLBACK_MESSAGE_RECEIVED = 7;
-        private static final int CALLBACK_MATCH_WITH_DISTANCE = 8;
-
-        private static final String MESSAGE_BUNDLE_KEY_MESSAGE = "message";
-        private static final String MESSAGE_BUNDLE_KEY_MESSAGE2 = "message2";
-
-        private final WeakReference<WifiAwareManager> mAwareManager;
-        private final boolean mIsPublish;
-        private final DiscoverySessionCallback mOriginalCallback;
-        private final int mClientId;
-
-        private final Handler mHandler;
-        private DiscoverySession mSession;
-
-        WifiAwareDiscoverySessionCallbackProxy(WifiAwareManager mgr, Looper looper,
-                boolean isPublish, DiscoverySessionCallback originalCallback,
-                int clientId) {
-            mAwareManager = new WeakReference<>(mgr);
-            mIsPublish = isPublish;
-            mOriginalCallback = originalCallback;
-            mClientId = clientId;
-
-            if (VDBG) {
-                Log.v(TAG, "WifiAwareDiscoverySessionCallbackProxy ctor: isPublish=" + isPublish);
-            }
-
-            mHandler = new Handler(looper) {
-                @Override
-                public void handleMessage(Message msg) {
-                    if (DBG) Log.d(TAG, "What=" + msg.what + ", msg=" + msg);
-
-                    if (mAwareManager.get() == null) {
-                        Log.w(TAG, "WifiAwareDiscoverySessionCallbackProxy: handleMessage post GC");
-                        return;
-                    }
-
-                    switch (msg.what) {
-                        case CALLBACK_SESSION_STARTED:
-                            onProxySessionStarted(msg.arg1);
-                            break;
-                        case CALLBACK_SESSION_CONFIG_SUCCESS:
-                            mOriginalCallback.onSessionConfigUpdated();
-                            break;
-                        case CALLBACK_SESSION_CONFIG_FAIL:
-                            mOriginalCallback.onSessionConfigFailed();
-                            if (mSession == null) {
-                                /*
-                                 * creation failed (as opposed to update
-                                 * failing)
-                                 */
-                                mAwareManager.clear();
-                            }
-                            break;
-                        case CALLBACK_SESSION_TERMINATED:
-                            onProxySessionTerminated(msg.arg1);
-                            break;
-                        case CALLBACK_MATCH:
-                        case CALLBACK_MATCH_WITH_DISTANCE:
-                            {
-                            List<byte[]> matchFilter = null;
-                            byte[] arg = msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE2);
-                            try {
-                                matchFilter = new TlvBufferUtils.TlvIterable(0, 1, arg).toList();
-                            } catch (BufferOverflowException e) {
-                                matchFilter = null;
-                                Log.e(TAG, "onServiceDiscovered: invalid match filter byte array '"
-                                        + new String(HexEncoding.encode(arg))
-                                        + "' - cannot be parsed: e=" + e);
-                            }
-                            if (msg.what == CALLBACK_MATCH) {
-                                mOriginalCallback.onServiceDiscovered(new PeerHandle(msg.arg1),
-                                        msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE),
-                                        matchFilter);
-                            } else {
-                                mOriginalCallback.onServiceDiscoveredWithinRange(
-                                        new PeerHandle(msg.arg1),
-                                        msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE),
-                                        matchFilter, msg.arg2);
-                            }
-                            break;
-                        }
-                        case CALLBACK_MESSAGE_SEND_SUCCESS:
-                            mOriginalCallback.onMessageSendSucceeded(msg.arg1);
-                            break;
-                        case CALLBACK_MESSAGE_SEND_FAIL:
-                            mOriginalCallback.onMessageSendFailed(msg.arg1);
-                            break;
-                        case CALLBACK_MESSAGE_RECEIVED:
-                            mOriginalCallback.onMessageReceived(new PeerHandle(msg.arg1),
-                                    (byte[]) msg.obj);
-                            break;
-                    }
-                }
-            };
-        }
-
-        @Override
-        public void onSessionStarted(int sessionId) {
-            if (VDBG) Log.v(TAG, "onSessionStarted: sessionId=" + sessionId);
-
-            Message msg = mHandler.obtainMessage(CALLBACK_SESSION_STARTED);
-            msg.arg1 = sessionId;
-            mHandler.sendMessage(msg);
-        }
-
-        @Override
-        public void onSessionConfigSuccess() {
-            if (VDBG) Log.v(TAG, "onSessionConfigSuccess");
-
-            Message msg = mHandler.obtainMessage(CALLBACK_SESSION_CONFIG_SUCCESS);
-            mHandler.sendMessage(msg);
-        }
-
-        @Override
-        public void onSessionConfigFail(int reason) {
-            if (VDBG) Log.v(TAG, "onSessionConfigFail: reason=" + reason);
-
-            Message msg = mHandler.obtainMessage(CALLBACK_SESSION_CONFIG_FAIL);
-            msg.arg1 = reason;
-            mHandler.sendMessage(msg);
-        }
-
-        @Override
-        public void onSessionTerminated(int reason) {
-            if (VDBG) Log.v(TAG, "onSessionTerminated: reason=" + reason);
-
-            Message msg = mHandler.obtainMessage(CALLBACK_SESSION_TERMINATED);
-            msg.arg1 = reason;
-            mHandler.sendMessage(msg);
-        }
-
-        private void onMatchCommon(int messageType, int peerId, byte[] serviceSpecificInfo,
-                byte[] matchFilter, int distanceMm) {
-            Bundle data = new Bundle();
-            data.putByteArray(MESSAGE_BUNDLE_KEY_MESSAGE, serviceSpecificInfo);
-            data.putByteArray(MESSAGE_BUNDLE_KEY_MESSAGE2, matchFilter);
-
-            Message msg = mHandler.obtainMessage(messageType);
-            msg.arg1 = peerId;
-            msg.arg2 = distanceMm;
-            msg.setData(data);
-            mHandler.sendMessage(msg);
-        }
-
-        @Override
-        public void onMatch(int peerId, byte[] serviceSpecificInfo, byte[] matchFilter) {
-            if (VDBG) Log.v(TAG, "onMatch: peerId=" + peerId);
-
-            onMatchCommon(CALLBACK_MATCH, peerId, serviceSpecificInfo, matchFilter, 0);
-        }
-
-        @Override
-        public void onMatchWithDistance(int peerId, byte[] serviceSpecificInfo, byte[] matchFilter,
-                int distanceMm) {
-            if (VDBG) {
-                Log.v(TAG, "onMatchWithDistance: peerId=" + peerId + ", distanceMm=" + distanceMm);
-            }
-
-            onMatchCommon(CALLBACK_MATCH_WITH_DISTANCE, peerId, serviceSpecificInfo, matchFilter,
-                    distanceMm);
-        }
-
-        @Override
-        public void onMessageSendSuccess(int messageId) {
-            if (VDBG) Log.v(TAG, "onMessageSendSuccess");
-
-            Message msg = mHandler.obtainMessage(CALLBACK_MESSAGE_SEND_SUCCESS);
-            msg.arg1 = messageId;
-            mHandler.sendMessage(msg);
-        }
-
-        @Override
-        public void onMessageSendFail(int messageId, int reason) {
-            if (VDBG) Log.v(TAG, "onMessageSendFail: reason=" + reason);
-
-            Message msg = mHandler.obtainMessage(CALLBACK_MESSAGE_SEND_FAIL);
-            msg.arg1 = messageId;
-            msg.arg2 = reason;
-            mHandler.sendMessage(msg);
-        }
-
-        @Override
-        public void onMessageReceived(int peerId, byte[] message) {
-            if (VDBG) {
-                Log.v(TAG, "onMessageReceived: peerId=" + peerId);
-            }
-
-            Message msg = mHandler.obtainMessage(CALLBACK_MESSAGE_RECEIVED);
-            msg.arg1 = peerId;
-            msg.obj = message;
-            mHandler.sendMessage(msg);
-        }
-
-        /*
-         * Proxied methods
-         */
-        public void onProxySessionStarted(int sessionId) {
-            if (VDBG) Log.v(TAG, "Proxy: onSessionStarted: sessionId=" + sessionId);
-            if (mSession != null) {
-                Log.e(TAG,
-                        "onSessionStarted: sessionId=" + sessionId + ": session already created!?");
-                throw new IllegalStateException(
-                        "onSessionStarted: sessionId=" + sessionId + ": session already created!?");
-            }
-
-            WifiAwareManager mgr = mAwareManager.get();
-            if (mgr == null) {
-                Log.w(TAG, "onProxySessionStarted: mgr GC'd");
-                return;
-            }
-
-            if (mIsPublish) {
-                PublishDiscoverySession session = new PublishDiscoverySession(mgr,
-                        mClientId, sessionId);
-                mSession = session;
-                mOriginalCallback.onPublishStarted(session);
-            } else {
-                SubscribeDiscoverySession
-                        session = new SubscribeDiscoverySession(mgr, mClientId, sessionId);
-                mSession = session;
-                mOriginalCallback.onSubscribeStarted(session);
-            }
-        }
-
-        public void onProxySessionTerminated(int reason) {
-            if (VDBG) Log.v(TAG, "Proxy: onSessionTerminated: reason=" + reason);
-            if (mSession != null) {
-                mSession.setTerminated();
-                mSession = null;
-            } else {
-                Log.w(TAG, "Proxy: onSessionTerminated called but mSession is null!?");
-            }
-            mAwareManager.clear();
-            mOriginalCallback.onSessionTerminated();
-        }
-    }
-}
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareNetworkInfo.java b/wifi/java/android/net/wifi/aware/WifiAwareNetworkInfo.java
deleted file mode 100644
index 60fe604..0000000
--- a/wifi/java/android/net/wifi/aware/WifiAwareNetworkInfo.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.aware;
-
-import android.annotation.Nullable;
-import android.net.NetworkCapabilities;
-import android.net.TransportInfo;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.net.Inet6Address;
-import java.net.NetworkInterface;
-import java.net.SocketException;
-import java.net.UnknownHostException;
-import java.util.Objects;
-
-/**
- * Wi-Fi Aware-specific network information. The information can be extracted from the
- * {@link android.net.NetworkCapabilities} of the network using
- * {@link NetworkCapabilities#getTransportInfo()}.
- * The {@link NetworkCapabilities} is provided by the connectivity service to apps, e.g. received
- * through the
- * {@link android.net.ConnectivityManager.NetworkCallback#onCapabilitiesChanged(android.net.Network,
- * android.net.NetworkCapabilities)} callback.
- * <p>
- * The Wi-Fi Aware-specific network information include the peer's scoped link-local IPv6 address
- * for the Wi-Fi Aware link, as well as (optionally) the port and transport protocol specified by
- * the peer.
- * The scoped link-local IPv6, port, and transport protocol can then be used to create a
- * {@link java.net.Socket} connection to the peer.
- * <p>
- * Note: these are the peer's IPv6 and port information - not the local device's!
- */
-public final class WifiAwareNetworkInfo implements TransportInfo, Parcelable {
-    private Inet6Address mIpv6Addr;
-    private int mPort = 0; // a value of 0 is considered invalid
-    private int mTransportProtocol = -1; // a value of -1 is considered invalid
-
-    /** @hide */
-    public WifiAwareNetworkInfo(Inet6Address ipv6Addr) {
-        mIpv6Addr = ipv6Addr;
-    }
-
-    /** @hide */
-    public WifiAwareNetworkInfo(Inet6Address ipv6Addr, int port, int transportProtocol) {
-        mIpv6Addr = ipv6Addr;
-        mPort = port;
-        mTransportProtocol = transportProtocol;
-    }
-
-    /**
-     * Get the scoped link-local IPv6 address of the Wi-Fi Aware peer (not of the local device!).
-     *
-     * @return An IPv6 address.
-     */
-    @Nullable
-    public Inet6Address getPeerIpv6Addr() {
-        return mIpv6Addr;
-    }
-
-    /**
-     * Get the port number to be used to create a network connection to the Wi-Fi Aware peer.
-     * The port information is provided by the app running on the peer which requested the
-     * connection, using the {@link WifiAwareNetworkSpecifier.Builder#setPort(int)}.
-     *
-     * @return A port number on the peer. A value of 0 indicates that no port was specified by the
-     *         peer.
-     */
-    public int getPort() {
-        return mPort;
-    }
-
-    /**
-     * Get the transport protocol to be used to communicate over a network connection to the Wi-Fi
-     * Aware peer. The transport protocol is provided by the app running on the peer which requested
-     * the connection, using the
-     * {@link WifiAwareNetworkSpecifier.Builder#setTransportProtocol(int)}.
-     * <p>
-     * The transport protocol number is assigned by the Internet Assigned Numbers Authority
-     * (IANA) https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml.
-     *
-     * @return A transport protocol id. A value of -1 indicates that no transport protocol was
-     *         specified by the peer.
-     */
-    public int getTransportProtocol() {
-        return mTransportProtocol;
-    }
-
-    // parcelable methods
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeByteArray(mIpv6Addr.getAddress());
-        NetworkInterface ni = mIpv6Addr.getScopedInterface();
-        dest.writeString(ni == null ? null : ni.getName());
-        dest.writeInt(mPort);
-        dest.writeInt(mTransportProtocol);
-    }
-
-    public static final @android.annotation.NonNull Creator<WifiAwareNetworkInfo> CREATOR =
-            new Creator<WifiAwareNetworkInfo>() {
-                @Override
-                public WifiAwareNetworkInfo createFromParcel(Parcel in) {
-                    byte[] addr = in.createByteArray();
-                    String interfaceName = in.readString();
-                    int port = in.readInt();
-                    int transportProtocol = in.readInt();
-                    Inet6Address ipv6Addr;
-                    try {
-                        NetworkInterface ni = null;
-                        if (interfaceName != null) {
-                            try {
-                                ni = NetworkInterface.getByName(interfaceName);
-                            } catch (SocketException e) {
-                                e.printStackTrace();
-                            }
-                        }
-                        ipv6Addr = Inet6Address.getByAddress(null, addr, ni);
-                    } catch (UnknownHostException e) {
-                        e.printStackTrace();
-                        return new WifiAwareNetworkInfo(null);
-                    }
-                    return new WifiAwareNetworkInfo(ipv6Addr, port, transportProtocol);
-                }
-
-                @Override
-                public WifiAwareNetworkInfo[] newArray(int size) {
-                    return new WifiAwareNetworkInfo[size];
-                }
-            };
-
-
-    // object methods
-
-    @Override
-    public String toString() {
-        return new StringBuilder("AwareNetworkInfo: IPv6=").append(mIpv6Addr).append(
-                ", port=").append(mPort).append(", transportProtocol=").append(
-                mTransportProtocol).toString();
-    }
-
-    /** @hide */
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-
-        if (!(obj instanceof WifiAwareNetworkInfo)) {
-            return false;
-        }
-
-        WifiAwareNetworkInfo lhs = (WifiAwareNetworkInfo) obj;
-        return Objects.equals(mIpv6Addr, lhs.mIpv6Addr) && mPort == lhs.mPort
-                && mTransportProtocol == lhs.mTransportProtocol;
-    }
-
-    /** @hide */
-    @Override
-    public int hashCode() {
-        return Objects.hash(mIpv6Addr, mPort, mTransportProtocol);
-    }
-}
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java b/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java
deleted file mode 100644
index 3547750..0000000
--- a/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java
+++ /dev/null
@@ -1,446 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.aware;
-
-import static android.net.wifi.aware.WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR;
-
-import android.annotation.IntRange;
-import android.annotation.NonNull;
-import android.net.NetworkSpecifier;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-
-import java.util.Arrays;
-import java.util.Objects;
-
-/**
- * Network specifier object used to request a Wi-Fi Aware network. Apps should use the
- * {@link WifiAwareNetworkSpecifier.Builder} class to create an instance.
- */
-public final class WifiAwareNetworkSpecifier extends NetworkSpecifier implements Parcelable {
-    /**
-     * TYPE: in band, specific peer: role, client_id, session_id, peer_id, pmk/passphrase optional
-     * @hide
-     */
-    public static final int NETWORK_SPECIFIER_TYPE_IB = 0;
-
-    /**
-     * TYPE: in band, any peer: role, client_id, session_id, pmk/passphrase optional
-     * [only permitted for RESPONDER]
-     * @hide
-     */
-    public static final int NETWORK_SPECIFIER_TYPE_IB_ANY_PEER = 1;
-
-    /**
-     * TYPE: out-of-band: role, client_id, peer_mac, pmk/passphrase optional
-     * @hide
-     */
-    public static final int NETWORK_SPECIFIER_TYPE_OOB = 2;
-
-    /**
-     * TYPE: out-of-band, any peer: role, client_id, pmk/passphrase optional
-     * [only permitted for RESPONDER]
-     * @hide
-     */
-    public static final int NETWORK_SPECIFIER_TYPE_OOB_ANY_PEER = 3;
-
-    /** @hide */
-    public static final int NETWORK_SPECIFIER_TYPE_MAX_VALID = NETWORK_SPECIFIER_TYPE_OOB_ANY_PEER;
-
-    /**
-     * One of the NETWORK_SPECIFIER_TYPE_* constants. The type of the network specifier object.
-     * @hide
-     */
-    public final int type;
-
-    /**
-     * The role of the device: WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR or
-     * WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER.
-     * @hide
-     */
-    public final int role;
-
-    /**
-     * The client ID of the device.
-     * @hide
-     */
-    public final int clientId;
-
-    /**
-     * The session ID in which context to request a data-path. Only relevant for IB requests.
-     * @hide
-     */
-    public final int sessionId;
-
-    /**
-     * The peer ID of the device which the data-path should be connected to. Only relevant for
-     * IB requests (i.e. not IB_ANY_PEER or OOB*).
-     * @hide
-     */
-    public final int peerId;
-
-    /**
-     * The peer MAC address of the device which the data-path should be connected to. Only relevant
-     * for OB requests (i.e. not OOB_ANY_PEER or IB*).
-     * @hide
-     */
-    public final byte[] peerMac;
-
-    /**
-     * The PMK of the requested data-path. Can be null. Only one or none of pmk or passphrase should
-     * be specified.
-     * @hide
-     */
-    public final byte[] pmk;
-
-    /**
-     * The Passphrase of the requested data-path. Can be null. Only one or none of the pmk or
-     * passphrase should be specified.
-     * @hide
-     */
-    public final String passphrase;
-
-    /**
-     * The port information to be used for this link. This information will be communicated to the
-     * peer as part of the layer 2 link setup.
-     *
-     * Information only allowed on secure links since a single layer-2 link is set up for all
-     * requestors. Therefore if multiple apps on a single device request links to the same peer
-     * device they all get the same link. However, the link is only set up on the first request -
-     * hence only the first can transmit the port information. But we don't want to expose that
-     * information to other apps. Limiting to secure links would (usually) imply single app usage.
-     *
-     * @hide
-     */
-    public final int port;
-
-    /**
-     * The transport protocol information to be used for this link. This information will be
-     * communicated to the peer as part of the layer 2 link setup.
-     *
-     * Information only allowed on secure links since a single layer-2 link is set up for all
-     * requestors. Therefore if multiple apps on a single device request links to the same peer
-     * device they all get the same link. However, the link is only set up on the first request -
-     * hence only the first can transmit the port information. But we don't want to expose that
-     * information to other apps. Limiting to secure links would (usually) imply single app usage.
-     *
-     * @hide
-     */
-    public final int transportProtocol;
-
-    /** @hide */
-    public WifiAwareNetworkSpecifier(int type, int role, int clientId, int sessionId, int peerId,
-            byte[] peerMac, byte[] pmk, String passphrase, int port, int transportProtocol) {
-        this.type = type;
-        this.role = role;
-        this.clientId = clientId;
-        this.sessionId = sessionId;
-        this.peerId = peerId;
-        this.peerMac = peerMac;
-        this.pmk = pmk;
-        this.passphrase = passphrase;
-        this.port = port;
-        this.transportProtocol = transportProtocol;
-    }
-
-    public static final @android.annotation.NonNull Creator<WifiAwareNetworkSpecifier> CREATOR =
-            new Creator<WifiAwareNetworkSpecifier>() {
-                @Override
-                public WifiAwareNetworkSpecifier createFromParcel(Parcel in) {
-                    return new WifiAwareNetworkSpecifier(
-                        in.readInt(), // type
-                        in.readInt(), // role
-                        in.readInt(), // clientId
-                        in.readInt(), // sessionId
-                        in.readInt(), // peerId
-                        in.createByteArray(), // peerMac
-                        in.createByteArray(), // pmk
-                        in.readString(), // passphrase
-                        in.readInt(), // port
-                        in.readInt()); // transportProtocol
-                }
-
-                @Override
-                public WifiAwareNetworkSpecifier[] newArray(int size) {
-                    return new WifiAwareNetworkSpecifier[size];
-                }
-            };
-
-    /**
-     * Indicates whether the network specifier specifies an OOB (out-of-band) data-path - i.e. a
-     * data-path created without a corresponding Aware discovery session.
-     *
-     * @hide
-     */
-    public boolean isOutOfBand() {
-        return type == NETWORK_SPECIFIER_TYPE_OOB || type == NETWORK_SPECIFIER_TYPE_OOB_ANY_PEER;
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(type);
-        dest.writeInt(role);
-        dest.writeInt(clientId);
-        dest.writeInt(sessionId);
-        dest.writeInt(peerId);
-        dest.writeByteArray(peerMac);
-        dest.writeByteArray(pmk);
-        dest.writeString(passphrase);
-        dest.writeInt(port);
-        dest.writeInt(transportProtocol);
-    }
-
-    /** @hide */
-    @Override
-    public boolean canBeSatisfiedBy(NetworkSpecifier other) {
-        // MatchAllNetworkSpecifier is taken care in NetworkCapabilities#satisfiedBySpecifier.
-        if (other instanceof WifiAwareAgentNetworkSpecifier) {
-            return ((WifiAwareAgentNetworkSpecifier) other).satisfiesAwareNetworkSpecifier(this);
-        }
-        return equals(other);
-    }
-
-    /** @hide */
-    @Override
-    public int hashCode() {
-        return Objects.hash(type, role, clientId, sessionId, peerId, Arrays.hashCode(peerMac),
-                Arrays.hashCode(pmk), passphrase, port, transportProtocol);
-    }
-
-    /** @hide */
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-
-        if (!(obj instanceof WifiAwareNetworkSpecifier)) {
-            return false;
-        }
-
-        WifiAwareNetworkSpecifier lhs = (WifiAwareNetworkSpecifier) obj;
-
-        return type == lhs.type
-                && role == lhs.role
-                && clientId == lhs.clientId
-                && sessionId == lhs.sessionId
-                && peerId == lhs.peerId
-                && Arrays.equals(peerMac, lhs.peerMac)
-                && Arrays.equals(pmk, lhs.pmk)
-                && Objects.equals(passphrase, lhs.passphrase)
-                && port == lhs.port
-                && transportProtocol == lhs.transportProtocol;
-    }
-
-    /** @hide */
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder("WifiAwareNetworkSpecifier [");
-        sb.append("type=").append(type)
-                .append(", role=").append(role)
-                .append(", clientId=").append(clientId)
-                .append(", sessionId=").append(sessionId)
-                .append(", peerId=").append(peerId)
-                // masking potential PII (although low impact information)
-                .append(", peerMac=").append((peerMac == null) ? "<null>" : "<non-null>")
-                // masking PII
-                .append(", pmk=").append((pmk == null) ? "<null>" : "<non-null>")
-                // masking PII
-                .append(", passphrase=").append((passphrase == null) ? "<null>" : "<non-null>")
-                .append(", port=").append(port).append(", transportProtocol=")
-                .append(transportProtocol)
-                .append("]");
-        return sb.toString();
-    }
-
-    /**
-     * A builder class for a Wi-Fi Aware network specifier to set up an Aware connection with a
-     * peer.
-     */
-    public static final class Builder {
-        private DiscoverySession mDiscoverySession;
-        private PeerHandle mPeerHandle;
-        private String mPskPassphrase;
-        private byte[] mPmk;
-        private int mPort = 0; // invalid value
-        private int mTransportProtocol = -1; // invalid value
-
-        /**
-         * Create a builder for {@link WifiAwareNetworkSpecifier} used in requests to set up a
-         * Wi-Fi Aware connection with a peer.
-         *
-         * @param discoverySession A Wi-Fi Aware discovery session in whose context the connection
-         *                         is created.
-         * @param peerHandle The handle of the peer to which the Wi-Fi Aware connection is
-         *                   requested. The peer is discovered through Wi-Fi Aware discovery. The
-         *                   handle can be obtained through
-         * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle, byte[], java.util.List)}
-         *                   or
-         *                   {@link DiscoverySessionCallback#onMessageReceived(PeerHandle, byte[])}.
-         */
-        public Builder(@NonNull DiscoverySession discoverySession, @NonNull PeerHandle peerHandle) {
-            if (discoverySession == null) {
-                throw new IllegalArgumentException("Non-null discoverySession required");
-            }
-            if (peerHandle == null) {
-                throw new IllegalArgumentException("Non-null peerHandle required");
-            }
-            mDiscoverySession = discoverySession;
-            mPeerHandle = peerHandle;
-        }
-
-        /**
-         * Configure the PSK Passphrase for the Wi-Fi Aware connection being requested. This method
-         * is optional - if not called, then an Open (unencrypted) connection will be created.
-         *
-         * @param pskPassphrase The (optional) passphrase to be used to encrypt the link. Use the
-         *                      {@link #setPmk(byte[])} to specify a PMK.
-         * @return the current {@link Builder} builder, enabling chaining of builder
-         *         methods.
-         */
-        public @NonNull Builder setPskPassphrase(@NonNull String pskPassphrase) {
-            if (!WifiAwareUtils.validatePassphrase(pskPassphrase)) {
-                throw new IllegalArgumentException("Passphrase must meet length requirements");
-            }
-            mPskPassphrase = pskPassphrase;
-            return this;
-        }
-
-        /**
-         * Configure the PMK for the Wi-Fi Aware connection being requested. This method
-         * is optional - if not called, then an Open (unencrypted) connection will be created.
-         *
-         * @param pmk A PMK (pairwise master key, see IEEE 802.11i) specifying the key to use for
-         *            encrypting the data-path. Use the {@link #setPskPassphrase(String)} to
-         *            specify a Passphrase.
-         * @return the current {@link Builder} builder, enabling chaining of builder
-         *         methods.
-         */
-        public @NonNull Builder setPmk(@NonNull byte[] pmk) {
-            if (!WifiAwareUtils.validatePmk(pmk)) {
-                throw new IllegalArgumentException("PMK must 32 bytes");
-            }
-            mPmk = pmk;
-            return this;
-        }
-
-        /**
-         * Configure the port number which will be used to create a connection over this link. This
-         * configuration should only be done on the server device, e.g. the device creating the
-         * {@link java.net.ServerSocket}.
-         * <p>Notes:
-         * <ul>
-         *     <li>The server device must be the Publisher device!
-         *     <li>The port information can only be specified on secure links, specified using
-         *     {@link #setPskPassphrase(String)} or {@link #setPmk(byte[])}.
-         * </ul>
-         *
-         * @param port A positive integer indicating the port to be used for communication.
-         * @return the current {@link Builder} builder, enabling chaining of builder
-         *         methods.
-         */
-        public @NonNull Builder setPort(@IntRange(from = 0, to = 65535) int port) {
-            if (port <= 0 || port > 65535) {
-                throw new IllegalArgumentException("The port must be a positive value (0, 65535]");
-            }
-            mPort = port;
-            return this;
-        }
-
-        /**
-         * Configure the transport protocol which will be used to create a connection over this
-         * link. This configuration should only be done on the server device, e.g. the device
-         * creating the {@link java.net.ServerSocket} for TCP.
-         * <p>Notes:
-         * <ul>
-         *     <li>The server device must be the Publisher device!
-         *     <li>The transport protocol information can only be specified on secure links,
-         *     specified using {@link #setPskPassphrase(String)} or {@link #setPmk(byte[])}.
-         * </ul>
-         * The transport protocol number is assigned by the Internet Assigned Numbers Authority
-         * (IANA) https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml.
-         *
-         * @param transportProtocol The transport protocol to be used for communication.
-         * @return the current {@link Builder} builder, enabling chaining of builder
-         *         methods.
-         */
-        public @NonNull
-                Builder setTransportProtocol(@IntRange(from = 0, to = 255) int transportProtocol) {
-            if (transportProtocol < 0 || transportProtocol > 255) {
-                throw new IllegalArgumentException(
-                        "The transport protocol must be in range [0, 255]");
-            }
-            mTransportProtocol = transportProtocol;
-            return this;
-        }
-
-        /**
-         * Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)}
-         * for a WiFi Aware connection (link) to the specified peer. The
-         * {@link android.net.NetworkRequest.Builder#addTransportType(int)} should be set to
-         * {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}.
-         * <p> The default builder constructor will initialize a NetworkSpecifier which requests an
-         * open (non-encrypted) link. To request an encrypted link use the
-         * {@link #setPskPassphrase(String)} or {@link #setPmk(byte[])} builder methods.
-         *
-         * @return A {@link NetworkSpecifier} to be used to construct
-         * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} to pass
-         * to {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest,
-         * android.net.ConnectivityManager.NetworkCallback)}
-         * [or other varieties of that API].
-         */
-        public @NonNull WifiAwareNetworkSpecifier build() {
-            if (mDiscoverySession == null) {
-                throw new IllegalStateException("Null discovery session!?");
-            }
-            if (mPeerHandle == null) {
-                throw new IllegalStateException("Null peerHandle!?");
-            }
-            if (mPskPassphrase != null & mPmk != null) {
-                throw new IllegalStateException(
-                        "Can only specify a Passphrase or a PMK - not both!");
-            }
-
-            int role = mDiscoverySession instanceof SubscribeDiscoverySession
-                    ? WIFI_AWARE_DATA_PATH_ROLE_INITIATOR
-                    : WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER;
-
-            if (mPort != 0 || mTransportProtocol != -1) {
-                if (role != WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER) {
-                    throw new IllegalStateException(
-                            "Port and transport protocol information can only "
-                                    + "be specified on the Publisher device (which is the server");
-                }
-                if (TextUtils.isEmpty(mPskPassphrase) && mPmk == null) {
-                    throw new IllegalStateException("Port and transport protocol information can "
-                            + "only be specified on a secure link");
-                }
-            }
-
-            return new WifiAwareNetworkSpecifier(
-                    WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_IB, role,
-                    mDiscoverySession.mClientId, mDiscoverySession.mSessionId, mPeerHandle.peerId,
-                    null, mPmk, mPskPassphrase, mPort, mTransportProtocol);
-        }
-    }
-}
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareSession.java b/wifi/java/android/net/wifi/aware/WifiAwareSession.java
deleted file mode 100644
index fe0872c..0000000
--- a/wifi/java/android/net/wifi/aware/WifiAwareSession.java
+++ /dev/null
@@ -1,343 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.aware;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.net.NetworkSpecifier;
-import android.os.Binder;
-import android.os.Handler;
-import android.os.Looper;
-import android.util.CloseGuard;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.lang.ref.Reference;
-import java.lang.ref.WeakReference;
-
-/**
- * This class represents a Wi-Fi Aware session - an attachment to the Wi-Fi Aware service through
- * which the app can execute discovery operations.
- */
-public class WifiAwareSession implements AutoCloseable {
-    private static final String TAG = "WifiAwareSession";
-    private static final boolean DBG = false;
-    private static final boolean VDBG = false; // STOPSHIP if true
-
-    private final WeakReference<WifiAwareManager> mMgr;
-    private final Binder mBinder;
-    private final int mClientId;
-
-    private boolean mTerminated = true;
-    private final CloseGuard mCloseGuard = new CloseGuard();
-
-    /** @hide */
-    public WifiAwareSession(WifiAwareManager manager, Binder binder, int clientId) {
-        if (VDBG) Log.v(TAG, "New session created: manager=" + manager + ", clientId=" + clientId);
-
-        mMgr = new WeakReference<>(manager);
-        mBinder = binder;
-        mClientId = clientId;
-        mTerminated = false;
-
-        mCloseGuard.open("close");
-    }
-
-    /**
-     * Destroy the Wi-Fi Aware service session and, if no other applications are attached to Aware,
-     * also disable Aware. This method destroys all outstanding operations - i.e. all publish and
-     * subscribes are terminated, and any outstanding data-links are shut-down. However, it is
-     * good practice to destroy these discovery sessions and connections explicitly before a
-     * session-wide destroy.
-     * <p>
-     * An application may re-attach after a destroy using
-     * {@link WifiAwareManager#attach(AttachCallback, Handler)} .
-     */
-    @Override
-    public void close() {
-        WifiAwareManager mgr = mMgr.get();
-        if (mgr == null) {
-            Log.w(TAG, "destroy: called post GC on WifiAwareManager");
-            return;
-        }
-        mgr.disconnect(mClientId, mBinder);
-        mTerminated = true;
-        mMgr.clear();
-        mCloseGuard.close();
-        Reference.reachabilityFence(this);
-    }
-
-    /** @hide */
-    @Override
-    protected void finalize() throws Throwable {
-        try {
-            if (mCloseGuard != null) {
-                mCloseGuard.warnIfOpen();
-            }
-
-            if (!mTerminated) {
-                close();
-            }
-        } finally {
-            super.finalize();
-        }
-    }
-
-    /**
-     * Access the client ID of the Aware session.
-     *
-     * Note: internal visibility for testing.
-     *
-     * @return The internal client ID.
-     *
-     * @hide
-     */
-    @VisibleForTesting
-    public int getClientId() {
-        return mClientId;
-    }
-
-    /**
-     * Issue a request to the Aware service to create a new Aware publish discovery session, using
-     * the specified {@code publishConfig} configuration. The results of the publish operation
-     * are routed to the callbacks of {@link DiscoverySessionCallback}:
-     * <ul>
-     *     <li>
-     *     {@link DiscoverySessionCallback#onPublishStarted(
-     *PublishDiscoverySession)}
-     *     is called when the publish session is created and provides a handle to the session.
-     *     Further operations on the publish session can be executed on that object.
-     *     <li>{@link DiscoverySessionCallback#onSessionConfigFailed()} is called if the
-     *     publish operation failed.
-     * </ul>
-     * <p>
-     * Other results of the publish session operations will also be routed to callbacks
-     * on the {@code callback} object. The resulting publish session can be modified using
-     * {@link PublishDiscoverySession#updatePublish(PublishConfig)}.
-     * <p>
-     *      An application must use the {@link DiscoverySession#close()} to
-     *      terminate the publish discovery session once it isn't needed. This will free
-     *      resources as well terminate any on-air transmissions.
-     * <p>The application must have the {@link android.Manifest.permission#ACCESS_FINE_LOCATION}
-     * permission to start a publish discovery session.
-     *
-     * @param publishConfig The {@link PublishConfig} specifying the
-     *            configuration of the requested publish session.
-     * @param callback A {@link DiscoverySessionCallback} derived object to be used for
-     *                 session event callbacks.
-     * @param handler The Handler on whose thread to execute the callbacks of the {@code
-     * callback} object. If a null is provided then the application's main thread will be used.
-     */
-    public void publish(@NonNull PublishConfig publishConfig,
-            @NonNull DiscoverySessionCallback callback, @Nullable Handler handler) {
-        WifiAwareManager mgr = mMgr.get();
-        if (mgr == null) {
-            Log.e(TAG, "publish: called post GC on WifiAwareManager");
-            return;
-        }
-        if (mTerminated) {
-            Log.e(TAG, "publish: called after termination");
-            return;
-        }
-        mgr.publish(mClientId, (handler == null) ? Looper.getMainLooper() : handler.getLooper(),
-                publishConfig, callback);
-    }
-
-    /**
-     * Issue a request to the Aware service to create a new Aware subscribe discovery session, using
-     * the specified {@code subscribeConfig} configuration. The results of the subscribe
-     * operation are routed to the callbacks of {@link DiscoverySessionCallback}:
-     * <ul>
-     *     <li>
-     *  {@link DiscoverySessionCallback#onSubscribeStarted(
-     *SubscribeDiscoverySession)}
-     *     is called when the subscribe session is created and provides a handle to the session.
-     *     Further operations on the subscribe session can be executed on that object.
-     *     <li>{@link DiscoverySessionCallback#onSessionConfigFailed()} is called if the
-     *     subscribe operation failed.
-     * </ul>
-     * <p>
-     * Other results of the subscribe session operations will also be routed to callbacks
-     * on the {@code callback} object. The resulting subscribe session can be modified using
-     * {@link SubscribeDiscoverySession#updateSubscribe(SubscribeConfig)}.
-     * <p>
-     *      An application must use the {@link DiscoverySession#close()} to
-     *      terminate the subscribe discovery session once it isn't needed. This will free
-     *      resources as well terminate any on-air transmissions.
-     * <p>The application must have the {@link android.Manifest.permission#ACCESS_FINE_LOCATION}
-     * permission to start a subscribe discovery session.
-     *
-     * @param subscribeConfig The {@link SubscribeConfig} specifying the
-     *            configuration of the requested subscribe session.
-     * @param callback A {@link DiscoverySessionCallback} derived object to be used for
-     *                 session event callbacks.
-     * @param handler The Handler on whose thread to execute the callbacks of the {@code
-     * callback} object. If a null is provided then the application's main thread will be used.
-     */
-    public void subscribe(@NonNull SubscribeConfig subscribeConfig,
-            @NonNull DiscoverySessionCallback callback, @Nullable Handler handler) {
-        WifiAwareManager mgr = mMgr.get();
-        if (mgr == null) {
-            Log.e(TAG, "publish: called post GC on WifiAwareManager");
-            return;
-        }
-        if (mTerminated) {
-            Log.e(TAG, "publish: called after termination");
-            return;
-        }
-        mgr.subscribe(mClientId, (handler == null) ? Looper.getMainLooper() : handler.getLooper(),
-                subscribeConfig, callback);
-    }
-
-    /**
-     * Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} for
-     * an unencrypted WiFi Aware connection (link) to the specified peer. The
-     * {@link android.net.NetworkRequest.Builder#addTransportType(int)} should be set to
-     * {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}.
-     * <p>
-     *     This API is targeted for applications which can obtain the peer MAC address using OOB
-     *     (out-of-band) discovery. Aware discovery does not provide the MAC address of the peer -
-     *     when using Aware discovery use the alternative network specifier method -
-     *     {@link android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder}.
-     * <p>
-     * To set up an encrypted link use the
-     * {@link #createNetworkSpecifierPassphrase(int, byte[], String)} API.
-     *
-     * @param role  The role of this device:
-     *              {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_INITIATOR} or
-     *              {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_RESPONDER}
-     * @param peer  The MAC address of the peer's Aware discovery interface. On a RESPONDER this
-     *              value is used to gate the acceptance of a connection request from only that
-     *              peer.
-     *
-     * @return A {@link NetworkSpecifier} to be used to construct
-     * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} to pass to
-     * {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest,
-     * android.net.ConnectivityManager.NetworkCallback)}
-     * [or other varieties of that API].
-     */
-    public NetworkSpecifier createNetworkSpecifierOpen(
-            @WifiAwareManager.DataPathRole int role, @NonNull byte[] peer) {
-        WifiAwareManager mgr = mMgr.get();
-        if (mgr == null) {
-            Log.e(TAG, "createNetworkSpecifierOpen: called post GC on WifiAwareManager");
-            return null;
-        }
-        if (mTerminated) {
-            Log.e(TAG, "createNetworkSpecifierOpen: called after termination");
-            return null;
-        }
-        return mgr.createNetworkSpecifier(mClientId, role, peer, null, null);
-    }
-
-    /**
-     * Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} for
-     * an encrypted WiFi Aware connection (link) to the specified peer. The
-     * {@link android.net.NetworkRequest.Builder#addTransportType(int)} should be set to
-     * {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}.
-     * <p>
-     *     This API is targeted for applications which can obtain the peer MAC address using OOB
-     *     (out-of-band) discovery. Aware discovery does not provide the MAC address of the peer -
-     *     when using Aware discovery use the alternative network specifier method -
-     *     {@link android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder}.
-     *
-     * @param role  The role of this device:
-     *              {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_INITIATOR} or
-     *              {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_RESPONDER}
-     * @param peer  The MAC address of the peer's Aware discovery interface. On a RESPONDER this
-     *              value is used to gate the acceptance of a connection request from only that
-     *              peer.
-     * @param passphrase The passphrase to be used to encrypt the link. The PMK is generated from
-     *                   the passphrase. Use {@link #createNetworkSpecifierOpen(int, byte[])} to
-     *                   specify an open (unencrypted) link.
-     *
-     * @return A {@link NetworkSpecifier} to be used to construct
-     * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} to pass to
-     * {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest,
-     * android.net.ConnectivityManager.NetworkCallback)}
-     * [or other varieties of that API].
-     */
-    public NetworkSpecifier createNetworkSpecifierPassphrase(
-            @WifiAwareManager.DataPathRole int role, @NonNull byte[] peer,
-            @NonNull String passphrase) {
-        WifiAwareManager mgr = mMgr.get();
-        if (mgr == null) {
-            Log.e(TAG, "createNetworkSpecifierPassphrase: called post GC on WifiAwareManager");
-            return null;
-        }
-        if (mTerminated) {
-            Log.e(TAG, "createNetworkSpecifierPassphrase: called after termination");
-            return null;
-        }
-        if (!WifiAwareUtils.validatePassphrase(passphrase)) {
-            throw new IllegalArgumentException("Passphrase must meet length requirements");
-        }
-
-        return mgr.createNetworkSpecifier(mClientId, role, peer, null, passphrase);
-    }
-
-    /**
-     * Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} for
-     * an encrypted WiFi Aware connection (link) to the specified peer. The
-     * {@link android.net.NetworkRequest.Builder#addTransportType(int)} should be set to
-     * {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}.
-     * <p>
-     *     This API is targeted for applications which can obtain the peer MAC address using OOB
-     *     (out-of-band) discovery. Aware discovery does not provide the MAC address of the peer -
-     *     when using Aware discovery use the alternative network specifier method -
-     *     {@link android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder}.
-     *
-     * @param role  The role of this device:
-     *              {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_INITIATOR} or
-     *              {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_RESPONDER}
-     * @param peer  The MAC address of the peer's Aware discovery interface. On a RESPONDER this
-     *              value is used to gate the acceptance of a connection request from only that
-     *              peer.
-     * @param pmk A PMK (pairwise master key, see IEEE 802.11i) specifying the key to use for
-     *            encrypting the data-path. Use the
-     *            {@link #createNetworkSpecifierPassphrase(int, byte[], String)} to specify a
-     *            Passphrase or {@link #createNetworkSpecifierOpen(int, byte[])} to specify an
-     *            open (unencrypted) link.
-     *
-     * @return A {@link NetworkSpecifier} to be used to construct
-     * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} to pass to
-     * {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest,
-     * android.net.ConnectivityManager.NetworkCallback)}
-     * [or other varieties of that API].
-     *
-     * @hide
-     */
-    @SystemApi
-    public NetworkSpecifier createNetworkSpecifierPmk(
-            @WifiAwareManager.DataPathRole int role, @NonNull byte[] peer, @NonNull byte[] pmk) {
-        WifiAwareManager mgr = mMgr.get();
-        if (mgr == null) {
-            Log.e(TAG, "createNetworkSpecifierPmk: called post GC on WifiAwareManager");
-            return null;
-        }
-        if (mTerminated) {
-            Log.e(TAG, "createNetworkSpecifierPmk: called after termination");
-            return null;
-        }
-        if (!WifiAwareUtils.validatePmk(pmk)) {
-            throw new IllegalArgumentException("PMK must 32 bytes");
-        }
-        return mgr.createNetworkSpecifier(mClientId, role, peer, pmk, null);
-    }
-}
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareUtils.java b/wifi/java/android/net/wifi/aware/WifiAwareUtils.java
deleted file mode 100644
index 3ece93df..0000000
--- a/wifi/java/android/net/wifi/aware/WifiAwareUtils.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.aware;
-
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.hardware.wifi.V1_0.Constants;
-
-/**
- * Provides utilities for the Wifi Aware manager/service.
- *
- * @hide
- */
-public class WifiAwareUtils {
-    /**
-     * Per spec: The Service Name is a UTF-8 encoded string from 1 to 255 bytes in length. The
-     * only acceptable single-byte UTF-8 symbols for a Service Name are alphanumeric values (A-Z,
-     * a-z, 0-9), the hyphen ('-'), and the period ('.'). All valid multi-byte UTF-8 characters
-     * are acceptable in a Service Name.
-     */
-    public static void validateServiceName(byte[] serviceNameData) throws IllegalArgumentException {
-        if (serviceNameData == null) {
-            throw new IllegalArgumentException("Invalid service name - null");
-        }
-
-        if (serviceNameData.length < 1 || serviceNameData.length > 255) {
-            throw new IllegalArgumentException("Invalid service name length - must be between "
-                    + "1 and 255 bytes (UTF-8 encoding)");
-        }
-
-        int index = 0;
-        while (index < serviceNameData.length) {
-            byte b = serviceNameData[index];
-            if ((b & 0x80) == 0x00) {
-                if (!((b >= '0' && b <= '9') || (b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z')
-                        || b == '-' || b == '.')) {
-                    throw new IllegalArgumentException("Invalid service name - illegal characters,"
-                            + " allowed = (0-9, a-z,A-Z, -, .)");
-                }
-            }
-            ++index;
-        }
-    }
-
-    /**
-     * Validates that the passphrase is a non-null string of the right size (per the HAL min/max
-     * length parameters).
-     *
-     * @param passphrase Passphrase to test
-     * @return true if passphrase is valid, false if not
-     */
-    public static boolean validatePassphrase(String passphrase) {
-        if (passphrase == null
-                || passphrase.length() < Constants.NanParamSizeLimits.MIN_PASSPHRASE_LENGTH
-                || passphrase.length() > Constants.NanParamSizeLimits.MAX_PASSPHRASE_LENGTH) {
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Validates that the PMK is a non-null byte array of the right size (32 bytes per spec).
-     *
-     * @param pmk PMK to test
-     * @return true if PMK is valid, false if not
-     */
-    public static boolean validatePmk(byte[] pmk) {
-        if (pmk == null || pmk.length != 32) {
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Returns true if the App version is older than minVersion.
-     */
-    public static boolean isLegacyVersion(Context context, int minVersion) {
-        try {
-            if (context.getPackageManager().getApplicationInfo(context.getOpPackageName(), 0)
-                    .targetSdkVersion < minVersion) {
-                return true;
-            }
-        } catch (PackageManager.NameNotFoundException e) {
-            // In case of exception, assume known app (more strict checking)
-            // Note: This case will never happen since checkPackage is
-            // called to verify valididity before checking App's version.
-        }
-        return false;
-    }
-}
diff --git a/wifi/java/android/net/wifi/aware/package.html b/wifi/java/android/net/wifi/aware/package.html
deleted file mode 100644
index c4f2e1f..0000000
--- a/wifi/java/android/net/wifi/aware/package.html
+++ /dev/null
@@ -1,43 +0,0 @@
-<HTML>
-<BODY>
-<p>Provides classes which allow applications to use Wi-Fi Aware to discover peers and create
-    connections to them.</p>
-<p>Using the Wi-Fi Aware APIs, applications can advertise services, discover peers which are
-    advertising services, and connect to them.
-    Wi-Fi Aware is independent of Wi-Fi infrastructure (i.e. a device may or may
-    not be associated with an AP concurrent to using Wi-Fi Aware). </p>
-<p>The primary entry point to Wi-Fi Aware capabilities is the
-    {@link android.net.wifi.aware.WifiAwareManager} class, which is acquired by calling
-    {@link android.content.Context#getSystemService(String)
-    Context.getSystemService(Context.WIFI_AWARE_SERVICE)}</p>
-
-<p>Some APIs may require the following user permissions:</p>
-<ul>
-    <li>{@link android.Manifest.permission#ACCESS_WIFI_STATE}</li>
-    <li>{@link android.Manifest.permission#CHANGE_WIFI_STATE}</li>
-    <li>{@link android.Manifest.permission#ACCESS_FINE_LOCATION}</li>
-</ul>
-
-<p class="note"><strong>Note:</strong> Not all Android-powered devices support Wi-Fi Aware
-    functionality.
-    If your application only works with Wi-Fi Aware (i.e. it should only be installed on devices which
-    support Wi-Fi Aware), declare so with a <a
-            href="{@docRoot}guide/topics/manifest/uses-feature-element.html">
-        {@code <uses-feature>}</a>
-    element in the manifest file:</p>
-<pre>
-&lt;manifest ...>
-    &lt;uses-feature android:name="android.hardware.wifi.aware" />
-    ...
-&lt;/manifest>
-</pre>
-<p>Alternatively, if you application does not require Wi-Fi Aware but can take advantage of it if
-    available, you can perform
-    the check at run-time in your code using {@link
-    android.content.pm.PackageManager#hasSystemFeature(String)} with {@link
-    android.content.pm.PackageManager#FEATURE_WIFI_AWARE}:</p>
-<pre>
-    getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_AWARE)
-</pre>
-</BODY>
-</HTML>
diff --git a/wifi/java/android/net/wifi/hotspot2/ConfigParser.java b/wifi/java/android/net/wifi/hotspot2/ConfigParser.java
deleted file mode 100644
index bb01365..0000000
--- a/wifi/java/android/net/wifi/hotspot2/ConfigParser.java
+++ /dev/null
@@ -1,486 +0,0 @@
-/**
- * Copyright (c) 2016, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.hotspot2;
-
-import android.net.wifi.hotspot2.omadm.PpsMoParser;
-import android.text.TextUtils;
-import android.util.Base64;
-import android.util.Log;
-import android.util.Pair;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.LineNumberReader;
-import java.nio.charset.StandardCharsets;
-import java.security.GeneralSecurityException;
-import java.security.KeyStore;
-import java.security.PrivateKey;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Utility class for building PasspointConfiguration from an installation file.
- */
-public final class ConfigParser {
-    private static final String TAG = "ConfigParser";
-
-    // Header names.
-    private static final String CONTENT_TYPE = "Content-Type";
-    private static final String CONTENT_TRANSFER_ENCODING = "Content-Transfer-Encoding";
-
-    // MIME types.
-    private static final String TYPE_MULTIPART_MIXED = "multipart/mixed";
-    private static final String TYPE_WIFI_CONFIG = "application/x-wifi-config";
-    private static final String TYPE_PASSPOINT_PROFILE = "application/x-passpoint-profile";
-    private static final String TYPE_CA_CERT = "application/x-x509-ca-cert";
-    private static final String TYPE_PKCS12 = "application/x-pkcs12";
-
-    private static final String ENCODING_BASE64 = "base64";
-    private static final String BOUNDARY = "boundary=";
-
-    /**
-     * Class represent a MIME (Multipurpose Internet Mail Extension) part.
-     */
-    private static class MimePart {
-        /**
-         * Content type of the part.
-         */
-        public String type = null;
-
-        /**
-         * Decoded data.
-         */
-        public byte[] data = null;
-
-        /**
-         * Flag indicating if this is the last part (ending with --{boundary}--).
-         */
-        public boolean isLast = false;
-    }
-
-    /**
-     * Class represent the MIME (Multipurpose Internet Mail Extension) header.
-     */
-    private static class MimeHeader {
-        /**
-         * Content type.
-         */
-        public String contentType = null;
-
-        /**
-         * Boundary string (optional), only applies for the outter MIME header.
-         */
-        public String boundary = null;
-
-        /**
-         * Encoding type.
-         */
-        public String encodingType = null;
-    }
-
-    /**
-     * @hide
-     */
-    public ConfigParser() {}
-
-    /**
-     * Parse the Hotspot 2.0 Release 1 configuration data into a {@link PasspointConfiguration}
-     * object.  The configuration data is a base64 encoded MIME multipart data.  Below is
-     * the format of the decoded message:
-     *
-     * Content-Type: multipart/mixed; boundary={boundary}
-     * Content-Transfer-Encoding: base64
-     * [Skip uninterested headers]
-     *
-     * --{boundary}
-     * Content-Type: application/x-passpoint-profile
-     * Content-Transfer-Encoding: base64
-     *
-     * [base64 encoded Passpoint profile data]
-     * --{boundary}
-     * Content-Type: application/x-x509-ca-cert
-     * Content-Transfer-Encoding: base64
-     *
-     * [base64 encoded X509 CA certificate data]
-     * --{boundary}
-     * Content-Type: application/x-pkcs12
-     * Content-Transfer-Encoding: base64
-     *
-     * [base64 encoded PKCS#12 ASN.1 structure containing client certificate chain]
-     * --{boundary}
-     *
-     * @param mimeType MIME type of the encoded data.
-     * @param data A base64 encoded MIME multipart message containing the Passpoint profile
-     *             (required), CA (Certificate Authority) certificate (optional), and client
-     *             certificate chain (optional).
-     * @return {@link PasspointConfiguration}
-     */
-    public static PasspointConfiguration parsePasspointConfig(String mimeType, byte[] data) {
-        // Verify MIME type.
-        if (!TextUtils.equals(mimeType, TYPE_WIFI_CONFIG)) {
-            Log.e(TAG, "Unexpected MIME type: " + mimeType);
-            return null;
-        }
-
-        try {
-            // Decode the data.
-            byte[] decodedData = Base64.decode(new String(data, StandardCharsets.ISO_8859_1),
-                    Base64.DEFAULT);
-            Map<String, byte[]> mimeParts = parseMimeMultipartMessage(new LineNumberReader(
-                    new InputStreamReader(new ByteArrayInputStream(decodedData),
-                            StandardCharsets.ISO_8859_1)));
-            return createPasspointConfig(mimeParts);
-        } catch (IOException | IllegalArgumentException e) {
-            Log.e(TAG, "Failed to parse installation file: " + e.getMessage());
-            return null;
-        }
-    }
-
-    /**
-     * Create a {@link PasspointConfiguration} object from list of MIME (Multipurpose Internet
-     * Mail Extension) parts.
-     *
-     * @param mimeParts Map of content type and content data.
-     * @return {@link PasspointConfiguration}
-     * @throws IOException
-     */
-    private static PasspointConfiguration createPasspointConfig(Map<String, byte[]> mimeParts)
-            throws IOException {
-        byte[] profileData = mimeParts.get(TYPE_PASSPOINT_PROFILE);
-        if (profileData == null) {
-            throw new IOException("Missing Passpoint Profile");
-        }
-
-        PasspointConfiguration config = PpsMoParser.parseMoText(new String(profileData));
-        if (config == null) {
-            throw new IOException("Failed to parse Passpoint profile");
-        }
-
-        // Credential is needed for storing the certificates and private client key.
-        if (config.getCredential() == null) {
-            throw new IOException("Passpoint profile missing credential");
-        }
-
-        // Don't allow the installer to make changes to the update identifier. This is an
-        // indicator of an R2 (or newer) network.
-        if (config.getUpdateIdentifier() != Integer.MIN_VALUE) {
-            config.setUpdateIdentifier(Integer.MIN_VALUE);
-        }
-
-        // Parse CA (Certificate Authority) certificate.
-        byte[] caCertData = mimeParts.get(TYPE_CA_CERT);
-        if (caCertData != null) {
-            try {
-                config.getCredential().setCaCertificate(parseCACert(caCertData));
-            } catch (CertificateException e) {
-                throw new IOException("Failed to parse CA Certificate");
-            }
-        }
-
-        // Parse PKCS12 data for client private key and certificate chain.
-        byte[] pkcs12Data = mimeParts.get(TYPE_PKCS12);
-        if (pkcs12Data != null) {
-            try {
-                Pair<PrivateKey, List<X509Certificate>> clientKey = parsePkcs12(pkcs12Data);
-                config.getCredential().setClientPrivateKey(clientKey.first);
-                config.getCredential().setClientCertificateChain(
-                        clientKey.second.toArray(new X509Certificate[clientKey.second.size()]));
-            } catch(GeneralSecurityException | IOException e) {
-                throw new IOException("Failed to parse PCKS12 string");
-            }
-        }
-        return config;
-    }
-
-    /**
-     * Parse a MIME (Multipurpose Internet Mail Extension) multipart message from the given
-     * input stream.
-     *
-     * @param in The input stream for reading the message data
-     * @return A map of a content type and content data pair
-     * @throws IOException
-     */
-    private static Map<String, byte[]> parseMimeMultipartMessage(LineNumberReader in)
-            throws IOException {
-        // Parse the outer MIME header.
-        MimeHeader header = parseHeaders(in);
-        if (!TextUtils.equals(header.contentType, TYPE_MULTIPART_MIXED)) {
-            throw new IOException("Invalid content type: " + header.contentType);
-        }
-        if (TextUtils.isEmpty(header.boundary)) {
-            throw new IOException("Missing boundary string");
-        }
-        if (!TextUtils.equals(header.encodingType, ENCODING_BASE64)) {
-            throw new IOException("Unexpected encoding: " + header.encodingType);
-        }
-
-        // Read pass the first boundary string.
-        for (;;) {
-            String line = in.readLine();
-            if (line == null) {
-                throw new IOException("Unexpected EOF before first boundary @ " +
-                        in.getLineNumber());
-            }
-            if (line.equals("--" + header.boundary)) {
-                break;
-            }
-        }
-
-        // Parse each MIME part.
-        Map<String, byte[]> mimeParts = new HashMap<>();
-        boolean isLast = false;
-        do {
-            MimePart mimePart = parseMimePart(in, header.boundary);
-            mimeParts.put(mimePart.type, mimePart.data);
-            isLast = mimePart.isLast;
-        } while(!isLast);
-        return mimeParts;
-    }
-
-    /**
-     * Parse a MIME (Multipurpose Internet Mail Extension) part.  We expect the data to
-     * be encoded in base64.
-     *
-     * @param in Input stream to read the data from
-     * @param boundary Boundary string indicate the end of the part
-     * @return {@link MimePart}
-     * @throws IOException
-     */
-    private static MimePart parseMimePart(LineNumberReader in, String boundary)
-            throws IOException {
-        MimeHeader header = parseHeaders(in);
-        // Expect encoding type to be base64.
-        if (!TextUtils.equals(header.encodingType, ENCODING_BASE64)) {
-            throw new IOException("Unexpected encoding type: " + header.encodingType);
-        }
-
-        // Check for a valid content type.
-        if (!TextUtils.equals(header.contentType, TYPE_PASSPOINT_PROFILE) &&
-                !TextUtils.equals(header.contentType, TYPE_CA_CERT) &&
-                !TextUtils.equals(header.contentType, TYPE_PKCS12)) {
-            throw new IOException("Unexpected content type: " + header.contentType);
-        }
-
-        StringBuilder text = new StringBuilder();
-        boolean isLast = false;
-        String partBoundary = "--" + boundary;
-        String endBoundary = partBoundary + "--";
-        for (;;) {
-            String line = in.readLine();
-            if (line == null) {
-                throw new IOException("Unexpected EOF file in body @ " + in.getLineNumber());
-            }
-            // Check for boundary line.
-            if (line.startsWith(partBoundary)) {
-                if (line.equals(endBoundary)) {
-                    isLast = true;
-                }
-                break;
-            }
-            text.append(line);
-        }
-
-        MimePart part = new MimePart();
-        part.type = header.contentType;
-        part.data = Base64.decode(text.toString(), Base64.DEFAULT);
-        part.isLast = isLast;
-        return part;
-    }
-
-    /**
-     * Parse a MIME (Multipurpose Internet Mail Extension) header from the input stream.
-     * @param in Input stream to read from.
-     * @return {@link MimeHeader}
-     * @throws IOException
-     */
-    private static MimeHeader parseHeaders(LineNumberReader in)
-            throws IOException {
-        MimeHeader header = new MimeHeader();
-
-        // Read the header from the input stream.
-        Map<String, String> headers = readHeaders(in);
-
-        // Parse each header.
-        for (Map.Entry<String, String> entry : headers.entrySet()) {
-            switch (entry.getKey()) {
-                case CONTENT_TYPE:
-                    Pair<String, String> value = parseContentType(entry.getValue());
-                    header.contentType = value.first;
-                    header.boundary = value.second;
-                    break;
-                case CONTENT_TRANSFER_ENCODING:
-                    header.encodingType = entry.getValue();
-                    break;
-                default:
-                    Log.d(TAG, "Ignore header: " + entry.getKey());
-                    break;
-            }
-        }
-        return header;
-    }
-
-    /**
-     * Parse the Content-Type header value.  The value will contain the content type string and
-     * an optional boundary string separated by a ";".  Below are examples of valid Content-Type
-     * header value:
-     *   multipart/mixed; boundary={boundary}
-     *   application/x-passpoint-profile
-     *
-     * @param contentType The Content-Type value string
-     * @return A pair of content type and boundary string
-     * @throws IOException
-     */
-    private static Pair<String, String> parseContentType(String contentType) throws IOException {
-        String[] attributes = contentType.split(";");
-        String type = null;
-        String boundary = null;
-
-        if (attributes.length < 1) {
-            throw new IOException("Invalid Content-Type: " + contentType);
-        }
-
-        // The type is always the first attribute.
-        type = attributes[0].trim();
-        // Look for boundary string from the rest of the attributes.
-        for (int i = 1; i < attributes.length; i++) {
-            String attribute = attributes[i].trim();
-            if (!attribute.startsWith(BOUNDARY)) {
-                Log.d(TAG, "Ignore Content-Type attribute: " + attributes[i]);
-                continue;
-            }
-            boundary = attribute.substring(BOUNDARY.length());
-            // Remove the leading and trailing quote if present.
-            if (boundary.length() > 1 && boundary.startsWith("\"") && boundary.endsWith("\"")) {
-                boundary = boundary.substring(1, boundary.length()-1);
-            }
-        }
-
-        return new Pair<String, String>(type, boundary);
-    }
-
-    /**
-     * Read the headers from the given input stream.  The header section is terminated by
-     * an empty line.
-     *
-     * @param in The input stream to read from
-     * @return Map of key-value pairs.
-     * @throws IOException
-     */
-    private static Map<String, String> readHeaders(LineNumberReader in)
-            throws IOException {
-        Map<String, String> headers = new HashMap<>();
-        String line;
-        String name = null;
-        StringBuilder value = null;
-        for (;;) {
-            line = in.readLine();
-            if (line == null) {
-                throw new IOException("Missing line @ " + in.getLineNumber());
-            }
-
-            // End of headers section.
-            if (line.length() == 0 || line.trim().length() == 0) {
-                // Save the previous header line.
-                if (name != null) {
-                    headers.put(name, value.toString());
-                }
-                break;
-            }
-
-            int nameEnd = line.indexOf(':');
-            if (nameEnd < 0) {
-                if (value != null) {
-                    // Continuation line for the header value.
-                    value.append(' ').append(line.trim());
-                } else {
-                    throw new IOException("Bad header line: '" + line + "' @ " +
-                            in.getLineNumber());
-                }
-            } else {
-                // New header line detected, make sure it doesn't start with a whitespace.
-                if (Character.isWhitespace(line.charAt(0))) {
-                    throw new IOException("Illegal blank prefix in header line '" + line +
-                            "' @ " + in.getLineNumber());
-                }
-
-                if (name != null) {
-                    // Save the previous header line.
-                    headers.put(name, value.toString());
-                }
-
-                // Setup the current header line.
-                name = line.substring(0, nameEnd).trim();
-                value = new StringBuilder();
-                value.append(line.substring(nameEnd+1).trim());
-            }
-        }
-        return headers;
-    }
-
-    /**
-     * Parse a CA (Certificate Authority) certificate data and convert it to a
-     * X509Certificate object.
-     *
-     * @param octets Certificate data
-     * @return X509Certificate
-     * @throws CertificateException
-     */
-    private static X509Certificate parseCACert(byte[] octets) throws CertificateException {
-        CertificateFactory factory = CertificateFactory.getInstance("X.509");
-        return (X509Certificate) factory.generateCertificate(new ByteArrayInputStream(octets));
-    }
-
-    private static Pair<PrivateKey, List<X509Certificate>> parsePkcs12(byte[] octets)
-            throws GeneralSecurityException, IOException {
-        KeyStore ks = KeyStore.getInstance("PKCS12");
-        ByteArrayInputStream in = new ByteArrayInputStream(octets);
-        ks.load(in, new char[0]);
-        in.close();
-
-        // Only expects one set of key and certificate chain.
-        if (ks.size() != 1) {
-            throw new IOException("Unexpected key size: " + ks.size());
-        }
-
-        String alias = ks.aliases().nextElement();
-        if (alias == null) {
-            throw new IOException("No alias found");
-        }
-
-        PrivateKey clientKey = (PrivateKey) ks.getKey(alias, null);
-        List<X509Certificate> clientCertificateChain = null;
-        Certificate[] chain = ks.getCertificateChain(alias);
-        if (chain != null) {
-            clientCertificateChain = new ArrayList<>();
-            for (Certificate certificate : chain) {
-                if (!(certificate instanceof X509Certificate)) {
-                    throw new IOException("Unexpceted certificate type: " +
-                            certificate.getClass());
-                }
-                clientCertificateChain.add((X509Certificate) certificate);
-            }
-        }
-        return new Pair<PrivateKey, List<X509Certificate>>(clientKey, clientCertificateChain);
-    }
-}
diff --git a/wifi/java/android/net/wifi/hotspot2/IProvisioningCallback.aidl b/wifi/java/android/net/wifi/hotspot2/IProvisioningCallback.aidl
deleted file mode 100644
index a6bdd5b6..0000000
--- a/wifi/java/android/net/wifi/hotspot2/IProvisioningCallback.aidl
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.hotspot2;
-
-/**
- * Interface for Provisioning callback.
- *
- * @hide
- */
-oneway interface IProvisioningCallback
-{
-    /**
-     * Service to manager callback providing failure notification
-     */
-    void onProvisioningFailure(int status);
-
-    /**
-     * Service to manager callback providing Provisioning status
-     */
-    void onProvisioningStatus(int status);
-
-    /**
-     * Service to manager callback providing completion of Provisioning/Remediation flow
-     */
-    void onProvisioningComplete();
-}
-
diff --git a/wifi/java/android/net/wifi/hotspot2/OsuProvider.java b/wifi/java/android/net/wifi/hotspot2/OsuProvider.java
deleted file mode 100644
index f0a0607..0000000
--- a/wifi/java/android/net/wifi/hotspot2/OsuProvider.java
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package android.net.wifi.hotspot2;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.net.Uri;
-import android.net.wifi.WifiSsid;
-import android.os.Bundle;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Objects;
-
-/**
- * Contained information for a Hotspot 2.0 OSU (Online Sign-Up provider).
- *
- * @hide
- */
-@SystemApi
-public final class OsuProvider implements Parcelable {
-    /**
-     * OSU (Online Sign-Up) method: OMA DM (Open Mobile Alliance Device Management).
-     * For more info, refer to Section 8.3 of the Hotspot 2.0 Release 2 Technical Specification.
-     * @hide
-     */
-    public static final int METHOD_OMA_DM = 0;
-
-    /**
-     * OSU (Online Sign-Up) method: SOAP XML SPP (Subscription Provisioning Protocol).
-     * For more info, refer to Section 8.4 of the Hotspot 2.0 Release 2 Technical Specification.
-     * @hide
-     */
-    public static final int METHOD_SOAP_XML_SPP = 1;
-
-    /**
-     * SSID of the network to connect for service sign-up.
-     */
-    private WifiSsid mOsuSsid;
-
-    /**
-     * Map of friendly names expressed as different language for the OSU provider.
-     */
-    private final Map<String, String> mFriendlyNames;
-
-    /**
-     * Description of the OSU provider.
-     */
-    private final String mServiceDescription;
-
-    /**
-     * URI to browse to for service sign-up.
-     */
-    private final Uri mServerUri;
-
-    /**
-     * Network Access Identifier used for authenticating with the OSU network when OSEN is used.
-     */
-    private final String mNetworkAccessIdentifier;
-
-    /**
-     * List of OSU (Online Sign-Up) method supported.
-     */
-    private final List<Integer> mMethodList;
-
-    /** @hide */
-    public OsuProvider(String osuSsid, Map<String, String> friendlyNames,
-            String serviceDescription, Uri serverUri, String nai, List<Integer> methodList) {
-        this(WifiSsid.createFromByteArray(osuSsid.getBytes(StandardCharsets.UTF_8)),
-                friendlyNames, serviceDescription, serverUri, nai, methodList);
-    }
-
-    /** @hide */
-    public OsuProvider(WifiSsid osuSsid, Map<String, String> friendlyNames,
-            String serviceDescription, Uri serverUri, String nai, List<Integer> methodList) {
-        mOsuSsid = osuSsid;
-        mFriendlyNames = friendlyNames;
-        mServiceDescription = serviceDescription;
-        mServerUri = serverUri;
-        mNetworkAccessIdentifier = nai;
-        if (methodList == null) {
-            mMethodList = new ArrayList<>();
-        } else {
-            mMethodList = new ArrayList<>(methodList);
-        }
-    }
-
-    /**
-     * Copy constructor.
-     *
-     * @param source The source to copy from
-     * @hide
-     */
-    public OsuProvider(OsuProvider source) {
-        if (source == null) {
-            mOsuSsid = null;
-            mFriendlyNames = null;
-            mServiceDescription = null;
-            mServerUri = null;
-            mNetworkAccessIdentifier = null;
-            mMethodList = new ArrayList<>();
-            return;
-        }
-
-        mOsuSsid = source.mOsuSsid;
-        mFriendlyNames = source.mFriendlyNames;
-        mServiceDescription = source.mServiceDescription;
-        mServerUri = source.mServerUri;
-        mNetworkAccessIdentifier = source.mNetworkAccessIdentifier;
-        if (source.mMethodList == null) {
-            mMethodList = new ArrayList<>();
-        } else {
-            mMethodList = new ArrayList<>(source.mMethodList);
-        }
-    }
-
-    /** @hide */
-    public WifiSsid getOsuSsid() {
-        return mOsuSsid;
-    }
-
-    /** @hide */
-    public void setOsuSsid(WifiSsid osuSsid) {
-        mOsuSsid = osuSsid;
-    }
-
-    /**
-     * Return the friendly Name for current language from the list of friendly names of OSU
-     * provider.
-     *
-     * The string matching the default locale will be returned if it is found, otherwise the string
-     * in english or the first string in the list will be returned if english is not found.
-     * A null will be returned if the list is empty.
-     *
-     * @return String matching the default locale, null otherwise
-     */
-    public @Nullable String getFriendlyName() {
-        if (mFriendlyNames == null || mFriendlyNames.isEmpty()) return null;
-        String lang = Locale.getDefault().getLanguage();
-        String friendlyName = mFriendlyNames.get(lang);
-        if (friendlyName != null) {
-            return friendlyName;
-        }
-        friendlyName = mFriendlyNames.get("en");
-        if (friendlyName != null) {
-            return friendlyName;
-        }
-        return mFriendlyNames.get(mFriendlyNames.keySet().stream().findFirst().get());
-    }
-
-    /** @hide */
-    public Map<String, String> getFriendlyNameList() {
-        return mFriendlyNames;
-    }
-
-    /** @hide */
-    public String getServiceDescription() {
-        return mServiceDescription;
-    }
-
-    public @Nullable Uri getServerUri() {
-        return mServerUri;
-    }
-
-    /** @hide */
-    public String getNetworkAccessIdentifier() {
-        return mNetworkAccessIdentifier;
-    }
-
-    /** @hide */
-    public List<Integer> getMethodList() {
-        return mMethodList;
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeParcelable(mOsuSsid, flags);
-        dest.writeString(mServiceDescription);
-        dest.writeParcelable(mServerUri, flags);
-        dest.writeString(mNetworkAccessIdentifier);
-        dest.writeList(mMethodList);
-        Bundle bundle = new Bundle();
-        bundle.putSerializable("friendlyNameMap", (HashMap<String, String>) mFriendlyNames);
-        dest.writeBundle(bundle);
-    }
-
-    @Override
-    public boolean equals(@Nullable Object thatObject) {
-        if (this == thatObject) {
-            return true;
-        }
-        if (!(thatObject instanceof OsuProvider)) {
-            return false;
-        }
-        OsuProvider that = (OsuProvider) thatObject;
-        return Objects.equals(mOsuSsid, that.mOsuSsid)
-                && Objects.equals(mFriendlyNames, that.mFriendlyNames)
-                && TextUtils.equals(mServiceDescription, that.mServiceDescription)
-                && Objects.equals(mServerUri, that.mServerUri)
-                && TextUtils.equals(mNetworkAccessIdentifier, that.mNetworkAccessIdentifier)
-                && Objects.equals(mMethodList, that.mMethodList);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(mOsuSsid, mServiceDescription, mFriendlyNames,
-                mServerUri, mNetworkAccessIdentifier, mMethodList);
-    }
-
-    @NonNull
-    @Override
-    public String toString() {
-        return "OsuProvider{mOsuSsid=" + mOsuSsid
-                + " mFriendlyNames=" + mFriendlyNames
-                + " mServiceDescription=" + mServiceDescription
-                + " mServerUri=" + mServerUri
-                + " mNetworkAccessIdentifier=" + mNetworkAccessIdentifier
-                + " mMethodList=" + mMethodList;
-    }
-
-    public static final @android.annotation.NonNull Creator<OsuProvider> CREATOR =
-            new Creator<OsuProvider>() {
-                @Override
-                public OsuProvider createFromParcel(Parcel in) {
-                    WifiSsid osuSsid = in.readParcelable(null);
-                    String serviceDescription = in.readString();
-                    Uri serverUri = in.readParcelable(null);
-                    String nai = in.readString();
-                    List<Integer> methodList = new ArrayList<>();
-                    in.readList(methodList, null);
-                    Bundle bundle = in.readBundle();
-                    Map<String, String> friendlyNamesMap = (HashMap) bundle.getSerializable(
-                            "friendlyNameMap");
-                    return new OsuProvider(osuSsid, friendlyNamesMap, serviceDescription,
-                            serverUri, nai, methodList);
-                }
-
-            @Override
-            public OsuProvider[] newArray(int size) {
-                return new OsuProvider[size];
-            }
-        };
-}
diff --git a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
deleted file mode 100644
index d1d1780..0000000
--- a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
+++ /dev/null
@@ -1,921 +0,0 @@
-/**
- * Copyright (c) 2016, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.hotspot2;
-
-import static android.net.wifi.WifiConfiguration.METERED_OVERRIDE_NONE;
-import static android.net.wifi.WifiConfiguration.MeteredOverride;
-
-import android.annotation.CurrentTimeMillisLong;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.net.wifi.hotspot2.pps.Credential;
-import android.net.wifi.hotspot2.pps.HomeSp;
-import android.net.wifi.hotspot2.pps.Policy;
-import android.net.wifi.hotspot2.pps.UpdateParameter;
-import android.os.Bundle;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.telephony.TelephonyManager;
-import android.text.TextUtils;
-import android.util.Log;
-
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Objects;
-
-/**
- * Class representing Passpoint configuration.  This contains configurations specified in
- * PerProviderSubscription (PPS) Management Object (MO) tree.
- *
- * For more info, refer to Hotspot 2.0 PPS MO defined in section 9.1 of the Hotspot 2.0
- * Release 2 Technical Specification.
- */
-public final class PasspointConfiguration implements Parcelable {
-    private static final String TAG = "PasspointConfiguration";
-
-    /**
-     * Number of bytes for certificate SHA-256 fingerprint byte array.
-     */
-    private static final int CERTIFICATE_SHA256_BYTES = 32;
-
-    /**
-     * Maximum bytes for URL string.
-     */
-    private static final int MAX_URL_BYTES = 1023;
-
-    /**
-     * Integer value used for indicating null value in the Parcel.
-     */
-    private static final int NULL_VALUE = -1;
-
-    /**
-     * Configurations under HomeSp subtree.
-     */
-    private HomeSp mHomeSp = null;
-
-    /**
-     * Set the Home SP (Service Provider) information.
-     *
-     * @param homeSp The Home SP information to set to
-     */
-    public void setHomeSp(HomeSp homeSp) { mHomeSp = homeSp; }
-    /**
-     * Get the Home SP (Service Provider) information.
-     *
-     * @return Home SP information
-     */
-    public HomeSp getHomeSp() { return mHomeSp; }
-
-    /**
-     * Configurations under AAAServerTrustedNames subtree.
-     */
-    private String[] mAaaServerTrustedNames = null;
-    /**
-     * Set the AAA server trusted names information.
-     *
-     * @param aaaServerTrustedNames The AAA server trusted names information to set to
-     * @hide
-     */
-    public void setAaaServerTrustedNames(@Nullable String[] aaaServerTrustedNames) {
-        mAaaServerTrustedNames = aaaServerTrustedNames;
-    }
-    /**
-     * Get the AAA server trusted names information.
-     *
-     * @return AAA server trusted names information
-     * @hide
-     */
-    public @Nullable String[] getAaaServerTrustedNames() {
-        return mAaaServerTrustedNames;
-    }
-
-    /**
-     * Configurations under Credential subtree.
-     */
-    private Credential mCredential = null;
-    /**
-     * Set the credential information.
-     *
-     * @param credential The credential information to set to
-     */
-    public void setCredential(Credential credential) {
-        mCredential = credential;
-    }
-    /**
-     * Get the credential information.
-     *
-     * @return credential information
-     */
-    public Credential getCredential() {
-        return mCredential;
-    }
-
-    /**
-     * Configurations under Policy subtree.
-     */
-    private Policy mPolicy = null;
-    /**
-     * @hide
-     */
-    public void setPolicy(Policy policy) {
-        mPolicy = policy;
-    }
-    /**
-     * @hide
-     */
-    public Policy getPolicy() {
-        return mPolicy;
-    }
-
-    /**
-     * Meta data for performing subscription update.
-     */
-    private UpdateParameter mSubscriptionUpdate = null;
-    /**
-     * @hide
-     */
-    public void setSubscriptionUpdate(UpdateParameter subscriptionUpdate) {
-        mSubscriptionUpdate = subscriptionUpdate;
-    }
-    /**
-     * @hide
-     */
-    public UpdateParameter getSubscriptionUpdate() {
-        return mSubscriptionUpdate;
-    }
-
-    /**
-     * List of HTTPS URL for retrieving trust root certificate and the corresponding SHA-256
-     * fingerprint of the certificate.  The certificates are used for verifying AAA server's
-     * identity during EAP authentication.
-     */
-    private Map<String, byte[]> mTrustRootCertList = null;
-    /**
-     * @hide
-     */
-    public void setTrustRootCertList(Map<String, byte[]> trustRootCertList) {
-        mTrustRootCertList = trustRootCertList;
-    }
-    /**
-     * @hide
-     */
-    public Map<String, byte[]> getTrustRootCertList() {
-        return mTrustRootCertList;
-    }
-
-    /**
-     * Set by the subscription server, updated every time the configuration is updated by
-     * the subscription server.
-     *
-     * Use Integer.MIN_VALUE to indicate unset value.
-     */
-    private int mUpdateIdentifier = Integer.MIN_VALUE;
-    /**
-     * @hide
-     */
-    public void setUpdateIdentifier(int updateIdentifier) {
-        mUpdateIdentifier = updateIdentifier;
-    }
-    /**
-     * @hide
-     */
-    public int getUpdateIdentifier() {
-        return mUpdateIdentifier;
-    }
-
-    /**
-     * The priority of the credential.
-     *
-     * Use Integer.MIN_VALUE to indicate unset value.
-     */
-    private int mCredentialPriority = Integer.MIN_VALUE;
-    /**
-     * @hide
-     */
-    public void setCredentialPriority(int credentialPriority) {
-        mCredentialPriority = credentialPriority;
-    }
-    /**
-     * @hide
-     */
-    public int getCredentialPriority() {
-        return mCredentialPriority;
-    }
-
-    /**
-     * The time this subscription is created. It is in the format of number
-     * of milliseconds since January 1, 1970, 00:00:00 GMT.
-     *
-     * Use Long.MIN_VALUE to indicate unset value.
-     */
-    private long mSubscriptionCreationTimeInMillis = Long.MIN_VALUE;
-    /**
-     * @hide
-     */
-    public void setSubscriptionCreationTimeInMillis(long subscriptionCreationTimeInMillis) {
-        mSubscriptionCreationTimeInMillis = subscriptionCreationTimeInMillis;
-    }
-    /**
-     * @hide
-     */
-    public long getSubscriptionCreationTimeInMillis() {
-        return mSubscriptionCreationTimeInMillis;
-    }
-
-    /**
-     * The time this subscription will expire. It is in the format of number
-     * of milliseconds since January 1, 1970, 00:00:00 GMT.
-     *
-     * Use Long.MIN_VALUE to indicate unset value.
-     */
-    private long mSubscriptionExpirationTimeMillis = Long.MIN_VALUE;
-    /**
-     * @hide
-     */
-    public void setSubscriptionExpirationTimeInMillis(long subscriptionExpirationTimeInMillis) {
-        mSubscriptionExpirationTimeMillis = subscriptionExpirationTimeInMillis;
-    }
-    /**
-     *  Utility method to get the time this subscription will expire. It is in the format of number
-     *  of milliseconds since January 1, 1970, 00:00:00 GMT.
-     *
-     *  @return The time this subscription will expire, or Long.MIN_VALUE to indicate unset value
-     */
-    @CurrentTimeMillisLong
-    public long getSubscriptionExpirationTimeMillis() {
-        return mSubscriptionExpirationTimeMillis;
-    }
-
-    /**
-     * The type of the subscription.  This is defined by the provider and the value is provider
-     * specific.
-     */
-    private String mSubscriptionType = null;
-    /**
-     * @hide
-     */
-    public void setSubscriptionType(String subscriptionType) {
-        mSubscriptionType = subscriptionType;
-    }
-    /**
-     * @hide
-     */
-    public String getSubscriptionType() {
-        return mSubscriptionType;
-    }
-
-    /**
-     * The time period for usage statistics accumulation. A value of zero means that usage
-     * statistics are not accumulated on a periodic basis (e.g., a one-time limit for
-     * “pay as you go” - PAYG service). A non-zero value specifies the usage interval in minutes.
-     */
-    private long mUsageLimitUsageTimePeriodInMinutes = Long.MIN_VALUE;
-    /**
-     * @hide
-     */
-    public void setUsageLimitUsageTimePeriodInMinutes(long usageLimitUsageTimePeriodInMinutes) {
-        mUsageLimitUsageTimePeriodInMinutes = usageLimitUsageTimePeriodInMinutes;
-    }
-    /**
-     * @hide
-     */
-    public long getUsageLimitUsageTimePeriodInMinutes() {
-        return mUsageLimitUsageTimePeriodInMinutes;
-    }
-
-    /**
-     * The time at which usage statistic accumulation  begins.  It is in the format of number
-     * of milliseconds since January 1, 1970, 00:00:00 GMT.
-     *
-     * Use Long.MIN_VALUE to indicate unset value.
-     */
-    private long mUsageLimitStartTimeInMillis = Long.MIN_VALUE;
-    /**
-     * @hide
-     */
-    public void setUsageLimitStartTimeInMillis(long usageLimitStartTimeInMillis) {
-        mUsageLimitStartTimeInMillis = usageLimitStartTimeInMillis;
-    }
-    /**
-     * @hide
-     */
-    public long getUsageLimitStartTimeInMillis() {
-        return mUsageLimitStartTimeInMillis;
-    }
-
-    /**
-     * The cumulative data limit in megabytes for the {@link #usageLimitUsageTimePeriodInMinutes}.
-     * A value of zero indicate unlimited data usage.
-     *
-     * Use Long.MIN_VALUE to indicate unset value.
-     */
-    private long mUsageLimitDataLimit = Long.MIN_VALUE;
-    /**
-     * @hide
-     */
-    public void setUsageLimitDataLimit(long usageLimitDataLimit) {
-        mUsageLimitDataLimit = usageLimitDataLimit;
-    }
-    /**
-     * @hide
-     */
-    public long getUsageLimitDataLimit() {
-        return mUsageLimitDataLimit;
-    }
-
-    /**
-     * The cumulative time limit in minutes for the {@link #usageLimitUsageTimePeriodInMinutes}.
-     * A value of zero indicate unlimited time usage.
-     */
-    private long mUsageLimitTimeLimitInMinutes = Long.MIN_VALUE;
-    /**
-     * @hide
-     */
-    public void setUsageLimitTimeLimitInMinutes(long usageLimitTimeLimitInMinutes) {
-        mUsageLimitTimeLimitInMinutes = usageLimitTimeLimitInMinutes;
-    }
-    /**
-     * @hide
-     */
-    public long getUsageLimitTimeLimitInMinutes() {
-        return mUsageLimitTimeLimitInMinutes;
-    }
-
-    /**
-     * The map of OSU service provider names whose each element is presented in different
-     * languages for the service provider, which is used for finding a matching
-     * PasspointConfiguration with a given service provider name.
-     */
-    private Map<String, String> mServiceFriendlyNames = null;
-
-    /**
-     * @hide
-     */
-    public void setServiceFriendlyNames(Map<String, String> serviceFriendlyNames) {
-        mServiceFriendlyNames = serviceFriendlyNames;
-    }
-
-    /**
-     * @hide
-     */
-    public Map<String, String> getServiceFriendlyNames() {
-        return mServiceFriendlyNames;
-    }
-
-    /**
-     * Return the friendly Name for current language from the list of friendly names of OSU
-     * provider.
-     * The string matching the default locale will be returned if it is found, otherwise the
-     * first string in the list will be returned.  A null will be returned if the list is empty.
-     *
-     * @return String matching the default locale, null otherwise
-     * @hide
-     */
-    public String getServiceFriendlyName() {
-        if (mServiceFriendlyNames == null || mServiceFriendlyNames.isEmpty()) return null;
-        String lang = Locale.getDefault().getLanguage();
-        String friendlyName = mServiceFriendlyNames.get(lang);
-        if (friendlyName != null) {
-            return friendlyName;
-        }
-        friendlyName = mServiceFriendlyNames.get("en");
-        if (friendlyName != null) {
-            return friendlyName;
-        }
-        return mServiceFriendlyNames.get(mServiceFriendlyNames.keySet().stream().findFirst().get());
-    }
-
-    /**
-     * The carrier ID identifies the operator who provides this network configuration.
-     *    see {@link TelephonyManager#getSimCarrierId()}
-     */
-    private int mCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID;
-
-    /**
-     * Set the carrier ID associated with current configuration.
-     * @param carrierId {@code mCarrierId}
-     * @hide
-     */
-    public void setCarrierId(int carrierId) {
-        this.mCarrierId = carrierId;
-    }
-
-    /**
-     * Get the carrier ID associated with current configuration.
-     * @return {@code mCarrierId}
-     * @hide
-     */
-    public int getCarrierId() {
-        return mCarrierId;
-    }
-
-    /**
-     * The auto-join configuration specifies whether or not the Passpoint Configuration is
-     * considered for auto-connection. If true then yes, if false then it isn't considered as part
-     * of auto-connection - but can still be manually connected to.
-     */
-    private boolean mIsAutojoinEnabled = true;
-
-    /**
-     * The mac randomization setting specifies whether a randomized or device MAC address will
-     * be used to connect to the passpoint network. If true, a randomized MAC will be used.
-     * Otherwise, the device MAC address will be used.
-     */
-    private boolean mIsMacRandomizationEnabled = true;
-
-    /**
-     * Indicates if the end user has expressed an explicit opinion about the
-     * meteredness of this network, such as through the Settings app.
-     * This value is one of {@link #METERED_OVERRIDE_NONE}, {@link #METERED_OVERRIDE_METERED},
-     * or {@link #METERED_OVERRIDE_NOT_METERED}.
-     * <p>
-     * This should always override any values from {@link WifiInfo#getMeteredHint()}.
-     *
-     * By default this field is set to {@link #METERED_OVERRIDE_NONE}.
-     */
-    private int mMeteredOverride = METERED_OVERRIDE_NONE;
-
-    /**
-     * Configures the auto-association status of this Passpoint configuration. A value of true
-     * indicates that the configuration will be considered for auto-connection, a value of false
-     * indicates that only manual connection will work - the framework will not auto-associate to
-     * this Passpoint network.
-     *
-     * @param autojoinEnabled true to be considered for framework auto-connection, false otherwise.
-     * @hide
-     */
-    public void setAutojoinEnabled(boolean autojoinEnabled) {
-        mIsAutojoinEnabled = autojoinEnabled;
-    }
-
-    /**
-     * Configures the MAC randomization setting for this Passpoint configuration.
-     * If set to true, the framework will use a randomized MAC address to connect to this Passpoint
-     * network. Otherwise, the framework will use the device MAC address.
-     *
-     * @param enabled true to use randomized MAC address, false to use device MAC address.
-     * @hide
-     */
-    public void setMacRandomizationEnabled(boolean enabled) {
-        mIsMacRandomizationEnabled = enabled;
-    }
-
-    /**
-     * Sets the metered override setting for this Passpoint configuration.
-     *
-     * @param meteredOverride One of the values in {@link MeteredOverride}
-     * @hide
-     */
-    public void setMeteredOverride(@MeteredOverride int meteredOverride) {
-        mMeteredOverride = meteredOverride;
-    }
-
-    /**
-     * Indicates whether the Passpoint configuration may be auto-connected to by the framework. A
-     * value of true indicates that auto-connection can happen, a value of false indicates that it
-     * cannot. However, even when auto-connection is not possible manual connection by the user is
-     * possible.
-     *
-     * @return the auto-join configuration: true for auto-connection (or join) enabled, false
-     * otherwise.
-     * @hide
-     */
-    @SystemApi
-    public boolean isAutojoinEnabled() {
-        return mIsAutojoinEnabled;
-    }
-
-    /**
-     * Indicates whether the user chose this configuration to be treated as metered or not.
-     *
-     * @return One of the values in {@link MeteredOverride}
-     * @hide
-     */
-    @SystemApi
-    @MeteredOverride
-    public int getMeteredOverride() {
-        return mMeteredOverride;
-    }
-
-    /**
-     * Indicates whether a randomized MAC address or device MAC address will be used for
-     * connections to this Passpoint network. If true, a randomized MAC address will be used.
-     * Otherwise, the device MAC address will be used.
-     *
-     * @return true for MAC randomization enabled. False for disabled.
-     * @hide
-     */
-    @SystemApi
-    public boolean isMacRandomizationEnabled() {
-        return mIsMacRandomizationEnabled;
-    }
-
-    /**
-     * Constructor for creating PasspointConfiguration with default values.
-     */
-    public PasspointConfiguration() {}
-
-    /**
-     * Copy constructor.
-     *
-     * @param source The source to copy from
-     */
-    public PasspointConfiguration(PasspointConfiguration source) {
-        if (source == null) {
-            return;
-        }
-
-        if (source.mHomeSp != null) {
-            mHomeSp = new HomeSp(source.mHomeSp);
-        }
-        if (source.mCredential != null) {
-            mCredential = new Credential(source.mCredential);
-        }
-        if (source.mPolicy != null) {
-            mPolicy = new Policy(source.mPolicy);
-        }
-        if (source.mTrustRootCertList != null) {
-            mTrustRootCertList = Collections.unmodifiableMap(source.mTrustRootCertList);
-        }
-        if (source.mSubscriptionUpdate != null) {
-            mSubscriptionUpdate = new UpdateParameter(source.mSubscriptionUpdate);
-        }
-        mUpdateIdentifier = source.mUpdateIdentifier;
-        mCredentialPriority = source.mCredentialPriority;
-        mSubscriptionCreationTimeInMillis = source.mSubscriptionCreationTimeInMillis;
-        mSubscriptionExpirationTimeMillis = source.mSubscriptionExpirationTimeMillis;
-        mSubscriptionType = source.mSubscriptionType;
-        mUsageLimitDataLimit = source.mUsageLimitDataLimit;
-        mUsageLimitStartTimeInMillis = source.mUsageLimitStartTimeInMillis;
-        mUsageLimitTimeLimitInMinutes = source.mUsageLimitTimeLimitInMinutes;
-        mUsageLimitUsageTimePeriodInMinutes = source.mUsageLimitUsageTimePeriodInMinutes;
-        mServiceFriendlyNames = source.mServiceFriendlyNames;
-        mAaaServerTrustedNames = source.mAaaServerTrustedNames;
-        mCarrierId = source.mCarrierId;
-        mIsAutojoinEnabled = source.mIsAutojoinEnabled;
-        mIsMacRandomizationEnabled = source.mIsMacRandomizationEnabled;
-        mMeteredOverride = source.mMeteredOverride;
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeParcelable(mHomeSp, flags);
-        dest.writeParcelable(mCredential, flags);
-        dest.writeParcelable(mPolicy, flags);
-        dest.writeParcelable(mSubscriptionUpdate, flags);
-        writeTrustRootCerts(dest, mTrustRootCertList);
-        dest.writeInt(mUpdateIdentifier);
-        dest.writeInt(mCredentialPriority);
-        dest.writeLong(mSubscriptionCreationTimeInMillis);
-        dest.writeLong(mSubscriptionExpirationTimeMillis);
-        dest.writeString(mSubscriptionType);
-        dest.writeLong(mUsageLimitUsageTimePeriodInMinutes);
-        dest.writeLong(mUsageLimitStartTimeInMillis);
-        dest.writeLong(mUsageLimitDataLimit);
-        dest.writeLong(mUsageLimitTimeLimitInMinutes);
-        dest.writeStringArray(mAaaServerTrustedNames);
-        Bundle bundle = new Bundle();
-        bundle.putSerializable("serviceFriendlyNames",
-                (HashMap<String, String>) mServiceFriendlyNames);
-        dest.writeBundle(bundle);
-        dest.writeInt(mCarrierId);
-        dest.writeBoolean(mIsAutojoinEnabled);
-        dest.writeBoolean(mIsMacRandomizationEnabled);
-        dest.writeInt(mMeteredOverride);
-    }
-
-    @Override
-    public boolean equals(Object thatObject) {
-        if (this == thatObject) {
-            return true;
-        }
-        if (!(thatObject instanceof PasspointConfiguration)) {
-            return false;
-        }
-        PasspointConfiguration that = (PasspointConfiguration) thatObject;
-        return (mHomeSp == null ? that.mHomeSp == null : mHomeSp.equals(that.mHomeSp))
-                && (mAaaServerTrustedNames == null ? that.mAaaServerTrustedNames == null
-                : Arrays.equals(mAaaServerTrustedNames, that.mAaaServerTrustedNames))
-                && (mCredential == null ? that.mCredential == null
-                : mCredential.equals(that.mCredential))
-                && (mPolicy == null ? that.mPolicy == null : mPolicy.equals(that.mPolicy))
-                && (mSubscriptionUpdate == null ? that.mSubscriptionUpdate == null
-                : mSubscriptionUpdate.equals(that.mSubscriptionUpdate))
-                && isTrustRootCertListEquals(mTrustRootCertList, that.mTrustRootCertList)
-                && mUpdateIdentifier == that.mUpdateIdentifier
-                && mCredentialPriority == that.mCredentialPriority
-                && mSubscriptionCreationTimeInMillis == that.mSubscriptionCreationTimeInMillis
-                && mSubscriptionExpirationTimeMillis == that.mSubscriptionExpirationTimeMillis
-                && TextUtils.equals(mSubscriptionType, that.mSubscriptionType)
-                && mUsageLimitUsageTimePeriodInMinutes == that.mUsageLimitUsageTimePeriodInMinutes
-                && mUsageLimitStartTimeInMillis == that.mUsageLimitStartTimeInMillis
-                && mUsageLimitDataLimit == that.mUsageLimitDataLimit
-                && mUsageLimitTimeLimitInMinutes == that.mUsageLimitTimeLimitInMinutes
-                && mCarrierId == that.mCarrierId
-                && mIsAutojoinEnabled == that.mIsAutojoinEnabled
-                && mIsMacRandomizationEnabled == that.mIsMacRandomizationEnabled
-                && mMeteredOverride == that.mMeteredOverride
-                && (mServiceFriendlyNames == null ? that.mServiceFriendlyNames == null
-                : mServiceFriendlyNames.equals(that.mServiceFriendlyNames));
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(mHomeSp, mCredential, mPolicy, mSubscriptionUpdate, mTrustRootCertList,
-                mUpdateIdentifier, mCredentialPriority, mSubscriptionCreationTimeInMillis,
-                mSubscriptionExpirationTimeMillis, mUsageLimitUsageTimePeriodInMinutes,
-                mUsageLimitStartTimeInMillis, mUsageLimitDataLimit, mUsageLimitTimeLimitInMinutes,
-                mServiceFriendlyNames, mCarrierId, mIsAutojoinEnabled, mIsMacRandomizationEnabled,
-                mMeteredOverride);
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder builder = new StringBuilder();
-        builder.append("UpdateIdentifier: ").append(mUpdateIdentifier).append("\n");
-        builder.append("CredentialPriority: ").append(mCredentialPriority).append("\n");
-        builder.append("SubscriptionCreationTime: ").append(
-                mSubscriptionCreationTimeInMillis != Long.MIN_VALUE
-                ? new Date(mSubscriptionCreationTimeInMillis) : "Not specified").append("\n");
-        builder.append("SubscriptionExpirationTime: ").append(
-                mSubscriptionExpirationTimeMillis != Long.MIN_VALUE
-                ? new Date(mSubscriptionExpirationTimeMillis) : "Not specified").append("\n");
-        builder.append("UsageLimitStartTime: ").append(mUsageLimitStartTimeInMillis != Long.MIN_VALUE
-                ? new Date(mUsageLimitStartTimeInMillis) : "Not specified").append("\n");
-        builder.append("UsageTimePeriod: ").append(mUsageLimitUsageTimePeriodInMinutes)
-                .append("\n");
-        builder.append("UsageLimitDataLimit: ").append(mUsageLimitDataLimit).append("\n");
-        builder.append("UsageLimitTimeLimit: ").append(mUsageLimitTimeLimitInMinutes).append("\n");
-        builder.append("Provisioned by a subscription server: ")
-                .append(isOsuProvisioned() ? "Yes" : "No").append("\n");
-        if (mHomeSp != null) {
-            builder.append("HomeSP Begin ---\n");
-            builder.append(mHomeSp);
-            builder.append("HomeSP End ---\n");
-        }
-        if (mCredential != null) {
-            builder.append("Credential Begin ---\n");
-            builder.append(mCredential);
-            builder.append("Credential End ---\n");
-        }
-        if (mPolicy != null) {
-            builder.append("Policy Begin ---\n");
-            builder.append(mPolicy);
-            builder.append("Policy End ---\n");
-        }
-        if (mSubscriptionUpdate != null) {
-            builder.append("SubscriptionUpdate Begin ---\n");
-            builder.append(mSubscriptionUpdate);
-            builder.append("SubscriptionUpdate End ---\n");
-        }
-        if (mTrustRootCertList != null) {
-            builder.append("TrustRootCertServers: ").append(mTrustRootCertList.keySet())
-                    .append("\n");
-        }
-        if (mAaaServerTrustedNames != null) {
-            builder.append("AAAServerTrustedNames: ")
-                    .append(String.join(";", mAaaServerTrustedNames)).append("\n");
-        }
-        if (mServiceFriendlyNames != null) {
-            builder.append("ServiceFriendlyNames: ").append(mServiceFriendlyNames);
-        }
-        builder.append("CarrierId:" + mCarrierId);
-        builder.append("IsAutojoinEnabled:" + mIsAutojoinEnabled);
-        builder.append("mIsMacRandomizationEnabled:" + mIsMacRandomizationEnabled);
-        builder.append("mMeteredOverride:" + mMeteredOverride);
-        return builder.toString();
-    }
-
-    /**
-     * Validate the R1 configuration data.
-     *
-     * @return true on success or false on failure
-     * @hide
-     */
-    public boolean validate() {
-        // Optional: PerProviderSubscription/<X+>/SubscriptionUpdate
-        if (mSubscriptionUpdate != null && !mSubscriptionUpdate.validate()) {
-            return false;
-        }
-        return validateForCommonR1andR2();
-    }
-
-    /**
-     * Validate the R2 configuration data.
-     *
-     * @return true on success or false on failure
-     * @hide
-     */
-    public boolean validateForR2() {
-        // Required: PerProviderSubscription/UpdateIdentifier
-        if (mUpdateIdentifier == Integer.MIN_VALUE) {
-            return false;
-        }
-
-        // Required: PerProviderSubscription/<X+>/SubscriptionUpdate
-        if (mSubscriptionUpdate == null || !mSubscriptionUpdate.validate()) {
-            return false;
-        }
-        return validateForCommonR1andR2();
-    }
-
-    private boolean validateForCommonR1andR2() {
-        // Required: PerProviderSubscription/<X+>/HomeSP
-        if (mHomeSp == null || !mHomeSp.validate()) {
-            return false;
-        }
-
-        // Required: PerProviderSubscription/<X+>/Credential
-        if (mCredential == null || !mCredential.validate()) {
-            return false;
-        }
-
-        // Optional: PerProviderSubscription/<X+>/Policy
-        if (mPolicy != null && !mPolicy.validate()) {
-            return false;
-        }
-
-        if (mTrustRootCertList != null) {
-            for (Map.Entry<String, byte[]> entry : mTrustRootCertList.entrySet()) {
-                String url = entry.getKey();
-                byte[] certFingerprint = entry.getValue();
-                if (TextUtils.isEmpty(url)) {
-                    Log.d(TAG, "Empty URL");
-                    return false;
-                }
-                if (url.getBytes(StandardCharsets.UTF_8).length > MAX_URL_BYTES) {
-                    Log.d(TAG, "URL bytes exceeded the max: "
-                            + url.getBytes(StandardCharsets.UTF_8).length);
-                    return false;
-                }
-
-                if (certFingerprint == null) {
-                    Log.d(TAG, "Fingerprint not specified");
-                    return false;
-                }
-                if (certFingerprint.length != CERTIFICATE_SHA256_BYTES) {
-                    Log.d(TAG, "Incorrect size of trust root certificate SHA-256 fingerprint: "
-                            + certFingerprint.length);
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-
-    public static final @android.annotation.NonNull Creator<PasspointConfiguration> CREATOR =
-        new Creator<PasspointConfiguration>() {
-            @Override
-            public PasspointConfiguration createFromParcel(Parcel in) {
-                PasspointConfiguration config = new PasspointConfiguration();
-                config.setHomeSp(in.readParcelable(null));
-                config.setCredential(in.readParcelable(null));
-                config.setPolicy(in.readParcelable(null));
-                config.setSubscriptionUpdate(in.readParcelable(null));
-                config.setTrustRootCertList(readTrustRootCerts(in));
-                config.setUpdateIdentifier(in.readInt());
-                config.setCredentialPriority(in.readInt());
-                config.setSubscriptionCreationTimeInMillis(in.readLong());
-                config.setSubscriptionExpirationTimeInMillis(in.readLong());
-                config.setSubscriptionType(in.readString());
-                config.setUsageLimitUsageTimePeriodInMinutes(in.readLong());
-                config.setUsageLimitStartTimeInMillis(in.readLong());
-                config.setUsageLimitDataLimit(in.readLong());
-                config.setUsageLimitTimeLimitInMinutes(in.readLong());
-                config.setAaaServerTrustedNames(in.createStringArray());
-                Bundle bundle = in.readBundle();
-                Map<String, String> friendlyNamesMap = (HashMap) bundle.getSerializable(
-                        "serviceFriendlyNames");
-                config.setServiceFriendlyNames(friendlyNamesMap);
-                config.mCarrierId = in.readInt();
-                config.mIsAutojoinEnabled = in.readBoolean();
-                config.mIsMacRandomizationEnabled = in.readBoolean();
-                config.mMeteredOverride = in.readInt();
-                return config;
-            }
-
-            @Override
-            public PasspointConfiguration[] newArray(int size) {
-                return new PasspointConfiguration[size];
-            }
-
-            /**
-             * Helper function for reading trust root certificate info list from a Parcel.
-             *
-             * @param in The Parcel to read from
-             * @return The list of trust root certificate URL with the corresponding certificate
-             *         fingerprint
-             */
-            private Map<String, byte[]> readTrustRootCerts(Parcel in) {
-                int size = in.readInt();
-                if (size == NULL_VALUE) {
-                    return null;
-                }
-                Map<String, byte[]> trustRootCerts = new HashMap<>(size);
-                for (int i = 0; i < size; i++) {
-                    String key = in.readString();
-                    byte[] value = in.createByteArray();
-                    trustRootCerts.put(key, value);
-                }
-                return trustRootCerts;
-            }
-        };
-
-    /**
-     * Helper function for writing trust root certificate information list.
-     *
-     * @param dest The Parcel to write to
-     * @param trustRootCerts The list of trust root certificate URL with the corresponding
-     *                       certificate fingerprint
-     */
-    private static void writeTrustRootCerts(Parcel dest, Map<String, byte[]> trustRootCerts) {
-        if (trustRootCerts == null) {
-            dest.writeInt(NULL_VALUE);
-            return;
-        }
-        dest.writeInt(trustRootCerts.size());
-        for (Map.Entry<String, byte[]> entry : trustRootCerts.entrySet()) {
-            dest.writeString(entry.getKey());
-            dest.writeByteArray(entry.getValue());
-        }
-    }
-
-    /**
-     * Helper function for comparing two trust root certificate list.  Cannot use Map#equals
-     * method since the value type (byte[]) doesn't override equals method.
-     *
-     * @param list1 The first trust root certificate list
-     * @param list2 The second trust root certificate list
-     * @return true if the two list are equal
-     */
-    private static boolean isTrustRootCertListEquals(Map<String, byte[]> list1,
-            Map<String, byte[]> list2) {
-        if (list1 == null || list2 == null) {
-            return list1 == list2;
-        }
-        if (list1.size() != list2.size()) {
-            return false;
-        }
-        for (Map.Entry<String, byte[]> entry : list1.entrySet()) {
-            if (!Arrays.equals(entry.getValue(), list2.get(entry.getKey()))) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Indicates if the Passpoint Configuration was provisioned by a subscription (OSU) server,
-     * which means that it's an R2 (or R3) profile.
-     *
-     * @return true if the Passpoint Configuration was provisioned by a subscription server.
-     */
-    public boolean isOsuProvisioned() {
-        return getUpdateIdentifier() != Integer.MIN_VALUE;
-    }
-
-    /**
-     * Get a unique identifier for a PasspointConfiguration object. The identifier depends on the
-     * configuration that identify the service provider under the HomeSp subtree, and on the
-     * credential configuration under the Credential subtree.
-     * The method throws an {@link IllegalStateException} if the configuration under HomeSp subtree
-     * or the configuration under Credential subtree are not initialized.
-     *
-     * @return A unique identifier
-     */
-    public @NonNull String getUniqueId() {
-        if (mCredential == null || mHomeSp == null || TextUtils.isEmpty(mHomeSp.getFqdn())) {
-            throw new IllegalStateException("Credential or HomeSP are not initialized");
-        }
-
-        StringBuilder sb = new StringBuilder();
-        sb.append(String.format("%s_%x%x", mHomeSp.getFqdn(), mHomeSp.getUniqueId(),
-                mCredential.getUniqueId()));
-        return sb.toString();
-    }
-}
diff --git a/wifi/java/android/net/wifi/hotspot2/ProvisioningCallback.java b/wifi/java/android/net/wifi/hotspot2/ProvisioningCallback.java
deleted file mode 100644
index 1d499b6..0000000
--- a/wifi/java/android/net/wifi/hotspot2/ProvisioningCallback.java
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.hotspot2;
-
-import android.annotation.SystemApi;
-import android.net.wifi.WifiManager;
-import android.os.Handler;
-
-/**
- * Base class for provisioning callbacks. Should be extended by applications and set when calling
- * {@link WifiManager#startSubscriptionProvisioning(OsuProvider, ProvisioningCallback, Handler)}.
- *
- * @hide
- */
-@SystemApi
-public abstract class ProvisioningCallback {
-
-    /**
-     * The reason code for Provisioning Failure due to connection failure to OSU AP.
-     */
-    public static final int OSU_FAILURE_AP_CONNECTION = 1;
-
-    /**
-     * The reason code for invalid server URL address.
-     */
-    public static final int OSU_FAILURE_SERVER_URL_INVALID = 2;
-
-    /**
-     * The reason code for provisioning failure due to connection failure to the server.
-     */
-    public static final int OSU_FAILURE_SERVER_CONNECTION = 3;
-
-    /**
-     * The reason code for provisioning failure due to invalid server certificate.
-     */
-    public static final int OSU_FAILURE_SERVER_VALIDATION = 4;
-
-    /**
-     * The reason code for provisioning failure due to invalid service provider.
-     */
-    public static final int OSU_FAILURE_SERVICE_PROVIDER_VERIFICATION = 5;
-
-    /**
-     * The reason code for provisioning failure when a provisioning flow is aborted.
-     */
-    public static final int OSU_FAILURE_PROVISIONING_ABORTED = 6;
-
-    /**
-     * The reason code for provisioning failure when a provisioning flow is not possible.
-     */
-    public static final int OSU_FAILURE_PROVISIONING_NOT_AVAILABLE = 7;
-
-    /**
-     * The reason code for provisioning failure due to invalid web url format for an OSU web page.
-     */
-    public static final int OSU_FAILURE_INVALID_URL_FORMAT_FOR_OSU = 8;
-
-    /**
-     * The reason code for provisioning failure when a command received is not the expected command
-     * type.
-     */
-    public static final int OSU_FAILURE_UNEXPECTED_COMMAND_TYPE = 9;
-
-    /**
-     * The reason code for provisioning failure when a SOAP message is not the expected message
-     * type.
-     */
-    public static final int OSU_FAILURE_UNEXPECTED_SOAP_MESSAGE_TYPE = 10;
-
-    /**
-     * The reason code for provisioning failure when a SOAP message exchange fails.
-     */
-    public static final int OSU_FAILURE_SOAP_MESSAGE_EXCHANGE = 11;
-
-    /**
-     * The reason code for provisioning failure when a redirect listener fails to start.
-     */
-    public static final int OSU_FAILURE_START_REDIRECT_LISTENER = 12;
-
-    /**
-     * The reason code for provisioning failure when a redirect listener timed out to receive a HTTP
-     * redirect response.
-     */
-    public static final int OSU_FAILURE_TIMED_OUT_REDIRECT_LISTENER = 13;
-
-    /**
-     * The reason code for provisioning failure when there is no OSU activity to listen to
-     * {@link WifiManager#ACTION_PASSPOINT_LAUNCH_OSU_VIEW} intent.
-     */
-    public static final int OSU_FAILURE_NO_OSU_ACTIVITY_FOUND = 14;
-
-    /**
-     * The reason code for provisioning failure when the status of a SOAP message is not the
-     * expected message status.
-     */
-    public static final int OSU_FAILURE_UNEXPECTED_SOAP_MESSAGE_STATUS = 15;
-
-    /**
-     * The reason code for provisioning failure when there is no PPS MO.
-     * MO.
-     */
-    public static final int OSU_FAILURE_NO_PPS_MO = 16;
-
-    /**
-     * The reason code for provisioning failure when there is no AAAServerTrustRoot node in a PPS
-     * MO.
-     */
-    public static final int OSU_FAILURE_NO_AAA_SERVER_TRUST_ROOT_NODE = 17;
-
-    /**
-     * The reason code for provisioning failure when there is no TrustRoot node for remediation
-     * server in a PPS MO.
-     */
-    public static final int OSU_FAILURE_NO_REMEDIATION_SERVER_TRUST_ROOT_NODE = 18;
-
-    /**
-     * The reason code for provisioning failure when there is no TrustRoot node for policy server in
-     * a PPS MO.
-     */
-    public static final int OSU_FAILURE_NO_POLICY_SERVER_TRUST_ROOT_NODE = 19;
-
-    /**
-     * The reason code for provisioning failure when failing to retrieve trust root certificates
-     * used for validating server certificate for AAA, Remediation and Policy server.
-     */
-    public static final int OSU_FAILURE_RETRIEVE_TRUST_ROOT_CERTIFICATES = 20;
-
-    /**
-     * The reason code for provisioning failure when there is no trust root certificate for AAA
-     * server.
-     */
-    public static final int OSU_FAILURE_NO_AAA_TRUST_ROOT_CERTIFICATE = 21;
-
-    /**
-     * The reason code for provisioning failure when a {@link PasspointConfiguration} is failed to
-     * install.
-     */
-    public static final int OSU_FAILURE_ADD_PASSPOINT_CONFIGURATION = 22;
-
-    /**
-     * The reason code for provisioning failure when an {@link OsuProvider} is not found for
-     * provisioning.
-     */
-    public static final int OSU_FAILURE_OSU_PROVIDER_NOT_FOUND = 23;
-
-    /**
-     * The status code for provisioning flow to indicate connecting to OSU AP
-     */
-    public static final int OSU_STATUS_AP_CONNECTING = 1;
-
-    /**
-     * The status code for provisioning flow to indicate the OSU AP is connected.
-     */
-    public static final int OSU_STATUS_AP_CONNECTED = 2;
-
-    /**
-     * The status code for provisioning flow to indicate connecting to the server.
-     */
-    public static final int OSU_STATUS_SERVER_CONNECTING = 3;
-
-    /**
-     * The status code for provisioning flow to indicate the server certificate is validated.
-     */
-    public static final int OSU_STATUS_SERVER_VALIDATED = 4;
-
-    /**
-     * The status code for provisioning flow to indicate the server is connected
-     */
-    public static final int OSU_STATUS_SERVER_CONNECTED = 5;
-
-    /**
-     * The status code for provisioning flow to indicate starting the first SOAP exchange.
-     */
-    public static final int OSU_STATUS_INIT_SOAP_EXCHANGE = 6;
-
-    /**
-     * The status code for provisioning flow to indicate waiting for a HTTP redirect response.
-     */
-    public static final int OSU_STATUS_WAITING_FOR_REDIRECT_RESPONSE = 7;
-
-    /**
-     * The status code for provisioning flow to indicate a HTTP redirect response is received.
-     */
-    public static final int OSU_STATUS_REDIRECT_RESPONSE_RECEIVED = 8;
-
-    /**
-     * The status code for provisioning flow to indicate starting the second SOAP exchange.
-     */
-    public static final int OSU_STATUS_SECOND_SOAP_EXCHANGE = 9;
-
-    /**
-     * The status code for provisioning flow to indicate starting the third SOAP exchange.
-     */
-    public static final int OSU_STATUS_THIRD_SOAP_EXCHANGE = 10;
-
-    /**
-     * The status code for provisioning flow to indicate starting a step retrieving trust root
-     * certs.
-     */
-    public static final int OSU_STATUS_RETRIEVING_TRUST_ROOT_CERTS = 11;
-
-    /**
-     * Provisioning status for OSU failure
-     *
-     * @param status indicates error condition
-     */
-    public abstract void onProvisioningFailure(int status);
-
-    /**
-     * Provisioning status when OSU is in progress
-     *
-     * @param status indicates status of OSU flow
-     */
-    public abstract void onProvisioningStatus(int status);
-
-    /**
-     * Provisioning complete when provisioning/remediation flow completes
-     */
-    public abstract void onProvisioningComplete();
-}
-
diff --git a/wifi/java/android/net/wifi/hotspot2/omadm/PpsMoParser.java b/wifi/java/android/net/wifi/hotspot2/omadm/PpsMoParser.java
deleted file mode 100644
index ae60ed4..0000000
--- a/wifi/java/android/net/wifi/hotspot2/omadm/PpsMoParser.java
+++ /dev/null
@@ -1,1787 +0,0 @@
-/**
- * Copyright (c) 2016, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.hotspot2.omadm;
-
-import android.net.wifi.hotspot2.PasspointConfiguration;
-import android.net.wifi.hotspot2.pps.Credential;
-import android.net.wifi.hotspot2.pps.HomeSp;
-import android.net.wifi.hotspot2.pps.Policy;
-import android.net.wifi.hotspot2.pps.UpdateParameter;
-import android.text.TextUtils;
-import android.util.Log;
-import android.util.Pair;
-
-import org.xml.sax.SAXException;
-
-import java.io.IOException;
-import java.text.DateFormat;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Utility class for converting OMA-DM (Open Mobile Alliance's Device Management)
- * PPS-MO (PerProviderSubscription Management Object) XML tree to a
- * {@link PasspointConfiguration} object.
- *
- * Currently this only supports PerProviderSubscription/HomeSP and
- * PerProviderSubscription/Credential subtree for Hotspot 2.0 Release 1 support.
- *
- * For more info, refer to Hotspot 2.0 PPS MO defined in section 9.1 of the Hotspot 2.0
- * Release 2 Technical Specification.
- *
- * Below is a sample XML string for a Release 1 PPS MO tree:
- *
- * <MgmtTree xmlns="syncml:dmddf1.2">
- *   <VerDTD>1.2</VerDTD>
- *   <Node>
- *     <NodeName>PerProviderSubscription</NodeName>
- *     <RTProperties>
- *       <Type>
- *         <DDFName>urn:wfa:mo:hotspot2dot0­perprovidersubscription:1.0</DDFName>
- *       </Type>
- *     </RTProperties>
- *     <Node>
- *       <NodeName>i001</NodeName>
- *       <Node>
- *         <NodeName>HomeSP</NodeName>
- *         <Node>
- *           <NodeName>FriendlyName</NodeName>
- *           <Value>Century House</Value>
- *         </Node>
- *         <Node>
- *           <NodeName>FQDN</NodeName>
- *           <Value>mi6.co.uk</Value>
- *         </Node>
- *         <Node>
- *           <NodeName>RoamingConsortiumOI</NodeName>
- *           <Value>112233,445566</Value>
- *         </Node>
- *       </Node>
- *       <Node>
- *         <NodeName>Credential</NodeName>
- *         <Node>
- *           <NodeName>Realm</NodeName>
- *           <Value>shaken.stirred.com</Value>
- *         </Node>
- *         <Node>
- *           <NodeName>UsernamePassword</NodeName>
- *           <Node>
- *             <NodeName>Username</NodeName>
- *             <Value>james</Value>
- *           </Node>
- *           <Node>
- *             <NodeName>Password</NodeName>
- *             <Value>Ym9uZDAwNw==</Value>
- *           </Node>
- *           <Node>
- *             <NodeName>EAPMethod</NodeName>
- *             <Node>
- *               <NodeName>EAPType</NodeName>
- *               <Value>21</Value>
- *             </Node>
- *             <Node>
- *               <NodeName>InnerMethod</NodeName>
- *               <Value>MS-CHAP-V2</Value>
- *             </Node>
- *           </Node>
- *         </Node>
- *       </Node>
- *     </Node>
- *   </Node>
- * </MgmtTree>
- */
-public final class PpsMoParser {
-    private static final String TAG = "PpsMoParser";
-
-    /**
-     * XML tags expected in the PPS MO (PerProviderSubscription Management Object) XML tree.
-     */
-    private static final String TAG_MANAGEMENT_TREE = "MgmtTree";
-    private static final String TAG_VER_DTD = "VerDTD";
-    private static final String TAG_NODE = "Node";
-    private static final String TAG_NODE_NAME = "NodeName";
-    private static final String TAG_RT_PROPERTIES = "RTProperties";
-    private static final String TAG_TYPE = "Type";
-    private static final String TAG_DDF_NAME = "DDFName";
-    private static final String TAG_VALUE = "Value";
-
-    /**
-     * Name for PerProviderSubscription node.
-     */
-    private static final String NODE_PER_PROVIDER_SUBSCRIPTION = "PerProviderSubscription";
-
-    /**
-     * Fields under PerProviderSubscription.
-     */
-    private static final String NODE_UPDATE_IDENTIFIER = "UpdateIdentifier";
-    private static final String NODE_AAA_SERVER_TRUST_ROOT = "AAAServerTrustRoot";
-    private static final String NODE_SUBSCRIPTION_UPDATE = "SubscriptionUpdate";
-    private static final String NODE_SUBSCRIPTION_PARAMETER = "SubscriptionParameters";
-    private static final String NODE_TYPE_OF_SUBSCRIPTION = "TypeOfSubscription";
-    private static final String NODE_USAGE_LIMITS = "UsageLimits";
-    private static final String NODE_DATA_LIMIT = "DataLimit";
-    private static final String NODE_START_DATE = "StartDate";
-    private static final String NODE_TIME_LIMIT = "TimeLimit";
-    private static final String NODE_USAGE_TIME_PERIOD = "UsageTimePeriod";
-    private static final String NODE_CREDENTIAL_PRIORITY = "CredentialPriority";
-    private static final String NODE_EXTENSION = "Extension";
-
-    /**
-     * Fields under Extension/Android subtree.
-     */
-    /*
-     * This node is used to put Android specific extension nodes and must be put
-     * under "Extension" node. Nodes with unknown names are allowed under this subtree.
-     * If there is any new node added in later release, it won't break older release parsing.
-     * <p>
-     * Ex:
-     * <Node>
-     *   <NodeName>Extension</NodeName>
-     *   <Node>
-     *     <NodeName>Android</NodeName>
-     *     <Node>
-     *       <NodeName>AndroidSpecificAttribute</NodeName>
-     *       <Value>AndroidSpecificValue</Value>
-     *     </Node>
-     *     <Node>
-     *       <NodeName>AndroidSpecificAttribute2</NodeName>
-     *       <Value>AndroidSpecificValue2</Value>
-     *     </Node>
-     *   </Node>
-     * </Node>
-     */
-    private static final String NODE_VENDOR_ANDROID = "Android";
-    /*
-     * This node describes AAA server trusted names. The trusted name must be put in
-     * a leaf named "FQDN". More than one trusted names can be provided by using
-     * semicolons to separate the strings (e.g., example.org;example.com).
-     * <p>
-     * Ex:
-     * <Node>
-     *   <NodeName>AAAServerTrustedNames</NodeName>
-     *   <Node>
-     *     <NodeName>FQDN</NodeName>
-     *     <Value>trusted.com;auth.net</Value>
-     *  </Node>
-     * <Node>
-     */
-    private static final String NODE_AAA_SERVER_TRUSTED_NAMES = "AAAServerTrustedNames";
-
-    /**
-     * Fields under HomeSP subtree.
-     */
-    private static final String NODE_HOMESP = "HomeSP";
-    private static final String NODE_FQDN = "FQDN";
-    private static final String NODE_FRIENDLY_NAME = "FriendlyName";
-    private static final String NODE_ROAMING_CONSORTIUM_OI = "RoamingConsortiumOI";
-    private static final String NODE_NETWORK_ID = "NetworkID";
-    private static final String NODE_SSID = "SSID";
-    private static final String NODE_HESSID = "HESSID";
-    private static final String NODE_ICON_URL = "IconURL";
-    private static final String NODE_HOME_OI_LIST = "HomeOIList";
-    private static final String NODE_HOME_OI = "HomeOI";
-    private static final String NODE_HOME_OI_REQUIRED = "HomeOIRequired";
-    private static final String NODE_OTHER_HOME_PARTNERS = "OtherHomePartners";
-
-    /**
-     * Fields under Credential subtree.
-     */
-    private static final String NODE_CREDENTIAL = "Credential";
-    private static final String NODE_CREATION_DATE = "CreationDate";
-    private static final String NODE_EXPIRATION_DATE = "ExpirationDate";
-    private static final String NODE_USERNAME_PASSWORD = "UsernamePassword";
-    private static final String NODE_USERNAME = "Username";
-    private static final String NODE_PASSWORD = "Password";
-    private static final String NODE_MACHINE_MANAGED = "MachineManaged";
-    private static final String NODE_SOFT_TOKEN_APP = "SoftTokenApp";
-    private static final String NODE_ABLE_TO_SHARE = "AbleToShare";
-    private static final String NODE_EAP_METHOD = "EAPMethod";
-    private static final String NODE_EAP_TYPE = "EAPType";
-    private static final String NODE_VENDOR_ID = "VendorId";
-    private static final String NODE_VENDOR_TYPE = "VendorType";
-    private static final String NODE_INNER_EAP_TYPE = "InnerEAPType";
-    private static final String NODE_INNER_VENDOR_ID = "InnerVendorID";
-    private static final String NODE_INNER_VENDOR_TYPE = "InnerVendorType";
-    private static final String NODE_INNER_METHOD = "InnerMethod";
-    private static final String NODE_DIGITAL_CERTIFICATE = "DigitalCertificate";
-    private static final String NODE_CERTIFICATE_TYPE = "CertificateType";
-    private static final String NODE_CERT_SHA256_FINGERPRINT = "CertSHA256Fingerprint";
-    private static final String NODE_REALM = "Realm";
-    private static final String NODE_SIM = "SIM";
-    private static final String NODE_SIM_IMSI = "IMSI";
-    private static final String NODE_CHECK_AAA_SERVER_CERT_STATUS = "CheckAAAServerCertStatus";
-
-    /**
-     * Fields under Policy subtree.
-     */
-    private static final String NODE_POLICY = "Policy";
-    private static final String NODE_PREFERRED_ROAMING_PARTNER_LIST =
-            "PreferredRoamingPartnerList";
-    private static final String NODE_FQDN_MATCH = "FQDN_Match";
-    private static final String NODE_PRIORITY = "Priority";
-    private static final String NODE_COUNTRY = "Country";
-    private static final String NODE_MIN_BACKHAUL_THRESHOLD = "MinBackhaulThreshold";
-    private static final String NODE_NETWORK_TYPE = "NetworkType";
-    private static final String NODE_DOWNLINK_BANDWIDTH = "DLBandwidth";
-    private static final String NODE_UPLINK_BANDWIDTH = "ULBandwidth";
-    private static final String NODE_POLICY_UPDATE = "PolicyUpdate";
-    private static final String NODE_UPDATE_INTERVAL = "UpdateInterval";
-    private static final String NODE_UPDATE_METHOD = "UpdateMethod";
-    private static final String NODE_RESTRICTION = "Restriction";
-    private static final String NODE_URI = "URI";
-    private static final String NODE_TRUST_ROOT = "TrustRoot";
-    private static final String NODE_CERT_URL = "CertURL";
-    private static final String NODE_SP_EXCLUSION_LIST = "SPExclusionList";
-    private static final String NODE_REQUIRED_PROTO_PORT_TUPLE = "RequiredProtoPortTuple";
-    private static final String NODE_IP_PROTOCOL = "IPProtocol";
-    private static final String NODE_PORT_NUMBER = "PortNumber";
-    private static final String NODE_MAXIMUM_BSS_LOAD_VALUE = "MaximumBSSLoadValue";
-    private static final String NODE_OTHER = "Other";
-
-    /**
-     * URN (Unique Resource Name) for PerProviderSubscription Management Object Tree.
-     */
-    private static final String PPS_MO_URN =
-            "urn:wfa:mo:hotspot2dot0-perprovidersubscription:1.0";
-
-    /**
-     * Exception for generic parsing errors.
-     */
-    private static class ParsingException extends Exception {
-        public ParsingException(String message) {
-            super(message);
-        }
-    }
-
-    /**
-     * Class representing a node within the PerProviderSubscription tree.
-     * This is used to flatten out and eliminate the extra layering in the XMLNode tree,
-     * to make the data parsing easier and cleaner.
-     *
-     * A PPSNode can be an internal or a leaf node, but not both.
-     *
-     */
-    private static abstract class PPSNode {
-        private final String mName;
-        public PPSNode(String name) {
-            mName = name;
-        }
-
-        /**
-         * @return the name of the node
-         */
-        public String getName() {
-            return mName;
-        }
-
-        /**
-         * Applies for internal node only.
-         *
-         * @return the list of children nodes.
-         */
-        public abstract List<PPSNode> getChildren();
-
-        /**
-         * Applies for leaf node only.
-         *
-         * @return the string value of the node
-         */
-        public abstract String getValue();
-
-        /**
-         * @return a flag indicating if this is a leaf or an internal node
-         */
-        public abstract boolean isLeaf();
-    }
-
-    /**
-     * Class representing a leaf node in a PPS (PerProviderSubscription) tree.
-     */
-    private static class LeafNode extends PPSNode {
-        private final String mValue;
-        public LeafNode(String nodeName, String value) {
-            super(nodeName);
-            mValue = value;
-        }
-
-        @Override
-        public String getValue() {
-            return mValue;
-        }
-
-        @Override
-        public List<PPSNode> getChildren() {
-            return null;
-        }
-
-        @Override
-        public boolean isLeaf() {
-            return true;
-        }
-    }
-
-    /**
-     * Class representing an internal node in a PPS (PerProviderSubscription) tree.
-     */
-    private static class InternalNode extends PPSNode {
-        private final List<PPSNode> mChildren;
-        public InternalNode(String nodeName, List<PPSNode> children) {
-            super(nodeName);
-            mChildren = children;
-        }
-
-        @Override
-        public String getValue() {
-            return null;
-        }
-
-        @Override
-        public List<PPSNode> getChildren() {
-            return mChildren;
-        }
-
-        @Override
-        public boolean isLeaf() {
-            return false;
-        }
-    }
-
-    /**
-     * @hide
-     */
-    public PpsMoParser() {}
-
-    /**
-     * Convert a XML string representation of a PPS MO (PerProviderSubscription
-     * Management Object) tree to a {@link PasspointConfiguration} object.
-     *
-     * @param xmlString XML string representation of a PPS MO tree
-     * @return {@link PasspointConfiguration} or null
-     */
-    public static PasspointConfiguration parseMoText(String xmlString) {
-        // Convert the XML string to a XML tree.
-        XMLParser xmlParser = new XMLParser();
-        XMLNode root = null;
-        try {
-            root = xmlParser.parse(xmlString);
-        } catch(IOException | SAXException e) {
-            return null;
-        }
-        if (root == null) {
-            return null;
-        }
-
-        // Verify root node is a "MgmtTree" node.
-        if (root.getTag() != TAG_MANAGEMENT_TREE) {
-            Log.e(TAG, "Root is not a MgmtTree");
-            return null;
-        }
-
-        String verDtd = null;    // Used for detecting duplicate VerDTD element.
-        PasspointConfiguration config = null;
-        for (XMLNode child : root.getChildren()) {
-            switch(child.getTag()) {
-                case TAG_VER_DTD:
-                    if (verDtd != null) {
-                        Log.e(TAG, "Duplicate VerDTD element");
-                        return null;
-                    }
-                    verDtd = child.getText();
-                    break;
-                case TAG_NODE:
-                    if (config != null) {
-                        Log.e(TAG, "Unexpected multiple Node element under MgmtTree");
-                        return null;
-                    }
-                    try {
-                        config = parsePpsNode(child);
-                    } catch (ParsingException e) {
-                        Log.e(TAG, e.getMessage());
-                        return null;
-                    }
-                    break;
-                default:
-                    Log.e(TAG, "Unknown node: " + child.getTag());
-                    return null;
-            }
-        }
-        return config;
-    }
-
-    /**
-     * Parse a PerProviderSubscription node. Below is the format of the XML tree (with
-     * each XML element represent a node in the tree):
-     *
-     * <Node>
-     *   <NodeName>PerProviderSubscription</NodeName>
-     *   <RTProperties>
-     *     ...
-     *   </RTPProperties>
-     *   <Node>
-     *     <NodeName>UpdateIdentifier</NodeName>
-     *     <Value>...</Value>
-     *   </Node>
-     *   <Node>
-     *     ...
-     *   </Node>
-     * </Node>
-     *
-     * @param node XMLNode that contains PerProviderSubscription node.
-     * @return PasspointConfiguration or null
-     * @throws ParsingException
-     */
-    private static PasspointConfiguration parsePpsNode(XMLNode node)
-            throws ParsingException {
-        PasspointConfiguration config = null;
-        String nodeName = null;
-        int updateIdentifier = Integer.MIN_VALUE;
-        for (XMLNode child : node.getChildren()) {
-            switch (child.getTag()) {
-                case TAG_NODE_NAME:
-                    if (nodeName != null) {
-                        throw new ParsingException("Duplicate NodeName: " + child.getText());
-                    }
-                    nodeName = child.getText();
-                    if (!TextUtils.equals(nodeName, NODE_PER_PROVIDER_SUBSCRIPTION)) {
-                        throw new ParsingException("Unexpected NodeName: " + nodeName);
-                    }
-                    break;
-                case TAG_NODE:
-                    // A node can be either an UpdateIdentifier node or a PerProviderSubscription
-                    // instance node.  Flatten out the XML tree first by converting it to a PPS
-                    // tree to reduce the complexity of the parsing code.
-                    PPSNode ppsNodeRoot = buildPpsNode(child);
-                    if (TextUtils.equals(ppsNodeRoot.getName(), NODE_UPDATE_IDENTIFIER)) {
-                        if (updateIdentifier != Integer.MIN_VALUE) {
-                            throw new ParsingException("Multiple node for UpdateIdentifier");
-                        }
-                        updateIdentifier = parseInteger(getPpsNodeValue(ppsNodeRoot));
-                    } else {
-                        // Only one PerProviderSubscription instance is expected and allowed.
-                        if (config != null) {
-                            throw new ParsingException("Multiple PPS instance");
-                        }
-                        config = parsePpsInstance(ppsNodeRoot);
-                    }
-                    break;
-                case TAG_RT_PROPERTIES:
-                    // Parse and verify URN stored in the RT (Run Time) Properties.
-                    String urn = parseUrn(child);
-                    if (!TextUtils.equals(urn, PPS_MO_URN)) {
-                        throw new ParsingException("Unknown URN: " + urn);
-                    }
-                    break;
-                default:
-                    throw new ParsingException("Unknown tag under PPS node: " + child.getTag());
-            }
-        }
-        if (config != null && updateIdentifier != Integer.MIN_VALUE) {
-            config.setUpdateIdentifier(updateIdentifier);
-        }
-        return config;
-    }
-
-    /**
-     * Parse the URN stored in the RTProperties. Below is the format of the RTPProperties node:
-     *
-     * <RTProperties>
-     *   <Type>
-     *     <DDFName>urn:...</DDFName>
-     *   </Type>
-     * </RTProperties>
-     *
-     * @param node XMLNode that contains RTProperties node.
-     * @return URN String of URN.
-     * @throws ParsingException
-     */
-    private static String parseUrn(XMLNode node) throws ParsingException {
-        if (node.getChildren().size() != 1)
-            throw new ParsingException("Expect RTPProperties node to only have one child");
-
-        XMLNode typeNode = node.getChildren().get(0);
-        if (typeNode.getChildren().size() != 1) {
-            throw new ParsingException("Expect Type node to only have one child");
-        }
-        if (!TextUtils.equals(typeNode.getTag(), TAG_TYPE)) {
-            throw new ParsingException("Unexpected tag for Type: " + typeNode.getTag());
-        }
-
-        XMLNode ddfNameNode = typeNode.getChildren().get(0);
-        if (!ddfNameNode.getChildren().isEmpty()) {
-            throw new ParsingException("Expect DDFName node to have no child");
-        }
-        if (!TextUtils.equals(ddfNameNode.getTag(), TAG_DDF_NAME)) {
-            throw new ParsingException("Unexpected tag for DDFName: " + ddfNameNode.getTag());
-        }
-
-        return ddfNameNode.getText();
-    }
-
-    /**
-     * Convert a XML tree represented by XMLNode to a PPS (PerProviderSubscription) instance tree
-     * represented by PPSNode.  This flattens out the XML tree to allow easier and cleaner parsing
-     * of the PPS configuration data.  Only three types of XML tag are expected: "NodeName",
-     * "Node", and "Value".
-     *
-     * The original XML tree (each XML element represent a node):
-     *
-     * <Node>
-     *   <NodeName>root</NodeName>
-     *   <Node>
-     *     <NodeName>child1</NodeName>
-     *     <Value>value1</Value>
-     *   </Node>
-     *   <Node>
-     *     <NodeName>child2</NodeName>
-     *     <Node>
-     *       <NodeName>grandchild1</NodeName>
-     *       ...
-     *     </Node>
-     *   </Node>
-     *   ...
-     * </Node>
-     *
-     * The converted PPS tree:
-     *
-     * [root] --- [child1, value1]
-     *   |
-     *   ---------[child2] --------[grandchild1] --- ...
-     *
-     * @param node XMLNode pointed to the root of a XML tree
-     * @return PPSNode pointing to the root of a PPS tree
-     * @throws ParsingException
-     */
-    private static PPSNode buildPpsNode(XMLNode node) throws ParsingException {
-        String nodeName = null;
-        String nodeValue = null;
-        List<PPSNode> childNodes = new ArrayList<PPSNode>();
-        // Names of parsed child nodes, use for detecting multiple child nodes with the same name.
-        Set<String> parsedNodes = new HashSet<String>();
-
-        for (XMLNode child : node.getChildren()) {
-            String tag = child.getTag();
-            if (TextUtils.equals(tag, TAG_NODE_NAME)) {
-                if (nodeName != null) {
-                    throw new ParsingException("Duplicate NodeName node");
-                }
-                nodeName = child.getText();
-            } else if (TextUtils.equals(tag, TAG_NODE)) {
-                PPSNode ppsNode = buildPpsNode(child);
-                if (parsedNodes.contains(ppsNode.getName())) {
-                    throw new ParsingException("Duplicate node: " + ppsNode.getName());
-                }
-                parsedNodes.add(ppsNode.getName());
-                childNodes.add(ppsNode);
-            } else if (TextUtils.equals(tag, TAG_VALUE)) {
-               if (nodeValue != null) {
-                   throw new ParsingException("Duplicate Value node");
-               }
-               nodeValue = child.getText();
-            } else {
-                throw new ParsingException("Unknown tag: " + tag);
-            }
-        }
-
-        if (nodeName == null) {
-            throw new ParsingException("Invalid node: missing NodeName");
-        }
-        if (nodeValue == null && childNodes.size() == 0) {
-            throw new ParsingException("Invalid node: " + nodeName +
-                    " missing both value and children");
-        }
-        if (nodeValue != null && childNodes.size() > 0) {
-            throw new ParsingException("Invalid node: " + nodeName +
-                    " contained both value and children");
-        }
-
-        if (nodeValue != null) {
-            return new LeafNode(nodeName, nodeValue);
-        }
-        return new InternalNode(nodeName, childNodes);
-    }
-
-    /**
-     * Return the value of a PPSNode.  An exception will be thrown if the given node
-     * is not a leaf node.
-     *
-     * @param node PPSNode to retrieve the value from
-     * @return String representing the value of the node
-     * @throws ParsingException
-     */
-    private static String getPpsNodeValue(PPSNode node) throws ParsingException {
-        if (!node.isLeaf()) {
-            throw new ParsingException("Cannot get value from a non-leaf node: " + node.getName());
-        }
-        return node.getValue();
-    }
-
-    /**
-     * Parse a PPS (PerProviderSubscription) configurations from a PPS tree.
-     *
-     * @param root PPSNode representing the root of the PPS tree
-     * @return PasspointConfiguration
-     * @throws ParsingException
-     */
-    private static PasspointConfiguration parsePpsInstance(PPSNode root)
-            throws ParsingException {
-        if (root.isLeaf()) {
-            throw new ParsingException("Leaf node not expected for PPS instance");
-        }
-
-        PasspointConfiguration config = new PasspointConfiguration();
-        for (PPSNode child : root.getChildren()) {
-            switch(child.getName()) {
-                case NODE_HOMESP:
-                    config.setHomeSp(parseHomeSP(child));
-                    break;
-                case NODE_CREDENTIAL:
-                    config.setCredential(parseCredential(child));
-                    break;
-                case NODE_POLICY:
-                    config.setPolicy(parsePolicy(child));
-                    break;
-                case NODE_AAA_SERVER_TRUST_ROOT:
-                    config.setTrustRootCertList(parseAAAServerTrustRootList(child));
-                    break;
-                case NODE_SUBSCRIPTION_UPDATE:
-                    config.setSubscriptionUpdate(parseUpdateParameter(child));
-                    break;
-                case NODE_SUBSCRIPTION_PARAMETER:
-                    parseSubscriptionParameter(child, config);
-                    break;
-                case NODE_CREDENTIAL_PRIORITY:
-                    config.setCredentialPriority(parseInteger(getPpsNodeValue(child)));
-                    break;
-                case NODE_EXTENSION:
-                    // All vendor specific information will be under this node.
-                    parseExtension(child, config);
-                    break;
-                default:
-                    throw new ParsingException("Unknown node: " + child.getName());
-            }
-        }
-        return config;
-    }
-
-    /**
-     * Parse configurations under PerProviderSubscription/HomeSP subtree.
-     *
-     * @param node PPSNode representing the root of the PerProviderSubscription/HomeSP subtree
-     * @return HomeSP
-     * @throws ParsingException
-     */
-    private static HomeSp parseHomeSP(PPSNode node) throws ParsingException {
-        if (node.isLeaf()) {
-            throw new ParsingException("Leaf node not expected for HomeSP");
-        }
-
-        HomeSp homeSp = new HomeSp();
-        for (PPSNode child : node.getChildren()) {
-            switch (child.getName()) {
-                case NODE_FQDN:
-                    homeSp.setFqdn(getPpsNodeValue(child));
-                    break;
-                case NODE_FRIENDLY_NAME:
-                    homeSp.setFriendlyName(getPpsNodeValue(child));
-                    break;
-                case NODE_ROAMING_CONSORTIUM_OI:
-                    homeSp.setRoamingConsortiumOis(
-                            parseRoamingConsortiumOI(getPpsNodeValue(child)));
-                    break;
-                case NODE_ICON_URL:
-                    homeSp.setIconUrl(getPpsNodeValue(child));
-                    break;
-                case NODE_NETWORK_ID:
-                    homeSp.setHomeNetworkIds(parseNetworkIds(child));
-                    break;
-                case NODE_HOME_OI_LIST:
-                    Pair<List<Long>, List<Long>> homeOIs = parseHomeOIList(child);
-                    homeSp.setMatchAllOis(convertFromLongList(homeOIs.first));
-                    homeSp.setMatchAnyOis(convertFromLongList(homeOIs.second));
-                    break;
-                case NODE_OTHER_HOME_PARTNERS:
-                    homeSp.setOtherHomePartners(parseOtherHomePartners(child));
-                    break;
-                default:
-                    throw new ParsingException("Unknown node under HomeSP: " + child.getName());
-            }
-        }
-        return homeSp;
-    }
-
-    /**
-     * Parse the roaming consortium OI string, which contains a list of OIs separated by ",".
-     *
-     * @param oiStr string containing list of OIs (Organization Identifiers) separated by ","
-     * @return long[]
-     * @throws ParsingException
-     */
-    private static long[] parseRoamingConsortiumOI(String oiStr)
-            throws ParsingException {
-        String[] oiStrArray = oiStr.split(",");
-        long[] oiArray = new long[oiStrArray.length];
-        for (int i = 0; i < oiStrArray.length; i++) {
-            oiArray[i] = parseLong(oiStrArray[i], 16);
-        }
-        return oiArray;
-    }
-
-    /**
-     * Parse configurations under PerProviderSubscription/HomeSP/NetworkID subtree.
-     *
-     * @param node PPSNode representing the root of the PerProviderSubscription/HomeSP/NetworkID
-     *             subtree
-     * @return HashMap<String, Long> representing list of <SSID, HESSID> pair.
-     * @throws ParsingException
-     */
-    static private Map<String, Long> parseNetworkIds(PPSNode node)
-            throws ParsingException {
-        if (node.isLeaf()) {
-            throw new ParsingException("Leaf node not expected for NetworkID");
-        }
-
-        Map<String, Long> networkIds = new HashMap<>();
-        for (PPSNode child : node.getChildren()) {
-            Pair<String, Long> networkId = parseNetworkIdInstance(child);
-            networkIds.put(networkId.first, networkId.second);
-        }
-        return networkIds;
-    }
-
-    /**
-     * Parse configurations under PerProviderSubscription/HomeSP/NetworkID/<X+> subtree.
-     * The instance name (<X+>) is irrelevant and must be unique for each instance, which
-     * is verified when the PPS tree is constructed {@link #buildPpsNode}.
-     *
-     * @param node PPSNode representing the root of the
-     *             PerProviderSubscription/HomeSP/NetworkID/<X+> subtree
-     * @return Pair<String, Long> representing <SSID, HESSID> pair.
-     * @throws ParsingException
-     */
-    static private Pair<String, Long> parseNetworkIdInstance(PPSNode node)
-            throws ParsingException {
-        if (node.isLeaf()) {
-            throw new ParsingException("Leaf node not expected for NetworkID instance");
-        }
-
-        String ssid = null;
-        Long hessid = null;
-        for (PPSNode child : node.getChildren()) {
-            switch (child.getName()) {
-                case NODE_SSID:
-                    ssid = getPpsNodeValue(child);
-                    break;
-                case NODE_HESSID:
-                    hessid = parseLong(getPpsNodeValue(child), 16);
-                    break;
-                default:
-                    throw new ParsingException("Unknown node under NetworkID instance: " +
-                            child.getName());
-            }
-        }
-        if (ssid == null)
-            throw new ParsingException("NetworkID instance missing SSID");
-
-        return new Pair<String, Long>(ssid, hessid);
-    }
-
-    /**
-     * Parse configurations under PerProviderSubscription/HomeSP/HomeOIList subtree.
-     *
-     * @param node PPSNode representing the root of the PerProviderSubscription/HomeSP/HomeOIList
-     *             subtree
-     * @return Pair<List<Long>, List<Long>> containing both MatchAllOIs and MatchAnyOIs list.
-     * @throws ParsingException
-     */
-    private static Pair<List<Long>, List<Long>> parseHomeOIList(PPSNode node)
-            throws ParsingException {
-        if (node.isLeaf()) {
-            throw new ParsingException("Leaf node not expected for HomeOIList");
-        }
-
-        List<Long> matchAllOIs = new ArrayList<Long>();
-        List<Long> matchAnyOIs = new ArrayList<Long>();
-        for (PPSNode child : node.getChildren()) {
-            Pair<Long, Boolean> homeOI = parseHomeOIInstance(child);
-            if (homeOI.second.booleanValue()) {
-                matchAllOIs.add(homeOI.first);
-            } else {
-                matchAnyOIs.add(homeOI.first);
-            }
-        }
-        return new Pair<List<Long>, List<Long>>(matchAllOIs, matchAnyOIs);
-    }
-
-    /**
-     * Parse configurations under PerProviderSubscription/HomeSP/HomeOIList/<X+> subtree.
-     * The instance name (<X+>) is irrelevant and must be unique for each instance, which
-     * is verified when the PPS tree is constructed {@link #buildPpsNode}.
-     *
-     * @param node PPSNode representing the root of the
-     *             PerProviderSubscription/HomeSP/HomeOIList/<X+> subtree
-     * @return Pair<Long, Boolean> containing a HomeOI and a HomeOIRequired flag
-     * @throws ParsingException
-     */
-    private static Pair<Long, Boolean> parseHomeOIInstance(PPSNode node) throws ParsingException {
-        if (node.isLeaf()) {
-            throw new ParsingException("Leaf node not expected for HomeOI instance");
-        }
-
-        Long oi = null;
-        Boolean required = null;
-        for (PPSNode child : node.getChildren()) {
-            switch (child.getName()) {
-                case NODE_HOME_OI:
-                    try {
-                        oi = Long.valueOf(getPpsNodeValue(child), 16);
-                    } catch (NumberFormatException e) {
-                        throw new ParsingException("Invalid HomeOI: " + getPpsNodeValue(child));
-                    }
-                    break;
-                case NODE_HOME_OI_REQUIRED:
-                    required = Boolean.valueOf(getPpsNodeValue(child));
-                    break;
-                default:
-                    throw new ParsingException("Unknown node under NetworkID instance: " +
-                            child.getName());
-            }
-        }
-        if (oi == null) {
-            throw new ParsingException("HomeOI instance missing OI field");
-        }
-        if (required == null) {
-            throw new ParsingException("HomeOI instance missing required field");
-        }
-        return new Pair<Long, Boolean>(oi, required);
-    }
-
-    /**
-     * Parse configurations under PerProviderSubscription/HomeSP/OtherHomePartners subtree.
-     * This contains a list of FQDN (Fully Qualified Domain Name) that are considered
-     * home partners.
-     *
-     * @param node PPSNode representing the root of the
-     *             PerProviderSubscription/HomeSP/OtherHomePartners subtree
-     * @return String[] list of partner's FQDN
-     * @throws ParsingException
-     */
-    private static String[] parseOtherHomePartners(PPSNode node) throws ParsingException {
-        if (node.isLeaf()) {
-            throw new ParsingException("Leaf node not expected for OtherHomePartners");
-        }
-        List<String> otherHomePartners = new ArrayList<String>();
-        for (PPSNode child : node.getChildren()) {
-            String fqdn = parseOtherHomePartnerInstance(child);
-            otherHomePartners.add(fqdn);
-        }
-        return otherHomePartners.toArray(new String[otherHomePartners.size()]);
-    }
-
-    /**
-     * Parse configurations under PerProviderSubscription/HomeSP/OtherHomePartners/<X+> subtree.
-     * The instance name (<X+>) is irrelevant and must be unique for each instance, which
-     * is verified when the PPS tree is constructed {@link #buildPpsNode}.
-     *
-     * @param node PPSNode representing the root of the
-     *             PerProviderSubscription/HomeSP/OtherHomePartners/<X+> subtree
-     * @return String FQDN of the partner
-     * @throws ParsingException
-     */
-    private static String parseOtherHomePartnerInstance(PPSNode node) throws ParsingException {
-        if (node.isLeaf()) {
-            throw new ParsingException("Leaf node not expected for OtherHomePartner instance");
-        }
-        String fqdn = null;
-        for (PPSNode child : node.getChildren()) {
-            switch (child.getName()) {
-                case NODE_FQDN:
-                    fqdn = getPpsNodeValue(child);
-                    break;
-                default:
-                    throw new ParsingException(
-                            "Unknown node under OtherHomePartner instance: " + child.getName());
-            }
-        }
-        if (fqdn == null) {
-            throw new ParsingException("OtherHomePartner instance missing FQDN field");
-        }
-        return fqdn;
-    }
-
-    /**
-     * Parse configurations under PerProviderSubscription/Credential subtree.
-     *
-     * @param node PPSNode representing the root of the PerProviderSubscription/Credential subtree
-     * @return Credential
-     * @throws ParsingException
-     */
-    private static Credential parseCredential(PPSNode node) throws ParsingException {
-        if (node.isLeaf()) {
-            throw new ParsingException("Leaf node not expected for Credential");
-        }
-
-        Credential credential = new Credential();
-        for (PPSNode child: node.getChildren()) {
-            switch (child.getName()) {
-                case NODE_CREATION_DATE:
-                    credential.setCreationTimeInMillis(parseDate(getPpsNodeValue(child)));
-                    break;
-                case NODE_EXPIRATION_DATE:
-                    credential.setExpirationTimeInMillis(parseDate(getPpsNodeValue(child)));
-                    break;
-                case NODE_USERNAME_PASSWORD:
-                    credential.setUserCredential(parseUserCredential(child));
-                    break;
-                case NODE_DIGITAL_CERTIFICATE:
-                    credential.setCertCredential(parseCertificateCredential(child));
-                    break;
-                case NODE_REALM:
-                    credential.setRealm(getPpsNodeValue(child));
-                    break;
-                case NODE_CHECK_AAA_SERVER_CERT_STATUS:
-                    credential.setCheckAaaServerCertStatus(
-                            Boolean.parseBoolean(getPpsNodeValue(child)));
-                    break;
-                case NODE_SIM:
-                    credential.setSimCredential(parseSimCredential(child));
-                    break;
-                default:
-                    throw new ParsingException("Unknown node under Credential: " +
-                            child.getName());
-            }
-        }
-        return credential;
-    }
-
-    /**
-     * Parse configurations under PerProviderSubscription/Credential/UsernamePassword subtree.
-     *
-     * @param node PPSNode representing the root of the
-     *             PerProviderSubscription/Credential/UsernamePassword subtree
-     * @return Credential.UserCredential
-     * @throws ParsingException
-     */
-    private static Credential.UserCredential parseUserCredential(PPSNode node)
-            throws ParsingException {
-        if (node.isLeaf()) {
-            throw new ParsingException("Leaf node not expected for UsernamePassword");
-        }
-
-        Credential.UserCredential userCred = new Credential.UserCredential();
-        for (PPSNode child : node.getChildren()) {
-            switch (child.getName()) {
-                case NODE_USERNAME:
-                    userCred.setUsername(getPpsNodeValue(child));
-                    break;
-                case NODE_PASSWORD:
-                    userCred.setPassword(getPpsNodeValue(child));
-                    break;
-                case NODE_MACHINE_MANAGED:
-                    userCred.setMachineManaged(Boolean.parseBoolean(getPpsNodeValue(child)));
-                    break;
-                case NODE_SOFT_TOKEN_APP:
-                    userCred.setSoftTokenApp(getPpsNodeValue(child));
-                    break;
-                case NODE_ABLE_TO_SHARE:
-                    userCred.setAbleToShare(Boolean.parseBoolean(getPpsNodeValue(child)));
-                    break;
-                case NODE_EAP_METHOD:
-                    parseEAPMethod(child, userCred);
-                    break;
-                default:
-                    throw new ParsingException("Unknown node under UsernamePassword: "
-                            + child.getName());
-            }
-        }
-        return userCred;
-    }
-
-    /**
-     * Parse configurations under PerProviderSubscription/Credential/UsernamePassword/EAPMethod
-     * subtree.
-     *
-     * @param node PPSNode representing the root of the
-     *             PerProviderSubscription/Credential/UsernamePassword/EAPMethod subtree
-     * @param userCred UserCredential to be updated with EAP method values.
-     * @throws ParsingException
-     */
-    private static void parseEAPMethod(PPSNode node, Credential.UserCredential userCred)
-            throws ParsingException {
-        if (node.isLeaf()) {
-            throw new ParsingException("Leaf node not expected for EAPMethod");
-        }
-
-        for (PPSNode child : node.getChildren()) {
-            switch(child.getName()) {
-                case NODE_EAP_TYPE:
-                    userCred.setEapType(parseInteger(getPpsNodeValue(child)));
-                    break;
-                case NODE_INNER_METHOD:
-                    userCred.setNonEapInnerMethod(getPpsNodeValue(child));
-                    break;
-                case NODE_VENDOR_ID:
-                case NODE_VENDOR_TYPE:
-                case NODE_INNER_EAP_TYPE:
-                case NODE_INNER_VENDOR_ID:
-                case NODE_INNER_VENDOR_TYPE:
-                    // Only EAP-TTLS is currently supported for user credential, which doesn't
-                    // use any of these parameters.
-                    Log.d(TAG, "Ignore unsupported EAP method parameter: " + child.getName());
-                    break;
-                default:
-                    throw new ParsingException("Unknown node under EAPMethod: " + child.getName());
-            }
-        }
-    }
-
-    /**
-     * Parse configurations under PerProviderSubscription/Credential/DigitalCertificate subtree.
-     *
-     * @param node PPSNode representing the root of the
-     *             PerProviderSubscription/Credential/DigitalCertificate subtree
-     * @return Credential.CertificateCredential
-     * @throws ParsingException
-     */
-    private static Credential.CertificateCredential parseCertificateCredential(PPSNode node)
-            throws ParsingException {
-        if (node.isLeaf()) {
-            throw new ParsingException("Leaf node not expected for CertificateCredential");
-        }
-
-        Credential.CertificateCredential certCred = new Credential.CertificateCredential();
-        for (PPSNode child : node.getChildren()) {
-            switch (child.getName()) {
-                case NODE_CERTIFICATE_TYPE:
-                    certCred.setCertType(getPpsNodeValue(child));
-                    break;
-                case NODE_CERT_SHA256_FINGERPRINT:
-                    certCred.setCertSha256Fingerprint(parseHexString(getPpsNodeValue(child)));
-                    break;
-                default:
-                    throw new ParsingException("Unknown node under CertificateCredential: "
-                            + child.getName());
-            }
-        }
-        return certCred;
-    }
-
-    /**
-     * Parse configurations under PerProviderSubscription/Credential/SIM subtree.
-     *
-     * @param node PPSNode representing the root of the PerProviderSubscription/Credential/SIM
-     *             subtree
-     * @return Credential.SimCredential
-     * @throws ParsingException
-     */
-    private static Credential.SimCredential parseSimCredential(PPSNode node)
-            throws ParsingException {
-        if (node.isLeaf()) {
-            throw new ParsingException("Leaf node not expected for SimCredential");
-        }
-
-        Credential.SimCredential simCred = new Credential.SimCredential();
-        for (PPSNode child : node.getChildren()) {
-            switch (child.getName()) {
-                case NODE_SIM_IMSI:
-                    simCred.setImsi(getPpsNodeValue(child));
-                    break;
-                case NODE_EAP_TYPE:
-                    simCred.setEapType(parseInteger(getPpsNodeValue(child)));
-                    break;
-                default:
-                    throw new ParsingException("Unknown node under SimCredential: "
-                            + child.getName());
-            }
-        }
-        return simCred;
-    }
-
-    /**
-     * Parse configurations under PerProviderSubscription/Policy subtree.
-     *
-     * @param node PPSNode representing the root of the PerProviderSubscription/Policy subtree
-     * @return {@link Policy}
-     * @throws ParsingException
-     */
-    private static Policy parsePolicy(PPSNode node) throws ParsingException {
-        if (node.isLeaf()) {
-            throw new ParsingException("Leaf node not expected for Policy");
-        }
-
-        Policy policy = new Policy();
-        for (PPSNode child : node.getChildren()) {
-            switch (child.getName()) {
-                case NODE_PREFERRED_ROAMING_PARTNER_LIST:
-                    policy.setPreferredRoamingPartnerList(parsePreferredRoamingPartnerList(child));
-                    break;
-                case NODE_MIN_BACKHAUL_THRESHOLD:
-                    parseMinBackhaulThreshold(child, policy);
-                    break;
-                case NODE_POLICY_UPDATE:
-                    policy.setPolicyUpdate(parseUpdateParameter(child));
-                    break;
-                case NODE_SP_EXCLUSION_LIST:
-                    policy.setExcludedSsidList(parseSpExclusionList(child));
-                    break;
-                case NODE_REQUIRED_PROTO_PORT_TUPLE:
-                    policy.setRequiredProtoPortMap(parseRequiredProtoPortTuple(child));
-                    break;
-                case NODE_MAXIMUM_BSS_LOAD_VALUE:
-                    policy.setMaximumBssLoadValue(parseInteger(getPpsNodeValue(child)));
-                    break;
-                default:
-                    throw new ParsingException("Unknown node under Policy: " + child.getName());
-            }
-        }
-        return policy;
-    }
-
-    /**
-     * Parse configurations under PerProviderSubscription/Policy/PreferredRoamingPartnerList
-     * subtree.
-     *
-     * @param node PPSNode representing the root of the
-     *             PerProviderSubscription/Policy/PreferredRoamingPartnerList subtree
-     * @return List of {@link Policy#RoamingPartner}
-     * @throws ParsingException
-     */
-    private static List<Policy.RoamingPartner> parsePreferredRoamingPartnerList(PPSNode node)
-            throws ParsingException {
-        if (node.isLeaf()) {
-            throw new ParsingException("Leaf node not expected for PreferredRoamingPartnerList");
-        }
-        List<Policy.RoamingPartner> partnerList = new ArrayList<>();
-        for (PPSNode child : node.getChildren()) {
-            partnerList.add(parsePreferredRoamingPartner(child));
-        }
-        return partnerList;
-    }
-
-    /**
-     * Parse configurations under PerProviderSubscription/Policy/PreferredRoamingPartnerList/<X+>
-     * subtree.
-     *
-     * @param node PPSNode representing the root of the
-     *             PerProviderSubscription/Policy/PreferredRoamingPartnerList/<X+> subtree
-     * @return {@link Policy#RoamingPartner}
-     * @throws ParsingException
-     */
-    private static Policy.RoamingPartner parsePreferredRoamingPartner(PPSNode node)
-            throws ParsingException {
-        if (node.isLeaf()) {
-            throw new ParsingException("Leaf node not expected for PreferredRoamingPartner "
-                    + "instance");
-        }
-
-        Policy.RoamingPartner roamingPartner = new Policy.RoamingPartner();
-        for (PPSNode child : node.getChildren()) {
-            switch (child.getName()) {
-                case NODE_FQDN_MATCH:
-                    // FQDN_Match field is in the format of "[FQDN],[MatchInfo]", where [MatchInfo]
-                    // is either "exactMatch" for exact match of FQDN or "includeSubdomains" for
-                    // matching all FQDNs with the same sub-domain.
-                    String fqdnMatch = getPpsNodeValue(child);
-                    String[] fqdnMatchArray = fqdnMatch.split(",");
-                    if (fqdnMatchArray.length != 2) {
-                        throw new ParsingException("Invalid FQDN_Match: " + fqdnMatch);
-                    }
-                    roamingPartner.setFqdn(fqdnMatchArray[0]);
-                    if (TextUtils.equals(fqdnMatchArray[1], "exactMatch")) {
-                        roamingPartner.setFqdnExactMatch(true);
-                    } else if (TextUtils.equals(fqdnMatchArray[1], "includeSubdomains")) {
-                        roamingPartner.setFqdnExactMatch(false);
-                    } else {
-                        throw new ParsingException("Invalid FQDN_Match: " + fqdnMatch);
-                    }
-                    break;
-                case NODE_PRIORITY:
-                    roamingPartner.setPriority(parseInteger(getPpsNodeValue(child)));
-                    break;
-                case NODE_COUNTRY:
-                    roamingPartner.setCountries(getPpsNodeValue(child));
-                    break;
-                default:
-                    throw new ParsingException("Unknown node under PreferredRoamingPartnerList "
-                            + "instance " + child.getName());
-            }
-        }
-        return roamingPartner;
-    }
-
-    /**
-     * Parse configurations under PerProviderSubscription/Policy/MinBackhaulThreshold subtree
-     * into the given policy.
-     *
-     * @param node PPSNode representing the root of the
-     *             PerProviderSubscription/Policy/MinBackhaulThreshold subtree
-     * @param policy The policy to store the MinBackhualThreshold configuration
-     * @throws ParsingException
-     */
-    private static void parseMinBackhaulThreshold(PPSNode node, Policy policy)
-            throws ParsingException {
-        if (node.isLeaf()) {
-            throw new ParsingException("Leaf node not expected for MinBackhaulThreshold");
-        }
-        for (PPSNode child : node.getChildren()) {
-            parseMinBackhaulThresholdInstance(child, policy);
-        }
-    }
-
-    /**
-     * Parse configurations under PerProviderSubscription/Policy/MinBackhaulThreshold/<X+> subtree
-     * into the given policy.
-     *
-     * @param node PPSNode representing the root of the
-     *             PerProviderSubscription/Policy/MinBackhaulThreshold/<X+> subtree
-     * @param policy The policy to store the MinBackhaulThreshold configuration
-     * @throws ParsingException
-     */
-    private static void parseMinBackhaulThresholdInstance(PPSNode node, Policy policy)
-            throws ParsingException {
-        if (node.isLeaf()) {
-            throw new ParsingException("Leaf node not expected for MinBackhaulThreshold instance");
-        }
-        String networkType = null;
-        long downlinkBandwidth = Long.MIN_VALUE;
-        long uplinkBandwidth = Long.MIN_VALUE;
-        for (PPSNode child : node.getChildren()) {
-            switch (child.getName()) {
-                case NODE_NETWORK_TYPE:
-                    networkType = getPpsNodeValue(child);
-                    break;
-                case NODE_DOWNLINK_BANDWIDTH:
-                    downlinkBandwidth = parseLong(getPpsNodeValue(child), 10);
-                    break;
-                case NODE_UPLINK_BANDWIDTH:
-                    uplinkBandwidth = parseLong(getPpsNodeValue(child), 10);
-                    break;
-                default:
-                    throw new ParsingException("Unknown node under MinBackhaulThreshold instance "
-                            + child.getName());
-            }
-        }
-        if (networkType == null) {
-            throw new ParsingException("Missing NetworkType field");
-        }
-
-        if (TextUtils.equals(networkType, "home")) {
-            policy.setMinHomeDownlinkBandwidth(downlinkBandwidth);
-            policy.setMinHomeUplinkBandwidth(uplinkBandwidth);
-        } else if (TextUtils.equals(networkType, "roaming")) {
-            policy.setMinRoamingDownlinkBandwidth(downlinkBandwidth);
-            policy.setMinRoamingUplinkBandwidth(uplinkBandwidth);
-        } else {
-            throw new ParsingException("Invalid network type: " + networkType);
-        }
-    }
-
-    /**
-     * Parse update parameters. This contained configurations from either
-     * PerProviderSubscription/Policy/PolicyUpdate or PerProviderSubscription/SubscriptionUpdate
-     * subtree.
-     *
-     * @param node PPSNode representing the root of the PerProviderSubscription/Policy/PolicyUpdate
-     *             or PerProviderSubscription/SubscriptionUpdate subtree
-     * @return {@link UpdateParameter}
-     * @throws ParsingException
-     */
-    private static UpdateParameter parseUpdateParameter(PPSNode node)
-            throws ParsingException {
-        if (node.isLeaf()) {
-            throw new ParsingException("Leaf node not expected for Update Parameters");
-        }
-
-        UpdateParameter updateParam = new UpdateParameter();
-        for (PPSNode child : node.getChildren()) {
-            switch(child.getName()) {
-                case NODE_UPDATE_INTERVAL:
-                    updateParam.setUpdateIntervalInMinutes(parseLong(getPpsNodeValue(child), 10));
-                    break;
-                case NODE_UPDATE_METHOD:
-                    updateParam.setUpdateMethod(getPpsNodeValue(child));
-                    break;
-                case NODE_RESTRICTION:
-                    updateParam.setRestriction(getPpsNodeValue(child));
-                    break;
-                case NODE_URI:
-                    updateParam.setServerUri(getPpsNodeValue(child));
-                    break;
-                case NODE_USERNAME_PASSWORD:
-                    Pair<String, String> usernamePassword = parseUpdateUserCredential(child);
-                    updateParam.setUsername(usernamePassword.first);
-                    updateParam.setBase64EncodedPassword(usernamePassword.second);
-                    break;
-                case NODE_TRUST_ROOT:
-                    Pair<String, byte[]> trustRoot = parseTrustRoot(child);
-                    updateParam.setTrustRootCertUrl(trustRoot.first);
-                    updateParam.setTrustRootCertSha256Fingerprint(trustRoot.second);
-                    break;
-                case NODE_OTHER:
-                    Log.d(TAG, "Ignore unsupported paramter: " + child.getName());
-                    break;
-                default:
-                    throw new ParsingException("Unknown node under Update Parameters: "
-                            + child.getName());
-            }
-        }
-        return updateParam;
-    }
-
-    /**
-     * Parse username and password parameters associated with policy or subscription update.
-     * This contained configurations under either
-     * PerProviderSubscription/Policy/PolicyUpdate/UsernamePassword or
-     * PerProviderSubscription/SubscriptionUpdate/UsernamePassword subtree.
-     *
-     * @param node PPSNode representing the root of the UsernamePassword subtree
-     * @return Pair of username and password
-     * @throws ParsingException
-     */
-    private static Pair<String, String> parseUpdateUserCredential(PPSNode node)
-            throws ParsingException {
-        if (node.isLeaf()) {
-            throw new ParsingException("Leaf node not expected for UsernamePassword");
-        }
-
-        String username = null;
-        String password = null;
-        for (PPSNode child : node.getChildren()) {
-            switch (child.getName()) {
-                case NODE_USERNAME:
-                    username = getPpsNodeValue(child);
-                    break;
-                case NODE_PASSWORD:
-                    password = getPpsNodeValue(child);
-                    break;
-                default:
-                    throw new ParsingException("Unknown node under UsernamePassword: "
-                            + child.getName());
-            }
-        }
-        return Pair.create(username, password);
-    }
-
-    /**
-     * Parse the trust root parameters associated with policy update, subscription update, or AAA
-     * server trust root.
-     *
-     * This contained configurations under either
-     * PerProviderSubscription/Policy/PolicyUpdate/TrustRoot or
-     * PerProviderSubscription/SubscriptionUpdate/TrustRoot or
-     * PerProviderSubscription/AAAServerTrustRoot/<X+> subtree.
-     *
-     * @param node PPSNode representing the root of the TrustRoot subtree
-     * @return Pair of Certificate URL and fingerprint
-     * @throws ParsingException
-     */
-    private static Pair<String, byte[]> parseTrustRoot(PPSNode node)
-            throws ParsingException {
-        if (node.isLeaf()) {
-            throw new ParsingException("Leaf node not expected for TrustRoot");
-        }
-
-        String certUrl = null;
-        byte[] certFingerprint = null;
-        for (PPSNode child : node.getChildren()) {
-            switch (child.getName()) {
-                case NODE_CERT_URL:
-                    certUrl = getPpsNodeValue(child);
-                    break;
-                case NODE_CERT_SHA256_FINGERPRINT:
-                    certFingerprint = parseHexString(getPpsNodeValue(child));
-                    break;
-                default:
-                    throw new ParsingException("Unknown node under TrustRoot: "
-                            + child.getName());
-            }
-        }
-        return Pair.create(certUrl, certFingerprint);
-    }
-
-    /**
-     * Parse configurations under PerProviderSubscription/Policy/SPExclusionList subtree.
-     *
-     * @param node PPSNode representing the root of the
-     *             PerProviderSubscription/Policy/SPExclusionList subtree
-     * @return Array of excluded SSIDs
-     * @throws ParsingException
-     */
-    private static String[] parseSpExclusionList(PPSNode node) throws ParsingException {
-        if (node.isLeaf()) {
-            throw new ParsingException("Leaf node not expected for SPExclusionList");
-        }
-        List<String> ssidList = new ArrayList<>();
-        for (PPSNode child : node.getChildren()) {
-            ssidList.add(parseSpExclusionInstance(child));
-        }
-        return ssidList.toArray(new String[ssidList.size()]);
-    }
-
-    /**
-     * Parse configurations under PerProviderSubscription/Policy/SPExclusionList/<X+> subtree.
-     *
-     * @param node PPSNode representing the root of the
-     *             PerProviderSubscription/Policy/SPExclusionList/<X+> subtree
-     * @return String
-     * @throws ParsingException
-     */
-    private static String parseSpExclusionInstance(PPSNode node) throws ParsingException {
-        if (node.isLeaf()) {
-            throw new ParsingException("Leaf node not expected for SPExclusion instance");
-        }
-        String ssid = null;
-        for (PPSNode child : node.getChildren()) {
-            switch (child.getName()) {
-                case NODE_SSID:
-                    ssid = getPpsNodeValue(child);
-                    break;
-                default:
-                    throw new ParsingException("Unknown node under SPExclusion instance");
-            }
-        }
-        return ssid;
-    }
-
-    /**
-     * Parse configurations under PerProviderSubscription/Policy/RequiredProtoPortTuple subtree.
-     *
-     * @param node PPSNode representing the root of the
-     *             PerProviderSubscription/Policy/RequiredProtoPortTuple subtree
-     * @return Map of IP Protocol to Port Number tuples
-     * @throws ParsingException
-     */
-    private static Map<Integer, String> parseRequiredProtoPortTuple(PPSNode node)
-            throws ParsingException {
-        if (node.isLeaf()) {
-            throw new ParsingException("Leaf node not expected for RequiredProtoPortTuple");
-        }
-        Map<Integer, String> protoPortTupleMap = new HashMap<>();
-        for (PPSNode child : node.getChildren()) {
-            Pair<Integer, String> protoPortTuple = parseProtoPortTuple(child);
-            protoPortTupleMap.put(protoPortTuple.first, protoPortTuple.second);
-        }
-        return protoPortTupleMap;
-    }
-
-    /**
-     * Parse configurations under PerProviderSubscription/Policy/RequiredProtoPortTuple/<X+>
-     * subtree.
-     *
-     * @param node PPSNode representing the root of the
-     *             PerProviderSubscription/Policy/RequiredProtoPortTuple/<X+> subtree
-     * @return Pair of IP Protocol to Port Number tuple
-     * @throws ParsingException
-     */
-    private static Pair<Integer, String> parseProtoPortTuple(PPSNode node)
-            throws ParsingException {
-        if (node.isLeaf()) {
-            throw new ParsingException("Leaf node not expected for RequiredProtoPortTuple "
-                    + "instance");
-        }
-        int proto = Integer.MIN_VALUE;
-        String ports = null;
-        for (PPSNode child : node.getChildren()) {
-            switch (child.getName()) {
-                case NODE_IP_PROTOCOL:
-                    proto = parseInteger(getPpsNodeValue(child));
-                    break;
-                case NODE_PORT_NUMBER:
-                    ports = getPpsNodeValue(child);
-                    break;
-                default:
-                    throw new ParsingException("Unknown node under RequiredProtoPortTuple instance"
-                            + child.getName());
-            }
-        }
-        if (proto == Integer.MIN_VALUE) {
-            throw new ParsingException("Missing IPProtocol field");
-        }
-        if (ports == null) {
-            throw new ParsingException("Missing PortNumber field");
-        }
-        return Pair.create(proto, ports);
-    }
-
-    /**
-     * Parse configurations under PerProviderSubscription/AAAServerTrustRoot subtree.
-     *
-     * @param node PPSNode representing the root of PerProviderSubscription/AAAServerTrustRoot
-     *             subtree
-     * @return Map of certificate URL with the corresponding certificate fingerprint
-     * @throws ParsingException
-     */
-    private static Map<String, byte[]> parseAAAServerTrustRootList(PPSNode node)
-            throws ParsingException {
-        if (node.isLeaf()) {
-            throw new ParsingException("Leaf node not expected for AAAServerTrustRoot");
-        }
-        Map<String, byte[]> certList = new HashMap<>();
-        for (PPSNode child : node.getChildren()) {
-            Pair<String, byte[]> certTuple = parseTrustRoot(child);
-            certList.put(certTuple.first, certTuple.second);
-        }
-        return certList;
-    }
-
-    /**
-     * Parse configurations under PerProviderSubscription/SubscriptionParameter subtree.
-     *
-     * @param node PPSNode representing the root of PerProviderSubscription/SubscriptionParameter
-     *             subtree
-     * @param config Instance of {@link PasspointConfiguration}
-     * @throws ParsingException
-     */
-    private static void parseSubscriptionParameter(PPSNode node, PasspointConfiguration config)
-            throws ParsingException {
-        if (node.isLeaf()) {
-            throw new ParsingException("Leaf node not expected for SubscriptionParameter");
-        }
-        for (PPSNode child : node.getChildren()) {
-            switch (child.getName()) {
-                case NODE_CREATION_DATE:
-                    config.setSubscriptionCreationTimeInMillis(parseDate(getPpsNodeValue(child)));
-                    break;
-                case NODE_EXPIRATION_DATE:
-                    config.setSubscriptionExpirationTimeInMillis(parseDate(getPpsNodeValue(child)));
-                    break;
-                case NODE_TYPE_OF_SUBSCRIPTION:
-                    config.setSubscriptionType(getPpsNodeValue(child));
-                    break;
-                case NODE_USAGE_LIMITS:
-                    parseUsageLimits(child, config);
-                    break;
-                default:
-                    throw new ParsingException("Unknown node under SubscriptionParameter"
-                            + child.getName());
-            }
-        }
-    }
-
-    /**
-     * Parse configurations under PerProviderSubscription/SubscriptionParameter/UsageLimits
-     * subtree.
-     *
-     * @param node PPSNode representing the root of
-     *             PerProviderSubscription/SubscriptionParameter/UsageLimits subtree
-     * @param config Instance of {@link PasspointConfiguration}
-     * @throws ParsingException
-     */
-    private static void parseUsageLimits(PPSNode node, PasspointConfiguration config)
-            throws ParsingException {
-        if (node.isLeaf()) {
-            throw new ParsingException("Leaf node not expected for UsageLimits");
-        }
-        for (PPSNode child : node.getChildren()) {
-            switch (child.getName()) {
-                case NODE_DATA_LIMIT:
-                    config.setUsageLimitDataLimit(parseLong(getPpsNodeValue(child), 10));
-                    break;
-                case NODE_START_DATE:
-                    config.setUsageLimitStartTimeInMillis(parseDate(getPpsNodeValue(child)));
-                    break;
-                case NODE_TIME_LIMIT:
-                    config.setUsageLimitTimeLimitInMinutes(parseLong(getPpsNodeValue(child), 10));
-                    break;
-                case NODE_USAGE_TIME_PERIOD:
-                    config.setUsageLimitUsageTimePeriodInMinutes(
-                            parseLong(getPpsNodeValue(child), 10));
-                    break;
-                default:
-                    throw new ParsingException("Unknown node under UsageLimits"
-                            + child.getName());
-            }
-        }
-    }
-
-    /**
-     * Parse configurations under PerProviderSubscription/Extension/Android/AAAServerTrustedNames
-     * subtree.
-     *
-     * @param node PPSNode representing the root of the
-     *             PerProviderSubscription/Extension/Android/AAAServerTrustedNames subtree
-     * @return String[] list of trusted name
-     * @throws ParsingException
-     */
-    private static String[] parseAaaServerTrustedNames(PPSNode node) throws ParsingException {
-        if (node.isLeaf()) {
-            throw new ParsingException("Leaf node not expected for AAAServerTrustedNames instance");
-        }
-        String fqdnListStr = null;
-        String[] fqdnListArray = null;
-        for (PPSNode child : node.getChildren()) {
-            switch (child.getName()) {
-                case NODE_FQDN:
-                    fqdnListStr = getPpsNodeValue(child);
-                    fqdnListArray = fqdnListStr.split(";");
-                    break;
-                default:
-                    throw new ParsingException(
-                            "Unknown node under AAAServerTrustedNames instance: "
-                            + child.getName());
-            }
-        }
-        if (fqdnListArray == null) {
-            throw new ParsingException("AAAServerTrustedNames instance missing FQDN field");
-        }
-
-        return fqdnListArray;
-    }
-
-    /**
-     * Parse configurations under PerProviderSubscription/Extension/Android subtree.
-     *
-     * @param node PPSNode representing the root of PerProviderSubscription/Extension
-     *             subtree
-     * @param config Instance of {@link PasspointConfiguration}
-     * @throws ParsingException
-     */
-    private static void parseVendorAndroidExtension(PPSNode node, PasspointConfiguration config)
-            throws ParsingException {
-        if (node.isLeaf()) {
-            throw new ParsingException("Leaf node not expected for AndroidExtension");
-        }
-        for (PPSNode child : node.getChildren()) {
-            switch (child.getName()) {
-                case NODE_AAA_SERVER_TRUSTED_NAMES:
-                    config.setAaaServerTrustedNames(parseAaaServerTrustedNames(child));
-                    break;
-                default:
-                    // Don't raise an exception for unknown nodes to avoid breaking old release
-                    Log.w(TAG, "Unknown node under Android Extension: " + child.getName());
-            }
-        }
-    }
-
-    /**
-     * Parse configurations under PerProviderSubscription/Extension subtree.
-     *
-     * @param node PPSNode representing the root of PerProviderSubscription/Extension
-     *             subtree
-     * @param config Instance of {@link PasspointConfiguration}
-     * @throws ParsingException
-     */
-    private static void parseExtension(PPSNode node, PasspointConfiguration config)
-            throws ParsingException {
-        if (node.isLeaf()) {
-            throw new ParsingException("Leaf node not expected for Extension");
-        }
-        for (PPSNode child : node.getChildren()) {
-            switch (child.getName()) {
-                case NODE_VENDOR_ANDROID:
-                    parseVendorAndroidExtension(child, config);
-                    break;
-                default:
-                    // Unknown nodes under Extension won't raise exception.
-                    // This allows adding new nodes in the future and
-                    // won't break older release.
-                    Log.w(TAG, "Unknown node under Extension: " + child.getName());
-            }
-        }
-    }
-
-    /**
-     * Convert a hex string to a byte array.
-     *
-     * @param str String containing hex values
-     * @return byte[]
-     * @throws ParsingException
-     */
-    private static byte[] parseHexString(String str) throws ParsingException {
-        if ((str.length() & 1) == 1) {
-            throw new ParsingException("Odd length hex string: " + str + ", length: "
-                    + str.length());
-        }
-
-        byte[] result = new byte[str.length() / 2];
-        for (int i = 0; i < result.length; i++) {
-          int index = i * 2;
-          try {
-              result[i] = (byte) Integer.parseInt(str.substring(index, index + 2), 16);
-          } catch (NumberFormatException e) {
-              throw new ParsingException("Invalid hex string: " + str);
-          }
-        }
-        return result;
-    }
-
-    /**
-     * Convert a date string to the number of milliseconds since January 1, 1970, 00:00:00 GMT.
-     *
-     * @param dateStr String in the format of yyyy-MM-dd'T'HH:mm:ss'Z'
-     * @return number of milliseconds
-     * @throws ParsingException
-     */
-    private static long parseDate(String dateStr) throws ParsingException {
-        try {
-            DateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
-            return format.parse(dateStr).getTime();
-        } catch (ParseException pe) {
-            throw new ParsingException("Badly formatted time: " + dateStr);
-        }
-    }
-
-    /**
-     * Parse an integer string.
-     *
-     * @param value String of integer value
-     * @return int
-     * @throws ParsingException
-     */
-    private static int parseInteger(String value) throws ParsingException {
-        try {
-            return Integer.parseInt(value);
-        } catch (NumberFormatException e) {
-            throw new ParsingException("Invalid integer value: " + value);
-        }
-    }
-
-    /**
-     * Parse a string representing a long integer.
-     *
-     * @param value String of long integer value
-     * @return long
-     * @throws ParsingException
-     */
-    private static long parseLong(String value, int radix) throws ParsingException {
-        try {
-            return Long.parseLong(value, radix);
-        } catch (NumberFormatException e) {
-            throw new ParsingException("Invalid long integer value: " + value);
-        }
-    }
-
-    /**
-     * Convert a List<Long> to a primitive long array long[].
-     *
-     * @param list List to be converted
-     * @return long[]
-     */
-    private static long[] convertFromLongList(List<Long> list) {
-        Long[] objectArray = list.toArray(new Long[list.size()]);
-        long[] primitiveArray = new long[objectArray.length];
-        for (int i = 0; i < objectArray.length; i++) {
-            primitiveArray[i] = objectArray[i].longValue();
-        }
-        return primitiveArray;
-    }
-}
diff --git a/wifi/java/android/net/wifi/hotspot2/omadm/XMLNode.java b/wifi/java/android/net/wifi/hotspot2/omadm/XMLNode.java
deleted file mode 100644
index 959d505..0000000
--- a/wifi/java/android/net/wifi/hotspot2/omadm/XMLNode.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/**
- * Copyright (c) 2016, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.hotspot2.omadm;
-
-import android.text.TextUtils;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * A class represent a node in an XML tree. Each node is an XML element.
- * Used by {@link XMLParser} for parsing/converting each XML element to XMLNode.
- *
- * @hide
- */
-public class XMLNode {
-    private final String mTag;
-    private final List<XMLNode> mChildren;
-    private final XMLNode mParent;
-    private StringBuilder mTextBuilder;
-    private String mText;
-
-    public XMLNode(XMLNode parent, String tag) {
-        mTag = tag;
-        mParent = parent;
-        mChildren = new ArrayList<>();
-        mTextBuilder = new StringBuilder();
-        mText = null;
-    }
-
-    /**
-     * Adding a text to this node. Invoked by {@link XMLParser#characters}.
-     *
-     * @param text String to be added
-     */
-    public void addText(String text) {
-        mTextBuilder.append(text);
-    }
-
-    /**
-     * Adding a child node to this node. Invoked by {@link XMLParser#startElement}.
-     *
-     * @param child XMLNode to be added
-     */
-    public void addChild(XMLNode child) {
-        mChildren.add(child);
-    }
-
-    /**
-     * Invoked when the end of the XML element is detected. Used for further processing
-     * of the text enclosed within this XML element. Invoked by {@link XMLParser#endElement}.
-     */
-    public void close() {
-        // Remove the leading and the trailing whitespaces.
-        mText = mTextBuilder.toString().trim();
-        mTextBuilder = null;
-    }
-
-    public String getTag() {
-        return mTag;
-    }
-
-    public XMLNode getParent() {
-        return mParent;
-    }
-
-    public String getText() {
-        return mText;
-    }
-
-    public List<XMLNode> getChildren() {
-        return mChildren;
-    }
-
-    @Override
-    public boolean equals(Object thatObject) {
-        if (this == thatObject) {
-            return true;
-        }
-        if (!(thatObject instanceof XMLNode)) {
-            return false;
-        }
-        XMLNode that = (XMLNode) thatObject;
-
-        return TextUtils.equals(mTag, that.mTag) &&
-                TextUtils.equals(mText, that.mText) &&
-                mChildren.equals(that.mChildren);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(mTag, mText, mChildren);
-    }
-}
diff --git a/wifi/java/android/net/wifi/hotspot2/omadm/XMLParser.java b/wifi/java/android/net/wifi/hotspot2/omadm/XMLParser.java
deleted file mode 100644
index 948052c..0000000
--- a/wifi/java/android/net/wifi/hotspot2/omadm/XMLParser.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.hotspot2.omadm;
-
-import org.xml.sax.Attributes;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-import org.xml.sax.helpers.DefaultHandler;
-
-import android.text.TextUtils;
-
-import java.io.IOException;
-import java.io.StringReader;
-
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
-
-/**
- * Class for parsing an XML string to an XML tree represented by {@link XMLNode}.
- *
- * The original XML string:
- * <root>
- *   <tag1>text1</tag1>
- *   <tag2>
- *     <tag3>text3</tag3>
- *   </tag2>
- * </root>
- *
- * The XML tree representation:
- *                  [root]
- *                     |
- *                     |
- *   [tag1, text1]-----|-----[tag2]
- *                             |
- *                             |
- *                       [tag3, text3]
- *
- * @hide
- */
-public class XMLParser extends DefaultHandler {
-    private XMLNode mRoot = null;
-    private XMLNode mCurrent = null;
-
-    public XMLNode parse(String text) throws IOException, SAXException {
-        if (TextUtils.isEmpty(text)) {
-            throw new IOException("XML string not provided");
-        }
-
-        // Reset pointers.
-        mRoot = null;
-        mCurrent = null;
-
-        try {
-            SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
-            parser.parse(new InputSource(new StringReader(text)), this);
-            return mRoot;
-        } catch (ParserConfigurationException pce) {
-            throw new SAXException(pce);
-        }
-    }
-
-    @Override
-    public void startElement(String uri, String localName, String qName, Attributes attributes)
-            throws SAXException {
-        XMLNode parent = mCurrent;
-
-        mCurrent = new XMLNode(parent, qName);
-
-        if (mRoot == null) {
-            mRoot = mCurrent;
-        } else if (parent == null) {
-            throw new SAXException("More than one root nodes");
-        } else {
-            parent.addChild(mCurrent);
-        }
-    }
-
-    @Override
-    public void endElement(String uri, String localName, String qName) throws SAXException {
-        if (!qName.equals(mCurrent.getTag())) {
-            throw new SAXException("End tag '" + qName + "' doesn't match current node: " +
-                    mCurrent);
-        }
-
-        mCurrent.close();
-        mCurrent = mCurrent.getParent();
-    }
-
-    @Override
-    public void characters(char[] ch, int start, int length) throws SAXException {
-        mCurrent.addText(new String(ch, start, length));
-    }
-}
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/Credential.java b/wifi/java/android/net/wifi/hotspot2/pps/Credential.java
deleted file mode 100644
index 282757a..0000000
--- a/wifi/java/android/net/wifi/hotspot2/pps/Credential.java
+++ /dev/null
@@ -1,1313 +0,0 @@
-/**
- * Copyright (c) 2016, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.hotspot2.pps;
-
-import android.net.wifi.EAPConstants;
-import android.net.wifi.ParcelUtil;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-import android.util.Log;
-
-import java.nio.charset.StandardCharsets;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.X509Certificate;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.Objects;
-import java.util.Set;
-
-/**
- * Class representing Credential subtree in the PerProviderSubscription (PPS)
- * Management Object (MO) tree.
- * For more info, refer to Hotspot 2.0 PPS MO defined in section 9.1 of the Hotspot 2.0
- * Release 2 Technical Specification.
- *
- * In addition to the fields in the Credential subtree, this will also maintain necessary
- * information for the private key and certificates associated with this credential.
- */
-public final class Credential implements Parcelable {
-    private static final String TAG = "Credential";
-
-    /**
-     * Max string length for realm.  Refer to Credential/Realm node in Hotspot 2.0 Release 2
-     * Technical Specification Section 9.1 for more info.
-     */
-    private static final int MAX_REALM_BYTES = 253;
-
-    /**
-     * The time this credential is created. It is in the format of number
-     * of milliseconds since January 1, 1970, 00:00:00 GMT.
-     * Using Long.MIN_VALUE to indicate unset value.
-     */
-    private long mCreationTimeInMillis = Long.MIN_VALUE;
-    /**
-     * @hide
-     */
-    public void setCreationTimeInMillis(long creationTimeInMillis) {
-        mCreationTimeInMillis = creationTimeInMillis;
-    }
-    /**
-     * @hide
-     */
-    public long getCreationTimeInMillis() {
-        return mCreationTimeInMillis;
-    }
-
-    /**
-     * The time this credential will expire. It is in the format of number
-     * of milliseconds since January 1, 1970, 00:00:00 GMT.
-    * Using Long.MIN_VALUE to indicate unset value.
-     */
-    private long mExpirationTimeInMillis = Long.MIN_VALUE;
-    /**
-     * @hide
-     */
-    public void setExpirationTimeInMillis(long expirationTimeInMillis) {
-        mExpirationTimeInMillis = expirationTimeInMillis;
-    }
-    /**
-     * @hide
-     */
-    public long getExpirationTimeInMillis() {
-        return mExpirationTimeInMillis;
-    }
-
-    /**
-     * The realm associated with this credential.  It will be used to determine
-     * if this credential can be used to authenticate with a given hotspot by
-     * comparing the realm specified in that hotspot's ANQP element.
-     */
-    private String mRealm = null;
-    /**
-     * Set the realm associated with this credential.
-     *
-     * @param realm The realm to set to
-     */
-    public void setRealm(String realm) {
-        mRealm = realm;
-    }
-    /**
-     * Get the realm associated with this credential.
-     *
-     * @return the realm associated with this credential
-     */
-    public String getRealm() {
-        return mRealm;
-    }
-
-    /**
-     * When set to true, the device should check AAA (Authentication, Authorization,
-     * and Accounting) server's certificate during EAP (Extensible Authentication
-     * Protocol) authentication.
-     */
-    private boolean mCheckAaaServerCertStatus = false;
-    /**
-     * @hide
-     */
-    public void setCheckAaaServerCertStatus(boolean checkAaaServerCertStatus) {
-        mCheckAaaServerCertStatus = checkAaaServerCertStatus;
-    }
-    /**
-     * @hide
-     */
-    public boolean getCheckAaaServerCertStatus() {
-        return mCheckAaaServerCertStatus;
-    }
-
-    /**
-     * Username-password based credential.
-     * Contains the fields under PerProviderSubscription/Credential/UsernamePassword subtree.
-     */
-    public static final class UserCredential implements Parcelable {
-        /**
-         * Maximum string length for username.  Refer to Credential/UsernamePassword/Username
-         * node in Hotspot 2.0 Release 2 Technical Specification Section 9.1 for more info.
-         */
-        private static final int MAX_USERNAME_BYTES = 63;
-
-        /**
-         * Maximum string length for password.  Refer to Credential/UsernamePassword/Password
-         * in Hotspot 2.0 Release 2 Technical Specification Section 9.1 for more info.
-         */
-        private static final int MAX_PASSWORD_BYTES = 255;
-
-        /**
-         * Supported authentication methods.
-         * @hide
-         */
-        public static final String AUTH_METHOD_PAP = "PAP";
-        /** @hide */
-        public static final String AUTH_METHOD_MSCHAP = "MS-CHAP";
-        /** @hide */
-        public static final String AUTH_METHOD_MSCHAPV2 = "MS-CHAP-V2";
-
-        /**
-         * Supported Non-EAP inner methods.  Refer to
-         * Credential/UsernamePassword/EAPMethod/InnerEAPType in Hotspot 2.0 Release 2 Technical
-         * Specification Section 9.1 for more info.
-         */
-        private static final Set<String> SUPPORTED_AUTH = new HashSet<String>(
-                Arrays.asList(AUTH_METHOD_PAP, AUTH_METHOD_MSCHAP, AUTH_METHOD_MSCHAPV2));
-
-        /**
-         * Username of the credential.
-         */
-        private String mUsername = null;
-        /**
-         * Set the username associated with this user credential.
-         *
-         * @param username The username to set to
-         */
-        public void setUsername(String username) {
-            mUsername = username;
-        }
-        /**
-         * Get the username associated with this user credential.
-         *
-         * @return the username associated with this user credential
-         */
-        public String getUsername() {
-            return mUsername;
-        }
-
-        /**
-         * Base64-encoded password.
-         */
-        private String mPassword = null;
-        /**
-         * Set the Base64-encoded password associated with this user credential.
-         *
-         * @param password The password to set to
-         */
-        public void setPassword(String password) {
-            mPassword = password;
-        }
-        /**
-         * Get the Base64-encoded password associated with this user credential.
-         *
-         * @return the Base64-encoded password associated with this user credential
-         */
-        public String getPassword() {
-            return mPassword;
-        }
-
-        /**
-         * Flag indicating if the password is machine managed.
-         */
-        private boolean mMachineManaged = false;
-        /**
-         * @hide
-         */
-        public void setMachineManaged(boolean machineManaged) {
-            mMachineManaged = machineManaged;
-        }
-        /**
-         * @hide
-         */
-        public boolean getMachineManaged() {
-            return mMachineManaged;
-        }
-
-        /**
-         * The name of the application used to generate the password.
-         */
-        private String mSoftTokenApp = null;
-        /**
-         * @hide
-         */
-        public void setSoftTokenApp(String softTokenApp) {
-            mSoftTokenApp = softTokenApp;
-        }
-        /**
-         * @hide
-         */
-        public String getSoftTokenApp() {
-            return mSoftTokenApp;
-        }
-
-        /**
-         * Flag indicating if this credential is usable on other mobile devices as well.
-         */
-        private boolean mAbleToShare = false;
-        /**
-         * @hide
-         */
-        public void setAbleToShare(boolean ableToShare) {
-            mAbleToShare = ableToShare;
-        }
-        /**
-         * @hide
-         */
-        public boolean getAbleToShare() {
-            return mAbleToShare;
-        }
-
-        /**
-         * EAP (Extensible Authentication Protocol) method type.
-         * Refer to
-         * <a href="http://www.iana.org/assignments/eap-numbers/eap-numbers.xml#eap-numbers-4">
-         * EAP Numbers</a> for valid values.
-         * Using Integer.MIN_VALUE to indicate unset value.
-         */
-        private int mEapType = Integer.MIN_VALUE;
-        /**
-         * Set the EAP (Extensible Authentication Protocol) method type associated with this
-         * user credential.
-         * Refer to
-         * <a href="http://www.iana.org/assignments/eap-numbers/eap-numbers.xml#eap-numbers-4">
-         * EAP Numbers</a> for valid values.
-         *
-         * @param eapType The EAP method type associated with this user credential
-         */
-        public void setEapType(int eapType) {
-            mEapType = eapType;
-        }
-        /**
-         * Get the EAP (Extensible Authentication Protocol) method type associated with this
-         * user credential.
-         *
-         * @return EAP method type
-         */
-        public int getEapType() {
-            return mEapType;
-        }
-
-        /**
-         * Non-EAP inner authentication method.
-         */
-        private String mNonEapInnerMethod = null;
-        /**
-         * Set the inner non-EAP method associated with this user credential.
-         *
-         * @param nonEapInnerMethod The non-EAP inner method to set to
-         */
-        public void setNonEapInnerMethod(String nonEapInnerMethod) {
-            mNonEapInnerMethod = nonEapInnerMethod;
-        }
-        /**
-         * Get the inner non-EAP method associated with this user credential.
-         *
-         * @return Non-EAP inner method associated with this user credential
-         */
-        public String getNonEapInnerMethod() {
-            return mNonEapInnerMethod;
-        }
-
-        /**
-         * Constructor for creating UserCredential with default values.
-         */
-        public UserCredential() {}
-
-        /**
-         * Copy constructor.
-         *
-         * @param source The source to copy from
-         */
-        public UserCredential(UserCredential source) {
-            if (source != null) {
-                mUsername = source.mUsername;
-                mPassword = source.mPassword;
-                mMachineManaged = source.mMachineManaged;
-                mSoftTokenApp = source.mSoftTokenApp;
-                mAbleToShare = source.mAbleToShare;
-                mEapType = source.mEapType;
-                mNonEapInnerMethod = source.mNonEapInnerMethod;
-            }
-        }
-
-        @Override
-        public int describeContents() {
-            return 0;
-        }
-
-        @Override
-        public void writeToParcel(Parcel dest, int flags) {
-            dest.writeString(mUsername);
-            dest.writeString(mPassword);
-            dest.writeInt(mMachineManaged ? 1 : 0);
-            dest.writeString(mSoftTokenApp);
-            dest.writeInt(mAbleToShare ? 1 : 0);
-            dest.writeInt(mEapType);
-            dest.writeString(mNonEapInnerMethod);
-        }
-
-        @Override
-        public boolean equals(Object thatObject) {
-            if (this == thatObject) {
-                return true;
-            }
-            if (!(thatObject instanceof UserCredential)) {
-                return false;
-            }
-
-            UserCredential that = (UserCredential) thatObject;
-            return TextUtils.equals(mUsername, that.mUsername)
-                    && TextUtils.equals(mPassword, that.mPassword)
-                    && mMachineManaged == that.mMachineManaged
-                    && TextUtils.equals(mSoftTokenApp, that.mSoftTokenApp)
-                    && mAbleToShare == that.mAbleToShare
-                    && mEapType == that.mEapType
-                    && TextUtils.equals(mNonEapInnerMethod, that.mNonEapInnerMethod);
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(mUsername, mPassword, mMachineManaged, mSoftTokenApp,
-                    mAbleToShare, mEapType, mNonEapInnerMethod);
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder builder = new StringBuilder();
-            builder.append("Username: ").append(mUsername).append("\n");
-            builder.append("MachineManaged: ").append(mMachineManaged).append("\n");
-            builder.append("SoftTokenApp: ").append(mSoftTokenApp).append("\n");
-            builder.append("AbleToShare: ").append(mAbleToShare).append("\n");
-            builder.append("EAPType: ").append(mEapType).append("\n");
-            builder.append("AuthMethod: ").append(mNonEapInnerMethod).append("\n");
-            return builder.toString();
-        }
-
-        /**
-         * Validate the configuration data.
-         *
-         * @return true on success or false on failure
-         * @hide
-         */
-        public boolean validate() {
-            if (TextUtils.isEmpty(mUsername)) {
-                Log.d(TAG, "Missing username");
-                return false;
-            }
-            if (mUsername.getBytes(StandardCharsets.UTF_8).length > MAX_USERNAME_BYTES) {
-                Log.d(TAG, "username exceeding maximum length: "
-                        + mUsername.getBytes(StandardCharsets.UTF_8).length);
-                return false;
-            }
-
-            if (TextUtils.isEmpty(mPassword)) {
-                Log.d(TAG, "Missing password");
-                return false;
-            }
-            if (mPassword.getBytes(StandardCharsets.UTF_8).length > MAX_PASSWORD_BYTES) {
-                Log.d(TAG, "password exceeding maximum length: "
-                        + mPassword.getBytes(StandardCharsets.UTF_8).length);
-                return false;
-            }
-
-            // Only supports EAP-TTLS for user credential.
-            if (mEapType != EAPConstants.EAP_TTLS) {
-                Log.d(TAG, "Invalid EAP Type for user credential: " + mEapType);
-                return false;
-            }
-
-            // Verify Non-EAP inner method for EAP-TTLS.
-            if (!SUPPORTED_AUTH.contains(mNonEapInnerMethod)) {
-                Log.d(TAG, "Invalid non-EAP inner method for EAP-TTLS: " + mNonEapInnerMethod);
-                return false;
-            }
-            return true;
-        }
-
-        public static final @android.annotation.NonNull Creator<UserCredential> CREATOR =
-            new Creator<UserCredential>() {
-                @Override
-                public UserCredential createFromParcel(Parcel in) {
-                    UserCredential userCredential = new UserCredential();
-                    userCredential.setUsername(in.readString());
-                    userCredential.setPassword(in.readString());
-                    userCredential.setMachineManaged(in.readInt() != 0);
-                    userCredential.setSoftTokenApp(in.readString());
-                    userCredential.setAbleToShare(in.readInt() != 0);
-                    userCredential.setEapType(in.readInt());
-                    userCredential.setNonEapInnerMethod(in.readString());
-                    return userCredential;
-                }
-
-                @Override
-                public UserCredential[] newArray(int size) {
-                    return new UserCredential[size];
-                }
-            };
-
-        /**
-         * Get a unique identifier for UserCredential.
-         *
-         * @hide
-         * @return a Unique identifier for a UserCredential object
-         */
-        public int getUniqueId() {
-            return Objects.hash(mUsername);
-        }
-    }
-    private UserCredential mUserCredential = null;
-    /**
-     * Set the user credential information.
-     *
-     * @param userCredential The user credential to set to
-     */
-    public void setUserCredential(UserCredential userCredential) {
-        mUserCredential = userCredential;
-    }
-    /**
-     * Get the user credential information.
-     *
-     * @return user credential information
-     */
-    public UserCredential getUserCredential() {
-        return mUserCredential;
-    }
-
-    /**
-     * Certificate based credential.  This is used for EAP-TLS.
-     * Contains fields under PerProviderSubscription/Credential/DigitalCertificate subtree.
-     */
-    public static final class CertificateCredential implements Parcelable {
-        /**
-         * Supported certificate types.
-         * @hide
-         */
-        public static final String CERT_TYPE_X509V3 = "x509v3";
-
-        /**
-         * Certificate SHA-256 fingerprint length.
-         */
-        private static final int CERT_SHA256_FINGER_PRINT_LENGTH = 32;
-
-        /**
-         * Certificate type.
-         */
-        private String mCertType = null;
-        /**
-         * Set the certificate type associated with this certificate credential.
-         *
-         * @param certType The certificate type to set to
-         */
-        public void setCertType(String certType) {
-            mCertType = certType;
-        }
-        /**
-         * Get the certificate type associated with this certificate credential.
-         *
-         * @return certificate type
-         */
-        public String getCertType() {
-            return mCertType;
-        }
-
-        /**
-         * The SHA-256 fingerprint of the certificate.
-         */
-        private byte[] mCertSha256Fingerprint = null;
-        /**
-         * Set the certificate SHA-256 fingerprint associated with this certificate credential.
-         *
-         * @param certSha256Fingerprint The certificate fingerprint to set to
-         */
-        public void setCertSha256Fingerprint(byte[] certSha256Fingerprint) {
-            mCertSha256Fingerprint = certSha256Fingerprint;
-        }
-        /**
-         * Get the certificate SHA-256 fingerprint associated with this certificate credential.
-         *
-         * @return certificate SHA-256 fingerprint
-         */
-        public byte[] getCertSha256Fingerprint() {
-            return mCertSha256Fingerprint;
-        }
-
-        /**
-         * Constructor for creating CertificateCredential with default values.
-         */
-        public CertificateCredential() {}
-
-        /**
-         * Copy constructor.
-         *
-         * @param source The source to copy from
-         */
-        public CertificateCredential(CertificateCredential source) {
-            if (source != null) {
-                mCertType = source.mCertType;
-                if (source.mCertSha256Fingerprint != null) {
-                    mCertSha256Fingerprint = Arrays.copyOf(source.mCertSha256Fingerprint,
-                                                          source.mCertSha256Fingerprint.length);
-                }
-            }
-        }
-
-        @Override
-        public int describeContents() {
-            return 0;
-        }
-
-        @Override
-        public void writeToParcel(Parcel dest, int flags) {
-            dest.writeString(mCertType);
-            dest.writeByteArray(mCertSha256Fingerprint);
-        }
-
-        @Override
-        public boolean equals(Object thatObject) {
-            if (this == thatObject) {
-                return true;
-            }
-            if (!(thatObject instanceof CertificateCredential)) {
-                return false;
-            }
-
-            CertificateCredential that = (CertificateCredential) thatObject;
-            return TextUtils.equals(mCertType, that.mCertType)
-                    && Arrays.equals(mCertSha256Fingerprint, that.mCertSha256Fingerprint);
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(mCertType, Arrays.hashCode(mCertSha256Fingerprint));
-        }
-
-        @Override
-        public String toString() {
-            return "CertificateType: " + mCertType + "\n";
-        }
-
-        /**
-         * Validate the configuration data.
-         *
-         * @return true on success or false on failure
-         * @hide
-         */
-        public boolean validate() {
-            if (!TextUtils.equals(CERT_TYPE_X509V3, mCertType)) {
-                Log.d(TAG, "Unsupported certificate type: " + mCertType);
-                return false;
-            }
-            if (mCertSha256Fingerprint == null
-                    || mCertSha256Fingerprint.length != CERT_SHA256_FINGER_PRINT_LENGTH) {
-                Log.d(TAG, "Invalid SHA-256 fingerprint");
-                return false;
-            }
-            return true;
-        }
-
-        public static final @android.annotation.NonNull Creator<CertificateCredential> CREATOR =
-            new Creator<CertificateCredential>() {
-                @Override
-                public CertificateCredential createFromParcel(Parcel in) {
-                    CertificateCredential certCredential = new CertificateCredential();
-                    certCredential.setCertType(in.readString());
-                    certCredential.setCertSha256Fingerprint(in.createByteArray());
-                    return certCredential;
-                }
-
-                @Override
-                public CertificateCredential[] newArray(int size) {
-                    return new CertificateCredential[size];
-                }
-            };
-    }
-    private CertificateCredential mCertCredential = null;
-    /**
-     * Set the certificate credential information.
-     *
-     * @param certCredential The certificate credential to set to
-     */
-    public void setCertCredential(CertificateCredential certCredential) {
-        mCertCredential = certCredential;
-    }
-    /**
-     * Get the certificate credential information.
-     *
-     * @return certificate credential information
-     */
-    public CertificateCredential getCertCredential() {
-        return mCertCredential;
-    }
-
-    /**
-     * SIM (Subscriber Identify Module) based credential.
-     * Contains fields under PerProviderSubscription/Credential/SIM subtree.
-     */
-    public static final class SimCredential implements Parcelable {
-        /**
-         * Maximum string length for IMSI.
-         */
-        private static final int MAX_IMSI_LENGTH = 15;
-
-        /**
-         * International Mobile Subscriber Identity, is used to identify the user
-         * of a cellular network and is a unique identification associated with all
-         * cellular networks
-         */
-        private String mImsi = null;
-        /**
-         * Set the IMSI (International Mobile Subscriber Identity) associated with this SIM
-         * credential.
-         *
-         * @param imsi The IMSI to set to
-         */
-        public void setImsi(String imsi) {
-            mImsi = imsi;
-        }
-        /**
-         * Get the IMSI (International Mobile Subscriber Identity) associated with this SIM
-         * credential.
-         *
-         * @return IMSI associated with this SIM credential
-         */
-        public String getImsi() {
-            return mImsi;
-        }
-
-        /**
-         * EAP (Extensible Authentication Protocol) method type for using SIM credential.
-         * Refer to http://www.iana.org/assignments/eap-numbers/eap-numbers.xml#eap-numbers-4
-         * for valid values.
-         * Using Integer.MIN_VALUE to indicate unset value.
-         */
-        private int mEapType = Integer.MIN_VALUE;
-        /**
-         * Set the EAP (Extensible Authentication Protocol) method type associated with this
-         * SIM credential.
-         *
-         * @param eapType The EAP method type to set to
-         */
-        public void setEapType(int eapType) {
-            mEapType = eapType;
-        }
-        /**
-         * Get the EAP (Extensible Authentication Protocol) method type associated with this
-         * SIM credential.
-         *
-         * @return EAP method type associated with this SIM credential
-         */
-        public int getEapType() {
-            return mEapType;
-        }
-
-        /**
-         * Constructor for creating SimCredential with default values.
-         */
-        public SimCredential() {}
-
-        /**
-         * Copy constructor
-         *
-         * @param source The source to copy from
-         */
-        public SimCredential(SimCredential source) {
-            if (source != null) {
-                mImsi = source.mImsi;
-                mEapType = source.mEapType;
-            }
-        }
-
-        @Override
-        public int describeContents() {
-            return 0;
-        }
-
-        @Override
-        public boolean equals(Object thatObject) {
-            if (this == thatObject) {
-                return true;
-            }
-            if (!(thatObject instanceof SimCredential)) {
-                return false;
-            }
-
-            SimCredential that = (SimCredential) thatObject;
-            return TextUtils.equals(mImsi, that.mImsi)
-                    && mEapType == that.mEapType;
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(mImsi, mEapType);
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder builder = new StringBuilder();
-            String imsi;
-            if (mImsi != null) {
-                if (mImsi.length() > 6 && mImsi.charAt(6) != '*') {
-                    // Truncate the full IMSI from the log
-                    imsi = mImsi.substring(0, 6) + "****";
-                } else {
-                    imsi = mImsi;
-                }
-                builder.append("IMSI: ").append(imsi).append("\n");
-            }
-            builder.append("EAPType: ").append(mEapType).append("\n");
-            return builder.toString();
-        }
-
-        @Override
-        public void writeToParcel(Parcel dest, int flags) {
-            dest.writeString(mImsi);
-            dest.writeInt(mEapType);
-        }
-
-        /**
-         * Validate the configuration data.
-         *
-         * @return true on success or false on failure
-         * @hide
-         */
-        public boolean validate() {
-            // Note: this only validate the format of IMSI string itself.  Additional verification
-            // will be done by WifiService at the time of provisioning to verify against the IMSI
-            // of the SIM card installed in the device.
-            if (!verifyImsi()) {
-                return false;
-            }
-            if (mEapType != EAPConstants.EAP_SIM && mEapType != EAPConstants.EAP_AKA
-                    && mEapType != EAPConstants.EAP_AKA_PRIME) {
-                Log.d(TAG, "Invalid EAP Type for SIM credential: " + mEapType);
-                return false;
-            }
-            return true;
-        }
-
-        public static final @android.annotation.NonNull Creator<SimCredential> CREATOR =
-            new Creator<SimCredential>() {
-                @Override
-                public SimCredential createFromParcel(Parcel in) {
-                    SimCredential simCredential = new SimCredential();
-                    simCredential.setImsi(in.readString());
-                    simCredential.setEapType(in.readInt());
-                    return simCredential;
-                }
-
-                @Override
-                public SimCredential[] newArray(int size) {
-                    return new SimCredential[size];
-                }
-            };
-
-        /**
-         * Verify the IMSI (International Mobile Subscriber Identity) string.  The string
-         * should contain zero or more numeric digits, and might ends with a "*" for prefix
-         * matching.
-         *
-         * @return true if IMSI is valid, false otherwise.
-         */
-        private boolean verifyImsi() {
-            if (TextUtils.isEmpty(mImsi)) {
-                Log.d(TAG, "Missing IMSI");
-                return false;
-            }
-            if (mImsi.length() > MAX_IMSI_LENGTH) {
-                Log.d(TAG, "IMSI exceeding maximum length: " + mImsi.length());
-                return false;
-            }
-
-            // Locate the first non-digit character.
-            int nonDigit;
-            char stopChar = '\0';
-            for (nonDigit = 0; nonDigit < mImsi.length(); nonDigit++) {
-                stopChar = mImsi.charAt(nonDigit);
-                if (stopChar < '0' || stopChar > '9') {
-                    break;
-                }
-            }
-
-            if (nonDigit == mImsi.length()) {
-                return true;
-            }
-            else if (nonDigit == mImsi.length()-1 && stopChar == '*') {
-                // Prefix matching.
-                return true;
-            }
-            return false;
-        }
-    }
-    private SimCredential mSimCredential = null;
-    /**
-     * Set the SIM credential information.
-     *
-     * @param simCredential The SIM credential to set to
-     */
-    public void setSimCredential(SimCredential simCredential) {
-        mSimCredential = simCredential;
-    }
-    /**
-     * Get the SIM credential information.
-     *
-     * @return SIM credential information
-     */
-    public SimCredential getSimCredential() {
-        return mSimCredential;
-    }
-
-    /**
-     * CA (Certificate Authority) X509 certificates.
-     */
-    private X509Certificate[] mCaCertificates = null;
-
-    /**
-     * Set the CA (Certification Authority) certificate associated with this credential.
-     *
-     * @param caCertificate The CA certificate to set to
-     */
-    public void setCaCertificate(X509Certificate caCertificate) {
-        mCaCertificates = null;
-        if (caCertificate != null) {
-            mCaCertificates = new X509Certificate[] {caCertificate};
-        }
-    }
-
-    /**
-     * Set the CA (Certification Authority) certificates associated with this credential.
-     *
-     * @param caCertificates The list of CA certificates to set to
-     * @hide
-     */
-    public void setCaCertificates(X509Certificate[] caCertificates) {
-        mCaCertificates = caCertificates;
-    }
-
-    /**
-     * Get the CA (Certification Authority) certificate associated with this credential.
-     *
-     * @return CA certificate associated with this credential, {@code null} if certificate is not
-     * set or certificate is more than one.
-     */
-    public X509Certificate getCaCertificate() {
-        return mCaCertificates == null || mCaCertificates.length > 1 ? null : mCaCertificates[0];
-    }
-
-    /**
-     * Get the CA (Certification Authority) certificates associated with this credential.
-     *
-     * @return The list of CA certificates associated with this credential
-     * @hide
-     */
-    public X509Certificate[] getCaCertificates() {
-        return mCaCertificates;
-    }
-
-    /**
-     * Client side X509 certificate chain.
-     */
-    private X509Certificate[] mClientCertificateChain = null;
-    /**
-     * Set the client certificate chain associated with this credential.
-     *
-     * @param certificateChain The client certificate chain to set to
-     */
-    public void setClientCertificateChain(X509Certificate[] certificateChain) {
-        mClientCertificateChain = certificateChain;
-    }
-    /**
-     * Get the client certificate chain associated with this credential.
-     *
-     * @return client certificate chain associated with this credential
-     */
-    public X509Certificate[] getClientCertificateChain() {
-        return mClientCertificateChain;
-    }
-
-    /**
-     * Client side private key.
-     */
-    private PrivateKey mClientPrivateKey = null;
-    /**
-     * Set the client private key associated with this credential.
-     *
-     * @param clientPrivateKey the client private key to set to
-     */
-    public void setClientPrivateKey(PrivateKey clientPrivateKey) {
-        mClientPrivateKey = clientPrivateKey;
-    }
-    /**
-     * Get the client private key associated with this credential.
-     *
-     * @return client private key associated with this credential.
-     */
-    public PrivateKey getClientPrivateKey() {
-        return mClientPrivateKey;
-    }
-
-    /**
-     * Constructor for creating Credential with default values.
-     */
-    public Credential() {}
-
-    /**
-     * Copy constructor.
-     *
-     * @param source The source to copy from
-     */
-    public Credential(Credential source) {
-        if (source != null) {
-            mCreationTimeInMillis = source.mCreationTimeInMillis;
-            mExpirationTimeInMillis = source.mExpirationTimeInMillis;
-            mRealm = source.mRealm;
-            mCheckAaaServerCertStatus = source.mCheckAaaServerCertStatus;
-            if (source.mUserCredential != null) {
-                mUserCredential = new UserCredential(source.mUserCredential);
-            }
-            if (source.mCertCredential != null) {
-                mCertCredential = new CertificateCredential(source.mCertCredential);
-            }
-            if (source.mSimCredential != null) {
-                mSimCredential = new SimCredential(source.mSimCredential);
-            }
-            if (source.mClientCertificateChain != null) {
-                mClientCertificateChain = Arrays.copyOf(source.mClientCertificateChain,
-                                                        source.mClientCertificateChain.length);
-            }
-            if (source.mCaCertificates != null) {
-                mCaCertificates = Arrays.copyOf(source.mCaCertificates,
-                        source.mCaCertificates.length);
-            }
-
-            mClientPrivateKey = source.mClientPrivateKey;
-        }
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeLong(mCreationTimeInMillis);
-        dest.writeLong(mExpirationTimeInMillis);
-        dest.writeString(mRealm);
-        dest.writeInt(mCheckAaaServerCertStatus ? 1 : 0);
-        dest.writeParcelable(mUserCredential, flags);
-        dest.writeParcelable(mCertCredential, flags);
-        dest.writeParcelable(mSimCredential, flags);
-        ParcelUtil.writeCertificates(dest, mCaCertificates);
-        ParcelUtil.writeCertificates(dest, mClientCertificateChain);
-        ParcelUtil.writePrivateKey(dest, mClientPrivateKey);
-    }
-
-    @Override
-    public boolean equals(Object thatObject) {
-        if (this == thatObject) {
-            return true;
-        }
-        if (!(thatObject instanceof Credential)) {
-            return false;
-        }
-
-        Credential that = (Credential) thatObject;
-        return TextUtils.equals(mRealm, that.mRealm)
-                && mCreationTimeInMillis == that.mCreationTimeInMillis
-                && mExpirationTimeInMillis == that.mExpirationTimeInMillis
-                && mCheckAaaServerCertStatus == that.mCheckAaaServerCertStatus
-                && (mUserCredential == null ? that.mUserCredential == null
-                    : mUserCredential.equals(that.mUserCredential))
-                && (mCertCredential == null ? that.mCertCredential == null
-                    : mCertCredential.equals(that.mCertCredential))
-                && (mSimCredential == null ? that.mSimCredential == null
-                    : mSimCredential.equals(that.mSimCredential))
-                && isX509CertificatesEquals(mCaCertificates, that.mCaCertificates)
-                && isX509CertificatesEquals(mClientCertificateChain, that.mClientCertificateChain)
-                && isPrivateKeyEquals(mClientPrivateKey, that.mClientPrivateKey);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(mCreationTimeInMillis, mExpirationTimeInMillis, mRealm,
-                mCheckAaaServerCertStatus, mUserCredential, mCertCredential, mSimCredential,
-                mClientPrivateKey, Arrays.hashCode(mCaCertificates),
-                Arrays.hashCode(mClientCertificateChain));
-    }
-
-    /**
-     * Get a unique identifier for Credential. This identifier depends only on items that remain
-     * constant throughout the lifetime of a subscription's credentials.
-     *
-     * @hide
-     * @return a Unique identifier for a Credential object
-     */
-    public int getUniqueId() {
-        return Objects.hash(mUserCredential != null ? mUserCredential.getUniqueId() : 0,
-                mCertCredential, mSimCredential, mRealm);
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder builder = new StringBuilder();
-        builder.append("Realm: ").append(mRealm).append("\n");
-        builder.append("CreationTime: ").append(mCreationTimeInMillis != Long.MIN_VALUE
-                ? new Date(mCreationTimeInMillis) : "Not specified").append("\n");
-        builder.append("ExpirationTime: ").append(mExpirationTimeInMillis != Long.MIN_VALUE
-                ? new Date(mExpirationTimeInMillis) : "Not specified").append("\n");
-        builder.append("CheckAAAServerStatus: ").append(mCheckAaaServerCertStatus).append("\n");
-        if (mUserCredential != null) {
-            builder.append("UserCredential Begin ---\n");
-            builder.append(mUserCredential);
-            builder.append("UserCredential End ---\n");
-        }
-        if (mCertCredential != null) {
-            builder.append("CertificateCredential Begin ---\n");
-            builder.append(mCertCredential);
-            builder.append("CertificateCredential End ---\n");
-        }
-        if (mSimCredential != null) {
-            builder.append("SIMCredential Begin ---\n");
-            builder.append(mSimCredential);
-            builder.append("SIMCredential End ---\n");
-        }
-        return builder.toString();
-    }
-
-    /**
-     * Validate the configuration data.
-     *
-     * @return true on success or false on failure
-     * @hide
-     */
-    public boolean validate() {
-        if (TextUtils.isEmpty(mRealm)) {
-            Log.d(TAG, "Missing realm");
-            return false;
-        }
-        if (mRealm.getBytes(StandardCharsets.UTF_8).length > MAX_REALM_BYTES) {
-            Log.d(TAG, "realm exceeding maximum length: "
-                    + mRealm.getBytes(StandardCharsets.UTF_8).length);
-            return false;
-        }
-
-        // Verify the credential.
-        if (mUserCredential != null) {
-            if (!verifyUserCredential()) {
-                return false;
-            }
-        } else if (mCertCredential != null) {
-            if (!verifyCertCredential()) {
-                return false;
-            }
-        } else if (mSimCredential != null) {
-            if (!verifySimCredential()) {
-                return false;
-            }
-        } else {
-            Log.d(TAG, "Missing required credential");
-            return false;
-        }
-
-        return true;
-    }
-
-    public static final @android.annotation.NonNull Creator<Credential> CREATOR =
-        new Creator<Credential>() {
-            @Override
-            public Credential createFromParcel(Parcel in) {
-                Credential credential = new Credential();
-                credential.setCreationTimeInMillis(in.readLong());
-                credential.setExpirationTimeInMillis(in.readLong());
-                credential.setRealm(in.readString());
-                credential.setCheckAaaServerCertStatus(in.readInt() != 0);
-                credential.setUserCredential(in.readParcelable(null));
-                credential.setCertCredential(in.readParcelable(null));
-                credential.setSimCredential(in.readParcelable(null));
-                credential.setCaCertificates(ParcelUtil.readCertificates(in));
-                credential.setClientCertificateChain(ParcelUtil.readCertificates(in));
-                credential.setClientPrivateKey(ParcelUtil.readPrivateKey(in));
-                return credential;
-            }
-
-            @Override
-            public Credential[] newArray(int size) {
-                return new Credential[size];
-            }
-        };
-
-    /**
-     * Verify user credential.
-     * If no CA certificate is provided, then the system uses the CAs in the trust store.
-     *
-     * @return true if user credential is valid, false otherwise.
-     */
-    private boolean verifyUserCredential() {
-        if (mUserCredential == null) {
-            Log.d(TAG, "Missing user credential");
-            return false;
-        }
-        if (mCertCredential != null || mSimCredential != null) {
-            Log.d(TAG, "Contained more than one type of credential");
-            return false;
-        }
-        if (!mUserCredential.validate()) {
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Verify certificate credential, which is used for EAP-TLS.  This will verify
-     * that the necessary client key and certificates are provided.
-     * If no CA certificate is provided, then the system uses the CAs in the trust store.
-     *
-     * @return true if certificate credential is valid, false otherwise.
-     */
-    private boolean verifyCertCredential() {
-        if (mCertCredential == null) {
-            Log.d(TAG, "Missing certificate credential");
-            return false;
-        }
-        if (mUserCredential != null || mSimCredential != null) {
-            Log.d(TAG, "Contained more than one type of credential");
-            return false;
-        }
-
-        if (!mCertCredential.validate()) {
-            return false;
-        }
-
-        if (mClientPrivateKey == null) {
-            Log.d(TAG, "Missing client private key for certificate credential");
-            return false;
-        }
-        try {
-            // Verify SHA-256 fingerprint for client certificate.
-            if (!verifySha256Fingerprint(mClientCertificateChain,
-                    mCertCredential.getCertSha256Fingerprint())) {
-                Log.d(TAG, "SHA-256 fingerprint mismatch");
-                return false;
-            }
-        } catch (NoSuchAlgorithmException | CertificateEncodingException e) {
-            Log.d(TAG, "Failed to verify SHA-256 fingerprint: " + e.getMessage());
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Verify SIM credential.
-     *
-     * @return true if SIM credential is valid, false otherwise.
-     */
-    private boolean verifySimCredential() {
-        if (mSimCredential == null) {
-            Log.d(TAG, "Missing SIM credential");
-            return false;
-        }
-        if (mUserCredential != null || mCertCredential != null) {
-            Log.d(TAG, "Contained more than one type of credential");
-            return false;
-        }
-        return mSimCredential.validate();
-    }
-
-    private static boolean isPrivateKeyEquals(PrivateKey key1, PrivateKey key2) {
-        if (key1 == null && key2 == null) {
-            return true;
-        }
-
-        /* Return false if only one of them is null */
-        if (key1 == null || key2 == null) {
-            return false;
-        }
-
-        return TextUtils.equals(key1.getAlgorithm(), key2.getAlgorithm()) &&
-                Arrays.equals(key1.getEncoded(), key2.getEncoded());
-    }
-
-    /**
-     * Verify two X.509 certificates are identical.
-     *
-     * @param cert1 a certificate to compare
-     * @param cert2 a certificate to compare
-     * @return {@code true} if given certificates are the same each other, {@code false} otherwise.
-     * @hide
-     */
-    public static boolean isX509CertificateEquals(X509Certificate cert1, X509Certificate cert2) {
-        if (cert1 == null && cert2 == null) {
-            return true;
-        }
-
-        /* Return false if only one of them is null */
-        if (cert1 == null || cert2 == null) {
-            return false;
-        }
-
-        boolean result = false;
-        try {
-            result = Arrays.equals(cert1.getEncoded(), cert2.getEncoded());
-        } catch (CertificateEncodingException e) {
-            /* empty, return false. */
-        }
-        return result;
-    }
-
-    private static boolean isX509CertificatesEquals(X509Certificate[] certs1,
-                                                    X509Certificate[] certs2) {
-        if (certs1 == null && certs2 == null) {
-            return true;
-        }
-
-        /* Return false if only one of them is null */
-        if (certs1 == null || certs2 == null) {
-            return false;
-        }
-
-        if (certs1.length != certs2.length) {
-            return false;
-        }
-
-        for (int i = 0; i < certs1.length; i++) {
-            if (!isX509CertificateEquals(certs1[i], certs2[i])) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Verify that the digest for a certificate in the certificate chain matches expected
-     * fingerprint.  The certificate that matches the fingerprint is the client certificate.
-     *
-     * @param certChain Chain of certificates
-     * @param expectedFingerprint The expected SHA-256 digest of the client certificate
-     * @return true if the certificate chain contains a matching certificate, false otherwise
-     * @throws NoSuchAlgorithmException
-     * @throws CertificateEncodingException
-     */
-    private static boolean verifySha256Fingerprint(X509Certificate[] certChain,
-                                                   byte[] expectedFingerprint)
-            throws NoSuchAlgorithmException, CertificateEncodingException {
-        if (certChain == null) {
-            return false;
-        }
-        MessageDigest digester = MessageDigest.getInstance("SHA-256");
-        for (X509Certificate certificate : certChain) {
-            digester.reset();
-            byte[] fingerprint = digester.digest(certificate.getEncoded());
-            if (Arrays.equals(expectedFingerprint, fingerprint)) {
-                return true;
-            }
-        }
-        return false;
-    }
-}
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java b/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java
deleted file mode 100644
index 8f34579..0000000
--- a/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java
+++ /dev/null
@@ -1,429 +0,0 @@
-/**
- * Copyright (c) 2016, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.hotspot2.pps;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-import android.util.Log;
-
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Objects;
-
-/**
- * Class representing HomeSP subtree in PerProviderSubscription (PPS)
- * Management Object (MO) tree.
- *
- * For more info, refer to Hotspot 2.0 PPS MO defined in section 9.1 of the Hotspot 2.0
- * Release 2 Technical Specification.
- */
-public final class HomeSp implements Parcelable {
-    private static final String TAG = "HomeSp";
-
-    /**
-     * Maximum number of bytes allowed for a SSID.
-     */
-    private static final int MAX_SSID_BYTES = 32;
-
-    /**
-     * Integer value used for indicating null value in the Parcel.
-     */
-    private static final int NULL_VALUE = -1;
-
-    /**
-     * FQDN (Fully Qualified Domain Name) of this home service provider.
-     */
-    private String mFqdn = null;
-    /**
-     * Set the FQDN (Fully Qualified Domain Name) associated with this home service provider.
-     *
-     * @param fqdn The FQDN to set to
-     */
-    public void setFqdn(String fqdn) {
-        mFqdn = fqdn;
-    }
-    /**
-     * Get the FQDN (Fully Qualified Domain Name) associated with this home service provider.
-     *
-     * @return the FQDN associated with this home service provider
-     */
-    public String getFqdn() {
-        return mFqdn;
-    }
-
-    /**
-     * Friendly name of this home service provider.
-     */
-    private String mFriendlyName = null;
-    /**
-     * Set the friendly name associated with this home service provider.
-     *
-     * @param friendlyName The friendly name to set to
-     */
-    public void setFriendlyName(String friendlyName) {
-        mFriendlyName = friendlyName;
-    }
-    /**
-     * Get the friendly name associated with this home service provider.
-     *
-     * @return the friendly name associated with this home service provider
-     */
-    public String getFriendlyName() {
-        return mFriendlyName;
-    }
-
-    /**
-     * Icon URL of this home service provider.
-     */
-    private String mIconUrl = null;
-    /**
-     * @hide
-     */
-    public void setIconUrl(String iconUrl) {
-        mIconUrl = iconUrl;
-    }
-    /**
-     * @hide
-     */
-    public String getIconUrl() {
-        return mIconUrl;
-    }
-
-    /**
-     * <SSID, HESSID> duple of the networks that are consider home networks.
-     *
-     * According to the Section 9.1.2 of the Hotspot 2.0 Release 2 Technical Specification,
-     * all nodes in the PSS MO are encoded using UTF-8 unless stated otherwise.  Thus, the SSID
-     * string is assumed to be encoded using UTF-8.
-     */
-    private Map<String, Long> mHomeNetworkIds = null;
-    /**
-     * @hide
-     */
-    public void setHomeNetworkIds(Map<String, Long> homeNetworkIds) {
-        mHomeNetworkIds = homeNetworkIds;
-    }
-    /**
-     * @hide
-     */
-    public Map<String, Long> getHomeNetworkIds() {
-        return mHomeNetworkIds;
-    }
-
-    /**
-     * Used for determining if this provider is a member of a given Hotspot provider.
-     * Every Organization Identifiers (OIs) in this list are required to match an OI in the
-     * the Roaming Consortium advertised by a Hotspot, in order to consider this provider
-     * as a member of that Hotspot provider (e.g. successful authentication with such Hotspot
-     * is possible).
-     *
-     * Refer to HomeSP/HomeOIList subtree in PerProviderSubscription (PPS) Management Object
-     * (MO) tree for more detail.
-     */
-    private long[] mMatchAllOis = null;
-    /**
-     * @hide
-     */
-    public void setMatchAllOis(long[] matchAllOis) {
-        mMatchAllOis = matchAllOis;
-    }
-    /**
-     * @hide
-     */
-    public long[] getMatchAllOis() {
-        return mMatchAllOis;
-    }
-
-    /**
-     * Used for determining if this provider is a member of a given Hotspot provider.
-     * Matching of any Organization Identifiers (OIs) in this list with an OI in the
-     * Roaming Consortium advertised by a Hotspot, will consider this provider as a member
-     * of that Hotspot provider (e.g. successful authentication with such Hotspot
-     * is possible).
-     *
-     * {@link #mMatchAllOIs} will have precedence over this one, meaning this list will
-     * only be used for matching if {@link #mMatchAllOIs} is null or empty.
-     *
-     * Refer to HomeSP/HomeOIList subtree in PerProviderSubscription (PPS) Management Object
-     * (MO) tree for more detail.
-     */
-    private long[] mMatchAnyOis = null;
-    /**
-     * @hide
-     */
-    public void setMatchAnyOis(long[] matchAnyOis) {
-        mMatchAnyOis = matchAnyOis;
-    }
-    /**
-     * @hide
-     */
-    public long[] getMatchAnyOis() {
-        return mMatchAnyOis;
-    }
-
-    /**
-     * List of FQDN (Fully Qualified Domain Name) of partner providers.
-     * These providers should also be regarded as home Hotspot operators.
-     * This relationship is most likely achieved via a commercial agreement or
-     * operator merges between the providers.
-     */
-    private String[] mOtherHomePartners = null;
-    /**
-     * @hide
-     */
-    public void setOtherHomePartners(String[] otherHomePartners) {
-        mOtherHomePartners = otherHomePartners;
-    }
-    /**
-     * @hide
-     */
-    public String[] getOtherHomePartners() {
-        return mOtherHomePartners;
-    }
-
-    /**
-     * List of Organization Identifiers (OIs) identifying a roaming consortium of
-     * which this provider is a member.
-     */
-    private long[] mRoamingConsortiumOis = null;
-    /**
-     * Set the Organization Identifiers (OIs) identifying a roaming consortium of which this
-     * provider is a member.
-     *
-     * @param roamingConsortiumOis Array of roaming consortium OIs
-     */
-    public void setRoamingConsortiumOis(long[] roamingConsortiumOis) {
-        mRoamingConsortiumOis = roamingConsortiumOis;
-    }
-    /**
-     * Get the Organization Identifiers (OIs) identifying a roaming consortium of which this
-     * provider is a member.
-     *
-     * @return array of roaming consortium OIs
-     */
-    public long[] getRoamingConsortiumOis() {
-        return mRoamingConsortiumOis;
-    }
-
-    /**
-     * Constructor for creating HomeSp with default values.
-     */
-    public HomeSp() {}
-
-    /**
-     * Copy constructor.
-     *
-     * @param source The source to copy from
-     */
-    public HomeSp(HomeSp source) {
-        if (source == null) {
-            return;
-        }
-        mFqdn = source.mFqdn;
-        mFriendlyName = source.mFriendlyName;
-        mIconUrl = source.mIconUrl;
-        if (source.mHomeNetworkIds != null) {
-            mHomeNetworkIds = Collections.unmodifiableMap(source.mHomeNetworkIds);
-        }
-        if (source.mMatchAllOis != null) {
-            mMatchAllOis = Arrays.copyOf(source.mMatchAllOis, source.mMatchAllOis.length);
-        }
-        if (source.mMatchAnyOis != null) {
-            mMatchAnyOis = Arrays.copyOf(source.mMatchAnyOis, source.mMatchAnyOis.length);
-        }
-        if (source.mOtherHomePartners != null) {
-            mOtherHomePartners = Arrays.copyOf(source.mOtherHomePartners,
-                    source.mOtherHomePartners.length);
-        }
-        if (source.mRoamingConsortiumOis != null) {
-            mRoamingConsortiumOis = Arrays.copyOf(source.mRoamingConsortiumOis,
-                    source.mRoamingConsortiumOis.length);
-        }
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeString(mFqdn);
-        dest.writeString(mFriendlyName);
-        dest.writeString(mIconUrl);
-        writeHomeNetworkIds(dest, mHomeNetworkIds);
-        dest.writeLongArray(mMatchAllOis);
-        dest.writeLongArray(mMatchAnyOis);
-        dest.writeStringArray(mOtherHomePartners);
-        dest.writeLongArray(mRoamingConsortiumOis);
-    }
-
-    @Override
-    public boolean equals(Object thatObject) {
-        if (this == thatObject) {
-            return true;
-        }
-        if (!(thatObject instanceof HomeSp)) {
-            return false;
-        }
-        HomeSp that = (HomeSp) thatObject;
-
-        return TextUtils.equals(mFqdn, that.mFqdn)
-                && TextUtils.equals(mFriendlyName, that.mFriendlyName)
-                && TextUtils.equals(mIconUrl, that.mIconUrl)
-                && (mHomeNetworkIds == null ? that.mHomeNetworkIds == null
-                        : mHomeNetworkIds.equals(that.mHomeNetworkIds))
-                && Arrays.equals(mMatchAllOis, that.mMatchAllOis)
-                && Arrays.equals(mMatchAnyOis, that.mMatchAnyOis)
-                && Arrays.equals(mOtherHomePartners, that.mOtherHomePartners)
-                && Arrays.equals(mRoamingConsortiumOis, that.mRoamingConsortiumOis);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(mFqdn, mFriendlyName, mIconUrl,
-                mHomeNetworkIds, Arrays.hashCode(mMatchAllOis),
-                Arrays.hashCode(mMatchAnyOis), Arrays.hashCode(mOtherHomePartners),
-                Arrays.hashCode(mRoamingConsortiumOis));
-    }
-
-    /**
-     * Get a unique identifier for HomeSp. This identifier depends only on items that remain
-     * constant throughout the lifetime of a subscription.
-     *
-     * @hide
-     * @return a Unique identifier for a HomeSp object
-     */
-    public int getUniqueId() {
-        return Objects.hash(mFqdn);
-    }
-
-
-    @Override
-    public String toString() {
-        StringBuilder builder = new StringBuilder();
-        builder.append("FQDN: ").append(mFqdn).append("\n");
-        builder.append("FriendlyName: ").append(mFriendlyName).append("\n");
-        builder.append("IconURL: ").append(mIconUrl).append("\n");
-        builder.append("HomeNetworkIDs: ").append(mHomeNetworkIds).append("\n");
-        builder.append("MatchAllOIs: ").append(mMatchAllOis).append("\n");
-        builder.append("MatchAnyOIs: ").append(mMatchAnyOis).append("\n");
-        builder.append("OtherHomePartners: ").append(mOtherHomePartners).append("\n");
-        builder.append("RoamingConsortiumOIs: ").append(mRoamingConsortiumOis).append("\n");
-        return builder.toString();
-    }
-
-    /**
-     * Validate HomeSp data.
-     *
-     * @return true on success or false on failure
-     * @hide
-     */
-    public boolean validate() {
-        if (TextUtils.isEmpty(mFqdn)) {
-            Log.d(TAG, "Missing FQDN");
-            return false;
-        }
-        if (TextUtils.isEmpty(mFriendlyName)) {
-            Log.d(TAG, "Missing friendly name");
-            return false;
-        }
-        // Verify SSIDs specified in the NetworkID
-        if (mHomeNetworkIds != null) {
-            for (Map.Entry<String, Long> entry : mHomeNetworkIds.entrySet()) {
-                if (entry.getKey() == null ||
-                        entry.getKey().getBytes(StandardCharsets.UTF_8).length > MAX_SSID_BYTES) {
-                    Log.d(TAG, "Invalid SSID in HomeNetworkIDs");
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-
-    public static final @android.annotation.NonNull Creator<HomeSp> CREATOR =
-        new Creator<HomeSp>() {
-            @Override
-            public HomeSp createFromParcel(Parcel in) {
-                HomeSp homeSp = new HomeSp();
-                homeSp.setFqdn(in.readString());
-                homeSp.setFriendlyName(in.readString());
-                homeSp.setIconUrl(in.readString());
-                homeSp.setHomeNetworkIds(readHomeNetworkIds(in));
-                homeSp.setMatchAllOis(in.createLongArray());
-                homeSp.setMatchAnyOis(in.createLongArray());
-                homeSp.setOtherHomePartners(in.createStringArray());
-                homeSp.setRoamingConsortiumOis(in.createLongArray());
-                return homeSp;
-            }
-
-            @Override
-            public HomeSp[] newArray(int size) {
-                return new HomeSp[size];
-            }
-
-            /**
-             * Helper function for reading a Home Network IDs map from a Parcel.
-             *
-             * @param in The Parcel to read from
-             * @return Map of home network IDs
-             */
-            private Map<String, Long> readHomeNetworkIds(Parcel in) {
-                int size = in.readInt();
-                if (size == NULL_VALUE) {
-                    return null;
-                }
-                Map<String, Long> networkIds = new HashMap<>(size);
-                for (int i = 0; i < size; i++) {
-                    String key = in.readString();
-                    Long value = null;
-                    long readValue = in.readLong();
-                    if (readValue != NULL_VALUE) {
-                        value = Long.valueOf(readValue);
-                    }
-                    networkIds.put(key, value);
-                }
-                return networkIds;
-            }
-        };
-
-    /**
-     * Helper function for writing Home Network IDs map to a Parcel.
-     *
-     * @param dest The Parcel to write to
-     * @param networkIds The map of home network IDs
-     */
-    private static void writeHomeNetworkIds(Parcel dest, Map<String, Long> networkIds) {
-        if (networkIds == null) {
-            dest.writeInt(NULL_VALUE);
-            return;
-        }
-        dest.writeInt(networkIds.size());
-        for (Map.Entry<String, Long> entry : networkIds.entrySet()) {
-            dest.writeString(entry.getKey());
-            if (entry.getValue() == null) {
-                dest.writeLong(NULL_VALUE);
-            } else {
-                dest.writeLong(entry.getValue());
-            }
-        }
-    }
-}
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/Policy.java b/wifi/java/android/net/wifi/hotspot2/pps/Policy.java
deleted file mode 100644
index b0a2cc3..0000000
--- a/wifi/java/android/net/wifi/hotspot2/pps/Policy.java
+++ /dev/null
@@ -1,576 +0,0 @@
-/**
- * Copyright (c) 2017, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.hotspot2.pps;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-import android.util.Log;
-
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-
-/**
- * Class representing Policy subtree in PerProviderSubscription (PPS)
- * Management Object (MO) tree.
- *
- * The Policy specifies additional criteria for Passpoint network selections, such as preferred
- * roaming partner, minimum backhaul bandwidth, and etc. It also provides the meta data for
- * updating the policy.
- *
- * For more info, refer to Hotspot 2.0 PPS MO defined in section 9.1 of the Hotspot 2.0
- * Release 2 Technical Specification.
- *
- * @hide
- */
-public final class Policy implements Parcelable {
-    private static final String TAG = "Policy";
-
-    /**
-     * Maximum number of SSIDs in the exclusion list.
-     */
-    private static final int MAX_EXCLUSION_SSIDS = 128;
-
-    /**
-     * Maximum byte for SSID.
-     */
-    private static final int MAX_SSID_BYTES = 32;
-
-    /**
-     * Maximum bytes for port string in {@link #requiredProtoPortMap}.
-     */
-    private static final int MAX_PORT_STRING_BYTES = 64;
-
-    /**
-     * Integer value used for indicating null value in the Parcel.
-     */
-    private static final int NULL_VALUE = -1;
-
-    /**
-     * Minimum available downlink/uplink bandwidth (in kilobits per second) required when
-     * selecting a network from home providers.
-     *
-     * The bandwidth is calculated as the LinkSpeed * (1 – LinkLoad/255), where LinkSpeed
-     * and LinkLoad parameters are drawn from the WAN Metrics ANQP element at that hotspot.
-     *
-     * Using Long.MIN_VALUE to indicate unset value.
-     */
-    private long mMinHomeDownlinkBandwidth = Long.MIN_VALUE;
-    public void setMinHomeDownlinkBandwidth(long minHomeDownlinkBandwidth) {
-        mMinHomeDownlinkBandwidth = minHomeDownlinkBandwidth;
-    }
-    public long getMinHomeDownlinkBandwidth() {
-        return mMinHomeDownlinkBandwidth;
-    }
-    private long mMinHomeUplinkBandwidth = Long.MIN_VALUE;
-    public void setMinHomeUplinkBandwidth(long minHomeUplinkBandwidth) {
-        mMinHomeUplinkBandwidth = minHomeUplinkBandwidth;
-    }
-    public long getMinHomeUplinkBandwidth() {
-        return mMinHomeUplinkBandwidth;
-    }
-
-    /**
-     * Minimum available downlink/uplink bandwidth (in kilobits per second) required when
-     * selecting a network from roaming providers.
-     *
-     * The bandwidth is calculated as the LinkSpeed * (1 – LinkLoad/255), where LinkSpeed
-     * and LinkLoad parameters are drawn from the WAN Metrics ANQP element at that hotspot.
-     *
-     * Using Long.MIN_VALUE to indicate unset value.
-     */
-    private long mMinRoamingDownlinkBandwidth = Long.MIN_VALUE;
-    public void setMinRoamingDownlinkBandwidth(long minRoamingDownlinkBandwidth) {
-        mMinRoamingDownlinkBandwidth = minRoamingDownlinkBandwidth;
-    }
-    public long getMinRoamingDownlinkBandwidth() {
-        return mMinRoamingDownlinkBandwidth;
-    }
-    private long mMinRoamingUplinkBandwidth = Long.MIN_VALUE;
-    public void setMinRoamingUplinkBandwidth(long minRoamingUplinkBandwidth) {
-        mMinRoamingUplinkBandwidth = minRoamingUplinkBandwidth;
-    }
-    public long getMinRoamingUplinkBandwidth() {
-        return mMinRoamingUplinkBandwidth;
-    }
-
-    /**
-     * List of SSIDs that are not preferred by the Home SP.
-     */
-    private String[] mExcludedSsidList = null;
-    public void setExcludedSsidList(String[] excludedSsidList) {
-        mExcludedSsidList = excludedSsidList;
-    }
-    public String[] getExcludedSsidList() {
-        return mExcludedSsidList;
-    }
-
-    /**
-     * List of IP protocol and port number required by one or more operator supported application.
-     * The port string contained one or more port numbers delimited by ",".
-     */
-    private Map<Integer, String> mRequiredProtoPortMap = null;
-    public void setRequiredProtoPortMap(Map<Integer, String> requiredProtoPortMap) {
-        mRequiredProtoPortMap = requiredProtoPortMap;
-    }
-    public Map<Integer, String> getRequiredProtoPortMap() {
-        return mRequiredProtoPortMap;
-    }
-
-    /**
-     * This specifies the maximum acceptable BSS load policy.  This is used to prevent device
-     * from joining an AP whose channel is overly congested with traffic.
-     * Using Integer.MIN_VALUE to indicate unset value.
-     */
-    private int mMaximumBssLoadValue = Integer.MIN_VALUE;
-    public void setMaximumBssLoadValue(int maximumBssLoadValue) {
-        mMaximumBssLoadValue = maximumBssLoadValue;
-    }
-    public int getMaximumBssLoadValue() {
-        return mMaximumBssLoadValue;
-    }
-
-    /**
-     * Policy associated with a roaming provider.  This specifies a priority associated
-     * with a roaming provider for given list of countries.
-     *
-     * Contains field under PerProviderSubscription/Policy/PreferredRoamingPartnerList.
-     */
-    public static final class RoamingPartner implements Parcelable {
-        /**
-         * FQDN of the roaming partner.
-         */
-        private String mFqdn = null;
-        public void setFqdn(String fqdn) {
-            mFqdn = fqdn;
-        }
-        public String getFqdn() {
-            return mFqdn;
-        }
-
-        /**
-         * Flag indicating the exact match of FQDN is required for FQDN matching.
-         *
-         * When this flag is set to false, sub-domain matching is used.  For example, when
-         * {@link #fqdn} s set to "example.com", "host.example.com" would be a match.
-         */
-        private boolean mFqdnExactMatch = false;
-        public void setFqdnExactMatch(boolean fqdnExactMatch) {
-            mFqdnExactMatch = fqdnExactMatch;
-        }
-        public boolean getFqdnExactMatch() {
-            return mFqdnExactMatch;
-        }
-
-        /**
-         * Priority associated with this roaming partner policy.
-         * Using Integer.MIN_VALUE to indicate unset value.
-         */
-        private int mPriority = Integer.MIN_VALUE;
-        public void setPriority(int priority) {
-            mPriority = priority;
-        }
-        public int getPriority() {
-            return mPriority;
-        }
-
-        /**
-         * A string contained One or more, comma delimited (i.e., ",") ISO/IEC 3166-1 two
-         * character country strings or the country-independent value, "*".
-         */
-        private String mCountries = null;
-        public void setCountries(String countries) {
-            mCountries = countries;
-        }
-        public String getCountries() {
-            return mCountries;
-        }
-
-        public RoamingPartner() {}
-
-        public RoamingPartner(RoamingPartner source) {
-            if (source != null) {
-                mFqdn = source.mFqdn;
-                mFqdnExactMatch = source.mFqdnExactMatch;
-                mPriority = source.mPriority;
-                mCountries = source.mCountries;
-            }
-        }
-
-        @Override
-        public int describeContents() {
-            return 0;
-        }
-
-        @Override
-        public void writeToParcel(Parcel dest, int flags) {
-            dest.writeString(mFqdn);
-            dest.writeInt(mFqdnExactMatch ? 1 : 0);
-            dest.writeInt(mPriority);
-            dest.writeString(mCountries);
-        }
-
-        @Override
-        public boolean equals(Object thatObject) {
-            if (this == thatObject) {
-                return true;
-            }
-            if (!(thatObject instanceof RoamingPartner)) {
-                return false;
-            }
-
-            RoamingPartner that = (RoamingPartner) thatObject;
-            return TextUtils.equals(mFqdn, that.mFqdn)
-                    && mFqdnExactMatch == that.mFqdnExactMatch
-                    && mPriority == that.mPriority
-                    && TextUtils.equals(mCountries, that.mCountries);
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(mFqdn, mFqdnExactMatch, mPriority, mCountries);
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder builder = new StringBuilder();
-            builder.append("FQDN: ").append(mFqdn).append("\n");
-            builder.append("ExactMatch: ").append("mFqdnExactMatch").append("\n");
-            builder.append("Priority: ").append(mPriority).append("\n");
-            builder.append("Countries: ").append(mCountries).append("\n");
-            return builder.toString();
-        }
-
-        /**
-         * Validate RoamingParnter data.
-         *
-         * @return true on success
-         * @hide
-         */
-        public boolean validate() {
-            if (TextUtils.isEmpty(mFqdn)) {
-                Log.d(TAG, "Missing FQDN");
-                return false;
-            }
-            if (TextUtils.isEmpty(mCountries)) {
-                Log.d(TAG, "Missing countries");
-                return false;
-            }
-            return true;
-        }
-
-        public static final @android.annotation.NonNull Creator<RoamingPartner> CREATOR =
-            new Creator<RoamingPartner>() {
-                @Override
-                public RoamingPartner createFromParcel(Parcel in) {
-                    RoamingPartner roamingPartner = new RoamingPartner();
-                    roamingPartner.setFqdn(in.readString());
-                    roamingPartner.setFqdnExactMatch(in.readInt() != 0);
-                    roamingPartner.setPriority(in.readInt());
-                    roamingPartner.setCountries(in.readString());
-                    return roamingPartner;
-                }
-
-                @Override
-                public RoamingPartner[] newArray(int size) {
-                    return new RoamingPartner[size];
-                }
-            };
-    }
-    private List<RoamingPartner> mPreferredRoamingPartnerList = null;
-    public void setPreferredRoamingPartnerList(List<RoamingPartner> partnerList) {
-        mPreferredRoamingPartnerList = partnerList;
-    }
-    public List<RoamingPartner> getPreferredRoamingPartnerList() {
-        return mPreferredRoamingPartnerList;
-    }
-
-    /**
-     * Meta data used for policy update.
-     */
-    private UpdateParameter mPolicyUpdate = null;
-    public void setPolicyUpdate(UpdateParameter policyUpdate) {
-        mPolicyUpdate = policyUpdate;
-    }
-    public UpdateParameter getPolicyUpdate() {
-        return mPolicyUpdate;
-    }
-
-    /**
-     * Constructor for creating Policy with default values.
-     */
-    public Policy() {}
-
-    /**
-     * Copy constructor.
-     *
-     * @param source The source to copy from
-     */
-    public Policy(Policy source) {
-        if (source == null) {
-            return;
-        }
-        mMinHomeDownlinkBandwidth = source.mMinHomeDownlinkBandwidth;
-        mMinHomeUplinkBandwidth = source.mMinHomeUplinkBandwidth;
-        mMinRoamingDownlinkBandwidth = source.mMinRoamingDownlinkBandwidth;
-        mMinRoamingUplinkBandwidth = source.mMinRoamingUplinkBandwidth;
-        mMaximumBssLoadValue = source.mMaximumBssLoadValue;
-        if (source.mExcludedSsidList != null) {
-            mExcludedSsidList = Arrays.copyOf(source.mExcludedSsidList,
-                    source.mExcludedSsidList.length);
-        }
-        if (source.mRequiredProtoPortMap != null) {
-            mRequiredProtoPortMap = Collections.unmodifiableMap(source.mRequiredProtoPortMap);
-        }
-        if (source.mPreferredRoamingPartnerList != null) {
-            mPreferredRoamingPartnerList = Collections.unmodifiableList(
-                    source.mPreferredRoamingPartnerList);
-        }
-        if (source.mPolicyUpdate != null) {
-            mPolicyUpdate = new UpdateParameter(source.mPolicyUpdate);
-        }
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeLong(mMinHomeDownlinkBandwidth);
-        dest.writeLong(mMinHomeUplinkBandwidth);
-        dest.writeLong(mMinRoamingDownlinkBandwidth);
-        dest.writeLong(mMinRoamingUplinkBandwidth);
-        dest.writeStringArray(mExcludedSsidList);
-        writeProtoPortMap(dest, mRequiredProtoPortMap);
-        dest.writeInt(mMaximumBssLoadValue);
-        writeRoamingPartnerList(dest, flags, mPreferredRoamingPartnerList);
-        dest.writeParcelable(mPolicyUpdate, flags);
-    }
-
-    @Override
-    public boolean equals(Object thatObject) {
-        if (this == thatObject) {
-            return true;
-        }
-        if (!(thatObject instanceof Policy)) {
-            return false;
-        }
-        Policy that = (Policy) thatObject;
-
-        return mMinHomeDownlinkBandwidth == that.mMinHomeDownlinkBandwidth
-                && mMinHomeUplinkBandwidth == that.mMinHomeUplinkBandwidth
-                && mMinRoamingDownlinkBandwidth == that.mMinRoamingDownlinkBandwidth
-                && mMinRoamingUplinkBandwidth == that.mMinRoamingUplinkBandwidth
-                && Arrays.equals(mExcludedSsidList, that.mExcludedSsidList)
-                && (mRequiredProtoPortMap == null ? that.mRequiredProtoPortMap == null
-                        : mRequiredProtoPortMap.equals(that.mRequiredProtoPortMap))
-                && mMaximumBssLoadValue == that.mMaximumBssLoadValue
-                && (mPreferredRoamingPartnerList == null
-                        ? that.mPreferredRoamingPartnerList == null
-                        : mPreferredRoamingPartnerList.equals(that.mPreferredRoamingPartnerList))
-                && (mPolicyUpdate == null ? that.mPolicyUpdate == null
-                        : mPolicyUpdate.equals(that.mPolicyUpdate));
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(mMinHomeDownlinkBandwidth, mMinHomeUplinkBandwidth,
-                mMinRoamingDownlinkBandwidth, mMinRoamingUplinkBandwidth, mExcludedSsidList,
-                mRequiredProtoPortMap, mMaximumBssLoadValue, mPreferredRoamingPartnerList,
-                mPolicyUpdate);
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder builder = new StringBuilder();
-        builder.append("MinHomeDownlinkBandwidth: ").append(mMinHomeDownlinkBandwidth)
-                .append("\n");
-        builder.append("MinHomeUplinkBandwidth: ").append(mMinHomeUplinkBandwidth).append("\n");
-        builder.append("MinRoamingDownlinkBandwidth: ").append(mMinRoamingDownlinkBandwidth)
-                .append("\n");
-        builder.append("MinRoamingUplinkBandwidth: ").append(mMinRoamingUplinkBandwidth)
-                .append("\n");
-        builder.append("ExcludedSSIDList: ").append(mExcludedSsidList).append("\n");
-        builder.append("RequiredProtoPortMap: ").append(mRequiredProtoPortMap).append("\n");
-        builder.append("MaximumBSSLoadValue: ").append(mMaximumBssLoadValue).append("\n");
-        builder.append("PreferredRoamingPartnerList: ").append(mPreferredRoamingPartnerList)
-                .append("\n");
-        if (mPolicyUpdate != null) {
-            builder.append("PolicyUpdate Begin ---\n");
-            builder.append(mPolicyUpdate);
-            builder.append("PolicyUpdate End ---\n");
-        }
-        return builder.toString();
-    }
-
-    /**
-     * Validate Policy data.
-     *
-     * @return true on success
-     * @hide
-     */
-    public boolean validate() {
-        if (mPolicyUpdate == null) {
-            Log.d(TAG, "PolicyUpdate not specified");
-            return false;
-        }
-        if (!mPolicyUpdate.validate()) {
-            return false;
-        }
-
-        // Validate SSID exclusion list.
-        if (mExcludedSsidList != null) {
-            if (mExcludedSsidList.length > MAX_EXCLUSION_SSIDS) {
-                Log.d(TAG, "SSID exclusion list size exceeded the max: "
-                        + mExcludedSsidList.length);
-                return false;
-            }
-            for (String ssid : mExcludedSsidList) {
-                if (ssid.getBytes(StandardCharsets.UTF_8).length > MAX_SSID_BYTES) {
-                    Log.d(TAG, "Invalid SSID: " + ssid);
-                    return false;
-                }
-            }
-        }
-        // Validate required protocol to port map.
-        if (mRequiredProtoPortMap != null) {
-            for (Map.Entry<Integer, String> entry : mRequiredProtoPortMap.entrySet()) {
-                String portNumber = entry.getValue();
-                if (portNumber.getBytes(StandardCharsets.UTF_8).length > MAX_PORT_STRING_BYTES) {
-                    Log.d(TAG, "PortNumber string bytes exceeded the max: " + portNumber);
-                    return false;
-                }
-            }
-        }
-        // Validate preferred roaming partner list.
-        if (mPreferredRoamingPartnerList != null) {
-            for (RoamingPartner partner : mPreferredRoamingPartnerList) {
-                if (!partner.validate()) {
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-
-    public static final @android.annotation.NonNull Creator<Policy> CREATOR =
-        new Creator<Policy>() {
-            @Override
-            public Policy createFromParcel(Parcel in) {
-                Policy policy = new Policy();
-                policy.setMinHomeDownlinkBandwidth(in.readLong());
-                policy.setMinHomeUplinkBandwidth(in.readLong());
-                policy.setMinRoamingDownlinkBandwidth(in.readLong());
-                policy.setMinRoamingUplinkBandwidth(in.readLong());
-                policy.setExcludedSsidList(in.createStringArray());
-                policy.setRequiredProtoPortMap(readProtoPortMap(in));
-                policy.setMaximumBssLoadValue(in.readInt());
-                policy.setPreferredRoamingPartnerList(readRoamingPartnerList(in));
-                policy.setPolicyUpdate(in.readParcelable(null));
-                return policy;
-            }
-
-            @Override
-            public Policy[] newArray(int size) {
-                return new Policy[size];
-            }
-
-            /**
-             * Helper function for reading IP Protocol to Port Number map from a Parcel.
-             *
-             * @param in The Parcel to read from
-             * @return Map of IP protocol to port number
-             */
-            private Map<Integer, String> readProtoPortMap(Parcel in) {
-                int size = in.readInt();
-                if (size == NULL_VALUE) {
-                    return null;
-                }
-                Map<Integer, String> protoPortMap = new HashMap<>(size);
-                for (int i = 0; i < size; i++) {
-                    int key = in.readInt();
-                    String value = in.readString();
-                    protoPortMap.put(key, value);
-                }
-                return protoPortMap;
-            }
-
-            /**
-             * Helper function for reading roaming partner list from a Parcel.
-             *
-             * @param in The Parcel to read from
-             * @return List of roaming partners
-             */
-            private List<RoamingPartner> readRoamingPartnerList(Parcel in) {
-                int size = in.readInt();
-                if (size == NULL_VALUE) {
-                    return null;
-                }
-                List<RoamingPartner> partnerList = new ArrayList<>();
-                for (int i = 0; i < size; i++) {
-                    partnerList.add(in.readParcelable(null));
-                }
-                return partnerList;
-            }
-
-        };
-
-    /**
-     * Helper function for writing IP Protocol to Port Number map to a Parcel.
-     *
-     * @param dest The Parcel to write to
-     * @param protoPortMap The map to write
-     */
-    private static void writeProtoPortMap(Parcel dest, Map<Integer, String> protoPortMap) {
-        if (protoPortMap == null) {
-            dest.writeInt(NULL_VALUE);
-            return;
-        }
-        dest.writeInt(protoPortMap.size());
-        for (Map.Entry<Integer, String> entry : protoPortMap.entrySet()) {
-            dest.writeInt(entry.getKey());
-            dest.writeString(entry.getValue());
-        }
-    }
-
-    /**
-     * Helper function for writing roaming partner list to a Parcel.
-     *
-     * @param dest The Parcel to write to
-     * @param flags The flag about how the object should be written
-     * @param partnerList The partner list to write
-     */
-    private static void writeRoamingPartnerList(Parcel dest, int flags,
-            List<RoamingPartner> partnerList) {
-        if (partnerList == null) {
-            dest.writeInt(NULL_VALUE);
-            return;
-        }
-        dest.writeInt(partnerList.size());
-        for (RoamingPartner partner : partnerList) {
-            dest.writeParcelable(partner, flags);
-        }
-    }
-}
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/UpdateParameter.java b/wifi/java/android/net/wifi/hotspot2/pps/UpdateParameter.java
deleted file mode 100644
index 4a8aa36..0000000
--- a/wifi/java/android/net/wifi/hotspot2/pps/UpdateParameter.java
+++ /dev/null
@@ -1,403 +0,0 @@
-/**
- * Copyright (c) 2017, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.hotspot2.pps;
-
-import android.net.wifi.ParcelUtil;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-import android.util.Base64;
-import android.util.Log;
-
-import java.nio.charset.StandardCharsets;
-import java.security.cert.X509Certificate;
-import java.util.Arrays;
-import java.util.Objects;
-
-/**
- * Class representing configuration parameters for subscription or policy update in
- * PerProviderSubscription (PPS) Management Object (MO) tree.  This is used by both
- * PerProviderSubscription/Policy/PolicyUpdate and PerProviderSubscription/SubscriptionUpdate
- * subtree.
- *
- * For more info, refer to Hotspot 2.0 PPS MO defined in section 9.1 of the Hotspot 2.0
- * Release 2 Technical Specification.
- *
- * @hide
- */
-public final class UpdateParameter implements Parcelable {
-    private static final String TAG = "UpdateParameter";
-
-    /**
-     * Value indicating policy update is not applicable.  Thus, never check with policy server
-     * for updates.
-     */
-    public static final long UPDATE_CHECK_INTERVAL_NEVER = 0xFFFFFFFFL;
-
-    /**
-     * Valid string for UpdateMethod.
-     */
-    public static final String UPDATE_METHOD_OMADM = "OMA-DM-ClientInitiated";
-    public static final String UPDATE_METHOD_SSP = "SSP-ClientInitiated";
-
-    /**
-     * Valid string for Restriction.
-     */
-    public static final String UPDATE_RESTRICTION_HOMESP = "HomeSP";
-    public static final String UPDATE_RESTRICTION_ROAMING_PARTNER = "RoamingPartner";
-    public static final String UPDATE_RESTRICTION_UNRESTRICTED = "Unrestricted";
-
-    /**
-     * Maximum bytes for URI string.
-     */
-    private static final int MAX_URI_BYTES = 1023;
-
-    /**
-     * Maximum bytes for URI string.
-     */
-    private static final int MAX_URL_BYTES = 1023;
-
-    /**
-     * Maximum bytes for username.
-     */
-    private static final int MAX_USERNAME_BYTES = 63;
-
-    /**
-     * Maximum bytes for password.
-     */
-    private static final int MAX_PASSWORD_BYTES = 255;
-
-    /**
-     * Number of bytes for certificate SHA-256 fingerprint byte array.
-     */
-    private static final int CERTIFICATE_SHA256_BYTES = 32;
-
-    /**
-     * This specifies how often the mobile device shall check with policy server for updates.
-     *
-     * Using Long.MIN_VALUE to indicate unset value.
-     */
-    private long mUpdateIntervalInMinutes = Long.MIN_VALUE;
-    public void setUpdateIntervalInMinutes(long updateIntervalInMinutes) {
-        mUpdateIntervalInMinutes = updateIntervalInMinutes;
-    }
-    public long getUpdateIntervalInMinutes() {
-        return mUpdateIntervalInMinutes;
-    }
-
-    /**
-     * The method used to update the policy.  Permitted values are "OMA-DM-ClientInitiated"
-     * and "SPP-ClientInitiated".
-     */
-    private String mUpdateMethod = null;
-    public void setUpdateMethod(String updateMethod) {
-        mUpdateMethod = updateMethod;
-    }
-    public String getUpdateMethod() {
-        return mUpdateMethod;
-    }
-
-    /**
-     * This specifies the hotspots at which the subscription update is permitted.  Permitted
-     * values are "HomeSP", "RoamingPartner", or "Unrestricted";
-     */
-    private String mRestriction = null;
-    public void setRestriction(String restriction) {
-        mRestriction = restriction;
-    }
-    public String getRestriction() {
-        return mRestriction;
-    }
-
-    /**
-     * The URI of the update server.
-     */
-    private String mServerUri = null;
-    public void setServerUri(String serverUri) {
-        mServerUri = serverUri;
-    }
-    public String getServerUri() {
-        return mServerUri;
-    }
-
-    /**
-     * Username used to authenticate with the policy server.
-     */
-    private String mUsername = null;
-    public void setUsername(String username) {
-        mUsername = username;
-    }
-    public String getUsername() {
-        return mUsername;
-    }
-
-    /**
-     * Base64 encoded password used to authenticate with the policy server.
-     */
-    private String mBase64EncodedPassword = null;
-    public void setBase64EncodedPassword(String password) {
-        mBase64EncodedPassword = password;
-    }
-    public String getBase64EncodedPassword() {
-        return mBase64EncodedPassword;
-    }
-
-    /**
-     * HTTPS URL for retrieving certificate for trust root.  The trust root is used to validate
-     * policy server's identity.
-     */
-    private String mTrustRootCertUrl = null;
-    public void setTrustRootCertUrl(String trustRootCertUrl) {
-        mTrustRootCertUrl = trustRootCertUrl;
-    }
-    public String getTrustRootCertUrl() {
-        return mTrustRootCertUrl;
-    }
-
-    /**
-     * SHA-256 fingerprint of the certificate located at {@code mTrustRootCertUrl}
-     */
-    private byte[] mTrustRootCertSha256Fingerprint = null;
-    public void setTrustRootCertSha256Fingerprint(byte[] fingerprint) {
-        mTrustRootCertSha256Fingerprint = fingerprint;
-    }
-    public byte[] getTrustRootCertSha256Fingerprint() {
-        return mTrustRootCertSha256Fingerprint;
-    }
-
-    /**
-     * CA (Certificate Authority) X509 certificates.
-     */
-    private X509Certificate mCaCertificate;
-
-    /**
-     * Set the CA (Certification Authority) certificate associated with Policy/Subscription update.
-     *
-     * @param caCertificate The CA certificate to set
-     * @hide
-     */
-    public void setCaCertificate(X509Certificate caCertificate) {
-        mCaCertificate = caCertificate;
-    }
-
-    /**
-     * Get the CA (Certification Authority) certificate associated with Policy/Subscription update.
-     *
-     * @return CA certificate associated and {@code null} if certificate is not set.
-     * @hide
-     */
-    public X509Certificate getCaCertificate() {
-        return mCaCertificate;
-    }
-
-    /**
-     * Constructor for creating Policy with default values.
-     */
-    public UpdateParameter() {}
-
-    /**
-     * Copy constructor.
-     *
-     * @param source The source to copy from
-     */
-    public UpdateParameter(UpdateParameter source) {
-        if (source == null) {
-            return;
-        }
-        mUpdateIntervalInMinutes = source.mUpdateIntervalInMinutes;
-        mUpdateMethod = source.mUpdateMethod;
-        mRestriction = source.mRestriction;
-        mServerUri = source.mServerUri;
-        mUsername = source.mUsername;
-        mBase64EncodedPassword = source.mBase64EncodedPassword;
-        mTrustRootCertUrl = source.mTrustRootCertUrl;
-        if (source.mTrustRootCertSha256Fingerprint != null) {
-            mTrustRootCertSha256Fingerprint = Arrays.copyOf(source.mTrustRootCertSha256Fingerprint,
-                    source.mTrustRootCertSha256Fingerprint.length);
-        }
-        mCaCertificate = source.mCaCertificate;
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeLong(mUpdateIntervalInMinutes);
-        dest.writeString(mUpdateMethod);
-        dest.writeString(mRestriction);
-        dest.writeString(mServerUri);
-        dest.writeString(mUsername);
-        dest.writeString(mBase64EncodedPassword);
-        dest.writeString(mTrustRootCertUrl);
-        dest.writeByteArray(mTrustRootCertSha256Fingerprint);
-        ParcelUtil.writeCertificate(dest, mCaCertificate);
-    }
-
-    @Override
-    public boolean equals(Object thatObject) {
-        if (this == thatObject) {
-            return true;
-        }
-        if (!(thatObject instanceof UpdateParameter)) {
-            return false;
-        }
-        UpdateParameter that = (UpdateParameter) thatObject;
-
-        return mUpdateIntervalInMinutes == that.mUpdateIntervalInMinutes
-                && TextUtils.equals(mUpdateMethod, that.mUpdateMethod)
-                && TextUtils.equals(mRestriction, that.mRestriction)
-                && TextUtils.equals(mServerUri, that.mServerUri)
-                && TextUtils.equals(mUsername, that.mUsername)
-                && TextUtils.equals(mBase64EncodedPassword, that.mBase64EncodedPassword)
-                && TextUtils.equals(mTrustRootCertUrl, that.mTrustRootCertUrl)
-                && Arrays.equals(mTrustRootCertSha256Fingerprint,
-                that.mTrustRootCertSha256Fingerprint)
-                && Credential.isX509CertificateEquals(mCaCertificate, that.mCaCertificate);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(mUpdateIntervalInMinutes, mUpdateMethod, mRestriction, mServerUri,
-                mUsername, mBase64EncodedPassword, mTrustRootCertUrl,
-                Arrays.hashCode(mTrustRootCertSha256Fingerprint), mCaCertificate);
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder builder = new StringBuilder();
-        builder.append("UpdateInterval: ").append(mUpdateIntervalInMinutes).append("\n");
-        builder.append("UpdateMethod: ").append(mUpdateMethod).append("\n");
-        builder.append("Restriction: ").append(mRestriction).append("\n");
-        builder.append("ServerURI: ").append(mServerUri).append("\n");
-        builder.append("Username: ").append(mUsername).append("\n");
-        builder.append("TrustRootCertURL: ").append(mTrustRootCertUrl).append("\n");
-        return builder.toString();
-    }
-
-    /**
-     * Validate UpdateParameter data.
-     *
-     * @return true on success
-     * @hide
-     */
-    public boolean validate() {
-        if (mUpdateIntervalInMinutes == Long.MIN_VALUE) {
-            Log.d(TAG, "Update interval not specified");
-            return false;
-        }
-        // Update not applicable.
-        if (mUpdateIntervalInMinutes == UPDATE_CHECK_INTERVAL_NEVER) {
-            return true;
-        }
-
-        if (!TextUtils.equals(mUpdateMethod, UPDATE_METHOD_OMADM)
-                && !TextUtils.equals(mUpdateMethod, UPDATE_METHOD_SSP)) {
-            Log.d(TAG, "Unknown update method: " + mUpdateMethod);
-            return false;
-        }
-
-        if (!TextUtils.equals(mRestriction, UPDATE_RESTRICTION_HOMESP)
-                && !TextUtils.equals(mRestriction, UPDATE_RESTRICTION_ROAMING_PARTNER)
-                && !TextUtils.equals(mRestriction, UPDATE_RESTRICTION_UNRESTRICTED)) {
-            Log.d(TAG, "Unknown restriction: " + mRestriction);
-            return false;
-        }
-
-        if (TextUtils.isEmpty(mServerUri)) {
-            Log.d(TAG, "Missing update server URI");
-            return false;
-        }
-        if (mServerUri.getBytes(StandardCharsets.UTF_8).length > MAX_URI_BYTES) {
-            Log.d(TAG, "URI bytes exceeded the max: "
-                    + mServerUri.getBytes(StandardCharsets.UTF_8).length);
-            return false;
-        }
-
-        if (TextUtils.isEmpty(mUsername)) {
-            Log.d(TAG, "Missing username");
-            return false;
-        }
-        if (mUsername.getBytes(StandardCharsets.UTF_8).length > MAX_USERNAME_BYTES) {
-            Log.d(TAG, "Username bytes exceeded the max: "
-                    + mUsername.getBytes(StandardCharsets.UTF_8).length);
-            return false;
-        }
-
-        if (TextUtils.isEmpty(mBase64EncodedPassword)) {
-            Log.d(TAG, "Missing username");
-            return false;
-        }
-        if (mBase64EncodedPassword.getBytes(StandardCharsets.UTF_8).length > MAX_PASSWORD_BYTES) {
-            Log.d(TAG, "Password bytes exceeded the max: "
-                    + mBase64EncodedPassword.getBytes(StandardCharsets.UTF_8).length);
-            return false;
-        }
-        try {
-            Base64.decode(mBase64EncodedPassword, Base64.DEFAULT);
-        } catch (IllegalArgumentException e) {
-            Log.d(TAG, "Invalid encoding for password: " + mBase64EncodedPassword);
-            return false;
-        }
-
-        if (TextUtils.isEmpty(mTrustRootCertUrl)) {
-            Log.d(TAG, "Missing trust root certificate URL");
-            return false;
-        }
-        if (mTrustRootCertUrl.getBytes(StandardCharsets.UTF_8).length > MAX_URL_BYTES) {
-            Log.d(TAG, "Trust root cert URL bytes exceeded the max: "
-                    + mTrustRootCertUrl.getBytes(StandardCharsets.UTF_8).length);
-            return false;
-        }
-
-        if (mTrustRootCertSha256Fingerprint == null) {
-            Log.d(TAG, "Missing trust root certificate SHA-256 fingerprint");
-            return false;
-        }
-        if (mTrustRootCertSha256Fingerprint.length != CERTIFICATE_SHA256_BYTES) {
-            Log.d(TAG, "Incorrect size of trust root certificate SHA-256 fingerprint: "
-                    + mTrustRootCertSha256Fingerprint.length);
-            return false;
-        }
-        return true;
-    }
-
-    public static final @android.annotation.NonNull Creator<UpdateParameter> CREATOR =
-        new Creator<UpdateParameter>() {
-            @Override
-            public UpdateParameter createFromParcel(Parcel in) {
-                UpdateParameter updateParam = new UpdateParameter();
-                updateParam.setUpdateIntervalInMinutes(in.readLong());
-                updateParam.setUpdateMethod(in.readString());
-                updateParam.setRestriction(in.readString());
-                updateParam.setServerUri(in.readString());
-                updateParam.setUsername(in.readString());
-                updateParam.setBase64EncodedPassword(in.readString());
-                updateParam.setTrustRootCertUrl(in.readString());
-                updateParam.setTrustRootCertSha256Fingerprint(in.createByteArray());
-                updateParam.setCaCertificate(ParcelUtil.readCertificate(in));
-                return updateParam;
-            }
-
-            @Override
-            public UpdateParameter[] newArray(int size) {
-                return new UpdateParameter[size];
-            }
-        };
-}
diff --git a/wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl b/wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl
deleted file mode 100644
index bfdd45d..0000000
--- a/wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl
+++ /dev/null
@@ -1,34 +0,0 @@
-/**
- * Copyright (c) 2008, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p;
-
-import android.os.Messenger;
-
-/**
- * Interface that WifiP2pService implements
- *
- * {@hide}
- */
-interface IWifiP2pManager
-{
-    Messenger getMessenger(in IBinder binder);
-    Messenger getP2pStateMachineMessenger();
-    oneway void close(in IBinder binder);
-    void setMiracastMode(int mode);
-    void checkConfigureWifiDisplayPermission();
-}
-
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java
deleted file mode 100644
index d479892..0000000
--- a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java
+++ /dev/null
@@ -1,505 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p;
-
-import android.annotation.IntDef;
-import android.annotation.IntRange;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.net.MacAddress;
-import android.net.wifi.WpsInfo;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.nio.charset.StandardCharsets;
-import java.util.regex.PatternSyntaxException;
-
-/**
- * A class representing a Wi-Fi P2p configuration for setting up a connection
- *
- * {@see WifiP2pManager}
- */
-public class WifiP2pConfig implements Parcelable {
-
-    /**
-     * The device MAC address uniquely identifies a Wi-Fi p2p device
-     */
-    public String deviceAddress = "";
-
-    /**
-     * Wi-Fi Protected Setup information
-     */
-    public WpsInfo wps;
-
-    /** Get the network name of this P2P configuration, or null if unset. */
-    @Nullable
-    public String getNetworkName() {
-        return networkName;
-    }
-
-    /** @hide */
-    public String networkName = "";
-
-    /** Get the passphrase of this P2P configuration, or null if unset. */
-    @Nullable
-    public String getPassphrase() {
-        return passphrase;
-    }
-
-    /** @hide */
-    public String passphrase = "";
-
-    /**
-     * Get the required band for the group owner.
-     * The result will be one of the following:
-     * {@link #GROUP_OWNER_BAND_AUTO},
-     * {@link #GROUP_OWNER_BAND_2GHZ},
-     * {@link #GROUP_OWNER_BAND_5GHZ}
-     */
-    @GroupOperatingBandType
-    public int getGroupOwnerBand() {
-        return groupOwnerBand;
-    }
-
-    /** @hide */
-    @GroupOperatingBandType
-    public int groupOwnerBand = GROUP_OWNER_BAND_AUTO;
-
-    /** @hide */
-    @IntDef(flag = false, prefix = { "GROUP_OWNER_BAND_" }, value = {
-        GROUP_OWNER_BAND_AUTO,
-        GROUP_OWNER_BAND_2GHZ,
-        GROUP_OWNER_BAND_5GHZ
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface GroupOperatingBandType {}
-
-    /**
-     * Allow the system to pick the operating frequency from all supported bands.
-     */
-    public static final int GROUP_OWNER_BAND_AUTO = 0;
-    /**
-     * Allow the system to pick the operating frequency from the 2.4 GHz band.
-     */
-    public static final int GROUP_OWNER_BAND_2GHZ = 1;
-    /**
-     * Allow the system to pick the operating frequency from the 5 GHz band.
-     */
-    public static final int GROUP_OWNER_BAND_5GHZ = 2;
-
-    /**
-     * The least inclination to be a group owner, to be filled in the field
-     * {@link #groupOwnerIntent}.
-     */
-    public static final int GROUP_OWNER_INTENT_MIN = 0;
-
-    /**
-     * The most inclination to be a group owner, to be filled in the field
-     * {@link #groupOwnerIntent}.
-     */
-    public static final int GROUP_OWNER_INTENT_MAX = 15;
-
-    /**
-     * The system can choose an appropriate owner intent value, to be filled in the field
-     * {@link #groupOwnerIntent}.
-     */
-    public static final int GROUP_OWNER_INTENT_AUTO = -1;
-
-    /**
-     * This is an integer value between {@link #GROUP_OWNER_INTENT_MIN} and
-     * {@link #GROUP_OWNER_INTENT_MAX} where
-     * {@link #GROUP_OWNER_INTENT_MIN} indicates the least inclination to be a group owner and
-     * {@link #GROUP_OWNER_INTENT_MAX} indicates the highest inclination to be a group owner.
-     *
-     * A value of {@link #GROUP_OWNER_INTENT_AUTO} indicates the system can choose an appropriate
-     * value.
-     *
-     * By default this field is set to {@link #GROUP_OWNER_INTENT_AUTO}.
-     */
-    @IntRange(from = 0, to = 15)
-    public int groupOwnerIntent = GROUP_OWNER_INTENT_AUTO;
-
-    /** @hide */
-    @UnsupportedAppUsage
-    public int netId = WifiP2pGroup.NETWORK_ID_PERSISTENT;
-
-    /**
-     * Get the network ID of this P2P configuration.
-     * @return either a non-negative network ID, or one of
-     * {@link WifiP2pGroup#NETWORK_ID_PERSISTENT} or {@link WifiP2pGroup#NETWORK_ID_TEMPORARY}.
-     */
-    public int getNetworkId() {
-        return netId;
-    }
-
-    public WifiP2pConfig() {
-        //set defaults
-        wps = new WpsInfo();
-        wps.setup = WpsInfo.PBC;
-    }
-
-    /** @hide */
-    public void invalidate() {
-        deviceAddress = "";
-    }
-
-    /** P2P-GO-NEG-REQUEST 42:fc:89:a8:96:09 dev_passwd_id=4 {@hide}*/
-    @UnsupportedAppUsage
-    public WifiP2pConfig(String supplicantEvent) throws IllegalArgumentException {
-        String[] tokens = supplicantEvent.split(" ");
-
-        if (tokens.length < 2 || !tokens[0].equals("P2P-GO-NEG-REQUEST")) {
-            throw new IllegalArgumentException("Malformed supplicant event");
-        }
-
-        deviceAddress = tokens[1];
-        wps = new WpsInfo();
-
-        if (tokens.length > 2) {
-            String[] nameVal = tokens[2].split("=");
-            int devPasswdId;
-            try {
-                devPasswdId = Integer.parseInt(nameVal[1]);
-            } catch (NumberFormatException e) {
-                devPasswdId = 0;
-            }
-            //Based on definitions in wps/wps_defs.h
-            switch (devPasswdId) {
-                //DEV_PW_USER_SPECIFIED = 0x0001,
-                case 0x01:
-                    wps.setup = WpsInfo.DISPLAY;
-                    break;
-                //DEV_PW_PUSHBUTTON = 0x0004,
-                case 0x04:
-                    wps.setup = WpsInfo.PBC;
-                    break;
-                //DEV_PW_REGISTRAR_SPECIFIED = 0x0005
-                case 0x05:
-                    wps.setup = WpsInfo.KEYPAD;
-                    break;
-                default:
-                    wps.setup = WpsInfo.PBC;
-                    break;
-            }
-        }
-    }
-
-    public String toString() {
-        StringBuffer sbuf = new StringBuffer();
-        sbuf.append("\n address: ").append(deviceAddress);
-        sbuf.append("\n wps: ").append(wps);
-        sbuf.append("\n groupOwnerIntent: ").append(groupOwnerIntent);
-        sbuf.append("\n persist: ").append(netId);
-        sbuf.append("\n networkName: ").append(networkName);
-        sbuf.append("\n passphrase: ").append(
-                TextUtils.isEmpty(passphrase) ? "<empty>" : "<non-empty>");
-        sbuf.append("\n groupOwnerBand: ").append(groupOwnerBand);
-        return sbuf.toString();
-    }
-
-    /** Implement the Parcelable interface */
-    public int describeContents() {
-        return 0;
-    }
-
-    /** copy constructor */
-    public WifiP2pConfig(WifiP2pConfig source) {
-        if (source != null) {
-            deviceAddress = source.deviceAddress;
-            wps = new WpsInfo(source.wps);
-            groupOwnerIntent = source.groupOwnerIntent;
-            netId = source.netId;
-            networkName = source.networkName;
-            passphrase = source.passphrase;
-            groupOwnerBand = source.groupOwnerBand;
-        }
-    }
-
-    /** Implement the Parcelable interface */
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeString(deviceAddress);
-        dest.writeParcelable(wps, flags);
-        dest.writeInt(groupOwnerIntent);
-        dest.writeInt(netId);
-        dest.writeString(networkName);
-        dest.writeString(passphrase);
-        dest.writeInt(groupOwnerBand);
-    }
-
-    /** Implement the Parcelable interface */
-    public static final @android.annotation.NonNull Creator<WifiP2pConfig> CREATOR =
-        new Creator<WifiP2pConfig>() {
-            public WifiP2pConfig createFromParcel(Parcel in) {
-                WifiP2pConfig config = new WifiP2pConfig();
-                config.deviceAddress = in.readString();
-                config.wps = (WpsInfo) in.readParcelable(null);
-                config.groupOwnerIntent = in.readInt();
-                config.netId = in.readInt();
-                config.networkName = in.readString();
-                config.passphrase = in.readString();
-                config.groupOwnerBand = in.readInt();
-                return config;
-            }
-
-            public WifiP2pConfig[] newArray(int size) {
-                return new WifiP2pConfig[size];
-            }
-        };
-
-    /**
-     * Builder used to build {@link WifiP2pConfig} objects for
-     * creating or joining a group.
-     */
-    public static final class Builder {
-
-        private static final MacAddress MAC_ANY_ADDRESS =
-                MacAddress.fromString("02:00:00:00:00:00");
-        /**
-         * Maximum number of bytes allowed for a SSID.
-         */
-        private static final int MAX_SSID_BYTES = 32;
-
-        private MacAddress mDeviceAddress = MAC_ANY_ADDRESS;
-        private String mNetworkName = "";
-        private String mPassphrase = "";
-        private int mGroupOperatingBand = GROUP_OWNER_BAND_AUTO;
-        private int mGroupOperatingFrequency = GROUP_OWNER_BAND_AUTO;
-        private int mNetId = WifiP2pGroup.NETWORK_ID_TEMPORARY;
-
-        /**
-         * Specify the peer's MAC address. If not set, the device will
-         * try to find a peer whose SSID matches the network name as
-         * specified by {@link #setNetworkName(String)}. Specifying null will
-         * reset the peer's MAC address to "02:00:00:00:00:00".
-         * <p>
-         *     Optional. "02:00:00:00:00:00" by default.
-         *
-         * @param deviceAddress the peer's MAC address.
-         * @return The builder to facilitate chaining
-         *         {@code builder.setXXX(..).setXXX(..)}.
-         */
-        public @NonNull Builder setDeviceAddress(@Nullable MacAddress deviceAddress) {
-            if (deviceAddress == null) {
-                mDeviceAddress = MAC_ANY_ADDRESS;
-            } else {
-                mDeviceAddress = deviceAddress;
-            }
-            return this;
-        }
-
-        /**
-         * Specify the network name, a.k.a. group name,
-         * for creating or joining a group.
-         * <p>
-         * A network name shall begin with "DIRECT-xy". x and y are selected
-         * from the following character set: upper case letters, lower case
-         * letters and numbers. Any byte values allowed for an SSID according to
-         * IEEE802.11-2012 [1] may be included after the string "DIRECT-xy"
-         * (including none).
-         * <p>
-         *     Must be called - an empty network name or an network name
-         *     not conforming to the P2P Group ID naming rule is not valid.
-         *
-         * @param networkName network name of a group.
-         * @return The builder to facilitate chaining
-         *         {@code builder.setXXX(..).setXXX(..)}.
-         */
-        public @NonNull Builder setNetworkName(@NonNull String networkName) {
-            if (TextUtils.isEmpty(networkName)) {
-                throw new IllegalArgumentException(
-                        "network name must be non-empty.");
-            }
-            if (networkName.getBytes(StandardCharsets.UTF_8).length > MAX_SSID_BYTES) {
-                throw new IllegalArgumentException(
-                        "network name exceeds " + MAX_SSID_BYTES + " bytes.");
-            }
-            try {
-                if (!networkName.matches("^DIRECT-[a-zA-Z0-9]{2}.*")) {
-                    throw new IllegalArgumentException(
-                            "network name must starts with the prefix DIRECT-xy.");
-                }
-            } catch (PatternSyntaxException e) {
-                // can never happen (fixed pattern)
-            }
-            mNetworkName = networkName;
-            return this;
-        }
-
-        /**
-         * Specify the passphrase for creating or joining a group.
-         * <p>
-         * The passphrase must be an ASCII string whose length is between 8
-         * and 63.
-         * <p>
-         *     Must be called - an empty passphrase is not valid.
-         *
-         * @param passphrase the passphrase of a group.
-         * @return The builder to facilitate chaining
-         *         {@code builder.setXXX(..).setXXX(..)}.
-         */
-        public @NonNull Builder setPassphrase(@NonNull String passphrase) {
-            if (TextUtils.isEmpty(passphrase)) {
-                throw new IllegalArgumentException(
-                        "passphrase must be non-empty.");
-            }
-            if (passphrase.length() < 8 || passphrase.length() > 63) {
-                throw new IllegalArgumentException(
-                        "The length of a passphrase must be between 8 and 63.");
-            }
-            mPassphrase = passphrase;
-            return this;
-        }
-
-        /**
-         * Specify the band to use for creating the group or joining the group. The band should
-         * be {@link #GROUP_OWNER_BAND_2GHZ}, {@link #GROUP_OWNER_BAND_5GHZ} or
-         * {@link #GROUP_OWNER_BAND_AUTO}.
-         * <p>
-         * When creating a group as Group Owner using {@link
-         * WifiP2pManager#createGroup(WifiP2pManager.Channel,
-         * WifiP2pConfig, WifiP2pManager.ActionListener)},
-         * specifying {@link #GROUP_OWNER_BAND_AUTO} allows the system to pick the operating
-         * frequency from all supported bands.
-         * Specifying {@link #GROUP_OWNER_BAND_2GHZ} or {@link #GROUP_OWNER_BAND_5GHZ}
-         * only allows the system to pick the operating frequency in the specified band.
-         * If the Group Owner cannot create a group in the specified band, the operation will fail.
-         * <p>
-         * When joining a group as Group Client using {@link
-         * WifiP2pManager#connect(WifiP2pManager.Channel, WifiP2pConfig,
-         * WifiP2pManager.ActionListener)},
-         * specifying {@link #GROUP_OWNER_BAND_AUTO} allows the system to scan all supported
-         * frequencies to find the desired group. Specifying {@link #GROUP_OWNER_BAND_2GHZ} or
-         * {@link #GROUP_OWNER_BAND_5GHZ} only allows the system to scan the specified band.
-         * <p>
-         *     {@link #setGroupOperatingBand(int)} and {@link #setGroupOperatingFrequency(int)} are
-         *     mutually exclusive. Setting operating band and frequency both is invalid.
-         * <p>
-         *     Optional. {@link #GROUP_OWNER_BAND_AUTO} by default.
-         *
-         * @param band the operating band of the group.
-         *             This should be one of {@link #GROUP_OWNER_BAND_AUTO},
-         *             {@link #GROUP_OWNER_BAND_2GHZ}, {@link #GROUP_OWNER_BAND_5GHZ}.
-         * @return The builder to facilitate chaining
-         *         {@code builder.setXXX(..).setXXX(..)}.
-         */
-        public @NonNull Builder setGroupOperatingBand(@GroupOperatingBandType int band) {
-            switch (band) {
-                case GROUP_OWNER_BAND_AUTO:
-                case GROUP_OWNER_BAND_2GHZ:
-                case GROUP_OWNER_BAND_5GHZ:
-                    mGroupOperatingBand = band;
-                    break;
-                default:
-                    throw new IllegalArgumentException(
-                        "Invalid constant for the group operating band!");
-            }
-            return this;
-        }
-
-        /**
-         * Specify the frequency, in MHz, to use for creating the group or joining the group.
-         * <p>
-         * When creating a group as Group Owner using {@link WifiP2pManager#createGroup(
-         * WifiP2pManager.Channel, WifiP2pConfig, WifiP2pManager.ActionListener)},
-         * specifying a frequency only allows the system to pick the specified frequency.
-         * If the Group Owner cannot create a group at the specified frequency,
-         * the operation will fail.
-         * When not specifying a frequency, it allows the system to pick operating frequency
-         * from all supported bands.
-         * <p>
-         * When joining a group as Group Client using {@link WifiP2pManager#connect(
-         * WifiP2pManager.Channel, WifiP2pConfig, WifiP2pManager.ActionListener)},
-         * specifying a frequency only allows the system to scan the specified frequency.
-         * If the frequency is not supported or invalid, the operation will fail.
-         * When not specifying a frequency, it allows the system to scan all supported
-         * frequencies to find the desired group.
-         * <p>
-         *     {@link #setGroupOperatingBand(int)} and {@link #setGroupOperatingFrequency(int)} are
-         *     mutually exclusive. Setting operating band and frequency both is invalid.
-         * <p>
-         *     Optional. 0 by default.
-         *
-         * @param frequency the operating frequency of the group.
-         * @return The builder to facilitate chaining
-         *         {@code builder.setXXX(..).setXXX(..)}.
-         */
-        public @NonNull Builder setGroupOperatingFrequency(int frequency) {
-            if (frequency < 0) {
-                throw new IllegalArgumentException(
-                    "Invalid group operating frequency!");
-            }
-            mGroupOperatingFrequency = frequency;
-            return this;
-        }
-
-        /**
-         * Specify that the group configuration be persisted (i.e. saved).
-         * By default the group configuration will not be saved.
-         * <p>
-         *     Optional. false by default.
-         *
-         * @param persistent is this group persistent group.
-         * @return The builder to facilitate chaining
-         *         {@code builder.setXXX(..).setXXX(..)}.
-         */
-        public @NonNull Builder enablePersistentMode(boolean persistent) {
-            if (persistent) {
-                mNetId = WifiP2pGroup.NETWORK_ID_PERSISTENT;
-            } else {
-                mNetId = WifiP2pGroup.NETWORK_ID_TEMPORARY;
-            }
-            return this;
-        }
-
-        /**
-         * Build {@link WifiP2pConfig} given the current requests made on the builder.
-         * @return {@link WifiP2pConfig} constructed based on builder method calls.
-         */
-        public @NonNull WifiP2pConfig build() {
-            if (TextUtils.isEmpty(mNetworkName)) {
-                throw new IllegalStateException(
-                        "network name must be non-empty.");
-            }
-            if (TextUtils.isEmpty(mPassphrase)) {
-                throw new IllegalStateException(
-                        "passphrase must be non-empty.");
-            }
-
-            if (mGroupOperatingFrequency > 0 && mGroupOperatingBand > 0) {
-                throw new IllegalStateException(
-                        "Preferred frequency and band are mutually exclusive.");
-            }
-
-            WifiP2pConfig config = new WifiP2pConfig();
-            config.deviceAddress = mDeviceAddress.toString();
-            config.networkName = mNetworkName;
-            config.passphrase = mPassphrase;
-            config.groupOwnerBand = GROUP_OWNER_BAND_AUTO;
-            if (mGroupOperatingFrequency > 0) {
-                config.groupOwnerBand = mGroupOperatingFrequency;
-            } else if (mGroupOperatingBand > 0) {
-                config.groupOwnerBand = mGroupOperatingBand;
-            }
-            config.netId = mNetId;
-            return config;
-        }
-    }
-}
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java b/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java
deleted file mode 100644
index 710175f..0000000
--- a/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java
+++ /dev/null
@@ -1,434 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.Log;
-
-import java.util.Objects;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * A class representing a Wi-Fi p2p device
- *
- * Note that the operations are not thread safe
- * {@see WifiP2pManager}
- */
-public class WifiP2pDevice implements Parcelable {
-
-    private static final String TAG = "WifiP2pDevice";
-
-    /**
-     * The device name is a user friendly string to identify a Wi-Fi p2p device
-     */
-    public String deviceName = "";
-
-    /**
-     * The device MAC address uniquely identifies a Wi-Fi p2p device
-     */
-    public String deviceAddress = "";
-
-    /**
-     * Primary device type identifies the type of device. For example, an application
-     * could filter the devices discovered to only display printers if the purpose is to
-     * enable a printing action from the user. See the Wi-Fi Direct technical specification
-     * for the full list of standard device types supported.
-     */
-    public String primaryDeviceType;
-
-    /**
-     * Secondary device type is an optional attribute that can be provided by a device in
-     * addition to the primary device type.
-     */
-    public String secondaryDeviceType;
-
-
-    // These definitions match the ones in wpa_supplicant
-    /* WPS config methods supported */
-    private static final int WPS_CONFIG_DISPLAY         = 0x0008;
-    private static final int WPS_CONFIG_PUSHBUTTON      = 0x0080;
-    private static final int WPS_CONFIG_KEYPAD          = 0x0100;
-
-    /* Device Capability bitmap */
-    private static final int DEVICE_CAPAB_SERVICE_DISCOVERY         = 1;
-    @SuppressWarnings("unused")
-    private static final int DEVICE_CAPAB_CLIENT_DISCOVERABILITY    = 1<<1;
-    @SuppressWarnings("unused")
-    private static final int DEVICE_CAPAB_CONCURRENT_OPER           = 1<<2;
-    @SuppressWarnings("unused")
-    private static final int DEVICE_CAPAB_INFRA_MANAGED             = 1<<3;
-    @SuppressWarnings("unused")
-    private static final int DEVICE_CAPAB_DEVICE_LIMIT              = 1<<4;
-    private static final int DEVICE_CAPAB_INVITATION_PROCEDURE      = 1<<5;
-
-    /* Group Capability bitmap */
-    private static final int GROUP_CAPAB_GROUP_OWNER                = 1;
-    @SuppressWarnings("unused")
-    private static final int GROUP_CAPAB_PERSISTENT_GROUP           = 1<<1;
-    private static final int GROUP_CAPAB_GROUP_LIMIT                = 1<<2;
-    @SuppressWarnings("unused")
-    private static final int GROUP_CAPAB_INTRA_BSS_DIST             = 1<<3;
-    @SuppressWarnings("unused")
-    private static final int GROUP_CAPAB_CROSS_CONN                 = 1<<4;
-    @SuppressWarnings("unused")
-    private static final int GROUP_CAPAB_PERSISTENT_RECONN          = 1<<5;
-    @SuppressWarnings("unused")
-    private static final int GROUP_CAPAB_GROUP_FORMATION            = 1<<6;
-
-    /**
-     * WPS config methods supported
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public int wpsConfigMethodsSupported;
-
-    /**
-     * Device capability
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public int deviceCapability;
-
-    /**
-     * Group capability
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public int groupCapability;
-
-    public static final int CONNECTED   = 0;
-    public static final int INVITED     = 1;
-    public static final int FAILED      = 2;
-    public static final int AVAILABLE   = 3;
-    public static final int UNAVAILABLE = 4;
-
-    /** Device connection status */
-    public int status = UNAVAILABLE;
-
-    /** @hide */
-    @UnsupportedAppUsage
-    public WifiP2pWfdInfo wfdInfo;
-
-    /** Detailed device string pattern with WFD info
-     * Example:
-     *  P2P-DEVICE-FOUND 00:18:6b:de:a3:6e p2p_dev_addr=00:18:6b:de:a3:6e
-     *  pri_dev_type=1-0050F204-1 name='DWD-300-DEA36E' config_methods=0x188
-     *  dev_capab=0x21 group_capab=0x9
-     */
-    private static final Pattern detailedDevicePattern = Pattern.compile(
-        "((?:[0-9a-f]{2}:){5}[0-9a-f]{2}) " +
-        "(\\d+ )?" +
-        "p2p_dev_addr=((?:[0-9a-f]{2}:){5}[0-9a-f]{2}) " +
-        "pri_dev_type=(\\d+-[0-9a-fA-F]+-\\d+) " +
-        "name='(.*)' " +
-        "config_methods=(0x[0-9a-fA-F]+) " +
-        "dev_capab=(0x[0-9a-fA-F]+) " +
-        "group_capab=(0x[0-9a-fA-F]+)" +
-        "( wfd_dev_info=0x([0-9a-fA-F]{12}))?"
-    );
-
-    /** 2 token device address pattern
-     * Example:
-     *  P2P-DEVICE-LOST p2p_dev_addr=fa:7b:7a:42:02:13
-     *  AP-STA-DISCONNECTED 42:fc:89:a8:96:09
-     */
-    private static final Pattern twoTokenPattern = Pattern.compile(
-        "(p2p_dev_addr=)?((?:[0-9a-f]{2}:){5}[0-9a-f]{2})"
-    );
-
-    /** 3 token device address pattern
-     * Example:
-     *  AP-STA-CONNECTED 42:fc:89:a8:96:09 p2p_dev_addr=fa:7b:7a:42:02:13
-     *  AP-STA-DISCONNECTED 42:fc:89:a8:96:09 p2p_dev_addr=fa:7b:7a:42:02:13
-     */
-    private static final Pattern threeTokenPattern = Pattern.compile(
-        "(?:[0-9a-f]{2}:){5}[0-9a-f]{2} p2p_dev_addr=((?:[0-9a-f]{2}:){5}[0-9a-f]{2})"
-    );
-
-
-    public WifiP2pDevice() {
-    }
-
-    /**
-     * @param string formats supported include
-     *  P2P-DEVICE-FOUND fa:7b:7a:42:02:13 p2p_dev_addr=fa:7b:7a:42:02:13
-     *  pri_dev_type=1-0050F204-1 name='p2p-TEST1' config_methods=0x188 dev_capab=0x27
-     *  group_capab=0x0 wfd_dev_info=000006015d022a0032
-     *
-     *  P2P-DEVICE-LOST p2p_dev_addr=fa:7b:7a:42:02:13
-     *
-     *  AP-STA-CONNECTED 42:fc:89:a8:96:09 [p2p_dev_addr=02:90:4c:a0:92:54]
-     *
-     *  AP-STA-DISCONNECTED 42:fc:89:a8:96:09 [p2p_dev_addr=02:90:4c:a0:92:54]
-     *
-     *  fa:7b:7a:42:02:13
-     *
-     *  Note: The events formats can be looked up in the wpa_supplicant code
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public WifiP2pDevice(String string) throws IllegalArgumentException {
-        String[] tokens = string.split("[ \n]");
-        Matcher match;
-
-        if (tokens.length < 1) {
-            throw new IllegalArgumentException("Malformed supplicant event");
-        }
-
-        switch (tokens.length) {
-            case 1:
-                /* Just a device address */
-                deviceAddress = string;
-                return;
-            case 2:
-                match = twoTokenPattern.matcher(string);
-                if (!match.find()) {
-                    throw new IllegalArgumentException("Malformed supplicant event");
-                }
-                deviceAddress = match.group(2);
-                return;
-            case 3:
-                match = threeTokenPattern.matcher(string);
-                if (!match.find()) {
-                    throw new IllegalArgumentException("Malformed supplicant event");
-                }
-                deviceAddress = match.group(1);
-                return;
-            default:
-                match = detailedDevicePattern.matcher(string);
-                if (!match.find()) {
-                    throw new IllegalArgumentException("Malformed supplicant event");
-                }
-
-                deviceAddress = match.group(3);
-                primaryDeviceType = match.group(4);
-                deviceName = match.group(5);
-                wpsConfigMethodsSupported = parseHex(match.group(6));
-                deviceCapability = parseHex(match.group(7));
-                groupCapability = parseHex(match.group(8));
-                if (match.group(9) != null) {
-                    String str = match.group(10);
-                    wfdInfo = new WifiP2pWfdInfo(parseHex(str.substring(0,4)),
-                            parseHex(str.substring(4,8)),
-                            parseHex(str.substring(8,12)));
-                }
-                break;
-        }
-
-        if (tokens[0].startsWith("P2P-DEVICE-FOUND")) {
-            status = AVAILABLE;
-        }
-    }
-
-    /** The Wifi Display information for this device, or null if unavailable. */
-    @Nullable
-    public WifiP2pWfdInfo getWfdInfo() {
-        return wfdInfo;
-    }
-
-    /** Returns true if WPS push button configuration is supported */
-    public boolean wpsPbcSupported() {
-        return (wpsConfigMethodsSupported & WPS_CONFIG_PUSHBUTTON) != 0;
-    }
-
-    /** Returns true if WPS keypad configuration is supported */
-    public boolean wpsKeypadSupported() {
-        return (wpsConfigMethodsSupported & WPS_CONFIG_KEYPAD) != 0;
-    }
-
-    /** Returns true if WPS display configuration is supported */
-    public boolean wpsDisplaySupported() {
-        return (wpsConfigMethodsSupported & WPS_CONFIG_DISPLAY) != 0;
-    }
-
-    /** Returns true if the device is capable of service discovery */
-    public boolean isServiceDiscoveryCapable() {
-        return (deviceCapability & DEVICE_CAPAB_SERVICE_DISCOVERY) != 0;
-    }
-
-    /** Returns true if the device is capable of invitation {@hide}*/
-    public boolean isInvitationCapable() {
-        return (deviceCapability & DEVICE_CAPAB_INVITATION_PROCEDURE) != 0;
-    }
-
-    /** Returns true if the device reaches the limit. {@hide}*/
-    public boolean isDeviceLimit() {
-        return (deviceCapability & DEVICE_CAPAB_DEVICE_LIMIT) != 0;
-    }
-
-    /** Returns true if the device is a group owner */
-    public boolean isGroupOwner() {
-        return (groupCapability & GROUP_CAPAB_GROUP_OWNER) != 0;
-    }
-
-    /** Returns true if the group reaches the limit. {@hide}*/
-    public boolean isGroupLimit() {
-        return (groupCapability & GROUP_CAPAB_GROUP_LIMIT) != 0;
-    }
-
-    /**
-     * Update this device's details using another {@link WifiP2pDevice} instance.
-     * This will throw an exception if the device address does not match.
-     *
-     * @param device another instance of {@link WifiP2pDevice} used to update this instance.
-     * @throws IllegalArgumentException if the device is null or the device address does not match
-     */
-    public void update(@NonNull WifiP2pDevice device) {
-        updateSupplicantDetails(device);
-        status = device.status;
-    }
-
-    /** Updates details obtained from supplicant @hide */
-    public void updateSupplicantDetails(WifiP2pDevice device) {
-        if (device == null) {
-            throw new IllegalArgumentException("device is null");
-        }
-        if (device.deviceAddress == null) {
-            throw new IllegalArgumentException("deviceAddress is null");
-        }
-        if (!deviceAddress.equals(device.deviceAddress)) {
-            throw new IllegalArgumentException("deviceAddress does not match");
-        }
-        deviceName = device.deviceName;
-        primaryDeviceType = device.primaryDeviceType;
-        secondaryDeviceType = device.secondaryDeviceType;
-        wpsConfigMethodsSupported = device.wpsConfigMethodsSupported;
-        deviceCapability = device.deviceCapability;
-        groupCapability = device.groupCapability;
-        wfdInfo = device.wfdInfo;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) return true;
-        if (!(obj instanceof WifiP2pDevice)) return false;
-
-        WifiP2pDevice other = (WifiP2pDevice) obj;
-        if (other == null || other.deviceAddress == null) {
-            return (deviceAddress == null);
-        }
-        return other.deviceAddress.equals(deviceAddress);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hashCode(deviceAddress);
-    }
-
-    @Override
-    public String toString() {
-        StringBuffer sbuf = new StringBuffer();
-        sbuf.append("Device: ").append(deviceName);
-        sbuf.append("\n deviceAddress: ").append(deviceAddress);
-        sbuf.append("\n primary type: ").append(primaryDeviceType);
-        sbuf.append("\n secondary type: ").append(secondaryDeviceType);
-        sbuf.append("\n wps: ").append(wpsConfigMethodsSupported);
-        sbuf.append("\n grpcapab: ").append(groupCapability);
-        sbuf.append("\n devcapab: ").append(deviceCapability);
-        sbuf.append("\n status: ").append(status);
-        sbuf.append("\n wfdInfo: ").append(wfdInfo);
-        return sbuf.toString();
-    }
-
-    /** Implement the Parcelable interface */
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    /** copy constructor */
-    public WifiP2pDevice(WifiP2pDevice source) {
-        if (source != null) {
-            deviceName = source.deviceName;
-            deviceAddress = source.deviceAddress;
-            primaryDeviceType = source.primaryDeviceType;
-            secondaryDeviceType = source.secondaryDeviceType;
-            wpsConfigMethodsSupported = source.wpsConfigMethodsSupported;
-            deviceCapability = source.deviceCapability;
-            groupCapability = source.groupCapability;
-            status = source.status;
-            if (source.wfdInfo != null) {
-                wfdInfo = new WifiP2pWfdInfo(source.wfdInfo);
-            }
-        }
-    }
-
-    /** Implement the Parcelable interface */
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeString(deviceName);
-        dest.writeString(deviceAddress);
-        dest.writeString(primaryDeviceType);
-        dest.writeString(secondaryDeviceType);
-        dest.writeInt(wpsConfigMethodsSupported);
-        dest.writeInt(deviceCapability);
-        dest.writeInt(groupCapability);
-        dest.writeInt(status);
-        if (wfdInfo != null) {
-            dest.writeInt(1);
-            wfdInfo.writeToParcel(dest, flags);
-        } else {
-            dest.writeInt(0);
-        }
-    }
-
-    /** Implement the Parcelable interface */
-    public static final @android.annotation.NonNull Creator<WifiP2pDevice> CREATOR =
-        new Creator<WifiP2pDevice>() {
-            @Override
-            public WifiP2pDevice createFromParcel(Parcel in) {
-                WifiP2pDevice device = new WifiP2pDevice();
-                device.deviceName = in.readString();
-                device.deviceAddress = in.readString();
-                device.primaryDeviceType = in.readString();
-                device.secondaryDeviceType = in.readString();
-                device.wpsConfigMethodsSupported = in.readInt();
-                device.deviceCapability = in.readInt();
-                device.groupCapability = in.readInt();
-                device.status = in.readInt();
-                if (in.readInt() == 1) {
-                    device.wfdInfo = WifiP2pWfdInfo.CREATOR.createFromParcel(in);
-                }
-                return device;
-            }
-
-            @Override
-            public WifiP2pDevice[] newArray(int size) {
-                return new WifiP2pDevice[size];
-            }
-        };
-
-    //supported formats: 0x1abc, 0X1abc, 1abc
-    private int parseHex(String hexString) {
-        int num = 0;
-        if (hexString.startsWith("0x") || hexString.startsWith("0X")) {
-            hexString = hexString.substring(2);
-        }
-
-        try {
-            num = Integer.parseInt(hexString, 16);
-        } catch(NumberFormatException e) {
-            Log.e(TAG, "Failed to parse hex string " + hexString);
-        }
-        return num;
-    }
-}
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java b/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java
deleted file mode 100644
index ededf67..0000000
--- a/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p;
-
-import android.compat.annotation.UnsupportedAppUsage;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-
-/**
- * A class representing a Wi-Fi P2p device list.
- *
- * Note that the operations are not thread safe.
- * {@see WifiP2pManager}
- */
-public class WifiP2pDeviceList implements Parcelable {
-
-    private final HashMap<String, WifiP2pDevice> mDevices = new HashMap<String, WifiP2pDevice>();
-
-    public WifiP2pDeviceList() {
-    }
-
-    /** copy constructor */
-    public WifiP2pDeviceList(WifiP2pDeviceList source) {
-        if (source != null) {
-            for (WifiP2pDevice d : source.getDeviceList()) {
-                mDevices.put(d.deviceAddress, new WifiP2pDevice(d));
-            }
-        }
-    }
-
-    /** @hide */
-    public WifiP2pDeviceList(ArrayList<WifiP2pDevice> devices) {
-        for (WifiP2pDevice device : devices) {
-            if (device.deviceAddress != null) {
-                mDevices.put(device.deviceAddress, new WifiP2pDevice(device));
-            }
-        }
-    }
-
-    private void validateDevice(WifiP2pDevice device) {
-        if (device == null) throw new IllegalArgumentException("Null device");
-        if (TextUtils.isEmpty(device.deviceAddress)) {
-            throw new IllegalArgumentException("Empty deviceAddress");
-        }
-    }
-
-    private void validateDeviceAddress(String deviceAddress) {
-        if (TextUtils.isEmpty(deviceAddress)) {
-            throw new IllegalArgumentException("Empty deviceAddress");
-        }
-    }
-
-    /** Clear the list @hide */
-    public boolean clear() {
-        if (mDevices.isEmpty()) return false;
-        mDevices.clear();
-        return true;
-    }
-
-    /**
-     * Add/update a device to the list. If the device is not found, a new device entry
-     * is created. If the device is already found, the device details are updated
-     * @param device to be updated
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public void update(WifiP2pDevice device) {
-        updateSupplicantDetails(device);
-        mDevices.get(device.deviceAddress).status = device.status;
-    }
-
-    /** Only updates details fetched from the supplicant @hide */
-    public void updateSupplicantDetails(WifiP2pDevice device) {
-        validateDevice(device);
-        WifiP2pDevice d = mDevices.get(device.deviceAddress);
-        if (d != null) {
-            d.deviceName = device.deviceName;
-            d.primaryDeviceType = device.primaryDeviceType;
-            d.secondaryDeviceType = device.secondaryDeviceType;
-            d.wpsConfigMethodsSupported = device.wpsConfigMethodsSupported;
-            d.deviceCapability = device.deviceCapability;
-            d.groupCapability = device.groupCapability;
-            d.wfdInfo = device.wfdInfo;
-            return;
-        }
-        //Not found, add a new one
-        mDevices.put(device.deviceAddress, device);
-    }
-
-    /** @hide */
-    public void updateGroupCapability(String deviceAddress, int groupCapab) {
-        validateDeviceAddress(deviceAddress);
-        WifiP2pDevice d = mDevices.get(deviceAddress);
-        if (d != null) {
-            d.groupCapability = groupCapab;
-        }
-    }
-
-    /** @hide */
-    public void updateStatus(String deviceAddress, int status) {
-        validateDeviceAddress(deviceAddress);
-        WifiP2pDevice d = mDevices.get(deviceAddress);
-        if (d != null) {
-            d.status = status;
-        }
-    }
-
-    /**
-     * Fetch a device from the list
-     * @param deviceAddress is the address of the device
-     * @return WifiP2pDevice device found, or null if none found
-     */
-    public WifiP2pDevice get(String deviceAddress) {
-        validateDeviceAddress(deviceAddress);
-        return mDevices.get(deviceAddress);
-    }
-
-    /** @hide */
-    public boolean remove(WifiP2pDevice device) {
-        validateDevice(device);
-        return mDevices.remove(device.deviceAddress) != null;
-    }
-
-    /**
-     * Remove a device from the list
-     * @param deviceAddress is the address of the device
-     * @return WifiP2pDevice device removed, or null if none removed
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public WifiP2pDevice remove(String deviceAddress) {
-        validateDeviceAddress(deviceAddress);
-        return mDevices.remove(deviceAddress);
-    }
-
-    /** Returns true if any device the list was removed @hide */
-    public boolean remove(WifiP2pDeviceList list) {
-        boolean ret = false;
-        for (WifiP2pDevice d : list.mDevices.values()) {
-            if (remove(d)) ret = true;
-        }
-        return ret;
-    }
-
-    /** Get the list of devices */
-    public Collection<WifiP2pDevice> getDeviceList() {
-        return Collections.unmodifiableCollection(mDevices.values());
-    }
-
-    /** @hide */
-    public boolean isGroupOwner(String deviceAddress) {
-        validateDeviceAddress(deviceAddress);
-        WifiP2pDevice device = mDevices.get(deviceAddress);
-        if (device == null) {
-            throw new IllegalArgumentException("Device not found " + deviceAddress);
-        }
-        return device.isGroupOwner();
-    }
-
-    public String toString() {
-        StringBuffer sbuf = new StringBuffer();
-        for (WifiP2pDevice device : mDevices.values()) {
-            sbuf.append("\n").append(device);
-        }
-        return sbuf.toString();
-    }
-
-    /** Implement the Parcelable interface */
-    public int describeContents() {
-        return 0;
-    }
-
-    /** Implement the Parcelable interface */
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mDevices.size());
-        for(WifiP2pDevice device : mDevices.values()) {
-            dest.writeParcelable(device, flags);
-        }
-    }
-
-    /** Implement the Parcelable interface */
-    public static final @android.annotation.NonNull Creator<WifiP2pDeviceList> CREATOR =
-        new Creator<WifiP2pDeviceList>() {
-            public WifiP2pDeviceList createFromParcel(Parcel in) {
-                WifiP2pDeviceList deviceList = new WifiP2pDeviceList();
-
-                int deviceCount = in.readInt();
-                for (int i = 0; i < deviceCount; i++) {
-                    deviceList.update((WifiP2pDevice)in.readParcelable(null));
-                }
-                return deviceList;
-            }
-
-            public WifiP2pDeviceList[] newArray(int size) {
-                return new WifiP2pDeviceList[size];
-            }
-        };
-}
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java b/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java
deleted file mode 100644
index e497b22..0000000
--- a/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java
+++ /dev/null
@@ -1,371 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p;
-
-import android.annotation.Nullable;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * A class representing a Wi-Fi P2p group. A p2p group consists of a single group
- * owner and one or more clients. In the case of a group with only two devices, one
- * will be the group owner and the other will be a group client.
- *
- * {@see WifiP2pManager}
- */
-public class WifiP2pGroup implements Parcelable {
-
-    /**
-     * The temporary network id.
-     * @see #getNetworkId()
-     */
-    public static final int NETWORK_ID_TEMPORARY = -1;
-
-    /**
-     * The temporary network id.
-     *
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public static final int TEMPORARY_NET_ID = NETWORK_ID_TEMPORARY;
-
-    /**
-     * The persistent network id.
-     * If a matching persistent profile is found, use it.
-     * Otherwise, create a new persistent profile.
-     * @see #getNetworkId()
-     */
-    public static final int NETWORK_ID_PERSISTENT = -2;
-
-    /** The network name */
-    private String mNetworkName;
-
-    /** Group owner */
-    private WifiP2pDevice mOwner;
-
-    /** Device is group owner */
-    private boolean mIsGroupOwner;
-
-    /** Group clients */
-    private List<WifiP2pDevice> mClients = new ArrayList<WifiP2pDevice>();
-
-    /** The passphrase used for WPA2-PSK */
-    private String mPassphrase;
-
-    private String mInterface;
-
-    /** The network ID in wpa_supplicant */
-    private int mNetId;
-
-    /** The frequency (in MHz) used by this group */
-    private int mFrequency;
-
-    /** P2P group started string pattern */
-    private static final Pattern groupStartedPattern = Pattern.compile(
-        "ssid=\"(.+)\" " +
-        "freq=(\\d+) " +
-        "(?:psk=)?([0-9a-fA-F]{64})?" +
-        "(?:passphrase=)?(?:\"(.{0,63})\")? " +
-        "go_dev_addr=((?:[0-9a-f]{2}:){5}[0-9a-f]{2})" +
-        " ?(\\[PERSISTENT\\])?"
-    );
-
-    public WifiP2pGroup() {
-    }
-
-    /**
-     * @param supplicantEvent formats supported include
-     *
-     *  P2P-GROUP-STARTED p2p-wlan0-0 [client|GO] ssid="DIRECT-W8" freq=2437
-     *  [psk=2182b2e50e53f260d04f3c7b25ef33c965a3291b9b36b455a82d77fd82ca15bc|
-     *  passphrase="fKG4jMe3"] go_dev_addr=fa:7b:7a:42:02:13 [PERSISTENT]
-     *
-     *  P2P-GROUP-REMOVED p2p-wlan0-0 [client|GO] reason=REQUESTED
-     *
-     *  P2P-INVITATION-RECEIVED sa=fa:7b:7a:42:02:13 go_dev_addr=f8:7b:7a:42:02:13
-     *  bssid=fa:7b:7a:42:82:13 unknown-network
-     *
-     *  P2P-INVITATION-RECEIVED sa=b8:f9:34:2a:c7:9d persistent=0
-     *
-     *  Note: The events formats can be looked up in the wpa_supplicant code
-     *  @hide
-     */
-    @UnsupportedAppUsage
-    public WifiP2pGroup(String supplicantEvent) throws IllegalArgumentException {
-
-        String[] tokens = supplicantEvent.split(" ");
-
-        if (tokens.length < 3) {
-            throw new IllegalArgumentException("Malformed supplicant event");
-        }
-
-        if (tokens[0].startsWith("P2P-GROUP")) {
-            mInterface = tokens[1];
-            mIsGroupOwner = tokens[2].equals("GO");
-
-            Matcher match = groupStartedPattern.matcher(supplicantEvent);
-            if (!match.find()) {
-                return;
-            }
-
-            mNetworkName = match.group(1);
-            // It throws NumberFormatException if the string cannot be parsed as an integer.
-            mFrequency = Integer.parseInt(match.group(2));
-            // psk is unused right now
-            //String psk = match.group(3);
-            mPassphrase = match.group(4);
-            mOwner = new WifiP2pDevice(match.group(5));
-            if (match.group(6) != null) {
-                mNetId = NETWORK_ID_PERSISTENT;
-            } else {
-                mNetId = NETWORK_ID_TEMPORARY;
-            }
-        } else if (tokens[0].equals("P2P-INVITATION-RECEIVED")) {
-            String sa = null;
-            mNetId = NETWORK_ID_PERSISTENT;
-            for (String token : tokens) {
-                String[] nameValue = token.split("=");
-                if (nameValue.length != 2) continue;
-
-                if (nameValue[0].equals("sa")) {
-                    sa = nameValue[1];
-
-                    // set source address into the client list.
-                    WifiP2pDevice dev = new WifiP2pDevice();
-                    dev.deviceAddress = nameValue[1];
-                    mClients.add(dev);
-                    continue;
-                }
-
-                if (nameValue[0].equals("go_dev_addr")) {
-                    mOwner = new WifiP2pDevice(nameValue[1]);
-                    continue;
-                }
-
-                if (nameValue[0].equals("persistent")) {
-                    mNetId = Integer.parseInt(nameValue[1]);
-                    continue;
-                }
-            }
-        } else {
-            throw new IllegalArgumentException("Malformed supplicant event");
-        }
-    }
-
-    /** @hide */
-    public void setNetworkName(String networkName) {
-        mNetworkName = networkName;
-    }
-
-    /**
-     * Get the network name (SSID) of the group. Legacy Wi-Fi clients will discover
-     * the p2p group using the network name.
-     */
-    public String getNetworkName() {
-        return mNetworkName;
-    }
-
-    /** @hide */
-    @UnsupportedAppUsage
-    public void setIsGroupOwner(boolean isGo) {
-        mIsGroupOwner = isGo;
-    }
-
-    /** Check whether this device is the group owner of the created p2p group */
-    public boolean isGroupOwner() {
-        return mIsGroupOwner;
-    }
-
-    /** @hide */
-    public void setOwner(WifiP2pDevice device) {
-        mOwner = device;
-    }
-
-    /** Get the details of the group owner as a {@link WifiP2pDevice} object */
-    public WifiP2pDevice getOwner() {
-        return mOwner;
-    }
-
-    /** @hide */
-    public void addClient(String address) {
-        addClient(new WifiP2pDevice(address));
-    }
-
-    /** @hide */
-    public void addClient(WifiP2pDevice device) {
-        for (WifiP2pDevice client : mClients) {
-            if (client.equals(device)) return;
-        }
-        mClients.add(device);
-    }
-
-    /** @hide */
-    public boolean removeClient(String address) {
-        return mClients.remove(new WifiP2pDevice(address));
-    }
-
-    /** @hide */
-    public boolean removeClient(WifiP2pDevice device) {
-        return mClients.remove(device);
-    }
-
-    /** @hide */
-    @UnsupportedAppUsage
-    public boolean isClientListEmpty() {
-        return mClients.size() == 0;
-    }
-
-    /**
-     * Returns {@code true} if the device is part of the group, {@code false} otherwise.
-     *
-     * @hide
-     */
-    public boolean contains(@Nullable WifiP2pDevice device) {
-        return mOwner.equals(device) || mClients.contains(device);
-    }
-
-    /** Get the list of clients currently part of the p2p group */
-    public Collection<WifiP2pDevice> getClientList() {
-        return Collections.unmodifiableCollection(mClients);
-    }
-
-    /** @hide */
-    public void setPassphrase(String passphrase) {
-        mPassphrase = passphrase;
-    }
-
-    /**
-     * Get the passphrase of the group. This function will return a valid passphrase only
-     * at the group owner. Legacy Wi-Fi clients will need this passphrase alongside
-     * network name obtained from {@link #getNetworkName()} to join the group
-     */
-    public String getPassphrase() {
-        return mPassphrase;
-    }
-
-    /** @hide */
-    @UnsupportedAppUsage
-    public void setInterface(String intf) {
-        mInterface = intf;
-    }
-
-    /** Get the interface name on which the group is created */
-    public String getInterface() {
-        return mInterface;
-    }
-
-    /** The network ID of the P2P group in wpa_supplicant. */
-    public int getNetworkId() {
-        return mNetId;
-    }
-
-    /** @hide */
-    @UnsupportedAppUsage
-    public void setNetworkId(int netId) {
-        this.mNetId = netId;
-    }
-
-    /** Get the operating frequency (in MHz) of the p2p group */
-    public int getFrequency() {
-        return mFrequency;
-    }
-
-    /** @hide */
-    public void setFrequency(int freq) {
-        this.mFrequency = freq;
-    }
-
-    public String toString() {
-        StringBuffer sbuf = new StringBuffer();
-        sbuf.append("network: ").append(mNetworkName);
-        sbuf.append("\n isGO: ").append(mIsGroupOwner);
-        sbuf.append("\n GO: ").append(mOwner);
-        for (WifiP2pDevice client : mClients) {
-            sbuf.append("\n Client: ").append(client);
-        }
-        sbuf.append("\n interface: ").append(mInterface);
-        sbuf.append("\n networkId: ").append(mNetId);
-        sbuf.append("\n frequency: ").append(mFrequency);
-        return sbuf.toString();
-    }
-
-    /** Implement the Parcelable interface */
-    public int describeContents() {
-        return 0;
-    }
-
-    /** copy constructor */
-    public WifiP2pGroup(WifiP2pGroup source) {
-        if (source != null) {
-            mNetworkName = source.getNetworkName();
-            mOwner = new WifiP2pDevice(source.getOwner());
-            mIsGroupOwner = source.mIsGroupOwner;
-            for (WifiP2pDevice d : source.getClientList()) mClients.add(d);
-            mPassphrase = source.getPassphrase();
-            mInterface = source.getInterface();
-            mNetId = source.getNetworkId();
-            mFrequency = source.getFrequency();
-        }
-    }
-
-    /** Implement the Parcelable interface */
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeString(mNetworkName);
-        dest.writeParcelable(mOwner, flags);
-        dest.writeByte(mIsGroupOwner ? (byte) 1: (byte) 0);
-        dest.writeInt(mClients.size());
-        for (WifiP2pDevice client : mClients) {
-            dest.writeParcelable(client, flags);
-        }
-        dest.writeString(mPassphrase);
-        dest.writeString(mInterface);
-        dest.writeInt(mNetId);
-        dest.writeInt(mFrequency);
-    }
-
-    /** Implement the Parcelable interface */
-    public static final @android.annotation.NonNull Creator<WifiP2pGroup> CREATOR =
-        new Creator<WifiP2pGroup>() {
-            public WifiP2pGroup createFromParcel(Parcel in) {
-                WifiP2pGroup group = new WifiP2pGroup();
-                group.setNetworkName(in.readString());
-                group.setOwner((WifiP2pDevice)in.readParcelable(null));
-                group.setIsGroupOwner(in.readByte() == (byte)1);
-                int clientCount = in.readInt();
-                for (int i=0; i<clientCount; i++) {
-                    group.addClient((WifiP2pDevice) in.readParcelable(null));
-                }
-                group.setPassphrase(in.readString());
-                group.setInterface(in.readString());
-                group.setNetworkId(in.readInt());
-                group.setFrequency(in.readInt());
-                return group;
-            }
-
-            public WifiP2pGroup[] newArray(int size) {
-                return new WifiP2pGroup[size];
-            }
-        };
-}
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.java b/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.java
deleted file mode 100644
index 8a86311..0000000
--- a/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.java
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.net.wifi.p2p;
-
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.LruCache;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-
-/**
- * A class representing a Wi-Fi P2p group list
- *
- * {@see WifiP2pManager}
- * @hide
- */
-@SystemApi
-public final class WifiP2pGroupList implements Parcelable {
-
-    private static final int CREDENTIAL_MAX_NUM             =   32;
-
-    @UnsupportedAppUsage
-    private final LruCache<Integer, WifiP2pGroup> mGroups;
-    private final GroupDeleteListener mListener;
-
-    private boolean isClearCalled = false;
-
-    /** @hide */
-    public interface GroupDeleteListener {
-        public void onDeleteGroup(int netId);
-    }
-
-    /** @hide */
-    public WifiP2pGroupList() {
-        this(null, null);
-    }
-
-    /** @hide */
-    @UnsupportedAppUsage
-    public WifiP2pGroupList(WifiP2pGroupList source, GroupDeleteListener listener) {
-        mListener = listener;
-        mGroups = new LruCache<Integer, WifiP2pGroup>(CREDENTIAL_MAX_NUM) {
-            @Override
-            protected void entryRemoved(boolean evicted, Integer netId,
-                    WifiP2pGroup oldValue, WifiP2pGroup newValue) {
-                if (mListener != null && !isClearCalled) {
-                    mListener.onDeleteGroup(oldValue.getNetworkId());
-                }
-            }
-        };
-
-        if (source != null) {
-            for (Map.Entry<Integer, WifiP2pGroup> item : source.mGroups.snapshot().entrySet()) {
-                mGroups.put(item.getKey(), item.getValue());
-            }
-        }
-    }
-
-    /**
-     * Get the list of P2P groups.
-     */
-    @NonNull
-    public List<WifiP2pGroup> getGroupList() {
-        return new ArrayList<>(mGroups.snapshot().values());
-    }
-
-    /**
-     * Add the specified group to this group list.
-     *
-     * @param group
-     * @hide
-     */
-    public void add(WifiP2pGroup group) {
-        mGroups.put(group.getNetworkId(), group);
-    }
-
-    /**
-     * Remove the group with the specified network id from this group list.
-     *
-     * @param netId
-     * @hide
-     */
-    public void remove(int netId) {
-        mGroups.remove(netId);
-    }
-
-    /**
-     * Remove the group with the specified device address from this group list.
-     *
-     * @param deviceAddress
-     */
-    void remove(String deviceAddress) {
-        remove(getNetworkId(deviceAddress));
-    }
-
-    /**
-     * Clear the group.
-     * @hide
-     */
-    public boolean clear() {
-        if (mGroups.size() == 0) return false;
-        isClearCalled = true;
-        mGroups.evictAll();
-        isClearCalled = false;
-        return true;
-    }
-
-    /**
-     * Return the network id of the group owner profile with the specified p2p device
-     * address.
-     * If more than one persistent group of the same address is present in the list,
-     * return the first one.
-     *
-     * @param deviceAddress p2p device address.
-     * @return the network id. if not found, return -1.
-     * @hide
-     */
-    public int getNetworkId(String deviceAddress) {
-        if (deviceAddress == null) return -1;
-
-        final Collection<WifiP2pGroup> groups = mGroups.snapshot().values();
-        for (WifiP2pGroup grp: groups) {
-            if (deviceAddress.equalsIgnoreCase(grp.getOwner().deviceAddress)) {
-                // update cache ordered.
-                mGroups.get(grp.getNetworkId());
-                return grp.getNetworkId();
-            }
-        }
-        return -1;
-    }
-
-    /**
-     * Return the network id of the group with the specified p2p device address
-     * and the ssid.
-     *
-     * @param deviceAddress p2p device address.
-     * @param ssid ssid.
-     * @return the network id. if not found, return -1.
-     * @hide
-     */
-    public int getNetworkId(String deviceAddress, String ssid) {
-        if (deviceAddress == null || ssid == null) {
-            return -1;
-        }
-
-        final Collection<WifiP2pGroup> groups = mGroups.snapshot().values();
-        for (WifiP2pGroup grp: groups) {
-            if (deviceAddress.equalsIgnoreCase(grp.getOwner().deviceAddress) &&
-                    ssid.equals(grp.getNetworkName())) {
-                // update cache ordered.
-                mGroups.get(grp.getNetworkId());
-                return grp.getNetworkId();
-            }
-        }
-
-        return -1;
-    }
-
-    /**
-     * Return the group owner address of the group with the specified network id
-     *
-     * @param netId network id.
-     * @return the address. if not found, return null.
-     * @hide
-     */
-    public String getOwnerAddr(int netId) {
-        WifiP2pGroup grp = mGroups.get(netId);
-        if (grp != null) {
-            return grp.getOwner().deviceAddress;
-        }
-        return null;
-    }
-
-    /**
-     * Return true if this group list contains the specified network id.
-     * This function does NOT update LRU information.
-     * It means the internal queue is NOT reordered.
-     *
-     * @param netId network id.
-     * @return true if the specified network id is present in this group list.
-     * @hide
-     */
-    public boolean contains(int netId) {
-        final Collection<WifiP2pGroup> groups = mGroups.snapshot().values();
-        for (WifiP2pGroup grp: groups) {
-            if (netId == grp.getNetworkId()) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public String toString() {
-        StringBuffer sbuf = new StringBuffer();
-
-        final Collection<WifiP2pGroup> groups = mGroups.snapshot().values();
-        for (WifiP2pGroup grp: groups) {
-            sbuf.append(grp).append("\n");
-        }
-        return sbuf.toString();
-    }
-
-    /** Implement the Parcelable interface */
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    /** Implement the Parcelable interface */
-    @Override
-    public void writeToParcel(@NonNull Parcel dest, int flags) {
-        final Collection<WifiP2pGroup> groups = mGroups.snapshot().values();
-        dest.writeInt(groups.size());
-        for(WifiP2pGroup group : groups) {
-            dest.writeParcelable(group, flags);
-        }
-    }
-
-    /** Implement the Parcelable interface */
-    public static final @NonNull Creator<WifiP2pGroupList> CREATOR =
-        new Creator<WifiP2pGroupList>() {
-            public WifiP2pGroupList createFromParcel(Parcel in) {
-                WifiP2pGroupList grpList = new WifiP2pGroupList();
-
-                int deviceCount = in.readInt();
-                for (int i = 0; i < deviceCount; i++) {
-                    grpList.add((WifiP2pGroup)in.readParcelable(null));
-                }
-                return grpList;
-            }
-
-            public WifiP2pGroupList[] newArray(int size) {
-                return new WifiP2pGroupList[size];
-            }
-        };
-}
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pInfo.java b/wifi/java/android/net/wifi/p2p/WifiP2pInfo.java
deleted file mode 100644
index 33bc37e..0000000
--- a/wifi/java/android/net/wifi/p2p/WifiP2pInfo.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p;
-
-import android.os.Parcelable;
-import android.os.Parcel;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-
-/**
- * A class representing connection information about a Wi-Fi p2p group
- *
- * {@see WifiP2pManager}
- */
-public class WifiP2pInfo implements Parcelable {
-
-    /** Indicates if a p2p group has been successfully formed */
-    public boolean groupFormed;
-
-    /** Indicates if the current device is the group owner */
-    public boolean isGroupOwner;
-
-    /** Group owner address */
-    public InetAddress groupOwnerAddress;
-
-    public WifiP2pInfo() {
-    }
-
-    public String toString() {
-        StringBuffer sbuf = new StringBuffer();
-        sbuf.append("groupFormed: ").append(groupFormed)
-            .append(" isGroupOwner: ").append(isGroupOwner)
-            .append(" groupOwnerAddress: ").append(groupOwnerAddress);
-        return sbuf.toString();
-    }
-
-    /** Implement the Parcelable interface */
-    public int describeContents() {
-        return 0;
-    }
-
-    /** copy constructor */
-    public WifiP2pInfo(WifiP2pInfo source) {
-        if (source != null) {
-            groupFormed = source.groupFormed;
-            isGroupOwner = source.isGroupOwner;
-            groupOwnerAddress = source.groupOwnerAddress;
-       }
-    }
-
-    /** Implement the Parcelable interface */
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeByte(groupFormed ? (byte)1 : (byte)0);
-        dest.writeByte(isGroupOwner ? (byte)1 : (byte)0);
-
-        if (groupOwnerAddress != null) {
-            dest.writeByte((byte)1);
-            dest.writeByteArray(groupOwnerAddress.getAddress());
-        } else {
-            dest.writeByte((byte)0);
-        }
-    }
-
-    /** Implement the Parcelable interface */
-    public static final @android.annotation.NonNull Creator<WifiP2pInfo> CREATOR =
-        new Creator<WifiP2pInfo>() {
-            public WifiP2pInfo createFromParcel(Parcel in) {
-                WifiP2pInfo info = new WifiP2pInfo();
-                info.groupFormed = (in.readByte() == 1);
-                info.isGroupOwner = (in.readByte() == 1);
-                if (in.readByte() == 1) {
-                    try {
-                        info.groupOwnerAddress = InetAddress.getByAddress(in.createByteArray());
-                    } catch (UnknownHostException e) {}
-                }
-                return info;
-            }
-
-            public WifiP2pInfo[] newArray(int size) {
-                return new WifiP2pInfo[size];
-            }
-        };
-}
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
deleted file mode 100644
index 724ccf0..0000000
--- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
+++ /dev/null
@@ -1,2034 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.annotation.SystemApi;
-import android.annotation.SystemService;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.content.Context;
-import android.net.NetworkInfo;
-import android.net.wifi.WpsInfo;
-import android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceInfo;
-import android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceResponse;
-import android.net.wifi.p2p.nsd.WifiP2pServiceInfo;
-import android.net.wifi.p2p.nsd.WifiP2pServiceRequest;
-import android.net.wifi.p2p.nsd.WifiP2pServiceResponse;
-import android.net.wifi.p2p.nsd.WifiP2pUpnpServiceInfo;
-import android.net.wifi.p2p.nsd.WifiP2pUpnpServiceResponse;
-import android.os.Binder;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.RemoteException;
-import android.text.TextUtils;
-import android.util.CloseGuard;
-import android.util.Log;
-
-import com.android.internal.util.AsyncChannel;
-import com.android.internal.util.Protocol;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.ref.Reference;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * This class provides the API for managing Wi-Fi peer-to-peer connectivity. This lets an
- * application discover available peers, setup connection to peers and query for the list of peers.
- * When a p2p connection is formed over wifi, the device continues to maintain the uplink
- * connection over mobile or any other available network for internet connectivity on the device.
- *
- * <p> The API is asynchronous and responses to requests from an application are on listener
- * callbacks provided by the application. The application needs to do an initialization with
- * {@link #initialize} before doing any p2p operation.
- *
- * <p> Most application calls need a {@link ActionListener} instance for receiving callbacks
- * {@link ActionListener#onSuccess} or {@link ActionListener#onFailure}. Action callbacks
- * indicate whether the initiation of the action was a success or a failure.
- * Upon failure, the reason of failure can be one of {@link #ERROR}, {@link #P2P_UNSUPPORTED}
- * or {@link #BUSY}.
- *
- * <p> An application can initiate discovery of peers with {@link #discoverPeers}. An initiated
- * discovery request from an application stays active until the device starts connecting to a peer
- * ,forms a p2p group or there is an explicit {@link #stopPeerDiscovery}.
- * Applications can listen to {@link #WIFI_P2P_DISCOVERY_CHANGED_ACTION} to know if a peer-to-peer
- * discovery is running or stopped. Additionally, {@link #WIFI_P2P_PEERS_CHANGED_ACTION} indicates
- * if the peer list has changed.
- *
- * <p> When an application needs to fetch the current list of peers, it can request the list
- * of peers with {@link #requestPeers}. When the peer list is available
- * {@link PeerListListener#onPeersAvailable} is called with the device list.
- *
- * <p> An application can initiate a connection request to a peer through {@link #connect}. See
- * {@link WifiP2pConfig} for details on setting up the configuration. For communication with legacy
- * Wi-Fi devices that do not support p2p, an app can create a group using {@link #createGroup}
- * which creates an access point whose details can be fetched with {@link #requestGroupInfo}.
- *
- * <p> After a successful group formation through {@link #createGroup} or through {@link #connect},
- * use {@link #requestConnectionInfo} to fetch the connection details. The connection info
- * {@link WifiP2pInfo} contains the address of the group owner
- * {@link WifiP2pInfo#groupOwnerAddress} and a flag {@link WifiP2pInfo#isGroupOwner} to indicate
- * if the current device is a p2p group owner. A p2p client can thus communicate with
- * the p2p group owner through a socket connection. If the current device is the p2p group owner,
- * {@link WifiP2pInfo#groupOwnerAddress} is anonymized unless the caller holds the
- * {@code android.Manifest.permission#LOCAL_MAC_ADDRESS} permission.
- *
- * <p> With peer discovery using {@link  #discoverPeers}, an application discovers the neighboring
- * peers, but has no good way to figure out which peer to establish a connection with. For example,
- * if a game application is interested in finding all the neighboring peers that are also running
- * the same game, it has no way to find out until after the connection is setup. Pre-association
- * service discovery is meant to address this issue of filtering the peers based on the running
- * services.
- *
- * <p>With pre-association service discovery, an application can advertise a service for a
- * application on a peer device prior to a connection setup between the devices.
- * Currently, DNS based service discovery (Bonjour) and Upnp are the higher layer protocols
- * supported. Get Bonjour resources at dns-sd.org and Upnp resources at upnp.org
- * As an example, a video application can discover a Upnp capable media renderer
- * prior to setting up a Wi-fi p2p connection with the device.
- *
- * <p> An application can advertise a Upnp or a Bonjour service with a call to
- * {@link #addLocalService}. After a local service is added,
- * the framework automatically responds to a peer application discovering the service prior
- * to establishing a p2p connection. A call to {@link #removeLocalService} removes a local
- * service and {@link #clearLocalServices} can be used to clear all local services.
- *
- * <p> An application that is looking for peer devices that support certain services
- * can do so with a call to  {@link #discoverServices}. Prior to initiating the discovery,
- * application can add service discovery request with a call to {@link #addServiceRequest},
- * remove a service discovery request with a call to {@link #removeServiceRequest} or clear
- * all requests with a call to {@link #clearServiceRequests}. When no service requests remain,
- * a previously running service discovery will stop.
- *
- * The application is notified of a result of service discovery request through listener callbacks
- * set through {@link #setDnsSdResponseListeners} for Bonjour or
- * {@link #setUpnpServiceResponseListener} for Upnp.
- *
- * <p class="note"><strong>Note:</strong>
- * Registering an application handler with {@link #initialize} requires the permissions
- * {@link android.Manifest.permission#ACCESS_WIFI_STATE} and
- * {@link android.Manifest.permission#CHANGE_WIFI_STATE} to perform any further peer-to-peer
- * operations.
- *
- * {@see WifiP2pConfig}
- * {@see WifiP2pInfo}
- * {@see WifiP2pGroup}
- * {@see WifiP2pDevice}
- * {@see WifiP2pDeviceList}
- * {@see android.net.wifi.WpsInfo}
- */
-@SystemService(Context.WIFI_P2P_SERVICE)
-public class WifiP2pManager {
-    private static final String TAG = "WifiP2pManager";
-    /**
-     * Broadcast intent action to indicate whether Wi-Fi p2p is enabled or disabled. An
-     * extra {@link #EXTRA_WIFI_STATE} provides the state information as int.
-     *
-     * @see #EXTRA_WIFI_STATE
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String WIFI_P2P_STATE_CHANGED_ACTION =
-        "android.net.wifi.p2p.STATE_CHANGED";
-
-    /**
-     * The lookup key for an int that indicates whether Wi-Fi p2p is enabled or disabled.
-     * Retrieve it with {@link android.content.Intent#getIntExtra(String,int)}.
-     *
-     * @see #WIFI_P2P_STATE_DISABLED
-     * @see #WIFI_P2P_STATE_ENABLED
-     */
-    public static final String EXTRA_WIFI_STATE = "wifi_p2p_state";
-
-    /** @hide */
-    @IntDef({
-            WIFI_P2P_STATE_DISABLED,
-            WIFI_P2P_STATE_ENABLED})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface WifiP2pState {
-    }
-
-    /**
-     * Wi-Fi p2p is disabled.
-     *
-     * @see #WIFI_P2P_STATE_CHANGED_ACTION
-     */
-    public static final int WIFI_P2P_STATE_DISABLED = 1;
-
-    /**
-     * Wi-Fi p2p is enabled.
-     *
-     * @see #WIFI_P2P_STATE_CHANGED_ACTION
-     */
-    public static final int WIFI_P2P_STATE_ENABLED = 2;
-
-    /**
-     * Broadcast intent action indicating that the state of Wi-Fi p2p connectivity
-     * has changed. One extra {@link #EXTRA_WIFI_P2P_INFO} provides the p2p connection info in
-     * the form of a {@link WifiP2pInfo} object. Another extra {@link #EXTRA_NETWORK_INFO} provides
-     * the network info in the form of a {@link android.net.NetworkInfo}. A third extra provides
-     * the details of the group and may contain a {@code null}.
-     *
-     * All of these permissions are required to receive this broadcast:
-     * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} and
-     * {@link android.Manifest.permission#ACCESS_WIFI_STATE}
-     *
-     * @see #EXTRA_WIFI_P2P_INFO
-     * @see #EXTRA_NETWORK_INFO
-     * @see #EXTRA_WIFI_P2P_GROUP
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String WIFI_P2P_CONNECTION_CHANGED_ACTION =
-        "android.net.wifi.p2p.CONNECTION_STATE_CHANGE";
-
-    /**
-     * The lookup key for a {@link android.net.wifi.p2p.WifiP2pInfo} object
-     * Retrieve with {@link android.content.Intent#getParcelableExtra(String)}.
-     */
-    public static final String EXTRA_WIFI_P2P_INFO = "wifiP2pInfo";
-
-    /**
-     * The lookup key for a {@link android.net.NetworkInfo} object associated with the
-     * p2p network. Retrieve with
-     * {@link android.content.Intent#getParcelableExtra(String)}.
-     */
-    public static final String EXTRA_NETWORK_INFO = "networkInfo";
-
-    /**
-     * The lookup key for a {@link android.net.wifi.p2p.WifiP2pGroup} object
-     * associated with the p2p network. Retrieve with
-     * {@link android.content.Intent#getParcelableExtra(String)}.
-     */
-    public static final String EXTRA_WIFI_P2P_GROUP = "p2pGroupInfo";
-
-    /**
-     * Broadcast intent action indicating that the available peer list has changed. This
-     * can be sent as a result of peers being found, lost or updated.
-     *
-     * All of these permissions are required to receive this broadcast:
-     * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} and
-     * {@link android.Manifest.permission#ACCESS_WIFI_STATE}
-     *
-     * <p> An extra {@link #EXTRA_P2P_DEVICE_LIST} provides the full list of
-     * current peers. The full list of peers can also be obtained any time with
-     * {@link #requestPeers}.
-     *
-     * @see #EXTRA_P2P_DEVICE_LIST
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String WIFI_P2P_PEERS_CHANGED_ACTION =
-        "android.net.wifi.p2p.PEERS_CHANGED";
-
-     /**
-      * The lookup key for a {@link android.net.wifi.p2p.WifiP2pDeviceList} object representing
-      * the new peer list when {@link #WIFI_P2P_PEERS_CHANGED_ACTION} broadcast is sent.
-      *
-      * <p>Retrieve with {@link android.content.Intent#getParcelableExtra(String)}.
-      */
-    public static final String EXTRA_P2P_DEVICE_LIST = "wifiP2pDeviceList";
-
-    /**
-     * Broadcast intent action indicating that peer discovery has either started or stopped.
-     * One extra {@link #EXTRA_DISCOVERY_STATE} indicates whether discovery has started
-     * or stopped.
-     *
-     * <p>Note that discovery will be stopped during a connection setup. If the application tries
-     * to re-initiate discovery during this time, it can fail.
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String WIFI_P2P_DISCOVERY_CHANGED_ACTION =
-        "android.net.wifi.p2p.DISCOVERY_STATE_CHANGE";
-
-    /**
-     * The lookup key for an int that indicates whether p2p discovery has started or stopped.
-     * Retrieve it with {@link android.content.Intent#getIntExtra(String,int)}.
-     *
-     * @see #WIFI_P2P_DISCOVERY_STARTED
-     * @see #WIFI_P2P_DISCOVERY_STOPPED
-     */
-    public static final String EXTRA_DISCOVERY_STATE = "discoveryState";
-
-    /** @hide */
-    @IntDef({
-            WIFI_P2P_DISCOVERY_STOPPED,
-            WIFI_P2P_DISCOVERY_STARTED})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface WifiP2pDiscoveryState {
-    }
-
-    /**
-     * p2p discovery has stopped
-     *
-     * @see #WIFI_P2P_DISCOVERY_CHANGED_ACTION
-     */
-    public static final int WIFI_P2P_DISCOVERY_STOPPED = 1;
-
-    /**
-     * p2p discovery has started
-     *
-     * @see #WIFI_P2P_DISCOVERY_CHANGED_ACTION
-     */
-    public static final int WIFI_P2P_DISCOVERY_STARTED = 2;
-
-    /**
-     * Broadcast intent action indicating that this device details have changed.
-     *
-     * <p> An extra {@link #EXTRA_WIFI_P2P_DEVICE} provides this device details.
-     * The valid device details can also be obtained with
-     * {@link #requestDeviceInfo(Channel, DeviceInfoListener)} when p2p is enabled.
-     * To get information notifications on P2P getting enabled refers
-     * {@link #WIFI_P2P_STATE_ENABLED}.
-     *
-     * <p> The {@link #EXTRA_WIFI_P2P_DEVICE} extra contains an anonymized version of the device's
-     * MAC address. Callers holding the {@code android.Manifest.permission#LOCAL_MAC_ADDRESS}
-     * permission can use {@link #requestDeviceInfo} to obtain the actual MAC address of this
-     * device.
-     *
-     * All of these permissions are required to receive this broadcast:
-     * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} and
-     * {@link android.Manifest.permission#ACCESS_WIFI_STATE}
-     *
-     * @see #EXTRA_WIFI_P2P_DEVICE
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String WIFI_P2P_THIS_DEVICE_CHANGED_ACTION =
-        "android.net.wifi.p2p.THIS_DEVICE_CHANGED";
-
-    /**
-     * The lookup key for a {@link android.net.wifi.p2p.WifiP2pDevice} object
-     * Retrieve with {@link android.content.Intent#getParcelableExtra(String)}.
-     */
-    public static final String EXTRA_WIFI_P2P_DEVICE = "wifiP2pDevice";
-
-    /**
-     * Broadcast intent action indicating that remembered persistent groups have changed.
-     *
-     * You can <em>not</em> receive this through components declared
-     * in manifests, only by explicitly registering for it with
-     * {@link android.content.Context#registerReceiver(android.content.BroadcastReceiver,
-     * android.content.IntentFilter) Context.registerReceiver()}.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final String ACTION_WIFI_P2P_PERSISTENT_GROUPS_CHANGED =
-            "android.net.wifi.p2p.action.WIFI_P2P_PERSISTENT_GROUPS_CHANGED";
-
-    /**
-     * The lookup key for a handover message returned by the WifiP2pService.
-     * @hide
-     */
-    public static final String EXTRA_HANDOVER_MESSAGE =
-            "android.net.wifi.p2p.EXTRA_HANDOVER_MESSAGE";
-
-    /**
-     * The lookup key for a calling package name from WifiP2pManager
-     * @hide
-     */
-    public static final String CALLING_PACKAGE =
-            "android.net.wifi.p2p.CALLING_PACKAGE";
-
-    /**
-     * The lookup key for a calling feature id from WifiP2pManager
-     * @hide
-     */
-    public static final String CALLING_FEATURE_ID =
-            "android.net.wifi.p2p.CALLING_FEATURE_ID";
-
-    /**
-     * The lookup key for a calling package binder from WifiP2pManager
-     * @hide
-     */
-    public static final String CALLING_BINDER =
-            "android.net.wifi.p2p.CALLING_BINDER";
-
-    IWifiP2pManager mService;
-
-    private static final int BASE = Protocol.BASE_WIFI_P2P_MANAGER;
-
-    /** @hide */
-    public static final int DISCOVER_PEERS                          = BASE + 1;
-    /** @hide */
-    public static final int DISCOVER_PEERS_FAILED                   = BASE + 2;
-    /** @hide */
-    public static final int DISCOVER_PEERS_SUCCEEDED                = BASE + 3;
-
-    /** @hide */
-    public static final int STOP_DISCOVERY                          = BASE + 4;
-    /** @hide */
-    public static final int STOP_DISCOVERY_FAILED                   = BASE + 5;
-    /** @hide */
-    public static final int STOP_DISCOVERY_SUCCEEDED                = BASE + 6;
-
-    /** @hide */
-    public static final int CONNECT                                 = BASE + 7;
-    /** @hide */
-    public static final int CONNECT_FAILED                          = BASE + 8;
-    /** @hide */
-    public static final int CONNECT_SUCCEEDED                       = BASE + 9;
-
-    /** @hide */
-    public static final int CANCEL_CONNECT                          = BASE + 10;
-    /** @hide */
-    public static final int CANCEL_CONNECT_FAILED                   = BASE + 11;
-    /** @hide */
-    public static final int CANCEL_CONNECT_SUCCEEDED                = BASE + 12;
-
-    /** @hide */
-    @UnsupportedAppUsage
-    public static final int CREATE_GROUP                            = BASE + 13;
-    /** @hide */
-    public static final int CREATE_GROUP_FAILED                     = BASE + 14;
-    /** @hide */
-    public static final int CREATE_GROUP_SUCCEEDED                  = BASE + 15;
-
-    /** @hide */
-    public static final int REMOVE_GROUP                            = BASE + 16;
-    /** @hide */
-    public static final int REMOVE_GROUP_FAILED                     = BASE + 17;
-    /** @hide */
-    public static final int REMOVE_GROUP_SUCCEEDED                  = BASE + 18;
-
-    /** @hide */
-    public static final int REQUEST_PEERS                           = BASE + 19;
-    /** @hide */
-    public static final int RESPONSE_PEERS                          = BASE + 20;
-
-    /** @hide */
-    public static final int REQUEST_CONNECTION_INFO                 = BASE + 21;
-    /** @hide */
-    public static final int RESPONSE_CONNECTION_INFO                = BASE + 22;
-
-    /** @hide */
-    public static final int REQUEST_GROUP_INFO                      = BASE + 23;
-    /** @hide */
-    public static final int RESPONSE_GROUP_INFO                     = BASE + 24;
-
-    /** @hide */
-    public static final int ADD_LOCAL_SERVICE                       = BASE + 28;
-    /** @hide */
-    public static final int ADD_LOCAL_SERVICE_FAILED                = BASE + 29;
-    /** @hide */
-    public static final int ADD_LOCAL_SERVICE_SUCCEEDED             = BASE + 30;
-
-    /** @hide */
-    public static final int REMOVE_LOCAL_SERVICE                    = BASE + 31;
-    /** @hide */
-    public static final int REMOVE_LOCAL_SERVICE_FAILED             = BASE + 32;
-    /** @hide */
-    public static final int REMOVE_LOCAL_SERVICE_SUCCEEDED          = BASE + 33;
-
-    /** @hide */
-    public static final int CLEAR_LOCAL_SERVICES                    = BASE + 34;
-    /** @hide */
-    public static final int CLEAR_LOCAL_SERVICES_FAILED             = BASE + 35;
-    /** @hide */
-    public static final int CLEAR_LOCAL_SERVICES_SUCCEEDED          = BASE + 36;
-
-    /** @hide */
-    public static final int ADD_SERVICE_REQUEST                     = BASE + 37;
-    /** @hide */
-    public static final int ADD_SERVICE_REQUEST_FAILED              = BASE + 38;
-    /** @hide */
-    public static final int ADD_SERVICE_REQUEST_SUCCEEDED           = BASE + 39;
-
-    /** @hide */
-    public static final int REMOVE_SERVICE_REQUEST                  = BASE + 40;
-    /** @hide */
-    public static final int REMOVE_SERVICE_REQUEST_FAILED           = BASE + 41;
-    /** @hide */
-    public static final int REMOVE_SERVICE_REQUEST_SUCCEEDED        = BASE + 42;
-
-    /** @hide */
-    public static final int CLEAR_SERVICE_REQUESTS                  = BASE + 43;
-    /** @hide */
-    public static final int CLEAR_SERVICE_REQUESTS_FAILED           = BASE + 44;
-    /** @hide */
-    public static final int CLEAR_SERVICE_REQUESTS_SUCCEEDED        = BASE + 45;
-
-    /** @hide */
-    public static final int DISCOVER_SERVICES                       = BASE + 46;
-    /** @hide */
-    public static final int DISCOVER_SERVICES_FAILED                = BASE + 47;
-    /** @hide */
-    public static final int DISCOVER_SERVICES_SUCCEEDED             = BASE + 48;
-
-    /** @hide */
-    public static final int PING                                    = BASE + 49;
-
-    /** @hide */
-    public static final int RESPONSE_SERVICE                        = BASE + 50;
-
-    /** @hide */
-    public static final int SET_DEVICE_NAME                         = BASE + 51;
-    /** @hide */
-    public static final int SET_DEVICE_NAME_FAILED                  = BASE + 52;
-    /** @hide */
-    public static final int SET_DEVICE_NAME_SUCCEEDED               = BASE + 53;
-
-    /** @hide */
-    public static final int DELETE_PERSISTENT_GROUP                 = BASE + 54;
-    /** @hide */
-    public static final int DELETE_PERSISTENT_GROUP_FAILED          = BASE + 55;
-    /** @hide */
-    public static final int DELETE_PERSISTENT_GROUP_SUCCEEDED       = BASE + 56;
-
-    /** @hide */
-    public static final int REQUEST_PERSISTENT_GROUP_INFO           = BASE + 57;
-    /** @hide */
-    public static final int RESPONSE_PERSISTENT_GROUP_INFO          = BASE + 58;
-
-    /** @hide */
-    public static final int SET_WFD_INFO                            = BASE + 59;
-    /** @hide */
-    public static final int SET_WFD_INFO_FAILED                     = BASE + 60;
-    /** @hide */
-    public static final int SET_WFD_INFO_SUCCEEDED                  = BASE + 61;
-
-    /** @hide */
-    public static final int START_WPS                               = BASE + 62;
-    /** @hide */
-    public static final int START_WPS_FAILED                        = BASE + 63;
-    /** @hide */
-    public static final int START_WPS_SUCCEEDED                     = BASE + 64;
-
-    /** @hide */
-    public static final int START_LISTEN                            = BASE + 65;
-    /** @hide */
-    public static final int START_LISTEN_FAILED                     = BASE + 66;
-    /** @hide */
-    public static final int START_LISTEN_SUCCEEDED                  = BASE + 67;
-
-    /** @hide */
-    public static final int STOP_LISTEN                             = BASE + 68;
-    /** @hide */
-    public static final int STOP_LISTEN_FAILED                      = BASE + 69;
-    /** @hide */
-    public static final int STOP_LISTEN_SUCCEEDED                   = BASE + 70;
-
-    /** @hide */
-    public static final int SET_CHANNEL                             = BASE + 71;
-    /** @hide */
-    public static final int SET_CHANNEL_FAILED                      = BASE + 72;
-    /** @hide */
-    public static final int SET_CHANNEL_SUCCEEDED                   = BASE + 73;
-
-    /** @hide */
-    public static final int GET_HANDOVER_REQUEST                    = BASE + 75;
-    /** @hide */
-    public static final int GET_HANDOVER_SELECT                     = BASE + 76;
-    /** @hide */
-    public static final int RESPONSE_GET_HANDOVER_MESSAGE           = BASE + 77;
-    /** @hide */
-    public static final int INITIATOR_REPORT_NFC_HANDOVER           = BASE + 78;
-    /** @hide */
-    public static final int RESPONDER_REPORT_NFC_HANDOVER           = BASE + 79;
-    /** @hide */
-    public static final int REPORT_NFC_HANDOVER_SUCCEEDED           = BASE + 80;
-    /** @hide */
-    public static final int REPORT_NFC_HANDOVER_FAILED              = BASE + 81;
-
-    /** @hide */
-    public static final int FACTORY_RESET                           = BASE + 82;
-    /** @hide */
-    public static final int FACTORY_RESET_FAILED                    = BASE + 83;
-    /** @hide */
-    public static final int FACTORY_RESET_SUCCEEDED                 = BASE + 84;
-
-    /** @hide */
-    public static final int REQUEST_ONGOING_PEER_CONFIG             = BASE + 85;
-    /** @hide */
-    public static final int RESPONSE_ONGOING_PEER_CONFIG            = BASE + 86;
-    /** @hide */
-    public static final int SET_ONGOING_PEER_CONFIG                 = BASE + 87;
-    /** @hide */
-    public static final int SET_ONGOING_PEER_CONFIG_FAILED          = BASE + 88;
-    /** @hide */
-    public static final int SET_ONGOING_PEER_CONFIG_SUCCEEDED       = BASE + 89;
-
-    /** @hide */
-    public static final int REQUEST_P2P_STATE                       = BASE + 90;
-    /** @hide */
-    public static final int RESPONSE_P2P_STATE                      = BASE + 91;
-
-    /** @hide */
-    public static final int REQUEST_DISCOVERY_STATE                 = BASE + 92;
-    /** @hide */
-    public static final int RESPONSE_DISCOVERY_STATE                = BASE + 93;
-
-    /** @hide */
-    public static final int REQUEST_NETWORK_INFO                    = BASE + 94;
-    /** @hide */
-    public static final int RESPONSE_NETWORK_INFO                   = BASE + 95;
-
-    /** @hide */
-    public static final int UPDATE_CHANNEL_INFO                     = BASE + 96;
-
-    /** @hide */
-    public static final int REQUEST_DEVICE_INFO                     = BASE + 97;
-    /** @hide */
-    public static final int RESPONSE_DEVICE_INFO                    = BASE + 98;
-
-    /**
-     * Create a new WifiP2pManager instance. Applications use
-     * {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve
-     * the standard {@link android.content.Context#WIFI_P2P_SERVICE Context.WIFI_P2P_SERVICE}.
-     * @param service the Binder interface
-     * @hide - hide this because it takes in a parameter of type IWifiP2pManager, which
-     * is a system private class.
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
-    public WifiP2pManager(IWifiP2pManager service) {
-        mService = service;
-    }
-
-    /**
-     * Passed with {@link ActionListener#onFailure}.
-     * Indicates that the operation failed due to an internal error.
-     */
-    public static final int ERROR               = 0;
-
-    /**
-     * Passed with {@link ActionListener#onFailure}.
-     * Indicates that the operation failed because p2p is unsupported on the device.
-     */
-    public static final int P2P_UNSUPPORTED     = 1;
-
-    /**
-     * Passed with {@link ActionListener#onFailure}.
-     * Indicates that the operation failed because the framework is busy and
-     * unable to service the request
-     */
-    public static final int BUSY                = 2;
-
-    /**
-     * Passed with {@link ActionListener#onFailure}.
-     * Indicates that the {@link #discoverServices} failed because no service
-     * requests are added. Use {@link #addServiceRequest} to add a service
-     * request.
-     */
-    public static final int NO_SERVICE_REQUESTS = 3;
-
-    /** Interface for callback invocation when framework channel is lost */
-    public interface ChannelListener {
-        /**
-         * The channel to the framework has been disconnected.
-         * Application could try re-initializing using {@link #initialize}
-         */
-        public void onChannelDisconnected();
-    }
-
-    /** Interface for callback invocation on an application action */
-    public interface ActionListener {
-        /** The operation succeeded */
-        public void onSuccess();
-        /**
-         * The operation failed
-         * @param reason The reason for failure could be one of {@link #P2P_UNSUPPORTED},
-         * {@link #ERROR} or {@link #BUSY}
-         */
-        public void onFailure(int reason);
-    }
-
-    /** Interface for callback invocation when peer list is available */
-    public interface PeerListListener {
-        /**
-         * The requested peer list is available
-         * @param peers List of available peers
-         */
-        public void onPeersAvailable(WifiP2pDeviceList peers);
-    }
-
-    /** Interface for callback invocation when connection info is available */
-    public interface ConnectionInfoListener {
-        /**
-         * The requested connection info is available
-         * @param info Wi-Fi p2p connection info
-         */
-        public void onConnectionInfoAvailable(WifiP2pInfo info);
-    }
-
-    /** Interface for callback invocation when group info is available */
-    public interface GroupInfoListener {
-        /**
-         * The requested p2p group info is available
-         * @param group Wi-Fi p2p group info
-         */
-        public void onGroupInfoAvailable(WifiP2pGroup group);
-    }
-
-   /**
-    * Interface for callback invocation when service discovery response other than
-    * Upnp or Bonjour is received
-    */
-    public interface ServiceResponseListener {
-
-        /**
-         * The requested service response is available.
-         *
-         * @param protocolType protocol type. currently only
-         * {@link WifiP2pServiceInfo#SERVICE_TYPE_VENDOR_SPECIFIC}.
-         * @param responseData service discovery response data based on the requested
-         *  service protocol type. The format depends on the service type.
-         * @param srcDevice source device.
-         */
-        public void onServiceAvailable(int protocolType,
-                byte[] responseData, WifiP2pDevice srcDevice);
-    }
-
-    /**
-     * Interface for callback invocation when Bonjour service discovery response
-     * is received
-     */
-    public interface DnsSdServiceResponseListener {
-
-        /**
-         * The requested Bonjour service response is available.
-         *
-         * <p>This function is invoked when the device with the specified Bonjour
-         * registration type returned the instance name.
-         * @param instanceName instance name.<br>
-         *  e.g) "MyPrinter".
-         * @param registrationType <br>
-         * e.g) "_ipp._tcp.local."
-         * @param srcDevice source device.
-         */
-        public void onDnsSdServiceAvailable(String instanceName,
-                String registrationType, WifiP2pDevice srcDevice);
-
-   }
-
-    /**
-     * Interface for callback invocation when Bonjour TXT record is available
-     * for a service
-     */
-   public interface DnsSdTxtRecordListener {
-        /**
-         * The requested Bonjour service response is available.
-         *
-         * <p>This function is invoked when the device with the specified full
-         * service domain service returned TXT record.
-         *
-         * @param fullDomainName full domain name. <br>
-         * e.g) "MyPrinter._ipp._tcp.local.".
-         * @param txtRecordMap TXT record data as a map of key/value pairs
-         * @param srcDevice source device.
-         */
-        public void onDnsSdTxtRecordAvailable(String fullDomainName,
-                Map<String, String> txtRecordMap,
-                WifiP2pDevice srcDevice);
-   }
-
-    /**
-     * Interface for callback invocation when upnp service discovery response
-     * is received
-     * */
-    public interface UpnpServiceResponseListener {
-
-        /**
-         * The requested upnp service response is available.
-         *
-         * <p>This function is invoked when the specified device or service is found.
-         *
-         * @param uniqueServiceNames The list of unique service names.<br>
-         * e.g) uuid:6859dede-8574-59ab-9332-123456789012::urn:schemas-upnp-org:device:
-         * MediaServer:1
-         * @param srcDevice source device.
-         */
-        public void onUpnpServiceAvailable(List<String> uniqueServiceNames,
-                WifiP2pDevice srcDevice);
-    }
-
-
-    /**
-     * Interface for callback invocation when stored group info list is available
-     *
-     * @hide
-     */
-    @SystemApi
-    public interface PersistentGroupInfoListener {
-        /**
-         * The requested stored p2p group info list is available
-         * @param groups Wi-Fi p2p group info list
-         */
-        void onPersistentGroupInfoAvailable(@NonNull WifiP2pGroupList groups);
-    }
-
-    /**
-     * Interface for callback invocation when Handover Request or Select Message is available
-     * @hide
-     */
-    public interface HandoverMessageListener {
-        public void onHandoverMessageAvailable(String handoverMessage);
-    }
-
-    /** Interface for callback invocation when p2p state is available
-     *  in response to {@link #requestP2pState}.
-     */
-    public interface P2pStateListener {
-        /**
-         * The requested p2p state is available.
-         * @param state Wi-Fi p2p state
-         *        @see #WIFI_P2P_STATE_DISABLED
-         *        @see #WIFI_P2P_STATE_ENABLED
-         */
-        void onP2pStateAvailable(@WifiP2pState int state);
-    }
-
-    /** Interface for callback invocation when p2p state is available
-     *  in response to {@link #requestDiscoveryState}.
-     */
-    public interface DiscoveryStateListener {
-        /**
-         * The requested p2p discovery state is available.
-         * @param state Wi-Fi p2p discovery state
-         *        @see #WIFI_P2P_DISCOVERY_STARTED
-         *        @see #WIFI_P2P_DISCOVERY_STOPPED
-         */
-        void onDiscoveryStateAvailable(@WifiP2pDiscoveryState int state);
-    }
-
-    /** Interface for callback invocation when {@link android.net.NetworkInfo} is available
-     *  in response to {@link #requestNetworkInfo}.
-     */
-    public interface NetworkInfoListener {
-        /**
-         * The requested {@link android.net.NetworkInfo} is available
-         * @param networkInfo Wi-Fi p2p {@link android.net.NetworkInfo}
-         */
-        void onNetworkInfoAvailable(@NonNull NetworkInfo networkInfo);
-    }
-
-    /**
-     * Interface for callback invocation when ongoing peer info is available
-     * @hide
-     */
-    public interface OngoingPeerInfoListener {
-        /**
-         * The requested ongoing WifiP2pConfig is available
-         * @param peerConfig WifiP2pConfig for current connecting session
-         */
-        void onOngoingPeerAvailable(WifiP2pConfig peerConfig);
-    }
-
-    /** Interface for callback invocation when {@link android.net.wifi.p2p.WifiP2pDevice}
-     *  is available in response to {@link #requestDeviceInfo(Channel, DeviceInfoListener)}.
-     */
-    public interface DeviceInfoListener {
-        /**
-         * The requested {@link android.net.wifi.p2p.WifiP2pDevice} is available.
-         * @param wifiP2pDevice Wi-Fi p2p {@link android.net.wifi.p2p.WifiP2pDevice}
-         */
-        void onDeviceInfoAvailable(@Nullable WifiP2pDevice wifiP2pDevice);
-    }
-
-    /**
-     * A channel that connects the application to the Wifi p2p framework.
-     * Most p2p operations require a Channel as an argument. An instance of Channel is obtained
-     * by doing a call on {@link #initialize}
-     */
-    public static class Channel implements AutoCloseable {
-        /** @hide */
-        public Channel(Context context, Looper looper, ChannelListener l, Binder binder,
-                WifiP2pManager p2pManager) {
-            mAsyncChannel = new AsyncChannel();
-            mHandler = new P2pHandler(looper);
-            mChannelListener = l;
-            mContext = context;
-            mBinder = binder;
-            mP2pManager = p2pManager;
-
-            mCloseGuard.open("close");
-        }
-        private final static int INVALID_LISTENER_KEY = 0;
-        private final WifiP2pManager mP2pManager;
-        private ChannelListener mChannelListener;
-        private ServiceResponseListener mServRspListener;
-        private DnsSdServiceResponseListener mDnsSdServRspListener;
-        private DnsSdTxtRecordListener mDnsSdTxtListener;
-        private UpnpServiceResponseListener mUpnpServRspListener;
-        private HashMap<Integer, Object> mListenerMap = new HashMap<Integer, Object>();
-        private final Object mListenerMapLock = new Object();
-        private int mListenerKey = 0;
-
-        private final CloseGuard mCloseGuard = new CloseGuard();
-
-        /**
-         * Close the current P2P connection and indicate to the P2P service that connections
-         * created by the app can be removed.
-         */
-        public void close() {
-            if (mP2pManager == null) {
-                Log.w(TAG, "Channel.close(): Null mP2pManager!?");
-            } else {
-                try {
-                    mP2pManager.mService.close(mBinder);
-                } catch (RemoteException e) {
-                    throw e.rethrowFromSystemServer();
-                }
-            }
-
-            mAsyncChannel.disconnect();
-            mCloseGuard.close();
-            Reference.reachabilityFence(this);
-        }
-
-        /** @hide */
-        @Override
-        protected void finalize() throws Throwable {
-            try {
-                if (mCloseGuard != null) {
-                    mCloseGuard.warnIfOpen();
-                }
-
-                close();
-            } finally {
-                super.finalize();
-            }
-        }
-
-        /* package */ final Binder mBinder;
-
-        @UnsupportedAppUsage
-        private AsyncChannel mAsyncChannel;
-        private P2pHandler mHandler;
-        Context mContext;
-        class P2pHandler extends Handler {
-            P2pHandler(Looper looper) {
-                super(looper);
-            }
-
-            @Override
-            public void handleMessage(Message message) {
-                Object listener = getListener(message.arg2);
-                switch (message.what) {
-                    case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
-                        if (mChannelListener != null) {
-                            mChannelListener.onChannelDisconnected();
-                            mChannelListener = null;
-                        }
-                        break;
-                    /* ActionListeners grouped together */
-                    case DISCOVER_PEERS_FAILED:
-                    case STOP_DISCOVERY_FAILED:
-                    case DISCOVER_SERVICES_FAILED:
-                    case CONNECT_FAILED:
-                    case CANCEL_CONNECT_FAILED:
-                    case CREATE_GROUP_FAILED:
-                    case REMOVE_GROUP_FAILED:
-                    case ADD_LOCAL_SERVICE_FAILED:
-                    case REMOVE_LOCAL_SERVICE_FAILED:
-                    case CLEAR_LOCAL_SERVICES_FAILED:
-                    case ADD_SERVICE_REQUEST_FAILED:
-                    case REMOVE_SERVICE_REQUEST_FAILED:
-                    case CLEAR_SERVICE_REQUESTS_FAILED:
-                    case SET_DEVICE_NAME_FAILED:
-                    case DELETE_PERSISTENT_GROUP_FAILED:
-                    case SET_WFD_INFO_FAILED:
-                    case START_WPS_FAILED:
-                    case START_LISTEN_FAILED:
-                    case STOP_LISTEN_FAILED:
-                    case SET_CHANNEL_FAILED:
-                    case REPORT_NFC_HANDOVER_FAILED:
-                    case FACTORY_RESET_FAILED:
-                    case SET_ONGOING_PEER_CONFIG_FAILED:
-                        if (listener != null) {
-                            ((ActionListener) listener).onFailure(message.arg1);
-                        }
-                        break;
-                    /* ActionListeners grouped together */
-                    case DISCOVER_PEERS_SUCCEEDED:
-                    case STOP_DISCOVERY_SUCCEEDED:
-                    case DISCOVER_SERVICES_SUCCEEDED:
-                    case CONNECT_SUCCEEDED:
-                    case CANCEL_CONNECT_SUCCEEDED:
-                    case CREATE_GROUP_SUCCEEDED:
-                    case REMOVE_GROUP_SUCCEEDED:
-                    case ADD_LOCAL_SERVICE_SUCCEEDED:
-                    case REMOVE_LOCAL_SERVICE_SUCCEEDED:
-                    case CLEAR_LOCAL_SERVICES_SUCCEEDED:
-                    case ADD_SERVICE_REQUEST_SUCCEEDED:
-                    case REMOVE_SERVICE_REQUEST_SUCCEEDED:
-                    case CLEAR_SERVICE_REQUESTS_SUCCEEDED:
-                    case SET_DEVICE_NAME_SUCCEEDED:
-                    case DELETE_PERSISTENT_GROUP_SUCCEEDED:
-                    case SET_WFD_INFO_SUCCEEDED:
-                    case START_WPS_SUCCEEDED:
-                    case START_LISTEN_SUCCEEDED:
-                    case STOP_LISTEN_SUCCEEDED:
-                    case SET_CHANNEL_SUCCEEDED:
-                    case REPORT_NFC_HANDOVER_SUCCEEDED:
-                    case FACTORY_RESET_SUCCEEDED:
-                    case SET_ONGOING_PEER_CONFIG_SUCCEEDED:
-                        if (listener != null) {
-                            ((ActionListener) listener).onSuccess();
-                        }
-                        break;
-                    case RESPONSE_PEERS:
-                        WifiP2pDeviceList peers = (WifiP2pDeviceList) message.obj;
-                        if (listener != null) {
-                            ((PeerListListener) listener).onPeersAvailable(peers);
-                        }
-                        break;
-                    case RESPONSE_CONNECTION_INFO:
-                        WifiP2pInfo wifiP2pInfo = (WifiP2pInfo) message.obj;
-                        if (listener != null) {
-                            ((ConnectionInfoListener) listener).onConnectionInfoAvailable(wifiP2pInfo);
-                        }
-                        break;
-                    case RESPONSE_GROUP_INFO:
-                        WifiP2pGroup group = (WifiP2pGroup) message.obj;
-                        if (listener != null) {
-                            ((GroupInfoListener) listener).onGroupInfoAvailable(group);
-                        }
-                        break;
-                    case RESPONSE_SERVICE:
-                        WifiP2pServiceResponse resp = (WifiP2pServiceResponse) message.obj;
-                        handleServiceResponse(resp);
-                        break;
-                    case RESPONSE_PERSISTENT_GROUP_INFO:
-                        WifiP2pGroupList groups = (WifiP2pGroupList) message.obj;
-                        if (listener != null) {
-                            ((PersistentGroupInfoListener) listener).
-                                onPersistentGroupInfoAvailable(groups);
-                        }
-                        break;
-                    case RESPONSE_GET_HANDOVER_MESSAGE:
-                        Bundle handoverBundle = (Bundle) message.obj;
-                        if (listener != null) {
-                            String handoverMessage = handoverBundle != null
-                                    ? handoverBundle.getString(EXTRA_HANDOVER_MESSAGE)
-                                    : null;
-                            ((HandoverMessageListener) listener)
-                                    .onHandoverMessageAvailable(handoverMessage);
-                        }
-                        break;
-                    case RESPONSE_ONGOING_PEER_CONFIG:
-                        WifiP2pConfig peerConfig = (WifiP2pConfig) message.obj;
-                        if (listener != null) {
-                            ((OngoingPeerInfoListener) listener)
-                                    .onOngoingPeerAvailable(peerConfig);
-                        }
-                        break;
-                    case RESPONSE_P2P_STATE:
-                        if (listener != null) {
-                            ((P2pStateListener) listener)
-                                    .onP2pStateAvailable(message.arg1);
-                        }
-                        break;
-                    case RESPONSE_DISCOVERY_STATE:
-                        if (listener != null) {
-                            ((DiscoveryStateListener) listener)
-                                    .onDiscoveryStateAvailable(message.arg1);
-                        }
-                        break;
-                    case RESPONSE_NETWORK_INFO:
-                        if (listener != null) {
-                            ((NetworkInfoListener) listener)
-                                    .onNetworkInfoAvailable((NetworkInfo) message.obj);
-                        }
-                        break;
-                    case RESPONSE_DEVICE_INFO:
-                        if (listener != null) {
-                            ((DeviceInfoListener) listener)
-                                    .onDeviceInfoAvailable((WifiP2pDevice) message.obj);
-                        }
-                        break;
-                    default:
-                        Log.d(TAG, "Ignored " + message);
-                        break;
-                }
-            }
-        }
-
-        private void handleServiceResponse(WifiP2pServiceResponse resp) {
-            if (resp instanceof WifiP2pDnsSdServiceResponse) {
-                handleDnsSdServiceResponse((WifiP2pDnsSdServiceResponse)resp);
-            } else if (resp instanceof WifiP2pUpnpServiceResponse) {
-                if (mUpnpServRspListener != null) {
-                    handleUpnpServiceResponse((WifiP2pUpnpServiceResponse)resp);
-                }
-            } else {
-                if (mServRspListener != null) {
-                    mServRspListener.onServiceAvailable(resp.getServiceType(),
-                            resp.getRawData(), resp.getSrcDevice());
-                }
-            }
-        }
-
-        private void handleUpnpServiceResponse(WifiP2pUpnpServiceResponse resp) {
-            mUpnpServRspListener.onUpnpServiceAvailable(resp.getUniqueServiceNames(),
-                    resp.getSrcDevice());
-        }
-
-        private void handleDnsSdServiceResponse(WifiP2pDnsSdServiceResponse resp) {
-            if (resp.getDnsType() == WifiP2pDnsSdServiceInfo.DNS_TYPE_PTR) {
-                if (mDnsSdServRspListener != null) {
-                    mDnsSdServRspListener.onDnsSdServiceAvailable(
-                            resp.getInstanceName(),
-                            resp.getDnsQueryName(),
-                            resp.getSrcDevice());
-                }
-            } else if (resp.getDnsType() == WifiP2pDnsSdServiceInfo.DNS_TYPE_TXT) {
-                if (mDnsSdTxtListener != null) {
-                    mDnsSdTxtListener.onDnsSdTxtRecordAvailable(
-                            resp.getDnsQueryName(),
-                            resp.getTxtRecord(),
-                            resp.getSrcDevice());
-                }
-            } else {
-                Log.e(TAG, "Unhandled resp " + resp);
-            }
-        }
-
-        @UnsupportedAppUsage
-        private int putListener(Object listener) {
-            if (listener == null) return INVALID_LISTENER_KEY;
-            int key;
-            synchronized (mListenerMapLock) {
-                do {
-                    key = mListenerKey++;
-                } while (key == INVALID_LISTENER_KEY);
-                mListenerMap.put(key, listener);
-            }
-            return key;
-        }
-
-        private Object getListener(int key) {
-            if (key == INVALID_LISTENER_KEY) return null;
-            synchronized (mListenerMapLock) {
-                return mListenerMap.remove(key);
-            }
-        }
-    }
-
-    private static void checkChannel(Channel c) {
-        if (c == null) throw new IllegalArgumentException("Channel needs to be initialized");
-    }
-
-    private static void checkServiceInfo(WifiP2pServiceInfo info) {
-        if (info == null) throw new IllegalArgumentException("service info is null");
-    }
-
-    private static void checkServiceRequest(WifiP2pServiceRequest req) {
-        if (req == null) throw new IllegalArgumentException("service request is null");
-    }
-
-    private static void checkP2pConfig(WifiP2pConfig c) {
-        if (c == null) throw new IllegalArgumentException("config cannot be null");
-        if (TextUtils.isEmpty(c.deviceAddress)) {
-            throw new IllegalArgumentException("deviceAddress cannot be empty");
-        }
-    }
-
-    /**
-     * Registers the application with the Wi-Fi framework. This function
-     * must be the first to be called before any p2p operations are performed.
-     *
-     * @param srcContext is the context of the source
-     * @param srcLooper is the Looper on which the callbacks are receivied
-     * @param listener for callback at loss of framework communication. Can be null.
-     * @return Channel instance that is necessary for performing any further p2p operations
-     */
-    public Channel initialize(Context srcContext, Looper srcLooper, ChannelListener listener) {
-        Binder binder = new Binder();
-        Channel channel = initalizeChannel(srcContext, srcLooper, listener, getMessenger(binder),
-                binder);
-        return channel;
-    }
-
-    /**
-     * Registers the application with the Wi-Fi framework. Enables system-only functionality.
-     * @hide
-     */
-    public Channel initializeInternal(Context srcContext, Looper srcLooper,
-                                      ChannelListener listener) {
-        return initalizeChannel(srcContext, srcLooper, listener, getP2pStateMachineMessenger(),
-                null);
-    }
-
-    private Channel initalizeChannel(Context srcContext, Looper srcLooper, ChannelListener listener,
-                                     Messenger messenger, Binder binder) {
-        if (messenger == null) return null;
-
-        Channel c = new Channel(srcContext, srcLooper, listener, binder, this);
-        if (c.mAsyncChannel.connectSync(srcContext, c.mHandler, messenger)
-                == AsyncChannel.STATUS_SUCCESSFUL) {
-            Bundle bundle = new Bundle();
-            bundle.putString(CALLING_PACKAGE, c.mContext.getOpPackageName());
-            bundle.putString(CALLING_FEATURE_ID, c.mContext.getAttributionTag());
-            bundle.putBinder(CALLING_BINDER, binder);
-            c.mAsyncChannel.sendMessage(UPDATE_CHANNEL_INFO, 0,
-                    c.putListener(null), bundle);
-            return c;
-        } else {
-            c.close();
-            return null;
-        }
-    }
-
-    /**
-     * Initiate peer discovery. A discovery process involves scanning for available Wi-Fi peers
-     * for the purpose of establishing a connection.
-     *
-     * <p> The function call immediately returns after sending a discovery request
-     * to the framework. The application is notified of a success or failure to initiate
-     * discovery through listener callbacks {@link ActionListener#onSuccess} or
-     * {@link ActionListener#onFailure}.
-     *
-     * <p> The discovery remains active until a connection is initiated or
-     * a p2p group is formed. Register for {@link #WIFI_P2P_PEERS_CHANGED_ACTION} intent to
-     * determine when the framework notifies of a change as peers are discovered.
-     *
-     * <p> Upon receiving a {@link #WIFI_P2P_PEERS_CHANGED_ACTION} intent, an application
-     * can request for the list of peers using {@link #requestPeers}.
-     *
-     * @param c is the channel created at {@link #initialize}
-     * @param listener for callbacks on success or failure. Can be null.
-     */
-    @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION)
-    public void discoverPeers(Channel c, ActionListener listener) {
-        checkChannel(c);
-        c.mAsyncChannel.sendMessage(DISCOVER_PEERS, 0, c.putListener(listener));
-    }
-
-    /**
-     * Stop an ongoing peer discovery
-     *
-     * <p> The function call immediately returns after sending a stop request
-     * to the framework. The application is notified of a success or failure to initiate
-     * stop through listener callbacks {@link ActionListener#onSuccess} or
-     * {@link ActionListener#onFailure}.
-     *
-     * @param c is the channel created at {@link #initialize}
-     * @param listener for callbacks on success or failure. Can be null.
-     */
-    public void stopPeerDiscovery(Channel c, ActionListener listener) {
-        checkChannel(c);
-        c.mAsyncChannel.sendMessage(STOP_DISCOVERY, 0, c.putListener(listener));
-    }
-
-    /**
-     * Start a p2p connection to a device with the specified configuration.
-     *
-     * <p> The function call immediately returns after sending a connection request
-     * to the framework. The application is notified of a success or failure to initiate
-     * connect through listener callbacks {@link ActionListener#onSuccess} or
-     * {@link ActionListener#onFailure}.
-     *
-     * <p> Register for {@link #WIFI_P2P_CONNECTION_CHANGED_ACTION} intent to
-     * determine when the framework notifies of a change in connectivity.
-     *
-     * <p> If the current device is not part of a p2p group, a connect request initiates
-     * a group negotiation with the peer.
-     *
-     * <p> If the current device is part of an existing p2p group or has created
-     * a p2p group with {@link #createGroup}, an invitation to join the group is sent to
-     * the peer device.
-     *
-     * @param c is the channel created at {@link #initialize}
-     * @param config options as described in {@link WifiP2pConfig} class
-     * @param listener for callbacks on success or failure. Can be null.
-     */
-    @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION)
-    public void connect(Channel c, WifiP2pConfig config, ActionListener listener) {
-        checkChannel(c);
-        checkP2pConfig(config);
-        c.mAsyncChannel.sendMessage(CONNECT, 0, c.putListener(listener), config);
-    }
-
-    /**
-     * Cancel any ongoing p2p group negotiation
-     *
-     * <p> The function call immediately returns after sending a connection cancellation request
-     * to the framework. The application is notified of a success or failure to initiate
-     * cancellation through listener callbacks {@link ActionListener#onSuccess} or
-     * {@link ActionListener#onFailure}.
-     *
-     * @param c is the channel created at {@link #initialize}
-     * @param listener for callbacks on success or failure. Can be null.
-     */
-    public void cancelConnect(Channel c, ActionListener listener) {
-        checkChannel(c);
-        c.mAsyncChannel.sendMessage(CANCEL_CONNECT, 0, c.putListener(listener));
-    }
-
-    /**
-     * Create a p2p group with the current device as the group owner. This essentially creates
-     * an access point that can accept connections from legacy clients as well as other p2p
-     * devices.
-     *
-     * <p class="note"><strong>Note:</strong>
-     * This function would normally not be used unless the current device needs
-     * to form a p2p connection with a legacy client
-     *
-     * <p> The function call immediately returns after sending a group creation request
-     * to the framework. The application is notified of a success or failure to initiate
-     * group creation through listener callbacks {@link ActionListener#onSuccess} or
-     * {@link ActionListener#onFailure}.
-     *
-     * <p> Application can request for the group details with {@link #requestGroupInfo}.
-     *
-     * @param c is the channel created at {@link #initialize}
-     * @param listener for callbacks on success or failure. Can be null.
-     */
-    @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION)
-    public void createGroup(Channel c, ActionListener listener) {
-        checkChannel(c);
-        c.mAsyncChannel.sendMessage(CREATE_GROUP, WifiP2pGroup.NETWORK_ID_PERSISTENT,
-                c.putListener(listener));
-    }
-
-    /**
-     * Create a p2p group with the current device as the group owner. This essentially creates
-     * an access point that can accept connections from legacy clients as well as other p2p
-     * devices.
-     *
-     * <p> An app should use {@link WifiP2pConfig.Builder} to build the configuration
-     * for a group.
-     *
-     * <p class="note"><strong>Note:</strong>
-     * This function would normally not be used unless the current device needs
-     * to form a p2p group as a Group Owner and allow peers to join it as either
-     * Group Clients or legacy Wi-Fi STAs.
-     *
-     * <p> The function call immediately returns after sending a group creation request
-     * to the framework. The application is notified of a success or failure to initiate
-     * group creation through listener callbacks {@link ActionListener#onSuccess} or
-     * {@link ActionListener#onFailure}.
-     *
-     * <p> Application can request for the group details with {@link #requestGroupInfo}.
-     *
-     * @param c is the channel created at {@link #initialize}.
-     * @param config the configuration of a p2p group.
-     * @param listener for callbacks on success or failure. Can be null.
-     */
-    @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION)
-    public void createGroup(@NonNull Channel c,
-            @Nullable WifiP2pConfig config,
-            @Nullable ActionListener listener) {
-        checkChannel(c);
-        c.mAsyncChannel.sendMessage(CREATE_GROUP, 0,
-                c.putListener(listener), config);
-    }
-
-    /**
-     * Remove the current p2p group.
-     *
-     * <p> The function call immediately returns after sending a group removal request
-     * to the framework. The application is notified of a success or failure to initiate
-     * group removal through listener callbacks {@link ActionListener#onSuccess} or
-     * {@link ActionListener#onFailure}.
-     *
-     * @param c is the channel created at {@link #initialize}
-     * @param listener for callbacks on success or failure. Can be null.
-     */
-    public void removeGroup(Channel c, ActionListener listener) {
-        checkChannel(c);
-        c.mAsyncChannel.sendMessage(REMOVE_GROUP, 0, c.putListener(listener));
-    }
-
-    /**
-     * Force p2p to enter listen state
-     *
-     * @param c is the channel created at {@link #initialize(Context, Looper, ChannelListener)}
-     * @param listener for callbacks on success or failure. Can be null.
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public void startListening(@NonNull Channel c, @Nullable ActionListener listener) {
-        checkChannel(c);
-        c.mAsyncChannel.sendMessage(START_LISTEN, 0, c.putListener(listener));
-    }
-
-    /**
-     * Force p2p to exit listen state
-     *
-     * @param c is the channel created at {@link #initialize(Context, Looper, ChannelListener)}
-     * @param listener for callbacks on success or failure. Can be null.
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public void stopListening(@NonNull Channel c, @Nullable ActionListener listener) {
-        checkChannel(c);
-        c.mAsyncChannel.sendMessage(STOP_LISTEN, 0, c.putListener(listener));
-    }
-
-    /**
-     * Set P2P listening and operating channel.
-     *
-     * @param c is the channel created at {@link #initialize}
-     * @param listeningChannel the listening channel's Wifi channel number. e.g. 1, 6, 11.
-     * @param operatingChannel the operating channel's Wifi channel number. e.g. 1, 6, 11.
-     * @param listener for callbacks on success or failure. Can be null.
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(anyOf = {
-            android.Manifest.permission.NETWORK_SETTINGS,
-            android.Manifest.permission.NETWORK_STACK,
-            android.Manifest.permission.OVERRIDE_WIFI_CONFIG
-    })
-    public void setWifiP2pChannels(@NonNull Channel c, int listeningChannel, int operatingChannel,
-            @Nullable ActionListener listener) {
-        checkChannel(c);
-        Bundle p2pChannels = new Bundle();
-        p2pChannels.putInt("lc", listeningChannel);
-        p2pChannels.putInt("oc", operatingChannel);
-        c.mAsyncChannel.sendMessage(SET_CHANNEL, 0, c.putListener(listener), p2pChannels);
-    }
-
-    /**
-     * Start a Wi-Fi Protected Setup (WPS) session.
-     *
-     * <p> The function call immediately returns after sending a request to start a
-     * WPS session. Currently, this is only valid if the current device is running
-     * as a group owner to allow any new clients to join the group. The application
-     * is notified of a success or failure to initiate WPS through listener callbacks
-     * {@link ActionListener#onSuccess} or {@link ActionListener#onFailure}.
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public void startWps(Channel c, WpsInfo wps, ActionListener listener) {
-        checkChannel(c);
-        c.mAsyncChannel.sendMessage(START_WPS, 0, c.putListener(listener), wps);
-    }
-
-    /**
-     * Register a local service for service discovery. If a local service is registered,
-     * the framework automatically responds to a service discovery request from a peer.
-     *
-     * <p> The function call immediately returns after sending a request to add a local
-     * service to the framework. The application is notified of a success or failure to
-     * add service through listener callbacks {@link ActionListener#onSuccess} or
-     * {@link ActionListener#onFailure}.
-     *
-     * <p>The service information is set through {@link WifiP2pServiceInfo}.<br>
-     * or its subclass calls  {@link WifiP2pUpnpServiceInfo#newInstance} or
-     *  {@link WifiP2pDnsSdServiceInfo#newInstance} for a Upnp or Bonjour service
-     * respectively
-     *
-     * <p>The service information can be cleared with calls to
-     *  {@link #removeLocalService} or {@link #clearLocalServices}.
-     *
-     * @param c is the channel created at {@link #initialize}
-     * @param servInfo is a local service information.
-     * @param listener for callbacks on success or failure. Can be null.
-     */
-    @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION)
-    public void addLocalService(Channel c, WifiP2pServiceInfo servInfo, ActionListener listener) {
-        checkChannel(c);
-        checkServiceInfo(servInfo);
-        c.mAsyncChannel.sendMessage(ADD_LOCAL_SERVICE, 0, c.putListener(listener), servInfo);
-    }
-
-    /**
-     * Remove a registered local service added with {@link #addLocalService}
-     *
-     * <p> The function call immediately returns after sending a request to remove a
-     * local service to the framework. The application is notified of a success or failure to
-     * add service through listener callbacks {@link ActionListener#onSuccess} or
-     * {@link ActionListener#onFailure}.
-     *
-     * @param c is the channel created at {@link #initialize}
-     * @param servInfo is the local service information.
-     * @param listener for callbacks on success or failure. Can be null.
-     */
-    public void removeLocalService(Channel c, WifiP2pServiceInfo servInfo,
-            ActionListener listener) {
-        checkChannel(c);
-        checkServiceInfo(servInfo);
-        c.mAsyncChannel.sendMessage(REMOVE_LOCAL_SERVICE, 0, c.putListener(listener), servInfo);
-    }
-
-    /**
-     * Clear all registered local services of service discovery.
-     *
-     * <p> The function call immediately returns after sending a request to clear all
-     * local services to the framework. The application is notified of a success or failure to
-     * add service through listener callbacks {@link ActionListener#onSuccess} or
-     * {@link ActionListener#onFailure}.
-     *
-     * @param c is the channel created at {@link #initialize}
-     * @param listener for callbacks on success or failure. Can be null.
-     */
-    public void clearLocalServices(Channel c, ActionListener listener) {
-        checkChannel(c);
-        c.mAsyncChannel.sendMessage(CLEAR_LOCAL_SERVICES, 0, c.putListener(listener));
-    }
-
-    /**
-     * Register a callback to be invoked on receiving service discovery response.
-     * Used only for vendor specific protocol right now. For Bonjour or Upnp, use
-     * {@link #setDnsSdResponseListeners} or {@link #setUpnpServiceResponseListener}
-     * respectively.
-     *
-     * <p> see {@link #discoverServices} for the detail.
-     *
-     * @param c is the channel created at {@link #initialize}
-     * @param listener for callbacks on receiving service discovery response.
-     */
-    public void setServiceResponseListener(Channel c,
-            ServiceResponseListener listener) {
-        checkChannel(c);
-        c.mServRspListener = listener;
-    }
-
-    /**
-     * Register a callback to be invoked on receiving Bonjour service discovery
-     * response.
-     *
-     * <p> see {@link #discoverServices} for the detail.
-     *
-     * @param c
-     * @param servListener is for listening to a Bonjour service response
-     * @param txtListener is for listening to a Bonjour TXT record response
-     */
-    public void setDnsSdResponseListeners(Channel c,
-            DnsSdServiceResponseListener servListener, DnsSdTxtRecordListener txtListener) {
-        checkChannel(c);
-        c.mDnsSdServRspListener = servListener;
-        c.mDnsSdTxtListener = txtListener;
-    }
-
-    /**
-     * Register a callback to be invoked on receiving upnp service discovery
-     * response.
-     *
-     * <p> see {@link #discoverServices} for the detail.
-     *
-     * @param c is the channel created at {@link #initialize}
-     * @param listener for callbacks on receiving service discovery response.
-     */
-    public void setUpnpServiceResponseListener(Channel c,
-            UpnpServiceResponseListener listener) {
-        checkChannel(c);
-        c.mUpnpServRspListener = listener;
-    }
-
-    /**
-     * Initiate service discovery. A discovery process involves scanning for
-     * requested services for the purpose of establishing a connection to a peer
-     * that supports an available service.
-     *
-     * <p> The function call immediately returns after sending a request to start service
-     * discovery to the framework. The application is notified of a success or failure to initiate
-     * discovery through listener callbacks {@link ActionListener#onSuccess} or
-     * {@link ActionListener#onFailure}.
-     *
-     * <p> The services to be discovered are specified with calls to {@link #addServiceRequest}.
-     *
-     * <p>The application is notified of the response against the service discovery request
-     * through listener callbacks registered by {@link #setServiceResponseListener} or
-     * {@link #setDnsSdResponseListeners}, or {@link #setUpnpServiceResponseListener}.
-     *
-     * @param c is the channel created at {@link #initialize}
-     * @param listener for callbacks on success or failure. Can be null.
-     */
-    @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION)
-    public void discoverServices(Channel c, ActionListener listener) {
-        checkChannel(c);
-        c.mAsyncChannel.sendMessage(DISCOVER_SERVICES, 0, c.putListener(listener));
-    }
-
-    /**
-     * Add a service discovery request.
-     *
-     * <p> The function call immediately returns after sending a request to add service
-     * discovery request to the framework. The application is notified of a success or failure to
-     * add service through listener callbacks {@link ActionListener#onSuccess} or
-     * {@link ActionListener#onFailure}.
-     *
-     * <p>After service discovery request is added, you can initiate service discovery by
-     * {@link #discoverServices}.
-     *
-     * <p>The added service requests can be cleared with calls to
-     * {@link #removeServiceRequest(Channel, WifiP2pServiceRequest, ActionListener)} or
-     * {@link #clearServiceRequests(Channel, ActionListener)}.
-     *
-     * @param c is the channel created at {@link #initialize}
-     * @param req is the service discovery request.
-     * @param listener for callbacks on success or failure. Can be null.
-     */
-    public void addServiceRequest(Channel c,
-            WifiP2pServiceRequest req, ActionListener listener) {
-        checkChannel(c);
-        checkServiceRequest(req);
-        c.mAsyncChannel.sendMessage(ADD_SERVICE_REQUEST, 0,
-                c.putListener(listener), req);
-    }
-
-    /**
-     * Remove a specified service discovery request added with {@link #addServiceRequest}
-     *
-     * <p> The function call immediately returns after sending a request to remove service
-     * discovery request to the framework. The application is notified of a success or failure to
-     * add service through listener callbacks {@link ActionListener#onSuccess} or
-     * {@link ActionListener#onFailure}.
-     *
-     * @param c is the channel created at {@link #initialize}
-     * @param req is the service discovery request.
-     * @param listener for callbacks on success or failure. Can be null.
-     */
-    public void removeServiceRequest(Channel c, WifiP2pServiceRequest req,
-            ActionListener listener) {
-        checkChannel(c);
-        checkServiceRequest(req);
-        c.mAsyncChannel.sendMessage(REMOVE_SERVICE_REQUEST, 0,
-                c.putListener(listener), req);
-    }
-
-    /**
-     * Clear all registered service discovery requests.
-     *
-     * <p> The function call immediately returns after sending a request to clear all
-     * service discovery requests to the framework. The application is notified of a success
-     * or failure to add service through listener callbacks {@link ActionListener#onSuccess} or
-     * {@link ActionListener#onFailure}.
-     *
-     * @param c is the channel created at {@link #initialize}
-     * @param listener for callbacks on success or failure. Can be null.
-     */
-    public void clearServiceRequests(Channel c, ActionListener listener) {
-        checkChannel(c);
-        c.mAsyncChannel.sendMessage(CLEAR_SERVICE_REQUESTS,
-                0, c.putListener(listener));
-    }
-
-    /**
-     * Request the current list of peers.
-     *
-     * @param c is the channel created at {@link #initialize}
-     * @param listener for callback when peer list is available. Can be null.
-     */
-    @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION)
-    public void requestPeers(Channel c, PeerListListener listener) {
-        checkChannel(c);
-        c.mAsyncChannel.sendMessage(REQUEST_PEERS, 0, c.putListener(listener));
-    }
-
-    /**
-     * Request device connection info.
-     *
-     * @param c is the channel created at {@link #initialize}
-     * @param listener for callback when connection info is available. Can be null.
-     */
-    public void requestConnectionInfo(Channel c, ConnectionInfoListener listener) {
-        checkChannel(c);
-        c.mAsyncChannel.sendMessage(REQUEST_CONNECTION_INFO, 0, c.putListener(listener));
-    }
-
-    /**
-     * Request p2p group info.
-     *
-     * @param c is the channel created at {@link #initialize}
-     * @param listener for callback when group info is available. Can be null.
-     */
-    @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION)
-    public void requestGroupInfo(Channel c, GroupInfoListener listener) {
-        checkChannel(c);
-        c.mAsyncChannel.sendMessage(REQUEST_GROUP_INFO, 0, c.putListener(listener));
-    }
-
-    /**
-     * Set p2p device name.
-     *
-     * @param c is the channel created at {@link #initialize}
-     * @param listener for callback when group info is available. Can be null.
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(anyOf = {
-            android.Manifest.permission.NETWORK_SETTINGS,
-            android.Manifest.permission.NETWORK_STACK,
-            android.Manifest.permission.OVERRIDE_WIFI_CONFIG
-    })
-    public void setDeviceName(@NonNull Channel c, @NonNull String devName,
-            @Nullable ActionListener listener) {
-        checkChannel(c);
-        WifiP2pDevice d = new WifiP2pDevice();
-        d.deviceName = devName;
-        c.mAsyncChannel.sendMessage(SET_DEVICE_NAME, 0, c.putListener(listener), d);
-    }
-
-    /**
-     * Set Wifi Display information.
-     *
-     * @param c is the channel created at {@link #initialize}
-     * @param wfdInfo the Wifi Display information to set
-     * @param listener for callbacks on success or failure. Can be null.
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.CONFIGURE_WIFI_DISPLAY)
-    public void setWfdInfo(@NonNull Channel c, @NonNull WifiP2pWfdInfo wfdInfo,
-            @Nullable ActionListener listener) {
-        setWFDInfo(c, wfdInfo, listener);
-    }
-
-    /** @hide */
-    @UnsupportedAppUsage
-    @RequiresPermission(android.Manifest.permission.CONFIGURE_WIFI_DISPLAY)
-    public void setWFDInfo(@NonNull Channel c, @NonNull WifiP2pWfdInfo wfdInfo,
-            @Nullable ActionListener listener) {
-        checkChannel(c);
-        try {
-            mService.checkConfigureWifiDisplayPermission();
-        } catch (RemoteException e) {
-            e.rethrowFromSystemServer();
-        }
-        c.mAsyncChannel.sendMessage(SET_WFD_INFO, 0, c.putListener(listener), wfdInfo);
-    }
-
-
-    /**
-     * Delete a stored persistent group from the system settings.
-     *
-     * <p> The function call immediately returns after sending a persistent group removal request
-     * to the framework. The application is notified of a success or failure to initiate
-     * group removal through listener callbacks {@link ActionListener#onSuccess} or
-     * {@link ActionListener#onFailure}.
-     *
-     * <p>The persistent p2p group list stored in the system can be obtained by
-     * {@link #requestPersistentGroupInfo(Channel, PersistentGroupInfoListener)} and
-     *  a network id can be obtained by {@link WifiP2pGroup#getNetworkId()}.
-     *
-     * @param c is the channel created at {@link #initialize}
-     * @param netId the network id of the p2p group.
-     * @param listener for callbacks on success or failure. Can be null.
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(anyOf = {
-            android.Manifest.permission.NETWORK_SETTINGS,
-            android.Manifest.permission.NETWORK_STACK,
-            android.Manifest.permission.OVERRIDE_WIFI_CONFIG
-    })
-    public void deletePersistentGroup(@NonNull Channel c, int netId,
-            @Nullable ActionListener listener) {
-        checkChannel(c);
-        c.mAsyncChannel.sendMessage(DELETE_PERSISTENT_GROUP, netId, c.putListener(listener));
-    }
-
-    /**
-     * Request a list of all the persistent p2p groups stored in system.
-     *
-     * @param c is the channel created at {@link #initialize}
-     * @param listener for callback when persistent group info list is available. Can be null.
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(anyOf = {
-            android.Manifest.permission.NETWORK_SETTINGS,
-            android.Manifest.permission.NETWORK_STACK,
-            android.Manifest.permission.READ_WIFI_CREDENTIAL
-    })
-    public void requestPersistentGroupInfo(@NonNull Channel c,
-            @Nullable PersistentGroupInfoListener listener) {
-        checkChannel(c);
-        c.mAsyncChannel.sendMessage(REQUEST_PERSISTENT_GROUP_INFO, 0, c.putListener(listener));
-    }
-
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(prefix = {"MIRACAST_"}, value = {
-            MIRACAST_DISABLED,
-            MIRACAST_SOURCE,
-            MIRACAST_SINK})
-    public @interface MiracastMode {}
-
-    /**
-     * Miracast is disabled.
-     * @hide
-     */
-    @SystemApi
-    public static final int MIRACAST_DISABLED = 0;
-    /**
-     * Device acts as a Miracast source.
-     * @hide
-     */
-    @SystemApi
-    public static final int MIRACAST_SOURCE   = 1;
-    /**
-     * Device acts as a Miracast sink.
-     * @hide
-     */
-    @SystemApi
-    public static final int MIRACAST_SINK     = 2;
-
-    /**
-     * This is used to provide information to drivers to optimize performance depending
-     * on the current mode of operation.
-     * {@link #MIRACAST_DISABLED} - disabled
-     * {@link #MIRACAST_SOURCE} - source operation
-     * {@link #MIRACAST_SINK} - sink operation
-     *
-     * As an example, the driver could reduce the channel dwell time during scanning
-     * when acting as a source or sink to minimize impact on Miracast.
-     *
-     * @param mode mode of operation. One of {@link #MIRACAST_DISABLED}, {@link #MIRACAST_SOURCE},
-     * or {@link #MIRACAST_SINK}
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.CONFIGURE_WIFI_DISPLAY)
-    public void setMiracastMode(@MiracastMode int mode) {
-        try {
-            mService.setMiracastMode(mode);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Get a reference to WifiP2pService handler. This is used to establish
-     * an AsyncChannel communication with WifiService
-     *
-     * @param binder A binder for the service to associate with this client.
-     *
-     * @return Messenger pointing to the WifiP2pService handler
-     * @hide
-     */
-    public Messenger getMessenger(Binder binder) {
-        try {
-            return mService.getMessenger(binder);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Get a reference to P2pStateMachine handler. This is used to establish
-     * a priveleged AsyncChannel communication with WifiP2pService.
-     *
-     * @return Messenger pointing to the WifiP2pService handler
-     * @hide
-     */
-    public Messenger getP2pStateMachineMessenger() {
-        try {
-            return mService.getP2pStateMachineMessenger();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Get a handover request message for use in WFA NFC Handover transfer.
-     * @hide
-     */
-    public void getNfcHandoverRequest(Channel c, HandoverMessageListener listener) {
-        checkChannel(c);
-        c.mAsyncChannel.sendMessage(GET_HANDOVER_REQUEST, 0, c.putListener(listener));
-    }
-
-
-    /**
-     * Get a handover select message for use in WFA NFC Handover transfer.
-     * @hide
-     */
-    public void getNfcHandoverSelect(Channel c, HandoverMessageListener listener) {
-        checkChannel(c);
-        c.mAsyncChannel.sendMessage(GET_HANDOVER_SELECT, 0, c.putListener(listener));
-    }
-
-    /**
-     * @hide
-     */
-    public void initiatorReportNfcHandover(Channel c, String handoverSelect,
-                                              ActionListener listener) {
-        checkChannel(c);
-        Bundle bundle = new Bundle();
-        bundle.putString(EXTRA_HANDOVER_MESSAGE, handoverSelect);
-        c.mAsyncChannel.sendMessage(INITIATOR_REPORT_NFC_HANDOVER, 0,
-                c.putListener(listener), bundle);
-    }
-
-
-    /**
-     * @hide
-     */
-    public void responderReportNfcHandover(Channel c, String handoverRequest,
-                                              ActionListener listener) {
-        checkChannel(c);
-        Bundle bundle = new Bundle();
-        bundle.putString(EXTRA_HANDOVER_MESSAGE, handoverRequest);
-        c.mAsyncChannel.sendMessage(RESPONDER_REPORT_NFC_HANDOVER, 0,
-                c.putListener(listener), bundle);
-    }
-
-    /**
-     * Removes all saved p2p groups.
-     *
-     * @param c is the channel created at {@link #initialize}.
-     * @param listener for callback on success or failure. Can be null.
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public void factoryReset(@NonNull Channel c, @Nullable ActionListener listener) {
-        checkChannel(c);
-        c.mAsyncChannel.sendMessage(FACTORY_RESET, 0, c.putListener(listener));
-    }
-
-    /**
-     * Request saved WifiP2pConfig which used for an ongoing peer connection
-     *
-     * @param c is the channel created at {@link #initialize}
-     * @param listener for callback when ongoing peer config updated. Can't be null.
-     *
-     * @hide
-     */
-    @RequiresPermission(android.Manifest.permission.NETWORK_STACK)
-    public void requestOngoingPeerConfig(@NonNull Channel c,
-            @NonNull OngoingPeerInfoListener listener) {
-        checkChannel(c);
-        c.mAsyncChannel.sendMessage(REQUEST_ONGOING_PEER_CONFIG,
-                Binder.getCallingUid(), c.putListener(listener));
-    }
-
-     /**
-     * Set saved WifiP2pConfig which used for an ongoing peer connection
-     *
-     * @param c is the channel created at {@link #initialize}
-     * @param config used for change an ongoing peer connection
-     * @param listener for callback when ongoing peer config updated. Can be null.
-     *
-     * @hide
-     */
-    @RequiresPermission(android.Manifest.permission.NETWORK_STACK)
-    public void setOngoingPeerConfig(@NonNull Channel c, @NonNull WifiP2pConfig config,
-            @Nullable ActionListener listener) {
-        checkChannel(c);
-        checkP2pConfig(config);
-        c.mAsyncChannel.sendMessage(SET_ONGOING_PEER_CONFIG, 0,
-                c.putListener(listener), config);
-    }
-
-    /**
-     * Request p2p enabled state.
-     *
-     * <p> This state indicates whether Wi-Fi p2p is enabled or disabled.
-     * The valid value is one of {@link #WIFI_P2P_STATE_DISABLED} or
-     * {@link #WIFI_P2P_STATE_ENABLED}. The state is returned using the
-     * {@link P2pStateListener} listener.
-     *
-     * <p> This state is also included in the {@link #WIFI_P2P_STATE_CHANGED_ACTION}
-     * broadcast event with extra {@link #EXTRA_WIFI_STATE}.
-     *
-     * @param c is the channel created at {@link #initialize}.
-     * @param listener for callback when p2p state is available..
-     */
-    public void requestP2pState(@NonNull Channel c,
-            @NonNull P2pStateListener listener) {
-        checkChannel(c);
-        if (listener == null) throw new IllegalArgumentException("This listener cannot be null.");
-        c.mAsyncChannel.sendMessage(REQUEST_P2P_STATE, 0, c.putListener(listener));
-    }
-
-    /**
-     * Request p2p discovery state.
-     *
-     * <p> This state indicates whether p2p discovery has started or stopped.
-     * The valid value is one of {@link #WIFI_P2P_DISCOVERY_STARTED} or
-     * {@link #WIFI_P2P_DISCOVERY_STOPPED}. The state is returned using the
-     * {@link DiscoveryStateListener} listener.
-     *
-     * <p> This state is also included in the {@link #WIFI_P2P_DISCOVERY_CHANGED_ACTION}
-     * broadcast event with extra {@link #EXTRA_DISCOVERY_STATE}.
-     *
-     * @param c is the channel created at {@link #initialize}.
-     * @param listener for callback when discovery state is available..
-     */
-    public void requestDiscoveryState(@NonNull Channel c,
-            @NonNull DiscoveryStateListener listener) {
-        checkChannel(c);
-        if (listener == null) throw new IllegalArgumentException("This listener cannot be null.");
-        c.mAsyncChannel.sendMessage(REQUEST_DISCOVERY_STATE, 0, c.putListener(listener));
-    }
-
-    /**
-     * Request network info.
-     *
-     * <p> This method provides the network info in the form of a {@link android.net.NetworkInfo}.
-     * {@link android.net.NetworkInfo#isAvailable()} indicates the p2p availability and
-     * {@link android.net.NetworkInfo#getDetailedState()} reports the current fine-grained state
-     * of the network. This {@link android.net.NetworkInfo} is returned using the
-     * {@link NetworkInfoListener} listener.
-     *
-     * <p> This information is also included in the {@link #WIFI_P2P_CONNECTION_CHANGED_ACTION}
-     * broadcast event with extra {@link #EXTRA_NETWORK_INFO}.
-     *
-     * @param c is the channel created at {@link #initialize}.
-     * @param listener for callback when network info is available..
-     */
-    public void requestNetworkInfo(@NonNull Channel c,
-            @NonNull NetworkInfoListener listener) {
-        checkChannel(c);
-        if (listener == null) throw new IllegalArgumentException("This listener cannot be null.");
-        c.mAsyncChannel.sendMessage(REQUEST_NETWORK_INFO, 0, c.putListener(listener));
-    }
-
-     /**
-     * Request Device Info
-     *
-     * <p> This method provides the device info
-     * in the form of a {@link android.net.wifi.p2p.WifiP2pDevice}.
-     * Valid {@link android.net.wifi.p2p.WifiP2pDevice} is returned when p2p is enabled.
-     * To get information notifications on P2P getting enabled refers
-     * {@link #WIFI_P2P_STATE_ENABLED}.
-     *
-     * <p> This {@link android.net.wifi.p2p.WifiP2pDevice} is returned using the
-     * {@link DeviceInfoListener} listener.
-     *
-     * <p> {@link android.net.wifi.p2p.WifiP2pDevice#deviceAddress} is only available if the caller
-     * holds the {@code android.Manifest.permission#LOCAL_MAC_ADDRESS} permission, and holds the
-     * anonymized MAC address (02:00:00:00:00:00) otherwise.
-     *
-     * <p> This information is also included in the {@link #WIFI_P2P_THIS_DEVICE_CHANGED_ACTION}
-     * broadcast event with extra {@link #EXTRA_WIFI_P2P_DEVICE}.
-     *
-     * @param c is the channel created at {@link #initialize(Context, Looper, ChannelListener)}.
-     * @param listener for callback when network info is available.
-     */
-    @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION)
-    public void requestDeviceInfo(@NonNull Channel c, @NonNull DeviceInfoListener listener) {
-        checkChannel(c);
-        if (listener == null) throw new IllegalArgumentException("This listener cannot be null.");
-        c.mAsyncChannel.sendMessage(REQUEST_DEVICE_INFO, 0, c.putListener(listener));
-    }
-}
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pProvDiscEvent.java b/wifi/java/android/net/wifi/p2p/WifiP2pProvDiscEvent.java
deleted file mode 100644
index d0fe92d..0000000
--- a/wifi/java/android/net/wifi/p2p/WifiP2pProvDiscEvent.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p;
-
-import android.compat.annotation.UnsupportedAppUsage;
-
-/**
- * A class representing a Wi-Fi p2p provisional discovery request/response
- * See {@link #WifiP2pProvDiscEvent} for supported types
- *
- * @hide
- */
-public class WifiP2pProvDiscEvent {
-
-    private static final String TAG = "WifiP2pProvDiscEvent";
-
-    public static final int PBC_REQ     = 1;
-    public static final int PBC_RSP     = 2;
-    public static final int ENTER_PIN   = 3;
-    public static final int SHOW_PIN    = 4;
-
-    /* One of PBC_REQ, PBC_RSP, ENTER_PIN or SHOW_PIN */
-    @UnsupportedAppUsage
-    public int event;
-
-    @UnsupportedAppUsage
-    public WifiP2pDevice device;
-
-    /* Valid when event = SHOW_PIN */
-    @UnsupportedAppUsage
-    public String pin;
-
-    @UnsupportedAppUsage
-    public WifiP2pProvDiscEvent() {
-        device = new WifiP2pDevice();
-    }
-
-    /**
-     * @param string formats supported include
-     *
-     *  P2P-PROV-DISC-PBC-REQ 42:fc:89:e1:e2:27
-     *  P2P-PROV-DISC-PBC-RESP 02:12:47:f2:5a:36
-     *  P2P-PROV-DISC-ENTER-PIN 42:fc:89:e1:e2:27
-     *  P2P-PROV-DISC-SHOW-PIN 42:fc:89:e1:e2:27 44490607
-     *
-     *  Note: The events formats can be looked up in the wpa_supplicant code
-     * @hide
-     */
-    public WifiP2pProvDiscEvent(String string) throws IllegalArgumentException {
-        String[] tokens = string.split(" ");
-
-        if (tokens.length < 2) {
-            throw new IllegalArgumentException("Malformed event " + string);
-        }
-
-        if (tokens[0].endsWith("PBC-REQ")) event = PBC_REQ;
-        else if (tokens[0].endsWith("PBC-RESP")) event = PBC_RSP;
-        else if (tokens[0].endsWith("ENTER-PIN")) event = ENTER_PIN;
-        else if (tokens[0].endsWith("SHOW-PIN")) event = SHOW_PIN;
-        else throw new IllegalArgumentException("Malformed event " + string);
-
-
-        device = new WifiP2pDevice();
-        device.deviceAddress = tokens[1];
-
-        if (event == SHOW_PIN) {
-            pin = tokens[2];
-        }
-    }
-
-    public String toString() {
-        StringBuffer sbuf = new StringBuffer();
-        sbuf.append(device);
-        sbuf.append("\n event: ").append(event);
-        sbuf.append("\n pin: ").append(pin);
-        return sbuf.toString();
-    }
-}
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java b/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java
deleted file mode 100644
index e399b5b..0000000
--- a/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p;
-
-import android.annotation.IntDef;
-import android.annotation.IntRange;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Locale;
-
-/**
- * A class representing Wifi Display information for a device.
- *
- * See Wifi Display technical specification v1.0.0, section 5.1.2.
- */
-public final class WifiP2pWfdInfo implements Parcelable {
-
-    private boolean mEnabled;
-
-    /** Device information bitmap */
-    private int mDeviceInfo;
-
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(prefix = { "DEVICE_TYPE_" }, value = {
-            DEVICE_TYPE_WFD_SOURCE,
-            DEVICE_TYPE_PRIMARY_SINK,
-            DEVICE_TYPE_SECONDARY_SINK,
-            DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK})
-    public @interface DeviceType {}
-
-    /** The device is a Wifi Display Source. */
-    public static final int DEVICE_TYPE_WFD_SOURCE = 0;
-    /** The device is a primary sink. */
-    public static final int DEVICE_TYPE_PRIMARY_SINK = 1;
-    /** The device is a secondary sink. */
-    public static final int DEVICE_TYPE_SECONDARY_SINK = 2;
-    /** The device is dual-role capable i.e. either a WFD source or a primary sink. */
-    public static final int DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK = 3;
-
-    /**
-     * {@link #mDeviceInfo} & {@link #DEVICE_TYPE} is one of {@link #DEVICE_TYPE_WFD_SOURCE},
-     * {@link #DEVICE_TYPE_PRIMARY_SINK}, {@link #DEVICE_TYPE_SECONDARY_SINK} or
-     * {@link #DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK}.
-     *
-     * The bit definition is listed in 5.1.2 WFD Device Information Subelement in
-     * Wi-Fi Display Technical Specification.
-     */
-    private static final int DEVICE_TYPE                            = 1 << 1 | 1 << 0;
-    private static final int COUPLED_SINK_SUPPORT_AT_SOURCE         = 1 << 2;
-    private static final int COUPLED_SINK_SUPPORT_AT_SINK           = 1 << 3;
-    private static final int SESSION_AVAILABLE_BIT1                 = 1 << 4;
-    private static final int SESSION_AVAILABLE_BIT2                 = 1 << 5;
-    private static final int SESSION_AVAILABLE                      =
-            SESSION_AVAILABLE_BIT2 | SESSION_AVAILABLE_BIT1;
-    /* The support of Content Protection using the HDCP system 2.0/2.1. */
-    private static final int CONTENT_PROTECTION_SUPPORT             = 1 << 8;
-
-    private int mCtrlPort;
-
-    private int mMaxThroughput;
-
-    /** Default constructor. */
-    public WifiP2pWfdInfo() {}
-
-    /** @hide */
-    @UnsupportedAppUsage
-    public WifiP2pWfdInfo(int devInfo, int ctrlPort, int maxTput) {
-        mEnabled = true;
-        mDeviceInfo = devInfo;
-        mCtrlPort = ctrlPort;
-        mMaxThroughput = maxTput;
-    }
-
-    /** Returns true is Wifi Display is enabled, false otherwise. */
-    public boolean isEnabled() {
-        return mEnabled;
-    }
-
-    /**
-     * Sets whether Wifi Display should be enabled.
-     *
-     * @param enabled true to enable Wifi Display, false to disable
-     */
-    public void setEnabled(boolean enabled) {
-        mEnabled = enabled;
-    }
-
-    /**
-     * Get the type of the device.
-     * One of {@link #DEVICE_TYPE_WFD_SOURCE}, {@link #DEVICE_TYPE_PRIMARY_SINK},
-     * {@link #DEVICE_TYPE_SECONDARY_SINK}, {@link #DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK}
-     */
-    @DeviceType
-    public int getDeviceType() {
-        return mDeviceInfo & DEVICE_TYPE;
-    }
-
-    /**
-     * Sets the type of the device.
-     *
-     * @param deviceType One of {@link #DEVICE_TYPE_WFD_SOURCE}, {@link #DEVICE_TYPE_PRIMARY_SINK},
-     * {@link #DEVICE_TYPE_SECONDARY_SINK}, {@link #DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK}
-     * @return true if the device type was successfully set, false otherwise
-     */
-    public boolean setDeviceType(@DeviceType int deviceType) {
-        if (DEVICE_TYPE_WFD_SOURCE <= deviceType
-                && deviceType <= DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK) {
-            mDeviceInfo &= ~DEVICE_TYPE;
-            mDeviceInfo |= deviceType;
-            return true;
-        }
-        return false;
-    }
-
-    /** Returns true if a session is available, false otherwise. */
-    public boolean isSessionAvailable() {
-        return (mDeviceInfo & SESSION_AVAILABLE) != 0;
-    }
-
-    /**
-     * Sets whether a session is available.
-     *
-     * @param enabled true to indicate that a session is available, false otherwise.
-     */
-    public void setSessionAvailable(boolean enabled) {
-        if (enabled) {
-            mDeviceInfo |= SESSION_AVAILABLE_BIT1;
-            mDeviceInfo &= ~SESSION_AVAILABLE_BIT2;
-        } else {
-            mDeviceInfo &= ~SESSION_AVAILABLE;
-        }
-    }
-
-    /**
-     * @return true if Content Protection using the HDCP system 2.0/2.1 is supported.
-     */
-    public boolean isContentProtectionSupported() {
-        return (mDeviceInfo & CONTENT_PROTECTION_SUPPORT) != 0;
-    }
-
-    /**
-     * Sets whether Content Protection using the HDCP system 2.0/2.1 is supported.
-     *
-     * @param enabled true to indicate that Content Protection is supported, false otherwise.
-     */
-    public void setContentProtectionSupported(boolean enabled) {
-        if (enabled) {
-            mDeviceInfo |= CONTENT_PROTECTION_SUPPORT;
-        } else {
-            mDeviceInfo &= ~CONTENT_PROTECTION_SUPPORT;
-        }
-    }
-
-    /** Returns the TCP port at which the WFD Device listens for RTSP messages. */
-    public int getControlPort() {
-        return mCtrlPort;
-    }
-
-    /** Sets the TCP port at which the WFD Device listens for RTSP messages. */
-    public void setControlPort(@IntRange(from = 0) int port) {
-        mCtrlPort = port;
-    }
-
-    /** Sets the maximum average throughput capability of the WFD Device, in megabits/second. */
-    public void setMaxThroughput(@IntRange(from = 0) int maxThroughput) {
-        mMaxThroughput = maxThroughput;
-    }
-
-    /** Returns the maximum average throughput capability of the WFD Device, in megabits/second. */
-    public int getMaxThroughput() {
-        return mMaxThroughput;
-    }
-
-    /** @hide */
-    public String getDeviceInfoHex() {
-        return String.format(
-                Locale.US, "%04x%04x%04x", mDeviceInfo, mCtrlPort, mMaxThroughput);
-    }
-
-    @Override
-    public String toString() {
-        StringBuffer sbuf = new StringBuffer();
-        sbuf.append("WFD enabled: ").append(mEnabled);
-        sbuf.append("WFD DeviceInfo: ").append(mDeviceInfo);
-        sbuf.append("\n WFD CtrlPort: ").append(mCtrlPort);
-        sbuf.append("\n WFD MaxThroughput: ").append(mMaxThroughput);
-        return sbuf.toString();
-    }
-
-    /** Implement the Parcelable interface */
-    public int describeContents() {
-        return 0;
-    }
-
-    /** Copy constructor. */
-    public WifiP2pWfdInfo(@Nullable WifiP2pWfdInfo source) {
-        if (source != null) {
-            mEnabled = source.mEnabled;
-            mDeviceInfo = source.mDeviceInfo;
-            mCtrlPort = source.mCtrlPort;
-            mMaxThroughput = source.mMaxThroughput;
-        }
-    }
-
-    /** Implement the Parcelable interface */
-    @Override
-    public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeInt(mEnabled ? 1 : 0);
-        dest.writeInt(mDeviceInfo);
-        dest.writeInt(mCtrlPort);
-        dest.writeInt(mMaxThroughput);
-    }
-
-    private void readFromParcel(Parcel in) {
-        mEnabled = (in.readInt() == 1);
-        mDeviceInfo = in.readInt();
-        mCtrlPort = in.readInt();
-        mMaxThroughput = in.readInt();
-    }
-
-    /** Implement the Parcelable interface */
-    public static final @NonNull Creator<WifiP2pWfdInfo> CREATOR =
-        new Creator<WifiP2pWfdInfo>() {
-            public WifiP2pWfdInfo createFromParcel(Parcel in) {
-                WifiP2pWfdInfo device = new WifiP2pWfdInfo();
-                device.readFromParcel(in);
-                return device;
-            }
-
-            public WifiP2pWfdInfo[] newArray(int size) {
-                return new WifiP2pWfdInfo[size];
-            }
-        };
-}
diff --git a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo.java b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo.java
deleted file mode 100644
index e2f40cf..0000000
--- a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo.java
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p.nsd;
-
-import android.compat.annotation.UnsupportedAppUsage;
-import android.os.Build;
-import android.text.TextUtils;
-
-import com.android.net.module.util.DnsSdTxtRecord;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-
-/**
- * A class for storing Bonjour service information that is advertised
- * over a Wi-Fi peer-to-peer setup.
- *
- * {@see android.net.wifi.p2p.WifiP2pManager#addLocalService}
- * {@see android.net.wifi.p2p.WifiP2pManager#removeLocalService}
- * {@see WifiP2pServiceInfo}
- * {@see WifiP2pUpnpServiceInfo}
- */
-public class WifiP2pDnsSdServiceInfo extends WifiP2pServiceInfo {
-
-    /**
-     * Bonjour version 1.
-     * @hide
-     */
-    public static final int VERSION_1 = 0x01;
-
-    /**
-     * Pointer record.
-     * @hide
-     */
-    public static final int DNS_TYPE_PTR = 12;
-
-    /**
-     * Text record.
-     * @hide
-     */
-    public static final int DNS_TYPE_TXT = 16;
-
-    /**
-     * virtual memory packet.
-     * see E.3 of the Wi-Fi Direct technical specification for the detail.<br>
-     * Key: domain name Value: pointer address.<br>
-     */
-    private final static Map<String, String> sVmPacket;
-
-    static {
-        sVmPacket = new HashMap<String, String>();
-        sVmPacket.put("_tcp.local.", "c00c");
-        sVmPacket.put("local.", "c011");
-        sVmPacket.put("_udp.local.", "c01c");
-    }
-
-    /**
-     * This constructor is only used in newInstance().
-     *
-     * @param queryList
-     */
-    private WifiP2pDnsSdServiceInfo(List<String> queryList) {
-        super(queryList);
-    }
-
-    /**
-     * Create a Bonjour service information object.
-     *
-     * @param instanceName instance name.<br>
-     *  e.g) "MyPrinter"
-     * @param serviceType service type.<br>
-     *  e.g) "_ipp._tcp"
-     * @param txtMap TXT record with key/value pair in a map confirming to format defined at
-     * http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt
-     * @return Bonjour service information object
-     */
-    public static WifiP2pDnsSdServiceInfo newInstance(String instanceName,
-            String serviceType, Map<String, String> txtMap) {
-        if (TextUtils.isEmpty(instanceName) || TextUtils.isEmpty(serviceType)) {
-            throw new IllegalArgumentException(
-                    "instance name or service type cannot be empty");
-        }
-
-        DnsSdTxtRecord txtRecord = new DnsSdTxtRecord();
-        if (txtMap != null) {
-            for (String key : txtMap.keySet()) {
-                txtRecord.set(key, txtMap.get(key));
-            }
-        }
-
-        ArrayList<String> queries = new ArrayList<String>();
-        queries.add(createPtrServiceQuery(instanceName, serviceType));
-        queries.add(createTxtServiceQuery(instanceName, serviceType, txtRecord));
-
-        return new WifiP2pDnsSdServiceInfo(queries);
-    }
-
-    /**
-     * Create wpa_supplicant service query for PTR record.
-     *
-     * @param instanceName instance name.<br>
-     *  e.g) "MyPrinter"
-     * @param serviceType service type.<br>
-     *  e.g) "_ipp._tcp"
-     * @return wpa_supplicant service query.
-     */
-    private static String createPtrServiceQuery(String instanceName,
-            String serviceType) {
-
-        StringBuffer sb = new StringBuffer();
-        sb.append("bonjour ");
-        sb.append(createRequest(serviceType + ".local.", DNS_TYPE_PTR, VERSION_1));
-        sb.append(" ");
-
-        byte[] data = instanceName.getBytes();
-        sb.append(String.format(Locale.US, "%02x", data.length));
-        sb.append(WifiP2pServiceInfo.bin2HexStr(data));
-        // This is the start point of this response.
-        // Therefore, it indicates the request domain name.
-        sb.append("c027");
-        return sb.toString();
-    }
-
-    /**
-     * Create wpa_supplicant service query for TXT record.
-     *
-     * @param instanceName instance name.<br>
-     *  e.g) "MyPrinter"
-     * @param serviceType service type.<br>
-     *  e.g) "_ipp._tcp"
-     * @param txtRecord TXT record.<br>
-     * @return wpa_supplicant service query.
-     */
-    private static String createTxtServiceQuery(String instanceName,
-            String serviceType,
-            DnsSdTxtRecord txtRecord) {
-
-
-        StringBuffer sb = new StringBuffer();
-        sb.append("bonjour ");
-
-        sb.append(createRequest((instanceName + "." + serviceType + ".local."),
-                DNS_TYPE_TXT, VERSION_1));
-        sb.append(" ");
-        byte[] rawData = txtRecord.getRawData();
-        if (rawData.length == 0) {
-            sb.append("00");
-        } else {
-            sb.append(bin2HexStr(rawData));
-        }
-        return sb.toString();
-    }
-
-    /**
-     * Create bonjour service discovery request.
-     *
-     * @param dnsName dns name
-     * @param dnsType dns type
-     * @param version version number
-     * @hide
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
-    static String createRequest(String dnsName, int dnsType, int version) {
-        StringBuffer sb = new StringBuffer();
-
-        /*
-         * The request format is as follows.
-         * ________________________________________________
-         * |  Encoded and Compressed dns name (variable)  |
-         * ________________________________________________
-         * |   Type (2)           | Version (1) |
-         */
-        if (dnsType == WifiP2pDnsSdServiceInfo.DNS_TYPE_TXT) {
-            dnsName = dnsName.toLowerCase(Locale.ROOT); // TODO: is this right?
-        }
-        sb.append(compressDnsName(dnsName));
-        sb.append(String.format(Locale.US, "%04x", dnsType));
-        sb.append(String.format(Locale.US, "%02x", version));
-
-        return sb.toString();
-    }
-
-    /**
-     * Compress DNS data.
-     *
-     * see E.3 of the Wi-Fi Direct technical specification for the detail.
-     *
-     * @param dnsName dns name
-     * @return compressed dns name
-     */
-    private static String compressDnsName(String dnsName) {
-        StringBuffer sb = new StringBuffer();
-
-        // The domain name is replaced with a pointer to a prior
-        // occurrence of the same name in virtual memory packet.
-        while (true) {
-            String data = sVmPacket.get(dnsName);
-            if (data != null) {
-                sb.append(data);
-                break;
-            }
-            int i = dnsName.indexOf('.');
-            if (i == -1) {
-                if (dnsName.length() > 0) {
-                    sb.append(String.format(Locale.US, "%02x", dnsName.length()));
-                    sb.append(WifiP2pServiceInfo.bin2HexStr(dnsName.getBytes()));
-                }
-                // for a sequence of labels ending in a zero octet
-                sb.append("00");
-                break;
-            }
-
-            String name = dnsName.substring(0, i);
-            dnsName = dnsName.substring(i + 1);
-            sb.append(String.format(Locale.US, "%02x", name.length()));
-            sb.append(WifiP2pServiceInfo.bin2HexStr(name.getBytes()));
-        }
-        return sb.toString();
-    }
-}
diff --git a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceRequest.java b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceRequest.java
deleted file mode 100644
index d5415e0..0000000
--- a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceRequest.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p.nsd;
-
-import android.net.wifi.p2p.WifiP2pManager;
-
-/**
- * A class for creating a Bonjour service discovery request for use with
- * {@link WifiP2pManager#addServiceRequest} and {@link WifiP2pManager#removeServiceRequest}
- *
- * {@see WifiP2pManager}
- * {@see WifiP2pServiceRequest}
- * {@see WifiP2pUpnpServiceRequest}
- */
-public class WifiP2pDnsSdServiceRequest extends WifiP2pServiceRequest {
-
-    /**
-     * This constructor is only used in newInstance().
-     *
-     * @param query The part of service specific query.
-     * @hide
-     */
-    private WifiP2pDnsSdServiceRequest(String query) {
-        super(WifiP2pServiceInfo.SERVICE_TYPE_BONJOUR, query);
-    }
-
-    /**
-     * This constructor is only used in newInstance().
-     * @hide
-     */
-    private WifiP2pDnsSdServiceRequest() {
-        super(WifiP2pServiceInfo.SERVICE_TYPE_BONJOUR, null);
-    }
-
-    private WifiP2pDnsSdServiceRequest(String dnsQuery, int dnsType, int version) {
-        super(WifiP2pServiceInfo.SERVICE_TYPE_BONJOUR, WifiP2pDnsSdServiceInfo.createRequest(
-                dnsQuery,
-                dnsType,
-                version));
-    }
-
-    /**
-     * Create a service discovery request to search all Bonjour services.
-     *
-     * @return service request for Bonjour.
-     */
-    public static WifiP2pDnsSdServiceRequest newInstance() {
-        return new WifiP2pDnsSdServiceRequest();
-    }
-
-    /**
-     * Create a service discovery to search for Bonjour services with the specified
-     * service type.
-     *
-     * @param serviceType service type. Cannot be null <br>
-     *  "_afpovertcp._tcp."(Apple File Sharing over TCP)<br>
-     *  "_ipp._tcp" (IP Printing over TCP)<br>
-     *  "_http._tcp" (http service)
-     * @return service request for DnsSd.
-     */
-    public static WifiP2pDnsSdServiceRequest newInstance(String serviceType) {
-        if (serviceType == null) {
-            throw new IllegalArgumentException("service type cannot be null");
-        }
-        return new WifiP2pDnsSdServiceRequest(serviceType + ".local.",
-                WifiP2pDnsSdServiceInfo.DNS_TYPE_PTR,
-                WifiP2pDnsSdServiceInfo.VERSION_1);
-    }
-
-    /**
-     * Create a service discovery request to get the TXT data from the specified
-     * Bonjour service.
-     *
-     * @param instanceName instance name. Cannot be null. <br>
-     *  "MyPrinter"
-     * @param serviceType service type. Cannot be null. <br>
-     * e.g) <br>
-     *  "_afpovertcp._tcp"(Apple File Sharing over TCP)<br>
-     *  "_ipp._tcp" (IP Printing over TCP)<br>
-     * @return service request for Bonjour.
-     */
-    public static WifiP2pDnsSdServiceRequest newInstance(String instanceName,
-            String serviceType) {
-        if (instanceName == null || serviceType == null) {
-            throw new IllegalArgumentException(
-                    "instance name or service type cannot be null");
-        }
-        String fullDomainName = instanceName + "." + serviceType + ".local.";
-        return new WifiP2pDnsSdServiceRequest(fullDomainName,
-                WifiP2pDnsSdServiceInfo.DNS_TYPE_TXT,
-                WifiP2pDnsSdServiceInfo.VERSION_1);
-    }
-}
diff --git a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceResponse.java b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceResponse.java
deleted file mode 100644
index ed84a1a..0000000
--- a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceResponse.java
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p.nsd;
-
-import android.net.wifi.p2p.WifiP2pDevice;
-
-import java.io.ByteArrayInputStream;
-import java.io.DataInputStream;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * A class for a response of bonjour service discovery.
- *
- * @hide
- */
-public class WifiP2pDnsSdServiceResponse extends WifiP2pServiceResponse {
-
-    /**
-     * DNS query name.
-     * e.g)
-     * for PTR
-     * "_ipp._tcp.local."
-     * for TXT
-     * "MyPrinter._ipp._tcp.local."
-     */
-    private String mDnsQueryName;
-
-    /**
-     * Service instance name.
-     * e.g) "MyPrinter"
-     * This field is only used when the dns type equals to
-     * {@link WifiP2pDnsSdServiceInfo#DNS_TYPE_PTR}.
-     */
-    private String mInstanceName;
-
-    /**
-     * DNS Type.
-     * Should be {@link WifiP2pDnsSdServiceInfo#DNS_TYPE_PTR} or
-     * {@link WifiP2pDnsSdServiceInfo#DNS_TYPE_TXT}.
-     */
-    private int mDnsType;
-
-    /**
-     * DnsSd version number.
-     * Should be {@link WifiP2pDnsSdServiceInfo#VERSION_1}.
-     */
-    private int mVersion;
-
-    /**
-     * Txt record.
-     * This field is only used when the dns type equals to
-     * {@link WifiP2pDnsSdServiceInfo#DNS_TYPE_TXT}.
-     */
-    private final HashMap<String, String> mTxtRecord = new HashMap<String, String>();
-
-    /**
-     * Virtual memory packet.
-     * see E.3 of the Wi-Fi Direct technical specification for the detail.<br>
-     * The spec can be obtained from wi-fi.org
-     * Key: pointer Value: domain name.<br>
-     */
-    private final static Map<Integer, String> sVmpack;
-
-    static {
-        sVmpack = new HashMap<Integer, String>();
-        sVmpack.put(0x0c, "_tcp.local.");
-        sVmpack.put(0x11, "local.");
-        sVmpack.put(0x1c, "_udp.local.");
-    }
-
-    /**
-     * Returns query DNS name.
-     * @return DNS name.
-     */
-    public String getDnsQueryName() {
-        return mDnsQueryName;
-    }
-
-    /**
-     * Return query DNS type.
-     * @return DNS type.
-     */
-    public int getDnsType() {
-        return mDnsType;
-    }
-
-    /**
-     * Return bonjour version number.
-     * @return version number.
-     */
-    public int getVersion() {
-        return mVersion;
-    }
-
-    /**
-     * Return instance name.
-     * @return
-     */
-    public String getInstanceName() {
-        return mInstanceName;
-    }
-
-    /**
-     * Return TXT record data.
-     * @return TXT record data.
-     */
-    public Map<String, String> getTxtRecord() {
-        return mTxtRecord;
-    }
-
-    @Override
-    public String toString() {
-        StringBuffer sbuf = new StringBuffer();
-        sbuf.append("serviceType:DnsSd(").append(mServiceType).append(")");
-        sbuf.append(" status:").append(Status.toString(mStatus));
-        sbuf.append(" srcAddr:").append(mDevice.deviceAddress);
-        sbuf.append(" version:").append(String.format("%02x", mVersion));
-        sbuf.append(" dnsName:").append(mDnsQueryName);
-        sbuf.append(" TxtRecord:");
-        for (String key : mTxtRecord.keySet()) {
-            sbuf.append(" key:").append(key).append(" value:").append(mTxtRecord.get(key));
-        }
-        if (mInstanceName != null) {
-            sbuf.append(" InsName:").append(mInstanceName);
-        }
-        return sbuf.toString();
-    }
-
-    /**
-     * This is only used in framework.
-     * @param status status code.
-     * @param dev source device.
-     * @param data RDATA.
-     * @hide
-     */
-    protected WifiP2pDnsSdServiceResponse(int status,
-            int tranId, WifiP2pDevice dev, byte[] data) {
-        super(WifiP2pServiceInfo.SERVICE_TYPE_BONJOUR,
-                status, tranId, dev, data);
-        if (!parse()) {
-            throw new IllegalArgumentException("Malformed bonjour service response");
-        }
-    }
-
-    /**
-     * Parse DnsSd service discovery response.
-     *
-     * @return {@code true} if the operation succeeded
-     */
-    private boolean parse() {
-        /*
-         * The data format from Wi-Fi Direct spec is as follows.
-         * ________________________________________________
-         * |  encoded and compressed dns name (variable)  |
-         * ________________________________________________
-         * |       dnstype(2byte)      |  version(1byte)  |
-         * ________________________________________________
-         * |              RDATA (variable)                |
-         */
-        if (mData == null) {
-            // the empty is OK.
-            return true;
-        }
-
-        DataInputStream dis = new DataInputStream(new ByteArrayInputStream(mData));
-
-        mDnsQueryName = readDnsName(dis);
-        if (mDnsQueryName == null) {
-            return false;
-        }
-
-        try {
-            mDnsType = dis.readUnsignedShort();
-            mVersion = dis.readUnsignedByte();
-        } catch (IOException e) {
-            e.printStackTrace();
-            return false;
-        }
-
-        if (mDnsType == WifiP2pDnsSdServiceInfo.DNS_TYPE_PTR) {
-            String rData = readDnsName(dis);
-            if (rData == null) {
-                return false;
-            }
-            if (rData.length() <= mDnsQueryName.length()) {
-                return false;
-            }
-
-            mInstanceName = rData.substring(0,
-                    rData.length() - mDnsQueryName.length() -1);
-        } else if (mDnsType == WifiP2pDnsSdServiceInfo.DNS_TYPE_TXT) {
-            return readTxtData(dis);
-        } else {
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Read dns name.
-     *
-     * @param dis data input stream.
-     * @return dns name
-     */
-    private String readDnsName(DataInputStream dis) {
-        StringBuffer sb = new StringBuffer();
-
-        // copy virtual memory packet.
-        HashMap<Integer, String> vmpack = new HashMap<Integer, String>(sVmpack);
-        if (mDnsQueryName != null) {
-            vmpack.put(0x27, mDnsQueryName);
-        }
-        try {
-            while (true) {
-                int i = dis.readUnsignedByte();
-                if (i == 0x00) {
-                    return sb.toString();
-                } else if (i == 0xc0) {
-                    // refer to pointer.
-                    String ref = vmpack.get(dis.readUnsignedByte());
-                    if (ref == null) {
-                        //invalid.
-                        return null;
-                    }
-                    sb.append(ref);
-                    return sb.toString();
-                } else {
-                    byte[] data = new byte[i];
-                    dis.readFully(data);
-                    sb.append(new String(data));
-                    sb.append(".");
-                }
-            }
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-        return null;
-    }
-
-    /**
-     * Read TXT record data.
-     *
-     * @param dis
-     * @return true if TXT data is valid
-     */
-    private boolean readTxtData(DataInputStream dis) {
-        try {
-            while (dis.available() > 0) {
-                int len = dis.readUnsignedByte();
-                if (len == 0) {
-                    break;
-                }
-                byte[] data = new byte[len];
-                dis.readFully(data);
-                String[] keyVal = new String(data).split("=");
-                if (keyVal.length != 2) {
-                    return false;
-                }
-                mTxtRecord.put(keyVal[0], keyVal[1]);
-            }
-            return true;
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-        return false;
-    }
-
-    /**
-     * Creates DnsSd service response.
-     *  This is only called from WifiP2pServiceResponse
-     *
-     * @param status status code.
-     * @param dev source device.
-     * @param data DnsSd response data.
-     * @return DnsSd service response data.
-     * @hide
-     */
-    static WifiP2pDnsSdServiceResponse newInstance(int status,
-            int transId, WifiP2pDevice dev, byte[] data) {
-        if (status != WifiP2pServiceResponse.Status.SUCCESS) {
-            return new WifiP2pDnsSdServiceResponse(status,
-                    transId, dev, null);
-        }
-        try {
-            return new WifiP2pDnsSdServiceResponse(status,
-                    transId, dev, data);
-        } catch (IllegalArgumentException e) {
-            e.printStackTrace();
-        }
-        return null;
-    }
-}
diff --git a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.java b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.java
deleted file mode 100644
index 37b442b..0000000
--- a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p.nsd;
-
-import android.compat.annotation.UnsupportedAppUsage;
-import android.os.Build;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * A class for storing service information that is advertised
- * over a Wi-Fi peer-to-peer setup
- *
- * @see WifiP2pUpnpServiceInfo
- * @see WifiP2pDnsSdServiceInfo
- */
-public class WifiP2pServiceInfo implements Parcelable {
-
-    /**
-     * All service protocol types.
-     */
-    public static final int SERVICE_TYPE_ALL             = 0;
-
-    /**
-     * DNS based service discovery protocol.
-     */
-    public static final int SERVICE_TYPE_BONJOUR         = 1;
-
-    /**
-     * UPnP protocol.
-     */
-    public static final int SERVICE_TYPE_UPNP            = 2;
-
-    /**
-     * WS-Discovery protocol
-     * @hide
-     */
-    public static final int SERVICE_TYPE_WS_DISCOVERY    = 3;
-
-    /**
-     * Vendor Specific protocol
-     */
-    public static final int SERVICE_TYPE_VENDOR_SPECIFIC = 255;
-
-    /**
-     * the list of query string for wpa_supplicant
-     *
-     * e.g)
-     * # IP Printing over TCP (PTR) (RDATA=MyPrinter._ipp._tcp.local.)
-     * {"bonjour", "045f697070c00c000c01", "094d795072696e746572c027"
-     *
-     * # IP Printing over TCP (TXT) (RDATA=txtvers=1,pdl=application/postscript)
-     * {"bonjour", "096d797072696e746572045f697070c00c001001",
-     *  "09747874766572733d311a70646c3d6170706c69636174696f6e2f706f7374736372797074"}
-     *
-     * [UPnP]
-     * # UPnP uuid
-     * {"upnp", "10", "uuid:6859dede-8574-59ab-9332-123456789012"}
-     *
-     * # UPnP rootdevice
-     * {"upnp", "10", "uuid:6859dede-8574-59ab-9332-123456789012::upnp:rootdevice"}
-     *
-     * # UPnP device
-     * {"upnp", "10", "uuid:6859dede-8574-59ab-9332-123456789012::urn:schemas-upnp
-     * -org:device:InternetGatewayDevice:1"}
-     *
-     *  # UPnP service
-     * {"upnp", "10", "uuid:6859dede-8574-59ab-9322-123456789012::urn:schemas-upnp
-     * -org:service:ContentDirectory:2"}
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
-    private List<String> mQueryList;
-
-    /**
-     * This is only used in subclass.
-     *
-     * @param queryList query string for wpa_supplicant
-     * @hide
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
-    protected WifiP2pServiceInfo(List<String> queryList) {
-        if (queryList == null) {
-            throw new IllegalArgumentException("query list cannot be null");
-        }
-        mQueryList = queryList;
-    }
-
-   /**
-    * Return the list of the query string for wpa_supplicant.
-    *
-    * @return the list of the query string for wpa_supplicant.
-    * @hide
-    */
-   public List<String> getSupplicantQueryList() {
-       return mQueryList;
-   }
-
-   /**
-    * Converts byte array to hex string.
-    *
-    * @param data
-    * @return hex string.
-    * @hide
-    */
-   static String bin2HexStr(byte[] data) {
-       StringBuffer sb = new StringBuffer();
-
-       for (byte b: data) {
-           String s = null;
-           try {
-               s = Integer.toHexString(b & 0xff);
-           } catch (Exception e) {
-               e.printStackTrace();
-               return null;
-           }
-           //add 0 padding
-           if (s.length() == 1) {
-               sb.append('0');
-           }
-           sb.append(s);
-       }
-       return sb.toString();
-   }
-
-   @Override
-   public boolean equals(Object o) {
-       if (o == this) {
-           return true;
-       }
-       if (!(o instanceof WifiP2pServiceInfo)) {
-           return false;
-       }
-
-       WifiP2pServiceInfo servInfo = (WifiP2pServiceInfo)o;
-       return  mQueryList.equals(servInfo.mQueryList);
-   }
-
-   @Override
-   public int hashCode() {
-       int result = 17;
-       result = 31 * result + (mQueryList == null ? 0 : mQueryList.hashCode());
-       return result;
-   }
-
-    /** Implement the Parcelable interface {@hide} */
-    public int describeContents() {
-        return 0;
-    }
-
-    /** Implement the Parcelable interface {@hide} */
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeStringList(mQueryList);
-    }
-
-    /** Implement the Parcelable interface {@hide} */
-    @UnsupportedAppUsage
-    public static final @android.annotation.NonNull Creator<WifiP2pServiceInfo> CREATOR =
-        new Creator<WifiP2pServiceInfo>() {
-            public WifiP2pServiceInfo createFromParcel(Parcel in) {
-
-                List<String> data = new ArrayList<String>();
-                in.readStringList(data);
-                return new WifiP2pServiceInfo(data);
-            }
-
-            public WifiP2pServiceInfo[] newArray(int size) {
-                return new WifiP2pServiceInfo[size];
-            }
-        };
-}
diff --git a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.java b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.java
deleted file mode 100644
index 68cbb88..0000000
--- a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.java
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p.nsd;
-
-import android.compat.annotation.UnsupportedAppUsage;
-import android.net.wifi.p2p.WifiP2pManager;
-import android.os.Build;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.Locale;
-
-/**
- * A class for creating a service discovery request for use with
- * {@link WifiP2pManager#addServiceRequest} and {@link WifiP2pManager#removeServiceRequest}
- *
- * <p>This class is used to create service discovery request for custom
- * vendor specific service discovery protocol {@link WifiP2pServiceInfo#SERVICE_TYPE_VENDOR_SPECIFIC}
- * or to search all service protocols {@link WifiP2pServiceInfo#SERVICE_TYPE_ALL}.
- *
- * <p>For the purpose of creating a UPnP or Bonjour service request, use
- * {@link WifiP2pUpnpServiceRequest} or {@link WifiP2pDnsSdServiceRequest} respectively.
- *
- * {@see WifiP2pManager}
- * {@see WifiP2pUpnpServiceRequest}
- * {@see WifiP2pDnsSdServiceRequest}
- */
-public class WifiP2pServiceRequest implements Parcelable {
-
-    /**
-     * Service discovery protocol. It's defined in table63 in Wi-Fi Direct specification.
-     */
-    private int mProtocolType;
-
-    /**
-     * The length of the service request TLV.
-     * The value is equal to 2 plus the number of octets in the
-     * query data field.
-     */
-    private int mLength;
-
-    /**
-     * Service transaction ID.
-     * This is a nonzero value used to match the service request/response TLVs.
-     */
-    private int mTransId;
-
-    /**
-     * The hex dump string of query data for the requested service information.
-     *
-     * e.g) DnsSd apple file sharing over tcp (dns name=_afpovertcp._tcp.local.)
-     * 0b5f6166706f766572746370c00c000c01
-     */
-    private String mQuery;
-
-    /**
-     * This constructor is only used in newInstance().
-     *
-     * @param protocolType service discovery protocol.
-     * @param query The part of service specific query.
-     * @hide
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
-    protected WifiP2pServiceRequest(int protocolType, String query) {
-        validateQuery(query);
-
-        mProtocolType = protocolType;
-        mQuery = query;
-        if (query != null) {
-            mLength = query.length()/2 + 2;
-        } else {
-            mLength = 2;
-        }
-    }
-
-    /**
-     * This constructor is only used in Parcelable.
-     *
-     * @param serviceType service discovery type.
-     * @param length the length of service discovery packet.
-     * @param transId the transaction id
-     * @param query The part of service specific query.
-     */
-    private WifiP2pServiceRequest(int serviceType, int length,
-            int transId, String query) {
-        mProtocolType = serviceType;
-        mLength = length;
-        mTransId = transId;
-        mQuery = query;
-    }
-
-    /**
-     * Return transaction id.
-     *
-     * @return transaction id
-     * @hide
-     */
-    public int getTransactionId() {
-        return mTransId;
-    }
-
-    /**
-     * Set transaction id.
-     *
-     * @param id
-     * @hide
-     */
-    public void setTransactionId(int id) {
-        mTransId = id;
-    }
-
-    /**
-     * Return wpa_supplicant request string.
-     *
-     * The format is the hex dump of the following frame.
-     * <pre>
-     * _______________________________________________________________
-     * |        Length (2)        |   Type (1)   | Transaction ID (1) |
-     * |                  Query Data (variable)                       |
-     * </pre>
-     *
-     * @return wpa_supplicant request string.
-     * @hide
-     */
-    public String getSupplicantQuery() {
-        StringBuffer sb = new StringBuffer();
-        // length is retained as little endian format.
-        sb.append(String.format(Locale.US, "%02x", (mLength) & 0xff));
-        sb.append(String.format(Locale.US, "%02x", (mLength >> 8) & 0xff));
-        sb.append(String.format(Locale.US, "%02x", mProtocolType));
-        sb.append(String.format(Locale.US, "%02x", mTransId));
-        if (mQuery != null) {
-            sb.append(mQuery);
-        }
-
-        return sb.toString();
-    }
-
-    /**
-     * Validate query.
-     *
-     * <p>If invalid, throw IllegalArgumentException.
-     * @param query The part of service specific query.
-     */
-    private void validateQuery(String query) {
-        if (query == null) {
-            return;
-        }
-
-        int UNSIGNED_SHORT_MAX = 0xffff;
-        if (query.length()%2 == 1) {
-            throw new IllegalArgumentException(
-                    "query size is invalid. query=" + query);
-        }
-        if (query.length()/2 > UNSIGNED_SHORT_MAX) {
-            throw new IllegalArgumentException(
-                    "query size is too large. len=" + query.length());
-        }
-
-        // check whether query is hex string.
-        query = query.toLowerCase(Locale.ROOT);
-        char[] chars = query.toCharArray();
-        for (char c: chars) {
-            if (!((c >= '0' && c <= '9') ||
-                    (c >= 'a' && c <= 'f'))){
-                throw new IllegalArgumentException(
-                        "query should be hex string. query=" + query);
-            }
-        }
-    }
-
-    /**
-     * Create a service discovery request.
-     *
-     * @param protocolType can be {@link WifiP2pServiceInfo#SERVICE_TYPE_ALL}
-     * or {@link WifiP2pServiceInfo#SERVICE_TYPE_VENDOR_SPECIFIC}.
-     * In order to create a UPnP or Bonjour service request, use
-     * {@link WifiP2pUpnpServiceRequest} or {@link WifiP2pDnsSdServiceRequest}
-     * respectively
-     *
-     * @param queryData hex string that is vendor specific.  Can be null.
-     * @return service discovery request.
-     */
-    public static WifiP2pServiceRequest newInstance(int protocolType, String queryData) {
-        return new WifiP2pServiceRequest(protocolType, queryData);
-    }
-
-    /**
-     * Create a service discovery request.
-     *
-     * @param protocolType can be {@link WifiP2pServiceInfo#SERVICE_TYPE_ALL}
-     * or {@link WifiP2pServiceInfo#SERVICE_TYPE_VENDOR_SPECIFIC}.
-     * In order to create a UPnP or Bonjour service request, use
-     * {@link WifiP2pUpnpServiceRequest} or {@link WifiP2pDnsSdServiceRequest}
-     * respectively
-     *
-     * @return service discovery request.
-     */
-    public static WifiP2pServiceRequest newInstance(int protocolType ) {
-        return new WifiP2pServiceRequest(protocolType, null);
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (o == this) {
-            return true;
-        }
-        if (!(o instanceof WifiP2pServiceRequest)) {
-            return false;
-        }
-
-        WifiP2pServiceRequest req = (WifiP2pServiceRequest)o;
-
-        /*
-         * Not compare transaction id.
-         * Transaction id may be changed on each service discovery operation.
-         */
-        if ((req.mProtocolType != mProtocolType) ||
-                (req.mLength != mLength)) {
-            return false;
-        }
-
-        if (req.mQuery == null && mQuery == null) {
-            return true;
-        } else if (req.mQuery != null) {
-            return req.mQuery.equals(mQuery);
-        }
-        return false;
-   }
-
-    @Override
-    public int hashCode() {
-        int result = 17;
-        result = 31 * result + mProtocolType;
-        result = 31 * result + mLength;
-        result = 31 * result + (mQuery == null ? 0 : mQuery.hashCode());
-        return result;
-    }
-
-    /** Implement the Parcelable interface {@hide} */
-    public int describeContents() {
-        return 0;
-    }
-
-    /** Implement the Parcelable interface {@hide} */
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mProtocolType);
-        dest.writeInt(mLength);
-        dest.writeInt(mTransId);
-        dest.writeString(mQuery);
-    }
-
-    /** Implement the Parcelable interface {@hide} */
-    @UnsupportedAppUsage
-    public static final @android.annotation.NonNull Creator<WifiP2pServiceRequest> CREATOR =
-        new Creator<WifiP2pServiceRequest>() {
-            public WifiP2pServiceRequest createFromParcel(Parcel in) {
-                int servType = in.readInt();
-                int length = in.readInt();
-                int transId = in.readInt();
-                String query = in.readString();
-                return new WifiP2pServiceRequest(servType, length, transId, query);
-            }
-
-            public WifiP2pServiceRequest[] newArray(int size) {
-                return new WifiP2pServiceRequest[size];
-            }
-        };
-}
diff --git a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceResponse.java b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceResponse.java
deleted file mode 100644
index 1b9c080..0000000
--- a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceResponse.java
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p.nsd;
-
-import android.net.wifi.p2p.WifiP2pDevice;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.io.ByteArrayInputStream;
-import java.io.DataInputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * The class for a response of service discovery.
- *
- * @hide
- */
-public class WifiP2pServiceResponse implements Parcelable {
-
-    private static int MAX_BUF_SIZE = 1024;
-
-    /**
-     * Service type. It's defined in table63 in Wi-Fi Direct specification.
-     */
-    protected int mServiceType;
-
-    /**
-     * Status code of service discovery response.
-     * It's defined in table65 in Wi-Fi Direct specification.
-     * @see Status
-     */
-    protected int mStatus;
-
-    /**
-     * Service transaction ID.
-     * This is a nonzero value used to match the service request/response TLVs.
-     */
-    protected int mTransId;
-
-    /**
-     * Source device.
-     */
-    protected WifiP2pDevice mDevice;
-
-    /**
-     * Service discovery response data based on the requested on
-     * the service protocol type. The protocol format depends on the service type.
-     */
-    protected byte[] mData;
-
-
-    /**
-     * The status code of service discovery response.
-     * Currently 4 status codes are defined and the status codes from  4 to 255
-     * are reserved.
-     *
-     * See Wi-Fi Direct specification for the detail.
-     */
-    public static class Status {
-        /** success */
-        public static final int SUCCESS = 0;
-
-        /** the service protocol type is not available */
-        public static final int SERVICE_PROTOCOL_NOT_AVAILABLE = 1;
-
-        /** the requested information is not available */
-        public static final int REQUESTED_INFORMATION_NOT_AVAILABLE = 2;
-
-        /** bad request */
-        public static final int BAD_REQUEST = 3;
-
-        /** @hide */
-        public static String toString(int status) {
-            switch(status) {
-            case SUCCESS:
-                return "SUCCESS";
-            case SERVICE_PROTOCOL_NOT_AVAILABLE:
-                return "SERVICE_PROTOCOL_NOT_AVAILABLE";
-            case REQUESTED_INFORMATION_NOT_AVAILABLE:
-                return "REQUESTED_INFORMATION_NOT_AVAILABLE";
-            case BAD_REQUEST:
-                return "BAD_REQUEST";
-            default:
-                return "UNKNOWN";
-            }
-        }
-
-        /** not used */
-        private Status() {}
-    }
-
-    /**
-     * Hidden constructor. This is only used in framework.
-     *
-     * @param serviceType service discovery type.
-     * @param status status code.
-     * @param transId transaction id.
-     * @param device source device.
-     * @param data query data.
-     */
-    protected WifiP2pServiceResponse(int serviceType, int status, int transId,
-            WifiP2pDevice device, byte[] data) {
-        mServiceType = serviceType;
-        mStatus = status;
-        mTransId = transId;
-        mDevice = device;
-        mData = data;
-    }
-
-    /**
-     * Return the service type of service discovery response.
-     *
-     * @return service discovery type.<br>
-     * e.g) {@link WifiP2pServiceInfo#SERVICE_TYPE_BONJOUR}
-     */
-    public int getServiceType() {
-        return mServiceType;
-    }
-
-    /**
-     * Return the status code of service discovery response.
-     *
-     * @return status code.
-     * @see Status
-     */
-    public int getStatus() {
-        return mStatus;
-    }
-
-    /**
-     * Return the transaction id of service discovery response.
-     *
-     * @return transaction id.
-     * @hide
-     */
-    public int getTransactionId() {
-        return mTransId;
-    }
-
-    /**
-     * Return response data.
-     *
-     * <pre>Data format depends on service type
-     *
-     * @return a query or response data.
-     */
-    public byte[] getRawData() {
-        return mData;
-    }
-
-    /**
-     * Returns the source device of service discovery response.
-     *
-     * <pre>This is valid only when service discovery response.
-     *
-     * @return the source device of service discovery response.
-     */
-    public WifiP2pDevice getSrcDevice() {
-        return mDevice;
-    }
-
-    /** @hide */
-    public void setSrcDevice(WifiP2pDevice dev) {
-        if (dev == null) return;
-        this.mDevice = dev;
-    }
-
-
-    /**
-     * Create the list of  WifiP2pServiceResponse instance from supplicant event.
-     *
-     * @param srcAddr source address of the service response
-     * @param tlvsBin byte array containing the binary tlvs data
-     * @return if parse failed, return null
-     * @hide
-     */
-    public static List<WifiP2pServiceResponse> newInstance(String srcAddr, byte[] tlvsBin) {
-        //updateIndicator not used, and not passed up from supplicant
-
-        List<WifiP2pServiceResponse> respList = new ArrayList<WifiP2pServiceResponse>();
-        WifiP2pDevice dev = new WifiP2pDevice();
-        dev.deviceAddress = srcAddr;
-        if (tlvsBin == null) {
-            return null;
-        }
-
-
-        DataInputStream dis = new DataInputStream(new ByteArrayInputStream(tlvsBin));
-        try {
-            while (dis.available() > 0) {
-                /*
-                 * Service discovery header is as follows.
-                 * ______________________________________________________________
-                 * |           Length(2byte)     | Type(1byte) | TransId(1byte)}|
-                 * ______________________________________________________________
-                 * | status(1byte)  |            vendor specific(variable)      |
-                 */
-                // The length equals to 3 plus the number of octets in the vendor
-                // specific content field. And this is little endian.
-                int length = (dis.readUnsignedByte() +
-                        (dis.readUnsignedByte() << 8)) - 3;
-                int type = dis.readUnsignedByte();
-                int transId = dis.readUnsignedByte();
-                int status = dis.readUnsignedByte();
-                if (length < 0) {
-                    return null;
-                }
-                if (length == 0) {
-                    if (status == Status.SUCCESS) {
-                        respList.add(new WifiP2pServiceResponse(type, status,
-                            transId, dev, null));
-                    }
-                    continue;
-                }
-                if (length > MAX_BUF_SIZE) {
-                    dis.skip(length);
-                    continue;
-                }
-                byte[] data = new byte[length];
-                dis.readFully(data);
-
-                WifiP2pServiceResponse resp;
-                if (type ==  WifiP2pServiceInfo.SERVICE_TYPE_BONJOUR) {
-                    resp = WifiP2pDnsSdServiceResponse.newInstance(status,
-                            transId, dev, data);
-                } else if (type == WifiP2pServiceInfo.SERVICE_TYPE_UPNP) {
-                    resp = WifiP2pUpnpServiceResponse.newInstance(status,
-                            transId, dev, data);
-                } else {
-                    resp = new WifiP2pServiceResponse(type, status, transId, dev, data);
-                }
-                if (resp != null && resp.getStatus() == Status.SUCCESS) {
-                    respList.add(resp);
-                }
-            }
-            return respList;
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-
-        if (respList.size() > 0) {
-            return respList;
-        }
-        return null;
-    }
-
-    /**
-     * Converts hex string to byte array.
-     *
-     * @param hex hex string. if invalid, return null.
-     * @return binary data.
-     */
-    private static byte[] hexStr2Bin(String hex) {
-        int sz = hex.length()/2;
-        byte[] b = new byte[hex.length()/2];
-
-        for (int i=0;i<sz;i++) {
-            try {
-                b[i] = (byte)Integer.parseInt(hex.substring(i*2, i*2+2), 16);
-            } catch (Exception e) {
-                e.printStackTrace();
-                return null;
-            }
-        }
-        return b;
-    }
-
-    @Override
-    public String toString() {
-        StringBuffer sbuf = new StringBuffer();
-        sbuf.append("serviceType:").append(mServiceType);
-        sbuf.append(" status:").append(Status.toString(mStatus));
-        sbuf.append(" srcAddr:").append(mDevice.deviceAddress);
-        sbuf.append(" data:").append(Arrays.toString(mData));
-        return sbuf.toString();
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (o == this) {
-            return true;
-        }
-        if (!(o instanceof WifiP2pServiceResponse)) {
-            return false;
-        }
-
-        WifiP2pServiceResponse req = (WifiP2pServiceResponse)o;
-
-        return (req.mServiceType == mServiceType) &&
-            (req.mStatus == mStatus) &&
-                equals(req.mDevice.deviceAddress, mDevice.deviceAddress) &&
-                Arrays.equals(req.mData, mData);
-    }
-
-    private boolean equals(Object a, Object b) {
-        if (a == null && b == null) {
-            return true;
-        } else if (a != null) {
-            return a.equals(b);
-        }
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        int result = 17;
-        result = 31 * result + mServiceType;
-        result = 31 * result + mStatus;
-        result = 31 * result + mTransId;
-        result = 31 * result + (mDevice.deviceAddress == null ?
-                0 : mDevice.deviceAddress.hashCode());
-        result = 31 * result + (mData == null ? 0 : Arrays.hashCode(mData));
-        return result;
-    }
-
-    /** Implement the Parcelable interface {@hide} */
-    public int describeContents() {
-        return 0;
-    }
-
-    /** Implement the Parcelable interface {@hide} */
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mServiceType);
-        dest.writeInt(mStatus);
-        dest.writeInt(mTransId);
-        dest.writeParcelable(mDevice, flags);
-        if (mData == null || mData.length == 0) {
-            dest.writeInt(0);
-        } else {
-            dest.writeInt(mData.length);
-            dest.writeByteArray(mData);
-        }
-    }
-
-    /** Implement the Parcelable interface {@hide} */
-    public static final @android.annotation.NonNull Creator<WifiP2pServiceResponse> CREATOR =
-        new Creator<WifiP2pServiceResponse>() {
-            public WifiP2pServiceResponse createFromParcel(Parcel in) {
-
-                int type = in.readInt();
-                int status = in.readInt();
-                int transId = in.readInt();
-                WifiP2pDevice dev = (WifiP2pDevice)in.readParcelable(null);
-                int len = in.readInt();
-                byte[] data = null;
-                if (len > 0) {
-                    data = new byte[len];
-                    in.readByteArray(data);
-                }
-                if (type ==  WifiP2pServiceInfo.SERVICE_TYPE_BONJOUR) {
-                    return WifiP2pDnsSdServiceResponse.newInstance(status,
-                            transId, dev, data);
-                } else if (type == WifiP2pServiceInfo.SERVICE_TYPE_UPNP) {
-                    return WifiP2pUpnpServiceResponse.newInstance(status,
-                            transId, dev, data);
-                }
-                return new WifiP2pServiceResponse(type, status, transId, dev, data);
-            }
-
-            public WifiP2pServiceResponse[] newArray(int size) {
-                return new WifiP2pServiceResponse[size];
-            }
-        };
-}
diff --git a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceInfo.java b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceInfo.java
deleted file mode 100644
index a4cdfd9..0000000
--- a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceInfo.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p.nsd;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Locale;
-import java.util.UUID;
-
-/**
- * A class for storing Upnp service information that is advertised
- * over a Wi-Fi peer-to-peer setup.
- *
- * {@see android.net.wifi.p2p.WifiP2pManager#addLocalService}
- * {@see android.net.wifi.p2p.WifiP2pManager#removeLocalService}
- * {@see WifiP2pServiceInfo}
- * {@see WifiP2pDnsSdServiceInfo}
- */
-public class WifiP2pUpnpServiceInfo extends WifiP2pServiceInfo {
-
-    /**
-     * UPnP version 1.0.
-     *
-     * <pre>Query Version should always be set to 0x10 if the query values are
-     * compatible with UPnP Device Architecture 1.0.
-     * @hide
-     */
-    public static final int VERSION_1_0 = 0x10;
-
-    /**
-     * This constructor is only used in newInstance().
-     *
-     * @param queryList
-     */
-    private WifiP2pUpnpServiceInfo(List<String> queryList) {
-        super(queryList);
-    }
-
-    /**
-     * Create UPnP service information object.
-     *
-     * @param uuid a string representation of this UUID in the following format,
-     *  as per <a href="http://www.ietf.org/rfc/rfc4122.txt">RFC 4122</a>.<br>
-     *  e.g) 6859dede-8574-59ab-9332-123456789012
-     * @param device a string representation of this device in the following format,
-     * as per
-     * <a href="http://www.upnp.org/specs/arch/UPnP-arch-DeviceArchitecture-v1.1.pdf">
-     *  UPnP Device Architecture1.1</a><br>
-     *  e.g) urn:schemas-upnp-org:device:MediaServer:1
-     * @param services a string representation of this service in the following format,
-     * as per
-     * <a href="http://www.upnp.org/specs/arch/UPnP-arch-DeviceArchitecture-v1.1.pdf">
-     *  UPnP Device Architecture1.1</a><br>
-     *  e.g) urn:schemas-upnp-org:service:ContentDirectory:1
-     * @return UPnP service information object.
-     */
-    public static WifiP2pUpnpServiceInfo newInstance(String uuid,
-            String device, List<String> services) {
-        if (uuid == null || device == null) {
-            throw new IllegalArgumentException("uuid or device cannnot be null");
-        }
-        UUID.fromString(uuid);
-
-        ArrayList<String> info = new ArrayList<String>();
-
-        info.add(createSupplicantQuery(uuid, null));
-        info.add(createSupplicantQuery(uuid, "upnp:rootdevice"));
-        info.add(createSupplicantQuery(uuid, device));
-        if (services != null) {
-            for (String service:services) {
-                info.add(createSupplicantQuery(uuid, service));
-            }
-        }
-
-        return new WifiP2pUpnpServiceInfo(info);
-    }
-
-    /**
-     * Create wpa_supplicant service query for upnp.
-     *
-     * @param uuid
-     * @param data
-     * @return wpa_supplicant service query for upnp
-     */
-    private static String createSupplicantQuery(String uuid, String data) {
-        StringBuffer sb = new StringBuffer();
-        sb.append("upnp ");
-        sb.append(String.format(Locale.US, "%02x ", VERSION_1_0));
-        sb.append("uuid:");
-        sb.append(uuid);
-        if (data != null) {
-            sb.append("::");
-            sb.append(data);
-        }
-        return sb.toString();
-    }
-}
diff --git a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceRequest.java b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceRequest.java
deleted file mode 100644
index 98e447e..0000000
--- a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceRequest.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p.nsd;
-
-import android.net.wifi.p2p.WifiP2pManager;
-
-import java.util.Locale;
-
-/**
- * A class for creating a Upnp service discovery request for use with
- * {@link WifiP2pManager#addServiceRequest} and {@link WifiP2pManager#removeServiceRequest}
- *
- * {@see WifiP2pManager}
- * {@see WifiP2pServiceRequest}
- * {@see WifiP2pDnsSdServiceRequest}
- */
-public class WifiP2pUpnpServiceRequest extends WifiP2pServiceRequest {
-
-    /**
-     * This constructor is only used in newInstance().
-     *
-     * @param query The part of service specific query.
-     * @hide
-     */
-    protected WifiP2pUpnpServiceRequest(String query) {
-        super(WifiP2pServiceInfo.SERVICE_TYPE_UPNP, query);
-    }
-
-    /**
-     * This constructor is only used in newInstance().
-     * @hide
-     */
-    protected WifiP2pUpnpServiceRequest() {
-        super(WifiP2pServiceInfo.SERVICE_TYPE_UPNP, null);
-    }
-
-    /**
-     * Create a service discovery request to search all UPnP services.
-     *
-     * @return service request for UPnP.
-     */
-    public static WifiP2pUpnpServiceRequest newInstance() {
-        return new WifiP2pUpnpServiceRequest();
-    }
-    /**
-     * Create a service discovery request to search specified UPnP services.
-     *
-     * @param st ssdp search target.  Cannot be null.<br>
-     * e.g ) <br>
-     * <ul>
-     * <li>"ssdp:all"
-     * <li>"upnp:rootdevice"
-     * <li>"urn:schemas-upnp-org:device:MediaServer:2"
-     * <li>"urn:schemas-upnp-org:service:ContentDirectory:2"
-     * <li>"uuid:6859dede-8574-59ab-9332-123456789012"
-     * </ul>
-     * @return service request for UPnP.
-     */
-    public static WifiP2pUpnpServiceRequest newInstance(String st) {
-        if (st == null) {
-            throw new IllegalArgumentException("search target cannot be null");
-        }
-        StringBuffer sb = new StringBuffer();
-        sb.append(String.format(Locale.US, "%02x", WifiP2pUpnpServiceInfo.VERSION_1_0));
-        sb.append(WifiP2pServiceInfo.bin2HexStr(st.getBytes()));
-        return new WifiP2pUpnpServiceRequest(sb.toString());
-    }
-}
diff --git a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceResponse.java b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceResponse.java
deleted file mode 100644
index ab95af6f6..0000000
--- a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceResponse.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p.nsd;
-
-import android.net.wifi.p2p.WifiP2pDevice;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * A class for a response of upnp service discovery.
- *
- * @hide
- */
-public class WifiP2pUpnpServiceResponse extends WifiP2pServiceResponse {
-
-    /**
-     * UPnP version. should be {@link WifiP2pUpnpServiceInfo#VERSION_1_0}
-     */
-    private int mVersion;
-
-    /**
-     * The list of Unique Service Name.
-     * e.g)
-     *{"uuid:6859dede-8574-59ab-9332-123456789012",
-     *"uuid:6859dede-8574-59ab-9332-123456789012::upnp:rootdevice"}
-     */
-    private List<String> mUniqueServiceNames;
-
-    /**
-     * Return UPnP version number.
-     *
-     * @return version number.
-     * @see WifiP2pUpnpServiceInfo#VERSION_1_0
-     */
-    public int getVersion() {
-        return mVersion;
-    }
-
-    /**
-     * Return Unique Service Name strings.
-     *
-     * @return Unique Service Name.<br>
-     * e.g ) <br>
-     * <ul>
-     * <li>"uuid:6859dede-8574-59ab-9332-123456789012"
-     * <li>"uuid:6859dede-8574-59ab-9332-123456789012::upnp:rootdevice"
-     * <li>"uuid:6859dede-8574-59ab-9332-123456789012::urn:schemas-upnp-org:device:
-     * MediaServer:2"
-     * <li>"uuid:6859dede-8574-59ab-9332-123456789012::urn:schemas-upnp-org:service:
-     * ContentDirectory:2"
-     * </ul>
-     */
-    public List<String> getUniqueServiceNames() {
-        return mUniqueServiceNames;
-    }
-
-    /**
-     * hidden constructor.
-     *
-     * @param status status code
-     * @param transId transaction id
-     * @param dev source device
-     * @param data UPnP response data.
-     */
-    protected WifiP2pUpnpServiceResponse(int status,
-            int transId, WifiP2pDevice dev, byte[] data) {
-        super(WifiP2pServiceInfo.SERVICE_TYPE_UPNP,
-                status, transId, dev, data);
-        if (!parse()) {
-            throw new IllegalArgumentException("Malformed upnp service response");
-        }
-    }
-
-    /**
-     * Parse UPnP service discovery response
-     *
-     * @return {@code true} if the operation succeeded
-     */
-    private boolean parse() {
-        /*
-         * The data format is as follows.
-         *
-         * ______________________________________________________
-         * |  Version (1)  |          USN (Variable)            |
-         */
-        if (mData == null) {
-            // the empty is OK.
-            return true;
-        }
-
-        if (mData.length < 1) {
-            return false;
-        }
-
-        mVersion = mData[0] & 0xff;
-        String[] names = new String(mData, 1, mData.length-1).split(",");
-        mUniqueServiceNames = new ArrayList<String>();
-        for (String name : names) {
-            mUniqueServiceNames.add(name);
-        }
-        return true;
-    }
-
-    @Override
-    public String toString() {
-        StringBuffer sbuf = new StringBuffer();
-        sbuf.append("serviceType:UPnP(").append(mServiceType).append(")");
-        sbuf.append(" status:").append(Status.toString(mStatus));
-        sbuf.append(" srcAddr:").append(mDevice.deviceAddress);
-        sbuf.append(" version:").append(String.format("%02x", mVersion));
-        if (mUniqueServiceNames != null) {
-            for (String name : mUniqueServiceNames) {
-                sbuf.append(" usn:").append(name);
-            }
-        }
-        return sbuf.toString();
-    }
-
-    /**
-     * Create upnp service response.
-     *
-     * <pre>This is only used in{@link WifiP2pServiceResponse}
-     *
-     * @param status status code.
-     * @param transId transaction id.
-     * @param device source device.
-     * @param data UPnP response data.
-     * @return UPnP service response data.
-     * @hide
-     */
-    static WifiP2pUpnpServiceResponse newInstance(int status,
-            int transId, WifiP2pDevice device, byte[] data) {
-        if (status != WifiP2pServiceResponse.Status.SUCCESS) {
-            return new WifiP2pUpnpServiceResponse(status, transId, device, null);
-        }
-
-        try {
-            return new WifiP2pUpnpServiceResponse(status, transId, device, data);
-        } catch (IllegalArgumentException e) {
-            e.printStackTrace();
-        }
-        return null;
-    }
-}
diff --git a/wifi/java/android/net/wifi/p2p/package.html b/wifi/java/android/net/wifi/p2p/package.html
deleted file mode 100644
index 6a5e8e6..0000000
--- a/wifi/java/android/net/wifi/p2p/package.html
+++ /dev/null
@@ -1,68 +0,0 @@
-<HTML>
-<BODY>
-<p>Provides classes to create peer-to-peer (P2P) connections with Wi-Fi Direct.</p>
-
-<p>Using these APIs, you can discover and connect to other devices when each
-device supports Wi-Fi Direct, then communicate over a speedy connection across distances much longer
-than a Bluetooth connection. The primary class you need to work with is {@link
-android.net.wifi.p2p.WifiP2pManager}, which you can acquire by calling {@link
-android.app.Activity#getSystemService getSystemService(WIFI_P2P_SERVICE)}. The {@link
-android.net.wifi.p2p.WifiP2pManager} includes APIs that allow you to:</p>
-<ul>
-<li>Initialize your application for P2P connections by calling {@link
-android.net.wifi.p2p.WifiP2pManager#initialize initialize()}</li>
-
-<li>Discover nearby devices by calling {@link android.net.wifi.p2p.WifiP2pManager#discoverPeers
-discoverPeers()}</li>
-
-<li>Start a P2P connection by calling {@link android.net.wifi.p2p.WifiP2pManager#connect
-connect()}</li>
-<li>And more</li>
-</ul>
-
-<p>Several other interfaces and classes are necessary as well, such as:</p>
-<ul>
-<li>The {@link android.net.wifi.p2p.WifiP2pManager.ActionListener} interface allows you to receive
-callbacks when an operation such as discovering peers or connecting to them succeeds or fails.</li>
-
-<li>{@link android.net.wifi.p2p.WifiP2pManager.PeerListListener} interface allows you to receive
-information about discovered peers. The callback provides a {@link
-android.net.wifi.p2p.WifiP2pDeviceList}, from which you can retrieve a {@link
-android.net.wifi.p2p.WifiP2pDevice} object for each device within range and get information such as
-the device name, address, device type, the WPS configurations the device supports, and more.</li>
-
-<li>The {@link android.net.wifi.p2p.WifiP2pManager.GroupInfoListener} interface allows you to
-receive information about a P2P group. The callback provides a {@link
-android.net.wifi.p2p.WifiP2pGroup} object, which provides group information such as the owner, the
-network name, and passphrase.</li>
-
-<li>{@link android.net.wifi.p2p.WifiP2pManager.ConnectionInfoListener} interface allows you to
-receive information about the current connection. The callback provides a {@link
-android.net.wifi.p2p.WifiP2pInfo} object, which has information such as whether a group has been
-formed and who is the group owner.</li>
-</ul>
-
-<p>In order to use the Wi-Fi P2P APIs, your app must request the following user permissions:</p>
-<ul>
-<li>{@link android.Manifest.permission#ACCESS_WIFI_STATE}</li>
-<li>{@link android.Manifest.permission#CHANGE_WIFI_STATE}</li>
-<li>{@link android.Manifest.permission#INTERNET} (although your app doesn’t technically connect
-to the Internet, communicating to Wi-Fi Direct peers with standard java sockets requires Internet
-permission).</li>
-</ul>
-
-<p>For example code, see the <a href="{@docRoot}resources/samples/WiFiDirectDemo/index.html">Wi-Fi
-Direct Demo</a> sample application.</p>
-
-<p class="note"><strong>Note:</strong> Not all Android-powered devices support Wi-Fi
-Direct. If your application uses Wi-Fi Direct, declare so with a <a
-href="{@docRoot}guide/topics/manifest/uses-feature-element.html">{@code <uses-feature>}</a>
-element in the manifest file:</p>
-<pre>
-&lt;manifest ...>
-    &lt;uses-feature android:name="android.hardware.wifi.direct" />
-    ...
-&lt;/manifest>
-</pre>
-</BODY>
-</HTML>
diff --git a/wifi/java/android/net/wifi/package.html b/wifi/java/android/net/wifi/package.html
deleted file mode 100644
index b21d39d0..0000000
--- a/wifi/java/android/net/wifi/package.html
+++ /dev/null
@@ -1,29 +0,0 @@
-<HTML>
-<BODY>
-<p>Provides classes to manage Wi-Fi functionality on the device.</p>
-<p>The Wi-Fi APIs provide a means by which applications can communicate 
-with the lower-level wireless stack that provides Wi-Fi network access. Almost all
-information from the device supplicant is available, including the connected network's
-link speed, IP address, negotiation state, and more, plus information about other
-networks that are available. Some other API features include the ability to
-scan, add, save, terminate and initiate Wi-Fi connections.</p>
-
-<p>Some APIs may require the following user permissions:</p>
-<ul>
-  <li>{@link android.Manifest.permission#ACCESS_WIFI_STATE}</li>
-  <li>{@link android.Manifest.permission#CHANGE_WIFI_STATE}</li>
-  <li>{@link android.Manifest.permission#CHANGE_WIFI_MULTICAST_STATE}</li>
-</ul>
-
-<p class="note"><strong>Note:</strong> Not all Android-powered devices provide Wi-Fi functionality.
-If your application uses Wi-Fi, declare so with a <a
-href="{@docRoot}guide/topics/manifest/uses-feature-element.html">{@code <uses-feature>}</a>
-element in the manifest file:</p>
-<pre>
-&lt;manifest ...>
-    &lt;uses-feature android:name="android.hardware.wifi" />
-    ...
-&lt;/manifest>
-</pre>
-</BODY>
-</HTML>
diff --git a/wifi/java/android/net/wifi/rtt/CivicLocation.java b/wifi/java/android/net/wifi/rtt/CivicLocation.java
deleted file mode 100644
index 1d41177..0000000
--- a/wifi/java/android/net/wifi/rtt/CivicLocation.java
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.rtt;
-
-import android.annotation.Nullable;
-import android.location.Address;
-import android.net.wifi.rtt.CivicLocationKeys.CivicLocationKeysType;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.Parcelable.Creator;
-import android.util.SparseArray;
-
-import java.nio.charset.StandardCharsets;
-import java.util.Locale;
-import java.util.Objects;
-
-/**
- * Decodes the Type Length Value (TLV) elements found in a Location Civic Record as defined by IEEE
- * P802.11-REVmc/D8.0 section 9.4.2.22.13 using the format described in IETF RFC 4776.
- *
- * <p>The TLVs each define a key, value pair for a civic address type such as apt, street, city,
- * county, and country. The class provides a general getter method to extract a value for an element
- * key, returning null if not set.
- *
- * @hide
- */
-public final class CivicLocation implements Parcelable {
-    // Address (class) line indexes
-    private static final int ADDRESS_LINE_0_ROOM_DESK_FLOOR = 0;
-    private static final int ADDRESS_LINE_1_NUMBER_ROAD_SUFFIX_APT = 1;
-    private static final int ADDRESS_LINE_2_CITY = 2;
-    private static final int ADDRESS_LINE_3_STATE_POSTAL_CODE = 3;
-    private static final int ADDRESS_LINE_4_COUNTRY = 4;
-
-    // Buffer management
-    private static final int MIN_CIVIC_BUFFER_SIZE = 3;
-    private static final int MAX_CIVIC_BUFFER_SIZE = 256;
-    private static final int COUNTRY_CODE_LENGTH = 2;
-    private static final int BYTE_MASK = 0xFF;
-    private static final int TLV_TYPE_INDEX = 0;
-    private static final int TLV_LENGTH_INDEX = 1;
-    private static final int TLV_VALUE_INDEX = 2;
-
-    private final boolean mIsValid;
-    private final String mCountryCode; // Two character country code (ISO 3166 standard).
-    private SparseArray<String> mCivicAddressElements =
-            new SparseArray<>(MIN_CIVIC_BUFFER_SIZE);
-
-
-    /**
-     * Constructor
-     *
-     * @param civicTLVs    a byte buffer containing parameters in the form type, length, value
-     * @param countryCode the two letter code defined by the ISO 3166 standard
-     *
-     * @hide
-     */
-    public CivicLocation(@Nullable byte[] civicTLVs, @Nullable String countryCode) {
-        this.mCountryCode = countryCode;
-        if (countryCode == null || countryCode.length() != COUNTRY_CODE_LENGTH) {
-            this.mIsValid = false;
-            return;
-        }
-        boolean isValid = false;
-        if (civicTLVs != null
-                && civicTLVs.length >= MIN_CIVIC_BUFFER_SIZE
-                && civicTLVs.length < MAX_CIVIC_BUFFER_SIZE) {
-            isValid = parseCivicTLVs(civicTLVs);
-        }
-
-        mIsValid = isValid;
-    }
-
-    private CivicLocation(Parcel in) {
-        mIsValid = in.readByte() != 0;
-        mCountryCode = in.readString();
-        mCivicAddressElements = in.readSparseArray(this.getClass().getClassLoader());
-    }
-
-    public static final @android.annotation.NonNull Creator<CivicLocation> CREATOR = new Creator<CivicLocation>() {
-        @Override
-        public CivicLocation createFromParcel(Parcel in) {
-            return new CivicLocation(in);
-        }
-
-        @Override
-        public CivicLocation[] newArray(int size) {
-            return new CivicLocation[size];
-        }
-    };
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel parcel, int flags) {
-        parcel.writeByte((byte) (mIsValid ? 1 : 0));
-        parcel.writeString(mCountryCode);
-        parcel.writeSparseArray((android.util.SparseArray) mCivicAddressElements);
-    }
-
-    /**
-     * Check TLV format and store TLV key/value pairs in this object so they can be queried by key.
-     *
-     * @param civicTLVs the buffer of TLV elements
-     * @return a boolean indicating success of the parsing process
-     */
-    private boolean parseCivicTLVs(byte[] civicTLVs) {
-        int bufferPtr = 0;
-        int bufferLength = civicTLVs.length;
-
-        // Iterate through the sub-elements contained in the LCI IE checking the accumulated
-        // element lengths do not overflow the total buffer length
-        while (bufferPtr < bufferLength) {
-            int civicAddressType = civicTLVs[bufferPtr + TLV_TYPE_INDEX] & BYTE_MASK;
-            int civicAddressTypeLength = civicTLVs[bufferPtr + TLV_LENGTH_INDEX];
-            if (civicAddressTypeLength != 0) {
-                if (bufferPtr + TLV_VALUE_INDEX + civicAddressTypeLength > bufferLength) {
-                    return false;
-                }
-                mCivicAddressElements.put(civicAddressType,
-                        new String(civicTLVs, bufferPtr + TLV_VALUE_INDEX,
-                                civicAddressTypeLength, StandardCharsets.UTF_8));
-            }
-            bufferPtr += civicAddressTypeLength + TLV_VALUE_INDEX;
-        }
-        return true;
-    }
-
-    /**
-     * Getter for the value of a civic Address element type.
-     *
-     * @param key an integer code for the element type key
-     * @return the string value associated with that element type
-     */
-    @Nullable
-    public String getCivicElementValue(@CivicLocationKeysType int key) {
-        return mCivicAddressElements.get(key);
-    }
-
-    /**
-     * Converts a CivicLocation object to a SparseArray.
-     *
-     * @return the SparseArray<string> representation of the CivicLocation
-     */
-    @Nullable
-    public SparseArray<String> toSparseArray() {
-        return mCivicAddressElements;
-    }
-
-    /**
-     * Generates a comma separated string of all the defined elements.
-     *
-     * @return a compiled string representing all elements
-     */
-    @Override
-    public String toString() {
-        return mCivicAddressElements.toString();
-    }
-
-    /**
-     * Converts Civic Location to the best effort Address Object.
-     *
-     * @return the {@link Address} object based on the Civic Location data
-     */
-    @Nullable
-    public Address toAddress() {
-        if (!mIsValid) {
-            return null;
-        }
-        Address address = new Address(Locale.US);
-        String room = formatAddressElement("Room: ", getCivicElementValue(CivicLocationKeys.ROOM));
-        String desk =
-                formatAddressElement(" Desk: ", getCivicElementValue(CivicLocationKeys.DESK));
-        String floor =
-                formatAddressElement(", Flr: ", getCivicElementValue(CivicLocationKeys.FLOOR));
-        String houseNumber = formatAddressElement("", getCivicElementValue(CivicLocationKeys.HNO));
-        String houseNumberSuffix =
-                formatAddressElement("", getCivicElementValue(CivicLocationKeys.HNS));
-        String road =
-                formatAddressElement(" ", getCivicElementValue(
-                        CivicLocationKeys.PRIMARY_ROAD_NAME));
-        String roadSuffix = formatAddressElement(" ", getCivicElementValue(CivicLocationKeys.STS));
-        String apt = formatAddressElement(", Apt: ", getCivicElementValue(CivicLocationKeys.APT));
-        String city = formatAddressElement("", getCivicElementValue(CivicLocationKeys.CITY));
-        String state = formatAddressElement("", getCivicElementValue(CivicLocationKeys.STATE));
-        String postalCode =
-                formatAddressElement(" ", getCivicElementValue(CivicLocationKeys.POSTAL_CODE));
-
-        // Aggregation into common address format
-        String addressLine0 =
-                new StringBuilder().append(room).append(desk).append(floor).toString();
-        String addressLine1 =
-                new StringBuilder().append(houseNumber).append(houseNumberSuffix).append(road)
-                        .append(roadSuffix).append(apt).toString();
-        String addressLine2 = city;
-        String addressLine3 = new StringBuilder().append(state).append(postalCode).toString();
-        String addressLine4 = mCountryCode;
-
-        // Setting Address object line fields by common convention.
-        address.setAddressLine(ADDRESS_LINE_0_ROOM_DESK_FLOOR, addressLine0);
-        address.setAddressLine(ADDRESS_LINE_1_NUMBER_ROAD_SUFFIX_APT, addressLine1);
-        address.setAddressLine(ADDRESS_LINE_2_CITY, addressLine2);
-        address.setAddressLine(ADDRESS_LINE_3_STATE_POSTAL_CODE, addressLine3);
-        address.setAddressLine(ADDRESS_LINE_4_COUNTRY, addressLine4);
-
-        // Other compatible fields between the CIVIC_ADDRESS and the Address Class.
-        address.setFeatureName(getCivicElementValue(CivicLocationKeys.NAM)); // Structure name
-        address.setSubThoroughfare(getCivicElementValue(CivicLocationKeys.HNO));
-        address.setThoroughfare(getCivicElementValue(CivicLocationKeys.PRIMARY_ROAD_NAME));
-        address.setSubLocality(getCivicElementValue(CivicLocationKeys.NEIGHBORHOOD));
-        address.setSubAdminArea(getCivicElementValue(CivicLocationKeys.COUNTY));
-        address.setAdminArea(getCivicElementValue(CivicLocationKeys.STATE));
-        address.setPostalCode(getCivicElementValue(CivicLocationKeys.POSTAL_CODE));
-        address.setCountryCode(mCountryCode); // Country
-        return address;
-    }
-
-    /**
-     * Prepares an address element so that it can be integrated into an address line convention.
-     *
-     * <p>If an address element is null, the return string will be empty e.g. "".
-     *
-     * @param label a string defining the type of address element
-     * @param value a string defining the elements value
-     * @return the formatted version of the value, with null values converted to empty strings
-     */
-    private String formatAddressElement(String label, String value) {
-        if (value != null) {
-            return label + value;
-        } else {
-            return "";
-        }
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (!(obj instanceof CivicLocation)) {
-            return false;
-        }
-        CivicLocation other = (CivicLocation) obj;
-        return mIsValid == other.mIsValid
-                && Objects.equals(mCountryCode, other.mCountryCode)
-                && isSparseArrayStringEqual(mCivicAddressElements, other.mCivicAddressElements);
-    }
-
-    @Override
-    public int hashCode() {
-        int[] civicAddressKeys = getSparseArrayKeys(mCivicAddressElements);
-        String[] civicAddressValues = getSparseArrayValues(mCivicAddressElements);
-        return Objects.hash(mIsValid, mCountryCode, civicAddressKeys, civicAddressValues);
-    }
-
-    /**
-     * Tests if the Civic Location object is valid
-     *
-     * @return a boolean defining mIsValid
-     */
-    public boolean isValid() {
-        return mIsValid;
-    }
-
-    /**
-     * Tests if two sparse arrays are equal on a key for key basis
-     *
-     * @param sa1 the first sparse array
-     * @param sa2 the second sparse array
-     * @return the boolean result after comparing values key by key
-     */
-    private boolean isSparseArrayStringEqual(SparseArray<String> sa1, SparseArray<String> sa2) {
-        int size = sa1.size();
-        if (size != sa2.size()) {
-            return false;
-        }
-        for (int i = 0; i < size; i++) {
-            String sa1Value = sa1.valueAt(i);
-            String sa2Value = sa2.valueAt(i);
-            if (!sa1Value.equals(sa2Value)) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Extract an array of all the keys in a SparseArray<String>
-     *
-     * @param sa the sparse array of Strings
-     * @return an integer array of all keys in the SparseArray<String>
-     */
-    private int[] getSparseArrayKeys(SparseArray<String> sa) {
-        int size = sa.size();
-        int[] keys = new int[size];
-        for (int i = 0; i < size; i++) {
-            keys[i] = sa.keyAt(i);
-        }
-        return keys;
-    }
-
-    /**
-     * Extract an array of all the String values in a SparseArray<String>
-     *
-     * @param sa the sparse array of Strings
-     * @return a String array of all values in the SparseArray<String>
-     */
-    private String[] getSparseArrayValues(SparseArray<String> sa) {
-        int size = sa.size();
-        String[] values = new String[size];
-        for (int i = 0; i < size; i++) {
-            values[i] = sa.valueAt(i);
-        }
-        return values;
-    }
-}
diff --git a/wifi/java/android/net/wifi/rtt/CivicLocationKeys.java b/wifi/java/android/net/wifi/rtt/CivicLocationKeys.java
deleted file mode 100644
index b03f4a9..0000000
--- a/wifi/java/android/net/wifi/rtt/CivicLocationKeys.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.rtt;
-
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import android.annotation.IntDef;
-
-import java.lang.annotation.Retention;
-
-/**
- * Civic Address key types used to define address elements.
- *
- * <p>These keys can be used with {@code ResponderLocation.toCivicLocationSparseArray()}
- * to look-up the corresponding string values.</p>
- */
-public class CivicLocationKeys {
-
-    /**
-     * An enumeration of all civic location keys.
-     *
-     * @hide
-     */
-    @Retention(SOURCE)
-    @IntDef({LANGUAGE, STATE, COUNTY, CITY, BOROUGH, NEIGHBORHOOD, GROUP_OF_STREETS, PRD, POD, STS,
-            HNO, HNS, LMK, LOC, NAM, POSTAL_CODE, BUILDING, APT, FLOOR, ROOM, TYPE_OF_PLACE, PCN,
-            PO_BOX, ADDITIONAL_CODE, DESK, PRIMARY_ROAD_NAME, ROAD_SECTION, BRANCH_ROAD_NAME,
-            SUBBRANCH_ROAD_NAME, STREET_NAME_PRE_MODIFIER, STREET_NAME_POST_MODIFIER, SCRIPT})
-    public @interface CivicLocationKeysType {
-    }
-
-    /** Language key e.g. i-default. */
-    public static final int LANGUAGE = 0;
-    /** Category label A1 key e.g. California. */
-    public static final int STATE = 1;
-    /** Category label A2 key e.g. Marin. */
-    public static final int COUNTY = 2;
-    /** Category label A3 key e.g. San Francisco. */
-    public static final int CITY = 3;
-    /** Category label A4 key e.g. Westminster. */
-    public static final int BOROUGH = 4;
-    /** Category label A5 key e.g. Pacific Heights. */
-    public static final int NEIGHBORHOOD = 5;
-    /** Category label A6 key e.g. University District. */
-    public static final int GROUP_OF_STREETS = 6;
-    // 7 - 15 not defined
-    /** Leading Street direction key e.g. N. */
-    public static final int PRD = 16;
-    /** Trailing street suffix key e.g. SW. */
-    public static final int POD = 17;
-    /** Street suffix or Type key e.g Ave, Platz. */
-    public static final int STS = 18;
-    /** House Number key e.g. 123. */
-    public static final int HNO = 19;
-    /** House number suffix key e.g. A, 1/2. */
-    public static final int HNS = 20;
-    /** Landmark or vanity address key e.g. Golden Gate Bridge. */
-    public static final int LMK = 21;
-    /** Additional Location info key e.g. South Wing. */
-    public static final int LOC = 22;
-    /** Name of residence key e.g. Joe's Barbershop. */
-    public static final int NAM = 23;
-    /** Postal or ZIP code key e.g. 10027-1234. */
-    public static final int POSTAL_CODE = 24;
-    /** Building key e.g. Lincoln Library. */
-    public static final int BUILDING = 25;
-    /** Apartment or suite key e.g. Apt 42. */
-    public static final int APT = 26;
-    /** Floor key e.g. 4. */
-    public static final int FLOOR = 27;
-    /** Room key e.g. 450F. */
-    public static final int ROOM = 28;
-    /** Type of place key e.g. office. */
-    public static final int TYPE_OF_PLACE = 29;
-    /** Postal community name key e.g. Leonia. */
-    public static final int PCN = 30;
-    /** Post Office Box key e.g. 12345. */
-    public static final int PO_BOX = 31;
-    /** Additional Code key e.g. 13203000003. */
-    public static final int ADDITIONAL_CODE = 32;
-    /** Seat, desk, pole, or cubical key e.g. WS 181. */
-    public static final int DESK = 33;
-    /** Primary road name key e.g. Shoreline. */
-    public static final int PRIMARY_ROAD_NAME = 34;
-    /** Road Section key e.g. 14. */
-    public static final int ROAD_SECTION = 35;
-    /** Branch Rd Name key e.g. Lane 7. */
-    public static final int BRANCH_ROAD_NAME = 36;
-    /** Subbranch Rd Name key e.g. Alley 8. */
-    public static final int SUBBRANCH_ROAD_NAME = 37;
-    /** Premodifier key e.g. Old. */
-    public static final int STREET_NAME_PRE_MODIFIER = 38;
-    /** Postmodifier key e.g. Service. */
-    public static final int STREET_NAME_POST_MODIFIER = 39;
-    /** Script key e.g. Latn. */
-    public static final int SCRIPT = 128;
-
-    /** private constructor */
-    private CivicLocationKeys() {}
-}
-
diff --git a/wifi/java/android/net/wifi/rtt/IRttCallback.aidl b/wifi/java/android/net/wifi/rtt/IRttCallback.aidl
deleted file mode 100644
index 578dd1e..0000000
--- a/wifi/java/android/net/wifi/rtt/IRttCallback.aidl
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.rtt;
-
-import android.net.wifi.rtt.RangingResult;
-
-/**
- * Interface for RTT result callback.
- *
- * @hide
- */
-oneway interface IRttCallback
-{
-    /**
-     * Service to manager callback indicating failure.
-     */
-    void onRangingFailure(int status);
-
-    /**
-     * Service to manager callback indicating success and providing results.
-     */
-    void onRangingResults(in List<RangingResult> results);
-}
diff --git a/wifi/java/android/net/wifi/rtt/IWifiRttManager.aidl b/wifi/java/android/net/wifi/rtt/IWifiRttManager.aidl
deleted file mode 100644
index 7c92a6b..0000000
--- a/wifi/java/android/net/wifi/rtt/IWifiRttManager.aidl
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.rtt;
-
-import android.os.WorkSource;
-
-import android.net.wifi.rtt.IRttCallback;
-import android.net.wifi.rtt.RangingRequest;
-
-/**
- * @hide
- */
-interface IWifiRttManager
-{
-    boolean isAvailable();
-    void startRanging(in IBinder binder, in String callingPackage, in String callingFeatureId,
-            in WorkSource workSource, in RangingRequest request, in IRttCallback callback);
-    void cancelRanging(in WorkSource workSource);
-}
diff --git a/wifi/java/android/net/wifi/rtt/RangingRequest.java b/wifi/java/android/net/wifi/rtt/RangingRequest.java
deleted file mode 100644
index 318efa6..0000000
--- a/wifi/java/android/net/wifi/rtt/RangingRequest.java
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.rtt;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.net.MacAddress;
-import android.net.wifi.ScanResult;
-import android.net.wifi.aware.AttachCallback;
-import android.net.wifi.aware.DiscoverySessionCallback;
-import android.net.wifi.aware.IdentityChangedListener;
-import android.net.wifi.aware.PeerHandle;
-import android.net.wifi.aware.WifiAwareManager;
-import android.os.Handler;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.StringJoiner;
-
-/**
- * Defines the ranging request to other devices. The ranging request is built using
- * {@link RangingRequest.Builder}.
- * A ranging request is executed using
- * {@link WifiRttManager#startRanging(RangingRequest, java.util.concurrent.Executor, RangingResultCallback)}.
- * <p>
- * The ranging request is a batch request - specifying a set of devices (specified using
- * {@link RangingRequest.Builder#addAccessPoint(ScanResult)} and
- * {@link RangingRequest.Builder#addAccessPoints(List)}).
- */
-public final class RangingRequest implements Parcelable {
-    private static final int MAX_PEERS = 10;
-
-    /**
-     * Returns the maximum number of peers to range which can be specified in a single {@code
-     * RangingRequest}. The limit applies no matter how the peers are added to the request, e.g.
-     * through {@link RangingRequest.Builder#addAccessPoint(ScanResult)} or
-     * {@link RangingRequest.Builder#addAccessPoints(List)}.
-     *
-     * @return Maximum number of peers.
-     */
-    public static int getMaxPeers() {
-        return MAX_PEERS;
-    }
-
-    /** @hide */
-    public final List<ResponderConfig> mRttPeers;
-
-    /** @hide */
-    private RangingRequest(List<ResponderConfig> rttPeers) {
-        mRttPeers = rttPeers;
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeList(mRttPeers);
-    }
-
-    public static final @android.annotation.NonNull Creator<RangingRequest> CREATOR = new Creator<RangingRequest>() {
-        @Override
-        public RangingRequest[] newArray(int size) {
-            return new RangingRequest[size];
-        }
-
-        @Override
-        public RangingRequest createFromParcel(Parcel in) {
-            return new RangingRequest(in.readArrayList(null));
-        }
-    };
-
-    /** @hide */
-    @Override
-    public String toString() {
-        StringJoiner sj = new StringJoiner(", ", "RangingRequest: mRttPeers=[", "]");
-        for (ResponderConfig rc : mRttPeers) {
-            sj.add(rc.toString());
-        }
-        return sj.toString();
-    }
-
-    /** @hide */
-    public void enforceValidity(boolean awareSupported) {
-        if (mRttPeers.size() > MAX_PEERS) {
-            throw new IllegalArgumentException(
-                    "Ranging to too many peers requested. Use getMaxPeers() API to get limit.");
-        }
-
-        for (ResponderConfig peer: mRttPeers) {
-            if (!peer.isValid(awareSupported)) {
-                throw new IllegalArgumentException("Invalid Responder specification");
-            }
-        }
-    }
-
-    /**
-     * Builder class used to construct {@link RangingRequest} objects.
-     */
-    public static final class Builder {
-        private List<ResponderConfig> mRttPeers = new ArrayList<>();
-
-        /**
-         * Add the device specified by the {@link ScanResult} to the list of devices with
-         * which to measure range. The total number of peers added to a request cannot exceed the
-         * limit specified by {@link #getMaxPeers()}.
-         * <p>
-         * Ranging may not be supported if the Access Point does not support IEEE 802.11mc. Use
-         * {@link ScanResult#is80211mcResponder()} to verify the Access Point's capabilities. If
-         * not supported the result status will be
-         * {@link RangingResult#STATUS_RESPONDER_DOES_NOT_SUPPORT_IEEE80211MC}.
-         *
-         * @param apInfo Information of an Access Point (AP) obtained in a Scan Result.
-         * @return The builder to facilitate chaining
-         *         {@code builder.setXXX(..).setXXX(..)}.
-         */
-        public Builder addAccessPoint(@NonNull ScanResult apInfo) {
-            if (apInfo == null) {
-                throw new IllegalArgumentException("Null ScanResult!");
-            }
-            return addResponder(ResponderConfig.fromScanResult(apInfo));
-        }
-
-        /**
-         * Add the devices specified by the {@link ScanResult}s to the list of devices with
-         * which to measure range. The total number of peers added to a request cannot exceed the
-         * limit specified by {@link #getMaxPeers()}.
-         * <p>
-         * Ranging may not be supported if the Access Point does not support IEEE 802.11mc. Use
-         * {@link ScanResult#is80211mcResponder()} to verify the Access Point's capabilities. If
-         * not supported the result status will be
-         * {@link RangingResult#STATUS_RESPONDER_DOES_NOT_SUPPORT_IEEE80211MC}.
-         *
-         * @param apInfos Information of an Access Points (APs) obtained in a Scan Result.
-         * @return The builder to facilitate chaining
-         *         {@code builder.setXXX(..).setXXX(..)}.
-         */
-        public Builder addAccessPoints(@NonNull List<ScanResult> apInfos) {
-            if (apInfos == null) {
-                throw new IllegalArgumentException("Null list of ScanResults!");
-            }
-            for (ScanResult scanResult : apInfos) {
-                addAccessPoint(scanResult);
-            }
-            return this;
-        }
-
-        /**
-         * Add the device specified by the {@code peerMacAddress} to the list of devices with
-         * which to measure range.
-         * <p>
-         * The MAC address may be obtained out-of-band from a peer Wi-Fi Aware device. A Wi-Fi
-         * Aware device may obtain its MAC address using the {@link IdentityChangedListener}
-         * provided to
-         * {@link WifiAwareManager#attach(AttachCallback, IdentityChangedListener, Handler)}.
-         * <p>
-         * Note: in order to use this API the device must support Wi-Fi Aware
-         * {@link android.net.wifi.aware}. The peer device which is being ranged to must be
-         * configured to publish a service (with any name) with:
-         * <li>Type {@link android.net.wifi.aware.PublishConfig#PUBLISH_TYPE_UNSOLICITED}.
-         * <li>Ranging enabled
-         * {@link android.net.wifi.aware.PublishConfig.Builder#setRangingEnabled(boolean)}.
-         *
-         * @param peerMacAddress The MAC address of the Wi-Fi Aware peer.
-         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
-         */
-        public Builder addWifiAwarePeer(@NonNull MacAddress peerMacAddress) {
-            if (peerMacAddress == null) {
-                throw new IllegalArgumentException("Null peer MAC address");
-            }
-            return addResponder(
-                    ResponderConfig.fromWifiAwarePeerMacAddressWithDefaults(peerMacAddress));
-        }
-
-        /**
-         * Add a device specified by a {@link PeerHandle} to the list of devices with which to
-         * measure range.
-         * <p>
-         * The {@link PeerHandle} may be obtained as part of the Wi-Fi Aware discovery process. E.g.
-         * using {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle, byte[], List)}.
-         * <p>
-         * Note: in order to use this API the device must support Wi-Fi Aware
-         * {@link android.net.wifi.aware}. The peer device which is being ranged to must be
-         * configured to publish a service (with any name) with:
-         * <li>Type {@link android.net.wifi.aware.PublishConfig#PUBLISH_TYPE_UNSOLICITED}.
-         * <li>Ranging enabled
-         * {@link android.net.wifi.aware.PublishConfig.Builder#setRangingEnabled(boolean)}.
-         *
-         * @param peerHandle The peer handler of the peer Wi-Fi Aware device.
-         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
-         */
-        public Builder addWifiAwarePeer(@NonNull PeerHandle peerHandle) {
-            if (peerHandle == null) {
-                throw new IllegalArgumentException("Null peer handler (identifier)");
-            }
-
-            return addResponder(ResponderConfig.fromWifiAwarePeerHandleWithDefaults(peerHandle));
-        }
-
-        /**
-         * Add the Responder device specified by the {@link ResponderConfig} to the list of devices
-         * with which to measure range. The total number of peers added to the request cannot exceed
-         * the limit specified by {@link #getMaxPeers()}.
-         *
-         * @param responder Information on the RTT Responder.
-         * @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
-         *
-         * @hide
-         */
-        @SystemApi
-        public Builder addResponder(@NonNull ResponderConfig responder) {
-            if (responder == null) {
-                throw new IllegalArgumentException("Null Responder!");
-            }
-
-            mRttPeers.add(responder);
-            return this;
-        }
-
-        /**
-         * Build {@link RangingRequest} given the current configurations made on the
-         * builder.
-         */
-        public RangingRequest build() {
-            return new RangingRequest(mRttPeers);
-        }
-    }
-
-    @Override
-    public boolean equals(@Nullable Object o) {
-        if (this == o) {
-            return true;
-        }
-
-        if (!(o instanceof RangingRequest)) {
-            return false;
-        }
-
-        RangingRequest lhs = (RangingRequest) o;
-
-        return mRttPeers.size() == lhs.mRttPeers.size() && mRttPeers.containsAll(lhs.mRttPeers);
-    }
-
-    @Override
-    public int hashCode() {
-        return mRttPeers.hashCode();
-    }
-}
diff --git a/wifi/java/android/net/wifi/rtt/RangingResult.java b/wifi/java/android/net/wifi/rtt/RangingResult.java
deleted file mode 100644
index a065bbc..0000000
--- a/wifi/java/android/net/wifi/rtt/RangingResult.java
+++ /dev/null
@@ -1,438 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.rtt;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.net.MacAddress;
-import android.net.wifi.aware.PeerHandle;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * Ranging result for a request started by
- * {@link WifiRttManager#startRanging(RangingRequest, java.util.concurrent.Executor, RangingResultCallback)}.
- * Results are returned in {@link RangingResultCallback#onRangingResults(List)}.
- * <p>
- * A ranging result is the distance measurement result for a single device specified in the
- * {@link RangingRequest}.
- */
-public final class RangingResult implements Parcelable {
-    private static final String TAG = "RangingResult";
-    private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
-
-    /** @hide */
-    @IntDef({STATUS_SUCCESS, STATUS_FAIL, STATUS_RESPONDER_DOES_NOT_SUPPORT_IEEE80211MC})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface RangeResultStatus {
-    }
-
-    /**
-     * Individual range request status, {@link #getStatus()}. Indicates ranging operation was
-     * successful and distance value is valid.
-     */
-    public static final int STATUS_SUCCESS = 0;
-
-    /**
-     * Individual range request status, {@link #getStatus()}. Indicates ranging operation failed
-     * and the distance value is invalid.
-     */
-    public static final int STATUS_FAIL = 1;
-
-    /**
-     * Individual range request status, {@link #getStatus()}. Indicates that the ranging operation
-     * failed because the specified peer does not support IEEE 802.11mc RTT operations. Support by
-     * an Access Point can be confirmed using
-     * {@link android.net.wifi.ScanResult#is80211mcResponder()}.
-     * <p>
-     * On such a failure, the individual result fields of {@link RangingResult} such as
-     * {@link RangingResult#getDistanceMm()} are invalid.
-     */
-    public static final int STATUS_RESPONDER_DOES_NOT_SUPPORT_IEEE80211MC = 2;
-
-    private final int mStatus;
-    private final MacAddress mMac;
-    private final PeerHandle mPeerHandle;
-    private final int mDistanceMm;
-    private final int mDistanceStdDevMm;
-    private final int mRssi;
-    private final int mNumAttemptedMeasurements;
-    private final int mNumSuccessfulMeasurements;
-    private final byte[] mLci;
-    private final byte[] mLcr;
-    private final ResponderLocation mResponderLocation;
-    private final long mTimestamp;
-
-    /** @hide */
-    public RangingResult(@RangeResultStatus int status, @NonNull MacAddress mac, int distanceMm,
-            int distanceStdDevMm, int rssi, int numAttemptedMeasurements,
-            int numSuccessfulMeasurements, byte[] lci, byte[] lcr,
-            ResponderLocation responderLocation, long timestamp) {
-        mStatus = status;
-        mMac = mac;
-        mPeerHandle = null;
-        mDistanceMm = distanceMm;
-        mDistanceStdDevMm = distanceStdDevMm;
-        mRssi = rssi;
-        mNumAttemptedMeasurements = numAttemptedMeasurements;
-        mNumSuccessfulMeasurements = numSuccessfulMeasurements;
-        mLci = lci == null ? EMPTY_BYTE_ARRAY : lci;
-        mLcr = lcr == null ? EMPTY_BYTE_ARRAY : lcr;
-        mResponderLocation = responderLocation;
-        mTimestamp = timestamp;
-    }
-
-    /** @hide */
-    public RangingResult(@RangeResultStatus int status, PeerHandle peerHandle, int distanceMm,
-            int distanceStdDevMm, int rssi, int numAttemptedMeasurements,
-            int numSuccessfulMeasurements, byte[] lci, byte[] lcr,
-            ResponderLocation responderLocation, long timestamp) {
-        mStatus = status;
-        mMac = null;
-        mPeerHandle = peerHandle;
-        mDistanceMm = distanceMm;
-        mDistanceStdDevMm = distanceStdDevMm;
-        mRssi = rssi;
-        mNumAttemptedMeasurements = numAttemptedMeasurements;
-        mNumSuccessfulMeasurements = numSuccessfulMeasurements;
-        mLci = lci == null ? EMPTY_BYTE_ARRAY : lci;
-        mLcr = lcr == null ? EMPTY_BYTE_ARRAY : lcr;
-        mResponderLocation = responderLocation;
-        mTimestamp = timestamp;
-    }
-
-    /**
-     * @return The status of ranging measurement: {@link #STATUS_SUCCESS} in case of success, and
-     * {@link #STATUS_FAIL} in case of failure.
-     */
-    @RangeResultStatus
-    public int getStatus() {
-        return mStatus;
-    }
-
-    /**
-     * @return The MAC address of the device whose range measurement was requested. Will correspond
-     * to the MAC address of the device in the {@link RangingRequest}.
-     * <p>
-     * Will return a {@code null} for results corresponding to requests issued using a {@code
-     * PeerHandle}, i.e. using the {@link RangingRequest.Builder#addWifiAwarePeer(PeerHandle)} API.
-     */
-    @Nullable
-    public MacAddress getMacAddress() {
-        return mMac;
-    }
-
-    /**
-     * @return The PeerHandle of the device whose reange measurement was requested. Will correspond
-     * to the PeerHandle of the devices requested using
-     * {@link RangingRequest.Builder#addWifiAwarePeer(PeerHandle)}.
-     * <p>
-     * Will return a {@code null} for results corresponding to requests issued using a MAC address.
-     */
-    @Nullable public PeerHandle getPeerHandle() {
-        return mPeerHandle;
-    }
-
-    /**
-     * @return The distance (in mm) to the device specified by {@link #getMacAddress()} or
-     * {@link #getPeerHandle()}.
-     * <p>
-     * Note: the measured distance may be negative for very close devices.
-     * <p>
-     * Only valid if {@link #getStatus()} returns {@link #STATUS_SUCCESS}, otherwise will throw an
-     * exception.
-     */
-    public int getDistanceMm() {
-        if (mStatus != STATUS_SUCCESS) {
-            throw new IllegalStateException(
-                    "getDistanceMm(): invoked on an invalid result: getStatus()=" + mStatus);
-        }
-        return mDistanceMm;
-    }
-
-    /**
-     * @return The standard deviation of the measured distance (in mm) to the device specified by
-     * {@link #getMacAddress()} or {@link #getPeerHandle()}. The standard deviation is calculated
-     * over the measurements executed in a single RTT burst. The number of measurements is returned
-     * by {@link #getNumSuccessfulMeasurements()} - 0 successful measurements indicate that the
-     * standard deviation is not valid (a valid standard deviation requires at least 2 data points).
-     * <p>
-     * Only valid if {@link #getStatus()} returns {@link #STATUS_SUCCESS}, otherwise will throw an
-     * exception.
-     */
-    public int getDistanceStdDevMm() {
-        if (mStatus != STATUS_SUCCESS) {
-            throw new IllegalStateException(
-                    "getDistanceStdDevMm(): invoked on an invalid result: getStatus()=" + mStatus);
-        }
-        return mDistanceStdDevMm;
-    }
-
-    /**
-     * @return The average RSSI, in units of dBm, observed during the RTT measurement.
-     * <p>
-     * Only valid if {@link #getStatus()} returns {@link #STATUS_SUCCESS}, otherwise will throw an
-     * exception.
-     */
-    public int getRssi() {
-        if (mStatus != STATUS_SUCCESS) {
-            throw new IllegalStateException(
-                    "getRssi(): invoked on an invalid result: getStatus()=" + mStatus);
-        }
-        return mRssi;
-    }
-
-    /**
-     * @return The number of attempted measurements used in the RTT exchange resulting in this set
-     * of results. The number of successful measurements is returned by
-     * {@link #getNumSuccessfulMeasurements()} which at most, if there are no errors, will be 1 less
-     * that the number of attempted measurements.
-     * <p>
-     * Only valid if {@link #getStatus()} returns {@link #STATUS_SUCCESS}, otherwise will throw an
-     * exception.
-     */
-    public int getNumAttemptedMeasurements() {
-        if (mStatus != STATUS_SUCCESS) {
-            throw new IllegalStateException(
-                    "getNumAttemptedMeasurements(): invoked on an invalid result: getStatus()="
-                            + mStatus);
-        }
-        return mNumAttemptedMeasurements;
-    }
-
-    /**
-     * @return The number of successful measurements used to calculate the distance and standard
-     * deviation. If the number of successful measurements if 1 then then standard deviation,
-     * returned by {@link #getDistanceStdDevMm()}, is not valid (a 0 is returned for the standard
-     * deviation).
-     * <p>
-     * The total number of measurement attempts is returned by
-     * {@link #getNumAttemptedMeasurements()}. The number of successful measurements will be at
-     * most 1 less then the number of attempted measurements.
-     * <p>
-     * Only valid if {@link #getStatus()} returns {@link #STATUS_SUCCESS}, otherwise will throw an
-     * exception.
-     */
-    public int getNumSuccessfulMeasurements() {
-        if (mStatus != STATUS_SUCCESS) {
-            throw new IllegalStateException(
-                    "getNumSuccessfulMeasurements(): invoked on an invalid result: getStatus()="
-                            + mStatus);
-        }
-        return mNumSuccessfulMeasurements;
-    }
-
-    /**
-     * @return The unverified responder location represented as {@link ResponderLocation} which
-     * captures location information the responder is programmed to broadcast. The responder
-     * location is referred to as unverified, because we are relying on the device/site
-     * administrator to correctly configure its location data.
-     * <p>
-     * Will return a {@code null} when the location information cannot be parsed.
-     * <p>
-     * Only valid if {@link #getStatus()} returns {@link #STATUS_SUCCESS}, otherwise will throw an
-     * exception.
-     */
-    @Nullable
-    public ResponderLocation getUnverifiedResponderLocation() {
-        if (mStatus != STATUS_SUCCESS) {
-            throw new IllegalStateException(
-                    "getUnverifiedResponderLocation(): invoked on an invalid result: getStatus()="
-                            + mStatus);
-        }
-        return mResponderLocation;
-    }
-
-    /**
-     * @return The Location Configuration Information (LCI) as self-reported by the peer. The format
-     * is specified in the IEEE 802.11-2016 specifications, section 9.4.2.22.10.
-     * <p>
-     * Note: the information is NOT validated - use with caution. Consider validating it with
-     * other sources of information before using it.
-     *
-     * @hide
-     */
-    @SystemApi
-    @NonNull
-    public byte[] getLci() {
-        if (mStatus != STATUS_SUCCESS) {
-            throw new IllegalStateException(
-                    "getLci(): invoked on an invalid result: getStatus()=" + mStatus);
-        }
-        return mLci;
-    }
-
-    /**
-     * @return The Location Civic report (LCR) as self-reported by the peer. The format
-     * is specified in the IEEE 802.11-2016 specifications, section 9.4.2.22.13.
-     * <p>
-     * Note: the information is NOT validated - use with caution. Consider validating it with
-     * other sources of information before using it.
-     *
-     * @hide
-     */
-    @SystemApi
-    @NonNull
-    public byte[] getLcr() {
-        if (mStatus != STATUS_SUCCESS) {
-            throw new IllegalStateException(
-                    "getReportedLocationCivic(): invoked on an invalid result: getStatus()="
-                            + mStatus);
-        }
-        return mLcr;
-    }
-
-    /**
-     * @return The timestamp at which the ranging operation was performed. The timestamp is in
-     * milliseconds since boot, including time spent in sleep, corresponding to values provided by
-     * {@link android.os.SystemClock#elapsedRealtime()}.
-     * <p>
-     * Only valid if {@link #getStatus()} returns {@link #STATUS_SUCCESS}, otherwise will throw an
-     * exception.
-     */
-    public long getRangingTimestampMillis() {
-        if (mStatus != STATUS_SUCCESS) {
-            throw new IllegalStateException(
-                    "getRangingTimestampMillis(): invoked on an invalid result: getStatus()="
-                            + mStatus);
-        }
-        return mTimestamp;
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mStatus);
-        if (mMac == null) {
-            dest.writeBoolean(false);
-        } else {
-            dest.writeBoolean(true);
-            mMac.writeToParcel(dest, flags);
-        }
-        if (mPeerHandle == null) {
-            dest.writeBoolean(false);
-        } else {
-            dest.writeBoolean(true);
-            dest.writeInt(mPeerHandle.peerId);
-        }
-        dest.writeInt(mDistanceMm);
-        dest.writeInt(mDistanceStdDevMm);
-        dest.writeInt(mRssi);
-        dest.writeInt(mNumAttemptedMeasurements);
-        dest.writeInt(mNumSuccessfulMeasurements);
-        dest.writeByteArray(mLci);
-        dest.writeByteArray(mLcr);
-        dest.writeParcelable(mResponderLocation, flags);
-        dest.writeLong(mTimestamp);
-    }
-
-    public static final @android.annotation.NonNull Creator<RangingResult> CREATOR = new Creator<RangingResult>() {
-        @Override
-        public RangingResult[] newArray(int size) {
-            return new RangingResult[size];
-        }
-
-        @Override
-        public RangingResult createFromParcel(Parcel in) {
-            int status = in.readInt();
-            boolean macAddressPresent = in.readBoolean();
-            MacAddress mac = null;
-            if (macAddressPresent) {
-                mac = MacAddress.CREATOR.createFromParcel(in);
-            }
-            boolean peerHandlePresent = in.readBoolean();
-            PeerHandle peerHandle = null;
-            if (peerHandlePresent) {
-                peerHandle = new PeerHandle(in.readInt());
-            }
-            int distanceMm = in.readInt();
-            int distanceStdDevMm = in.readInt();
-            int rssi = in.readInt();
-            int numAttemptedMeasurements = in.readInt();
-            int numSuccessfulMeasurements = in.readInt();
-            byte[] lci = in.createByteArray();
-            byte[] lcr = in.createByteArray();
-            ResponderLocation responderLocation =
-                    in.readParcelable(this.getClass().getClassLoader());
-            long timestamp = in.readLong();
-            if (peerHandlePresent) {
-                return new RangingResult(status, peerHandle, distanceMm, distanceStdDevMm, rssi,
-                        numAttemptedMeasurements, numSuccessfulMeasurements, lci, lcr,
-                        responderLocation, timestamp);
-            } else {
-                return new RangingResult(status, mac, distanceMm, distanceStdDevMm, rssi,
-                        numAttemptedMeasurements, numSuccessfulMeasurements, lci, lcr,
-                        responderLocation, timestamp);
-            }
-        }
-    };
-
-    /** @hide */
-    @Override
-    public String toString() {
-        return new StringBuilder("RangingResult: [status=").append(mStatus).append(", mac=").append(
-                mMac).append(", peerHandle=").append(
-                mPeerHandle == null ? "<null>" : mPeerHandle.peerId).append(", distanceMm=").append(
-                mDistanceMm).append(", distanceStdDevMm=").append(mDistanceStdDevMm).append(
-                ", rssi=").append(mRssi).append(", numAttemptedMeasurements=").append(
-                mNumAttemptedMeasurements).append(", numSuccessfulMeasurements=").append(
-                mNumSuccessfulMeasurements).append(", lci=").append(mLci).append(", lcr=").append(
-                mLcr).append(", responderLocation=").append(mResponderLocation)
-                .append(", timestamp=").append(mTimestamp).append("]").toString();
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) {
-            return true;
-        }
-
-        if (!(o instanceof RangingResult)) {
-            return false;
-        }
-
-        RangingResult lhs = (RangingResult) o;
-
-        return mStatus == lhs.mStatus && Objects.equals(mMac, lhs.mMac) && Objects.equals(
-                mPeerHandle, lhs.mPeerHandle) && mDistanceMm == lhs.mDistanceMm
-                && mDistanceStdDevMm == lhs.mDistanceStdDevMm && mRssi == lhs.mRssi
-                && mNumAttemptedMeasurements == lhs.mNumAttemptedMeasurements
-                && mNumSuccessfulMeasurements == lhs.mNumSuccessfulMeasurements
-                && Arrays.equals(mLci, lhs.mLci) && Arrays.equals(mLcr, lhs.mLcr)
-                && mTimestamp == lhs.mTimestamp
-                && Objects.equals(mResponderLocation, lhs.mResponderLocation);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(mStatus, mMac, mPeerHandle, mDistanceMm, mDistanceStdDevMm, mRssi,
-                mNumAttemptedMeasurements, mNumSuccessfulMeasurements, mLci, mLcr,
-                mResponderLocation, mTimestamp);
-    }
-}
diff --git a/wifi/java/android/net/wifi/rtt/RangingResultCallback.java b/wifi/java/android/net/wifi/rtt/RangingResultCallback.java
deleted file mode 100644
index fa7d79e..0000000
--- a/wifi/java/android/net/wifi/rtt/RangingResultCallback.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.rtt;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.List;
-
-/**
- * Base class for ranging result callbacks. Should be extended by applications and set when calling
- * {@link WifiRttManager#startRanging(RangingRequest, java.util.concurrent.Executor, RangingResultCallback)}.
- * If the ranging operation fails in whole (not attempted) then {@link #onRangingFailure(int)}
- * will be called with a failure code. If the ranging operation is performed for each of the
- * requested peers then the {@link #onRangingResults(List)} will be called with the set of
- * results (@link {@link RangingResult}, each of which has its own success/failure code
- * {@link RangingResult#getStatus()}.
- */
-public abstract class RangingResultCallback {
-    /** @hide */
-    @IntDef({STATUS_CODE_FAIL, STATUS_CODE_FAIL_RTT_NOT_AVAILABLE})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface RangingOperationStatus {
-    }
-
-    /**
-     * A failure code for the whole ranging request operation. Indicates a failure.
-     */
-    public static final int STATUS_CODE_FAIL = 1;
-
-    /**
-     * A failure code for the whole ranging request operation. Indicates that the request failed due
-     * to RTT not being available - e.g. Wi-Fi was disabled. Use the
-     * {@link WifiRttManager#isAvailable()} and {@link WifiRttManager#ACTION_WIFI_RTT_STATE_CHANGED}
-     * to track RTT availability.
-     */
-    public static final int STATUS_CODE_FAIL_RTT_NOT_AVAILABLE = 2;
-
-    /**
-     * Called when a ranging operation failed in whole - i.e. no ranging operation to any of the
-     * devices specified in the request was attempted.
-     *
-     * @param code A status code indicating the type of failure.
-     */
-    public abstract void onRangingFailure(@RangingOperationStatus int code);
-
-    /**
-     * Called when a ranging operation was executed. The list of results corresponds to devices
-     * specified in the ranging request.
-     *
-     * @param results List of range measurements, one per requested device.
-     */
-    public abstract void onRangingResults(@NonNull List<RangingResult> results);
-}
diff --git a/wifi/java/android/net/wifi/rtt/ResponderConfig.java b/wifi/java/android/net/wifi/rtt/ResponderConfig.java
deleted file mode 100644
index be4eecc..0000000
--- a/wifi/java/android/net/wifi/rtt/ResponderConfig.java
+++ /dev/null
@@ -1,514 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.rtt;
-
-import static android.net.wifi.ScanResult.InformationElement.EID_EXTENSION_PRESENT;
-import static android.net.wifi.ScanResult.InformationElement.EID_EXT_HE_CAPABILITIES;
-import static android.net.wifi.ScanResult.InformationElement.EID_HT_CAPABILITIES;
-import static android.net.wifi.ScanResult.InformationElement.EID_VHT_CAPABILITIES;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.net.MacAddress;
-import android.net.wifi.ScanResult;
-import android.net.wifi.aware.PeerHandle;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.Log;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Objects;
-
-/**
- * Defines the configuration of an IEEE 802.11mc Responder. The Responder may be an Access Point
- * (AP), a Wi-Fi Aware device, or a manually configured Responder.
- * <p>
- * A Responder configuration may be constructed from a {@link ScanResult} or manually (with the
- * data obtained out-of-band from a peer).
- *
- * @hide
- */
-@SystemApi
-public final class ResponderConfig implements Parcelable {
-    private static final String TAG = "ResponderConfig";
-    private static final int AWARE_BAND_2_DISCOVERY_CHANNEL = 2437;
-
-    /** @hide */
-    @IntDef({RESPONDER_AP, RESPONDER_STA, RESPONDER_P2P_GO, RESPONDER_P2P_CLIENT, RESPONDER_AWARE})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface ResponderType {
-    }
-
-    /**
-     * Responder is an AP.
-     */
-    public static final int RESPONDER_AP = 0;
-    /**
-     * Responder is a STA.
-     */
-    public static final int RESPONDER_STA = 1;
-    /**
-     * Responder is a Wi-Fi Direct Group Owner (GO).
-     */
-    public static final int RESPONDER_P2P_GO = 2;
-    /**
-     * Responder is a Wi-Fi Direct Group Client.
-     */
-    public static final int RESPONDER_P2P_CLIENT = 3;
-    /**
-     * Responder is a Wi-Fi Aware device.
-     */
-    public static final int RESPONDER_AWARE = 4;
-
-
-    /** @hide */
-    @IntDef({
-            CHANNEL_WIDTH_20MHZ, CHANNEL_WIDTH_40MHZ, CHANNEL_WIDTH_80MHZ, CHANNEL_WIDTH_160MHZ,
-            CHANNEL_WIDTH_80MHZ_PLUS_MHZ})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface ChannelWidth {
-    }
-
-    /**
-     * Channel bandwidth is 20 MHZ
-     */
-    public static final int CHANNEL_WIDTH_20MHZ = 0;
-    /**
-     * Channel bandwidth is 40 MHZ
-     */
-    public static final int CHANNEL_WIDTH_40MHZ = 1;
-    /**
-     * Channel bandwidth is 80 MHZ
-     */
-    public static final int CHANNEL_WIDTH_80MHZ = 2;
-    /**
-     * Channel bandwidth is 160 MHZ
-     */
-    public static final int CHANNEL_WIDTH_160MHZ = 3;
-    /**
-     * Channel bandwidth is 160 MHZ, but 80MHZ + 80MHZ
-     */
-    public static final int CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 4;
-
-    /** @hide */
-    @IntDef({PREAMBLE_LEGACY, PREAMBLE_HT, PREAMBLE_VHT, PREAMBLE_HE})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface PreambleType {
-    }
-
-    /**
-     * Preamble type: Legacy.
-     */
-    public static final int PREAMBLE_LEGACY = 0;
-
-    /**
-     * Preamble type: HT.
-     */
-    public static final int PREAMBLE_HT = 1;
-
-    /**
-     * Preamble type: VHT.
-     */
-    public static final int PREAMBLE_VHT = 2;
-
-    /**
-     * Preamble type: HE.
-     */
-    public static final int PREAMBLE_HE = 3;
-
-    /**
-     * The MAC address of the Responder. Will be null if a Wi-Fi Aware peer identifier (the
-     * peerHandle field) ise used to identify the Responder.
-     */
-    public final MacAddress macAddress;
-
-    /**
-     * The peer identifier of a Wi-Fi Aware Responder. Will be null if a MAC Address (the macAddress
-     * field) is used to identify the Responder.
-     */
-    public final PeerHandle peerHandle;
-
-    /**
-     * The device type of the Responder.
-     */
-    public final int responderType;
-
-    /**
-     * Indicates whether the Responder device supports IEEE 802.11mc.
-     */
-    public final boolean supports80211mc;
-
-    /**
-     * Responder channel bandwidth, specified using {@link ChannelWidth}.
-     */
-    public final int channelWidth;
-
-    /**
-     * The primary 20 MHz frequency (in MHz) of the channel of the Responder.
-     */
-    public final int frequency;
-
-    /**
-     * Not used if the {@link #channelWidth} is 20 MHz. If the Responder uses 40, 80 or 160 MHz,
-     * this is the center frequency (in MHz), if the Responder uses 80 + 80 MHz, this is the
-     * center frequency of the first segment (in MHz).
-     */
-    public final int centerFreq0;
-
-    /**
-     * Only used if the {@link #channelWidth} is 80 + 80 MHz. If the Responder uses 80 + 80 MHz,
-     * this is the center frequency of the second segment (in MHz).
-     */
-    public final int centerFreq1;
-
-    /**
-     * The preamble used by the Responder, specified using {@link PreambleType}.
-     */
-    public final int preamble;
-
-    /**
-     * Constructs Responder configuration, using a MAC address to identify the Responder.
-     *
-     * @param macAddress      The MAC address of the Responder.
-     * @param responderType   The type of the responder device, specified using
-     *                        {@link ResponderType}.
-     * @param supports80211mc Indicates whether the responder supports IEEE 802.11mc.
-     * @param channelWidth    Responder channel bandwidth, specified using {@link ChannelWidth}.
-     * @param frequency       The primary 20 MHz frequency (in MHz) of the channel of the Responder.
-     * @param centerFreq0     Not used if the {@code channelWidth} is 20 MHz. If the Responder uses
-     *                        40, 80 or 160 MHz, this is the center frequency (in MHz), if the
-     *                        Responder uses 80 + 80 MHz, this is the center frequency of the first
-     *                        segment (in MHz).
-     * @param centerFreq1     Only used if the {@code channelWidth} is 80 + 80 MHz. If the
-     *                        Responder
-     *                        uses 80 + 80 MHz, this is the center frequency of the second segment
-     *                        (in
-     *                        MHz).
-     * @param preamble        The preamble used by the Responder, specified using
-     *                        {@link PreambleType}.
-     */
-    public ResponderConfig(@NonNull MacAddress macAddress, @ResponderType int responderType,
-            boolean supports80211mc, @ChannelWidth int channelWidth, int frequency, int centerFreq0,
-            int centerFreq1, @PreambleType int preamble) {
-        if (macAddress == null) {
-            throw new IllegalArgumentException(
-                    "Invalid ResponderConfig - must specify a MAC address");
-        }
-        this.macAddress = macAddress;
-        this.peerHandle = null;
-        this.responderType = responderType;
-        this.supports80211mc = supports80211mc;
-        this.channelWidth = channelWidth;
-        this.frequency = frequency;
-        this.centerFreq0 = centerFreq0;
-        this.centerFreq1 = centerFreq1;
-        this.preamble = preamble;
-    }
-
-    /**
-     * Constructs Responder configuration, using a Wi-Fi Aware PeerHandle to identify the Responder.
-     *
-     * @param peerHandle      The Wi-Fi Aware peer identifier of the Responder.
-     * @param responderType   The type of the responder device, specified using
-     *                        {@link ResponderType}.
-     * @param supports80211mc Indicates whether the responder supports IEEE 802.11mc.
-     * @param channelWidth    Responder channel bandwidth, specified using {@link ChannelWidth}.
-     * @param frequency       The primary 20 MHz frequency (in MHz) of the channel of the Responder.
-     * @param centerFreq0     Not used if the {@code channelWidth} is 20 MHz. If the Responder uses
-     *                        40, 80 or 160 MHz, this is the center frequency (in MHz), if the
-     *                        Responder uses 80 + 80 MHz, this is the center frequency of the first
-     *                        segment (in MHz).
-     * @param centerFreq1     Only used if the {@code channelWidth} is 80 + 80 MHz. If the
-     *                        Responder
-     *                        uses 80 + 80 MHz, this is the center frequency of the second segment
-     *                        (in
-     *                        MHz).
-     * @param preamble        The preamble used by the Responder, specified using
-     *                        {@link PreambleType}.
-     */
-    public ResponderConfig(@NonNull PeerHandle peerHandle, @ResponderType int responderType,
-            boolean supports80211mc, @ChannelWidth int channelWidth, int frequency, int centerFreq0,
-            int centerFreq1, @PreambleType int preamble) {
-        this.macAddress = null;
-        this.peerHandle = peerHandle;
-        this.responderType = responderType;
-        this.supports80211mc = supports80211mc;
-        this.channelWidth = channelWidth;
-        this.frequency = frequency;
-        this.centerFreq0 = centerFreq0;
-        this.centerFreq1 = centerFreq1;
-        this.preamble = preamble;
-    }
-
-    /**
-     * Constructs Responder configuration. This is an internal-only constructor which specifies both
-     * a MAC address and a Wi-Fi PeerHandle to identify the Responder.
-     *
-     * @param macAddress      The MAC address of the Responder.
-     * @param peerHandle      The Wi-Fi Aware peer identifier of the Responder.
-     * @param responderType   The type of the responder device, specified using
-     *                        {@link ResponderType}.
-     * @param supports80211mc Indicates whether the responder supports IEEE 802.11mc.
-     * @param channelWidth    Responder channel bandwidth, specified using {@link ChannelWidth}.
-     * @param frequency       The primary 20 MHz frequency (in MHz) of the channel of the Responder.
-     * @param centerFreq0     Not used if the {@code channelWidth} is 20 MHz. If the Responder uses
-     *                        40, 80 or 160 MHz, this is the center frequency (in MHz), if the
-     *                        Responder uses 80 + 80 MHz, this is the center frequency of the first
-     *                        segment (in MHz).
-     * @param centerFreq1     Only used if the {@code channelWidth} is 80 + 80 MHz. If the
-     *                        Responder
-     *                        uses 80 + 80 MHz, this is the center frequency of the second segment
-     *                        (in
-     *                        MHz).
-     * @param preamble        The preamble used by the Responder, specified using
-     *                        {@link PreambleType}.
-     * @hide
-     */
-    public ResponderConfig(@NonNull MacAddress macAddress, @NonNull PeerHandle peerHandle,
-            @ResponderType int responderType, boolean supports80211mc,
-            @ChannelWidth int channelWidth, int frequency, int centerFreq0, int centerFreq1,
-            @PreambleType int preamble) {
-        this.macAddress = macAddress;
-        this.peerHandle = peerHandle;
-        this.responderType = responderType;
-        this.supports80211mc = supports80211mc;
-        this.channelWidth = channelWidth;
-        this.frequency = frequency;
-        this.centerFreq0 = centerFreq0;
-        this.centerFreq1 = centerFreq1;
-        this.preamble = preamble;
-    }
-
-    /**
-     * Creates a Responder configuration from a {@link ScanResult} corresponding to an Access
-     * Point (AP), which can be obtained from {@link android.net.wifi.WifiManager#getScanResults()}.
-     */
-    public static ResponderConfig fromScanResult(ScanResult scanResult) {
-        MacAddress macAddress = MacAddress.fromString(scanResult.BSSID);
-        int responderType = RESPONDER_AP;
-        boolean supports80211mc = scanResult.is80211mcResponder();
-        int channelWidth = translateScanResultChannelWidth(scanResult.channelWidth);
-        int frequency = scanResult.frequency;
-        int centerFreq0 = scanResult.centerFreq0;
-        int centerFreq1 = scanResult.centerFreq1;
-
-        int preamble;
-        if (scanResult.informationElements != null && scanResult.informationElements.length != 0) {
-            boolean htCapabilitiesPresent = false;
-            boolean vhtCapabilitiesPresent = false;
-            boolean heCapabilitiesPresent = false;
-
-            for (ScanResult.InformationElement ie : scanResult.informationElements) {
-                if (ie.id == EID_HT_CAPABILITIES) {
-                    htCapabilitiesPresent = true;
-                } else if (ie.id == EID_VHT_CAPABILITIES) {
-                    vhtCapabilitiesPresent = true;
-                } else if (ie.id == EID_EXTENSION_PRESENT && ie.idExt == EID_EXT_HE_CAPABILITIES) {
-                    heCapabilitiesPresent = true;
-                }
-            }
-
-            if (heCapabilitiesPresent) {
-                preamble = PREAMBLE_HE;
-            } else if (vhtCapabilitiesPresent) {
-                preamble = PREAMBLE_VHT;
-            } else if (htCapabilitiesPresent) {
-                preamble = PREAMBLE_HT;
-            } else {
-                preamble = PREAMBLE_LEGACY;
-            }
-        } else {
-            Log.e(TAG, "Scan Results do not contain IEs - using backup method to select preamble");
-            if (channelWidth == CHANNEL_WIDTH_80MHZ || channelWidth == CHANNEL_WIDTH_160MHZ) {
-                preamble = PREAMBLE_VHT;
-            } else {
-                preamble = PREAMBLE_HT;
-            }
-        }
-
-        return new ResponderConfig(macAddress, responderType, supports80211mc, channelWidth,
-                frequency, centerFreq0, centerFreq1, preamble);
-    }
-
-    /**
-     * Creates a Responder configuration from a MAC address corresponding to a Wi-Fi Aware
-     * Responder. The Responder parameters are set to defaults.
-     */
-    public static ResponderConfig fromWifiAwarePeerMacAddressWithDefaults(MacAddress macAddress) {
-        /* Note: the parameters are those of the Aware discovery channel (channel 6). A Responder
-         * is expected to be brought up and available to negotiate a maximum accuracy channel
-         * (i.e. Band 5 @ 80MHz). A Responder is brought up on the peer by starting an Aware
-         * Unsolicited Publisher with Ranging enabled.
-         */
-        return new ResponderConfig(macAddress, RESPONDER_AWARE, true, CHANNEL_WIDTH_20MHZ,
-                AWARE_BAND_2_DISCOVERY_CHANNEL, 0, 0, PREAMBLE_HT);
-    }
-
-    /**
-     * Creates a Responder configuration from a {@link PeerHandle} corresponding to a Wi-Fi Aware
-     * Responder. The Responder parameters are set to defaults.
-     */
-    public static ResponderConfig fromWifiAwarePeerHandleWithDefaults(PeerHandle peerHandle) {
-        /* Note: the parameters are those of the Aware discovery channel (channel 6). A Responder
-         * is expected to be brought up and available to negotiate a maximum accuracy channel
-         * (i.e. Band 5 @ 80MHz). A Responder is brought up on the peer by starting an Aware
-         * Unsolicited Publisher with Ranging enabled.
-         */
-        return new ResponderConfig(peerHandle, RESPONDER_AWARE, true, CHANNEL_WIDTH_20MHZ,
-                AWARE_BAND_2_DISCOVERY_CHANNEL, 0, 0, PREAMBLE_HT);
-    }
-
-    /**
-     * Check whether the Responder configuration is valid.
-     *
-     * @return true if valid, false otherwise.
-     * @hide
-     */
-    public boolean isValid(boolean awareSupported) {
-        if (macAddress == null && peerHandle == null || macAddress != null && peerHandle != null) {
-            return false;
-        }
-        if (!awareSupported && responderType == RESPONDER_AWARE) {
-            return false;
-        }
-
-        return true;
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        if (macAddress == null) {
-            dest.writeBoolean(false);
-        } else {
-            dest.writeBoolean(true);
-            macAddress.writeToParcel(dest, flags);
-        }
-        if (peerHandle == null) {
-            dest.writeBoolean(false);
-        } else {
-            dest.writeBoolean(true);
-            dest.writeInt(peerHandle.peerId);
-        }
-        dest.writeInt(responderType);
-        dest.writeInt(supports80211mc ? 1 : 0);
-        dest.writeInt(channelWidth);
-        dest.writeInt(frequency);
-        dest.writeInt(centerFreq0);
-        dest.writeInt(centerFreq1);
-        dest.writeInt(preamble);
-    }
-
-    public static final @android.annotation.NonNull Creator<ResponderConfig> CREATOR = new Creator<ResponderConfig>() {
-        @Override
-        public ResponderConfig[] newArray(int size) {
-            return new ResponderConfig[size];
-        }
-
-        @Override
-        public ResponderConfig createFromParcel(Parcel in) {
-            boolean macAddressPresent = in.readBoolean();
-            MacAddress macAddress = null;
-            if (macAddressPresent) {
-                macAddress = MacAddress.CREATOR.createFromParcel(in);
-            }
-            boolean peerHandlePresent = in.readBoolean();
-            PeerHandle peerHandle = null;
-            if (peerHandlePresent) {
-                peerHandle = new PeerHandle(in.readInt());
-            }
-            int responderType = in.readInt();
-            boolean supports80211mc = in.readInt() == 1;
-            int channelWidth = in.readInt();
-            int frequency = in.readInt();
-            int centerFreq0 = in.readInt();
-            int centerFreq1 = in.readInt();
-            int preamble = in.readInt();
-
-            if (peerHandle == null) {
-                return new ResponderConfig(macAddress, responderType, supports80211mc, channelWidth,
-                        frequency, centerFreq0, centerFreq1, preamble);
-            } else {
-                return new ResponderConfig(peerHandle, responderType, supports80211mc, channelWidth,
-                        frequency, centerFreq0, centerFreq1, preamble);
-            }
-        }
-    };
-
-    @Override
-    public boolean equals(@Nullable Object o) {
-        if (this == o) {
-            return true;
-        }
-
-        if (!(o instanceof ResponderConfig)) {
-            return false;
-        }
-
-        ResponderConfig lhs = (ResponderConfig) o;
-
-        return Objects.equals(macAddress, lhs.macAddress) && Objects.equals(peerHandle,
-                lhs.peerHandle) && responderType == lhs.responderType
-                && supports80211mc == lhs.supports80211mc && channelWidth == lhs.channelWidth
-                && frequency == lhs.frequency && centerFreq0 == lhs.centerFreq0
-                && centerFreq1 == lhs.centerFreq1 && preamble == lhs.preamble;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(macAddress, peerHandle, responderType, supports80211mc, channelWidth,
-                frequency, centerFreq0, centerFreq1, preamble);
-    }
-
-    /** @hide */
-    @Override
-    public String toString() {
-        return new StringBuffer("ResponderConfig: macAddress=").append(macAddress).append(
-                ", peerHandle=").append(peerHandle == null ? "<null>" : peerHandle.peerId).append(
-                ", responderType=").append(responderType).append(", supports80211mc=").append(
-                supports80211mc).append(", channelWidth=").append(channelWidth).append(
-                ", frequency=").append(frequency).append(", centerFreq0=").append(
-                centerFreq0).append(", centerFreq1=").append(centerFreq1).append(
-                ", preamble=").append(preamble).toString();
-    }
-
-    /** @hide */
-    static int translateScanResultChannelWidth(int scanResultChannelWidth) {
-        switch (scanResultChannelWidth) {
-            case ScanResult.CHANNEL_WIDTH_20MHZ:
-                return CHANNEL_WIDTH_20MHZ;
-            case ScanResult.CHANNEL_WIDTH_40MHZ:
-                return CHANNEL_WIDTH_40MHZ;
-            case ScanResult.CHANNEL_WIDTH_80MHZ:
-                return CHANNEL_WIDTH_80MHZ;
-            case ScanResult.CHANNEL_WIDTH_160MHZ:
-                return CHANNEL_WIDTH_160MHZ;
-            case ScanResult.CHANNEL_WIDTH_80MHZ_PLUS_MHZ:
-                return CHANNEL_WIDTH_80MHZ_PLUS_MHZ;
-            default:
-                throw new IllegalArgumentException(
-                        "translateScanResultChannelWidth: bad " + scanResultChannelWidth);
-        }
-    }
-}
diff --git a/wifi/java/android/net/wifi/rtt/ResponderLocation.java b/wifi/java/android/net/wifi/rtt/ResponderLocation.java
deleted file mode 100644
index 218b2dca..0000000
--- a/wifi/java/android/net/wifi/rtt/ResponderLocation.java
+++ /dev/null
@@ -1,1427 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.rtt;
-
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SuppressLint;
-import android.annotation.SystemApi;
-import android.location.Address;
-import android.location.Location;
-import android.net.MacAddress;
-import android.net.Uri;
-import android.net.wifi.rtt.CivicLocationKeys.CivicLocationKeysType;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-import android.util.SparseArray;
-import android.webkit.MimeTypeMap;
-
-import java.lang.annotation.Retention;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * ResponderLocation is both a Location Configuration Information (LCI) decoder and a Location Civic
- * Report (LCR) decoder for information received from a Wi-Fi Access Point (AP) during Wi-Fi RTT
- * ranging process.
- *
- * <p>This is based on the IEEE P802.11-REVmc/D8.0 spec section 9.4.2.22, under Measurement Report
- * Element. Subelement location data-fields parsed from separate input LCI and LCR Information
- * Elements are unified in this class.</p>
- *
- * <p>Note: The information provided by this class is broadcast by a responder (usually an Access
- * Point), and passed on as-is. There is no guarantee this information is accurate or correct, and
- * as a result developers should carefully consider how this information should be used and provide
- * corresponding advice to users.</p>
- */
-public final class ResponderLocation implements Parcelable {
-    private static final int BYTE_MASK = 0xFF;
-    private static final int LSB_IN_BYTE = 0x01;
-    private static final int MSB_IN_BYTE = 0x80;
-    private static final int MIN_BUFFER_SIZE = 3; // length of LEAD_LCI_ELEMENT_BYTES
-    private static final int MAX_BUFFER_SIZE = 256;
-
-    // Information Element (IE) fields
-    private static final byte MEASUREMENT_TOKEN_AUTONOMOUS = 0x01;
-    private static final byte MEASUREMENT_REPORT_MODE = 0x00;
-    private static final byte MEASUREMENT_TYPE_LCI = 0x08;
-    private static final byte MEASUREMENT_TYPE_LCR = 0x0b;
-
-    // LCI Subelement IDs
-    private static final byte SUBELEMENT_LCI = 0x00;
-    private static final byte SUBELEMENT_Z = 0x04;
-    private static final byte SUBELEMENT_USAGE = 0x06;
-    private static final byte SUBELEMENT_BSSID_LIST = 0x07;
-
-    // LCI Subelement Lengths
-    private static final int SUBELEMENT_LCI_LENGTH = 16;
-    private static final int SUBELEMENT_Z_LENGTH = 6;
-    private static final int SUBELEMENT_USAGE_LENGTH1 = 1;
-    private static final int SUBELEMENT_USAGE_LENGTH3 = 3;
-    private static final int SUBELEMENT_BSSID_LIST_MIN_BUFFER_LENGTH = 1;
-
-    private static final byte[] LEAD_LCI_ELEMENT_BYTES = {
-            MEASUREMENT_TOKEN_AUTONOMOUS, MEASUREMENT_REPORT_MODE, MEASUREMENT_TYPE_LCI
-    };
-
-    // Subelement LCI constants
-
-    /* The LCI subelement bit-field lengths are described in Figure 9-214 of the REVmc spec and
-    represented here as a an array of integers */
-    private static final int[] SUBELEMENT_LCI_BIT_FIELD_LENGTHS = {
-            6, 34, 6, 34, 4, 6, 30, 3, 1, 1, 1, 2
-    };
-    private static final int LATLNG_FRACTION_BITS = 25;
-    private static final int LATLNG_UNCERTAINTY_BASE = 8;
-    private static final int ALTITUDE_FRACTION_BITS = 8;
-    private static final int ALTITUDE_UNCERTAINTY_BASE = 21;
-    private static final double LAT_ABS_LIMIT = 90.0;
-    private static final double LNG_ABS_LIMIT = 180.0;
-    private static final int UNCERTAINTY_UNDEFINED = 0;
-
-    // Subelement LCI fields indices
-    private static final int SUBELEMENT_LCI_LAT_UNCERTAINTY_INDEX = 0;
-    private static final int SUBELEMENT_LCI_LAT_INDEX = 1;
-    private static final int SUBELEMENT_LCI_LNG_UNCERTAINTY_INDEX = 2;
-    private static final int SUBELEMENT_LCI_LNG_INDEX = 3;
-    private static final int SUBELEMENT_LCI_ALT_TYPE_INDEX = 4;
-    private static final int SUBELEMENT_LCI_ALT_UNCERTAINTY_INDEX = 5;
-    private static final int SUBELEMENT_LCI_ALT_INDEX = 6;
-    private static final int SUBELEMENT_LCI_DATUM_INDEX = 7;
-    private static final int SUBELEMENT_LCI_REGLOC_AGREEMENT_INDEX = 8;
-    private static final int SUBELEMENT_LCI_REGLOC_DSE_INDEX = 9;
-    private static final int SUBELEMENT_LCI_DEPENDENT_STA_INDEX = 10;
-    private static final int SUBELEMENT_LCI_VERSION_INDEX = 11;
-
-    /**
-     * The Altitude value is interpreted based on the Altitude Type, and the selected mDatum.
-     *
-     * @hide
-     */
-    @Retention(SOURCE)
-    @IntDef({ALTITUDE_UNDEFINED, ALTITUDE_METERS, ALTITUDE_FLOORS})
-    public @interface AltitudeType {
-    }
-
-    /**
-     * Altitude is not defined for the Responder.
-     * The altitude and altitude uncertainty should not be used: see section 2.4 of IETF RFC 6225.
-     */
-    public static final int ALTITUDE_UNDEFINED = 0;
-    /** Responder Altitude is measured in meters.  */
-    public static final int ALTITUDE_METERS = 1;
-    /** Responder Altitude is measured in floors. */
-    public static final int ALTITUDE_FLOORS = 2;
-
-    /**
-     * The Datum value determines how coordinates are organized in relation to the real world.
-     *
-     * @hide
-     */
-    @Retention(SOURCE)
-    @IntDef({DATUM_UNDEFINED, DATUM_WGS84, DATUM_NAD83_NAV88, DATUM_NAD83_MLLW})
-    public @interface DatumType {
-    }
-
-    /** Datum is not defined. */
-    public static final int DATUM_UNDEFINED = 0;
-    /** Datum used is WGS84. */
-    public static final int DATUM_WGS84 = 1;
-    /** Datum used is NAD83 NAV88. */
-    public static final int DATUM_NAD83_NAV88 = 2;
-    /** Datum used is NAD83 MLLW. */
-    public static final int DATUM_NAD83_MLLW = 3;
-
-
-    /** Version of the LCI protocol is 1.0, the only defined protocol at this time. */
-    public static final int LCI_VERSION_1 = 1;
-
-    /** Provider/Source of the location */
-    private static final String LOCATION_PROVIDER = "WiFi Access Point";
-
-    // LCI Subelement Z constants
-    private static final int[] SUBELEMENT_Z_BIT_FIELD_LENGTHS = {2, 14, 24, 8};
-    private static final int Z_FLOOR_NUMBER_FRACTION_BITS = 4;
-    private static final int Z_FLOOR_HEIGHT_FRACTION_BITS = 12;
-    private static final int Z_MAX_HEIGHT_UNCERTAINTY_FACTOR = 25;
-
-    // LCI Subelement Z fields indices
-    private static final int SUBELEMENT_Z_LAT_EXPECTED_TO_MOVE_INDEX = 0;
-    private static final int SUBELEMENT_Z_FLOOR_NUMBER_INDEX = 1;
-    private static final int SUBELEMENT_Z_HEIGHT_ABOVE_FLOOR_INDEX = 2;
-    private static final int SUBELEMENT_Z_HEIGHT_ABOVE_FLOOR_UNCERTAINTY_INDEX = 3;
-
-    // LCI Subelement Usage Rules constants
-    private static final int SUBELEMENT_USAGE_MASK_RETRANSMIT = 0x01;
-    private static final int SUBELEMENT_USAGE_MASK_RETENTION_EXPIRES = 0x02;
-    private static final int SUBELEMENT_USAGE_MASK_STA_LOCATION_POLICY = 0x04;
-
-    // LCI Subelement Usage Rules field indices
-    private static final int SUBELEMENT_USAGE_PARAMS_INDEX = 0; // 8 bits
-
-    // LCI Subelement BSSID List
-    private static final int SUBELEMENT_BSSID_MAX_INDICATOR_INDEX = 0;
-    private static final int SUBELEMENT_BSSID_LIST_INDEX = 1;
-    private static final int BYTES_IN_A_BSSID = 6;
-
-    /**
-     * The Expected-To-Move value determines how mobile we expect the STA to be.
-     *
-     * @hide
-     */
-    @Retention(SOURCE)
-    @IntDef({LOCATION_FIXED, LOCATION_VARIABLE, LOCATION_MOVEMENT_UNKNOWN, LOCATION_RESERVED})
-    public @interface ExpectedToMoveType {
-    }
-
-    /** Location of responder is fixed (does not move) */
-    public static final int LOCATION_FIXED = 0;
-    /** Location of the responder is variable, and may move */
-    public static final int LOCATION_VARIABLE = 1;
-    /** Location of the responder is not known to be either fixed or variable. */
-    public static final int LOCATION_MOVEMENT_UNKNOWN = 2;
-    /** Location of the responder status is a reserved value */
-    public static final int LOCATION_RESERVED = 3;
-
-    // LCR Subelement IDs
-    private static final byte SUBELEMENT_LOCATION_CIVIC = 0x00;
-    private static final byte SUBELEMENT_MAP_IMAGE = 0x05;
-
-    // LCR Subelement Lengths
-    private static final int SUBELEMENT_LOCATION_CIVIC_MIN_LENGTH = 2;
-    private static final int SUBELEMENT_LOCATION_CIVIC_MAX_LENGTH = 256;
-    private static final int SUBELEMENT_MAP_IMAGE_URL_MAX_LENGTH = 256;
-
-    private static final byte[] LEAD_LCR_ELEMENT_BYTES = {
-            MEASUREMENT_TOKEN_AUTONOMOUS, MEASUREMENT_REPORT_MODE, MEASUREMENT_TYPE_LCR
-    };
-
-    // LCR Location Civic Subelement
-    private static final int CIVIC_COUNTRY_CODE_INDEX = 0;
-    private static final int CIVIC_TLV_LIST_INDEX = 2;
-
-    // LCR Map Image Subelement field indexes.
-    private static final int SUBELEMENT_IMAGE_MAP_TYPE_INDEX = 0;
-    private static final int MAP_TYPE_URL_DEFINED = 0;
-    private static final String[] SUPPORTED_IMAGE_FILE_EXTENSIONS = {
-            "",
-            "png",
-            "gif",
-            "jpg",
-            "svg",
-            "dxf",
-            "dwg",
-            "dwf",
-            "cad",
-            "tif",
-            "gml",
-            "kml",
-            "bmp",
-            "pgm",
-            "ppm",
-            "xbm",
-            "xpm",
-            "ico"
-    };
-
-    // General LCI and LCR state
-    private final boolean mIsValid;
-
-    /*
-      These members are not final because we are not sure if the corresponding subelement will be
-      present until after the parsing process. However, the default value should be set as listed.
-    */
-    private boolean mIsLciValid = false;
-    private boolean mIsZValid = false;
-    private boolean mIsUsageValid = true; // By default this is assumed true
-    private boolean mIsBssidListValid = false;
-    private boolean mIsLocationCivicValid = false;
-    private boolean mIsMapImageValid = false;
-
-    // LCI Subelement LCI state
-    private double mLatitudeUncertainty;
-    private double mLatitude;
-    private double mLongitudeUncertainty;
-    private double mLongitude;
-    private int mAltitudeType;
-    private double mAltitudeUncertainty;
-    private double mAltitude;
-    private int mDatum;
-    private boolean mLciRegisteredLocationAgreement;
-    private boolean mLciRegisteredLocationDse;
-    private boolean mLciDependentStation;
-    private int mLciVersion;
-
-    // LCI Subelement Z state
-    private int mExpectedToMove;
-    private double mFloorNumber;
-    private double mHeightAboveFloorMeters;
-    private double mHeightAboveFloorUncertaintyMeters;
-
-    // LCI Subelement Usage Rights state
-    private boolean mUsageRetransmit;
-    private boolean mUsageRetentionExpires;
-    private boolean mUsageExtraInfoOnAssociation;
-
-    // LCI Subelement BSSID List state
-    private ArrayList<MacAddress> mBssidList;
-
-    // LCR Subelement Location Civic state
-    private String mCivicLocationCountryCode;
-    private String mCivicLocationString;
-    private CivicLocation mCivicLocation;
-
-    // LCR Subelement Map Image state
-    private int mMapImageType;
-    private Uri mMapImageUri;
-
-    /**
-     * Constructor
-     *
-     * @param lciBuffer the bytes received in the LCI Measurement Report Information Element
-     * @param lcrBuffer the bytes received in the LCR Measurement Report Information Element
-     *
-     * @hide
-     */
-    public ResponderLocation(byte[] lciBuffer, byte[] lcrBuffer) {
-        boolean isLciIeValid = false;
-        boolean isLcrIeValid = false;
-        setLciSubelementDefaults();
-        setZaxisSubelementDefaults();
-        setUsageSubelementDefaults();
-        setBssidListSubelementDefaults();
-        setCivicLocationSubelementDefaults();
-        setMapImageSubelementDefaults();
-        if (lciBuffer != null && lciBuffer.length > LEAD_LCI_ELEMENT_BYTES.length) {
-            isLciIeValid = parseInformationElementBuffer(
-                MEASUREMENT_TYPE_LCI, lciBuffer, LEAD_LCI_ELEMENT_BYTES);
-        }
-        if (lcrBuffer != null && lcrBuffer.length > LEAD_LCR_ELEMENT_BYTES.length) {
-            isLcrIeValid = parseInformationElementBuffer(
-                MEASUREMENT_TYPE_LCR, lcrBuffer, LEAD_LCR_ELEMENT_BYTES);
-        }
-
-        boolean isLciValid = isLciIeValid && mIsUsageValid
-                && (mIsLciValid || mIsZValid || mIsBssidListValid);
-
-        boolean isLcrValid = isLcrIeValid && mIsUsageValid
-                && (mIsLocationCivicValid || mIsMapImageValid);
-
-        mIsValid = isLciValid || isLcrValid;
-
-        if (!mIsValid) {
-            setLciSubelementDefaults();
-            setZaxisSubelementDefaults();
-            setCivicLocationSubelementDefaults();
-            setMapImageSubelementDefaults();
-        }
-    }
-
-    private ResponderLocation(Parcel in) {
-        // Object Validation
-        mIsValid = in.readByte() != 0;
-        mIsLciValid = in.readByte() != 0;
-        mIsZValid = in.readByte() != 0;
-        mIsUsageValid = in.readByte() != 0;
-        mIsBssidListValid = in.readByte() != 0;
-        mIsLocationCivicValid = in.readByte() != 0;
-        mIsMapImageValid = in.readByte() != 0;
-
-        // LCI Subelement LCI state
-        mLatitudeUncertainty = in.readDouble();
-        mLatitude = in.readDouble();
-        mLongitudeUncertainty = in.readDouble();
-        mLongitude = in.readDouble();
-        mAltitudeType = in.readInt();
-        mAltitudeUncertainty = in.readDouble();
-        mAltitude = in.readDouble();
-        mDatum = in.readInt();
-        mLciRegisteredLocationAgreement = in.readByte() != 0;
-        mLciRegisteredLocationDse = in.readByte() != 0;
-        mLciDependentStation = in.readByte() != 0;
-        mLciVersion = in.readInt();
-
-        // LCI Subelement Z state
-        mExpectedToMove = in.readInt();
-        mFloorNumber = in.readDouble();
-        mHeightAboveFloorMeters = in.readDouble();
-        mHeightAboveFloorUncertaintyMeters = in.readDouble();
-
-        // LCI Usage Rights
-        mUsageRetransmit = in.readByte() != 0;
-        mUsageRetentionExpires = in.readByte() != 0;
-        mUsageExtraInfoOnAssociation = in.readByte() != 0;
-
-        // LCI Subelement BSSID List
-        mBssidList = in.readArrayList(MacAddress.class.getClassLoader());
-
-        // LCR Subelement Location Civic
-        mCivicLocationCountryCode = in.readString();
-        mCivicLocationString = in.readString();
-        mCivicLocation = in.readParcelable(this.getClass().getClassLoader());
-
-        // LCR Subelement Map Image
-        mMapImageType = in.readInt();
-        String urlString = in.readString();
-        if (TextUtils.isEmpty(urlString)) {
-            mMapImageUri = null;
-        } else {
-            mMapImageUri = Uri.parse(urlString);
-        }
-    }
-
-    public static final @android.annotation.NonNull Creator<ResponderLocation> CREATOR = new Creator<ResponderLocation>() {
-        @Override
-        public ResponderLocation createFromParcel(Parcel in) {
-            return new ResponderLocation(in);
-        }
-
-        @Override
-        public ResponderLocation[] newArray(int size) {
-            return new ResponderLocation[size];
-        }
-    };
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel parcel, int flags) {
-        // Object
-        parcel.writeByte((byte) (mIsValid ? 1 : 0));
-        parcel.writeByte((byte) (mIsLciValid ? 1 : 0));
-        parcel.writeByte((byte) (mIsZValid ? 1 : 0));
-        parcel.writeByte((byte) (mIsUsageValid ? 1 : 0));
-        parcel.writeByte((byte) (mIsBssidListValid ? 1 : 0));
-        parcel.writeByte((byte) (mIsLocationCivicValid ? 1 : 0));
-        parcel.writeByte((byte) (mIsMapImageValid ? 1 : 0));
-
-        // LCI Subelement LCI state
-        parcel.writeDouble(mLatitudeUncertainty);
-        parcel.writeDouble(mLatitude);
-        parcel.writeDouble(mLongitudeUncertainty);
-        parcel.writeDouble(mLongitude);
-        parcel.writeInt(mAltitudeType);
-        parcel.writeDouble(mAltitudeUncertainty);
-        parcel.writeDouble(mAltitude);
-        parcel.writeInt(mDatum);
-        parcel.writeByte((byte) (mLciRegisteredLocationAgreement ? 1 : 0));
-        parcel.writeByte((byte) (mLciRegisteredLocationDse ? 1 : 0));
-        parcel.writeByte((byte) (mLciDependentStation ? 1 : 0));
-        parcel.writeInt(mLciVersion);
-
-        // LCI Subelement Z state
-        parcel.writeInt(mExpectedToMove);
-        parcel.writeDouble(mFloorNumber);
-        parcel.writeDouble(mHeightAboveFloorMeters);
-        parcel.writeDouble(mHeightAboveFloorUncertaintyMeters);
-
-        // LCI Usage Rights
-        parcel.writeByte((byte) (mUsageRetransmit ? 1 : 0));
-        parcel.writeByte((byte) (mUsageRetentionExpires ? 1 : 0));
-        parcel.writeByte((byte) (mUsageExtraInfoOnAssociation ? 1 : 0));
-
-        // LCI Subelement BSSID List
-        parcel.writeList(mBssidList);
-
-        // LCR Subelement Location Civic
-        parcel.writeString(mCivicLocationCountryCode);
-        parcel.writeString(mCivicLocationString);
-        parcel.writeParcelable(mCivicLocation, flags);
-
-        // LCR Subelement Map Image
-        parcel.writeInt(mMapImageType);
-        if (mMapImageUri != null) {
-            parcel.writeString(mMapImageUri.toString());
-        } else {
-            parcel.writeString("");
-        }
-    }
-
-    /**
-     * Test if the Information Element (IE) is in the correct format, and then parse its Subelements
-     * based on their type, and setting state in this object when present.
-     *
-     * @return a boolean indicating the success of the parsing function
-     */
-    private boolean parseInformationElementBuffer(
-            int ieType, byte[] buffer, byte[] expectedLeadBytes) {
-        int bufferPtr = 0;
-        int bufferLength = buffer.length;
-
-        // Ensure the buffer size is within expected limits
-        if (bufferLength < MIN_BUFFER_SIZE || bufferLength > MAX_BUFFER_SIZE) {
-            return false;
-        }
-
-        // Ensure the IE contains the correct leading bytes
-        byte[] leadBufferBytes = Arrays.copyOfRange(buffer, bufferPtr, expectedLeadBytes.length);
-        if (!Arrays.equals(leadBufferBytes, expectedLeadBytes)) {
-            return false;
-        }
-
-        // Iterate through the sub-elements contained in the Information Element (IE)
-        bufferPtr += expectedLeadBytes.length;
-        // Loop over the buffer ensuring there are 2-bytes available for each new subelement tested.
-        while (bufferPtr + 1 < bufferLength) {
-            byte subelement = buffer[bufferPtr++];
-            int subelementLength = buffer[bufferPtr++];
-            // Check there is enough data for the next subelement
-            if ((bufferPtr + subelementLength) > bufferLength || subelementLength <= 0) {
-                return false;
-            }
-
-            byte[] subelementData =
-                    Arrays.copyOfRange(buffer, bufferPtr, bufferPtr + subelementLength);
-
-            if (ieType == MEASUREMENT_TYPE_LCI) {
-                switch (subelement) {
-                    case SUBELEMENT_LCI:
-                        mIsLciValid = parseSubelementLci(subelementData);
-                        if (!mIsLciValid || mLciVersion != LCI_VERSION_1) {
-                            setLciSubelementDefaults();
-                        }
-                        break;
-                    case SUBELEMENT_Z:
-                        mIsZValid = parseSubelementZ(subelementData);
-                        if (!mIsZValid) {
-                            setZaxisSubelementDefaults();
-                        }
-                        break;
-                    case SUBELEMENT_USAGE:
-                        mIsUsageValid = parseSubelementUsage(subelementData);
-                        // Note: if the Usage Subelement is not valid, don't reset the state, as
-                        // it is now indicating the whole ResponderLocation is invalid.
-                        break;
-                    case SUBELEMENT_BSSID_LIST:
-                        mIsBssidListValid = parseSubelementBssidList(subelementData);
-                        if (!mIsBssidListValid) {
-                            setBssidListSubelementDefaults();
-                        }
-                        break;
-                    default:
-                        break; // skip over unused or vendor specific subelements
-                }
-            } else if (ieType == MEASUREMENT_TYPE_LCR) {
-                switch (subelement) {
-                    case SUBELEMENT_LOCATION_CIVIC:
-                        mIsLocationCivicValid = parseSubelementLocationCivic(subelementData);
-                        if (!mIsLocationCivicValid) {
-                            setCivicLocationSubelementDefaults();
-                        }
-                        break;
-                    case SUBELEMENT_MAP_IMAGE:
-                        mIsMapImageValid = parseSubelementMapImage(subelementData);
-                        if (!mIsMapImageValid) {
-                            setMapImageSubelementDefaults();
-                        }
-                        break;
-                    default:
-                        break; // skip over unused or other vendor specific subelements
-                }
-            }
-
-            bufferPtr += subelementLength;
-        }
-        return true;
-    }
-
-    /**
-     * Parse the LCI Sub-Element in the LCI Information Element (IE).
-     *
-     * @param buffer a buffer containing the subelement
-     * @return boolean true indicates success
-     */
-    private boolean parseSubelementLci(byte[] buffer) {
-        if (buffer.length > SUBELEMENT_LCI_LENGTH) {
-            return false;
-        }
-        swapEndianByteByByte(buffer);
-        long[] subelementLciFields = getFieldData(buffer, SUBELEMENT_LCI_BIT_FIELD_LENGTHS);
-        if (subelementLciFields == null) {
-            return false;
-        }
-        // Set member state based on parsed buffer data
-        mLatitudeUncertainty = decodeLciLatLngUncertainty(
-                subelementLciFields[SUBELEMENT_LCI_LAT_UNCERTAINTY_INDEX]);
-        mLatitude = decodeLciLatLng(subelementLciFields, SUBELEMENT_LCI_BIT_FIELD_LENGTHS,
-                SUBELEMENT_LCI_LAT_INDEX, LAT_ABS_LIMIT);
-        mLongitudeUncertainty = decodeLciLatLngUncertainty(
-                subelementLciFields[SUBELEMENT_LCI_LNG_UNCERTAINTY_INDEX]);
-        mLongitude =
-                decodeLciLatLng(subelementLciFields, SUBELEMENT_LCI_BIT_FIELD_LENGTHS,
-                        SUBELEMENT_LCI_LNG_INDEX, LNG_ABS_LIMIT);
-        mAltitudeType = (int) subelementLciFields[SUBELEMENT_LCI_ALT_TYPE_INDEX] & BYTE_MASK;
-        mAltitudeUncertainty =
-                decodeLciAltUncertainty(subelementLciFields[SUBELEMENT_LCI_ALT_UNCERTAINTY_INDEX]);
-        mAltitude =
-                Math.scalb(subelementLciFields[SUBELEMENT_LCI_ALT_INDEX], -ALTITUDE_FRACTION_BITS);
-        mDatum = (int) subelementLciFields[SUBELEMENT_LCI_DATUM_INDEX] & BYTE_MASK;
-        mLciRegisteredLocationAgreement =
-                (subelementLciFields[SUBELEMENT_LCI_REGLOC_AGREEMENT_INDEX] == 1);
-        mLciRegisteredLocationDse =
-                (subelementLciFields[SUBELEMENT_LCI_REGLOC_DSE_INDEX] == 1);
-        mLciDependentStation =
-                (subelementLciFields[SUBELEMENT_LCI_DEPENDENT_STA_INDEX] == 1);
-        mLciVersion = (int) subelementLciFields[SUBELEMENT_LCI_VERSION_INDEX];
-        return true;
-    }
-
-    /**
-     * Decode the floating point value of an encoded lat or lng in the LCI subelement field.
-     *
-     * @param fields        the array of field data represented as longs
-     * @param bitFieldSizes the lengths of each field
-     * @param offset        the offset of the field being decoded
-     * @param limit the maximum absolute value (note: different for lat vs lng)
-     * @return the floating point value of the lat or lng
-     */
-    private double decodeLciLatLng(long[] fields, int[] bitFieldSizes, int offset, double limit) {
-        double angle;
-        if ((fields[offset] & (long) Math.pow(2, bitFieldSizes[offset] - 1)) != 0) {
-            // Negative 2's complement value
-            // Note: The Math.pow(...) method cannot return a NaN value because the bitFieldSize
-            // for Lat or Lng is limited to exactly 34 bits.
-            angle = Math.scalb((double) fields[offset] - Math.pow(2, bitFieldSizes[offset]),
-                    -LATLNG_FRACTION_BITS);
-        } else {
-            // Positive 2's complement value
-            angle = Math.scalb((double) fields[offset], -LATLNG_FRACTION_BITS);
-        }
-        if (angle > limit) {
-            angle = limit;
-        } else if (angle < -limit) {
-            angle = -limit;
-        }
-        return angle;
-    }
-
-    /**
-     * Coverts an encoded Lat/Lng uncertainty into a number of degrees.
-     *
-     * @param encodedValue the encoded uncertainty
-     * @return the value in degrees
-     */
-    private double decodeLciLatLngUncertainty(long encodedValue) {
-        return Math.pow(2, LATLNG_UNCERTAINTY_BASE - encodedValue);
-    }
-
-    /**
-     * Converts an encoded Alt uncertainty into a number of degrees.
-     *
-     * @param encodedValue the encoded uncertainty
-     * @return the value in degrees
-     */
-    private double decodeLciAltUncertainty(long encodedValue) {
-        return Math.pow(2, ALTITUDE_UNCERTAINTY_BASE - encodedValue);
-    }
-
-    /**
-     * Parse the Z subelement of the LCI IE.
-     *
-     * @param buffer a buffer containing the subelement
-     * @return boolean true indicates success
-     */
-    private boolean parseSubelementZ(byte[] buffer) {
-        if (buffer.length != SUBELEMENT_Z_LENGTH) {
-            return false;
-        }
-        swapEndianByteByByte(buffer);
-        long[] subelementZFields = getFieldData(buffer, SUBELEMENT_Z_BIT_FIELD_LENGTHS);
-        if (subelementZFields == null) {
-            return false;
-        }
-
-        mExpectedToMove =
-                (int) subelementZFields[SUBELEMENT_Z_LAT_EXPECTED_TO_MOVE_INDEX] & BYTE_MASK;
-        mFloorNumber = decodeZUnsignedToSignedValue(subelementZFields,
-                SUBELEMENT_Z_BIT_FIELD_LENGTHS, SUBELEMENT_Z_FLOOR_NUMBER_INDEX,
-                Z_FLOOR_NUMBER_FRACTION_BITS);
-
-        mHeightAboveFloorMeters = decodeZUnsignedToSignedValue(subelementZFields,
-                SUBELEMENT_Z_BIT_FIELD_LENGTHS, SUBELEMENT_Z_HEIGHT_ABOVE_FLOOR_INDEX,
-                Z_FLOOR_HEIGHT_FRACTION_BITS);
-
-        long zHeightUncertainty =
-                subelementZFields[SUBELEMENT_Z_HEIGHT_ABOVE_FLOOR_UNCERTAINTY_INDEX];
-        if (zHeightUncertainty > 0 && zHeightUncertainty < Z_MAX_HEIGHT_UNCERTAINTY_FACTOR) {
-            mHeightAboveFloorUncertaintyMeters =
-                    Math.pow(2, Z_FLOOR_HEIGHT_FRACTION_BITS - zHeightUncertainty - 1);
-        } else {
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Decode a two's complement encoded value, to a signed double based on the field length.
-     *
-     * @param fieldValues the array of field values reprented as longs
-     * @param fieldLengths the array of field lengths
-     * @param index the index of the field being decoded
-     * @param fraction the number of fractional bits in the value
-     * @return the signed value represented as a double
-     */
-    private double decodeZUnsignedToSignedValue(long[] fieldValues, int[] fieldLengths, int index,
-            int fraction) {
-        int value = (int) fieldValues[index];
-        int maxPositiveValue = (int) Math.pow(2, fieldLengths[index] - 1) - 1;
-        if (value > maxPositiveValue) {
-            value -= Math.pow(2, fieldLengths[index]);
-        }
-        return Math.scalb(value, -fraction);
-    }
-
-    /**
-     * Parse Subelement Usage Rights
-     */
-    private boolean parseSubelementUsage(byte[] buffer) {
-        if (buffer.length != SUBELEMENT_USAGE_LENGTH1
-                && buffer.length != SUBELEMENT_USAGE_LENGTH3) {
-            return false;
-        }
-        mUsageRetransmit =
-                (buffer[SUBELEMENT_USAGE_PARAMS_INDEX] & SUBELEMENT_USAGE_MASK_RETRANSMIT) != 0;
-        mUsageRetentionExpires =
-                (buffer[SUBELEMENT_USAGE_PARAMS_INDEX] & SUBELEMENT_USAGE_MASK_RETENTION_EXPIRES)
-                        != 0;
-        mUsageExtraInfoOnAssociation =
-                (buffer[SUBELEMENT_USAGE_PARAMS_INDEX] & SUBELEMENT_USAGE_MASK_STA_LOCATION_POLICY)
-                        != 0;
-        // Note: the Retransmit flag must be true, and RetentionExpires, false for the
-        // ResponderLocation object to be usable by public applications.
-        return (mUsageRetransmit && !mUsageRetentionExpires);
-    }
-
-    /**
-     * Parse the BSSID List Subelement of the LCI IE.
-     *
-     * @param buffer a buffer containing the subelement
-     * @return boolean true indicates success
-     */
-    private boolean parseSubelementBssidList(byte[] buffer) {
-        if (buffer.length < SUBELEMENT_BSSID_LIST_MIN_BUFFER_LENGTH) {
-            return false;
-        }
-        if ((buffer.length - 1) % BYTES_IN_A_BSSID != 0) {
-            return false;
-        }
-
-        int maxBssidIndicator = (int) buffer[SUBELEMENT_BSSID_MAX_INDICATOR_INDEX] & BYTE_MASK;
-        int bssidListLength = (buffer.length - 1) / BYTES_IN_A_BSSID;
-        // The maxBSSIDIndicator is ignored. Its use is still being clarified in 802.11REVmd,
-        // which is not published at this time. This field will be used in a future
-        // release of Android after 802.11REVmd is public. Here, we interpret the following
-        // params as an explicit list of BSSIDs.
-
-
-        int bssidOffset = SUBELEMENT_BSSID_LIST_INDEX;
-        for (int i = 0; i < bssidListLength; i++) {
-            byte[] bssid = Arrays.copyOfRange(buffer, bssidOffset, bssidOffset + BYTES_IN_A_BSSID);
-            MacAddress macAddress = MacAddress.fromBytes(bssid);
-            mBssidList.add(macAddress);
-            bssidOffset += BYTES_IN_A_BSSID;
-        }
-        return true;
-    }
-
-    /**
-     * Parse the Location Civic subelement in the LCR IE.
-     *
-     * @param buffer a buffer containing the subelement
-     * @return boolean true indicates success
-     */
-    private boolean parseSubelementLocationCivic(byte[] buffer) {
-        if (buffer.length <  SUBELEMENT_LOCATION_CIVIC_MIN_LENGTH
-                || buffer.length > SUBELEMENT_LOCATION_CIVIC_MAX_LENGTH) {
-            return false;
-        }
-        mCivicLocationCountryCode =
-                new String(Arrays.copyOfRange(buffer, CIVIC_COUNTRY_CODE_INDEX,
-                        CIVIC_TLV_LIST_INDEX)).toUpperCase();
-        CivicLocation civicLocation =
-                new CivicLocation(
-                        Arrays.copyOfRange(buffer, CIVIC_TLV_LIST_INDEX, buffer.length),
-                        mCivicLocationCountryCode);
-        if (!civicLocation.isValid()) {
-            return false;
-        }
-        this.mCivicLocation = civicLocation;
-        mCivicLocationString = civicLocation.toString();
-        return true;
-    }
-
-    /**
-     * Parse the Map Image subelement in the LCR IE.
-     *
-     * @param buffer a buffer containing the subelement
-     * @return boolean true indicates success
-     */
-    private boolean parseSubelementMapImage(byte[] buffer) {
-        if (buffer.length > SUBELEMENT_MAP_IMAGE_URL_MAX_LENGTH) {
-            return false;
-        }
-        int mapImageType = buffer[SUBELEMENT_IMAGE_MAP_TYPE_INDEX];
-        int supportedTypesMax = SUPPORTED_IMAGE_FILE_EXTENSIONS.length - 1;
-        if (mapImageType < MAP_TYPE_URL_DEFINED || mapImageType > supportedTypesMax) {
-            return false;
-        }
-        this.mMapImageType = mapImageType;
-        byte[] urlBytes = Arrays.copyOfRange(buffer, 1, buffer.length);
-        mMapImageUri = Uri.parse(new String(urlBytes, StandardCharsets.UTF_8));
-        return true;
-    }
-
-    /**
-     * Convert an image type code to a Mime type
-     *
-     * @param imageTypeCode encoded as an integer
-     * @return the mime type of the image file
-     */
-    private String imageTypeToMime(int imageTypeCode, String imageUrl) {
-        int supportedExtensionsMax = SUPPORTED_IMAGE_FILE_EXTENSIONS.length - 1;
-        if ((imageTypeCode == 0 && imageUrl == null) || imageTypeCode > supportedExtensionsMax) {
-            return null;
-        }
-        MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton();
-        if (imageTypeCode == 0) {
-            return mimeTypeMap.getMimeTypeFromExtension(
-                    MimeTypeMap.getFileExtensionFromUrl(imageUrl));
-        } else {
-            return mimeTypeMap.getMimeTypeFromExtension(
-                    SUPPORTED_IMAGE_FILE_EXTENSIONS[imageTypeCode]);
-        }
-    }
-
-    /**
-     * Converts a byte array containing fields of variable size, into an array of longs where the
-     * field boundaries are defined in a constant int array passed as an argument.
-     *
-     * @param buffer        the byte array containing all the fields
-     * @param bitFieldSizes the int array defining the size of each field
-     */
-    private long[] getFieldData(byte[] buffer, int[] bitFieldSizes) {
-        int bufferLengthBits = buffer.length * Byte.SIZE;
-        int sumBitFieldSizes = 0;
-        for (int i : bitFieldSizes) {
-            if (i > Long.SIZE) {
-                return null;
-            }
-            sumBitFieldSizes += i;
-        }
-        if (bufferLengthBits != sumBitFieldSizes) {
-            return null;
-        }
-        long[] fieldData = new long[bitFieldSizes.length];
-        int bufferBitPos = 0;
-        for (int fieldIndex = 0; fieldIndex < bitFieldSizes.length; fieldIndex++) {
-            int bitFieldSize = bitFieldSizes[fieldIndex];
-            long field = 0;
-            for (int n = 0; n < bitFieldSize; n++) {
-                field |= ((long) getBitAtBitOffsetInByteArray(buffer, bufferBitPos + n) << n);
-            }
-            fieldData[fieldIndex] = field;
-            bufferBitPos += bitFieldSize;
-        }
-        return fieldData;
-    }
-
-    /**
-     * Retrieves state of a bit at the bit-offset in a byte array, where the offset represents the
-     * bytes in contiguous data with each value in big endian order.
-     *
-     * @param buffer          the data buffer of bytes containing all the fields
-     * @param bufferBitOffset the bit offset into the entire buffer
-     * @return a zero or one value, representing the state of that bit.
-     */
-    private int getBitAtBitOffsetInByteArray(byte[] buffer, int bufferBitOffset) {
-        int bufferIndex = bufferBitOffset / Byte.SIZE; // The byte index that contains the bit
-        int bitOffsetInByte = bufferBitOffset % Byte.SIZE; // The bit offset within that byte
-        int result = (buffer[bufferIndex] & (MSB_IN_BYTE >> bitOffsetInByte)) == 0 ? 0 : 1;
-        return result;
-    }
-
-    /**
-     * Reverses the order of the bits in each byte of a byte array.
-     *
-     * @param buffer the array containing each byte that will be reversed
-     */
-    private void swapEndianByteByByte(byte[] buffer) {
-        for (int n = 0; n < buffer.length; n++) {
-            byte currentByte = buffer[n];
-            byte reversedByte = 0; // Cleared value
-            byte bitSelectorMask = LSB_IN_BYTE;
-            for (int i = 0; i < Byte.SIZE; i++) {
-                reversedByte = (byte) (reversedByte << 1);
-                if ((currentByte & bitSelectorMask) != 0) {
-                    reversedByte = (byte) (reversedByte | LSB_IN_BYTE);
-                }
-                bitSelectorMask = (byte) (bitSelectorMask << 1);
-            }
-            buffer[n] = reversedByte;
-        }
-    }
-
-    /**
-     * Sets the LCI subelement fields to the default undefined values.
-     */
-    private void setLciSubelementDefaults() {
-        mIsLciValid = false;
-        mLatitudeUncertainty = UNCERTAINTY_UNDEFINED;
-        mLatitude = 0;
-        mLongitudeUncertainty = UNCERTAINTY_UNDEFINED;
-        mLongitude = 0;
-        mAltitudeType = ALTITUDE_UNDEFINED;
-        mAltitudeUncertainty = UNCERTAINTY_UNDEFINED;
-        mAltitude = 0;
-        mDatum = DATUM_UNDEFINED;
-        mLciRegisteredLocationAgreement = false;
-        mLciRegisteredLocationDse = false;
-        mLciDependentStation = false;
-        mLciVersion = 0;
-    }
-
-    /**
-     * Sets the Z subelement fields to the default values when undefined.
-     */
-    private void setZaxisSubelementDefaults() {
-        mIsZValid = false;
-        mExpectedToMove = 0;
-        mFloorNumber = 0;
-        mHeightAboveFloorMeters = 0;
-        mHeightAboveFloorUncertaintyMeters = 0;
-    }
-
-    /**
-     * Sets the Usage Policy subelement fields to the default undefined values.
-     */
-    private void setUsageSubelementDefaults() {
-        mUsageRetransmit = true;
-        mUsageRetentionExpires = false;
-        mUsageExtraInfoOnAssociation = false;
-    }
-
-    /**
-     * Sets the BSSID List subelement fields to the default values when undefined.
-     */
-    private void setBssidListSubelementDefaults() {
-        mIsBssidListValid = false;
-        mBssidList = new ArrayList<>();
-    }
-
-    /**
-     * Sets the LCR Civic Location subelement field to the default undefined value.
-     *
-     * @hide
-     */
-    public void setCivicLocationSubelementDefaults() {
-        mIsLocationCivicValid = false;
-        mCivicLocationCountryCode = "";
-        mCivicLocationString = "";
-        mCivicLocation = null;
-    }
-
-    /**
-     * Sets the LCR Map Image subelement field to the default values when undefined.
-     */
-    private void setMapImageSubelementDefaults() {
-        mIsMapImageValid = false;
-        mMapImageType = MAP_TYPE_URL_DEFINED;
-        mMapImageUri = null;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj == null || getClass() != obj.getClass()) {
-            return false;
-        }
-        ResponderLocation other = (ResponderLocation) obj;
-        return mIsValid == other.mIsValid
-                && mIsLciValid == other.mIsLciValid
-                && mIsZValid == other.mIsZValid
-                && mIsUsageValid == other.mIsUsageValid
-                && mIsBssidListValid == other.mIsBssidListValid
-                && mIsLocationCivicValid == other.mIsLocationCivicValid
-                && mIsMapImageValid == other.mIsMapImageValid
-                && mLatitudeUncertainty == other.mLatitudeUncertainty
-                && mLatitude == other.mLatitude
-                && mLongitudeUncertainty == other.mLongitudeUncertainty
-                && mLongitude == other.mLongitude
-                && mAltitudeType == other.mAltitudeType
-                && mAltitudeUncertainty == other.mAltitudeUncertainty
-                && mAltitude == other.mAltitude
-                && mDatum == other.mDatum
-                && mLciRegisteredLocationAgreement == other.mLciRegisteredLocationAgreement
-                && mLciRegisteredLocationDse == other.mLciRegisteredLocationDse
-                && mLciDependentStation == other.mLciDependentStation
-                && mLciVersion == other.mLciVersion
-                && mExpectedToMove == other.mExpectedToMove
-                && mFloorNumber == other.mFloorNumber
-                && mHeightAboveFloorMeters == other.mHeightAboveFloorMeters
-                && mHeightAboveFloorUncertaintyMeters
-                        == other.mHeightAboveFloorUncertaintyMeters
-                && mUsageRetransmit == other.mUsageRetransmit
-                && mUsageRetentionExpires == other.mUsageRetentionExpires
-                && mUsageExtraInfoOnAssociation == other.mUsageExtraInfoOnAssociation
-                && mBssidList.equals(other.mBssidList)
-                && mCivicLocationCountryCode.equals(other.mCivicLocationCountryCode)
-                && mCivicLocationString.equals(other.mCivicLocationString)
-                && Objects.equals(mCivicLocation, other.mCivicLocation)
-                && mMapImageType == other.mMapImageType
-                && Objects.equals(mMapImageUri, other.mMapImageUri);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(mIsValid, mIsLciValid, mIsZValid, mIsUsageValid, mIsBssidListValid,
-                mIsLocationCivicValid, mIsMapImageValid, mLatitudeUncertainty, mLatitude,
-                mLongitudeUncertainty, mLongitude, mAltitudeType, mAltitudeUncertainty, mAltitude,
-                mDatum, mLciRegisteredLocationAgreement,
-                mLciRegisteredLocationDse, mLciDependentStation, mLciVersion,
-                mExpectedToMove, mFloorNumber, mHeightAboveFloorMeters,
-                mHeightAboveFloorUncertaintyMeters, mUsageRetransmit, mUsageRetentionExpires,
-                mUsageExtraInfoOnAssociation, mBssidList, mCivicLocationCountryCode,
-                mCivicLocationString, mCivicLocation, mMapImageType, mMapImageUri);
-    }
-
-    /**
-     * @return true if the ResponderLocation object is valid and contains useful information
-     * relevant to the location of the Responder. If this is ever false, this object will not be
-     * available to developers, and have a null value.
-     *
-     * @hide
-     */
-    public boolean isValid() {
-        return mIsValid;
-    }
-
-    /**
-     * @return true if the LCI subelement (containing Latitude, Longitude and Altitude) is valid.
-     *
-     * <p> This method tells us if the responder has provided its Location Configuration
-     * Information (LCI) directly, and is useful when an external database of responder locations
-     * is not available</p>
-     *
-     * <p>If isLciSubelementValid() returns true, all the LCI values provided by the corresponding
-     * getter methods will have been set as described by the responder, or else if false, they
-     * should not be used and will throw an IllegalStateException.</p>
-     */
-    public boolean isLciSubelementValid() {
-        return mIsLciValid;
-    }
-
-    /**
-     * @return the latitude uncertainty in degrees.
-     * <p>
-     * Only valid if {@link #isLciSubelementValid()} returns true, or will throw an exception.
-     * </p>
-     * <p> An unknown uncertainty is indicated by 0.</p>
-     */
-    public double getLatitudeUncertainty() {
-        if (!mIsLciValid) {
-            throw new IllegalStateException(
-                "getLatitudeUncertainty(): invoked on an invalid result: mIsLciValid = false.");
-        }
-        return mLatitudeUncertainty;
-    }
-
-    /**
-     * @return the latitude in degrees
-     * <p>
-     * Only valid if {@link #isLciSubelementValid()} returns true, or will throw an exception.
-     */
-    public double getLatitude() {
-        if (!mIsLciValid) {
-            throw new IllegalStateException(
-                "getLatitude(): invoked on an invalid result: mIsLciValid = false.");
-        }
-        return mLatitude;
-    }
-
-    /**
-     * @return the Longitude uncertainty in degrees.
-     * <p>
-     * Only valid if {@link #isLciSubelementValid()} returns true, or will throw an exception.
-     * </p>
-     * <p> An unknown uncertainty is indicated by 0.</p>
-     */
-    public double getLongitudeUncertainty() {
-        if (!mIsLciValid) {
-            throw new IllegalStateException(
-                "getLongitudeUncertainty(): invoked on an invalid result: mIsLciValid = false.");
-        }
-        return mLongitudeUncertainty;
-    }
-
-    /**
-     * @return the Longitude in degrees..
-     * <p>
-     * Only valid if {@link #isLciSubelementValid()} returns true, or will throw an exception.
-     */
-    public double getLongitude() {
-        if (!mIsLciValid) {
-            throw new IllegalStateException(
-                "getLatitudeUncertainty(): invoked on an invalid result: mIsLciValid = false.");
-        }
-        return mLongitude;
-    }
-
-    /**
-     * @return the Altitude type.
-     * <p>
-     * Only valid if {@link #isLciSubelementValid()} returns true, or will throw an exception.
-     */
-    @AltitudeType
-    public int getAltitudeType() {
-        if (!mIsLciValid) {
-            throw new IllegalStateException(
-                "getLatitudeUncertainty(): invoked on an invalid result: mIsLciValid = false.");
-        }
-        return mAltitudeType;
-    }
-
-    /**
-     * @return the Altitude uncertainty in meters.
-     * <p>
-     * Only valid if {@link #isLciSubelementValid()} returns true, or will throw an exception.
-     * </p>
-     * <p>An unknown uncertainty is indicated by 0.</p>
-     */
-    public double getAltitudeUncertainty() {
-        if (!mIsLciValid) {
-            throw new IllegalStateException(
-                "getLatitudeUncertainty(): invoked on an invalid result: mIsLciValid = false.");
-        }
-        return mAltitudeUncertainty;
-    }
-
-    /**
-     * @return the Altitude in units defined by the altitude type.
-     * <p>
-     * Only valid if {@link #isLciSubelementValid()} returns true, or will throw an exception.
-     */
-    public double getAltitude() {
-        if (!mIsLciValid) {
-            throw new IllegalStateException(
-                "getAltitude(): invoked on an invalid result: mIsLciValid = false.");
-        }
-        return mAltitude;
-    }
-
-    /**
-     * @return the Datum used for the LCI positioning information.
-     * <p>
-     * Only valid if {@link #isLciSubelementValid()} returns true, or will throw an exception.
-     */
-    @DatumType
-    public int getDatum() {
-        if (!mIsLciValid) {
-            throw new IllegalStateException(
-                "getDatum(): invoked on an invalid result: mIsLciValid = false.");
-        }
-        return mDatum;
-    }
-
-    /**
-     * @return true if the station is operating within a national policy area or an international
-     * agreement area near a national border, otherwise false
-     * (see 802.11REVmc Section 11.12.3 - Registered STA Operation).
-     * <p>
-     * Only valid if {@link #isLciSubelementValid()} returns true, or will throw an exception.
-     */
-    public boolean getRegisteredLocationAgreementIndication() {
-        if (!mIsLciValid) {
-            throw new IllegalStateException(
-                "getRegisteredLocationAgreementIndication(): "
-                        + "invoked on an invalid result: mIsLciValid = false.");
-        }
-        return mLciRegisteredLocationAgreement;
-    }
-
-    /**
-     * @return true indicating this is an enabling station, enabling the operation of nearby STAs
-     * with Dynamic Station Enablement (DSE), otherwise false.
-     * (see 802.11REVmc Section 11.12.3 - Registered STA Operation).
-     * <p>
-     * Only valid if {@link #isLciSubelementValid()} returns true, or will throw an exception.
-     *
-     * @hide
-     */
-    public boolean getRegisteredLocationDseIndication() {
-        if (!mIsLciValid) {
-            throw new IllegalStateException(
-                "getRegisteredLocationDseIndication(): "
-                    + "invoked on an invalid result: mIsLciValid = false.");
-        }
-        return mLciRegisteredLocationDse;
-    }
-
-    /**
-     * @return true indicating this is a dependent station that is operating with the enablement of
-     * an enabling station whose LCI is being reported, otherwise false.
-     * (see 802.11REVmc Section 11.12.3 - Registered STA Operation).
-     * <p>
-     * Only valid if {@link #isLciSubelementValid()} returns true, or will throw an exception.
-     *
-     * @hide
-     */
-    public boolean getDependentStationIndication() {
-        if (!mIsLciValid) {
-            throw new IllegalStateException(
-                "getDependentStationIndication(): "
-                    + "invoked on an invalid result: mIsLciValid = false.");
-        }
-        return mLciDependentStation;
-    }
-
-    /**
-     * @return a value greater or equal to 1, indicating the current version number
-     * of the LCI protocol.
-     * <p>
-     * Only valid if {@link #isLciSubelementValid()} returns true, or will throw an exception.
-     */
-    public int getLciVersion() {
-        if (!mIsLciValid) {
-            throw new IllegalStateException(
-                "getLciVersion(): "
-                    + "invoked on an invalid result: mIsLciValid = false.");
-        }
-        return mLciVersion;
-    }
-
-    /**
-     * @return the LCI location represented as a {@link Location} object (best effort).
-     * <p>
-     * Only valid if {@link #isLciSubelementValid()} returns true, or will throw an exception.
-     */
-    @NonNull
-    public Location toLocation() {
-        if (!mIsLciValid) {
-            throw new IllegalStateException(
-                "toLocation(): "
-                    + "invoked on an invalid result: mIsLciValid = false.");
-        }
-        Location location = new Location(LOCATION_PROVIDER);
-        location.setLatitude(mLatitude);
-        location.setLongitude(mLongitude);
-        location.setAccuracy((float) (mLatitudeUncertainty + mLongitudeUncertainty) / 2);
-        location.setAltitude(mAltitude);
-        location.setVerticalAccuracyMeters((float) mAltitudeUncertainty);
-        location.setTime(System.currentTimeMillis());
-        return location;
-    }
-
-    /**
-     * @return if the Z subelement (containing mobility, Floor, Height above floor) is valid.
-     */
-    public boolean isZaxisSubelementValid() {
-        return mIsZValid;
-    }
-
-    /**
-     * @return an integer representing the mobility of the responder.
-     * <p>
-     * Only valid if {@link #isZaxisSubelementValid()} returns true, or will throw an exception.
-     */
-    @ExpectedToMoveType
-    public int getExpectedToMove() {
-        if (!mIsZValid) {
-            throw new IllegalStateException(
-                "getExpectedToMove(): invoked on an invalid result: mIsZValid = false.");
-        }
-        return mExpectedToMove;
-    }
-
-    /**
-     * @return the Z sub element Floor Number.
-     * <p>
-     * Only valid if {@link #isZaxisSubelementValid()} returns true, or will throw an exception.
-     * </p>
-     * <p>Note: this number can be positive or negative, with value increments of +/- 1/16 of a
-     * floor.</p>.
-     */
-    public double getFloorNumber() {
-        if (!mIsZValid) {
-            throw new IllegalStateException(
-                "getFloorNumber(): invoked on an invalid result: mIsZValid = false)");
-        }
-        return mFloorNumber;
-    }
-
-    /**
-     * @return the Z subelement Height above the floor in meters.
-     * <p>
-     * Only valid if {@link #isZaxisSubelementValid()} returns true, or will throw an exception.
-     * </p>
-     * <p>This value can be positive or negative. </p>
-     */
-    public double getHeightAboveFloorMeters() {
-        if (!mIsZValid) {
-            throw new IllegalStateException(
-                "getHeightAboveFloorMeters(): invoked on an invalid result: mIsZValid = false)");
-        }
-        return mHeightAboveFloorMeters;
-    }
-
-    /**
-     * @return the Z subelement Height above the floor uncertainty in meters.
-     * <p>
-     * Only valid if {@link #isZaxisSubelementValid()} returns true, or will throw an exception.
-     * </p>
-     * <p>An unknown uncertainty is indicated by 0.</p>
-     */
-    public double getHeightAboveFloorUncertaintyMeters() {
-        if (!mIsZValid) {
-            throw new IllegalStateException(
-                "getHeightAboveFloorUncertaintyMeters():"
-                    + "invoked on an invalid result: mIsZValid = false)");
-        }
-        return mHeightAboveFloorUncertaintyMeters;
-    }
-
-    /**
-     * @return true if the location information received from the responder can be
-     * retransmitted to another device, physically separate from the one that received it.
-     *
-     * @hide
-     */
-    public boolean getRetransmitPolicyIndication() {
-        return mUsageRetransmit;
-    }
-
-    /**
-     * @return true if location-data received should expire (and be deleted)
-     * by the time provided in the getRelativeExpirationTimeHours() method.
-     *
-     * @hide
-     */
-    public boolean getRetentionExpiresIndication() {
-        return mUsageRetentionExpires;
-    }
-
-    /**
-     * @return true if there is extra location info available on association.
-     *
-     * @hide
-     */
-    @SystemApi
-    public boolean getExtraInfoOnAssociationIndication() {
-        return mUsageExtraInfoOnAssociation;
-    }
-
-    /**
-     * @return the Immutable list of colocated BSSIDs at the responder.
-     *
-     * <p> Will return an empty list when there are no bssids listed.
-     */
-    public List<MacAddress> getColocatedBssids() {
-        return Collections.unmodifiableList(mBssidList);
-    }
-
-    /**
-     * @return the civic location represented as an {@link Address} object (best effort).
-     *
-     * <p> Will return a {@code null} when there is no Civic Location defined.
-     */
-    @Nullable
-    public Address toCivicLocationAddress() {
-        if (mCivicLocation != null && mCivicLocation.isValid()) {
-            return mCivicLocation.toAddress();
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * @return the civic location represented as a {@link SparseArray}
-     * <p>
-     * Valid keys to access the SparseArray can be found in {@code CivicLocationKeys}.
-     * </p>
-     * <p> Will return a {@code null} when there is no Civic Location defined.
-     *
-     */
-    @Nullable
-    @SuppressLint("ChangedType")
-    public SparseArray<String> toCivicLocationSparseArray() {
-        if (mCivicLocation != null && mCivicLocation.isValid()) {
-            return mCivicLocation.toSparseArray();
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * @return the civic location two upper-case ASCII character country code defined in ISO 3166.
-     *
-     * <p> Will return a {@code null} when there is no country code defined.
-     *
-     * @hide
-     */
-    @Nullable
-    public String getCivicLocationCountryCode() {
-        return mCivicLocationCountryCode;
-    }
-
-    /**
-     * @return the value of the Civic Location String associated with a key.
-     *
-     * <p> Will return a {@code null} when there is no value associated with the key provided.
-     *
-     * @param key used to find a corresponding value in the Civic Location Tuple list
-     *
-     * @hide
-     */
-    @Nullable
-    public String getCivicLocationElementValue(@CivicLocationKeysType int key) {
-        return mCivicLocation.getCivicElementValue(key);
-    }
-
-    /**
-     * @return the Map Image file Mime type, referred to by getMapImageUrl().
-     */
-    @Nullable
-    public String getMapImageMimeType() {
-        if (mMapImageUri == null) {
-            return null;
-        } else {
-            return imageTypeToMime(mMapImageType, mMapImageUri.toString());
-        }
-    }
-
-    /**
-     * @return a URI referencing a map-file showing the local floor plan.
-     *
-     * <p> Will return a {@code null} when there is no URI defined.
-     */
-    @Nullable
-    public Uri getMapImageUri() {
-        return mMapImageUri;
-    }
-}
diff --git a/wifi/java/android/net/wifi/rtt/WifiRttManager.java b/wifi/java/android/net/wifi/rtt/WifiRttManager.java
deleted file mode 100644
index 865702a..0000000
--- a/wifi/java/android/net/wifi/rtt/WifiRttManager.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.rtt;
-
-import static android.Manifest.permission.ACCESS_FINE_LOCATION;
-import static android.Manifest.permission.ACCESS_WIFI_STATE;
-import static android.Manifest.permission.CHANGE_WIFI_STATE;
-import static android.Manifest.permission.LOCATION_HARDWARE;
-
-import android.annotation.CallbackExecutor;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
-import android.annotation.SdkConstant;
-import android.annotation.SystemApi;
-import android.annotation.SystemService;
-import android.content.Context;
-import android.os.Binder;
-import android.os.RemoteException;
-import android.os.WorkSource;
-import android.util.Log;
-
-import java.util.List;
-import java.util.concurrent.Executor;
-
-/**
- * This class provides the primary API for measuring distance (range) to other devices using the
- * IEEE 802.11mc Wi-Fi Round Trip Time (RTT) technology.
- * <p>
- * The devices which can be ranged include:
- * <li>Access Points (APs)
- * <li>Wi-Fi Aware peers
- * <p>
- * Ranging requests are triggered using
- * {@link #startRanging(RangingRequest, Executor, RangingResultCallback)}. Results (in case of
- * successful operation) are returned in the {@link RangingResultCallback#onRangingResults(List)}
- * callback.
- * <p>
- *     Wi-Fi RTT may not be usable at some points, e.g. when Wi-Fi is disabled. To validate that
- *     the functionality is available use the {@link #isAvailable()} function. To track
- *     changes in RTT usability register for the {@link #ACTION_WIFI_RTT_STATE_CHANGED}
- *     broadcast. Note that this broadcast is not sticky - you should register for it and then
- *     check the above API to avoid a race condition.
- */
-@SystemService(Context.WIFI_RTT_RANGING_SERVICE)
-public class WifiRttManager {
-    private static final String TAG = "WifiRttManager";
-    private static final boolean VDBG = false;
-
-    private final Context mContext;
-    private final IWifiRttManager mService;
-
-    /**
-     * Broadcast intent action to indicate that the state of Wi-Fi RTT availability has changed.
-     * Use the {@link #isAvailable()} to query the current status.
-     * This broadcast is <b>not</b> sticky, use the {@link #isAvailable()} API after registering
-     * the broadcast to check the current state of Wi-Fi RTT.
-     * <p>Note: The broadcast is only delivered to registered receivers - no manifest registered
-     * components will be launched.
-     */
-    @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_WIFI_RTT_STATE_CHANGED =
-            "android.net.wifi.rtt.action.WIFI_RTT_STATE_CHANGED";
-
-    /** @hide */
-    public WifiRttManager(@NonNull Context context, @NonNull IWifiRttManager service) {
-        mContext = context;
-        mService = service;
-    }
-
-    /**
-     * Returns the current status of RTT API: whether or not RTT is available. To track
-     * changes in the state of RTT API register for the
-     * {@link #ACTION_WIFI_RTT_STATE_CHANGED} broadcast.
-     * <p>Note: availability of RTT does not mean that the app can use the API. The app's
-     * permissions and platform Location Mode are validated at run-time.
-     *
-     * @return A boolean indicating whether the app can use the RTT API at this time (true) or
-     * not (false).
-     */
-    public boolean isAvailable() {
-        try {
-            return mService.isAvailable();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Initiate a request to range to a set of devices specified in the {@link RangingRequest}.
-     * Results will be returned in the {@link RangingResultCallback} set of callbacks.
-     *
-     * @param request  A request specifying a set of devices whose distance measurements are
-     *                 requested.
-     * @param executor The Executor on which to run the callback.
-     * @param callback A callback for the result of the ranging request.
-     */
-    @RequiresPermission(allOf = {ACCESS_FINE_LOCATION, CHANGE_WIFI_STATE, ACCESS_WIFI_STATE})
-    public void startRanging(@NonNull RangingRequest request,
-            @NonNull @CallbackExecutor Executor executor, @NonNull RangingResultCallback callback) {
-        startRanging(null, request, executor, callback);
-    }
-
-    /**
-     * Initiate a request to range to a set of devices specified in the {@link RangingRequest}.
-     * Results will be returned in the {@link RangingResultCallback} set of callbacks.
-     *
-     * @param workSource A mechanism to specify an alternative work-source for the request.
-     * @param request  A request specifying a set of devices whose distance measurements are
-     *                 requested.
-     * @param executor The Executor on which to run the callback.
-     * @param callback A callback for the result of the ranging request.
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(allOf = {LOCATION_HARDWARE, ACCESS_FINE_LOCATION, CHANGE_WIFI_STATE,
-            ACCESS_WIFI_STATE})
-    public void startRanging(@Nullable WorkSource workSource, @NonNull RangingRequest request,
-            @NonNull @CallbackExecutor Executor executor, @NonNull RangingResultCallback callback) {
-        if (VDBG) {
-            Log.v(TAG, "startRanging: workSource=" + workSource + ", request=" + request
-                    + ", callback=" + callback + ", executor=" + executor);
-        }
-
-        if (executor == null) {
-            throw new IllegalArgumentException("Null executor provided");
-        }
-        if (callback == null) {
-            throw new IllegalArgumentException("Null callback provided");
-        }
-
-        Binder binder = new Binder();
-        try {
-            mService.startRanging(binder, mContext.getOpPackageName(),
-                    mContext.getAttributionTag(), workSource, request, new IRttCallback.Stub() {
-                        @Override
-                        public void onRangingFailure(int status) throws RemoteException {
-                            clearCallingIdentity();
-                            executor.execute(() -> callback.onRangingFailure(status));
-                        }
-
-                        @Override
-                        public void onRangingResults(List<RangingResult> results)
-                                throws RemoteException {
-                            clearCallingIdentity();
-                            executor.execute(() -> callback.onRangingResults(results));
-                        }
-                    });
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Cancel all ranging requests for the specified work sources. The requests have been requested
-     * using {@link #startRanging(WorkSource, RangingRequest, Executor, RangingResultCallback)}.
-     *
-     * @param workSource The work-sources of the requesters.
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(allOf = {LOCATION_HARDWARE})
-    public void cancelRanging(@Nullable WorkSource workSource) {
-        if (VDBG) {
-            Log.v(TAG, "cancelRanging: workSource=" + workSource);
-        }
-
-        try {
-            mService.cancelRanging(workSource);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-}
diff --git a/wifi/java/android/net/wifi/rtt/package.html b/wifi/java/android/net/wifi/rtt/package.html
deleted file mode 100644
index 4a32f52..0000000
--- a/wifi/java/android/net/wifi/rtt/package.html
+++ /dev/null
@@ -1,45 +0,0 @@
-<HTML>
-<BODY>
-<p>Provides classes which allow applications to use Wi-Fi RTT (IEEE 802.11mc) to measure distance
-    to supporting Access Points and peer devices.</p>
-<p>The primary entry point to Wi-Fi RTT capabilities is the
-    {@link android.net.wifi.rtt.WifiRttManager} class, which is acquired by calling
-    {@link android.content.Context#getSystemService(String)
-    Context.getSystemService(Context.WIFI_RTT_RANGING_SERVICE)}</p>
-
-<p>Some APIs may require the following user permissions:</p>
-<ul>
-    <li>{@link android.Manifest.permission#ACCESS_WIFI_STATE}</li>
-    <li>{@link android.Manifest.permission#CHANGE_WIFI_STATE}</li>
-    <li>{@link android.Manifest.permission#ACCESS_FINE_LOCATION}</li>
-</ul>
-<p>Usage of the API is also gated by the device's Location Mode: whether it permits Wi-Fi based
-location to be queried.</p>
-
-<p class="note"><strong>Note:</strong> Not all Android-powered devices support Wi-Fi RTT
-    functionality.
-    If your application only works with Wi-Fi RTT (i.e. it should only be installed on devices which
-    support Wi-Fi RTT), declare so with a <a
-            href="{@docRoot}guide/topics/manifest/uses-feature-element.html">
-        {@code <uses-feature>}</a>
-    element in the manifest file:</p>
-<pre>
-&lt;manifest ...>
-    &lt;uses-feature android:name="android.hardware.wifi.rtt" />
-    ...
-&lt;/manifest>
-</pre>
-<p>Alternatively, if your application does not require Wi-Fi RTT but can take advantage of it if
-    available, you can perform
-    the check at run-time in your code using {@link
-    android.content.pm.PackageManager#hasSystemFeature(String)} with {@link
-    android.content.pm.PackageManager#FEATURE_WIFI_RTT}:</p>
-<pre>
-    getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_RTT)
-</pre>
-
-<p>For an example of this functionality, see
-<a href="{@docRoot}guide/topics/connectivity/wifi-rtt" class="external">Wi-Fi location: ranging
-with RTT</a>.</p>
-</BODY>
-</HTML>
diff --git a/wifi/java/android/net/wifi/util/HexEncoding.java b/wifi/java/android/net/wifi/util/HexEncoding.java
deleted file mode 100644
index 9ebf947..0000000
--- a/wifi/java/android/net/wifi/util/HexEncoding.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.util;
-
-/**
- * Hexadecimal encoding where each byte is represented by two hexadecimal digits.
- *
- * Note: this is copied from {@link libcore.util.HexEncoding}.
- *
- * @hide
- */
-public class HexEncoding {
-
-    private static final char[] LOWER_CASE_DIGITS = {
-            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
-    };
-
-    private static final char[] UPPER_CASE_DIGITS = {
-            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
-    };
-
-    /** Hidden constructor to prevent instantiation. */
-    private HexEncoding() {}
-
-    /**
-     * Encodes the provided byte as a two-digit hexadecimal String value.
-     */
-    public static String encodeToString(byte b, boolean upperCase) {
-        char[] digits = upperCase ? UPPER_CASE_DIGITS : LOWER_CASE_DIGITS;
-        char[] buf = new char[2]; // We always want two digits.
-        buf[0] = digits[(b >> 4) & 0xf];
-        buf[1] = digits[b & 0xf];
-        return new String(buf, 0, 2);
-    }
-
-    /**
-     * Encodes the provided data as a sequence of hexadecimal characters.
-     */
-    public static char[] encode(byte[] data) {
-        return encode(data, 0, data.length, true /* upperCase */);
-    }
-
-    /**
-     * Encodes the provided data as a sequence of hexadecimal characters.
-     */
-    public static char[] encode(byte[] data, boolean upperCase) {
-        return encode(data, 0, data.length, upperCase);
-    }
-
-    /**
-     * Encodes the provided data as a sequence of hexadecimal characters.
-     */
-    public static char[] encode(byte[] data, int offset, int len) {
-        return encode(data, offset, len, true /* upperCase */);
-    }
-
-    /**
-     * Encodes the provided data as a sequence of hexadecimal characters.
-     */
-    private static char[] encode(byte[] data, int offset, int len, boolean upperCase) {
-        char[] digits = upperCase ? UPPER_CASE_DIGITS : LOWER_CASE_DIGITS;
-        char[] result = new char[len * 2];
-        for (int i = 0; i < len; i++) {
-            byte b = data[offset + i];
-            int resultIndex = 2 * i;
-            result[resultIndex] = (digits[(b >> 4) & 0x0f]);
-            result[resultIndex + 1] = (digits[b & 0x0f]);
-        }
-
-        return result;
-    }
-
-    /**
-     * Encodes the provided data as a sequence of hexadecimal characters.
-     */
-    public static String encodeToString(byte[] data) {
-        return encodeToString(data, true /* upperCase */);
-    }
-
-    /**
-     * Encodes the provided data as a sequence of hexadecimal characters.
-     */
-    public static String encodeToString(byte[] data, boolean upperCase) {
-        return new String(encode(data, upperCase));
-    }
-
-    /**
-     * Decodes the provided hexadecimal string into a byte array.  Odd-length inputs
-     * are not allowed.
-     *
-     * Throws an {@code IllegalArgumentException} if the input is malformed.
-     */
-    public static byte[] decode(String encoded) throws IllegalArgumentException {
-        return decode(encoded.toCharArray());
-    }
-
-    /**
-     * Decodes the provided hexadecimal string into a byte array. If {@code allowSingleChar}
-     * is {@code true} odd-length inputs are allowed and the first character is interpreted
-     * as the lower bits of the first result byte.
-     *
-     * Throws an {@code IllegalArgumentException} if the input is malformed.
-     */
-    public static byte[] decode(String encoded, boolean allowSingleChar)
-            throws IllegalArgumentException {
-        return decode(encoded.toCharArray(), allowSingleChar);
-    }
-
-    /**
-     * Decodes the provided hexadecimal string into a byte array.  Odd-length inputs
-     * are not allowed.
-     *
-     * Throws an {@code IllegalArgumentException} if the input is malformed.
-     */
-    public static byte[] decode(char[] encoded) throws IllegalArgumentException {
-        return decode(encoded, false);
-    }
-
-    /**
-     * Decodes the provided hexadecimal string into a byte array. If {@code allowSingleChar}
-     * is {@code true} odd-length inputs are allowed and the first character is interpreted
-     * as the lower bits of the first result byte.
-     *
-     * Throws an {@code IllegalArgumentException} if the input is malformed.
-     */
-    public static byte[] decode(char[] encoded, boolean allowSingleChar)
-            throws IllegalArgumentException {
-        int encodedLength = encoded.length;
-        int resultLengthBytes = (encodedLength + 1) / 2;
-        byte[] result = new byte[resultLengthBytes];
-
-        int resultOffset = 0;
-        int i = 0;
-        if (allowSingleChar) {
-            if ((encodedLength % 2) != 0) {
-                // Odd number of digits -- the first digit is the lower 4 bits of the first result
-                // byte.
-                result[resultOffset++] = (byte) toDigit(encoded, i);
-                i++;
-            }
-        } else {
-            if ((encodedLength % 2) != 0) {
-                throw new IllegalArgumentException("Invalid input length: " + encodedLength);
-            }
-        }
-
-        for (; i < encodedLength; i += 2) {
-            result[resultOffset++] = (byte) ((toDigit(encoded, i) << 4) | toDigit(encoded, i + 1));
-        }
-
-        return result;
-    }
-
-    private static int toDigit(char[] str, int offset) throws IllegalArgumentException {
-        // NOTE: that this isn't really a code point in the traditional sense, since we're
-        // just rejecting surrogate pairs outright.
-        int pseudoCodePoint = str[offset];
-
-        if ('0' <= pseudoCodePoint && pseudoCodePoint <= '9') {
-            return pseudoCodePoint - '0';
-        } else if ('a' <= pseudoCodePoint && pseudoCodePoint <= 'f') {
-            return 10 + (pseudoCodePoint - 'a');
-        } else if ('A' <= pseudoCodePoint && pseudoCodePoint <= 'F') {
-            return 10 + (pseudoCodePoint - 'A');
-        }
-
-        throw new IllegalArgumentException("Illegal char: " + str[offset] + " at offset " + offset);
-    }
-}
diff --git a/wifi/non-updatable/java/src/android/net/wifi/SoftApConfToXmlMigrationUtil.java b/wifi/java/src/android/net/wifi/SoftApConfToXmlMigrationUtil.java
similarity index 100%
rename from wifi/non-updatable/java/src/android/net/wifi/SoftApConfToXmlMigrationUtil.java
rename to wifi/java/src/android/net/wifi/SoftApConfToXmlMigrationUtil.java
diff --git a/wifi/non-updatable/java/src/android/net/wifi/WifiMigration.java b/wifi/java/src/android/net/wifi/WifiMigration.java
similarity index 100%
rename from wifi/non-updatable/java/src/android/net/wifi/WifiMigration.java
rename to wifi/java/src/android/net/wifi/WifiMigration.java
diff --git a/wifi/non-updatable/java/src/android/net/wifi/WifiNetworkScoreCache.java b/wifi/java/src/android/net/wifi/WifiNetworkScoreCache.java
similarity index 100%
rename from wifi/non-updatable/java/src/android/net/wifi/WifiNetworkScoreCache.java
rename to wifi/java/src/android/net/wifi/WifiNetworkScoreCache.java
diff --git a/wifi/non-updatable/java/src/android/net/wifi/nl80211/ChannelSettings.java b/wifi/java/src/android/net/wifi/nl80211/ChannelSettings.java
similarity index 100%
rename from wifi/non-updatable/java/src/android/net/wifi/nl80211/ChannelSettings.java
rename to wifi/java/src/android/net/wifi/nl80211/ChannelSettings.java
diff --git a/wifi/non-updatable/java/src/android/net/wifi/nl80211/DeviceWiphyCapabilities.java b/wifi/java/src/android/net/wifi/nl80211/DeviceWiphyCapabilities.java
similarity index 100%
rename from wifi/non-updatable/java/src/android/net/wifi/nl80211/DeviceWiphyCapabilities.java
rename to wifi/java/src/android/net/wifi/nl80211/DeviceWiphyCapabilities.java
diff --git a/wifi/non-updatable/java/src/android/net/wifi/nl80211/HiddenNetwork.java b/wifi/java/src/android/net/wifi/nl80211/HiddenNetwork.java
similarity index 100%
rename from wifi/non-updatable/java/src/android/net/wifi/nl80211/HiddenNetwork.java
rename to wifi/java/src/android/net/wifi/nl80211/HiddenNetwork.java
diff --git a/wifi/non-updatable/java/src/android/net/wifi/nl80211/NativeScanResult.java b/wifi/java/src/android/net/wifi/nl80211/NativeScanResult.java
similarity index 100%
rename from wifi/non-updatable/java/src/android/net/wifi/nl80211/NativeScanResult.java
rename to wifi/java/src/android/net/wifi/nl80211/NativeScanResult.java
diff --git a/wifi/non-updatable/java/src/android/net/wifi/nl80211/NativeWifiClient.java b/wifi/java/src/android/net/wifi/nl80211/NativeWifiClient.java
similarity index 100%
rename from wifi/non-updatable/java/src/android/net/wifi/nl80211/NativeWifiClient.java
rename to wifi/java/src/android/net/wifi/nl80211/NativeWifiClient.java
diff --git a/wifi/non-updatable/java/src/android/net/wifi/nl80211/PnoNetwork.java b/wifi/java/src/android/net/wifi/nl80211/PnoNetwork.java
similarity index 100%
rename from wifi/non-updatable/java/src/android/net/wifi/nl80211/PnoNetwork.java
rename to wifi/java/src/android/net/wifi/nl80211/PnoNetwork.java
diff --git a/wifi/non-updatable/java/src/android/net/wifi/nl80211/PnoSettings.java b/wifi/java/src/android/net/wifi/nl80211/PnoSettings.java
similarity index 100%
rename from wifi/non-updatable/java/src/android/net/wifi/nl80211/PnoSettings.java
rename to wifi/java/src/android/net/wifi/nl80211/PnoSettings.java
diff --git a/wifi/non-updatable/java/src/android/net/wifi/nl80211/RadioChainInfo.java b/wifi/java/src/android/net/wifi/nl80211/RadioChainInfo.java
similarity index 100%
rename from wifi/non-updatable/java/src/android/net/wifi/nl80211/RadioChainInfo.java
rename to wifi/java/src/android/net/wifi/nl80211/RadioChainInfo.java
diff --git a/wifi/non-updatable/java/src/android/net/wifi/nl80211/SingleScanSettings.java b/wifi/java/src/android/net/wifi/nl80211/SingleScanSettings.java
similarity index 100%
rename from wifi/non-updatable/java/src/android/net/wifi/nl80211/SingleScanSettings.java
rename to wifi/java/src/android/net/wifi/nl80211/SingleScanSettings.java
diff --git a/wifi/non-updatable/java/src/android/net/wifi/nl80211/WifiNl80211Manager.java b/wifi/java/src/android/net/wifi/nl80211/WifiNl80211Manager.java
similarity index 100%
rename from wifi/non-updatable/java/src/android/net/wifi/nl80211/WifiNl80211Manager.java
rename to wifi/java/src/android/net/wifi/nl80211/WifiNl80211Manager.java
diff --git a/wifi/non-updatable/migration_samples/README.txt b/wifi/migration_samples/README.txt
similarity index 100%
rename from wifi/non-updatable/migration_samples/README.txt
rename to wifi/migration_samples/README.txt
diff --git a/wifi/non-updatable/migration_samples/Shared_WifiConfigStore.xml b/wifi/migration_samples/Shared_WifiConfigStore.xml
similarity index 100%
rename from wifi/non-updatable/migration_samples/Shared_WifiConfigStore.xml
rename to wifi/migration_samples/Shared_WifiConfigStore.xml
diff --git a/wifi/non-updatable/migration_samples/Shared_WifiConfigStoreSoftAp.xml b/wifi/migration_samples/Shared_WifiConfigStoreSoftAp.xml
similarity index 100%
rename from wifi/non-updatable/migration_samples/Shared_WifiConfigStoreSoftAp.xml
rename to wifi/migration_samples/Shared_WifiConfigStoreSoftAp.xml
diff --git a/wifi/non-updatable/migration_samples/User_WifiConfigStore.xml b/wifi/migration_samples/User_WifiConfigStore.xml
similarity index 100%
rename from wifi/non-updatable/migration_samples/User_WifiConfigStore.xml
rename to wifi/migration_samples/User_WifiConfigStore.xml
diff --git a/wifi/non-updatable/migration_samples/User_WifiConfigStoreNetworkSuggestions.xml b/wifi/migration_samples/User_WifiConfigStoreNetworkSuggestions.xml
similarity index 100%
rename from wifi/non-updatable/migration_samples/User_WifiConfigStoreNetworkSuggestions.xml
rename to wifi/migration_samples/User_WifiConfigStoreNetworkSuggestions.xml
diff --git a/wifi/non-updatable/tests/Android.bp b/wifi/non-updatable/tests/Android.bp
deleted file mode 100644
index 3f5cacf..0000000
--- a/wifi/non-updatable/tests/Android.bp
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright (C) 2020 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-android_test {
-    name: "FrameworksWifiNonUpdatableApiTests",
-
-    defaults: ["framework-wifi-test-defaults"],
-
-    srcs: ["src/**/*.java"],
-
-    jacoco: {
-        include_filter: ["android.net.wifi.*"],
-        // TODO(b/147521214) need to exclude test classes
-        exclude_filter: [],
-    },
-
-    static_libs: [
-        "androidx.test.rules",
-        "frameworks-base-testutils",
-        "guava",
-        "mockito-target-minus-junit4",
-        "truth-prebuilt",
-    ],
-
-    libs: [
-        "android.test.runner",
-        "android.test.base",
-    ],
-
-    test_suites: [
-        "general-tests",
-    ],
-}
diff --git a/wifi/non-updatable/tests/AndroidManifest.xml b/wifi/non-updatable/tests/AndroidManifest.xml
deleted file mode 100644
index b4b6b2d..0000000
--- a/wifi/non-updatable/tests/AndroidManifest.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2020 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-     package="android.net.wifi.test">
-
-    <application>
-        <uses-library android:name="android.test.runner"/>
-        <activity android:label="WifiTestDummyLabel"
-             android:name="WifiTestDummyName"
-             android:exported="true">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN"/>
-                <category android:name="android.intent.category.LAUNCHER"/>
-            </intent-filter>
-        </activity>
-    </application>
-
-    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
-         android:targetPackage="android.net.wifi.test"
-         android:label="Frameworks Wifi Non-updatable API Tests">
-    </instrumentation>
-
-</manifest>
diff --git a/wifi/non-updatable/tests/AndroidTest.xml b/wifi/non-updatable/tests/AndroidTest.xml
deleted file mode 100644
index 5f3fdd4..0000000
--- a/wifi/non-updatable/tests/AndroidTest.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2020 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<configuration description="Runs Frameworks Wifi Non-updatable API Tests.">
-    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
-        <option name="test-file-name" value="FrameworksWifiNonUpdatableApiTests.apk" />
-    </target_preparer>
-
-    <option name="test-suite-tag" value="apct" />
-    <option name="test-tag" value="FrameworksWifiNonUpdatableApiTests" />
-    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
-        <option name="package" value="android.net.wifi.test" />
-        <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
-        <option name="hidden-api-checks" value="false"/>
-    </test>
-</configuration>
diff --git a/wifi/non-updatable/tests/README.md b/wifi/non-updatable/tests/README.md
deleted file mode 100644
index ad535f4..0000000
--- a/wifi/non-updatable/tests/README.md
+++ /dev/null
@@ -1,32 +0,0 @@
-# Wifi Non-Updatable Framework Unit Tests
-This package contains unit tests for the non-updatable part (i.e. outside the Wifi module) of the
-Android Wifi framework APIs based on the
-[Android Testing Support Library](http://developer.android.com/tools/testing-support-library/index.html).
-The test cases are built using the [JUnit](http://junit.org/) and [Mockito](http://mockito.org/)
-libraries.
-
-## Running Tests
-The easiest way to run tests is simply run
-
-```
-atest android.net.wifi
-```
-
-To pick up changes in framework/base, you will need to:
-1. rebuild the framework library 'make -j32'
-2. sync over the updated library to the device 'adb sync'
-3. restart framework on the device 'adb shell stop' then 'adb shell start'
-
-To enable syncing data to the device for first time after clean reflash:
-1. adb disable-verity
-2. adb reboot
-3. adb remount
-
-## Adding Tests
-Tests can be added by adding classes to the src directory. JUnit4 style test cases can
-be written by simply annotating test methods with `org.junit.Test`.
-
-## Debugging Tests
-If you are trying to debug why tests are not doing what you expected, you can add android log
-statements and use logcat to view them. The beginning and end of every tests is automatically logged
-with the tag `TestRunner`.
diff --git a/wifi/tests/Android.bp b/wifi/tests/Android.bp
index b3979c7..3f5cacf 100644
--- a/wifi/tests/Android.bp
+++ b/wifi/tests/Android.bp
@@ -12,15 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-// Make test APK
-// ============================================================
-
 android_test {
-    name: "FrameworksWifiApiTests",
+    name: "FrameworksWifiNonUpdatableApiTests",
 
     defaults: ["framework-wifi-test-defaults"],
 
-    srcs: ["**/*.java"],
+    srcs: ["src/**/*.java"],
 
     jacoco: {
         include_filter: ["android.net.wifi.*"],
@@ -30,12 +27,9 @@
 
     static_libs: [
         "androidx.test.rules",
-        "core-test-rules",
+        "frameworks-base-testutils",
         "guava",
         "mockito-target-minus-junit4",
-        "net-tests-utils",
-        "net-utils-framework-common",
-        "frameworks-base-testutils",
         "truth-prebuilt",
     ],
 
@@ -46,6 +40,5 @@
 
     test_suites: [
         "general-tests",
-        "mts",
     ],
 }
diff --git a/wifi/tests/AndroidManifest.xml b/wifi/tests/AndroidManifest.xml
index b6c38bc..b4b6b2d 100644
--- a/wifi/tests/AndroidManifest.xml
+++ b/wifi/tests/AndroidManifest.xml
@@ -1,7 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
-
 <!--
-  ~ Copyright (C) 2016 The Android Open Source Project
+  ~ Copyright (C) 2020 The Android Open Source Project
   ~
   ~ Licensed under the Apache License, Version 2.0 (the "License");
   ~ you may not use this file except in compliance with the License.
@@ -17,22 +16,23 @@
   -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.net.wifi.test">
+     package="android.net.wifi.test">
 
     <application>
-        <uses-library android:name="android.test.runner" />
+        <uses-library android:name="android.test.runner"/>
         <activity android:label="WifiTestDummyLabel"
-                  android:name="WifiTestDummyName">
+             android:name="WifiTestDummyName"
+             android:exported="true">
             <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
+                <action android:name="android.intent.action.MAIN"/>
                 <category android:name="android.intent.category.LAUNCHER"/>
             </intent-filter>
         </activity>
     </application>
 
     <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
-        android:targetPackage="android.net.wifi.test"
-        android:label="Frameworks Wifi API Tests">
+         android:targetPackage="android.net.wifi.test"
+         android:label="Frameworks Wifi Non-updatable API Tests">
     </instrumentation>
 
 </manifest>
diff --git a/wifi/tests/AndroidTest.xml b/wifi/tests/AndroidTest.xml
index 5d0839b..5f3fdd4 100644
--- a/wifi/tests/AndroidTest.xml
+++ b/wifi/tests/AndroidTest.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
+<!-- Copyright (C) 2020 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -13,24 +13,16 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<configuration description="Runs Frameworks Wifi API Tests.">
+<configuration description="Runs Frameworks Wifi Non-updatable API Tests.">
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
-        <option name="test-file-name" value="FrameworksWifiApiTests.apk" />
+        <option name="test-file-name" value="FrameworksWifiNonUpdatableApiTests.apk" />
     </target_preparer>
 
     <option name="test-suite-tag" value="apct" />
-    <option name="test-tag" value="FrameworksWifiApiTests" />
-    <option name="config-descriptor:metadata" key="mainline-param"
-        value="com.google.android.wifi.apex" />
+    <option name="test-tag" value="FrameworksWifiNonUpdatableApiTests" />
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="android.net.wifi.test" />
         <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
         <option name="hidden-api-checks" value="false"/>
     </test>
-
-    <!-- Only run FrameworksWifiApiTests in MTS if the Wifi Mainline module is installed. -->
-    <object type="module_controller"
-            class="com.android.tradefed.testtype.suite.module.MainlineTestModuleController">
-        <option name="mainline-module-package-name" value="com.google.android.wifi" />
-    </object>
 </configuration>
diff --git a/wifi/tests/README.md b/wifi/tests/README.md
index f909404..ad535f4 100644
--- a/wifi/tests/README.md
+++ b/wifi/tests/README.md
@@ -1,5 +1,6 @@
-# Wifi Unit Tests
-This package contains unit tests for the android wifi framework APIs based on the
+# Wifi Non-Updatable Framework Unit Tests
+This package contains unit tests for the non-updatable part (i.e. outside the Wifi module) of the
+Android Wifi framework APIs based on the
 [Android Testing Support Library](http://developer.android.com/tools/testing-support-library/index.html).
 The test cases are built using the [JUnit](http://junit.org/) and [Mockito](http://mockito.org/)
 libraries.
diff --git a/wifi/tests/assets/hsr1/HSR1ProfileWithCACert.base64 b/wifi/tests/assets/hsr1/HSR1ProfileWithCACert.base64
deleted file mode 100644
index 760c839..0000000
--- a/wifi/tests/assets/hsr1/HSR1ProfileWithCACert.base64
+++ /dev/null
@@ -1,86 +0,0 @@
-TUlNRS1WZXJzaW9uOiAxLjAKQ29udGVudC1UeXBlOiBtdWx0aXBhcnQvbWl4ZWQ7IGJvdW5kYXJ5
-PXtib3VuZGFyeX07IGNoYXJzZXQ9VVRGLTgKQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogYmFz
-ZTY0CgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi94LXBhc3Nwb2ludC1w
-cm9maWxlOyBjaGFyc2V0PVVURi04CkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IGJhc2U2NAoK
-UEUxbmJYUlVjbVZsSUhodGJHNXpQU0p6ZVc1amJXdzZaRzFrWkdZeExqSWlQZ29nSUR4V1pYSkVW
-RVErTVM0eVBDOVdaWEpFVkVRKwpDaUFnUEU1dlpHVStDaUFnSUNBOFRtOWtaVTVoYldVK1VHVnlV
-SEp2ZG1sa1pYSlRkV0p6WTNKcGNIUnBiMjQ4TDA1dlpHVk9ZVzFsClBnb2dJQ0FnUEZKVVVISnZj
-R1Z5ZEdsbGN6NEtJQ0FnSUNBZ1BGUjVjR1UrQ2lBZ0lDQWdJQ0FnUEVSRVJrNWhiV1UrZFhKdU9u
-ZG0KWVRwdGJ6cG9iM1J6Y0c5ME1tUnZkREF0Y0dWeWNISnZkbWxrWlhKemRXSnpZM0pwY0hScGIy
-NDZNUzR3UEM5RVJFWk9ZVzFsUGdvZwpJQ0FnSUNBOEwxUjVjR1UrQ2lBZ0lDQThMMUpVVUhKdmNH
-VnlkR2xsY3o0S0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBOFRtOWtaVTVoCmJXVSthVEF3TVR3dlRt
-OWtaVTVoYldVK0NpQWdJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQWdJRHhPYjJSbFRtRnRaVDVJYjIx
-bFUxQTgKTDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEU1
-dlpHVk9ZVzFsUGtaeWFXVnVaR3g1VG1GdApaVHd2VG05a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNB
-OFZtRnNkV1UrUlhoaGJYQnNaU0JPWlhSM2IzSnJQQzlXWVd4MVpUNEtJQ0FnCklDQWdJQ0E4TDA1
-dlpHVStDaUFnSUNBZ0lDQWdQRTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrWlU1aGJXVStSbEZF
-VGp3dlRtOWsKWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0E4Vm1Gc2RXVSthRzkwYzNCdmRDNWxlR0Z0
-Y0d4bExtNWxkRHd2Vm1Gc2RXVStDaUFnSUNBZwpJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJRHhP
-YjJSbFBnb2dJQ0FnSUNBZ0lDQWdQRTV2WkdWT1lXMWxQbEp2WVcxcGJtZERiMjV6CmIzSjBhWFZ0
-VDBrOEwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBqRXhNakl6TXl3ME5EVTFO
-alk4TDFaaGJIVmwKUGdvZ0lDQWdJQ0FnSUR3dlRtOWtaVDRLSUNBZ0lDQWdQQzlPYjJSbFBnb2dJ
-Q0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0E4VG05awpaVTVoYldVK1EzSmxaR1Z1ZEdsaGJEd3ZU
-bTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdQRTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrClpVNWhi
-V1UrVW1WaGJHMDhMMDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQbVY0WVcxd2JH
-VXVZMjl0UEM5V1lXeDEKWlQ0S0lDQWdJQ0FnSUNBOEwwNXZaR1UrQ2lBZ0lDQWdJQ0FnUEU1dlpH
-VStDaUFnSUNBZ0lDQWdJQ0E4VG05a1pVNWhiV1UrVlhObApjbTVoYldWUVlYTnpkMjl5WkR3dlRt
-OWtaVTVoYldVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrWlQ0S0lDQWdJQ0FnSUNBZ0lDQWdQRTV2ClpH
-Vk9ZVzFsUGxWelpYSnVZVzFsUEM5T2IyUmxUbUZ0WlQ0S0lDQWdJQ0FnSUNBZ0lDQWdQRlpoYkhW
-bFBuVnpaWEk4TDFaaGJIVmwKUGdvZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNB
-Z1BFNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lEeE9iMlJsVG1GdApaVDVRWVhOemQyOXlaRHd2VG05
-a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lEeFdZV3gxWlQ1alIwWjZZek5rZG1OdFVUMDhMMVpo
-CmJIVmxQZ29nSUNBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEU1dlpHVStDaUFn
-SUNBZ0lDQWdJQ0FnSUR4T2IyUmwKVG1GdFpUNUZRVkJOWlhSb2IyUThMMDV2WkdWT1lXMWxQZ29n
-SUNBZ0lDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0FnSUNBZwpJQ0E4VG05a1pVNWhiV1Ur
-UlVGUVZIbHdaVHd2VG05a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBqSXhQ
-QzlXCllXeDFaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThU
-bTlrWlQ0S0lDQWdJQ0FnSUNBZ0lDQWcKSUNBOFRtOWtaVTVoYldVK1NXNXVaWEpOWlhSb2IyUThM
-MDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnSUNBZ0lEeFdZV3gxWlQ1TgpVeTFEU0VGUUxWWXlQ
-QzlXWVd4MVpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEM5T2Iy
-UmxQZ29nCklDQWdJQ0FnSUR3dlRtOWtaVDRLSUNBZ0lDQWdJQ0E4VG05a1pUNEtJQ0FnSUNBZ0lD
-QWdJRHhPYjJSbFRtRnRaVDVFYVdkcGRHRnMKUTJWeWRHbG1hV05oZEdVOEwwNXZaR1ZPWVcxbFBn
-b2dJQ0FnSUNBZ0lDQWdQRTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJSbApUbUZ0WlQ1RFpY
-SjBhV1pwWTJGMFpWUjVjR1U4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThWbUZzZFdV
-K2VEVXdPWFl6ClBDOVdZV3gxWlQ0S0lDQWdJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJQ0FnSUNB
-Z0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ0lDQTgKVG05a1pVNWhiV1UrUTJWeWRGTklRVEkxTmta
-cGJtZGxjbkJ5YVc1MFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEZaaApiSFZsUGpG
-bU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaakZt
-TVdZeFpqRm1NV1l4ClpqRm1NV1l4WmpGbU1XWThMMVpoYkhWbFBnb2dJQ0FnSUNBZ0lDQWdQQzlP
-YjJSbFBnb2dJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWcKSUNBZ0lDQThUbTlrWlQ0S0lDQWdJQ0Fn
-SUNBZ0lEeE9iMlJsVG1GdFpUNVRTVTA4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZwpQRTV2
-WkdVK0NpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJSbFRtRnRaVDVKVFZOSlBDOU9iMlJsVG1GdFpUNEtJ
-Q0FnSUNBZ0lDQWdJQ0FnClBGWmhiSFZsUGpFeU16UTFOaW84TDFaaGJIVmxQZ29nSUNBZ0lDQWdJ
-Q0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEU1dlpHVSsKQ2lBZ0lDQWdJQ0FnSUNBZ0lEeE9i
-MlJsVG1GdFpUNUZRVkJVZVhCbFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEZaaApi
-SFZsUGpJelBDOVdZV3gxWlQ0S0lDQWdJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJQ0FnSUNBOEww
-NXZaR1UrQ2lBZ0lDQWdJRHd2ClRtOWtaVDRLSUNBZ0lEd3ZUbTlrWlQ0S0lDQThMMDV2WkdVK0Nq
-d3ZUV2R0ZEZSeVpXVSsKCi0te2JvdW5kYXJ5fQpDb250ZW50LVR5cGU6IGFwcGxpY2F0aW9uL3gt
-eDUwOS1jYS1jZXJ0CkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IGJhc2U2NAoKTFMwdExTMUNS
-VWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVUkxSRU5EUVdoRFowRjNTVUpCWjBsS1FV
-bE1iRVprZDNwTQpWblZ5VFVFd1IwTlRjVWRUU1dJelJGRkZRa04zVlVGTlFrbDRSVVJCVDBKblRs
-WUtRa0ZOVkVJd1ZrSlZRMEpFVVZSRmQwaG9ZMDVOClZGbDNUVlJGZVUxVVJURk5SRVV4VjJoalRr
-MXFXWGROVkVFMVRWUkZNVTFFUlRGWGFrRlRUVkpCZHdwRVoxbEVWbEZSUkVWM1pFWlIKVmtGblVU
-QkZlRTFKU1VKSmFrRk9RbWRyY1docmFVYzVkekJDUVZGRlJrRkJUME5CVVRoQlRVbEpRa05uUzBO
-QlVVVkJDbnB1UVZCVgplakkyVFhOaFpUUjNjelF6WTNwU05ERXZTakpSZEhKVFNWcFZTMjFXVlhO
-V2RXMUVZbGxJY2xCT2RsUllTMU5OV0VGalpYZFBVa1JSCldWZ0tVbkYyU0had2JqaERjMk5DTVN0
-dlIxaGFka2gzZUdvMGVsWXdWMHR2U3pKNlpWaHJZWFV6ZG1ONWJETklTVXQxY0VwbWNUSlUKUlVG
-RFpXWldhbW93ZEFwS1Z5dFlNelZRUjFkd09TOUlOWHBKVlU1V1RsWnFVemRWYlhNNE5FbDJTMmhT
-UWpnMU1USlFRamxWZVVoaApaMWhaVmxnMVIxZHdRV05XY0hsbWNteFNDa1pKT1ZGa2FHZ3JVR0py
-TUhWNWEzUmtZbVl2UTJSbVowaFBiMlZpY2xSMGQxSnNhazB3CmIwUjBXQ3N5UTNZMmFqQjNRa3Mz
-YUVRNGNGQjJaakVyZFhrS1IzcGplbWxuUVZVdk5FdDNOMlZhY1hsa1pqbENLelZTZFhCU0swbGEK
-YVhCWU5ERjRSV2xKY2t0U2QzRnBOVEUzVjFkNldHTnFZVWN5WTA1aVpqUTFNUXA0Y0VnMVVHNVdN
-Mmt4ZEhFd05HcE5SMUZWZWtaMwpTVVJCVVVGQ2J6UkhRVTFJTkhkSVVWbEVWbEl3VDBKQ1dVVkdT
-WGRZTkhaek9FSnBRbU5UWTI5a0NqVnViMXBJVWswNFJUUXJhVTFGClNVZEJNVlZrU1hkUk4wMUVi
-VUZHU1hkWU5IWnpPRUpwUW1OVFkyOWtOVzV2V2toU1RUaEZOQ3RwYjFKaGEwWkVRVk1LVFZKQmQw
-Um4KV1VSV1VWRkVSWGRrUmxGV1FXZFJNRVY0WjJkclFXZDFWVll6UkUxMFZ6WnpkMFJCV1VSV1Vq
-QlVRa0ZWZDBGM1JVSXZla0ZNUW1kTwpWZ3BJVVRoRlFrRk5RMEZSV1hkRVVWbEtTMjlhU1doMlkw
-NUJVVVZNUWxGQlJHZG5SVUpCUm1aUmNVOVVRVGRTZGpkTEsyeDFVVGR3CmJtRnpORUpaZDBoRkNq
-bEhSVkF2ZFc5b2RqWkxUM2t3VkVkUlJtSnlVbFJxUm05TVZrNUNPVUphTVhsdFRVUmFNQzlVU1hk
-SlZXTTMKZDJrM1lUaDBOVzFGY1ZsSU1UVXpkMWNLWVZkdmIybFRhbmxNVEdoMVNUUnpUbkpPUTA5
-MGFYTmtRbkV5Y2pKTlJsaDBObWd3YlVGUgpXVTlRZGpoU09FczNMMlpuVTNoSFJuRjZhSGxPYlcx
-V1RBb3hjVUpLYkdSNE16UlRjSGR6VkVGTVVWWlFZalJvUjNkS2VscG1jakZRClkzQkZVWGcyZUUx
-dVZHdzRlRVZYV2tVelRYTTVPWFZoVlhoaVVYRkpkMUoxQ2t4blFVOXJUa050V1RKdE9EbFdhSHBo
-U0VveGRWWTQKTlVGa1RTOTBSQ3RaYzIxc2JtNXFkRGxNVWtObGFtSkNhWEJxU1VkcVQxaHlaekZL
-VUN0c2VGWUtiWFZOTkhaSUsxQXZiV3h0ZUhOUQpVSG93WkRZMVlpdEZSMjFLV25CdlRHdFBMM1Jr
-VGs1MlExbDZha3B3VkVWWGNFVnpUelpPVFdoTFdXODlDaTB0TFMwdFJVNUVJRU5GClVsUkpSa2xE
-UVZSRkxTMHRMUzBLCi0te2JvdW5kYXJ5fS0tCg==
\ No newline at end of file
diff --git a/wifi/tests/assets/hsr1/HSR1ProfileWithCACert.conf b/wifi/tests/assets/hsr1/HSR1ProfileWithCACert.conf
deleted file mode 100644
index 5b4e4cb..0000000
--- a/wifi/tests/assets/hsr1/HSR1ProfileWithCACert.conf
+++ /dev/null
@@ -1,74 +0,0 @@
-MIME-Version: 1.0
-Content-Type: multipart/mixed; boundary={boundary}; charset=UTF-8
-Content-Transfer-Encoding: base64
-
---{boundary}
-Content-Type: application/x-passpoint-profile; charset=UTF-8
-Content-Transfer-Encoding: base64
-
-PE1nbXRUcmVlIHhtbG5zPSJzeW5jbWw6ZG1kZGYxLjIiPgogIDxWZXJEVEQ+MS4yPC9WZXJEVEQ+
-CiAgPE5vZGU+CiAgICA8Tm9kZU5hbWU+UGVyUHJvdmlkZXJTdWJzY3JpcHRpb248L05vZGVOYW1l
-PgogICAgPFJUUHJvcGVydGllcz4KICAgICAgPFR5cGU+CiAgICAgICAgPERERk5hbWU+dXJuOndm
-YTptbzpob3RzcG90MmRvdDAtcGVycHJvdmlkZXJzdWJzY3JpcHRpb246MS4wPC9EREZOYW1lPgog
-ICAgICA8L1R5cGU+CiAgICA8L1JUUHJvcGVydGllcz4KICAgIDxOb2RlPgogICAgICA8Tm9kZU5h
-bWU+aTAwMTwvTm9kZU5hbWU+CiAgICAgIDxOb2RlPgogICAgICAgIDxOb2RlTmFtZT5Ib21lU1A8
-L05vZGVOYW1lPgogICAgICAgIDxOb2RlPgogICAgICAgICAgPE5vZGVOYW1lPkZyaWVuZGx5TmFt
-ZTwvTm9kZU5hbWU+CiAgICAgICAgICA8VmFsdWU+RXhhbXBsZSBOZXR3b3JrPC9WYWx1ZT4KICAg
-ICAgICA8L05vZGU+CiAgICAgICAgPE5vZGU+CiAgICAgICAgICA8Tm9kZU5hbWU+RlFETjwvTm9k
-ZU5hbWU+CiAgICAgICAgICA8VmFsdWU+aG90c3BvdC5leGFtcGxlLm5ldDwvVmFsdWU+CiAgICAg
-ICAgPC9Ob2RlPgogICAgICAgIDxOb2RlPgogICAgICAgICAgPE5vZGVOYW1lPlJvYW1pbmdDb25z
-b3J0aXVtT0k8L05vZGVOYW1lPgogICAgICAgICAgPFZhbHVlPjExMjIzMyw0NDU1NjY8L1ZhbHVl
-PgogICAgICAgIDwvTm9kZT4KICAgICAgPC9Ob2RlPgogICAgICA8Tm9kZT4KICAgICAgICA8Tm9k
-ZU5hbWU+Q3JlZGVudGlhbDwvTm9kZU5hbWU+CiAgICAgICAgPE5vZGU+CiAgICAgICAgICA8Tm9k
-ZU5hbWU+UmVhbG08L05vZGVOYW1lPgogICAgICAgICAgPFZhbHVlPmV4YW1wbGUuY29tPC9WYWx1
-ZT4KICAgICAgICA8L05vZGU+CiAgICAgICAgPE5vZGU+CiAgICAgICAgICA8Tm9kZU5hbWU+VXNl
-cm5hbWVQYXNzd29yZDwvTm9kZU5hbWU+CiAgICAgICAgICA8Tm9kZT4KICAgICAgICAgICAgPE5v
-ZGVOYW1lPlVzZXJuYW1lPC9Ob2RlTmFtZT4KICAgICAgICAgICAgPFZhbHVlPnVzZXI8L1ZhbHVl
-PgogICAgICAgICAgPC9Ob2RlPgogICAgICAgICAgPE5vZGU+CiAgICAgICAgICAgIDxOb2RlTmFt
-ZT5QYXNzd29yZDwvTm9kZU5hbWU+CiAgICAgICAgICAgIDxWYWx1ZT5jR0Z6YzNkdmNtUT08L1Zh
-bHVlPgogICAgICAgICAgPC9Ob2RlPgogICAgICAgICAgPE5vZGU+CiAgICAgICAgICAgIDxOb2Rl
-TmFtZT5FQVBNZXRob2Q8L05vZGVOYW1lPgogICAgICAgICAgICA8Tm9kZT4KICAgICAgICAgICAg
-ICA8Tm9kZU5hbWU+RUFQVHlwZTwvTm9kZU5hbWU+CiAgICAgICAgICAgICAgPFZhbHVlPjIxPC9W
-YWx1ZT4KICAgICAgICAgICAgPC9Ob2RlPgogICAgICAgICAgICA8Tm9kZT4KICAgICAgICAgICAg
-ICA8Tm9kZU5hbWU+SW5uZXJNZXRob2Q8L05vZGVOYW1lPgogICAgICAgICAgICAgIDxWYWx1ZT5N
-Uy1DSEFQLVYyPC9WYWx1ZT4KICAgICAgICAgICAgPC9Ob2RlPgogICAgICAgICAgPC9Ob2RlPgog
-ICAgICAgIDwvTm9kZT4KICAgICAgICA8Tm9kZT4KICAgICAgICAgIDxOb2RlTmFtZT5EaWdpdGFs
-Q2VydGlmaWNhdGU8L05vZGVOYW1lPgogICAgICAgICAgPE5vZGU+CiAgICAgICAgICAgIDxOb2Rl
-TmFtZT5DZXJ0aWZpY2F0ZVR5cGU8L05vZGVOYW1lPgogICAgICAgICAgICA8VmFsdWU+eDUwOXYz
-PC9WYWx1ZT4KICAgICAgICAgIDwvTm9kZT4KICAgICAgICAgIDxOb2RlPgogICAgICAgICAgICA8
-Tm9kZU5hbWU+Q2VydFNIQTI1NkZpbmdlcnByaW50PC9Ob2RlTmFtZT4KICAgICAgICAgICAgPFZh
-bHVlPjFmMWYxZjFmMWYxZjFmMWYxZjFmMWYxZjFmMWYxZjFmMWYxZjFmMWYxZjFmMWYxZjFmMWYx
-ZjFmMWYxZjFmMWY8L1ZhbHVlPgogICAgICAgICAgPC9Ob2RlPgogICAgICAgIDwvTm9kZT4KICAg
-ICAgICA8Tm9kZT4KICAgICAgICAgIDxOb2RlTmFtZT5TSU08L05vZGVOYW1lPgogICAgICAgICAg
-PE5vZGU+CiAgICAgICAgICAgIDxOb2RlTmFtZT5JTVNJPC9Ob2RlTmFtZT4KICAgICAgICAgICAg
-PFZhbHVlPjEyMzQ1Nio8L1ZhbHVlPgogICAgICAgICAgPC9Ob2RlPgogICAgICAgICAgPE5vZGU+
-CiAgICAgICAgICAgIDxOb2RlTmFtZT5FQVBUeXBlPC9Ob2RlTmFtZT4KICAgICAgICAgICAgPFZh
-bHVlPjIzPC9WYWx1ZT4KICAgICAgICAgIDwvTm9kZT4KICAgICAgICA8L05vZGU+CiAgICAgIDwv
-Tm9kZT4KICAgIDwvTm9kZT4KICA8L05vZGU+CjwvTWdtdFRyZWU+
-
---{boundary}
-Content-Type: application/x-x509-ca-cert
-Content-Transfer-Encoding: base64
-
-LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURLRENDQWhDZ0F3SUJBZ0lKQUlMbEZkd3pM
-VnVyTUEwR0NTcUdTSWIzRFFFQkN3VUFNQkl4RURBT0JnTlYKQkFNVEIwVkJVQ0JEUVRFd0hoY05N
-VFl3TVRFeU1URTFNREUxV2hjTk1qWXdNVEE1TVRFMU1ERTFXakFTTVJBdwpEZ1lEVlFRREV3ZEZR
-VkFnUTBFeE1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBCnpuQVBV
-ejI2TXNhZTR3czQzY3pSNDEvSjJRdHJTSVpVS21WVXNWdW1EYllIclBOdlRYS1NNWEFjZXdPUkRR
-WVgKUnF2SHZwbjhDc2NCMStvR1hadkh3eGo0elYwV0tvSzJ6ZVhrYXUzdmN5bDNISUt1cEpmcTJU
-RUFDZWZWamowdApKVytYMzVQR1dwOS9INXpJVU5WTlZqUzdVbXM4NEl2S2hSQjg1MTJQQjlVeUhh
-Z1hZVlg1R1dwQWNWcHlmcmxSCkZJOVFkaGgrUGJrMHV5a3RkYmYvQ2RmZ0hPb2ViclR0d1Jsak0w
-b0R0WCsyQ3Y2ajB3Qks3aEQ4cFB2ZjErdXkKR3pjemlnQVUvNEt3N2VacXlkZjlCKzVSdXBSK0la
-aXBYNDF4RWlJcktSd3FpNTE3V1d6WGNqYUcyY05iZjQ1MQp4cEg1UG5WM2kxdHEwNGpNR1FVekZ3
-SURBUUFCbzRHQU1INHdIUVlEVlIwT0JCWUVGSXdYNHZzOEJpQmNTY29kCjVub1pIUk04RTQraU1F
-SUdBMVVkSXdRN01EbUFGSXdYNHZzOEJpQmNTY29kNW5vWkhSTThFNCtpb1Jha0ZEQVMKTVJBd0Rn
-WURWUVFERXdkRlFWQWdRMEV4Z2drQWd1VVYzRE10VzZzd0RBWURWUjBUQkFVd0F3RUIvekFMQmdO
-VgpIUThFQkFNQ0FRWXdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBRmZRcU9UQTdSdjdLK2x1UTdw
-bmFzNEJZd0hFCjlHRVAvdW9odjZLT3kwVEdRRmJyUlRqRm9MVk5COUJaMXltTURaMC9USXdJVWM3
-d2k3YTh0NW1FcVlIMTUzd1cKYVdvb2lTanlMTGh1STRzTnJOQ090aXNkQnEycjJNRlh0NmgwbUFR
-WU9QdjhSOEs3L2ZnU3hHRnF6aHlObW1WTAoxcUJKbGR4MzRTcHdzVEFMUVZQYjRoR3dKelpmcjFQ
-Y3BFUXg2eE1uVGw4eEVXWkUzTXM5OXVhVXhiUXFJd1J1CkxnQU9rTkNtWTJtODlWaHphSEoxdVY4
-NUFkTS90RCtZc21sbm5qdDlMUkNlamJCaXBqSUdqT1hyZzFKUCtseFYKbXVNNHZIK1AvbWxteHNQ
-UHowZDY1YitFR21KWnBvTGtPL3RkTk52Q1l6akpwVEVXcEVzTzZOTWhLWW89Ci0tLS0tRU5EIENF
-UlRJRklDQVRFLS0tLS0K
---{boundary}--
diff --git a/wifi/tests/assets/hsr1/HSR1ProfileWithInvalidContentType.base64 b/wifi/tests/assets/hsr1/HSR1ProfileWithInvalidContentType.base64
deleted file mode 100644
index 2775a9f..0000000
--- a/wifi/tests/assets/hsr1/HSR1ProfileWithInvalidContentType.base64
+++ /dev/null
@@ -1,86 +0,0 @@
-TUlNRS1WZXJzaW9uOiAxLjAKQ29udGVudC1UeXBlOiBtdWx0aXBhcnQvbWl4ZWQ7IGJvdW5kYXJ5
-PXtib3VuZGFyeX07IGNoYXJzZXQ9VVRGLTgKQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogYmFz
-ZTY0CgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi9wYXNzcG9pbnQtcHJv
-ZmlsZTsgY2hhcnNldD1VVEYtOApDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBiYXNlNjQKClBF
-MW5iWFJVY21WbElIaHRiRzV6UFNKemVXNWpiV3c2Wkcxa1pHWXhMaklpUGdvZ0lEeFdaWEpFVkVR
-K01TNHlQQzlXWlhKRVZFUSsKQ2lBZ1BFNXZaR1UrQ2lBZ0lDQThUbTlrWlU1aGJXVStVR1Z5VUhK
-dmRtbGtaWEpUZFdKelkzSnBjSFJwYjI0OEwwNXZaR1ZPWVcxbApQZ29nSUNBZ1BGSlVVSEp2Y0dW
-eWRHbGxjejRLSUNBZ0lDQWdQRlI1Y0dVK0NpQWdJQ0FnSUNBZ1BFUkVSazVoYldVK2RYSnVPbmRt
-CllUcHRienBvYjNSemNHOTBNbVJ2ZERBdGNHVnljSEp2ZG1sa1pYSnpkV0p6WTNKcGNIUnBiMjQ2
-TVM0d1BDOUVSRVpPWVcxbFBnb2cKSUNBZ0lDQThMMVI1Y0dVK0NpQWdJQ0E4TDFKVVVISnZjR1Z5
-ZEdsbGN6NEtJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQThUbTlrWlU1aApiV1UrYVRBd01Ud3ZUbTlr
-WlU1aGJXVStDaUFnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUR4T2IyUmxUbUZ0WlQ1SWIyMWxV
-MUE4CkwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZa
-R1ZPWVcxbFBrWnlhV1Z1Wkd4NVRtRnQKWlR3dlRtOWtaVTVoYldVK0NpQWdJQ0FnSUNBZ0lDQThW
-bUZzZFdVK1JYaGhiWEJzWlNCT1pYUjNiM0pyUEM5V1lXeDFaVDRLSUNBZwpJQ0FnSUNBOEwwNXZa
-R1UrQ2lBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0E4VG05a1pVNWhiV1UrUmxGRVRq
-d3ZUbTlrClpVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNBOFZtRnNkV1UrYUc5MGMzQnZkQzVsZUdGdGNH
-eGxMbTVsZER3dlZtRnNkV1UrQ2lBZ0lDQWcKSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUR4T2Iy
-UmxQZ29nSUNBZ0lDQWdJQ0FnUEU1dlpHVk9ZVzFsUGxKdllXMXBibWREYjI1egpiM0owYVhWdFQw
-azhMMDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQakV4TWpJek15dzBORFUxTmpZ
-OEwxWmhiSFZsClBnb2dJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNB
-Z0lDQThUbTlrWlQ0S0lDQWdJQ0FnSUNBOFRtOWsKWlU1aGJXVStRM0psWkdWdWRHbGhiRHd2VG05
-a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0E4VG05awpaVTVoYldV
-K1VtVmhiRzA4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ1BGWmhiSFZsUG1WNFlXMXdiR1V1
-WTI5dFBDOVdZV3gxClpUNEtJQ0FnSUNBZ0lDQThMMDV2WkdVK0NpQWdJQ0FnSUNBZ1BFNXZaR1Ur
-Q2lBZ0lDQWdJQ0FnSUNBOFRtOWtaVTVoYldVK1ZYTmwKY201aGJXVlFZWE56ZDI5eVpEd3ZUbTlr
-WlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0E4VG05a1pUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEU1dgpaR1ZP
-WVcxbFBsVnpaWEp1WVcxbFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQ
-blZ6WlhJOEwxWmhiSFZsClBnb2dJQ0FnSUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdQ
-RTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJSbFRtRnQKWlQ1UVlYTnpkMjl5WkR3dlRtOWta
-VTVoYldVK0NpQWdJQ0FnSUNBZ0lDQWdJRHhXWVd4MVpUNWpSMFo2WXpOa2RtTnRVVDA4TDFaaApi
-SFZsUGdvZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZaR1UrQ2lBZ0lD
-QWdJQ0FnSUNBZ0lEeE9iMlJsClRtRnRaVDVGUVZCTlpYUm9iMlE4TDA1dlpHVk9ZVzFsUGdvZ0lD
-QWdJQ0FnSUNBZ0lDQThUbTlrWlQ0S0lDQWdJQ0FnSUNBZ0lDQWcKSUNBOFRtOWtaVTVoYldVK1JV
-RlFWSGx3WlR3dlRtOWtaVTVoYldVK0NpQWdJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQakl4UEM5
-VwpZV3gxWlQ0S0lDQWdJQ0FnSUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdJQ0E4VG05
-a1pUNEtJQ0FnSUNBZ0lDQWdJQ0FnCklDQThUbTlrWlU1aGJXVStTVzV1WlhKTlpYUm9iMlE4TDA1
-dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ0lDQWdJRHhXWVd4MVpUNU4KVXkxRFNFRlFMVll5UEM5
-V1lXeDFaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJs
-UGdvZwpJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0Fn
-SUR4T2IyUmxUbUZ0WlQ1RWFXZHBkR0ZzClEyVnlkR2xtYVdOaGRHVThMMDV2WkdWT1lXMWxQZ29n
-SUNBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2IyUmwKVG1GdFpUNURaWEow
-YVdacFkyRjBaVlI1Y0dVOEwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWdJQ0E4Vm1Gc2RXVStl
-RFV3T1hZegpQQzlXWVd4MVpUNEtJQ0FnSUNBZ0lDQWdJRHd2VG05a1pUNEtJQ0FnSUNBZ0lDQWdJ
-RHhPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdJQ0E4ClRtOWtaVTVoYldVK1EyVnlkRk5JUVRJMU5rWnBi
-bWRsY25CeWFXNTBQQzlPYjJSbFRtRnRaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BGWmgKYkhWbFBqRm1N
-V1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1X
-WXhaakZtTVdZeApaakZtTVdZeFpqRm1NV1k4TDFaaGJIVmxQZ29nSUNBZ0lDQWdJQ0FnUEM5T2Iy
-UmxQZ29nSUNBZ0lDQWdJRHd2VG05a1pUNEtJQ0FnCklDQWdJQ0E4VG05a1pUNEtJQ0FnSUNBZ0lD
-QWdJRHhPYjJSbFRtRnRaVDVUU1UwOEwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWcKUEU1dlpH
-VStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2IyUmxUbUZ0WlQ1SlRWTkpQQzlPYjJSbFRtRnRaVDRLSUNB
-Z0lDQWdJQ0FnSUNBZwpQRlpoYkhWbFBqRXlNelExTmlvOEwxWmhiSFZsUGdvZ0lDQWdJQ0FnSUNB
-Z1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZaR1UrCkNpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJS
-bFRtRnRaVDVGUVZCVWVYQmxQQzlPYjJSbFRtRnRaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BGWmgKYkhW
-bFBqSXpQQzlXWVd4MVpUNEtJQ0FnSUNBZ0lDQWdJRHd2VG05a1pUNEtJQ0FnSUNBZ0lDQThMMDV2
-WkdVK0NpQWdJQ0FnSUR3dgpUbTlrWlQ0S0lDQWdJRHd2VG05a1pUNEtJQ0E4TDA1dlpHVStDand2
-VFdkdGRGUnlaV1UrCgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi94LXg1
-MDktY2EtY2VydApDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBiYXNlNjQKCkxTMHRMUzFDUlVk
-SlRpQkRSVkpVU1VaSlEwRlVSUzB0TFMwdENrMUpTVVJMUkVORFFXaERaMEYzU1VKQlowbEtRVWxN
-YkVaa2QzcE0KVm5WeVRVRXdSME5UY1VkVFNXSXpSRkZGUWtOM1ZVRk5Ra2w0UlVSQlQwSm5UbFlL
-UWtGTlZFSXdWa0pWUTBKRVVWUkZkMGhvWTA1TgpWRmwzVFZSRmVVMVVSVEZOUkVVeFYyaGpUazFx
-V1hkTlZFRTFUVlJGTVUxRVJURlhha0ZUVFZKQmR3cEVaMWxFVmxGUlJFVjNaRVpSClZrRm5VVEJG
-ZUUxSlNVSkpha0ZPUW1kcmNXaHJhVWM1ZHpCQ1FWRkZSa0ZCVDBOQlVUaEJUVWxKUWtOblMwTkJV
-VVZCQ25wdVFWQlYKZWpJMlRYTmhaVFIzY3pRelkzcFNOREV2U2pKUmRISlRTVnBWUzIxV1ZYTldk
-VzFFWWxsSWNsQk9kbFJZUzFOTldFRmpaWGRQVWtSUgpXVmdLVW5GMlNIWndiamhEYzJOQ01TdHZS
-MWhhZGtoM2VHbzBlbFl3VjB0dlN6SjZaVmhyWVhVemRtTjViRE5JU1V0MWNFcG1jVEpVClJVRkRa
-V1pXYW1vd2RBcEtWeXRZTXpWUVIxZHdPUzlJTlhwSlZVNVdUbFpxVXpkVmJYTTRORWwyUzJoU1Fq
-ZzFNVEpRUWpsVmVVaGgKWjFoWlZsZzFSMWR3UVdOV2NIbG1jbXhTQ2taSk9WRmthR2dyVUdKck1I
-VjVhM1JrWW1ZdlEyUm1aMGhQYjJWaWNsUjBkMUpzYWswdwpiMFIwV0NzeVEzWTJhakIzUWtzM2FF
-UTRjRkIyWmpFcmRYa0tSM3BqZW1sblFWVXZORXQzTjJWYWNYbGtaamxDS3pWU2RYQlNLMGxhCmFY
-QllOREY0UldsSmNrdFNkM0ZwTlRFM1YxZDZXR05xWVVjeVkwNWlaalExTVFwNGNFZzFVRzVXTTJr
-eGRIRXdOR3BOUjFGVmVrWjMKU1VSQlVVRkNielJIUVUxSU5IZElVVmxFVmxJd1QwSkNXVVZHU1hk
-WU5IWnpPRUpwUW1OVFkyOWtDalZ1YjFwSVVrMDRSVFFyYVUxRgpTVWRCTVZWa1NYZFJOMDFFYlVG
-R1NYZFlOSFp6T0VKcFFtTlRZMjlrTlc1dldraFNUVGhGTkN0cGIxSmhhMFpFUVZNS1RWSkJkMFJu
-CldVUldVVkZFUlhka1JsRldRV2RSTUVWNFoyZHJRV2QxVlZZelJFMTBWelp6ZDBSQldVUldVakJV
-UWtGVmQwRjNSVUl2ZWtGTVFtZE8KVmdwSVVUaEZRa0ZOUTBGUldYZEVVVmxLUzI5YVNXaDJZMDVC
-VVVWTVFsRkJSR2RuUlVKQlJtWlJjVTlVUVRkU2RqZExLMngxVVRkdwpibUZ6TkVKWmQwaEZDamxI
-UlZBdmRXOW9kalpMVDNrd1ZFZFJSbUp5VWxScVJtOU1WazVDT1VKYU1YbHRUVVJhTUM5VVNYZEpW
-V00zCmQyazNZVGgwTlcxRmNWbElNVFV6ZDFjS1lWZHZiMmxUYW5sTVRHaDFTVFJ6VG5KT1EwOTBh
-WE5rUW5FeWNqSk5SbGgwTm1nd2JVRlIKV1U5UWRqaFNPRXMzTDJablUzaEhSbkY2YUhsT2JXMVdU
-QW94Y1VKS2JHUjRNelJUY0hkelZFRk1VVlpRWWpSb1IzZEtlbHBtY2pGUQpZM0JGVVhnMmVFMXVW
-R3c0ZUVWWFdrVXpUWE01T1hWaFZYaGlVWEZKZDFKMUNreG5RVTlyVGtOdFdUSnRPRGxXYUhwaFNF
-b3hkVlk0Ck5VRmtUUzkwUkN0WmMyMXNibTVxZERsTVVrTmxhbUpDYVhCcVNVZHFUMWh5WnpGS1VD
-dHNlRllLYlhWTk5IWklLMUF2Yld4dGVITlEKVUhvd1pEWTFZaXRGUjIxS1duQnZUR3RQTDNSa1Rr
-NTJRMWw2YWtwd1ZFVlhjRVZ6VHpaT1RXaExXVzg5Q2kwdExTMHRSVTVFSUVORgpVbFJKUmtsRFFW
-UkZMUzB0TFMwSwotLXtib3VuZGFyeX0tLQo=
\ No newline at end of file
diff --git a/wifi/tests/assets/hsr1/HSR1ProfileWithMissingBoundary.base64 b/wifi/tests/assets/hsr1/HSR1ProfileWithMissingBoundary.base64
deleted file mode 100644
index 7023453..0000000
--- a/wifi/tests/assets/hsr1/HSR1ProfileWithMissingBoundary.base64
+++ /dev/null
@@ -1,86 +0,0 @@
-TUlNRS1WZXJzaW9uOiAxLjAKQ29udGVudC1UeXBlOiBtdWx0aXBhcnQvbWl4ZWQ7IGJvdW5kYXJ5
-PXtib3VuZGFyeX07IGNoYXJzZXQ9VVRGLTgKQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogYmFz
-ZTY0CgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi94LXBhc3Nwb2ludC1w
-cm9maWxlOyBjaGFyc2V0PVVURi04CkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IGJhc2U2NAoK
-UEUxbmJYUlVjbVZsSUhodGJHNXpQU0p6ZVc1amJXdzZaRzFrWkdZeExqSWlQZ29nSUR4V1pYSkVW
-RVErTVM0eVBDOVdaWEpFVkVRKwpDaUFnUEU1dlpHVStDaUFnSUNBOFRtOWtaVTVoYldVK1VHVnlV
-SEp2ZG1sa1pYSlRkV0p6WTNKcGNIUnBiMjQ4TDA1dlpHVk9ZVzFsClBnb2dJQ0FnUEZKVVVISnZj
-R1Z5ZEdsbGN6NEtJQ0FnSUNBZ1BGUjVjR1UrQ2lBZ0lDQWdJQ0FnUEVSRVJrNWhiV1UrZFhKdU9u
-ZG0KWVRwdGJ6cG9iM1J6Y0c5ME1tUnZkREF0Y0dWeWNISnZkbWxrWlhKemRXSnpZM0pwY0hScGIy
-NDZNUzR3UEM5RVJFWk9ZVzFsUGdvZwpJQ0FnSUNBOEwxUjVjR1UrQ2lBZ0lDQThMMUpVVUhKdmNH
-VnlkR2xsY3o0S0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBOFRtOWtaVTVoCmJXVSthVEF3TVR3dlRt
-OWtaVTVoYldVK0NpQWdJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQWdJRHhPYjJSbFRtRnRaVDVJYjIx
-bFUxQTgKTDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEU1
-dlpHVk9ZVzFsUGtaeWFXVnVaR3g1VG1GdApaVHd2VG05a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNB
-OFZtRnNkV1UrUlhoaGJYQnNaU0JPWlhSM2IzSnJQQzlXWVd4MVpUNEtJQ0FnCklDQWdJQ0E4TDA1
-dlpHVStDaUFnSUNBZ0lDQWdQRTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrWlU1aGJXVStSbEZF
-VGp3dlRtOWsKWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0E4Vm1Gc2RXVSthRzkwYzNCdmRDNWxlR0Z0
-Y0d4bExtNWxkRHd2Vm1Gc2RXVStDaUFnSUNBZwpJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJRHhP
-YjJSbFBnb2dJQ0FnSUNBZ0lDQWdQRTV2WkdWT1lXMWxQbEp2WVcxcGJtZERiMjV6CmIzSjBhWFZ0
-VDBrOEwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBqRXhNakl6TXl3ME5EVTFO
-alk4TDFaaGJIVmwKUGdvZ0lDQWdJQ0FnSUR3dlRtOWtaVDRLSUNBZ0lDQWdQQzlPYjJSbFBnb2dJ
-Q0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0E4VG05awpaVTVoYldVK1EzSmxaR1Z1ZEdsaGJEd3ZU
-bTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdQRTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrClpVNWhi
-V1UrVW1WaGJHMDhMMDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQbVY0WVcxd2JH
-VXVZMjl0UEM5V1lXeDEKWlQ0S0lDQWdJQ0FnSUNBOEwwNXZaR1UrQ2lBZ0lDQWdJQ0FnUEU1dlpH
-VStDaUFnSUNBZ0lDQWdJQ0E4VG05a1pVNWhiV1UrVlhObApjbTVoYldWUVlYTnpkMjl5WkR3dlRt
-OWtaVTVoYldVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrWlQ0S0lDQWdJQ0FnSUNBZ0lDQWdQRTV2ClpH
-Vk9ZVzFsUGxWelpYSnVZVzFsUEM5T2IyUmxUbUZ0WlQ0S0lDQWdJQ0FnSUNBZ0lDQWdQRlpoYkhW
-bFBuVnpaWEk4TDFaaGJIVmwKUGdvZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNB
-Z1BFNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lEeE9iMlJsVG1GdApaVDVRWVhOemQyOXlaRHd2VG05
-a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lEeFdZV3gxWlQ1alIwWjZZek5rZG1OdFVUMDhMMVpo
-CmJIVmxQZ29nSUNBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEU1dlpHVStDaUFn
-SUNBZ0lDQWdJQ0FnSUR4T2IyUmwKVG1GdFpUNUZRVkJOWlhSb2IyUThMMDV2WkdWT1lXMWxQZ29n
-SUNBZ0lDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0FnSUNBZwpJQ0E4VG05a1pVNWhiV1Ur
-UlVGUVZIbHdaVHd2VG05a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBqSXhQ
-QzlXCllXeDFaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThU
-bTlrWlQ0S0lDQWdJQ0FnSUNBZ0lDQWcKSUNBOFRtOWtaVTVoYldVK1NXNXVaWEpOWlhSb2IyUThM
-MDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnSUNBZ0lEeFdZV3gxWlQ1TgpVeTFEU0VGUUxWWXlQ
-QzlXWVd4MVpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEM5T2Iy
-UmxQZ29nCklDQWdJQ0FnSUR3dlRtOWtaVDRLSUNBZ0lDQWdJQ0E4VG05a1pUNEtJQ0FnSUNBZ0lD
-QWdJRHhPYjJSbFRtRnRaVDVFYVdkcGRHRnMKUTJWeWRHbG1hV05oZEdVOEwwNXZaR1ZPWVcxbFBn
-b2dJQ0FnSUNBZ0lDQWdQRTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJSbApUbUZ0WlQ1RFpY
-SjBhV1pwWTJGMFpWUjVjR1U4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThWbUZzZFdV
-K2VEVXdPWFl6ClBDOVdZV3gxWlQ0S0lDQWdJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJQ0FnSUNB
-Z0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ0lDQTgKVG05a1pVNWhiV1UrUTJWeWRGTklRVEkxTmta
-cGJtZGxjbkJ5YVc1MFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEZaaApiSFZsUGpG
-bU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaakZt
-TVdZeFpqRm1NV1l4ClpqRm1NV1l4WmpGbU1XWThMMVpoYkhWbFBnb2dJQ0FnSUNBZ0lDQWdQQzlP
-YjJSbFBnb2dJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWcKSUNBZ0lDQThUbTlrWlQ0S0lDQWdJQ0Fn
-SUNBZ0lEeE9iMlJsVG1GdFpUNVRTVTA4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZwpQRTV2
-WkdVK0NpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJSbFRtRnRaVDVKVFZOSlBDOU9iMlJsVG1GdFpUNEtJ
-Q0FnSUNBZ0lDQWdJQ0FnClBGWmhiSFZsUGpFeU16UTFOaW84TDFaaGJIVmxQZ29nSUNBZ0lDQWdJ
-Q0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEU1dlpHVSsKQ2lBZ0lDQWdJQ0FnSUNBZ0lEeE9i
-MlJsVG1GdFpUNUZRVkJVZVhCbFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEZaaApi
-SFZsUGpJelBDOVdZV3gxWlQ0S0lDQWdJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJQ0FnSUNBOEww
-NXZaR1UrQ2lBZ0lDQWdJRHd2ClRtOWtaVDRLSUNBZ0lEd3ZUbTlrWlQ0S0lDQThMMDV2WkdVK0Nq
-d3ZUV2R0ZEZSeVpXVSsKCi0te2JvdW5kYXJ5fQpDb250ZW50LVR5cGU6IGFwcGxpY2F0aW9uL3gt
-eDUwOS1jYS1jZXJ0CkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IGJhc2U2NAoKTFMwdExTMUNS
-VWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVUkxSRU5EUVdoRFowRjNTVUpCWjBsS1FV
-bE1iRVprZDNwTQpWblZ5VFVFd1IwTlRjVWRUU1dJelJGRkZRa04zVlVGTlFrbDRSVVJCVDBKblRs
-WUtRa0ZOVkVJd1ZrSlZRMEpFVVZSRmQwaG9ZMDVOClZGbDNUVlJGZVUxVVJURk5SRVV4VjJoalRr
-MXFXWGROVkVFMVRWUkZNVTFFUlRGWGFrRlRUVkpCZHdwRVoxbEVWbEZSUkVWM1pFWlIKVmtGblVU
-QkZlRTFKU1VKSmFrRk9RbWRyY1docmFVYzVkekJDUVZGRlJrRkJUME5CVVRoQlRVbEpRa05uUzBO
-QlVVVkJDbnB1UVZCVgplakkyVFhOaFpUUjNjelF6WTNwU05ERXZTakpSZEhKVFNWcFZTMjFXVlhO
-V2RXMUVZbGxJY2xCT2RsUllTMU5OV0VGalpYZFBVa1JSCldWZ0tVbkYyU0had2JqaERjMk5DTVN0
-dlIxaGFka2gzZUdvMGVsWXdWMHR2U3pKNlpWaHJZWFV6ZG1ONWJETklTVXQxY0VwbWNUSlUKUlVG
-RFpXWldhbW93ZEFwS1Z5dFlNelZRUjFkd09TOUlOWHBKVlU1V1RsWnFVemRWYlhNNE5FbDJTMmhT
-UWpnMU1USlFRamxWZVVoaApaMWhaVmxnMVIxZHdRV05XY0hsbWNteFNDa1pKT1ZGa2FHZ3JVR0py
-TUhWNWEzUmtZbVl2UTJSbVowaFBiMlZpY2xSMGQxSnNhazB3CmIwUjBXQ3N5UTNZMmFqQjNRa3Mz
-YUVRNGNGQjJaakVyZFhrS1IzcGplbWxuUVZVdk5FdDNOMlZhY1hsa1pqbENLelZTZFhCU0swbGEK
-YVhCWU5ERjRSV2xKY2t0U2QzRnBOVEUzVjFkNldHTnFZVWN5WTA1aVpqUTFNUXA0Y0VnMVVHNVdN
-Mmt4ZEhFd05HcE5SMUZWZWtaMwpTVVJCVVVGQ2J6UkhRVTFJTkhkSVVWbEVWbEl3VDBKQ1dVVkdT
-WGRZTkhaek9FSnBRbU5UWTI5a0NqVnViMXBJVWswNFJUUXJhVTFGClNVZEJNVlZrU1hkUk4wMUVi
-VUZHU1hkWU5IWnpPRUpwUW1OVFkyOWtOVzV2V2toU1RUaEZOQ3RwYjFKaGEwWkVRVk1LVFZKQmQw
-Um4KV1VSV1VWRkVSWGRrUmxGV1FXZFJNRVY0WjJkclFXZDFWVll6UkUxMFZ6WnpkMFJCV1VSV1Vq
-QlVRa0ZWZDBGM1JVSXZla0ZNUW1kTwpWZ3BJVVRoRlFrRk5RMEZSV1hkRVVWbEtTMjlhU1doMlkw
-NUJVVVZNUWxGQlJHZG5SVUpCUm1aUmNVOVVRVGRTZGpkTEsyeDFVVGR3CmJtRnpORUpaZDBoRkNq
-bEhSVkF2ZFc5b2RqWkxUM2t3VkVkUlJtSnlVbFJxUm05TVZrNUNPVUphTVhsdFRVUmFNQzlVU1hk
-SlZXTTMKZDJrM1lUaDBOVzFGY1ZsSU1UVXpkMWNLWVZkdmIybFRhbmxNVEdoMVNUUnpUbkpPUTA5
-MGFYTmtRbkV5Y2pKTlJsaDBObWd3YlVGUgpXVTlRZGpoU09FczNMMlpuVTNoSFJuRjZhSGxPYlcx
-V1RBb3hjVUpLYkdSNE16UlRjSGR6VkVGTVVWWlFZalJvUjNkS2VscG1jakZRClkzQkZVWGcyZUUx
-dVZHdzRlRVZYV2tVelRYTTVPWFZoVlhoaVVYRkpkMUoxQ2t4blFVOXJUa050V1RKdE9EbFdhSHBo
-U0VveGRWWTQKTlVGa1RTOTBSQ3RaYzIxc2JtNXFkRGxNVWtObGFtSkNhWEJxU1VkcVQxaHlaekZL
-VUN0c2VGWUtiWFZOTkhaSUsxQXZiV3h0ZUhOUQpVSG93WkRZMVlpdEZSMjFLV25CdlRHdFBMM1Jr
-VGs1MlExbDZha3B3VkVWWGNFVnpUelpPVFdoTFdXODlDaTB0TFMwdFJVNUVJRU5GClVsUkpSa2xE
-UVZSRkxTMHRMUzBLCg==
\ No newline at end of file
diff --git a/wifi/tests/assets/hsr1/HSR1ProfileWithNonBase64Part.base64 b/wifi/tests/assets/hsr1/HSR1ProfileWithNonBase64Part.base64
deleted file mode 100644
index 5c23f61..0000000
--- a/wifi/tests/assets/hsr1/HSR1ProfileWithNonBase64Part.base64
+++ /dev/null
@@ -1,86 +0,0 @@
-TUlNRS1WZXJzaW9uOiAxLjAKQ29udGVudC1UeXBlOiBtdWx0aXBhcnQvbWl4ZWQ7IGJvdW5kYXJ5
-PXtib3VuZGFyeX07IGNoYXJzZXQ9VVRGLTgKQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogOGJp
-dAoKLS17Ym91bmRhcnl9CkNvbnRlbnQtVHlwZTogYXBwbGljYXRpb24veC1wYXNzcG9pbnQtcHJv
-ZmlsZTsgY2hhcnNldD1VVEYtOApDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBiYXNlNjQKClBF
-MW5iWFJVY21WbElIaHRiRzV6UFNKemVXNWpiV3c2Wkcxa1pHWXhMaklpUGdvZ0lEeFdaWEpFVkVR
-K01TNHlQQzlXWlhKRVZFUSsKQ2lBZ1BFNXZaR1UrQ2lBZ0lDQThUbTlrWlU1aGJXVStVR1Z5VUhK
-dmRtbGtaWEpUZFdKelkzSnBjSFJwYjI0OEwwNXZaR1ZPWVcxbApQZ29nSUNBZ1BGSlVVSEp2Y0dW
-eWRHbGxjejRLSUNBZ0lDQWdQRlI1Y0dVK0NpQWdJQ0FnSUNBZ1BFUkVSazVoYldVK2RYSnVPbmRt
-CllUcHRienBvYjNSemNHOTBNbVJ2ZERBdGNHVnljSEp2ZG1sa1pYSnpkV0p6WTNKcGNIUnBiMjQ2
-TVM0d1BDOUVSRVpPWVcxbFBnb2cKSUNBZ0lDQThMMVI1Y0dVK0NpQWdJQ0E4TDFKVVVISnZjR1Z5
-ZEdsbGN6NEtJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQThUbTlrWlU1aApiV1UrYVRBd01Ud3ZUbTlr
-WlU1aGJXVStDaUFnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUR4T2IyUmxUbUZ0WlQ1SWIyMWxV
-MUE4CkwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZa
-R1ZPWVcxbFBrWnlhV1Z1Wkd4NVRtRnQKWlR3dlRtOWtaVTVoYldVK0NpQWdJQ0FnSUNBZ0lDQThW
-bUZzZFdVK1JYaGhiWEJzWlNCT1pYUjNiM0pyUEM5V1lXeDFaVDRLSUNBZwpJQ0FnSUNBOEwwNXZa
-R1UrQ2lBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0E4VG05a1pVNWhiV1UrUmxGRVRq
-d3ZUbTlrClpVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNBOFZtRnNkV1UrYUc5MGMzQnZkQzVsZUdGdGNH
-eGxMbTVsZER3dlZtRnNkV1UrQ2lBZ0lDQWcKSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUR4T2Iy
-UmxQZ29nSUNBZ0lDQWdJQ0FnUEU1dlpHVk9ZVzFsUGxKdllXMXBibWREYjI1egpiM0owYVhWdFQw
-azhMMDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQakV4TWpJek15dzBORFUxTmpZ
-OEwxWmhiSFZsClBnb2dJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNB
-Z0lDQThUbTlrWlQ0S0lDQWdJQ0FnSUNBOFRtOWsKWlU1aGJXVStRM0psWkdWdWRHbGhiRHd2VG05
-a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0E4VG05awpaVTVoYldV
-K1VtVmhiRzA4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ1BGWmhiSFZsUG1WNFlXMXdiR1V1
-WTI5dFBDOVdZV3gxClpUNEtJQ0FnSUNBZ0lDQThMMDV2WkdVK0NpQWdJQ0FnSUNBZ1BFNXZaR1Ur
-Q2lBZ0lDQWdJQ0FnSUNBOFRtOWtaVTVoYldVK1ZYTmwKY201aGJXVlFZWE56ZDI5eVpEd3ZUbTlr
-WlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0E4VG05a1pUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEU1dgpaR1ZP
-WVcxbFBsVnpaWEp1WVcxbFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQ
-blZ6WlhJOEwxWmhiSFZsClBnb2dJQ0FnSUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdQ
-RTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJSbFRtRnQKWlQ1UVlYTnpkMjl5WkR3dlRtOWta
-VTVoYldVK0NpQWdJQ0FnSUNBZ0lDQWdJRHhXWVd4MVpUNWpSMFo2WXpOa2RtTnRVVDA4TDFaaApi
-SFZsUGdvZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZaR1UrQ2lBZ0lD
-QWdJQ0FnSUNBZ0lEeE9iMlJsClRtRnRaVDVGUVZCTlpYUm9iMlE4TDA1dlpHVk9ZVzFsUGdvZ0lD
-QWdJQ0FnSUNBZ0lDQThUbTlrWlQ0S0lDQWdJQ0FnSUNBZ0lDQWcKSUNBOFRtOWtaVTVoYldVK1JV
-RlFWSGx3WlR3dlRtOWtaVTVoYldVK0NpQWdJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQakl4UEM5
-VwpZV3gxWlQ0S0lDQWdJQ0FnSUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdJQ0E4VG05
-a1pUNEtJQ0FnSUNBZ0lDQWdJQ0FnCklDQThUbTlrWlU1aGJXVStTVzV1WlhKTlpYUm9iMlE4TDA1
-dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ0lDQWdJRHhXWVd4MVpUNU4KVXkxRFNFRlFMVll5UEM5
-V1lXeDFaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJs
-UGdvZwpJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0Fn
-SUR4T2IyUmxUbUZ0WlQ1RWFXZHBkR0ZzClEyVnlkR2xtYVdOaGRHVThMMDV2WkdWT1lXMWxQZ29n
-SUNBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2IyUmwKVG1GdFpUNURaWEow
-YVdacFkyRjBaVlI1Y0dVOEwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWdJQ0E4Vm1Gc2RXVStl
-RFV3T1hZegpQQzlXWVd4MVpUNEtJQ0FnSUNBZ0lDQWdJRHd2VG05a1pUNEtJQ0FnSUNBZ0lDQWdJ
-RHhPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdJQ0E4ClRtOWtaVTVoYldVK1EyVnlkRk5JUVRJMU5rWnBi
-bWRsY25CeWFXNTBQQzlPYjJSbFRtRnRaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BGWmgKYkhWbFBqRm1N
-V1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1X
-WXhaakZtTVdZeApaakZtTVdZeFpqRm1NV1k4TDFaaGJIVmxQZ29nSUNBZ0lDQWdJQ0FnUEM5T2Iy
-UmxQZ29nSUNBZ0lDQWdJRHd2VG05a1pUNEtJQ0FnCklDQWdJQ0E4VG05a1pUNEtJQ0FnSUNBZ0lD
-QWdJRHhPYjJSbFRtRnRaVDVUU1UwOEwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWcKUEU1dlpH
-VStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2IyUmxUbUZ0WlQ1SlRWTkpQQzlPYjJSbFRtRnRaVDRLSUNB
-Z0lDQWdJQ0FnSUNBZwpQRlpoYkhWbFBqRXlNelExTmlvOEwxWmhiSFZsUGdvZ0lDQWdJQ0FnSUNB
-Z1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZaR1UrCkNpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJS
-bFRtRnRaVDVGUVZCVWVYQmxQQzlPYjJSbFRtRnRaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BGWmgKYkhW
-bFBqSXpQQzlXWVd4MVpUNEtJQ0FnSUNBZ0lDQWdJRHd2VG05a1pUNEtJQ0FnSUNBZ0lDQThMMDV2
-WkdVK0NpQWdJQ0FnSUR3dgpUbTlrWlQ0S0lDQWdJRHd2VG05a1pUNEtJQ0E4TDA1dlpHVStDand2
-VFdkdGRGUnlaV1UrCgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi94LXg1
-MDktY2EtY2VydApDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBiYXNlNjQKCkxTMHRMUzFDUlVk
-SlRpQkRSVkpVU1VaSlEwRlVSUzB0TFMwdENrMUpTVVJMUkVORFFXaERaMEYzU1VKQlowbEtRVWxN
-YkVaa2QzcE0KVm5WeVRVRXdSME5UY1VkVFNXSXpSRkZGUWtOM1ZVRk5Ra2w0UlVSQlQwSm5UbFlL
-UWtGTlZFSXdWa0pWUTBKRVVWUkZkMGhvWTA1TgpWRmwzVFZSRmVVMVVSVEZOUkVVeFYyaGpUazFx
-V1hkTlZFRTFUVlJGTVUxRVJURlhha0ZUVFZKQmR3cEVaMWxFVmxGUlJFVjNaRVpSClZrRm5VVEJG
-ZUUxSlNVSkpha0ZPUW1kcmNXaHJhVWM1ZHpCQ1FWRkZSa0ZCVDBOQlVUaEJUVWxKUWtOblMwTkJV
-VVZCQ25wdVFWQlYKZWpJMlRYTmhaVFIzY3pRelkzcFNOREV2U2pKUmRISlRTVnBWUzIxV1ZYTldk
-VzFFWWxsSWNsQk9kbFJZUzFOTldFRmpaWGRQVWtSUgpXVmdLVW5GMlNIWndiamhEYzJOQ01TdHZS
-MWhhZGtoM2VHbzBlbFl3VjB0dlN6SjZaVmhyWVhVemRtTjViRE5JU1V0MWNFcG1jVEpVClJVRkRa
-V1pXYW1vd2RBcEtWeXRZTXpWUVIxZHdPUzlJTlhwSlZVNVdUbFpxVXpkVmJYTTRORWwyUzJoU1Fq
-ZzFNVEpRUWpsVmVVaGgKWjFoWlZsZzFSMWR3UVdOV2NIbG1jbXhTQ2taSk9WRmthR2dyVUdKck1I
-VjVhM1JrWW1ZdlEyUm1aMGhQYjJWaWNsUjBkMUpzYWswdwpiMFIwV0NzeVEzWTJhakIzUWtzM2FF
-UTRjRkIyWmpFcmRYa0tSM3BqZW1sblFWVXZORXQzTjJWYWNYbGtaamxDS3pWU2RYQlNLMGxhCmFY
-QllOREY0UldsSmNrdFNkM0ZwTlRFM1YxZDZXR05xWVVjeVkwNWlaalExTVFwNGNFZzFVRzVXTTJr
-eGRIRXdOR3BOUjFGVmVrWjMKU1VSQlVVRkNielJIUVUxSU5IZElVVmxFVmxJd1QwSkNXVVZHU1hk
-WU5IWnpPRUpwUW1OVFkyOWtDalZ1YjFwSVVrMDRSVFFyYVUxRgpTVWRCTVZWa1NYZFJOMDFFYlVG
-R1NYZFlOSFp6T0VKcFFtTlRZMjlrTlc1dldraFNUVGhGTkN0cGIxSmhhMFpFUVZNS1RWSkJkMFJu
-CldVUldVVkZFUlhka1JsRldRV2RSTUVWNFoyZHJRV2QxVlZZelJFMTBWelp6ZDBSQldVUldVakJV
-UWtGVmQwRjNSVUl2ZWtGTVFtZE8KVmdwSVVUaEZRa0ZOUTBGUldYZEVVVmxLUzI5YVNXaDJZMDVC
-VVVWTVFsRkJSR2RuUlVKQlJtWlJjVTlVUVRkU2RqZExLMngxVVRkdwpibUZ6TkVKWmQwaEZDamxI
-UlZBdmRXOW9kalpMVDNrd1ZFZFJSbUp5VWxScVJtOU1WazVDT1VKYU1YbHRUVVJhTUM5VVNYZEpW
-V00zCmQyazNZVGgwTlcxRmNWbElNVFV6ZDFjS1lWZHZiMmxUYW5sTVRHaDFTVFJ6VG5KT1EwOTBh
-WE5rUW5FeWNqSk5SbGgwTm1nd2JVRlIKV1U5UWRqaFNPRXMzTDJablUzaEhSbkY2YUhsT2JXMVdU
-QW94Y1VKS2JHUjRNelJUY0hkelZFRk1VVlpRWWpSb1IzZEtlbHBtY2pGUQpZM0JGVVhnMmVFMXVW
-R3c0ZUVWWFdrVXpUWE01T1hWaFZYaGlVWEZKZDFKMUNreG5RVTlyVGtOdFdUSnRPRGxXYUhwaFNF
-b3hkVlk0Ck5VRmtUUzkwUkN0WmMyMXNibTVxZERsTVVrTmxhbUpDYVhCcVNVZHFUMWh5WnpGS1VD
-dHNlRllLYlhWTk5IWklLMUF2Yld4dGVITlEKVUhvd1pEWTFZaXRGUjIxS1duQnZUR3RQTDNSa1Rr
-NTJRMWw2YWtwd1ZFVlhjRVZ6VHpaT1RXaExXVzg5Q2kwdExTMHRSVTVFSUVORgpVbFJKUmtsRFFW
-UkZMUzB0TFMwSwotLXtib3VuZGFyeX0tLQo=
\ No newline at end of file
diff --git a/wifi/tests/assets/hsr1/HSR1ProfileWithUpdateIdentifier.base64 b/wifi/tests/assets/hsr1/HSR1ProfileWithUpdateIdentifier.base64
deleted file mode 100644
index bab7607..0000000
--- a/wifi/tests/assets/hsr1/HSR1ProfileWithUpdateIdentifier.base64
+++ /dev/null
@@ -1,88 +0,0 @@
-TUlNRS1WZXJzaW9uOiAxLjAKQ29udGVudC1UeXBlOiBtdWx0aXBhcnQvbWl4ZWQ7IGJvdW5kYXJ5
-PXtib3VuZGFyeX07IGNoYXJzZXQ9VVRGLTgKQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogYmFz
-ZTY0CgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi94LXBhc3Nwb2ludC1w
-cm9maWxlOyBjaGFyc2V0PVVURi04CkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IGJhc2U2NAoK
-UEUxbmJYUlVjbVZsSUhodGJHNXpQU0p6ZVc1amJXdzZaRzFrWkdZeExqSWlQZ29nSUR4V1pYSkVW
-RVErTVM0eVBDOVdaWEpFVkVRKwpDaUFnUEU1dlpHVStDaUFnSUNBOFRtOWtaVTVoYldVK1VHVnlV
-SEp2ZG1sa1pYSlRkV0p6WTNKcGNIUnBiMjQ4TDA1dlpHVk9ZVzFsClBnb2dJQ0FnUEZKVVVISnZj
-R1Z5ZEdsbGN6NEtJQ0FnSUNBZ1BGUjVjR1UrQ2lBZ0lDQWdJQ0FnUEVSRVJrNWhiV1UrZFhKdU9u
-ZG0KWVRwdGJ6cG9iM1J6Y0c5ME1tUnZkREF0Y0dWeWNISnZkbWxrWlhKemRXSnpZM0pwY0hScGIy
-NDZNUzR3UEM5RVJFWk9ZVzFsUGdvZwpJQ0FnSUNBOEwxUjVjR1UrQ2lBZ0lDQThMMUpVVUhKdmNH
-VnlkR2xsY3o0S0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBOFRtOWtaVTVoCmJXVStWWEJrWVhSbFNX
-UmxiblJwWm1sbGNqd3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lEeFdZV3gxWlQ0eE1qTTBQQzlXWVd4
-MVpUNEsKSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBOFRtOWtaVTVoYldV
-K2FUQXdNVHd2VG05a1pVNWhiV1UrQ2lBZwpJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQWdJRHhPYjJS
-bFRtRnRaVDVJYjIxbFUxQThMMDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJRHhPCmIyUmxQZ29nSUNB
-Z0lDQWdJQ0FnUEU1dlpHVk9ZVzFsUGtaeWFXVnVaR3g1VG1GdFpUd3ZUbTlrWlU1aGJXVStDaUFn
-SUNBZ0lDQWcKSUNBOFZtRnNkV1UrUlhoaGJYQnNaU0JPWlhSM2IzSnJQQzlXWVd4MVpUNEtJQ0Fn
-SUNBZ0lDQThMMDV2WkdVK0NpQWdJQ0FnSUNBZwpQRTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThUbTlr
-WlU1aGJXVStSbEZFVGp3dlRtOWtaVTVoYldVK0NpQWdJQ0FnSUNBZ0lDQThWbUZzCmRXVSthRzkw
-YzNCdmRDNWxlR0Z0Y0d4bExtNWxkRHd2Vm1Gc2RXVStDaUFnSUNBZ0lDQWdQQzlPYjJSbFBnb2dJ
-Q0FnSUNBZ0lEeE8KYjJSbFBnb2dJQ0FnSUNBZ0lDQWdQRTV2WkdWT1lXMWxQbEp2WVcxcGJtZERi
-MjV6YjNKMGFYVnRUMGs4TDA1dlpHVk9ZVzFsUGdvZwpJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBqRXhN
-akl6TXl3ME5EVTFOalk4TDFaaGJIVmxQZ29nSUNBZ0lDQWdJRHd2VG05a1pUNEtJQ0FnCklDQWdQ
-QzlPYjJSbFBnb2dJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0E4VG05a1pVNWhiV1UrUTNKbFpH
-VnVkR2xoYkR3dlRtOWsKWlU1aGJXVStDaUFnSUNBZ0lDQWdQRTV2WkdVK0NpQWdJQ0FnSUNBZ0lD
-QThUbTlrWlU1aGJXVStVbVZoYkcwOEwwNXZaR1ZPWVcxbApQZ29nSUNBZ0lDQWdJQ0FnUEZaaGJI
-VmxQbVY0WVcxd2JHVXVZMjl0UEM5V1lXeDFaVDRLSUNBZ0lDQWdJQ0E4TDA1dlpHVStDaUFnCklD
-QWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0E4VG05a1pVNWhiV1UrVlhObGNtNWhiV1ZRWVhO
-emQyOXlaRHd2VG05a1pVNWgKYldVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrWlQ0S0lDQWdJQ0FnSUNB
-Z0lDQWdQRTV2WkdWT1lXMWxQbFZ6WlhKdVlXMWxQQzlPYjJSbApUbUZ0WlQ0S0lDQWdJQ0FnSUNB
-Z0lDQWdQRlpoYkhWbFBuVnpaWEk4TDFaaGJIVmxQZ29nSUNBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29n
-CklDQWdJQ0FnSUNBZ1BFNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lEeE9iMlJsVG1GdFpUNVFZWE56
-ZDI5eVpEd3ZUbTlrWlU1aGJXVSsKQ2lBZ0lDQWdJQ0FnSUNBZ0lEeFdZV3gxWlQ1alIwWjZZek5r
-ZG1OdFVUMDhMMVpoYkhWbFBnb2dJQ0FnSUNBZ0lDQWdQQzlPYjJSbApQZ29nSUNBZ0lDQWdJQ0Fn
-UEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2IyUmxUbUZ0WlQ1RlFWQk5aWFJvYjJROEwwNXZa
-R1ZPCllXMWxQZ29nSUNBZ0lDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0FnSUNBZ0lDQThU
-bTlrWlU1aGJXVStSVUZRVkhsd1pUd3YKVG05a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lDQWdQ
-RlpoYkhWbFBqSXhQQzlXWVd4MVpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEM5TwpiMlJsUGdvZ0lDQWdJ
-Q0FnSUNBZ0lDQThUbTlrWlQ0S0lDQWdJQ0FnSUNBZ0lDQWdJQ0E4VG05a1pVNWhiV1UrU1c1dVpY
-Sk5aWFJvCmIyUThMMDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnSUNBZ0lEeFdZV3gxWlQ1TlV5
-MURTRUZRTFZZeVBDOVdZV3gxWlQ0S0lDQWcKSUNBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lD
-QWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJRHd2VG05a1pUNEtJQ0FnSUNBZwpJQ0E4VG05a1pU
-NEtJQ0FnSUNBZ0lDQWdJRHhPYjJSbFRtRnRaVDVFYVdkcGRHRnNRMlZ5ZEdsbWFXTmhkR1U4TDA1
-dlpHVk9ZVzFsClBnb2dJQ0FnSUNBZ0lDQWdQRTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJS
-bFRtRnRaVDVEWlhKMGFXWnBZMkYwWlZSNWNHVTgKTDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNB
-Z0lDQThWbUZzZFdVK2VEVXdPWFl6UEM5V1lXeDFaVDRLSUNBZ0lDQWdJQ0FnSUR3dgpUbTlrWlQ0
-S0lDQWdJQ0FnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThUbTlrWlU1aGJXVStRMlZ5
-ZEZOSVFUSTFOa1pwCmJtZGxjbkJ5YVc1MFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0Fn
-UEZaaGJIVmxQakZtTVdZeFpqRm1NV1l4WmpGbU1XWXgKWmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4
-WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaakZtTVdZOEwxWmhiSFZsUGdvZwpJQ0Fn
-SUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJQ0FnSUNBOFRtOWta
-VDRLSUNBZ0lDQWdJQ0FnCklEeE9iMlJsVG1GdFpUNVRTVTA4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJ
-Q0FnSUNBZ1BFNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lEeE8KYjJSbFRtRnRaVDVKVFZOSlBDOU9i
-MlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQakV5TXpRMU5pbzhMMVpoYkhWbApQ
-Z29nSUNBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lD
-QWdJQ0FnSUR4T2IyUmxUbUZ0ClpUNUZRVkJVZVhCbFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lD
-QWdJQ0FnUEZaaGJIVmxQakl6UEM5V1lXeDFaVDRLSUNBZ0lDQWcKSUNBZ0lEd3ZUbTlrWlQ0S0lD
-QWdJQ0FnSUNBOEwwNXZaR1UrQ2lBZ0lDQWdJRHd2VG05a1pUNEtJQ0FnSUR3dlRtOWtaVDRLSUNB
-OApMMDV2WkdVK0Nqd3ZUV2R0ZEZSeVpXVSsKCi0te2JvdW5kYXJ5fQpDb250ZW50LVR5cGU6IGFw
-cGxpY2F0aW9uL3gteDUwOS1jYS1jZXJ0CkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IGJhc2U2
-NAoKTFMwdExTMUNSVWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVUkxSRU5EUVdoRFow
-RjNTVUpCWjBsS1FVbE1iRVprZDNwTQpWblZ5VFVFd1IwTlRjVWRUU1dJelJGRkZRa04zVlVGTlFr
-bDRSVVJCVDBKblRsWUtRa0ZOVkVJd1ZrSlZRMEpFVVZSRmQwaG9ZMDVOClZGbDNUVlJGZVUxVVJU
-Rk5SRVV4VjJoalRrMXFXWGROVkVFMVRWUkZNVTFFUlRGWGFrRlRUVkpCZHdwRVoxbEVWbEZSUkVW
-M1pFWlIKVmtGblVUQkZlRTFKU1VKSmFrRk9RbWRyY1docmFVYzVkekJDUVZGRlJrRkJUME5CVVRo
-QlRVbEpRa05uUzBOQlVVVkJDbnB1UVZCVgplakkyVFhOaFpUUjNjelF6WTNwU05ERXZTakpSZEhK
-VFNWcFZTMjFXVlhOV2RXMUVZbGxJY2xCT2RsUllTMU5OV0VGalpYZFBVa1JSCldWZ0tVbkYyU0ha
-d2JqaERjMk5DTVN0dlIxaGFka2gzZUdvMGVsWXdWMHR2U3pKNlpWaHJZWFV6ZG1ONWJETklTVXQx
-Y0VwbWNUSlUKUlVGRFpXWldhbW93ZEFwS1Z5dFlNelZRUjFkd09TOUlOWHBKVlU1V1RsWnFVemRW
-YlhNNE5FbDJTMmhTUWpnMU1USlFRamxWZVVoaApaMWhaVmxnMVIxZHdRV05XY0hsbWNteFNDa1pK
-T1ZGa2FHZ3JVR0pyTUhWNWEzUmtZbVl2UTJSbVowaFBiMlZpY2xSMGQxSnNhazB3CmIwUjBXQ3N5
-UTNZMmFqQjNRa3MzYUVRNGNGQjJaakVyZFhrS1IzcGplbWxuUVZVdk5FdDNOMlZhY1hsa1pqbENL
-elZTZFhCU0swbGEKYVhCWU5ERjRSV2xKY2t0U2QzRnBOVEUzVjFkNldHTnFZVWN5WTA1aVpqUTFN
-UXA0Y0VnMVVHNVdNMmt4ZEhFd05HcE5SMUZWZWtaMwpTVVJCVVVGQ2J6UkhRVTFJTkhkSVVWbEVW
-bEl3VDBKQ1dVVkdTWGRZTkhaek9FSnBRbU5UWTI5a0NqVnViMXBJVWswNFJUUXJhVTFGClNVZEJN
-VlZrU1hkUk4wMUViVUZHU1hkWU5IWnpPRUpwUW1OVFkyOWtOVzV2V2toU1RUaEZOQ3RwYjFKaGEw
-WkVRVk1LVFZKQmQwUm4KV1VSV1VWRkVSWGRrUmxGV1FXZFJNRVY0WjJkclFXZDFWVll6UkUxMFZ6
-WnpkMFJCV1VSV1VqQlVRa0ZWZDBGM1JVSXZla0ZNUW1kTwpWZ3BJVVRoRlFrRk5RMEZSV1hkRVVW
-bEtTMjlhU1doMlkwNUJVVVZNUWxGQlJHZG5SVUpCUm1aUmNVOVVRVGRTZGpkTEsyeDFVVGR3CmJt
-RnpORUpaZDBoRkNqbEhSVkF2ZFc5b2RqWkxUM2t3VkVkUlJtSnlVbFJxUm05TVZrNUNPVUphTVhs
-dFRVUmFNQzlVU1hkSlZXTTMKZDJrM1lUaDBOVzFGY1ZsSU1UVXpkMWNLWVZkdmIybFRhbmxNVEdo
-MVNUUnpUbkpPUTA5MGFYTmtRbkV5Y2pKTlJsaDBObWd3YlVGUgpXVTlRZGpoU09FczNMMlpuVTNo
-SFJuRjZhSGxPYlcxV1RBb3hjVUpLYkdSNE16UlRjSGR6VkVGTVVWWlFZalJvUjNkS2VscG1jakZR
-ClkzQkZVWGcyZUUxdVZHdzRlRVZYV2tVelRYTTVPWFZoVlhoaVVYRkpkMUoxQ2t4blFVOXJUa050
-V1RKdE9EbFdhSHBoU0VveGRWWTQKTlVGa1RTOTBSQ3RaYzIxc2JtNXFkRGxNVWtObGFtSkNhWEJx
-U1VkcVQxaHlaekZLVUN0c2VGWUtiWFZOTkhaSUsxQXZiV3h0ZUhOUQpVSG93WkRZMVlpdEZSMjFL
-V25CdlRHdFBMM1JrVGs1MlExbDZha3B3VkVWWGNFVnpUelpPVFdoTFdXODlDaTB0TFMwdFJVNUVJ
-RU5GClVsUkpSa2xEUVZSRkxTMHRMUzBLCi0te2JvdW5kYXJ5fS0tCg==
\ No newline at end of file
diff --git a/wifi/tests/assets/hsr1/HSR1ProfileWithoutProfile.base64 b/wifi/tests/assets/hsr1/HSR1ProfileWithoutProfile.base64
deleted file mode 100644
index 833c527..0000000
--- a/wifi/tests/assets/hsr1/HSR1ProfileWithoutProfile.base64
+++ /dev/null
@@ -1,31 +0,0 @@
-Q29udGVudC1UeXBlOiBtdWx0aXBhcnQvbWl4ZWQ7IGJvdW5kYXJ5PXtib3VuZGFyeX0KQ29udGVu
-dC1UcmFuc2Zlci1FbmNvZGluZzogYmFzZTY0CgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBh
-cHBsaWNhdGlvbi94LXg1MDktY2EtY2VydApDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBiYXNl
-NjQKCkxTMHRMUzFDUlVkSlRpQkRSVkpVU1VaSlEwRlVSUzB0TFMwdENrMUpTVVJMUkVORFFXaERa
-MEYzU1VKQlowbEtRVWxNYkVaa2QzcE0KVm5WeVRVRXdSME5UY1VkVFNXSXpSRkZGUWtOM1ZVRk5R
-a2w0UlVSQlQwSm5UbFlLUWtGTlZFSXdWa0pWUTBKRVVWUkZkMGhvWTA1TgpWRmwzVFZSRmVVMVVS
-VEZOUkVVeFYyaGpUazFxV1hkTlZFRTFUVlJGTVUxRVJURlhha0ZUVFZKQmR3cEVaMWxFVmxGUlJF
-VjNaRVpSClZrRm5VVEJGZUUxSlNVSkpha0ZPUW1kcmNXaHJhVWM1ZHpCQ1FWRkZSa0ZCVDBOQlVU
-aEJUVWxKUWtOblMwTkJVVVZCQ25wdVFWQlYKZWpJMlRYTmhaVFIzY3pRelkzcFNOREV2U2pKUmRI
-SlRTVnBWUzIxV1ZYTldkVzFFWWxsSWNsQk9kbFJZUzFOTldFRmpaWGRQVWtSUgpXVmdLVW5GMlNI
-WndiamhEYzJOQ01TdHZSMWhhZGtoM2VHbzBlbFl3VjB0dlN6SjZaVmhyWVhVemRtTjViRE5JU1V0
-MWNFcG1jVEpVClJVRkRaV1pXYW1vd2RBcEtWeXRZTXpWUVIxZHdPUzlJTlhwSlZVNVdUbFpxVXpk
-VmJYTTRORWwyUzJoU1FqZzFNVEpRUWpsVmVVaGgKWjFoWlZsZzFSMWR3UVdOV2NIbG1jbXhTQ2ta
-Sk9WRmthR2dyVUdKck1IVjVhM1JrWW1ZdlEyUm1aMGhQYjJWaWNsUjBkMUpzYWswdwpiMFIwV0Nz
-eVEzWTJhakIzUWtzM2FFUTRjRkIyWmpFcmRYa0tSM3BqZW1sblFWVXZORXQzTjJWYWNYbGtaamxD
-S3pWU2RYQlNLMGxhCmFYQllOREY0UldsSmNrdFNkM0ZwTlRFM1YxZDZXR05xWVVjeVkwNWlaalEx
-TVFwNGNFZzFVRzVXTTJreGRIRXdOR3BOUjFGVmVrWjMKU1VSQlVVRkNielJIUVUxSU5IZElVVmxF
-VmxJd1QwSkNXVVZHU1hkWU5IWnpPRUpwUW1OVFkyOWtDalZ1YjFwSVVrMDRSVFFyYVUxRgpTVWRC
-TVZWa1NYZFJOMDFFYlVGR1NYZFlOSFp6T0VKcFFtTlRZMjlrTlc1dldraFNUVGhGTkN0cGIxSmhh
-MFpFUVZNS1RWSkJkMFJuCldVUldVVkZFUlhka1JsRldRV2RSTUVWNFoyZHJRV2QxVlZZelJFMTBW
-elp6ZDBSQldVUldVakJVUWtGVmQwRjNSVUl2ZWtGTVFtZE8KVmdwSVVUaEZRa0ZOUTBGUldYZEVV
-VmxLUzI5YVNXaDJZMDVCVVVWTVFsRkJSR2RuUlVKQlJtWlJjVTlVUVRkU2RqZExLMngxVVRkdwpi
-bUZ6TkVKWmQwaEZDamxIUlZBdmRXOW9kalpMVDNrd1ZFZFJSbUp5VWxScVJtOU1WazVDT1VKYU1Y
-bHRUVVJhTUM5VVNYZEpWV00zCmQyazNZVGgwTlcxRmNWbElNVFV6ZDFjS1lWZHZiMmxUYW5sTVRH
-aDFTVFJ6VG5KT1EwOTBhWE5rUW5FeWNqSk5SbGgwTm1nd2JVRlIKV1U5UWRqaFNPRXMzTDJablUz
-aEhSbkY2YUhsT2JXMVdUQW94Y1VKS2JHUjRNelJUY0hkelZFRk1VVlpRWWpSb1IzZEtlbHBtY2pG
-UQpZM0JGVVhnMmVFMXVWR3c0ZUVWWFdrVXpUWE01T1hWaFZYaGlVWEZKZDFKMUNreG5RVTlyVGtO
-dFdUSnRPRGxXYUhwaFNFb3hkVlk0Ck5VRmtUUzkwUkN0WmMyMXNibTVxZERsTVVrTmxhbUpDYVhC
-cVNVZHFUMWh5WnpGS1VDdHNlRllLYlhWTk5IWklLMUF2Yld4dGVITlEKVUhvd1pEWTFZaXRGUjIx
-S1duQnZUR3RQTDNSa1RrNTJRMWw2YWtwd1ZFVlhjRVZ6VHpaT1RXaExXVzg5Q2kwdExTMHRSVTVF
-SUVORgpVbFJKUmtsRFFWUkZMUzB0TFMwSwotLXtib3VuZGFyeX0tLQo=
diff --git a/wifi/tests/assets/hsr1/README.txt b/wifi/tests/assets/hsr1/README.txt
deleted file mode 100644
index 9f3cdc2..0000000
--- a/wifi/tests/assets/hsr1/README.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-HSR1ProfileWithCACert.conf - unencoded installation file that contains a Passpoint profile and a CA Certificate
-HSR1ProfileWithCACert.base64 - base64 encoded of the data contained in HSR1ProfileWithCAWith.conf
-HSR1ProfileWithNonBase64Part.base64 - base64 encoded installation file that contains a part of non-base64 encoding type
-HSR1ProfileWithMissingBoundary.base64 - base64 encoded installation file with missing end-boundary in the MIME data
-HSR1ProfileWithInvalidContentType.base64 - base64 encoded installation file with that contains a MIME part with an invalid content type
-HSR1ProfileWithUpdateIdentifier.base64 - base64 encoded installation file with that contains an R2 update identifier
diff --git a/wifi/tests/assets/pps/PerProviderSubscription.xml b/wifi/tests/assets/pps/PerProviderSubscription.xml
deleted file mode 100644
index e9afb35..0000000
--- a/wifi/tests/assets/pps/PerProviderSubscription.xml
+++ /dev/null
@@ -1,430 +0,0 @@
-<MgmtTree xmlns="syncml:dmddf1.2">
-  <VerDTD>1.2</VerDTD>
-  <Node>
-    <NodeName>PerProviderSubscription</NodeName>
-    <RTProperties>
-      <Type>
-        <DDFName>urn:wfa:mo:hotspot2dot0-perprovidersubscription:1.0</DDFName>
-      </Type>
-    </RTProperties>
-    <Node>
-      <NodeName>UpdateIdentifier</NodeName>
-      <Value>12</Value>
-    </Node>
-    <Node>
-      <NodeName>i001</NodeName>
-      <Node>
-        <NodeName>Extension</NodeName>
-        <Node>
-          <NodeName>VendorSpecific</NodeName>
-          <Value>Test</Value>
-        </Node>
-        <Node>
-          <NodeName>VendorExtension</NodeName>
-          <Node>
-            <NodeName>VendorAttribute</NodeName>
-            <Value>VendorValue</Value>
-          </Node>
-        </Node>
-        <Node>
-          <NodeName>Android</NodeName>
-          <Node>
-            <NodeName>AAAServerTrustedNames</NodeName>
-            <Node>
-              <NodeName>FQDN</NodeName>
-              <Value>trusted.fqdn.com;another-trusted.fqdn.com</Value>
-            </Node>
-          </Node>
-          <Node>
-            <NodeName>NewSubTree</NodeName>
-            <Node>
-              <NodeName>NewAttribute</NodeName>
-              <Value>NewValue</Value>
-            </Node>
-          </Node>
-        </Node>
-      </Node>
-      <Node>
-        <NodeName>HomeSP</NodeName>
-        <Node>
-          <NodeName>FriendlyName</NodeName>
-          <Value>Century House</Value>
-        </Node>
-        <Node>
-          <NodeName>FQDN</NodeName>
-          <Value>mi6.co.uk</Value>
-        </Node>
-        <Node>
-          <NodeName>RoamingConsortiumOI</NodeName>
-          <Value>112233,445566</Value>
-        </Node>
-        <Node>
-          <NodeName>IconURL</NodeName>
-          <Value>icon.test.com</Value>
-        </Node>
-        <Node>
-          <NodeName>NetworkID</NodeName>
-          <Node>
-            <NodeName>n001</NodeName>
-            <Node>
-              <NodeName>SSID</NodeName>
-              <Value>TestSSID</Value>
-            </Node>
-            <Node>
-              <NodeName>HESSID</NodeName>
-              <Value>12345678</Value>
-            </Node>
-          </Node>
-          <Node>
-            <NodeName>n002</NodeName>
-            <Node>
-              <NodeName>SSID</NodeName>
-              <Value>NullHESSID</Value>
-            </Node>
-          </Node>
-        </Node>
-        <Node>
-          <NodeName>HomeOIList</NodeName>
-          <Node>
-            <NodeName>h001</NodeName>
-            <Node>
-              <NodeName>HomeOI</NodeName>
-              <Value>11223344</Value>
-            </Node>
-            <Node>
-              <NodeName>HomeOIRequired</NodeName>
-              <Value>true</Value>
-            </Node>
-          </Node>
-          <Node>
-            <NodeName>h002</NodeName>
-            <Node>
-              <NodeName>HomeOI</NodeName>
-              <Value>55667788</Value>
-            </Node>
-            <Node>
-              <NodeName>HomeOIRequired</NodeName>
-              <Value>false</Value>
-            </Node>
-          </Node>
-        </Node>
-        <Node>
-          <NodeName>OtherHomePartners</NodeName>
-          <Node>
-            <NodeName>o001</NodeName>
-            <Node>
-              <NodeName>FQDN</NodeName>
-              <Value>other.fqdn.com</Value>
-            </Node>
-          </Node>
-        </Node>
-      </Node>
-      <Node>
-        <NodeName>Credential</NodeName>
-        <Node>
-          <NodeName>CreationDate</NodeName>
-          <Value>2016-01-01T10:00:00Z</Value>
-        </Node>
-        <Node>
-          <NodeName>ExpirationDate</NodeName>
-          <Value>2016-02-01T10:00:00Z</Value>
-        </Node>
-        <Node>
-          <NodeName>Realm</NodeName>
-          <Value>shaken.stirred.com</Value>
-        </Node>
-        <Node>
-          <NodeName>CheckAAAServerCertStatus</NodeName>
-          <Value>true</Value>
-        </Node>
-        <Node>
-          <NodeName>UsernamePassword</NodeName>
-          <Node>
-            <NodeName>Username</NodeName>
-            <Value>james</Value>
-          </Node>
-          <Node>
-            <NodeName>Password</NodeName>
-            <Value>Ym9uZDAwNw==</Value>
-          </Node>
-          <Node>
-            <NodeName>MachineManaged</NodeName>
-            <Value>true</Value>
-          </Node>
-          <Node>
-            <NodeName>SoftTokenApp</NodeName>
-            <Value>TestApp</Value>
-          </Node>
-          <Node>
-            <NodeName>AbleToShare</NodeName>
-            <Value>true</Value>
-          </Node>
-          <Node>
-            <NodeName>EAPMethod</NodeName>
-            <Node>
-              <NodeName>EAPType</NodeName>
-              <Value>21</Value>
-            </Node>
-            <Node>
-              <NodeName>InnerMethod</NodeName>
-              <Value>MS-CHAP-V2</Value>
-            </Node>
-          </Node>
-        </Node>
-        <Node>
-          <NodeName>DigitalCertificate</NodeName>
-          <Node>
-            <NodeName>CertificateType</NodeName>
-            <Value>x509v3</Value>
-          </Node>
-          <Node>
-            <NodeName>CertSHA256Fingerprint</NodeName>
-            <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value>
-          </Node>
-        </Node>
-        <Node>
-          <NodeName>SIM</NodeName>
-          <Node>
-            <NodeName>IMSI</NodeName>
-            <Value>imsi</Value>
-          </Node>
-          <Node>
-            <NodeName>EAPType</NodeName>
-            <Value>24</Value>
-          </Node>
-        </Node>
-      </Node>
-      <Node>
-        <NodeName>Policy</NodeName>
-        <Node>
-          <NodeName>PreferredRoamingPartnerList</NodeName>
-          <Node>
-            <NodeName>p001</NodeName>
-            <Node>
-              <NodeName>FQDN_Match</NodeName>
-              <Value>test1.fqdn.com,exactMatch</Value>
-            </Node>
-            <Node>
-              <NodeName>Priority</NodeName>
-              <Value>127</Value>
-            </Node>
-            <Node>
-              <NodeName>Country</NodeName>
-              <Value>us,fr</Value>
-            </Node>
-          </Node>
-          <Node>
-            <NodeName>p002</NodeName>
-            <Node>
-              <NodeName>FQDN_Match</NodeName>
-              <Value>test2.fqdn.com,includeSubdomains</Value>
-            </Node>
-            <Node>
-              <NodeName>Priority</NodeName>
-              <Value>200</Value>
-            </Node>
-            <Node>
-              <NodeName>Country</NodeName>
-              <Value>*</Value>
-            </Node>
-          </Node>
-        </Node>
-        <Node>
-          <NodeName>MinBackhaulThreshold</NodeName>
-          <Node>
-            <NodeName>m001</NodeName>
-            <Node>
-              <NodeName>NetworkType</NodeName>
-              <Value>home</Value>
-            </Node>
-            <Node>
-              <NodeName>DLBandwidth</NodeName>
-              <Value>23412</Value>
-            </Node>
-            <Node>
-              <NodeName>ULBandwidth</NodeName>
-              <Value>9823</Value>
-            </Node>
-          </Node>
-          <Node>
-            <NodeName>m002</NodeName>
-            <Node>
-              <NodeName>NetworkType</NodeName>
-              <Value>roaming</Value>
-            </Node>
-            <Node>
-              <NodeName>DLBandwidth</NodeName>
-              <Value>9271</Value>
-            </Node>
-            <Node>
-              <NodeName>ULBandwidth</NodeName>
-              <Value>2315</Value>
-            </Node>
-          </Node>
-        </Node>
-        <Node>
-          <NodeName>PolicyUpdate</NodeName>
-          <Node>
-            <NodeName>UpdateInterval</NodeName>
-            <Value>120</Value>
-          </Node>
-          <Node>
-            <NodeName>UpdateMethod</NodeName>
-            <Value>OMA-DM-ClientInitiated</Value>
-          </Node>
-          <Node>
-            <NodeName>Restriction</NodeName>
-            <Value>HomeSP</Value>
-          </Node>
-          <Node>
-            <NodeName>URI</NodeName>
-            <Value>policy.update.com</Value>
-          </Node>
-          <Node>
-            <NodeName>UsernamePassword</NodeName>
-            <Node>
-              <NodeName>Username</NodeName>
-              <Value>updateUser</Value>
-            </Node>
-            <Node>
-              <NodeName>Password</NodeName>
-              <Value>updatePass</Value>
-            </Node>
-          </Node>
-          <Node>
-            <NodeName>TrustRoot</NodeName>
-            <Node>
-              <NodeName>CertURL</NodeName>
-              <Value>update.cert.com</Value>
-            </Node>
-            <Node>
-              <NodeName>CertSHA256Fingerprint</NodeName>
-              <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value>
-            </Node>
-          </Node>
-        </Node>
-        <Node>
-          <NodeName>SPExclusionList</NodeName>
-          <Node>
-            <NodeName>s001</NodeName>
-            <Node>
-              <NodeName>SSID</NodeName>
-              <Value>excludeSSID</Value>
-            </Node>
-          </Node>
-        </Node>
-        <Node>
-          <NodeName>RequiredProtoPortTuple</NodeName>
-          <Node>
-            <NodeName>r001</NodeName>
-            <Node>
-              <NodeName>IPProtocol</NodeName>
-              <Value>12</Value>
-            </Node>
-            <Node>
-              <NodeName>PortNumber</NodeName>
-              <Value>34,92,234</Value>
-            </Node>
-          </Node>
-        </Node>
-        <Node>
-          <NodeName>MaximumBSSLoadValue</NodeName>
-          <Value>23</Value>
-        </Node>
-      </Node>
-      <Node>
-        <NodeName>CredentialPriority</NodeName>
-        <Value>99</Value>
-      </Node>
-      <Node>
-        <NodeName>AAAServerTrustRoot</NodeName>
-        <Node>
-          <NodeName>a001</NodeName>
-          <Node>
-            <NodeName>CertURL</NodeName>
-            <Value>server1.trust.root.com</Value>
-          </Node>
-          <Node>
-            <NodeName>CertSHA256Fingerprint</NodeName>
-            <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value>
-          </Node>
-        </Node>
-      </Node>
-      <Node>
-        <NodeName>SubscriptionUpdate</NodeName>
-        <Node>
-          <NodeName>UpdateInterval</NodeName>
-          <Value>120</Value>
-        </Node>
-        <Node>
-          <NodeName>UpdateMethod</NodeName>
-          <Value>SSP-ClientInitiated</Value>
-        </Node>
-        <Node>
-          <NodeName>Restriction</NodeName>
-          <Value>RoamingPartner</Value>
-        </Node>
-        <Node>
-          <NodeName>URI</NodeName>
-          <Value>subscription.update.com</Value>
-        </Node>
-        <Node>
-          <NodeName>UsernamePassword</NodeName>
-          <Node>
-            <NodeName>Username</NodeName>
-            <Value>subscriptionUser</Value>
-          </Node>
-          <Node>
-            <NodeName>Password</NodeName>
-            <Value>subscriptionPass</Value>
-          </Node>
-        </Node>
-        <Node>
-          <NodeName>TrustRoot</NodeName>
-          <Node>
-            <NodeName>CertURL</NodeName>
-            <Value>subscription.update.cert.com</Value>
-          </Node>
-          <Node>
-            <NodeName>CertSHA256Fingerprint</NodeName>
-            <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value>
-          </Node>
-        </Node>
-      </Node>
-      <Node>
-        <NodeName>SubscriptionParameters</NodeName>
-        <Node>
-          <NodeName>CreationDate</NodeName>
-          <Value>2016-02-01T10:00:00Z</Value>
-        </Node>
-        <Node>
-          <NodeName>ExpirationDate</NodeName>
-          <Value>2016-03-01T10:00:00Z</Value>
-        </Node>
-        <Node>
-          <NodeName>TypeOfSubscription</NodeName>
-          <Value>Gold</Value>
-        </Node>
-        <Node>
-          <NodeName>UsageLimits</NodeName>
-          <Node>
-            <NodeName>DataLimit</NodeName>
-            <Value>921890</Value>
-          </Node>
-          <Node>
-            <NodeName>StartDate</NodeName>
-            <Value>2016-12-01T10:00:00Z</Value>
-          </Node>
-          <Node>
-            <NodeName>TimeLimit</NodeName>
-            <Value>120</Value>
-          </Node>
-          <Node>
-            <NodeName>UsageTimePeriod</NodeName>
-            <Value>99910</Value>
-          </Node>
-        </Node>
-      </Node>
-    </Node>
-  </Node>
-</MgmtTree>
diff --git a/wifi/tests/assets/pps/PerProviderSubscription_DuplicateHomeSP.xml b/wifi/tests/assets/pps/PerProviderSubscription_DuplicateHomeSP.xml
deleted file mode 100644
index e13eb2a..0000000
--- a/wifi/tests/assets/pps/PerProviderSubscription_DuplicateHomeSP.xml
+++ /dev/null
@@ -1,95 +0,0 @@
-<MgmtTree xmlns="syncml:dmddf1.2">
-  <VerDTD>1.2</VerDTD>
-  <Node>
-    <NodeName>PerProviderSubscription</NodeName>
-    <RTProperties>
-      <Type>
-        <DDFName>urn:wfa:mo:hotspot2dot0-perprovidersubscription:1.0</DDFName>
-      </Type>
-    </RTProperties>
-    <Node>
-      <NodeName>i001</NodeName>
-      <Node>
-        <NodeName>HomeSP</NodeName>
-        <Node>
-          <NodeName>FriendlyName</NodeName>
-          <Value>Century House</Value>
-        </Node>
-        <Node>
-          <NodeName>FQDN</NodeName>
-          <Value>mi6.co.uk</Value>
-        </Node>
-        <Node>
-          <NodeName>RoamingConsortiumOI</NodeName>
-          <Value>112233,445566</Value>
-        </Node>
-      </Node>
-      <Node>
-        <NodeName>HomeSP</NodeName>
-        <Node>
-          <NodeName>FriendlyName</NodeName>
-          <Value>Century House</Value>
-        </Node>
-        <Node>
-          <NodeName>FQDN</NodeName>
-          <Value>mi6.co.uk</Value>
-        </Node>
-        <Node>
-          <NodeName>RoamingConsortiumOI</NodeName>
-          <Value>112233,445566</Value>
-        </Node>
-      </Node>
-      <Node>
-        <NodeName>Credential</NodeName>
-        <Node>
-          <NodeName>Realm</NodeName>
-          <Value>shaken.stirred.com</Value>
-        </Node>
-        <Node>
-          <NodeName>UsernamePassword</NodeName>
-          <Node>
-            <NodeName>Username</NodeName>
-            <Value>james</Value>
-          </Node>
-          <Node>
-            <NodeName>Password</NodeName>
-            <Value>Ym9uZDAwNw==</Value>
-          </Node>
-          <Node>
-            <NodeName>EAPMethod</NodeName>
-            <Node>
-              <NodeName>EAPType</NodeName>
-              <Value>21</Value>
-            </Node>
-            <Node>
-              <NodeName>InnerMethod</NodeName>
-              <Value>MS-CHAP-V2</Value>
-            </Node>
-          </Node>
-        </Node>
-        <Node>
-          <NodeName>DigitalCertificate</NodeName>
-          <Node>
-            <NodeName>CertificateType</NodeName>
-            <Value>x509v3</Value>
-          </Node>
-          <Node>
-            <NodeName>CertSHA256FingerPrint</NodeName>
-            <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value>
-          </Node>
-        </Node>
-        <Node>
-          <NodeName>SIM</NodeName>
-          <Node>
-            <NodeName>IMSI</NodeName>
-            <Value>imsi</Value>
-          </Node>
-          <Node>
-            <NodeName>EAPType</NodeName>
-            <Value>24</Value>
-          </Node>
-        </Node>
-      </Node>
-    </Node>
-  </Node>
-</MgmtTree>
diff --git a/wifi/tests/assets/pps/PerProviderSubscription_DuplicateValue.xml b/wifi/tests/assets/pps/PerProviderSubscription_DuplicateValue.xml
deleted file mode 100644
index 8719ffa..0000000
--- a/wifi/tests/assets/pps/PerProviderSubscription_DuplicateValue.xml
+++ /dev/null
@@ -1,81 +0,0 @@
-<MgmtTree xmlns="syncml:dmddf1.2">
-  <VerDTD>1.2</VerDTD>
-  <Node>
-    <NodeName>PerProviderSubscription</NodeName>
-    <RTProperties>
-      <Type>
-        <DDFName>urn:wfa:mo:hotspot2dot0-perprovidersubscription:1.0</DDFName>
-      </Type>
-    </RTProperties>
-    <Node>
-      <NodeName>i001</NodeName>
-      <Node>
-        <NodeName>HomeSP</NodeName>
-        <Node>
-          <NodeName>FriendlyName</NodeName>
-          <Value>Century House</Value>
-          <Value>Century House</Value>
-        </Node>
-        <Node>
-          <NodeName>FQDN</NodeName>
-          <Value>mi6.co.uk</Value>
-        </Node>
-        <Node>
-          <NodeName>RoamingConsortiumOI</NodeName>
-          <Value>112233,445566</Value>
-        </Node>
-      </Node>
-      <Node>
-        <NodeName>Credential</NodeName>
-        <Node>
-          <NodeName>Realm</NodeName>
-          <Value>shaken.stirred.com</Value>
-        </Node>
-        <Node>
-          <NodeName>UsernamePassword</NodeName>
-          <Node>
-            <NodeName>Username</NodeName>
-            <Value>james</Value>
-          </Node>
-          <Node>
-            <NodeName>Password</NodeName>
-            <Value>Ym9uZDAwNw==</Value>
-          </Node>
-          <Node>
-            <NodeName>EAPMethod</NodeName>
-            <Node>
-              <NodeName>EAPType</NodeName>
-              <Value>21</Value>
-            </Node>
-            <Node>
-              <NodeName>InnerMethod</NodeName>
-              <Value>MS-CHAP-V2</Value>
-            </Node>
-          </Node>
-        </Node>
-        <Node>
-          <NodeName>DigitalCertificate</NodeName>
-          <Node>
-            <NodeName>CertificateType</NodeName>
-            <Value>x509v3</Value>
-          </Node>
-          <Node>
-            <NodeName>CertSHA256FingerPrint</NodeName>
-            <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value>
-          </Node>
-        </Node>
-        <Node>
-          <NodeName>SIM</NodeName>
-          <Node>
-            <NodeName>IMSI</NodeName>
-            <Value>imsi</Value>
-          </Node>
-          <Node>
-            <NodeName>EAPType</NodeName>
-            <Value>24</Value>
-          </Node>
-        </Node>
-      </Node>
-    </Node>
-  </Node>
-</MgmtTree>
diff --git a/wifi/tests/assets/pps/PerProviderSubscription_InvalidName.xml b/wifi/tests/assets/pps/PerProviderSubscription_InvalidName.xml
deleted file mode 100644
index c761237..0000000
--- a/wifi/tests/assets/pps/PerProviderSubscription_InvalidName.xml
+++ /dev/null
@@ -1,80 +0,0 @@
-<MgmtTree xmlns="syncml:dmddf1.2">
-  <VerDTD>1.2</VerDTD>
-  <Node>
-    <NodeName>PerProviderSubscription</NodeName>
-    <RTProperties>
-      <Type>
-        <DDFName>urn:wfa:mo:hotspot2dot0-perprovidersubscription:1.0</DDFName>
-      </Type>
-    </RTProperties>
-    <Node>
-      <NodeName>i001</NodeName>
-      <Node>
-        <NodeName>HomeSP</NodeName>
-        <Node>
-          <NodeName>FriendName</NodeName>
-          <Value>Century House</Value>
-        </Node>
-        <Node>
-          <NodeName>FQDN</NodeName>
-          <Value>mi6.co.uk</Value>
-        </Node>
-        <Node>
-          <NodeName>RoamingConsortiumOI</NodeName>
-          <Value>112233,445566</Value>
-        </Node>
-      </Node>
-      <Node>
-        <NodeName>Credential</NodeName>
-        <Node>
-          <NodeName>Realm</NodeName>
-          <Value>shaken.stirred.com</Value>
-        </Node>
-        <Node>
-          <NodeName>UsernamePassword</NodeName>
-          <Node>
-            <NodeName>Username</NodeName>
-            <Value>james</Value>
-          </Node>
-          <Node>
-            <NodeName>Password</NodeName>
-            <Value>Ym9uZDAwNw==</Value>
-          </Node>
-          <Node>
-            <NodeName>EAPMethod</NodeName>
-            <Node>
-              <NodeName>EAPType</NodeName>
-              <Value>21</Value>
-            </Node>
-            <Node>
-              <NodeName>InnerMethod</NodeName>
-              <Value>MS-CHAP-V2</Value>
-            </Node>
-          </Node>
-        </Node>
-        <Node>
-          <NodeName>DigitalCertificate</NodeName>
-          <Node>
-            <NodeName>CertificateType</NodeName>
-            <Value>x509v3</Value>
-          </Node>
-          <Node>
-            <NodeName>CertSHA256FingerPrint</NodeName>
-            <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value>
-          </Node>
-        </Node>
-        <Node>
-          <NodeName>SIM</NodeName>
-          <Node>
-            <NodeName>IMSI</NodeName>
-            <Value>imsi</Value>
-          </Node>
-          <Node>
-            <NodeName>EAPType</NodeName>
-            <Value>24</Value>
-          </Node>
-        </Node>
-      </Node>
-    </Node>
-  </Node>
-</MgmtTree>
diff --git a/wifi/tests/assets/pps/PerProviderSubscription_InvalidNode.xml b/wifi/tests/assets/pps/PerProviderSubscription_InvalidNode.xml
deleted file mode 100644
index 6b807af..0000000
--- a/wifi/tests/assets/pps/PerProviderSubscription_InvalidNode.xml
+++ /dev/null
@@ -1,84 +0,0 @@
-<MgmtTree xmlns="syncml:dmddf1.2">
-  <VerDTD>1.2</VerDTD>
-  <Node>
-    <NodeName>PerProviderSubscription</NodeName>
-    <RTProperties>
-      <Type>
-        <DDFName>urn:wfa:mo:hotspot2dot0-perprovidersubscription:1.0</DDFName>
-      </Type>
-    </RTProperties>
-    <Node>
-      <NodeName>i001</NodeName>
-      <Node>
-        <NodeName>HomeSP</NodeName>
-        <Node>
-          <NodeName>FriendlyName</NodeName>
-          <Value>Century House</Value>
-        </Node>
-        <Node>
-          <NodeName>FQDN</NodeName>
-          <Value>mi6.co.uk</Value>
-          <Node>
-            <NodeName>InvalidNode</NodeName>
-            <Value>Test</Value>
-          </Node>
-        </Node>
-        <Node>
-          <NodeName>RoamingConsortiumOI</NodeName>
-          <Value>112233,445566</Value>
-        </Node>
-      </Node>
-      <Node>
-        <NodeName>Credential</NodeName>
-        <Node>
-          <NodeName>Realm</NodeName>
-          <Value>shaken.stirred.com</Value>
-        </Node>
-        <Node>
-          <NodeName>UsernamePassword</NodeName>
-          <Node>
-            <NodeName>Username</NodeName>
-            <Value>james</Value>
-          </Node>
-          <Node>
-            <NodeName>Password</NodeName>
-            <Value>Ym9uZDAwNw==</Value>
-          </Node>
-          <Node>
-            <NodeName>EAPMethod</NodeName>
-            <Node>
-              <NodeName>EAPType</NodeName>
-              <Value>21</Value>
-            </Node>
-            <Node>
-              <NodeName>InnerMethod</NodeName>
-              <Value>MS-CHAP-V2</Value>
-            </Node>
-          </Node>
-        </Node>
-        <Node>
-          <NodeName>DigitalCertificate</NodeName>
-          <Node>
-            <NodeName>CertificateType</NodeName>
-            <Value>x509v3</Value>
-          </Node>
-          <Node>
-            <NodeName>CertSHA256FingerPrint</NodeName>
-            <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value>
-          </Node>
-        </Node>
-        <Node>
-          <NodeName>SIM</NodeName>
-          <Node>
-            <NodeName>IMSI</NodeName>
-            <Value>imsi</Value>
-          </Node>
-          <Node>
-            <NodeName>EAPType</NodeName>
-            <Value>24</Value>
-          </Node>
-        </Node>
-      </Node>
-    </Node>
-  </Node>
-</MgmtTree>
diff --git a/wifi/tests/assets/pps/PerProviderSubscription_MissingName.xml b/wifi/tests/assets/pps/PerProviderSubscription_MissingName.xml
deleted file mode 100644
index ed06b47..0000000
--- a/wifi/tests/assets/pps/PerProviderSubscription_MissingName.xml
+++ /dev/null
@@ -1,79 +0,0 @@
-<MgmtTree xmlns="syncml:dmddf1.2">
-  <VerDTD>1.2</VerDTD>
-  <Node>
-    <NodeName>PerProviderSubscription</NodeName>
-    <RTProperties>
-      <Type>
-        <DDFName>urn:wfa:mo:hotspot2dot0-perprovidersubscription:1.0</DDFName>
-      </Type>
-    </RTProperties>
-    <Node>
-      <NodeName>i001</NodeName>
-      <Node>
-        <Node>
-          <NodeName>FriendlyName</NodeName>
-          <Value>Century House</Value>
-        </Node>
-        <Node>
-          <NodeName>FQDN</NodeName>
-          <Value>mi6.co.uk</Value>
-        </Node>
-        <Node>
-          <NodeName>RoamingConsortiumOI</NodeName>
-          <Value>112233,445566</Value>
-        </Node>
-      </Node>
-      <Node>
-        <NodeName>Credential</NodeName>
-        <Node>
-          <NodeName>Realm</NodeName>
-          <Value>shaken.stirred.com</Value>
-        </Node>
-        <Node>
-          <NodeName>UsernamePassword</NodeName>
-          <Node>
-            <NodeName>Username</NodeName>
-            <Value>james</Value>
-          </Node>
-          <Node>
-            <NodeName>Password</NodeName>
-            <Value>Ym9uZDAwNw==</Value>
-          </Node>
-          <Node>
-            <NodeName>EAPMethod</NodeName>
-            <Node>
-              <NodeName>EAPType</NodeName>
-              <Value>21</Value>
-            </Node>
-            <Node>
-              <NodeName>InnerMethod</NodeName>
-              <Value>MS-CHAP-V2</Value>
-            </Node>
-          </Node>
-        </Node>
-        <Node>
-          <NodeName>DigitalCertificate</NodeName>
-          <Node>
-            <NodeName>CertificateType</NodeName>
-            <Value>x509v3</Value>
-          </Node>
-          <Node>
-            <NodeName>CertSHA256FingerPrint</NodeName>
-            <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value>
-          </Node>
-        </Node>
-        <Node>
-          <NodeName>SIM</NodeName>
-          <Node>
-            <NodeName>IMSI</NodeName>
-            <Value>imsi</Value>
-          </Node>
-          <Node>
-            <NodeName>EAPType</NodeName>
-            <Value>24</Value>
-          </Node>
-        </Node>
-      </Node>
-    </Node>
-  </Node>
-</MgmtTree>
diff --git a/wifi/tests/assets/pps/PerProviderSubscription_MissingValue.xml b/wifi/tests/assets/pps/PerProviderSubscription_MissingValue.xml
deleted file mode 100644
index f7e35dd..0000000
--- a/wifi/tests/assets/pps/PerProviderSubscription_MissingValue.xml
+++ /dev/null
@@ -1,79 +0,0 @@
-<MgmtTree xmlns="syncml:dmddf1.2">
-  <VerDTD>1.2</VerDTD>
-  <Node>
-    <NodeName>PerProviderSubscription</NodeName>
-    <RTProperties>
-      <Type>
-        <DDFName>urn:wfa:mo:hotspot2dot0-perprovidersubscription:1.0</DDFName>
-      </Type>
-    </RTProperties>
-    <Node>
-      <NodeName>i001</NodeName>
-      <Node>
-        <NodeName>HomeSP</NodeName>
-        <Node>
-          <NodeName>FriendlyName</NodeName>
-        </Node>
-        <Node>
-          <NodeName>FQDN</NodeName>
-          <Value>mi6.co.uk</Value>
-        </Node>
-        <Node>
-          <NodeName>RoamingConsortiumOI</NodeName>
-          <Value>112233,445566</Value>
-        </Node>
-      </Node>
-      <Node>
-        <NodeName>Credential</NodeName>
-        <Node>
-          <NodeName>Realm</NodeName>
-          <Value>shaken.stirred.com</Value>
-        </Node>
-        <Node>
-          <NodeName>UsernamePassword</NodeName>
-          <Node>
-            <NodeName>Username</NodeName>
-            <Value>james</Value>
-          </Node>
-          <Node>
-            <NodeName>Password</NodeName>
-            <Value>Ym9uZDAwNw==</Value>
-          </Node>
-          <Node>
-            <NodeName>EAPMethod</NodeName>
-            <Node>
-              <NodeName>EAPType</NodeName>
-              <Value>21</Value>
-            </Node>
-            <Node>
-              <NodeName>InnerMethod</NodeName>
-              <Value>MS-CHAP-V2</Value>
-            </Node>
-          </Node>
-        </Node>
-        <Node>
-          <NodeName>DigitalCertificate</NodeName>
-          <Node>
-            <NodeName>CertificateType</NodeName>
-            <Value>x509v3</Value>
-          </Node>
-          <Node>
-            <NodeName>CertSHA256FingerPrint</NodeName>
-            <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value>
-          </Node>
-        </Node>
-        <Node>
-          <NodeName>SIM</NodeName>
-          <Node>
-            <NodeName>IMSI</NodeName>
-            <Value>imsi</Value>
-          </Node>
-          <Node>
-            <NodeName>EAPType</NodeName>
-            <Value>24</Value>
-          </Node>
-        </Node>
-      </Node>
-    </Node>
-  </Node>
-</MgmtTree>
diff --git a/wifi/tests/assets/pps/README.txt b/wifi/tests/assets/pps/README.txt
deleted file mode 100644
index 369c0a9..0000000
--- a/wifi/tests/assets/pps/README.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-PerProviderSubscription.xml - valid PPS XML file
-PerProviderSubscription_DuplicateHomeSP.xml - containing multiple HomeSP node
-PerProviderSubscription_DuplicateValue.xml - FriendlyName node contains multiple Value
-PerProviderSubscription_MissingValue.xml - FriendlyName node is missing Value
-PerProviderSubscription_MissingName.xml - HomeSP node is missing NodeName
-PerProviderSubscription_InvalidNode.xml - FQDN node contains both Value and a child node
-PerProviderSubscription_InvalidName.xml - FriendlyName node have a typo in its name
diff --git a/wifi/tests/src/android/net/wifi/EasyConnectStatusCallbackTest.java b/wifi/tests/src/android/net/wifi/EasyConnectStatusCallbackTest.java
deleted file mode 100644
index b101414..0000000
--- a/wifi/tests/src/android/net/wifi/EasyConnectStatusCallbackTest.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import android.util.SparseArray;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Unit tests for {@link android.net.wifi.EasyConnectStatusCallbackTest}.
- */
-@SmallTest
-public class EasyConnectStatusCallbackTest {
-    private EasyConnectStatusCallback mEasyConnectStatusCallback = new EasyConnectStatusCallback() {
-        @Override
-        public void onEnrolleeSuccess(int newNetworkId) {
-
-        }
-
-        @Override
-        public void onConfiguratorSuccess(int code) {
-
-        }
-
-        @Override
-        public void onProgress(int code) {
-
-        }
-
-        @Override
-        public void onFailure(int code) {
-            mOnFailureR1EventReceived = true;
-            mLastCode = code;
-        }
-    };
-    private boolean mOnFailureR1EventReceived;
-    private int mLastCode;
-
-    @Before
-    public void setUp() {
-        mOnFailureR1EventReceived = false;
-        mLastCode = 0;
-    }
-
-    /**
-     * Test that the legacy R1 onFailure is called by default if the R2 onFailure is not overridden
-     * by the app.
-     */
-    @Test
-    public void testR1OnFailureCalled() {
-
-        SparseArray<int[]> channelList = new SparseArray<>();
-        int[] channelArray = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
-
-        channelList.append(81, channelArray);
-        mEasyConnectStatusCallback.onFailure(
-                EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_CANNOT_FIND_NETWORK,
-                "SomeSSID", channelList, new int[] {81});
-
-        assertTrue(mOnFailureR1EventReceived);
-        assertEquals(mLastCode,
-                EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_CANNOT_FIND_NETWORK);
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/FakeKeys.java b/wifi/tests/src/android/net/wifi/FakeKeys.java
deleted file mode 100644
index 8aa6add..0000000
--- a/wifi/tests/src/android/net/wifi/FakeKeys.java
+++ /dev/null
@@ -1,673 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package android.net.wifi;
-
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.nio.charset.StandardCharsets;
-import java.security.KeyFactory;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.PKCS8EncodedKeySpec;
-
-/**
- * A class containing test certificates and private keys.
- */
-public class FakeKeys {
-    private static final String CA_CERT0_STRING = "-----BEGIN CERTIFICATE-----\n" +
-            "MIIDKDCCAhCgAwIBAgIJAILlFdwzLVurMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNV\n" +
-            "BAMTB0VBUCBDQTEwHhcNMTYwMTEyMTE1MDE1WhcNMjYwMTA5MTE1MDE1WjASMRAw\n" +
-            "DgYDVQQDEwdFQVAgQ0ExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA\n" +
-            "znAPUz26Msae4ws43czR41/J2QtrSIZUKmVUsVumDbYHrPNvTXKSMXAcewORDQYX\n" +
-            "RqvHvpn8CscB1+oGXZvHwxj4zV0WKoK2zeXkau3vcyl3HIKupJfq2TEACefVjj0t\n" +
-            "JW+X35PGWp9/H5zIUNVNVjS7Ums84IvKhRB8512PB9UyHagXYVX5GWpAcVpyfrlR\n" +
-            "FI9Qdhh+Pbk0uyktdbf/CdfgHOoebrTtwRljM0oDtX+2Cv6j0wBK7hD8pPvf1+uy\n" +
-            "GzczigAU/4Kw7eZqydf9B+5RupR+IZipX41xEiIrKRwqi517WWzXcjaG2cNbf451\n" +
-            "xpH5PnV3i1tq04jMGQUzFwIDAQABo4GAMH4wHQYDVR0OBBYEFIwX4vs8BiBcScod\n" +
-            "5noZHRM8E4+iMEIGA1UdIwQ7MDmAFIwX4vs8BiBcScod5noZHRM8E4+ioRakFDAS\n" +
-            "MRAwDgYDVQQDEwdFQVAgQ0ExggkAguUV3DMtW6swDAYDVR0TBAUwAwEB/zALBgNV\n" +
-            "HQ8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAFfQqOTA7Rv7K+luQ7pnas4BYwHE\n" +
-            "9GEP/uohv6KOy0TGQFbrRTjFoLVNB9BZ1ymMDZ0/TIwIUc7wi7a8t5mEqYH153wW\n" +
-            "aWooiSjyLLhuI4sNrNCOtisdBq2r2MFXt6h0mAQYOPv8R8K7/fgSxGFqzhyNmmVL\n" +
-            "1qBJldx34SpwsTALQVPb4hGwJzZfr1PcpEQx6xMnTl8xEWZE3Ms99uaUxbQqIwRu\n" +
-            "LgAOkNCmY2m89VhzaHJ1uV85AdM/tD+Ysmlnnjt9LRCejbBipjIGjOXrg1JP+lxV\n" +
-            "muM4vH+P/mlmxsPPz0d65b+EGmJZpoLkO/tdNNvCYzjJpTEWpEsO6NMhKYo=\n" +
-            "-----END CERTIFICATE-----\n";
-    public static final X509Certificate CA_CERT0 = loadCertificate(CA_CERT0_STRING);
-
-    private static final String CA_CERT1_STRING = "-----BEGIN CERTIFICATE-----\n" +
-            "MIIDKDCCAhCgAwIBAgIJAOM5SzKO2pzCMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNV\n" +
-            "BAMTB0VBUCBDQTAwHhcNMTYwMTEyMDAxMDQ3WhcNMjYwMTA5MDAxMDQ3WjASMRAw\n" +
-            "DgYDVQQDEwdFQVAgQ0EwMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA\n" +
-            "89ug+IEKVQXnJGKg5g4uVHg6J/8iRUxR5k2eH5o03hrJNMfN2D+cBe/wCiZcnWbI\n" +
-            "GbGZACWm2nQth2wy9Zgm2LOd3b4ocrHYls3XLq6Qb5Dd7a0JKU7pdGufiNVEkrmF\n" +
-            "EB+N64wgwH4COTvCiN4erp5kyJwkfqAl2xLkZo0C464c9XoyQOXbmYD9A8v10wZu\n" +
-            "jyNsEo7Nr2USyw+qhjWSbFbEirP77Tvx+7pJQJwdtk1V9Tn73T2dGF2WHYejei9S\n" +
-            "mcWpdIUqsu9etYH+zDmtu7I1xlkwiaVsNr2+D+qaCJyOYqrDTKVNK5nmbBPXDWZc\n" +
-            "NoDbTOoqquX7xONpq9M6jQIDAQABo4GAMH4wHQYDVR0OBBYEFAZ3A2S4qJZZwuNY\n" +
-            "wkJ6mAdc0gVdMEIGA1UdIwQ7MDmAFAZ3A2S4qJZZwuNYwkJ6mAdc0gVdoRakFDAS\n" +
-            "MRAwDgYDVQQDEwdFQVAgQ0EwggkA4zlLMo7anMIwDAYDVR0TBAUwAwEB/zALBgNV\n" +
-            "HQ8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAHmdMwEhtys4d0E+t7owBmoVR+lU\n" +
-            "hMCcRtWs8YKX5WIM2kTweT0h/O1xwE1mWmRv/IbDAEb8od4BjAQLhIcolStr2JaO\n" +
-            "9ZzyxjOnNzqeErh/1DHDbb/moPpqfeJ8YiEz7nH/YU56Q8iCPO7TsgS0sNNE7PfN\n" +
-            "IUsBW0yHRgpQ4OxWmiZG2YZWiECRzAC0ecPzo59N5iH4vLQIMTMYquiDeMPQnn1e\n" +
-            "NDGxG8gCtDKIaS6tMg3a28MvWB094pr2ETou8O1C8Ji0Y4hE8QJmSdT7I4+GZjgW\n" +
-            "g94DZ5RiL7sdp3vC48CXOmeT61YBIvhGUsE1rPhXqkpqQ3Z3C4TFF0jXZZc=\n" +
-            "-----END CERTIFICATE-----\n";
-    public static final X509Certificate CA_CERT1 = loadCertificate(CA_CERT1_STRING);
-
-    private static final String CLIENT_CERT_STR = "-----BEGIN CERTIFICATE-----\n" +
-            "MIIE/DCCAuQCAQEwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UEBhMCVVMxCzAJBgNV\n" +
-            "BAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdUZXN0aW5n\n" +
-            "MB4XDTE2MDkzMDIwNTQyOFoXDTE3MDkzMDIwNTQyOFowRDELMAkGA1UEBhMCVVMx\n" +
-            "CzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdU\n" +
-            "ZXN0aW5nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAnpmcbuaeHfnJ\n" +
-            "k+2QNvxmdVFTawyFMNk0USCq5sexscwmxbewG/Rb8YnixwJWS44v2XkSujB67z5C\n" +
-            "s2qudFEhRXKdEuC6idbAuA97KjipHh0AAniWMsyv61fvbgsUC0b0canx3LiDq81p\n" +
-            "y28NNGmAvoazLZUZ4AhBRiwYZY6FKk723gmZoGbEIeG7J1dlXPusc1662rIjz4eU\n" +
-            "zlmmlvqyHfNqnNk8L14Vug6Xh+lOEGN85xhu1YHAEKGrS89kZxs5rum/cZU8KH2V\n" +
-            "v6eKnY03kxjiVLQtnLpm/7VUEoCMGHyruRj+p3my4+DgqMsmsH52RZCBsjyGlpbU\n" +
-            "NOwOTIX6xh+Rqloduz4AnrMYYIiIw2s8g+2zJM7VbcVKx0fGS26BKdrxgrXWfmNE\n" +
-            "nR0/REQ5AxDGw0jfTUvtdTkXAf+K4MDjcNLEZ+MA4rHfAfQWZtUR5BkHCQYxNpJk\n" +
-            "pA0gyk+BpKdC4WdzI14NSWsu5sRCmBCFqH6BTOSEq/V1cNorBxNwLSSTwFFqUDqx\n" +
-            "Y5nQLXygkJf9WHZWtSKeSjtOYgilz7UKzC2s3CsjmIyGFe+SwpuHJnuE4Uc8Z5Cb\n" +
-            "bjNGHPzqL6XnmzZHJp7RF8kBdKdjGC7dCUltzOfICZeKlzOOq+Kw42T/nXjuXvpb\n" +
-            "nkXNxg741Nwd6RecykXJbseFwm3EYxkCAwEAATANBgkqhkiG9w0BAQsFAAOCAgEA\n" +
-            "Ga1mGwI9aXkL2fTPXO9YkAPzoGeX8aeuVYSQaSkNq+5vnogYCyAt3YDHjRG+ewTT\n" +
-            "WbnPA991xRAPac+biJeXWmwvgGj0YuT7e79phAiGkTTnbAjFHGfYnBy/tI/v7btO\n" +
-            "hRNElA5yTJ1m2fVbBEKXzMR83jrT9iyI+YLRN86zUZIaC86xxSbqnrdWN2jOK6MX\n" +
-            "dS8Arp9tPQjC/4gW+2Ilxv68jiYh+5auWHQZVjppWVY//iu4mAbkq1pTwQEhZ8F8\n" +
-            "Zrmh9DHh60hLFcfSuhIAwf/NMzppwdkjy1ruKVrpijhGKGp4OWu8nvOUgHSzxc7F\n" +
-            "PwpVZ5N2Ku4L8MLO6BG2VasRJK7l17TzDXlfLZHJjkuryOFxVaQKt8ZNFgTOaCXS\n" +
-            "E+gpTLksKU7riYckoiP4+H1sn9qcis0e8s4o/uf1UVc8GSdDw61ReGM5oZEDm1u8\n" +
-            "H9x20QU6igLqzyBpqvCKv7JNgU1uB2PAODHH78zJiUfnKd1y+o+J1iWzaGj3EFji\n" +
-            "T8AXksbTP733FeFXfggXju2dyBH+Z1S5BBTEOd1brWgXlHSAZGm97MKZ94r6/tkX\n" +
-            "qfv3fCos0DKz0oV7qBxYS8wiYhzrRVxG6ITAoH8uuUVVQaZF+G4nJ2jEqNbfuKyX\n" +
-            "ATQsVNjNNlDA0J33GobPMjT326wa4YAWMx8PI5PJZ3g=\n" +
-            "-----END CERTIFICATE-----\n";
-    public static final X509Certificate CLIENT_CERT = loadCertificate(CLIENT_CERT_STR);
-
-    private static final byte[] FAKE_RSA_KEY_1 = new byte[] {
-            (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x78, (byte) 0x02, (byte) 0x01,
-            (byte) 0x00, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a,
-            (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01,
-            (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x04, (byte) 0x82,
-            (byte) 0x02, (byte) 0x62, (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x5e,
-            (byte) 0x02, (byte) 0x01, (byte) 0x00, (byte) 0x02, (byte) 0x81, (byte) 0x81,
-            (byte) 0x00, (byte) 0xce, (byte) 0x29, (byte) 0xeb, (byte) 0xf6, (byte) 0x5b,
-            (byte) 0x25, (byte) 0xdc, (byte) 0xa1, (byte) 0xa6, (byte) 0x2c, (byte) 0x66,
-            (byte) 0xcb, (byte) 0x20, (byte) 0x90, (byte) 0x27, (byte) 0x86, (byte) 0x8a,
-            (byte) 0x44, (byte) 0x71, (byte) 0x50, (byte) 0xda, (byte) 0xd3, (byte) 0x02,
-            (byte) 0x77, (byte) 0x55, (byte) 0xe9, (byte) 0xe8, (byte) 0x08, (byte) 0xf3,
-            (byte) 0x36, (byte) 0x9a, (byte) 0xae, (byte) 0xab, (byte) 0x04, (byte) 0x6d,
-            (byte) 0x00, (byte) 0x99, (byte) 0xbf, (byte) 0x7d, (byte) 0x0f, (byte) 0x67,
-            (byte) 0x8b, (byte) 0x1d, (byte) 0xd4, (byte) 0x2b, (byte) 0x7c, (byte) 0xcb,
-            (byte) 0xcd, (byte) 0x33, (byte) 0xc7, (byte) 0x84, (byte) 0x30, (byte) 0xe2,
-            (byte) 0x45, (byte) 0x21, (byte) 0xb3, (byte) 0x75, (byte) 0xf5, (byte) 0x79,
-            (byte) 0x02, (byte) 0xda, (byte) 0x50, (byte) 0xa3, (byte) 0x8b, (byte) 0xce,
-            (byte) 0xc3, (byte) 0x8e, (byte) 0x0f, (byte) 0x25, (byte) 0xeb, (byte) 0x08,
-            (byte) 0x2c, (byte) 0xdd, (byte) 0x1c, (byte) 0xcf, (byte) 0xff, (byte) 0x3b,
-            (byte) 0xde, (byte) 0xb6, (byte) 0xaa, (byte) 0x2a, (byte) 0xa9, (byte) 0xc4,
-            (byte) 0x8a, (byte) 0x24, (byte) 0x24, (byte) 0xe6, (byte) 0x29, (byte) 0x0d,
-            (byte) 0x98, (byte) 0x4c, (byte) 0x32, (byte) 0xa1, (byte) 0x7b, (byte) 0x23,
-            (byte) 0x2b, (byte) 0x42, (byte) 0x30, (byte) 0xee, (byte) 0x78, (byte) 0x08,
-            (byte) 0x47, (byte) 0xad, (byte) 0xf2, (byte) 0x96, (byte) 0xd5, (byte) 0xf1,
-            (byte) 0x62, (byte) 0x42, (byte) 0x2d, (byte) 0x35, (byte) 0x19, (byte) 0xb4,
-            (byte) 0x3c, (byte) 0xc9, (byte) 0xc3, (byte) 0x5f, (byte) 0x03, (byte) 0x16,
-            (byte) 0x3a, (byte) 0x23, (byte) 0xac, (byte) 0xcb, (byte) 0xce, (byte) 0x9e,
-            (byte) 0x51, (byte) 0x2e, (byte) 0x6d, (byte) 0x02, (byte) 0x03, (byte) 0x01,
-            (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x81, (byte) 0x80, (byte) 0x16,
-            (byte) 0x59, (byte) 0xc3, (byte) 0x24, (byte) 0x1d, (byte) 0x33, (byte) 0x98,
-            (byte) 0x9c, (byte) 0xc9, (byte) 0xc8, (byte) 0x2c, (byte) 0x88, (byte) 0xbf,
-            (byte) 0x0a, (byte) 0x01, (byte) 0xce, (byte) 0xfb, (byte) 0x34, (byte) 0x7a,
-            (byte) 0x58, (byte) 0x7a, (byte) 0xb0, (byte) 0xbf, (byte) 0xa6, (byte) 0xb2,
-            (byte) 0x60, (byte) 0xbe, (byte) 0x70, (byte) 0x21, (byte) 0xf5, (byte) 0xfc,
-            (byte) 0x85, (byte) 0x0d, (byte) 0x33, (byte) 0x58, (byte) 0xa1, (byte) 0xe5,
-            (byte) 0x09, (byte) 0x36, (byte) 0x84, (byte) 0xb2, (byte) 0x04, (byte) 0x0a,
-            (byte) 0x02, (byte) 0xd3, (byte) 0x88, (byte) 0x1f, (byte) 0x0c, (byte) 0x2b,
-            (byte) 0x1d, (byte) 0xe9, (byte) 0x3d, (byte) 0xe7, (byte) 0x79, (byte) 0xf9,
-            (byte) 0x32, (byte) 0x5c, (byte) 0x8a, (byte) 0x75, (byte) 0x49, (byte) 0x12,
-            (byte) 0xe4, (byte) 0x05, (byte) 0x26, (byte) 0xd4, (byte) 0x2e, (byte) 0x9e,
-            (byte) 0x1f, (byte) 0xcc, (byte) 0x54, (byte) 0xad, (byte) 0x33, (byte) 0x8d,
-            (byte) 0x99, (byte) 0x00, (byte) 0xdc, (byte) 0xf5, (byte) 0xb4, (byte) 0xa2,
-            (byte) 0x2f, (byte) 0xba, (byte) 0xe5, (byte) 0x62, (byte) 0x30, (byte) 0x6d,
-            (byte) 0xe6, (byte) 0x3d, (byte) 0xeb, (byte) 0x24, (byte) 0xc2, (byte) 0xdc,
-            (byte) 0x5f, (byte) 0xb7, (byte) 0x16, (byte) 0x35, (byte) 0xa3, (byte) 0x98,
-            (byte) 0x98, (byte) 0xa8, (byte) 0xef, (byte) 0xe8, (byte) 0xc4, (byte) 0x96,
-            (byte) 0x6d, (byte) 0x38, (byte) 0xab, (byte) 0x26, (byte) 0x6d, (byte) 0x30,
-            (byte) 0xc2, (byte) 0xa0, (byte) 0x44, (byte) 0xe4, (byte) 0xff, (byte) 0x7e,
-            (byte) 0xbe, (byte) 0x7c, (byte) 0x33, (byte) 0xa5, (byte) 0x10, (byte) 0xad,
-            (byte) 0xd7, (byte) 0x1e, (byte) 0x13, (byte) 0x20, (byte) 0xb3, (byte) 0x1f,
-            (byte) 0x41, (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xf1, (byte) 0x89,
-            (byte) 0x07, (byte) 0x0f, (byte) 0xe8, (byte) 0xcf, (byte) 0xab, (byte) 0x13,
-            (byte) 0x2a, (byte) 0x8f, (byte) 0x88, (byte) 0x80, (byte) 0x11, (byte) 0x9a,
-            (byte) 0x79, (byte) 0xb6, (byte) 0x59, (byte) 0x3a, (byte) 0x50, (byte) 0x6e,
-            (byte) 0x57, (byte) 0x37, (byte) 0xab, (byte) 0x2a, (byte) 0xd2, (byte) 0xaa,
-            (byte) 0xd9, (byte) 0x72, (byte) 0x73, (byte) 0xff, (byte) 0x8b, (byte) 0x47,
-            (byte) 0x76, (byte) 0xdd, (byte) 0xdc, (byte) 0xf5, (byte) 0x97, (byte) 0x44,
-            (byte) 0x3a, (byte) 0x78, (byte) 0xbe, (byte) 0x17, (byte) 0xb4, (byte) 0x22,
-            (byte) 0x6f, (byte) 0xe5, (byte) 0x23, (byte) 0x70, (byte) 0x1d, (byte) 0x10,
-            (byte) 0x5d, (byte) 0xba, (byte) 0x16, (byte) 0x81, (byte) 0xf1, (byte) 0x45,
-            (byte) 0xce, (byte) 0x30, (byte) 0xb4, (byte) 0xab, (byte) 0x80, (byte) 0xe4,
-            (byte) 0x98, (byte) 0x31, (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xda,
-            (byte) 0x82, (byte) 0x9d, (byte) 0x3f, (byte) 0xca, (byte) 0x2f, (byte) 0xe1,
-            (byte) 0xd4, (byte) 0x86, (byte) 0x77, (byte) 0x48, (byte) 0xa6, (byte) 0xab,
-            (byte) 0xab, (byte) 0x1c, (byte) 0x42, (byte) 0x5c, (byte) 0xd5, (byte) 0xc7,
-            (byte) 0x46, (byte) 0x59, (byte) 0x91, (byte) 0x3f, (byte) 0xfc, (byte) 0xcc,
-            (byte) 0xec, (byte) 0xc2, (byte) 0x40, (byte) 0x12, (byte) 0x2c, (byte) 0x8d,
-            (byte) 0x1f, (byte) 0xa2, (byte) 0x18, (byte) 0x88, (byte) 0xee, (byte) 0x82,
-            (byte) 0x4a, (byte) 0x5a, (byte) 0x5e, (byte) 0x88, (byte) 0x20, (byte) 0xe3,
-            (byte) 0x7b, (byte) 0xe0, (byte) 0xd8, (byte) 0x3a, (byte) 0x52, (byte) 0x9a,
-            (byte) 0x26, (byte) 0x6a, (byte) 0x04, (byte) 0xec, (byte) 0xe8, (byte) 0xb9,
-            (byte) 0x48, (byte) 0x40, (byte) 0xe1, (byte) 0xe1, (byte) 0x83, (byte) 0xa6,
-            (byte) 0x67, (byte) 0xa6, (byte) 0xfd, (byte) 0x02, (byte) 0x41, (byte) 0x00,
-            (byte) 0x89, (byte) 0x72, (byte) 0x3e, (byte) 0xb0, (byte) 0x90, (byte) 0xfd,
-            (byte) 0x4c, (byte) 0x0e, (byte) 0xd6, (byte) 0x13, (byte) 0x63, (byte) 0xcb,
-            (byte) 0xed, (byte) 0x38, (byte) 0x88, (byte) 0xb6, (byte) 0x79, (byte) 0xc4,
-            (byte) 0x33, (byte) 0x6c, (byte) 0xf6, (byte) 0xf8, (byte) 0xd8, (byte) 0xd0,
-            (byte) 0xbf, (byte) 0x9d, (byte) 0x35, (byte) 0xac, (byte) 0x69, (byte) 0xd2,
-            (byte) 0x2b, (byte) 0xc1, (byte) 0xf9, (byte) 0x24, (byte) 0x7b, (byte) 0xce,
-            (byte) 0xcd, (byte) 0xcb, (byte) 0xa7, (byte) 0xb2, (byte) 0x7a, (byte) 0x0a,
-            (byte) 0x27, (byte) 0x19, (byte) 0xc9, (byte) 0xaf, (byte) 0x0d, (byte) 0x21,
-            (byte) 0x89, (byte) 0x88, (byte) 0x7c, (byte) 0xad, (byte) 0x9e, (byte) 0x8d,
-            (byte) 0x47, (byte) 0x6d, (byte) 0x3f, (byte) 0xce, (byte) 0x7b, (byte) 0xa1,
-            (byte) 0x74, (byte) 0xf1, (byte) 0xa0, (byte) 0xa1, (byte) 0x02, (byte) 0x41,
-            (byte) 0x00, (byte) 0xd9, (byte) 0xa8, (byte) 0xf5, (byte) 0xfe, (byte) 0xce,
-            (byte) 0xe6, (byte) 0x77, (byte) 0x6b, (byte) 0xfe, (byte) 0x2d, (byte) 0xe0,
-            (byte) 0x1e, (byte) 0xb6, (byte) 0x2e, (byte) 0x12, (byte) 0x4e, (byte) 0x40,
-            (byte) 0xaf, (byte) 0x6a, (byte) 0x7b, (byte) 0x37, (byte) 0x49, (byte) 0x2a,
-            (byte) 0x96, (byte) 0x25, (byte) 0x83, (byte) 0x49, (byte) 0xd4, (byte) 0x0c,
-            (byte) 0xc6, (byte) 0x78, (byte) 0x25, (byte) 0x24, (byte) 0x90, (byte) 0x90,
-            (byte) 0x06, (byte) 0x15, (byte) 0x9e, (byte) 0xfe, (byte) 0xf9, (byte) 0xdf,
-            (byte) 0x5b, (byte) 0xf3, (byte) 0x7e, (byte) 0x38, (byte) 0x70, (byte) 0xeb,
-            (byte) 0x57, (byte) 0xd0, (byte) 0xd9, (byte) 0xa7, (byte) 0x0e, (byte) 0x14,
-            (byte) 0xf7, (byte) 0x95, (byte) 0x68, (byte) 0xd5, (byte) 0xc8, (byte) 0xab,
-            (byte) 0x9d, (byte) 0x3a, (byte) 0x2b, (byte) 0x51, (byte) 0xf9, (byte) 0x02,
-            (byte) 0x41, (byte) 0x00, (byte) 0x96, (byte) 0xdf, (byte) 0xe9, (byte) 0x67,
-            (byte) 0x6c, (byte) 0xdc, (byte) 0x90, (byte) 0x14, (byte) 0xb4, (byte) 0x1d,
-            (byte) 0x22, (byte) 0x33, (byte) 0x4a, (byte) 0x31, (byte) 0xc1, (byte) 0x9d,
-            (byte) 0x2e, (byte) 0xff, (byte) 0x9a, (byte) 0x2a, (byte) 0x95, (byte) 0x4b,
-            (byte) 0x27, (byte) 0x74, (byte) 0xcb, (byte) 0x21, (byte) 0xc3, (byte) 0xd2,
-            (byte) 0x0b, (byte) 0xb2, (byte) 0x46, (byte) 0x87, (byte) 0xf8, (byte) 0x28,
-            (byte) 0x01, (byte) 0x8b, (byte) 0xd8, (byte) 0xb9, (byte) 0x4b, (byte) 0xcd,
-            (byte) 0x9a, (byte) 0x96, (byte) 0x41, (byte) 0x0e, (byte) 0x36, (byte) 0x6d,
-            (byte) 0x40, (byte) 0x42, (byte) 0xbc, (byte) 0xd9, (byte) 0xd3, (byte) 0x7b,
-            (byte) 0xbc, (byte) 0xa7, (byte) 0x92, (byte) 0x90, (byte) 0xdd, (byte) 0xa1,
-            (byte) 0x9c, (byte) 0xce, (byte) 0xa1, (byte) 0x87, (byte) 0x11, (byte) 0x51
-    };
-    public static final PrivateKey RSA_KEY1 = loadPrivateKey("RSA", FAKE_RSA_KEY_1);
-
-    private static final String CA_SUITE_B_RSA3072_CERT_STRING =
-            "-----BEGIN CERTIFICATE-----\n"
-                    + "MIIEnTCCAwWgAwIBAgIUD87Y8fFLzLr1HQ/64aEnjNq2R/4wDQYJKoZIhvcNAQEM\n"
-                    + "BQAwXjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMQwwCgYDVQQHDANNVFYxEDAO\n"
-                    + "BgNVBAoMB0FuZHJvaWQxDjAMBgNVBAsMBVdpLUZpMRIwEAYDVQQDDAl1bml0ZXN0\n"
-                    + "Q0EwHhcNMjAwNzIxMDIxNzU0WhcNMzAwNTMwMDIxNzU0WjBeMQswCQYDVQQGEwJV\n"
-                    + "UzELMAkGA1UECAwCQ0ExDDAKBgNVBAcMA01UVjEQMA4GA1UECgwHQW5kcm9pZDEO\n"
-                    + "MAwGA1UECwwFV2ktRmkxEjAQBgNVBAMMCXVuaXRlc3RDQTCCAaIwDQYJKoZIhvcN\n"
-                    + "AQEBBQADggGPADCCAYoCggGBAMtrsT0otlxh0QS079KpRRbU1PQjCihSoltXnrxF\n"
-                    + "sTWZs2weVEeYVyYU5LaauCDDgISCMtjtfbfylMBeYjpWB5hYzYQOiTzo0anWhMyb\n"
-                    + "Ngb7gpMVZuIl6lwMYRyVRKwHWnTo2EUg1ZzW5rGe5fs/KHj6//hoNFm+3Oju0TQd\n"
-                    + "nraQULpoERPF5B7p85Cssk8uNbviBfZXvtCuJ4N6w7PNceOY/9bbwc1mC+pPZmzV\n"
-                    + "SOAg0vvbIQRzChm63C3jBC3xmxSOOZVrKN4zKDG2s8P0oCNGt0NlgRMrgbPRekzg\n"
-                    + "4avkbA0vTuc2AyriTEYkdea/Mt4EpRg9XuOb43U/GJ/d/vQv2/9fsxhXmsZrn8kr\n"
-                    + "Qo5MMHJFUd96GgHmvYSU3Mf/5r8gF626lvqHioGuTAuHUSnr02ri1WUxZ15LDRgY\n"
-                    + "quMjDCFZfucjJPDAdtiHcFSej/4SLJlN39z8oKKNPn3aL9Gv49oAKs9S8tfDVzMk\n"
-                    + "fDLROQFHFuW715GnnMgEAoOpRwIDAQABo1MwUTAdBgNVHQ4EFgQUeVuGmSVN4ARs\n"
-                    + "mesUMWSJ2qWLbxUwHwYDVR0jBBgwFoAUeVuGmSVN4ARsmesUMWSJ2qWLbxUwDwYD\n"
-                    + "VR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQwFAAOCAYEAit1Lo/hegZpPuT9dlWZJ\n"
-                    + "bC8JvAf95O8lnn6LFb69pgYOHCLgCIlvYXu9rdBUJgZo+V1MzJJljiO6RxWRfKbQ\n"
-                    + "8WBYkoqR1EqriR3Kn8q/SjIZCdFSaznTyU1wQMveBQ6RJWXSUhYVfE9RjyFTp7B4\n"
-                    + "UyH2uCluR/0T06HQNGfH5XpIYQqCk1Zgng5lmEmheLDPoJpa92lKeQFJMC6eYz9g\n"
-                    + "lF1GHxPxkPfbMJ6ZDp5X6Yopu6Q6uEXhVKM/iQVcgzRkx9rid+xTYl+nOKyK/XfC\n"
-                    + "z8P0/TFIoPTW02DLge5wKagdoCpy1B7HdrAXyUjoH4B8MsUkq3kYPFSjPzScuTtV\n"
-                    + "kUuDw5ipCNeXCRnhbYqRDk6PX5GUu2cmN9jtaH3tbgm3fKNOsd/BO1fLIl7qjXlR\n"
-                    + "27HHbC0JXjNvlm2DLp23v4NTxS7WZGYsxyUj5DZrxBxqCsTXu/01w1BrQKWKh9FM\n"
-                    + "aVrlA8omfVODK2CSuw+KhEMHepRv/AUgsLl4L4+RMoa+\n"
-                    + "-----END CERTIFICATE-----\n";
-    public static final X509Certificate CA_SUITE_B_RSA3072_CERT =
-            loadCertificate(CA_SUITE_B_RSA3072_CERT_STRING);
-
-    private static final String CA_SUITE_B_ECDSA_CERT_STRING =
-            "-----BEGIN CERTIFICATE-----\n"
-                    + "MIICTzCCAdSgAwIBAgIUdnLttwNPnQzFufplGOr9bTrGCqMwCgYIKoZIzj0EAwMw\n"
-                    + "XjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMQwwCgYDVQQHDANNVFYxEDAOBgNV\n"
-                    + "BAoMB0FuZHJvaWQxDjAMBgNVBAsMBVdpLUZpMRIwEAYDVQQDDAl1bml0ZXN0Q0Ew\n"
-                    + "HhcNMjAwNzIxMDIyNDA1WhcNMzAwNTMwMDIyNDA1WjBeMQswCQYDVQQGEwJVUzEL\n"
-                    + "MAkGA1UECAwCQ0ExDDAKBgNVBAcMA01UVjEQMA4GA1UECgwHQW5kcm9pZDEOMAwG\n"
-                    + "A1UECwwFV2ktRmkxEjAQBgNVBAMMCXVuaXRlc3RDQTB2MBAGByqGSM49AgEGBSuB\n"
-                    + "BAAiA2IABFmntXwk9icqhDQFUP1xy04WyEpaGW4q6Q+8pujlSl/X3iotPZ++GZfp\n"
-                    + "Mfv3YDHDBl6sELPQ2BEjyPXmpsKjOUdiUe69e88oGEdeqT2xXiQ6uzpTfJD4170i\n"
-                    + "O/TwLrQGKKNTMFEwHQYDVR0OBBYEFCjptsX3g4g5W0L4oEP6N3gfyiZXMB8GA1Ud\n"
-                    + "IwQYMBaAFCjptsX3g4g5W0L4oEP6N3gfyiZXMA8GA1UdEwEB/wQFMAMBAf8wCgYI\n"
-                    + "KoZIzj0EAwMDaQAwZgIxAK61brUYRbLmQKiaEboZgrHtnPAcGo7Yzx3MwHecx3Dm\n"
-                    + "5soIeLVYc8bPYN1pbhXW1gIxALdEe2sh03nBHyQH4adYoZungoCwt8mp/7sJFxou\n"
-                    + "9UnRegyBgGzf74ROWdpZHzh+Pg==\n"
-                    + "-----END CERTIFICATE-----\n";
-    public static final X509Certificate CA_SUITE_B_ECDSA_CERT =
-            loadCertificate(CA_SUITE_B_ECDSA_CERT_STRING);
-
-    private static final String CLIENT_SUITE_B_RSA3072_CERT_STRING =
-            "-----BEGIN CERTIFICATE-----\n"
-                    + "MIIERzCCAq8CFDopjyNgaj+c2TN2k06h7okEWpHJMA0GCSqGSIb3DQEBDAUAMF4x\n"
-                    + "CzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEMMAoGA1UEBwwDTVRWMRAwDgYDVQQK\n"
-                    + "DAdBbmRyb2lkMQ4wDAYDVQQLDAVXaS1GaTESMBAGA1UEAwwJdW5pdGVzdENBMB4X\n"
-                    + "DTIwMDcyMTAyMjkxMVoXDTMwMDUzMDAyMjkxMVowYjELMAkGA1UEBhMCVVMxCzAJ\n"
-                    + "BgNVBAgMAkNBMQwwCgYDVQQHDANNVFYxEDAOBgNVBAoMB0FuZHJvaWQxDjAMBgNV\n"
-                    + "BAsMBVdpLUZpMRYwFAYDVQQDDA11bml0ZXN0Q2xpZW50MIIBojANBgkqhkiG9w0B\n"
-                    + "AQEFAAOCAY8AMIIBigKCAYEAwSK3C5K5udtCKTnE14e8z2cZvwmB4Xe+a8+7QLud\n"
-                    + "Hooc/lQzClgK4MbVUC0D3FE+U32C78SxKoTaRWtvPmNm+UaFT8KkwyUno/dv+2XD\n"
-                    + "pd/zARQ+3FwAfWopAhEyCVSxwsCa+slQ4juRIMIuUC1Mm0NaptZyM3Tj/ICQEfpk\n"
-                    + "o9qVIbiK6eoJMTkY8EWfAn7RTFdfR1OLuO0mVOjgLW9/+upYv6hZ19nAMAxw4QTJ\n"
-                    + "x7lLwALX7B+tDYNEZHDqYL2zyvQWAj2HClere8QYILxkvktgBg2crEJJe4XbDH7L\n"
-                    + "A3rrXmsiqf1ZbfFFEzK9NFqovL+qGh+zIP+588ShJFO9H/RDnDpiTnAFTWXQdTwg\n"
-                    + "szSS0Vw2PB+JqEABAa9DeMvXT1Oy+NY3ItPHyy63nQZVI2rXANw4NhwS0Z6DF+Qs\n"
-                    + "TNrj+GU7e4SG/EGR8SvldjYfQTWFLg1l/UT1hOOkQZwdsaW1zgKyeuiFB2KdMmbA\n"
-                    + "Sq+Ux1L1KICo0IglwWcB/8nnAgMBAAEwDQYJKoZIhvcNAQEMBQADggGBAMYwJkNw\n"
-                    + "BaCviKFmReDTMwWPRy4AMNViEeqAXgERwDEKwM7efjsaj5gctWfKsxX6UdLzkhgg\n"
-                    + "6S/T6PxVWKzJ6l7SoOuTa6tMQOZp+h3R1mdfEQbw8B5cXBxZ+batzAai6Fiy1FKS\n"
-                    + "/ka3INbcGfYuIYghfTrb4/NJKN06ZaQ1bpPwq0e4gN7800T2nbawvSf7r+8ZLcG3\n"
-                    + "6bGCjRMwDSIipNvOwoj3TG315XC7TccX5difQ4sKOY+d2MkVJ3RiO0Ciw2ZbEW8d\n"
-                    + "1FH5vUQJWnBUfSFznosGzLwH3iWfqlP+27jNE+qB2igEwCRFgVAouURx5ou43xuX\n"
-                    + "qf6JkdI3HTJGLIWxkp7gOeln4dEaYzKjYw+P0VqJvKVqQ0IXiLjHgE0J9p0vgyD6\n"
-                    + "HVVcP7U8RgqrbIjL1QgHU4KBhGi+WSUh/mRplUCNvHgcYdcHi/gHpj/j6ubwqIGV\n"
-                    + "z4iSolAHYTmBWcLyE0NgpzE6ntp+53r2KaUJA99l2iGVzbWTwqPSm0XAVw==\n"
-                    + "-----END CERTIFICATE-----\n";
-    public static final X509Certificate CLIENT_SUITE_B_RSA3072_CERT =
-            loadCertificate(CLIENT_SUITE_B_RSA3072_CERT_STRING);
-
-    private static final byte[] CLIENT_SUITE_B_RSA3072_KEY_DATA = new byte[]{
-            (byte) 0x30, (byte) 0x82, (byte) 0x06, (byte) 0xfe, (byte) 0x02, (byte) 0x01,
-            (byte) 0x00, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a,
-            (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01,
-            (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x04, (byte) 0x82,
-            (byte) 0x06, (byte) 0xe8, (byte) 0x30, (byte) 0x82, (byte) 0x06, (byte) 0xe4,
-            (byte) 0x02, (byte) 0x01, (byte) 0x00, (byte) 0x02, (byte) 0x82, (byte) 0x01,
-            (byte) 0x81, (byte) 0x00, (byte) 0xc1, (byte) 0x22, (byte) 0xb7, (byte) 0x0b,
-            (byte) 0x92, (byte) 0xb9, (byte) 0xb9, (byte) 0xdb, (byte) 0x42, (byte) 0x29,
-            (byte) 0x39, (byte) 0xc4, (byte) 0xd7, (byte) 0x87, (byte) 0xbc, (byte) 0xcf,
-            (byte) 0x67, (byte) 0x19, (byte) 0xbf, (byte) 0x09, (byte) 0x81, (byte) 0xe1,
-            (byte) 0x77, (byte) 0xbe, (byte) 0x6b, (byte) 0xcf, (byte) 0xbb, (byte) 0x40,
-            (byte) 0xbb, (byte) 0x9d, (byte) 0x1e, (byte) 0x8a, (byte) 0x1c, (byte) 0xfe,
-            (byte) 0x54, (byte) 0x33, (byte) 0x0a, (byte) 0x58, (byte) 0x0a, (byte) 0xe0,
-            (byte) 0xc6, (byte) 0xd5, (byte) 0x50, (byte) 0x2d, (byte) 0x03, (byte) 0xdc,
-            (byte) 0x51, (byte) 0x3e, (byte) 0x53, (byte) 0x7d, (byte) 0x82, (byte) 0xef,
-            (byte) 0xc4, (byte) 0xb1, (byte) 0x2a, (byte) 0x84, (byte) 0xda, (byte) 0x45,
-            (byte) 0x6b, (byte) 0x6f, (byte) 0x3e, (byte) 0x63, (byte) 0x66, (byte) 0xf9,
-            (byte) 0x46, (byte) 0x85, (byte) 0x4f, (byte) 0xc2, (byte) 0xa4, (byte) 0xc3,
-            (byte) 0x25, (byte) 0x27, (byte) 0xa3, (byte) 0xf7, (byte) 0x6f, (byte) 0xfb,
-            (byte) 0x65, (byte) 0xc3, (byte) 0xa5, (byte) 0xdf, (byte) 0xf3, (byte) 0x01,
-            (byte) 0x14, (byte) 0x3e, (byte) 0xdc, (byte) 0x5c, (byte) 0x00, (byte) 0x7d,
-            (byte) 0x6a, (byte) 0x29, (byte) 0x02, (byte) 0x11, (byte) 0x32, (byte) 0x09,
-            (byte) 0x54, (byte) 0xb1, (byte) 0xc2, (byte) 0xc0, (byte) 0x9a, (byte) 0xfa,
-            (byte) 0xc9, (byte) 0x50, (byte) 0xe2, (byte) 0x3b, (byte) 0x91, (byte) 0x20,
-            (byte) 0xc2, (byte) 0x2e, (byte) 0x50, (byte) 0x2d, (byte) 0x4c, (byte) 0x9b,
-            (byte) 0x43, (byte) 0x5a, (byte) 0xa6, (byte) 0xd6, (byte) 0x72, (byte) 0x33,
-            (byte) 0x74, (byte) 0xe3, (byte) 0xfc, (byte) 0x80, (byte) 0x90, (byte) 0x11,
-            (byte) 0xfa, (byte) 0x64, (byte) 0xa3, (byte) 0xda, (byte) 0x95, (byte) 0x21,
-            (byte) 0xb8, (byte) 0x8a, (byte) 0xe9, (byte) 0xea, (byte) 0x09, (byte) 0x31,
-            (byte) 0x39, (byte) 0x18, (byte) 0xf0, (byte) 0x45, (byte) 0x9f, (byte) 0x02,
-            (byte) 0x7e, (byte) 0xd1, (byte) 0x4c, (byte) 0x57, (byte) 0x5f, (byte) 0x47,
-            (byte) 0x53, (byte) 0x8b, (byte) 0xb8, (byte) 0xed, (byte) 0x26, (byte) 0x54,
-            (byte) 0xe8, (byte) 0xe0, (byte) 0x2d, (byte) 0x6f, (byte) 0x7f, (byte) 0xfa,
-            (byte) 0xea, (byte) 0x58, (byte) 0xbf, (byte) 0xa8, (byte) 0x59, (byte) 0xd7,
-            (byte) 0xd9, (byte) 0xc0, (byte) 0x30, (byte) 0x0c, (byte) 0x70, (byte) 0xe1,
-            (byte) 0x04, (byte) 0xc9, (byte) 0xc7, (byte) 0xb9, (byte) 0x4b, (byte) 0xc0,
-            (byte) 0x02, (byte) 0xd7, (byte) 0xec, (byte) 0x1f, (byte) 0xad, (byte) 0x0d,
-            (byte) 0x83, (byte) 0x44, (byte) 0x64, (byte) 0x70, (byte) 0xea, (byte) 0x60,
-            (byte) 0xbd, (byte) 0xb3, (byte) 0xca, (byte) 0xf4, (byte) 0x16, (byte) 0x02,
-            (byte) 0x3d, (byte) 0x87, (byte) 0x0a, (byte) 0x57, (byte) 0xab, (byte) 0x7b,
-            (byte) 0xc4, (byte) 0x18, (byte) 0x20, (byte) 0xbc, (byte) 0x64, (byte) 0xbe,
-            (byte) 0x4b, (byte) 0x60, (byte) 0x06, (byte) 0x0d, (byte) 0x9c, (byte) 0xac,
-            (byte) 0x42, (byte) 0x49, (byte) 0x7b, (byte) 0x85, (byte) 0xdb, (byte) 0x0c,
-            (byte) 0x7e, (byte) 0xcb, (byte) 0x03, (byte) 0x7a, (byte) 0xeb, (byte) 0x5e,
-            (byte) 0x6b, (byte) 0x22, (byte) 0xa9, (byte) 0xfd, (byte) 0x59, (byte) 0x6d,
-            (byte) 0xf1, (byte) 0x45, (byte) 0x13, (byte) 0x32, (byte) 0xbd, (byte) 0x34,
-            (byte) 0x5a, (byte) 0xa8, (byte) 0xbc, (byte) 0xbf, (byte) 0xaa, (byte) 0x1a,
-            (byte) 0x1f, (byte) 0xb3, (byte) 0x20, (byte) 0xff, (byte) 0xb9, (byte) 0xf3,
-            (byte) 0xc4, (byte) 0xa1, (byte) 0x24, (byte) 0x53, (byte) 0xbd, (byte) 0x1f,
-            (byte) 0xf4, (byte) 0x43, (byte) 0x9c, (byte) 0x3a, (byte) 0x62, (byte) 0x4e,
-            (byte) 0x70, (byte) 0x05, (byte) 0x4d, (byte) 0x65, (byte) 0xd0, (byte) 0x75,
-            (byte) 0x3c, (byte) 0x20, (byte) 0xb3, (byte) 0x34, (byte) 0x92, (byte) 0xd1,
-            (byte) 0x5c, (byte) 0x36, (byte) 0x3c, (byte) 0x1f, (byte) 0x89, (byte) 0xa8,
-            (byte) 0x40, (byte) 0x01, (byte) 0x01, (byte) 0xaf, (byte) 0x43, (byte) 0x78,
-            (byte) 0xcb, (byte) 0xd7, (byte) 0x4f, (byte) 0x53, (byte) 0xb2, (byte) 0xf8,
-            (byte) 0xd6, (byte) 0x37, (byte) 0x22, (byte) 0xd3, (byte) 0xc7, (byte) 0xcb,
-            (byte) 0x2e, (byte) 0xb7, (byte) 0x9d, (byte) 0x06, (byte) 0x55, (byte) 0x23,
-            (byte) 0x6a, (byte) 0xd7, (byte) 0x00, (byte) 0xdc, (byte) 0x38, (byte) 0x36,
-            (byte) 0x1c, (byte) 0x12, (byte) 0xd1, (byte) 0x9e, (byte) 0x83, (byte) 0x17,
-            (byte) 0xe4, (byte) 0x2c, (byte) 0x4c, (byte) 0xda, (byte) 0xe3, (byte) 0xf8,
-            (byte) 0x65, (byte) 0x3b, (byte) 0x7b, (byte) 0x84, (byte) 0x86, (byte) 0xfc,
-            (byte) 0x41, (byte) 0x91, (byte) 0xf1, (byte) 0x2b, (byte) 0xe5, (byte) 0x76,
-            (byte) 0x36, (byte) 0x1f, (byte) 0x41, (byte) 0x35, (byte) 0x85, (byte) 0x2e,
-            (byte) 0x0d, (byte) 0x65, (byte) 0xfd, (byte) 0x44, (byte) 0xf5, (byte) 0x84,
-            (byte) 0xe3, (byte) 0xa4, (byte) 0x41, (byte) 0x9c, (byte) 0x1d, (byte) 0xb1,
-            (byte) 0xa5, (byte) 0xb5, (byte) 0xce, (byte) 0x02, (byte) 0xb2, (byte) 0x7a,
-            (byte) 0xe8, (byte) 0x85, (byte) 0x07, (byte) 0x62, (byte) 0x9d, (byte) 0x32,
-            (byte) 0x66, (byte) 0xc0, (byte) 0x4a, (byte) 0xaf, (byte) 0x94, (byte) 0xc7,
-            (byte) 0x52, (byte) 0xf5, (byte) 0x28, (byte) 0x80, (byte) 0xa8, (byte) 0xd0,
-            (byte) 0x88, (byte) 0x25, (byte) 0xc1, (byte) 0x67, (byte) 0x01, (byte) 0xff,
-            (byte) 0xc9, (byte) 0xe7, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x00,
-            (byte) 0x01, (byte) 0x02, (byte) 0x82, (byte) 0x01, (byte) 0x80, (byte) 0x04,
-            (byte) 0xb1, (byte) 0xcc, (byte) 0x53, (byte) 0x3a, (byte) 0xb0, (byte) 0xcb,
-            (byte) 0x04, (byte) 0xba, (byte) 0x59, (byte) 0xf8, (byte) 0x2e, (byte) 0x81,
-            (byte) 0xb2, (byte) 0xa9, (byte) 0xf3, (byte) 0x3c, (byte) 0xa5, (byte) 0x52,
-            (byte) 0x90, (byte) 0x6f, (byte) 0x98, (byte) 0xc4, (byte) 0x69, (byte) 0x5b,
-            (byte) 0x83, (byte) 0x84, (byte) 0x20, (byte) 0xb1, (byte) 0xae, (byte) 0xc3,
-            (byte) 0x04, (byte) 0x46, (byte) 0x6a, (byte) 0x24, (byte) 0x2f, (byte) 0xcd,
-            (byte) 0x6b, (byte) 0x90, (byte) 0x70, (byte) 0x20, (byte) 0x45, (byte) 0x25,
-            (byte) 0x1a, (byte) 0xc3, (byte) 0x02, (byte) 0x42, (byte) 0xf3, (byte) 0x49,
-            (byte) 0xe2, (byte) 0x3e, (byte) 0x21, (byte) 0x87, (byte) 0xdd, (byte) 0x6a,
-            (byte) 0x94, (byte) 0x2a, (byte) 0x1e, (byte) 0x0f, (byte) 0xdb, (byte) 0x77,
-            (byte) 0x5f, (byte) 0xc1, (byte) 0x2c, (byte) 0x03, (byte) 0xfb, (byte) 0xcf,
-            (byte) 0x91, (byte) 0x82, (byte) 0xa1, (byte) 0xbf, (byte) 0xb0, (byte) 0x73,
-            (byte) 0xfa, (byte) 0xda, (byte) 0xbc, (byte) 0xf8, (byte) 0x9f, (byte) 0x45,
-            (byte) 0xd3, (byte) 0xe8, (byte) 0xbb, (byte) 0x38, (byte) 0xfb, (byte) 0xc2,
-            (byte) 0x2d, (byte) 0x76, (byte) 0x51, (byte) 0x96, (byte) 0x18, (byte) 0x03,
-            (byte) 0x15, (byte) 0xd9, (byte) 0xea, (byte) 0x82, (byte) 0x25, (byte) 0x83,
-            (byte) 0xff, (byte) 0x5c, (byte) 0x85, (byte) 0x06, (byte) 0x09, (byte) 0xb2,
-            (byte) 0x46, (byte) 0x12, (byte) 0x64, (byte) 0x02, (byte) 0x74, (byte) 0x4f,
-            (byte) 0xbc, (byte) 0x9a, (byte) 0x25, (byte) 0x18, (byte) 0x01, (byte) 0x07,
-            (byte) 0x17, (byte) 0x25, (byte) 0x55, (byte) 0x7c, (byte) 0xdc, (byte) 0xe1,
-            (byte) 0xd1, (byte) 0x5a, (byte) 0x2f, (byte) 0x25, (byte) 0xaf, (byte) 0xf6,
-            (byte) 0x8f, (byte) 0xa4, (byte) 0x9a, (byte) 0x5a, (byte) 0x3a, (byte) 0xfe,
-            (byte) 0x2e, (byte) 0x93, (byte) 0x24, (byte) 0xa0, (byte) 0x27, (byte) 0xac,
-            (byte) 0x07, (byte) 0x75, (byte) 0x33, (byte) 0x01, (byte) 0x54, (byte) 0x23,
-            (byte) 0x0f, (byte) 0xe8, (byte) 0x9f, (byte) 0xfa, (byte) 0x36, (byte) 0xe6,
-            (byte) 0x3a, (byte) 0xd5, (byte) 0x78, (byte) 0xb0, (byte) 0xe4, (byte) 0x6a,
-            (byte) 0x16, (byte) 0x50, (byte) 0xbd, (byte) 0x0f, (byte) 0x9f, (byte) 0x32,
-            (byte) 0xa1, (byte) 0x6b, (byte) 0xf5, (byte) 0xa4, (byte) 0x34, (byte) 0x58,
-            (byte) 0xb6, (byte) 0xa4, (byte) 0xb3, (byte) 0xc3, (byte) 0x83, (byte) 0x08,
-            (byte) 0x18, (byte) 0xc7, (byte) 0xef, (byte) 0x95, (byte) 0xe2, (byte) 0x1b,
-            (byte) 0xba, (byte) 0x35, (byte) 0x61, (byte) 0xa3, (byte) 0xb4, (byte) 0x30,
-            (byte) 0xe0, (byte) 0xd1, (byte) 0xc1, (byte) 0xa2, (byte) 0x3a, (byte) 0xc6,
-            (byte) 0xb4, (byte) 0xd2, (byte) 0x80, (byte) 0x5a, (byte) 0xaf, (byte) 0xa4,
-            (byte) 0x54, (byte) 0x3c, (byte) 0x66, (byte) 0x5a, (byte) 0x1c, (byte) 0x4d,
-            (byte) 0xe1, (byte) 0xd9, (byte) 0x98, (byte) 0x44, (byte) 0x01, (byte) 0x1b,
-            (byte) 0x8c, (byte) 0xe9, (byte) 0x80, (byte) 0x54, (byte) 0x83, (byte) 0x3d,
-            (byte) 0x96, (byte) 0x25, (byte) 0x41, (byte) 0x1c, (byte) 0xad, (byte) 0xae,
-            (byte) 0x3b, (byte) 0x7a, (byte) 0xd7, (byte) 0x9d, (byte) 0x10, (byte) 0x7c,
-            (byte) 0xd1, (byte) 0xa7, (byte) 0x96, (byte) 0x39, (byte) 0xa5, (byte) 0x2f,
-            (byte) 0xbe, (byte) 0xc3, (byte) 0x2c, (byte) 0x64, (byte) 0x01, (byte) 0xfe,
-            (byte) 0xa2, (byte) 0xd1, (byte) 0x6a, (byte) 0xcf, (byte) 0x4c, (byte) 0x76,
-            (byte) 0x3b, (byte) 0xc8, (byte) 0x35, (byte) 0x21, (byte) 0xda, (byte) 0x98,
-            (byte) 0xcf, (byte) 0xf9, (byte) 0x29, (byte) 0xff, (byte) 0x30, (byte) 0x59,
-            (byte) 0x36, (byte) 0x53, (byte) 0x0b, (byte) 0xbb, (byte) 0xfa, (byte) 0xba,
-            (byte) 0xc4, (byte) 0x03, (byte) 0x23, (byte) 0xe0, (byte) 0xd3, (byte) 0x33,
-            (byte) 0xff, (byte) 0x32, (byte) 0xdb, (byte) 0x30, (byte) 0x64, (byte) 0xc7,
-            (byte) 0x56, (byte) 0xca, (byte) 0x55, (byte) 0x14, (byte) 0xee, (byte) 0x58,
-            (byte) 0xfe, (byte) 0x96, (byte) 0x7e, (byte) 0x1c, (byte) 0x34, (byte) 0x16,
-            (byte) 0xeb, (byte) 0x76, (byte) 0x26, (byte) 0x48, (byte) 0xe2, (byte) 0xe5,
-            (byte) 0x5c, (byte) 0xd5, (byte) 0x83, (byte) 0x37, (byte) 0xd9, (byte) 0x09,
-            (byte) 0x71, (byte) 0xbc, (byte) 0x54, (byte) 0x25, (byte) 0xca, (byte) 0x2e,
-            (byte) 0xdb, (byte) 0x36, (byte) 0x39, (byte) 0xcc, (byte) 0x3a, (byte) 0x81,
-            (byte) 0x95, (byte) 0x9e, (byte) 0xf4, (byte) 0x01, (byte) 0xa7, (byte) 0xc0,
-            (byte) 0x20, (byte) 0xce, (byte) 0x70, (byte) 0x55, (byte) 0x2c, (byte) 0xe0,
-            (byte) 0x93, (byte) 0x72, (byte) 0xa6, (byte) 0x25, (byte) 0xda, (byte) 0x64,
-            (byte) 0x19, (byte) 0x18, (byte) 0xd2, (byte) 0x31, (byte) 0xe2, (byte) 0x7c,
-            (byte) 0xf2, (byte) 0x30, (byte) 0x9e, (byte) 0x8d, (byte) 0xc6, (byte) 0x14,
-            (byte) 0x8a, (byte) 0x38, (byte) 0xf0, (byte) 0x94, (byte) 0xeb, (byte) 0xf4,
-            (byte) 0x64, (byte) 0x92, (byte) 0x3d, (byte) 0x67, (byte) 0xa6, (byte) 0x2c,
-            (byte) 0x52, (byte) 0xfc, (byte) 0x60, (byte) 0xca, (byte) 0x2a, (byte) 0xcf,
-            (byte) 0x24, (byte) 0xd5, (byte) 0x42, (byte) 0x5f, (byte) 0xc7, (byte) 0x9f,
-            (byte) 0xf3, (byte) 0xb4, (byte) 0xdf, (byte) 0x76, (byte) 0x6e, (byte) 0x53,
-            (byte) 0xa1, (byte) 0x7b, (byte) 0xae, (byte) 0xa5, (byte) 0x84, (byte) 0x1f,
-            (byte) 0xfa, (byte) 0xc0, (byte) 0xb4, (byte) 0x6c, (byte) 0xc9, (byte) 0x02,
-            (byte) 0x81, (byte) 0xc1, (byte) 0x00, (byte) 0xf3, (byte) 0x17, (byte) 0xd9,
-            (byte) 0x48, (byte) 0x17, (byte) 0x87, (byte) 0x84, (byte) 0x16, (byte) 0xea,
-            (byte) 0x2d, (byte) 0x31, (byte) 0x1b, (byte) 0xce, (byte) 0xec, (byte) 0xaf,
-            (byte) 0xdc, (byte) 0x6b, (byte) 0xaf, (byte) 0xc8, (byte) 0xf1, (byte) 0x40,
-            (byte) 0xa7, (byte) 0x4f, (byte) 0xef, (byte) 0x48, (byte) 0x08, (byte) 0x5e,
-            (byte) 0x9a, (byte) 0xd1, (byte) 0xc0, (byte) 0xb1, (byte) 0xfe, (byte) 0xe7,
-            (byte) 0x03, (byte) 0xd5, (byte) 0x96, (byte) 0x01, (byte) 0xe8, (byte) 0x40,
-            (byte) 0xca, (byte) 0x78, (byte) 0xcb, (byte) 0xb3, (byte) 0x28, (byte) 0x1a,
-            (byte) 0xf0, (byte) 0xe5, (byte) 0xf6, (byte) 0x46, (byte) 0xef, (byte) 0xcd,
-            (byte) 0x1a, (byte) 0x0f, (byte) 0x13, (byte) 0x2d, (byte) 0x38, (byte) 0xf8,
-            (byte) 0xf7, (byte) 0x88, (byte) 0x21, (byte) 0x15, (byte) 0xce, (byte) 0x48,
-            (byte) 0xf4, (byte) 0x92, (byte) 0x7e, (byte) 0x9b, (byte) 0x2e, (byte) 0x2f,
-            (byte) 0x22, (byte) 0x3e, (byte) 0x5c, (byte) 0x67, (byte) 0xd7, (byte) 0x58,
-            (byte) 0xf6, (byte) 0xef, (byte) 0x1f, (byte) 0xb4, (byte) 0x04, (byte) 0xc7,
-            (byte) 0xfd, (byte) 0x8c, (byte) 0x4e, (byte) 0x27, (byte) 0x9e, (byte) 0xb9,
-            (byte) 0xef, (byte) 0x0f, (byte) 0xf7, (byte) 0x4a, (byte) 0xc2, (byte) 0xf4,
-            (byte) 0x64, (byte) 0x6b, (byte) 0xe0, (byte) 0xfb, (byte) 0xe3, (byte) 0x45,
-            (byte) 0xd5, (byte) 0x37, (byte) 0xa0, (byte) 0x2a, (byte) 0xc6, (byte) 0xf3,
-            (byte) 0xf6, (byte) 0xcc, (byte) 0xb5, (byte) 0x94, (byte) 0xbf, (byte) 0x56,
-            (byte) 0xa0, (byte) 0x61, (byte) 0x36, (byte) 0x88, (byte) 0x35, (byte) 0xd5,
-            (byte) 0xa5, (byte) 0xad, (byte) 0x20, (byte) 0x48, (byte) 0xda, (byte) 0x70,
-            (byte) 0x35, (byte) 0xd9, (byte) 0x75, (byte) 0x66, (byte) 0xa5, (byte) 0xac,
-            (byte) 0x86, (byte) 0x7a, (byte) 0x75, (byte) 0x49, (byte) 0x88, (byte) 0x40,
-            (byte) 0xce, (byte) 0xb0, (byte) 0x6f, (byte) 0x57, (byte) 0x15, (byte) 0x54,
-            (byte) 0xd3, (byte) 0x2f, (byte) 0x11, (byte) 0x9b, (byte) 0xe3, (byte) 0x87,
-            (byte) 0xc8, (byte) 0x8d, (byte) 0x98, (byte) 0xc6, (byte) 0xe0, (byte) 0xbc,
-            (byte) 0x85, (byte) 0xb9, (byte) 0x04, (byte) 0x43, (byte) 0xa9, (byte) 0x41,
-            (byte) 0xce, (byte) 0x42, (byte) 0x1a, (byte) 0x57, (byte) 0x10, (byte) 0xd8,
-            (byte) 0xe4, (byte) 0x6a, (byte) 0x51, (byte) 0x10, (byte) 0x0a, (byte) 0xec,
-            (byte) 0xe4, (byte) 0x57, (byte) 0xc7, (byte) 0xee, (byte) 0xe9, (byte) 0xd6,
-            (byte) 0xcb, (byte) 0x3e, (byte) 0xba, (byte) 0xfa, (byte) 0xe9, (byte) 0x0e,
-            (byte) 0xed, (byte) 0x87, (byte) 0x04, (byte) 0x9a, (byte) 0x48, (byte) 0xba,
-            (byte) 0xaf, (byte) 0x08, (byte) 0xf5, (byte) 0x02, (byte) 0x81, (byte) 0xc1,
-            (byte) 0x00, (byte) 0xcb, (byte) 0x63, (byte) 0xd6, (byte) 0x54, (byte) 0xb6,
-            (byte) 0xf3, (byte) 0xf3, (byte) 0x8c, (byte) 0xf8, (byte) 0xd0, (byte) 0xd2,
-            (byte) 0x84, (byte) 0xc1, (byte) 0xf5, (byte) 0x12, (byte) 0xe0, (byte) 0x02,
-            (byte) 0x80, (byte) 0x42, (byte) 0x92, (byte) 0x4e, (byte) 0xa4, (byte) 0x5c,
-            (byte) 0xa5, (byte) 0x64, (byte) 0xec, (byte) 0xb7, (byte) 0xdc, (byte) 0xe0,
-            (byte) 0x2d, (byte) 0x5d, (byte) 0xac, (byte) 0x0e, (byte) 0x24, (byte) 0x48,
-            (byte) 0x13, (byte) 0x05, (byte) 0xe8, (byte) 0xff, (byte) 0x96, (byte) 0x93,
-            (byte) 0xba, (byte) 0x3c, (byte) 0x88, (byte) 0xcc, (byte) 0x80, (byte) 0xf9,
-            (byte) 0xdb, (byte) 0xa8, (byte) 0x4d, (byte) 0x86, (byte) 0x47, (byte) 0xc8,
-            (byte) 0xbf, (byte) 0x34, (byte) 0x2d, (byte) 0xda, (byte) 0xb6, (byte) 0x28,
-            (byte) 0xf0, (byte) 0x1e, (byte) 0xd2, (byte) 0x46, (byte) 0x0d, (byte) 0x6f,
-            (byte) 0x36, (byte) 0x8e, (byte) 0x84, (byte) 0xd8, (byte) 0xaf, (byte) 0xf7,
-            (byte) 0x69, (byte) 0x23, (byte) 0x77, (byte) 0xfb, (byte) 0xc5, (byte) 0x04,
-            (byte) 0x08, (byte) 0x18, (byte) 0xac, (byte) 0x85, (byte) 0x80, (byte) 0x87,
-            (byte) 0x1c, (byte) 0xfe, (byte) 0x8e, (byte) 0x5d, (byte) 0x00, (byte) 0x7f,
-            (byte) 0x5b, (byte) 0x33, (byte) 0xf5, (byte) 0xdf, (byte) 0x70, (byte) 0x81,
-            (byte) 0xad, (byte) 0x81, (byte) 0xf4, (byte) 0x5a, (byte) 0x37, (byte) 0x8a,
-            (byte) 0x79, (byte) 0x09, (byte) 0xc5, (byte) 0x55, (byte) 0xab, (byte) 0x58,
-            (byte) 0x7c, (byte) 0x47, (byte) 0xca, (byte) 0xa5, (byte) 0x80, (byte) 0x49,
-            (byte) 0x5f, (byte) 0x71, (byte) 0x83, (byte) 0xfb, (byte) 0x3b, (byte) 0x06,
-            (byte) 0xec, (byte) 0x75, (byte) 0x23, (byte) 0xc4, (byte) 0x32, (byte) 0xc7,
-            (byte) 0x18, (byte) 0xf6, (byte) 0x82, (byte) 0x95, (byte) 0x98, (byte) 0x39,
-            (byte) 0xf7, (byte) 0x92, (byte) 0x31, (byte) 0xc0, (byte) 0x89, (byte) 0xba,
-            (byte) 0xd4, (byte) 0xd4, (byte) 0x58, (byte) 0x4e, (byte) 0x38, (byte) 0x35,
-            (byte) 0x10, (byte) 0xb9, (byte) 0xf1, (byte) 0x27, (byte) 0xdc, (byte) 0xff,
-            (byte) 0xc7, (byte) 0xb2, (byte) 0xba, (byte) 0x1f, (byte) 0x27, (byte) 0xaf,
-            (byte) 0x99, (byte) 0xd5, (byte) 0xb0, (byte) 0x39, (byte) 0xe7, (byte) 0x43,
-            (byte) 0x88, (byte) 0xd3, (byte) 0xce, (byte) 0x38, (byte) 0xc2, (byte) 0x99,
-            (byte) 0x43, (byte) 0xfc, (byte) 0x8a, (byte) 0xe3, (byte) 0x60, (byte) 0x0d,
-            (byte) 0x0a, (byte) 0xb8, (byte) 0xc4, (byte) 0x29, (byte) 0xca, (byte) 0x0d,
-            (byte) 0x30, (byte) 0xaf, (byte) 0xca, (byte) 0xd0, (byte) 0xaa, (byte) 0x67,
-            (byte) 0xb1, (byte) 0xdd, (byte) 0xdb, (byte) 0x7a, (byte) 0x11, (byte) 0xad,
-            (byte) 0xeb, (byte) 0x02, (byte) 0x81, (byte) 0xc0, (byte) 0x71, (byte) 0xb8,
-            (byte) 0xcf, (byte) 0x72, (byte) 0x35, (byte) 0x67, (byte) 0xb5, (byte) 0x38,
-            (byte) 0x8f, (byte) 0x16, (byte) 0xd3, (byte) 0x29, (byte) 0x82, (byte) 0x35,
-            (byte) 0x21, (byte) 0xd4, (byte) 0x49, (byte) 0x20, (byte) 0x74, (byte) 0x2d,
-            (byte) 0xc0, (byte) 0xa4, (byte) 0x44, (byte) 0xf5, (byte) 0xd8, (byte) 0xc9,
-            (byte) 0xe9, (byte) 0x90, (byte) 0x1d, (byte) 0xde, (byte) 0x3a, (byte) 0xa6,
-            (byte) 0xd7, (byte) 0xe5, (byte) 0xe8, (byte) 0x4e, (byte) 0x83, (byte) 0xd7,
-            (byte) 0xe6, (byte) 0x2f, (byte) 0x92, (byte) 0x31, (byte) 0x21, (byte) 0x3f,
-            (byte) 0xfa, (byte) 0xd2, (byte) 0x85, (byte) 0x92, (byte) 0x1f, (byte) 0xff,
-            (byte) 0x61, (byte) 0x00, (byte) 0xf6, (byte) 0xda, (byte) 0x6e, (byte) 0xc6,
-            (byte) 0x7f, (byte) 0x5a, (byte) 0x35, (byte) 0x79, (byte) 0xdc, (byte) 0xdc,
-            (byte) 0xa3, (byte) 0x2e, (byte) 0x9f, (byte) 0x35, (byte) 0xd1, (byte) 0x5c,
-            (byte) 0xda, (byte) 0xb9, (byte) 0xf7, (byte) 0x58, (byte) 0x7d, (byte) 0x4f,
-            (byte) 0xb6, (byte) 0x13, (byte) 0xd7, (byte) 0x2c, (byte) 0x0a, (byte) 0xa8,
-            (byte) 0x4d, (byte) 0xf2, (byte) 0xe4, (byte) 0x67, (byte) 0x4f, (byte) 0x8b,
-            (byte) 0xa6, (byte) 0xca, (byte) 0x1a, (byte) 0xbb, (byte) 0x02, (byte) 0x63,
-            (byte) 0x8f, (byte) 0xb7, (byte) 0x46, (byte) 0xec, (byte) 0x7a, (byte) 0x8a,
-            (byte) 0x09, (byte) 0x0a, (byte) 0x45, (byte) 0x3a, (byte) 0x8d, (byte) 0xa8,
-            (byte) 0x83, (byte) 0x4b, (byte) 0x0a, (byte) 0xdb, (byte) 0x4b, (byte) 0x99,
-            (byte) 0xf3, (byte) 0x69, (byte) 0x95, (byte) 0xf0, (byte) 0xcf, (byte) 0xe9,
-            (byte) 0xf7, (byte) 0x67, (byte) 0xc9, (byte) 0x45, (byte) 0x18, (byte) 0x2f,
-            (byte) 0xf0, (byte) 0x5c, (byte) 0x90, (byte) 0xbd, (byte) 0xa6, (byte) 0x66,
-            (byte) 0x8c, (byte) 0xfe, (byte) 0x60, (byte) 0x5d, (byte) 0x6c, (byte) 0x27,
-            (byte) 0xec, (byte) 0xc1, (byte) 0x84, (byte) 0xb2, (byte) 0xa1, (byte) 0x97,
-            (byte) 0x9e, (byte) 0x16, (byte) 0x29, (byte) 0xa7, (byte) 0xe0, (byte) 0x38,
-            (byte) 0xa2, (byte) 0x36, (byte) 0x05, (byte) 0x5f, (byte) 0xda, (byte) 0x72,
-            (byte) 0x1a, (byte) 0x5f, (byte) 0xa8, (byte) 0x7d, (byte) 0x41, (byte) 0x35,
-            (byte) 0xf6, (byte) 0x4e, (byte) 0x0a, (byte) 0x88, (byte) 0x8e, (byte) 0x00,
-            (byte) 0x98, (byte) 0xa6, (byte) 0xca, (byte) 0xc1, (byte) 0xdf, (byte) 0x72,
-            (byte) 0x6c, (byte) 0xfe, (byte) 0x29, (byte) 0xbe, (byte) 0xa3, (byte) 0x9b,
-            (byte) 0x0b, (byte) 0x5c, (byte) 0x0b, (byte) 0x9d, (byte) 0xa7, (byte) 0x71,
-            (byte) 0xce, (byte) 0x04, (byte) 0xfa, (byte) 0xac, (byte) 0x01, (byte) 0x8d,
-            (byte) 0x52, (byte) 0xa0, (byte) 0x3d, (byte) 0xdd, (byte) 0x02, (byte) 0x81,
-            (byte) 0xc1, (byte) 0x00, (byte) 0xc1, (byte) 0xc0, (byte) 0x2e, (byte) 0xa9,
-            (byte) 0xee, (byte) 0xca, (byte) 0xff, (byte) 0xe4, (byte) 0xf8, (byte) 0x15,
-            (byte) 0xfd, (byte) 0xa5, (byte) 0x68, (byte) 0x1b, (byte) 0x2d, (byte) 0x4a,
-            (byte) 0xe6, (byte) 0x37, (byte) 0x06, (byte) 0xb3, (byte) 0xd7, (byte) 0x64,
-            (byte) 0xad, (byte) 0xb9, (byte) 0x05, (byte) 0x26, (byte) 0x97, (byte) 0x94,
-            (byte) 0x3a, (byte) 0x9e, (byte) 0x1c, (byte) 0xd0, (byte) 0xcd, (byte) 0x7b,
-            (byte) 0xf4, (byte) 0x88, (byte) 0xe2, (byte) 0xa5, (byte) 0x6d, (byte) 0xed,
-            (byte) 0x24, (byte) 0x77, (byte) 0x52, (byte) 0x39, (byte) 0x43, (byte) 0x0f,
-            (byte) 0x4e, (byte) 0x75, (byte) 0xd8, (byte) 0xa3, (byte) 0x59, (byte) 0x5a,
-            (byte) 0xc2, (byte) 0xba, (byte) 0x9a, (byte) 0x5b, (byte) 0x60, (byte) 0x31,
-            (byte) 0x0d, (byte) 0x58, (byte) 0x89, (byte) 0x13, (byte) 0xe8, (byte) 0x95,
-            (byte) 0xdd, (byte) 0xae, (byte) 0xcc, (byte) 0x1f, (byte) 0x73, (byte) 0x48,
-            (byte) 0x55, (byte) 0xd8, (byte) 0xfb, (byte) 0x67, (byte) 0xce, (byte) 0x18,
-            (byte) 0x85, (byte) 0x59, (byte) 0xad, (byte) 0x1f, (byte) 0x93, (byte) 0xe1,
-            (byte) 0xb7, (byte) 0x54, (byte) 0x80, (byte) 0x8e, (byte) 0x5f, (byte) 0xbc,
-            (byte) 0x1c, (byte) 0x96, (byte) 0x66, (byte) 0x2e, (byte) 0x40, (byte) 0x17,
-            (byte) 0x2e, (byte) 0x01, (byte) 0x7a, (byte) 0x7d, (byte) 0xaa, (byte) 0xff,
-            (byte) 0xa3, (byte) 0xd2, (byte) 0xdf, (byte) 0xe2, (byte) 0xf3, (byte) 0x54,
-            (byte) 0x51, (byte) 0xeb, (byte) 0xba, (byte) 0x7c, (byte) 0x2a, (byte) 0x22,
-            (byte) 0xc6, (byte) 0x42, (byte) 0xbc, (byte) 0xa1, (byte) 0x6c, (byte) 0xcf,
-            (byte) 0x73, (byte) 0x2e, (byte) 0x07, (byte) 0xfc, (byte) 0xf5, (byte) 0x67,
-            (byte) 0x25, (byte) 0xd0, (byte) 0xfa, (byte) 0xeb, (byte) 0xb4, (byte) 0xd4,
-            (byte) 0x19, (byte) 0xcc, (byte) 0x64, (byte) 0xa1, (byte) 0x2e, (byte) 0x78,
-            (byte) 0x45, (byte) 0xd9, (byte) 0x7f, (byte) 0x1b, (byte) 0x4c, (byte) 0x10,
-            (byte) 0x31, (byte) 0x44, (byte) 0xe8, (byte) 0xcc, (byte) 0xf9, (byte) 0x1b,
-            (byte) 0x87, (byte) 0x31, (byte) 0xd6, (byte) 0x69, (byte) 0x85, (byte) 0x4a,
-            (byte) 0x49, (byte) 0xf6, (byte) 0xb2, (byte) 0xe0, (byte) 0xb8, (byte) 0x98,
-            (byte) 0x3c, (byte) 0xf6, (byte) 0x78, (byte) 0x46, (byte) 0xc8, (byte) 0x3d,
-            (byte) 0x60, (byte) 0xc1, (byte) 0xaa, (byte) 0x2f, (byte) 0x28, (byte) 0xa1,
-            (byte) 0x14, (byte) 0x6b, (byte) 0x75, (byte) 0x4d, (byte) 0xb1, (byte) 0x3d,
-            (byte) 0x80, (byte) 0x49, (byte) 0x33, (byte) 0xfd, (byte) 0x71, (byte) 0xc0,
-            (byte) 0x13, (byte) 0x1e, (byte) 0x16, (byte) 0x69, (byte) 0x80, (byte) 0xa4,
-            (byte) 0x9c, (byte) 0xd7, (byte) 0x02, (byte) 0x81, (byte) 0xc1, (byte) 0x00,
-            (byte) 0x8c, (byte) 0x33, (byte) 0x2d, (byte) 0xd9, (byte) 0xf3, (byte) 0x42,
-            (byte) 0x4d, (byte) 0xca, (byte) 0x5e, (byte) 0x60, (byte) 0x14, (byte) 0x10,
-            (byte) 0xf6, (byte) 0xf3, (byte) 0x71, (byte) 0x15, (byte) 0x88, (byte) 0x54,
-            (byte) 0x84, (byte) 0x21, (byte) 0x04, (byte) 0xb1, (byte) 0xaf, (byte) 0x02,
-            (byte) 0x11, (byte) 0x7f, (byte) 0x42, (byte) 0x3e, (byte) 0x86, (byte) 0xcb,
-            (byte) 0x6c, (byte) 0xf5, (byte) 0x57, (byte) 0x78, (byte) 0x4a, (byte) 0x03,
-            (byte) 0x9b, (byte) 0x80, (byte) 0xc2, (byte) 0x04, (byte) 0x3a, (byte) 0x6b,
-            (byte) 0xb3, (byte) 0x30, (byte) 0x31, (byte) 0x7e, (byte) 0xc3, (byte) 0x89,
-            (byte) 0x09, (byte) 0x4e, (byte) 0x86, (byte) 0x59, (byte) 0x41, (byte) 0xb5,
-            (byte) 0xae, (byte) 0xd5, (byte) 0xc6, (byte) 0x38, (byte) 0xbc, (byte) 0xd7,
-            (byte) 0xd7, (byte) 0x8e, (byte) 0xa3, (byte) 0x1a, (byte) 0xde, (byte) 0x32,
-            (byte) 0xad, (byte) 0x8d, (byte) 0x15, (byte) 0x81, (byte) 0xfe, (byte) 0xac,
-            (byte) 0xbd, (byte) 0xd0, (byte) 0xca, (byte) 0xbc, (byte) 0xd8, (byte) 0x6a,
-            (byte) 0xe1, (byte) 0xfe, (byte) 0xda, (byte) 0xc4, (byte) 0xd8, (byte) 0x62,
-            (byte) 0x71, (byte) 0x20, (byte) 0xa3, (byte) 0xd3, (byte) 0x06, (byte) 0x11,
-            (byte) 0xa9, (byte) 0x53, (byte) 0x7a, (byte) 0x44, (byte) 0x89, (byte) 0x3d,
-            (byte) 0x28, (byte) 0x5e, (byte) 0x7d, (byte) 0xf0, (byte) 0x60, (byte) 0xeb,
-            (byte) 0xb5, (byte) 0xdf, (byte) 0xed, (byte) 0x4f, (byte) 0x6d, (byte) 0x05,
-            (byte) 0x59, (byte) 0x06, (byte) 0xb0, (byte) 0x62, (byte) 0x50, (byte) 0x1c,
-            (byte) 0xb7, (byte) 0x2c, (byte) 0x44, (byte) 0xa4, (byte) 0x49, (byte) 0xf8,
-            (byte) 0x4f, (byte) 0x4b, (byte) 0xab, (byte) 0x71, (byte) 0x5b, (byte) 0xcb,
-            (byte) 0x31, (byte) 0x10, (byte) 0x41, (byte) 0xe0, (byte) 0x1a, (byte) 0x15,
-            (byte) 0xdc, (byte) 0x4c, (byte) 0x5d, (byte) 0x4f, (byte) 0x62, (byte) 0x83,
-            (byte) 0xa4, (byte) 0x80, (byte) 0x06, (byte) 0x36, (byte) 0xba, (byte) 0xc9,
-            (byte) 0xe2, (byte) 0xa4, (byte) 0x11, (byte) 0x98, (byte) 0x6b, (byte) 0x4c,
-            (byte) 0xe9, (byte) 0x90, (byte) 0x55, (byte) 0x18, (byte) 0xde, (byte) 0xe1,
-            (byte) 0x42, (byte) 0x38, (byte) 0x28, (byte) 0xa3, (byte) 0x54, (byte) 0x56,
-            (byte) 0x31, (byte) 0xaf, (byte) 0x5a, (byte) 0xd6, (byte) 0xf0, (byte) 0x26,
-            (byte) 0xe0, (byte) 0x7a, (byte) 0xd9, (byte) 0x6c, (byte) 0x64, (byte) 0xca,
-            (byte) 0x5d, (byte) 0x6d, (byte) 0x3d, (byte) 0x9a, (byte) 0xfe, (byte) 0x36,
-            (byte) 0x93, (byte) 0x9e, (byte) 0x62, (byte) 0x94, (byte) 0xc6, (byte) 0x07,
-            (byte) 0x83, (byte) 0x96, (byte) 0xd6, (byte) 0x27, (byte) 0xa6, (byte) 0xd8
-    };
-    public static final PrivateKey CLIENT_SUITE_B_RSA3072_KEY =
-            loadPrivateKey("RSA", CLIENT_SUITE_B_RSA3072_KEY_DATA);
-
-    private static final String CLIENT_SUITE_B_ECDSA_CERT_STRING =
-            "-----BEGIN CERTIFICATE-----\n"
-                    + "MIIB9zCCAX4CFDpfSZh3AH07BEfGWuMDa7Ynz6y+MAoGCCqGSM49BAMDMF4xCzAJ\n"
-                    + "BgNVBAYTAlVTMQswCQYDVQQIDAJDQTEMMAoGA1UEBwwDTVRWMRAwDgYDVQQKDAdB\n"
-                    + "bmRyb2lkMQ4wDAYDVQQLDAVXaS1GaTESMBAGA1UEAwwJdW5pdGVzdENBMB4XDTIw\n"
-                    + "MDcyMTAyMjk1MFoXDTMwMDUzMDAyMjk1MFowYjELMAkGA1UEBhMCVVMxCzAJBgNV\n"
-                    + "BAgMAkNBMQwwCgYDVQQHDANNVFYxEDAOBgNVBAoMB0FuZHJvaWQxDjAMBgNVBAsM\n"
-                    + "BVdpLUZpMRYwFAYDVQQDDA11bml0ZXN0Q2xpZW50MHYwEAYHKoZIzj0CAQYFK4EE\n"
-                    + "ACIDYgAEhxhVJ7dcSqrto0X+dgRxtd8BWG8cWmPjBji3MIxDLfpcMDoIB84ae1Ew\n"
-                    + "gJn4YUYHrWsUDiVNihv8j7a/Ol1qcIY2ybH7tbezefLmagqA4vXEUXZXoUyL4ZNC\n"
-                    + "DWcdw6LrMAoGCCqGSM49BAMDA2cAMGQCMH4aP73HrriRUJRguiuRic+X4Cqj/7YQ\n"
-                    + "ueJmP87KF92/thhoQ9OrRo8uJITPmNDswwIwP2Q1AZCSL4BI9dYrqu07Ar+pSkXE\n"
-                    + "R7oOqGdZR+d/MvXcFSrbIaLKEoHXmQamIHLe\n"
-                    + "-----END CERTIFICATE-----\n";
-    public static final X509Certificate CLIENT_SUITE_B_ECDSA_CERT =
-            loadCertificate(CLIENT_SUITE_B_ECDSA_CERT_STRING);
-
-    private static final byte[] CLIENT_SUITE_B_ECC_KEY_DATA = new byte[]{
-            (byte) 0x30, (byte) 0x81, (byte) 0xb6, (byte) 0x02, (byte) 0x01, (byte) 0x00,
-            (byte) 0x30, (byte) 0x10, (byte) 0x06, (byte) 0x07, (byte) 0x2a, (byte) 0x86,
-            (byte) 0x48, (byte) 0xce, (byte) 0x3d, (byte) 0x02, (byte) 0x01, (byte) 0x06,
-            (byte) 0x05, (byte) 0x2b, (byte) 0x81, (byte) 0x04, (byte) 0x00, (byte) 0x22,
-            (byte) 0x04, (byte) 0x81, (byte) 0x9e, (byte) 0x30, (byte) 0x81, (byte) 0x9b,
-            (byte) 0x02, (byte) 0x01, (byte) 0x01, (byte) 0x04, (byte) 0x30, (byte) 0xea,
-            (byte) 0x6c, (byte) 0x4b, (byte) 0x6d, (byte) 0x43, (byte) 0xf9, (byte) 0x6c,
-            (byte) 0x91, (byte) 0xdc, (byte) 0x2d, (byte) 0x6e, (byte) 0x87, (byte) 0x4f,
-            (byte) 0x0a, (byte) 0x0b, (byte) 0x97, (byte) 0x25, (byte) 0x1c, (byte) 0x79,
-            (byte) 0xa2, (byte) 0x07, (byte) 0xdc, (byte) 0x94, (byte) 0xc2, (byte) 0xee,
-            (byte) 0x64, (byte) 0x51, (byte) 0x6d, (byte) 0x4e, (byte) 0x35, (byte) 0x1c,
-            (byte) 0x22, (byte) 0x2f, (byte) 0xc0, (byte) 0xea, (byte) 0x09, (byte) 0x47,
-            (byte) 0x3e, (byte) 0xb9, (byte) 0xb6, (byte) 0xb8, (byte) 0x83, (byte) 0x9e,
-            (byte) 0xed, (byte) 0x59, (byte) 0xe5, (byte) 0xe7, (byte) 0x0f, (byte) 0xa1,
-            (byte) 0x64, (byte) 0x03, (byte) 0x62, (byte) 0x00, (byte) 0x04, (byte) 0x87,
-            (byte) 0x18, (byte) 0x55, (byte) 0x27, (byte) 0xb7, (byte) 0x5c, (byte) 0x4a,
-            (byte) 0xaa, (byte) 0xed, (byte) 0xa3, (byte) 0x45, (byte) 0xfe, (byte) 0x76,
-            (byte) 0x04, (byte) 0x71, (byte) 0xb5, (byte) 0xdf, (byte) 0x01, (byte) 0x58,
-            (byte) 0x6f, (byte) 0x1c, (byte) 0x5a, (byte) 0x63, (byte) 0xe3, (byte) 0x06,
-            (byte) 0x38, (byte) 0xb7, (byte) 0x30, (byte) 0x8c, (byte) 0x43, (byte) 0x2d,
-            (byte) 0xfa, (byte) 0x5c, (byte) 0x30, (byte) 0x3a, (byte) 0x08, (byte) 0x07,
-            (byte) 0xce, (byte) 0x1a, (byte) 0x7b, (byte) 0x51, (byte) 0x30, (byte) 0x80,
-            (byte) 0x99, (byte) 0xf8, (byte) 0x61, (byte) 0x46, (byte) 0x07, (byte) 0xad,
-            (byte) 0x6b, (byte) 0x14, (byte) 0x0e, (byte) 0x25, (byte) 0x4d, (byte) 0x8a,
-            (byte) 0x1b, (byte) 0xfc, (byte) 0x8f, (byte) 0xb6, (byte) 0xbf, (byte) 0x3a,
-            (byte) 0x5d, (byte) 0x6a, (byte) 0x70, (byte) 0x86, (byte) 0x36, (byte) 0xc9,
-            (byte) 0xb1, (byte) 0xfb, (byte) 0xb5, (byte) 0xb7, (byte) 0xb3, (byte) 0x79,
-            (byte) 0xf2, (byte) 0xe6, (byte) 0x6a, (byte) 0x0a, (byte) 0x80, (byte) 0xe2,
-            (byte) 0xf5, (byte) 0xc4, (byte) 0x51, (byte) 0x76, (byte) 0x57, (byte) 0xa1,
-            (byte) 0x4c, (byte) 0x8b, (byte) 0xe1, (byte) 0x93, (byte) 0x42, (byte) 0x0d,
-            (byte) 0x67, (byte) 0x1d, (byte) 0xc3, (byte) 0xa2, (byte) 0xeb
-    };
-    public static final PrivateKey CLIENT_SUITE_B_ECC_KEY =
-            loadPrivateKey("EC", CLIENT_SUITE_B_ECC_KEY_DATA);
-
-    private static X509Certificate loadCertificate(String blob) {
-        try {
-            final CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
-            InputStream stream = new ByteArrayInputStream(blob.getBytes(StandardCharsets.UTF_8));
-
-            return (X509Certificate) certFactory.generateCertificate(stream);
-        } catch (Exception e) {
-            e.printStackTrace();
-            return null;
-        }
-    }
-
-    private static PrivateKey loadPrivateKey(String algorithm, byte[] fakeKey) {
-        try {
-            KeyFactory kf = KeyFactory.getInstance(algorithm);
-            return kf.generatePrivate(new PKCS8EncodedKeySpec(fakeKey));
-        } catch (InvalidKeySpecException | NoSuchAlgorithmException e) {
-            return null;
-        }
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/ParcelUtilTest.java b/wifi/tests/src/android/net/wifi/ParcelUtilTest.java
deleted file mode 100644
index 917b1df..0000000
--- a/wifi/tests/src/android/net/wifi/ParcelUtilTest.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package android.net.wifi;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.security.PrivateKey;
-import java.security.cert.X509Certificate;
-
-/**
- * Unit tests for {@link android.net.wifi.ParcelUtil}.
- */
-@SmallTest
-public class ParcelUtilTest {
-    private Parcel mParcel;
-
-    @Before
-    public void setUp() throws Exception {
-        mParcel = Parcel.obtain();
-    }
-
-    @Test
-    public void readWriteNullPrivateKey() throws Exception {
-        ParcelUtil.writePrivateKey(mParcel, null);
-
-        mParcel.setDataPosition(0);    // Rewind data position back to the beginning for read.
-        PrivateKey readKey = ParcelUtil.readPrivateKey(mParcel);
-        assertNull(readKey);
-    }
-
-    @Test
-    public void readWriteValidPrivateKey() throws Exception {
-        PrivateKey writeKey = FakeKeys.RSA_KEY1;
-        ParcelUtil.writePrivateKey(mParcel, writeKey);
-
-        mParcel.setDataPosition(0);    // Rewind data position back to the beginning for read.
-        PrivateKey readKey = ParcelUtil.readPrivateKey(mParcel);
-        assertNotNull(readKey);
-        assertEquals(writeKey.getAlgorithm(), readKey.getAlgorithm());
-        assertArrayEquals(writeKey.getEncoded(), readKey.getEncoded());
-    }
-
-    @Test
-    public void readWriteNullCertificate() throws Exception {
-        ParcelUtil.writeCertificate(mParcel, null);
-
-        mParcel.setDataPosition(0);    // Rewind data position back to the beginning for read.
-        X509Certificate readCert = ParcelUtil.readCertificate(mParcel);
-        assertNull(readCert);
-    }
-
-    @Test
-    public void readWriteValidCertificate() throws Exception {
-        X509Certificate writeCert = FakeKeys.CA_CERT1;
-        ParcelUtil.writeCertificate(mParcel, writeCert);
-
-        mParcel.setDataPosition(0);    // Rewind data position back to the beginning for read.
-        X509Certificate readCert = ParcelUtil.readCertificate(mParcel);
-        assertNotNull(readCert);
-        assertArrayEquals(writeCert.getEncoded(), readCert.getEncoded());
-    }
-
-    @Test
-    public void readWriteNullCertificates() throws Exception {
-        ParcelUtil.writeCertificates(mParcel, null);
-
-        mParcel.setDataPosition(0);    // Rewind data position back to the beginning for read.
-        X509Certificate[] readCerts = ParcelUtil.readCertificates(mParcel);
-        assertNull(readCerts);
-    }
-
-    @Test
-    public void readWriteValidCertificates() throws Exception {
-        X509Certificate[] writeCerts = new X509Certificate[2];
-        writeCerts[0] = FakeKeys.CA_CERT0;
-        writeCerts[1] = FakeKeys.CA_CERT1;
-        ParcelUtil.writeCertificates(mParcel, writeCerts);
-
-        mParcel.setDataPosition(0);    // Rewind data position back to the beginning for read.
-        X509Certificate[] readCerts = ParcelUtil.readCertificates(mParcel);
-        assertNotNull(readCerts);
-        assertEquals(writeCerts.length, readCerts.length);
-        for (int i = 0; i < writeCerts.length; i++) {
-            assertNotNull(readCerts[i]);
-            assertArrayEquals(writeCerts[i].getEncoded(), readCerts[i].getEncoded());
-        }
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/ScanResultTest.java b/wifi/tests/src/android/net/wifi/ScanResultTest.java
deleted file mode 100644
index f1ec5e8..0000000
--- a/wifi/tests/src/android/net/wifi/ScanResultTest.java
+++ /dev/null
@@ -1,301 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.mockito.Mockito.validateMockitoUsage;
-
-import android.net.wifi.ScanResult.InformationElement;
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.MockitoAnnotations;
-
-/**
- * Unit tests for {@link android.net.wifi.WifiScanner}.
- */
-@SmallTest
-public class ScanResultTest {
-    public static final String TEST_SSID = "\"test_ssid\"";
-    public static final String TEST_BSSID = "04:ac:fe:45:34:10";
-    public static final String TEST_CAPS = "CCMP";
-    public static final int TEST_LEVEL = -56;
-    public static final int TEST_FREQUENCY = 2412;
-    public static final long TEST_TSF = 04660l;
-    public static final @WifiAnnotations.WifiStandard int TEST_WIFI_STANDARD =
-            ScanResult.WIFI_STANDARD_11AC;
-
-    /**
-     * Frequency to channel map. This include some frequencies used outside the US.
-     * Representing it using a vector (instead of map) for simplification.
-     */
-    private static final int[] FREQUENCY_TO_CHANNEL_MAP = {
-            2412, WifiScanner.WIFI_BAND_24_GHZ, 1,
-            2417, WifiScanner.WIFI_BAND_24_GHZ, 2,
-            2422, WifiScanner.WIFI_BAND_24_GHZ, 3,
-            2427, WifiScanner.WIFI_BAND_24_GHZ, 4,
-            2432, WifiScanner.WIFI_BAND_24_GHZ, 5,
-            2437, WifiScanner.WIFI_BAND_24_GHZ, 6,
-            2442, WifiScanner.WIFI_BAND_24_GHZ, 7,
-            2447, WifiScanner.WIFI_BAND_24_GHZ, 8,
-            2452, WifiScanner.WIFI_BAND_24_GHZ, 9,
-            2457, WifiScanner.WIFI_BAND_24_GHZ, 10,
-            2462, WifiScanner.WIFI_BAND_24_GHZ, 11,
-            /* 12, 13 are only legitimate outside the US. */
-            2467, WifiScanner.WIFI_BAND_24_GHZ, 12,
-            2472, WifiScanner.WIFI_BAND_24_GHZ, 13,
-            /* 14 is for Japan, DSSS and CCK only. */
-            2484, WifiScanner.WIFI_BAND_24_GHZ, 14,
-            /* 34 valid in Japan. */
-            5170, WifiScanner.WIFI_BAND_5_GHZ, 34,
-            5180, WifiScanner.WIFI_BAND_5_GHZ, 36,
-            5190, WifiScanner.WIFI_BAND_5_GHZ, 38,
-            5200, WifiScanner.WIFI_BAND_5_GHZ, 40,
-            5210, WifiScanner.WIFI_BAND_5_GHZ, 42,
-            5220, WifiScanner.WIFI_BAND_5_GHZ, 44,
-            5230, WifiScanner.WIFI_BAND_5_GHZ, 46,
-            5240, WifiScanner.WIFI_BAND_5_GHZ, 48,
-            5260, WifiScanner.WIFI_BAND_5_GHZ, 52,
-            5280, WifiScanner.WIFI_BAND_5_GHZ, 56,
-            5300, WifiScanner.WIFI_BAND_5_GHZ, 60,
-            5320, WifiScanner.WIFI_BAND_5_GHZ, 64,
-            5500, WifiScanner.WIFI_BAND_5_GHZ, 100,
-            5520, WifiScanner.WIFI_BAND_5_GHZ, 104,
-            5540, WifiScanner.WIFI_BAND_5_GHZ, 108,
-            5560, WifiScanner.WIFI_BAND_5_GHZ, 112,
-            5580, WifiScanner.WIFI_BAND_5_GHZ, 116,
-            /* 120, 124, 128 valid in Europe/Japan. */
-            5600, WifiScanner.WIFI_BAND_5_GHZ, 120,
-            5620, WifiScanner.WIFI_BAND_5_GHZ, 124,
-            5640, WifiScanner.WIFI_BAND_5_GHZ, 128,
-            /* 132+ valid in US. */
-            5660, WifiScanner.WIFI_BAND_5_GHZ, 132,
-            5680, WifiScanner.WIFI_BAND_5_GHZ, 136,
-            5700, WifiScanner.WIFI_BAND_5_GHZ, 140,
-            /* 144 is supported by a subset of WiFi chips. */
-            5720, WifiScanner.WIFI_BAND_5_GHZ, 144,
-            5745, WifiScanner.WIFI_BAND_5_GHZ, 149,
-            5765, WifiScanner.WIFI_BAND_5_GHZ, 153,
-            5785, WifiScanner.WIFI_BAND_5_GHZ, 157,
-            5805, WifiScanner.WIFI_BAND_5_GHZ, 161,
-            5825, WifiScanner.WIFI_BAND_5_GHZ, 165,
-            5845, WifiScanner.WIFI_BAND_5_GHZ, 169,
-            5865, WifiScanner.WIFI_BAND_5_GHZ, 173,
-            /* Now some 6GHz channels */
-            5955, WifiScanner.WIFI_BAND_6_GHZ, 1,
-            5935, WifiScanner.WIFI_BAND_6_GHZ, 2,
-            5970, WifiScanner.WIFI_BAND_6_GHZ, 4,
-            6110, WifiScanner.WIFI_BAND_6_GHZ, 32
-    };
-
-    /**
-     * Setup before tests.
-     */
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-    }
-
-    /**
-     * Clean up after tests.
-     */
-    @After
-    public void cleanup() {
-        validateMockitoUsage();
-    }
-
-    /**
-     * Verify parcel read/write for ScanResult.
-     */
-    @Test
-    public void verifyScanResultParcelWithoutRadioChainInfo() throws Exception {
-        ScanResult writeScanResult = createScanResult();
-        ScanResult readScanResult = parcelReadWrite(writeScanResult);
-        assertScanResultEquals(writeScanResult, readScanResult);
-    }
-
-    /**
-     * Verify parcel read/write for ScanResult.
-     */
-    @Test
-    public void verifyScanResultParcelWithZeroRadioChainInfo() throws Exception {
-        ScanResult writeScanResult = createScanResult();
-        writeScanResult.radioChainInfos = new ScanResult.RadioChainInfo[0];
-        ScanResult readScanResult = parcelReadWrite(writeScanResult);
-        assertNull(readScanResult.radioChainInfos);
-    }
-
-    /**
-     * Verify parcel read/write for ScanResult.
-     */
-    @Test
-    public void verifyScanResultParcelWithRadioChainInfo() throws Exception {
-        ScanResult writeScanResult = createScanResult();
-        writeScanResult.radioChainInfos = new ScanResult.RadioChainInfo[2];
-        writeScanResult.radioChainInfos[0] = new ScanResult.RadioChainInfo();
-        writeScanResult.radioChainInfos[0].id = 0;
-        writeScanResult.radioChainInfos[0].level = -45;
-        writeScanResult.radioChainInfos[1] = new ScanResult.RadioChainInfo();
-        writeScanResult.radioChainInfos[1].id = 1;
-        writeScanResult.radioChainInfos[1].level = -54;
-        ScanResult readScanResult = parcelReadWrite(writeScanResult);
-        assertScanResultEquals(writeScanResult, readScanResult);
-    }
-
-    /**
-     * Verify copy constructor for ScanResult.
-     */
-    @Test
-    public void verifyScanResultCopyWithoutRadioChainInfo() throws Exception {
-        ScanResult scanResult = createScanResult();
-        ScanResult copyScanResult = new ScanResult(scanResult);
-        assertScanResultEquals(scanResult, copyScanResult);
-    }
-
-    /**
-     * Verify copy constructor for ScanResult.
-     */
-    @Test
-    public void verifyScanResultCopyWithRadioChainInfo() throws Exception {
-        ScanResult scanResult = createScanResult();
-        scanResult.radioChainInfos = new ScanResult.RadioChainInfo[2];
-        scanResult.radioChainInfos[0] = new ScanResult.RadioChainInfo();
-        scanResult.radioChainInfos[0].id = 0;
-        scanResult.radioChainInfos[0].level = -45;
-        scanResult.radioChainInfos[1] = new ScanResult.RadioChainInfo();
-        scanResult.radioChainInfos[1].id = 1;
-        scanResult.radioChainInfos[1].level = -54;
-        ScanResult copyScanResult = new ScanResult(scanResult);
-        assertScanResultEquals(scanResult, copyScanResult);
-    }
-
-    /**
-     * Verify parcel read/write for ScanResult with Information Element
-     */
-    @Test
-    public void verifyScanResultParcelWithInformationElement() throws Exception {
-        ScanResult writeScanResult = createScanResult();
-        writeScanResult.informationElements = new ScanResult.InformationElement[2];
-        writeScanResult.informationElements[0] = new ScanResult.InformationElement();
-        writeScanResult.informationElements[0].id = InformationElement.EID_HT_OPERATION;
-        writeScanResult.informationElements[0].idExt = 0;
-        writeScanResult.informationElements[0].bytes = new byte[]{0x11, 0x22, 0x33};
-        writeScanResult.informationElements[1] = new ScanResult.InformationElement();
-        writeScanResult.informationElements[1].id = InformationElement.EID_EXTENSION_PRESENT;
-        writeScanResult.informationElements[1].idExt = InformationElement.EID_EXT_HE_OPERATION;
-        writeScanResult.informationElements[1].bytes = new byte[]{0x44, 0x55, 0x66};
-        ScanResult readScanResult = new ScanResult(writeScanResult);
-        assertScanResultEquals(writeScanResult, readScanResult);
-    }
-
-    /**
-     * Verify toString for ScanResult.
-     */
-    @Test
-    public void verifyScanResultToStringWithoutRadioChainInfo() throws Exception {
-        ScanResult scanResult = createScanResult();
-        assertEquals("SSID: \"test_ssid\", BSSID: 04:ac:fe:45:34:10, capabilities: CCMP, "
-                + "level: -56, frequency: 2412, timestamp: 2480, "
-                + "distance: 0(cm), distanceSd: 0(cm), "
-                + "passpoint: no, ChannelBandwidth: 0, centerFreq0: 0, centerFreq1: 0, "
-                + "standard: 11ac, "
-                + "80211mcResponder: is not supported, "
-                + "Radio Chain Infos: null", scanResult.toString());
-    }
-
-    /**
-     * Verify toString for ScanResult.
-     */
-    @Test
-    public void verifyScanResultToStringWithRadioChainInfo() throws Exception {
-        ScanResult scanResult = createScanResult();
-        scanResult.radioChainInfos = new ScanResult.RadioChainInfo[2];
-        scanResult.radioChainInfos[0] = new ScanResult.RadioChainInfo();
-        scanResult.radioChainInfos[0].id = 0;
-        scanResult.radioChainInfos[0].level = -45;
-        scanResult.radioChainInfos[1] = new ScanResult.RadioChainInfo();
-        scanResult.radioChainInfos[1].id = 1;
-        scanResult.radioChainInfos[1].level = -54;
-        assertEquals("SSID: \"test_ssid\", BSSID: 04:ac:fe:45:34:10, capabilities: CCMP, "
-                + "level: -56, frequency: 2412, timestamp: 2480, distance: 0(cm), "
-                + "distanceSd: 0(cm), "
-                + "passpoint: no, ChannelBandwidth: 0, centerFreq0: 0, centerFreq1: 0, "
-                + "standard: 11ac, "
-                + "80211mcResponder: is not supported, "
-                + "Radio Chain Infos: [RadioChainInfo: id=0, level=-45, "
-                + "RadioChainInfo: id=1, level=-54]", scanResult.toString());
-    }
-
-    /**
-     * verify frequency to channel conversion for all possible frequencies.
-     */
-    @Test
-    public void convertFrequencyToChannel() throws Exception {
-        for (int i = 0; i < FREQUENCY_TO_CHANNEL_MAP.length; i += 3) {
-            assertEquals(FREQUENCY_TO_CHANNEL_MAP[i + 2],
-                    ScanResult.convertFrequencyMhzToChannel(FREQUENCY_TO_CHANNEL_MAP[i]));
-        }
-    }
-
-    /**
-     * Verify frequency to channel conversion failed for an invalid frequency.
-     */
-    @Test
-    public void convertFrequencyToChannelWithInvalidFreq() throws Exception {
-        assertEquals(-1, ScanResult.convertFrequencyMhzToChannel(8000));
-    }
-
-    /**
-     * Write the provided {@link ScanResult} to a parcel and deserialize it.
-     */
-    private static ScanResult parcelReadWrite(ScanResult writeResult) throws Exception {
-        Parcel parcel = Parcel.obtain();
-        writeResult.writeToParcel(parcel, 0);
-        parcel.setDataPosition(0);    // Rewind data position back to the beginning for read.
-        return ScanResult.CREATOR.createFromParcel(parcel);
-    }
-
-    private static ScanResult createScanResult() {
-        ScanResult result = new ScanResult();
-        result.wifiSsid = WifiSsid.createFromAsciiEncoded(TEST_SSID);
-        result.BSSID = TEST_BSSID;
-        result.capabilities = TEST_CAPS;
-        result.level = TEST_LEVEL;
-        result.frequency = TEST_FREQUENCY;
-        result.timestamp = TEST_TSF;
-        result.setWifiStandard(TEST_WIFI_STANDARD);
-        return result;
-    }
-
-    private static void assertScanResultEquals(ScanResult expected, ScanResult actual) {
-        assertEquals(expected.SSID, actual.SSID);
-        assertEquals(expected.BSSID, actual.BSSID);
-        assertEquals(expected.capabilities, actual.capabilities);
-        assertEquals(expected.level, actual.level);
-        assertEquals(expected.frequency, actual.frequency);
-        assertEquals(expected.timestamp, actual.timestamp);
-        assertEquals(expected.getWifiStandard(), actual.getWifiStandard());
-        assertArrayEquals(expected.radioChainInfos, actual.radioChainInfos);
-        assertArrayEquals(expected.informationElements, actual.informationElements);
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/SoftApCapabilityTest.java b/wifi/tests/src/android/net/wifi/SoftApCapabilityTest.java
deleted file mode 100644
index 73b501a..0000000
--- a/wifi/tests/src/android/net/wifi/SoftApCapabilityTest.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import android.os.Parcel;
-
-import static org.junit.Assert.assertEquals;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-/**
- * Unit tests for {@link android.net.wifi.SoftApCapability}.
- */
-@SmallTest
-public class SoftApCapabilityTest {
-
-    /**
-     * Verifies copy constructor.
-     */
-    @Test
-    public void testCopyOperator() throws Exception {
-        long testSoftApFeature = SoftApCapability.SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT
-                | SoftApCapability.SOFTAP_FEATURE_ACS_OFFLOAD;
-        SoftApCapability capability = new SoftApCapability(testSoftApFeature);
-        capability.setMaxSupportedClients(10);
-
-        SoftApCapability copiedCapability = new SoftApCapability(capability);
-
-        assertEquals(capability, copiedCapability);
-        assertEquals(capability.hashCode(), copiedCapability.hashCode());
-    }
-
-    /**
-     * Verifies parcel serialization/deserialization.
-     */
-    @Test
-    public void testParcelOperation() throws Exception {
-        long testSoftApFeature = SoftApCapability.SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT
-                | SoftApCapability.SOFTAP_FEATURE_ACS_OFFLOAD;
-        SoftApCapability capability = new SoftApCapability(testSoftApFeature);
-        capability.setMaxSupportedClients(10);
-
-        Parcel parcelW = Parcel.obtain();
-        capability.writeToParcel(parcelW, 0);
-        byte[] bytes = parcelW.marshall();
-        parcelW.recycle();
-
-        Parcel parcelR = Parcel.obtain();
-        parcelR.unmarshall(bytes, 0, bytes.length);
-        parcelR.setDataPosition(0);
-        SoftApCapability fromParcel = SoftApCapability.CREATOR.createFromParcel(parcelR);
-
-        assertEquals(capability, fromParcel);
-        assertEquals(capability.hashCode(), fromParcel.hashCode());
-    }
-
-}
diff --git a/wifi/non-updatable/tests/src/android/net/wifi/SoftApConfToXmlMigrationUtilTest.java b/wifi/tests/src/android/net/wifi/SoftApConfToXmlMigrationUtilTest.java
similarity index 100%
rename from wifi/non-updatable/tests/src/android/net/wifi/SoftApConfToXmlMigrationUtilTest.java
rename to wifi/tests/src/android/net/wifi/SoftApConfToXmlMigrationUtilTest.java
diff --git a/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java b/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java
deleted file mode 100644
index d78c942..0000000
--- a/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java
+++ /dev/null
@@ -1,339 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.junit.Assert.assertNull;
-
-import android.net.MacAddress;
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Random;
-
-@SmallTest
-public class SoftApConfigurationTest {
-    private static final String TEST_CHAR_SET_AS_STRING = "abcdefghijklmnopqrstuvwxyz0123456789";
-
-    private SoftApConfiguration parcelUnparcel(SoftApConfiguration configIn) {
-        Parcel parcel = Parcel.obtain();
-        parcel.writeParcelable(configIn, 0);
-        parcel.setDataPosition(0);
-        SoftApConfiguration configOut =
-                parcel.readParcelable(SoftApConfiguration.class.getClassLoader());
-        parcel.recycle();
-        return configOut;
-    }
-
-    /**
-     * Helper method to generate random string.
-     *
-     * Note: this method has limited use as a random string generator.
-     * The characters used in this method do no not cover all valid inputs.
-     * @param length number of characters to generate for the string
-     * @return String generated string of random characters
-     */
-    private String generateRandomString(int length) {
-        Random random = new Random();
-        StringBuilder stringBuilder = new StringBuilder(length);
-        int index = -1;
-        while (stringBuilder.length() < length) {
-            index = random.nextInt(TEST_CHAR_SET_AS_STRING.length());
-            stringBuilder.append(TEST_CHAR_SET_AS_STRING.charAt(index));
-        }
-        return stringBuilder.toString();
-    }
-
-    @Test
-    public void testBasicSettings() {
-        SoftApConfiguration original = new SoftApConfiguration.Builder()
-                .setSsid("ssid")
-                .setBssid(MacAddress.fromString("11:22:33:44:55:66"))
-                .build();
-        assertThat(original.getSsid()).isEqualTo("ssid");
-        assertThat(original.getBssid()).isEqualTo(MacAddress.fromString("11:22:33:44:55:66"));
-        assertThat(original.getPassphrase()).isNull();
-        assertThat(original.getSecurityType()).isEqualTo(SoftApConfiguration.SECURITY_TYPE_OPEN);
-        assertThat(original.getBand()).isEqualTo(SoftApConfiguration.BAND_2GHZ);
-        assertThat(original.getChannel()).isEqualTo(0);
-        assertThat(original.isHiddenSsid()).isEqualTo(false);
-        assertThat(original.getMaxNumberOfClients()).isEqualTo(0);
-
-        SoftApConfiguration unparceled = parcelUnparcel(original);
-        assertThat(unparceled).isNotSameAs(original);
-        assertThat(unparceled).isEqualTo(original);
-        assertThat(unparceled.hashCode()).isEqualTo(original.hashCode());
-
-        SoftApConfiguration copy = new SoftApConfiguration.Builder(original).build();
-        assertThat(copy).isNotSameAs(original);
-        assertThat(copy).isEqualTo(original);
-        assertThat(copy.hashCode()).isEqualTo(original.hashCode());
-    }
-
-    @Test
-    public void testWpa2() {
-        SoftApConfiguration original = new SoftApConfiguration.Builder()
-                .setPassphrase("secretsecret", SoftApConfiguration.SECURITY_TYPE_WPA2_PSK)
-                .build();
-        assertThat(original.getPassphrase()).isEqualTo("secretsecret");
-        assertThat(original.getSecurityType()).isEqualTo(
-                SoftApConfiguration.SECURITY_TYPE_WPA2_PSK);
-        assertThat(original.getBand()).isEqualTo(SoftApConfiguration.BAND_2GHZ);
-        assertThat(original.getChannel()).isEqualTo(0);
-        assertThat(original.isHiddenSsid()).isEqualTo(false);
-        assertThat(original.getMaxNumberOfClients()).isEqualTo(0);
-
-        SoftApConfiguration unparceled = parcelUnparcel(original);
-        assertThat(unparceled).isNotSameAs(original);
-        assertThat(unparceled).isEqualTo(original);
-        assertThat(unparceled.hashCode()).isEqualTo(original.hashCode());
-
-        SoftApConfiguration copy = new SoftApConfiguration.Builder(original).build();
-        assertThat(copy).isNotSameAs(original);
-        assertThat(copy).isEqualTo(original);
-        assertThat(copy.hashCode()).isEqualTo(original.hashCode());
-    }
-
-    @Test
-    public void testWpa2WithAllFieldCustomized() {
-        List<MacAddress> testBlockedClientList = new ArrayList<>();
-        List<MacAddress> testAllowedClientList = new ArrayList<>();
-        testBlockedClientList.add(MacAddress.fromString("11:22:33:44:55:66"));
-        testAllowedClientList.add(MacAddress.fromString("aa:bb:cc:dd:ee:ff"));
-        SoftApConfiguration original = new SoftApConfiguration.Builder()
-                .setPassphrase("secretsecret", SoftApConfiguration.SECURITY_TYPE_WPA2_PSK)
-                .setChannel(149, SoftApConfiguration.BAND_5GHZ)
-                .setHiddenSsid(true)
-                .setMaxNumberOfClients(10)
-                .setAutoShutdownEnabled(true)
-                .setShutdownTimeoutMillis(500000)
-                .setClientControlByUserEnabled(true)
-                .setBlockedClientList(testBlockedClientList)
-                .setAllowedClientList(testAllowedClientList)
-                .build();
-        assertThat(original.getPassphrase()).isEqualTo("secretsecret");
-        assertThat(original.getSecurityType()).isEqualTo(
-                SoftApConfiguration.SECURITY_TYPE_WPA2_PSK);
-        assertThat(original.getBand()).isEqualTo(SoftApConfiguration.BAND_5GHZ);
-        assertThat(original.getChannel()).isEqualTo(149);
-        assertThat(original.isHiddenSsid()).isEqualTo(true);
-        assertThat(original.getMaxNumberOfClients()).isEqualTo(10);
-        assertThat(original.isAutoShutdownEnabled()).isEqualTo(true);
-        assertThat(original.getShutdownTimeoutMillis()).isEqualTo(500000);
-        assertThat(original.isClientControlByUserEnabled()).isEqualTo(true);
-        assertThat(original.getBlockedClientList()).isEqualTo(testBlockedClientList);
-        assertThat(original.getAllowedClientList()).isEqualTo(testAllowedClientList);
-
-        SoftApConfiguration unparceled = parcelUnparcel(original);
-        assertThat(unparceled).isNotSameAs(original);
-        assertThat(unparceled).isEqualTo(original);
-        assertThat(unparceled.hashCode()).isEqualTo(original.hashCode());
-
-        SoftApConfiguration copy = new SoftApConfiguration.Builder(original).build();
-        assertThat(copy).isNotSameAs(original);
-        assertThat(copy).isEqualTo(original);
-        assertThat(copy.hashCode()).isEqualTo(original.hashCode());
-    }
-
-    @Test
-    public void testWpa3Sae() {
-        SoftApConfiguration original = new SoftApConfiguration.Builder()
-                .setPassphrase("secretsecret", SoftApConfiguration.SECURITY_TYPE_WPA3_SAE)
-                .setChannel(149, SoftApConfiguration.BAND_5GHZ)
-                .setHiddenSsid(true)
-                .build();
-        assertThat(original.getPassphrase()).isEqualTo("secretsecret");
-        assertThat(original.getSecurityType()).isEqualTo(
-                SoftApConfiguration.SECURITY_TYPE_WPA3_SAE);
-        assertThat(original.getBand()).isEqualTo(SoftApConfiguration.BAND_5GHZ);
-        assertThat(original.getChannel()).isEqualTo(149);
-        assertThat(original.isHiddenSsid()).isEqualTo(true);
-
-
-        SoftApConfiguration unparceled = parcelUnparcel(original);
-        assertThat(unparceled).isNotSameAs(original);
-        assertThat(unparceled).isEqualTo(original);
-        assertThat(unparceled.hashCode()).isEqualTo(original.hashCode());
-
-        SoftApConfiguration copy = new SoftApConfiguration.Builder(original).build();
-        assertThat(copy).isNotSameAs(original);
-        assertThat(copy).isEqualTo(original);
-        assertThat(copy.hashCode()).isEqualTo(original.hashCode());
-    }
-
-    @Test
-    public void testWpa3SaeTransition() {
-        SoftApConfiguration original = new SoftApConfiguration.Builder()
-                .setPassphrase("secretsecret",
-                        SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION)
-                .setChannel(149, SoftApConfiguration.BAND_5GHZ)
-                .setHiddenSsid(true)
-                .build();
-        assertThat(original.getSecurityType()).isEqualTo(
-                SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION);
-        assertThat(original.getPassphrase()).isEqualTo("secretsecret");
-        assertThat(original.getBand()).isEqualTo(SoftApConfiguration.BAND_5GHZ);
-        assertThat(original.getChannel()).isEqualTo(149);
-        assertThat(original.isHiddenSsid()).isEqualTo(true);
-
-
-        SoftApConfiguration unparceled = parcelUnparcel(original);
-        assertThat(unparceled).isNotSameAs(original);
-        assertThat(unparceled).isEqualTo(original);
-        assertThat(unparceled.hashCode()).isEqualTo(original.hashCode());
-
-        SoftApConfiguration copy = new SoftApConfiguration.Builder(original).build();
-        assertThat(copy).isNotSameAs(original);
-        assertThat(copy).isEqualTo(original);
-        assertThat(copy.hashCode()).isEqualTo(original.hashCode());
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testInvalidShortPasswordLengthForWpa2() {
-        SoftApConfiguration original = new SoftApConfiguration.Builder()
-                .setPassphrase(generateRandomString(SoftApConfiguration.PSK_MIN_LEN - 1),
-                        SoftApConfiguration.SECURITY_TYPE_WPA2_PSK)
-                .setChannel(149, SoftApConfiguration.BAND_5GHZ)
-                .setHiddenSsid(true)
-                .build();
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testInvalidLongPasswordLengthForWpa2() {
-        SoftApConfiguration original = new SoftApConfiguration.Builder()
-                .setPassphrase(generateRandomString(SoftApConfiguration.PSK_MAX_LEN + 1),
-                        SoftApConfiguration.SECURITY_TYPE_WPA2_PSK)
-                .setChannel(149, SoftApConfiguration.BAND_5GHZ)
-                .setHiddenSsid(true)
-                .build();
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testInvalidShortPasswordLengthForWpa3SaeTransition() {
-        SoftApConfiguration original = new SoftApConfiguration.Builder()
-                .setPassphrase(generateRandomString(SoftApConfiguration.PSK_MIN_LEN - 1),
-                        SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION)
-                .setChannel(149, SoftApConfiguration.BAND_5GHZ)
-                .setHiddenSsid(true)
-                .build();
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testInvalidLongPasswordLengthForWpa3SaeTransition() {
-        SoftApConfiguration original = new SoftApConfiguration.Builder()
-                .setPassphrase(generateRandomString(SoftApConfiguration.PSK_MAX_LEN + 1),
-                        SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION)
-                .setChannel(149, SoftApConfiguration.BAND_5GHZ)
-                .setHiddenSsid(true)
-                .build();
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testInvalieShutdownTimeoutMillis() {
-        SoftApConfiguration original = new SoftApConfiguration.Builder()
-                .setShutdownTimeoutMillis(-1)
-                .build();
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testSetClientListExceptionWhenExistMacAddressInBothList() {
-        final MacAddress testMacAddress_1 = MacAddress.fromString("22:33:44:55:66:77");
-        final MacAddress testMacAddress_2 = MacAddress.fromString("aa:bb:cc:dd:ee:ff");
-        ArrayList<MacAddress> testAllowedClientList = new ArrayList<>();
-        testAllowedClientList.add(testMacAddress_1);
-        testAllowedClientList.add(testMacAddress_2);
-        ArrayList<MacAddress> testBlockedClientList = new ArrayList<>();
-        testBlockedClientList.add(testMacAddress_1);
-        SoftApConfiguration.Builder configBuilder = new SoftApConfiguration.Builder();
-        configBuilder.setBlockedClientList(testBlockedClientList)
-                .setAllowedClientList(testAllowedClientList)
-                .build();
-    }
-
-    @Test
-    public void testToWifiConfigurationWithUnsupportedParameter() {
-        SoftApConfiguration sae_config = new SoftApConfiguration.Builder()
-                .setPassphrase("secretsecret", SoftApConfiguration.SECURITY_TYPE_WPA3_SAE)
-                .build();
-
-        assertNull(sae_config.toWifiConfiguration());
-        SoftApConfiguration band_6g_config = new SoftApConfiguration.Builder()
-                .setBand(SoftApConfiguration.BAND_6GHZ)
-                .build();
-
-        assertNull(band_6g_config.toWifiConfiguration());
-    }
-
-    @Test
-    public void testToWifiConfigurationWithSupportedParameter() {
-        SoftApConfiguration softApConfig_2g = new SoftApConfiguration.Builder()
-                .setPassphrase("secretsecret",
-                        SoftApConfiguration.SECURITY_TYPE_WPA2_PSK)
-                .setChannel(11, SoftApConfiguration.BAND_2GHZ)
-                .setHiddenSsid(true)
-                .build();
-        WifiConfiguration wifiConfig_2g = softApConfig_2g.toWifiConfiguration();
-        assertThat(wifiConfig_2g.getAuthType()).isEqualTo(WifiConfiguration.KeyMgmt.WPA2_PSK);
-        assertThat(wifiConfig_2g.preSharedKey).isEqualTo("secretsecret");
-        assertThat(wifiConfig_2g.apBand).isEqualTo(WifiConfiguration.AP_BAND_2GHZ);
-        assertThat(wifiConfig_2g.apChannel).isEqualTo(11);
-        assertThat(wifiConfig_2g.hiddenSSID).isEqualTo(true);
-
-        SoftApConfiguration softApConfig_5g = new SoftApConfiguration.Builder()
-                .setPassphrase("secretsecret",
-                        SoftApConfiguration.SECURITY_TYPE_WPA2_PSK)
-                .setChannel(149, SoftApConfiguration.BAND_5GHZ)
-                .setHiddenSsid(true)
-                .build();
-        WifiConfiguration wifiConfig_5g = softApConfig_5g.toWifiConfiguration();
-        assertThat(wifiConfig_5g.getAuthType()).isEqualTo(WifiConfiguration.KeyMgmt.WPA2_PSK);
-        assertThat(wifiConfig_5g.preSharedKey).isEqualTo("secretsecret");
-        assertThat(wifiConfig_5g.apBand).isEqualTo(WifiConfiguration.AP_BAND_5GHZ);
-        assertThat(wifiConfig_5g.apChannel).isEqualTo(149);
-        assertThat(wifiConfig_5g.hiddenSSID).isEqualTo(true);
-
-        SoftApConfiguration softApConfig_2g5g = new SoftApConfiguration.Builder()
-                .setPassphrase("secretsecret",
-                        SoftApConfiguration.SECURITY_TYPE_WPA2_PSK)
-                .setBand(SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ)
-                .setHiddenSsid(true)
-                .build();
-        WifiConfiguration wifiConfig_2g5g = softApConfig_2g5g.toWifiConfiguration();
-        assertThat(wifiConfig_2g5g.getAuthType()).isEqualTo(WifiConfiguration.KeyMgmt.WPA2_PSK);
-        assertThat(wifiConfig_2g5g.preSharedKey).isEqualTo("secretsecret");
-        assertThat(wifiConfig_2g5g.apBand).isEqualTo(WifiConfiguration.AP_BAND_ANY);
-        assertThat(wifiConfig_2g5g.apChannel).isEqualTo(0);
-        assertThat(wifiConfig_2g5g.hiddenSSID).isEqualTo(true);
-
-        SoftApConfiguration softApConfig_sae_transition = new SoftApConfiguration.Builder()
-                .setPassphrase("secretsecret",
-                SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION)
-                .build();
-
-        WifiConfiguration wifiConfig_sae_transition =
-                softApConfig_sae_transition.toWifiConfiguration();
-        assertThat(wifiConfig_sae_transition.getAuthType())
-                .isEqualTo(WifiConfiguration.KeyMgmt.WPA2_PSK);
-        assertThat(wifiConfig_sae_transition.preSharedKey).isEqualTo("secretsecret");
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/SoftApInfoTest.java b/wifi/tests/src/android/net/wifi/SoftApInfoTest.java
deleted file mode 100644
index 929f3ab..0000000
--- a/wifi/tests/src/android/net/wifi/SoftApInfoTest.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import android.os.Parcel;
-
-import static org.junit.Assert.assertEquals;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-/**
- * Unit tests for {@link android.net.wifi.SoftApInfo}.
- */
-@SmallTest
-public class SoftApInfoTest {
-
-    /**
-     * Verifies copy constructor.
-     */
-    @Test
-    public void testCopyOperator() throws Exception {
-        SoftApInfo info = new SoftApInfo();
-        info.setFrequency(2412);
-        info.setBandwidth(SoftApInfo.CHANNEL_WIDTH_20MHZ);
-
-        SoftApInfo copiedInfo = new SoftApInfo(info);
-
-        assertEquals(info, copiedInfo);
-        assertEquals(info.hashCode(), copiedInfo.hashCode());
-    }
-
-    /**
-     * Verifies parcel serialization/deserialization.
-     */
-    @Test
-    public void testParcelOperation() throws Exception {
-        SoftApInfo info = new SoftApInfo();
-        info.setFrequency(2412);
-        info.setBandwidth(SoftApInfo.CHANNEL_WIDTH_20MHZ);
-
-        Parcel parcelW = Parcel.obtain();
-        info.writeToParcel(parcelW, 0);
-        byte[] bytes = parcelW.marshall();
-        parcelW.recycle();
-
-        Parcel parcelR = Parcel.obtain();
-        parcelR.unmarshall(bytes, 0, bytes.length);
-        parcelR.setDataPosition(0);
-        SoftApInfo fromParcel = SoftApInfo.CREATOR.createFromParcel(parcelR);
-
-        assertEquals(info, fromParcel);
-        assertEquals(info.hashCode(), fromParcel.hashCode());
-    }
-
-}
diff --git a/wifi/tests/src/android/net/wifi/WifiClientTest.java b/wifi/tests/src/android/net/wifi/WifiClientTest.java
deleted file mode 100644
index 7a3baf9..0000000
--- a/wifi/tests/src/android/net/wifi/WifiClientTest.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import static com.android.testutils.MiscAsserts.assertFieldCountEquals;
-import static com.android.testutils.ParcelUtils.assertParcelSane;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
-
-import android.net.MacAddress;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-/**
- * Unit tests for {@link android.net.wifi.WifiClient}.
- */
-@SmallTest
-public class WifiClientTest {
-    private static final String INTERFACE_NAME = "wlan0";
-    private static final String MAC_ADDRESS_STRING = "00:0a:95:9d:68:16";
-    private static final MacAddress MAC_ADDRESS = MacAddress.fromString(MAC_ADDRESS_STRING);
-
-    /**
-     *  Verify parcel write/read with WifiClient.
-     */
-    @Test
-    public void testWifiClientParcelWriteRead() throws Exception {
-        WifiClient writeWifiClient = new WifiClient(MAC_ADDRESS);
-
-        assertParcelSane(writeWifiClient, 1);
-    }
-
-    /**
-     *  Verify equals with WifiClient.
-     */
-    @Test
-    public void testWifiClientEquals() throws Exception {
-        WifiClient writeWifiClient = new WifiClient(MAC_ADDRESS);
-        WifiClient writeWifiClientEquals = new WifiClient(MAC_ADDRESS);
-
-        assertEquals(writeWifiClient, writeWifiClientEquals);
-        assertEquals(writeWifiClient.hashCode(), writeWifiClientEquals.hashCode());
-        assertFieldCountEquals(1, WifiClient.class);
-    }
-
-    /**
-     *  Verify not-equals with WifiClient.
-     */
-    @Test
-    public void testWifiClientNotEquals() throws Exception {
-        final MacAddress macAddressNotEquals = MacAddress.fromString("00:00:00:00:00:00");
-        WifiClient writeWifiClient = new WifiClient(MAC_ADDRESS);
-        WifiClient writeWifiClientNotEquals = new WifiClient(macAddressNotEquals);
-
-        assertNotEquals(writeWifiClient, writeWifiClientNotEquals);
-        assertNotEquals(writeWifiClient.hashCode(), writeWifiClientNotEquals.hashCode());
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java
deleted file mode 100644
index d4b2051..0000000
--- a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java
+++ /dev/null
@@ -1,590 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import static android.net.wifi.WifiConfiguration.SECURITY_TYPE_EAP;
-import static android.net.wifi.WifiConfiguration.SECURITY_TYPE_EAP_SUITE_B;
-import static android.net.wifi.WifiConfiguration.SECURITY_TYPE_OPEN;
-import static android.net.wifi.WifiConfiguration.SECURITY_TYPE_OWE;
-import static android.net.wifi.WifiConfiguration.SECURITY_TYPE_PSK;
-import static android.net.wifi.WifiConfiguration.SECURITY_TYPE_SAE;
-import static android.net.wifi.WifiConfiguration.SECURITY_TYPE_WAPI_CERT;
-import static android.net.wifi.WifiConfiguration.SECURITY_TYPE_WAPI_PSK;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNotSame;
-import static org.junit.Assert.assertTrue;
-
-import android.net.MacAddress;
-import android.net.wifi.WifiConfiguration.KeyMgmt;
-import android.net.wifi.WifiConfiguration.NetworkSelectionStatus;
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.net.module.util.MacAddressUtils;
-
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Unit tests for {@link android.net.wifi.WifiConfiguration}.
- */
-@SmallTest
-public class WifiConfigurationTest {
-
-    @Before
-    public void setUp() {
-    }
-
-    /**
-     * Check that parcel marshalling/unmarshalling works
-     *
-     * Create and populate a WifiConfiguration.
-     * Marshall and unmashall it, and expect to recover a copy of the original.
-     * Marshall the resulting object, and expect the bytes to match the
-     * first marshall result.
-     */
-    @Test
-    public void testWifiConfigurationParcel() {
-        String cookie = "C O.o |<IE";
-        WifiConfiguration config = new WifiConfiguration();
-        config.setPasspointManagementObjectTree(cookie);
-        config.trusted = false;
-        config.updateIdentifier = "1234";
-        config.fromWifiNetworkSpecifier = true;
-        config.fromWifiNetworkSuggestion = true;
-        config.setRandomizedMacAddress(MacAddressUtils.createRandomUnicastAddress());
-        MacAddress macBeforeParcel = config.getRandomizedMacAddress();
-        Parcel parcelW = Parcel.obtain();
-        config.writeToParcel(parcelW, 0);
-        byte[] bytes = parcelW.marshall();
-        parcelW.recycle();
-
-        Parcel parcelR = Parcel.obtain();
-        parcelR.unmarshall(bytes, 0, bytes.length);
-        parcelR.setDataPosition(0);
-        WifiConfiguration reconfig = WifiConfiguration.CREATOR.createFromParcel(parcelR);
-
-        // lacking a useful config.equals, check two fields near the end.
-        assertEquals(cookie, reconfig.getMoTree());
-        assertEquals(macBeforeParcel, reconfig.getRandomizedMacAddress());
-        assertEquals(config.updateIdentifier, reconfig.updateIdentifier);
-        assertFalse(reconfig.trusted);
-        assertTrue(config.fromWifiNetworkSpecifier);
-        assertTrue(config.fromWifiNetworkSuggestion);
-
-        Parcel parcelWW = Parcel.obtain();
-        reconfig.writeToParcel(parcelWW, 0);
-        byte[] rebytes = parcelWW.marshall();
-        parcelWW.recycle();
-
-        assertArrayEquals(bytes, rebytes);
-    }
-
-    @Test
-    public void testIsOpenNetwork_IsOpen_NullWepKeys() {
-        WifiConfiguration config = new WifiConfiguration();
-        config.allowedKeyManagement.clear();
-        config.wepKeys = null;
-
-        assertTrue(config.isOpenNetwork());
-    }
-
-    @Test
-    public void testIsOpenNetwork_IsOpen_ZeroLengthWepKeysArray() {
-        WifiConfiguration config = new WifiConfiguration();
-        config.allowedKeyManagement.clear();
-        config.wepKeys = new String[0];
-
-        assertTrue(config.isOpenNetwork());
-    }
-
-    @Test
-    public void testIsOpenNetwork_IsOpen_NullWepKeysArray() {
-        WifiConfiguration config = new WifiConfiguration();
-        config.allowedKeyManagement.clear();
-        config.wepKeys = new String[1];
-
-        assertTrue(config.isOpenNetwork());
-    }
-
-    @Test
-    public void testIsOpenNetwork_NotOpen_HasWepKeys() {
-        WifiConfiguration config = new WifiConfiguration();
-        config.allowedKeyManagement.clear();
-        config.wepKeys = new String[] {"test"};
-
-        assertFalse(config.isOpenNetwork());
-    }
-
-    @Test
-    public void testIsOpenNetwork_NotOpen_HasNullWepKeyFollowedByNonNullKey() {
-        WifiConfiguration config = new WifiConfiguration();
-        config.allowedKeyManagement.clear();
-        config.wepKeys = new String[] {null, null, "test"};
-
-        assertFalse(config.isOpenNetwork());
-    }
-
-    @Test
-    public void testIsOpenNetwork_NotOpen_HasAuthType() {
-        for (int keyMgmt = 0; keyMgmt < WifiConfiguration.KeyMgmt.strings.length; keyMgmt++) {
-            if (keyMgmt == WifiConfiguration.KeyMgmt.NONE
-                    || keyMgmt == WifiConfiguration.KeyMgmt.OWE) {
-                continue;
-            }
-            WifiConfiguration config = new WifiConfiguration();
-            config.allowedKeyManagement.clear();
-            config.allowedKeyManagement.set(keyMgmt);
-            config.wepKeys = null;
-
-            assertFalse("Open network reported when key mgmt was set to "
-                            + WifiConfiguration.KeyMgmt.strings[keyMgmt], config.isOpenNetwork());
-        }
-    }
-
-    @Test
-    public void testIsOpenNetwork_NotOpen_HasAuthTypeNoneAndMore() {
-        WifiConfiguration config = new WifiConfiguration();
-        config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
-        config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
-        config.wepKeys = null;
-
-        assertFalse(config.isOpenNetwork());
-    }
-
-    @Test
-    public void testSetRandomizedMacAddress_ChangesSavedAddress() {
-        WifiConfiguration config = new WifiConfiguration();
-        MacAddress defaultMac = MacAddress.fromString(WifiInfo.DEFAULT_MAC_ADDRESS);
-        assertEquals(defaultMac, config.getRandomizedMacAddress());
-
-        MacAddress macToChangeInto = MacAddressUtils.createRandomUnicastAddress();
-        config.setRandomizedMacAddress(macToChangeInto);
-        MacAddress macAfterChange = config.getRandomizedMacAddress();
-
-        assertEquals(macToChangeInto, macAfterChange);
-    }
-
-    @Test
-    public void testSetRandomizedMacAddress_DoesNothingWhenNull() {
-        WifiConfiguration config = new WifiConfiguration();
-        MacAddress defaultMac = MacAddress.fromString(WifiInfo.DEFAULT_MAC_ADDRESS);
-        config.setRandomizedMacAddress(null);
-        assertEquals(defaultMac, config.getRandomizedMacAddress());
-    }
-
-    /**
-     * Verifies that updateIdentifier should be copied for copy constructor.
-     */
-    @Test
-    public void testUpdateIdentifierForCopyConstructor() {
-        WifiConfiguration config = new WifiConfiguration();
-        config.updateIdentifier = "1234";
-        WifiConfiguration copyConfig = new WifiConfiguration(config);
-
-        assertEquals(config.updateIdentifier, copyConfig.updateIdentifier);
-    }
-
-    /**
-     * Verifies that getKeyIdForCredentials returns the expected string for Enterprise networks
-     * @throws Exception
-     */
-    @Test
-    public void testGetKeyIdForCredentials() throws Exception {
-        WifiConfiguration config = new WifiConfiguration();
-        final String mSsid = "TestAP";
-        config.SSID = mSsid;
-
-        // Test various combinations
-        // EAP with TLS
-        config.allowedKeyManagement.set(KeyMgmt.WPA_EAP);
-        config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
-        config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.NONE);
-        String keyId = config.getKeyIdForCredentials(config);
-        assertEquals(keyId, mSsid + "_WPA_EAP_TLS_NULL");
-
-        // EAP with TTLS & MSCHAPv2
-        config.allowedKeyManagement.set(KeyMgmt.WPA_EAP);
-        config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TTLS);
-        config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.MSCHAPV2);
-        keyId = config.getKeyIdForCredentials(config);
-        assertEquals(keyId, mSsid + "_WPA_EAP_TTLS_MSCHAPV2");
-
-        // Suite-B 192 with PWD & GTC
-        config.allowedKeyManagement.clear();
-        config.allowedKeyManagement.set(KeyMgmt.SUITE_B_192);
-        config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.PWD);
-        config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.GTC);
-        keyId = config.getKeyIdForCredentials(config);
-        assertEquals(keyId, mSsid + "_SUITE_B_192_PWD_GTC");
-
-        // IEEE8021X with SIM
-        config.allowedKeyManagement.clear();
-        config.allowedKeyManagement.set(KeyMgmt.IEEE8021X);
-        config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.SIM);
-        config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.NONE);
-        keyId = config.getKeyIdForCredentials(config);
-        assertEquals(keyId, mSsid + "_IEEE8021X_SIM_NULL");
-
-        // Try calling this method with non-Enterprise network, expect an exception
-        boolean exceptionThrown = false;
-        try {
-            config.allowedKeyManagement.clear();
-            config.allowedKeyManagement.set(KeyMgmt.WPA2_PSK);
-            config.preSharedKey = "TestPsk";
-            keyId = config.getKeyIdForCredentials(config);
-        } catch (IllegalStateException e) {
-            exceptionThrown = true;
-        }
-        assertTrue(exceptionThrown);
-    }
-
-    /**
-     * Verifies that getKeyIdForCredentials returns the expected string for Suggestion Enterprise
-     * networks
-     * @throws Exception
-     */
-    @Test
-    public void testGetKeyIdForCredentialsForSuggestion() throws Exception {
-        WifiConfiguration config = new WifiConfiguration();
-        final String mSsid = "TestAP";
-        final String packageName = "TestApp";
-        final String bSsid = MacAddressUtils.createRandomUnicastAddress().toString();
-        String suggestionSuffix = "_" + bSsid + "_" + packageName;
-        config.SSID = mSsid;
-        config.fromWifiNetworkSuggestion = true;
-        config.creatorName = packageName;
-        config.BSSID = bSsid;
-
-        // Test various combinations
-        // EAP with TLS
-        config.allowedKeyManagement.set(KeyMgmt.WPA_EAP);
-        config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
-        config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.NONE);
-        String keyId = config.getKeyIdForCredentials(config);
-        assertEquals(keyId, mSsid + "_WPA_EAP_TLS_NULL" + suggestionSuffix);
-
-        // EAP with TTLS & MSCHAPv2
-        config.allowedKeyManagement.set(KeyMgmt.WPA_EAP);
-        config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TTLS);
-        config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.MSCHAPV2);
-        keyId = config.getKeyIdForCredentials(config);
-        assertEquals(keyId, mSsid + "_WPA_EAP_TTLS_MSCHAPV2" + suggestionSuffix);
-
-        // Suite-B 192 with PWD & GTC
-        config.allowedKeyManagement.clear();
-        config.allowedKeyManagement.set(KeyMgmt.SUITE_B_192);
-        config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.PWD);
-        config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.GTC);
-        keyId = config.getKeyIdForCredentials(config);
-        assertEquals(keyId, mSsid + "_SUITE_B_192_PWD_GTC" + suggestionSuffix);
-
-        // IEEE8021X with SIM
-        config.allowedKeyManagement.clear();
-        config.allowedKeyManagement.set(KeyMgmt.IEEE8021X);
-        config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.SIM);
-        config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.NONE);
-        keyId = config.getKeyIdForCredentials(config);
-        assertEquals(keyId, mSsid + "_IEEE8021X_SIM_NULL" + suggestionSuffix);
-
-        // Try calling this method with non-Enterprise network, expect an exception
-        boolean exceptionThrown = false;
-        try {
-            config.allowedKeyManagement.clear();
-            config.allowedKeyManagement.set(KeyMgmt.WPA2_PSK);
-            config.preSharedKey = "TestPsk";
-            keyId = config.getKeyIdForCredentials(config);
-        } catch (IllegalStateException e) {
-            exceptionThrown = true;
-        }
-        assertTrue(exceptionThrown);
-    }
-
-    /**
-     * Verifies that getSsidAndSecurityTypeString returns the correct String for networks of
-     * various different security types
-     */
-    @Test
-    public void testGetSsidAndSecurityTypeString() {
-        WifiConfiguration config = new WifiConfiguration();
-        final String mSsid = "TestAP";
-        config.SSID = mSsid;
-
-        // Test various combinations
-        config.allowedKeyManagement.set(KeyMgmt.WPA_PSK);
-        assertEquals(mSsid + KeyMgmt.strings[KeyMgmt.WPA_PSK],
-                config.getSsidAndSecurityTypeString());
-
-        config.allowedKeyManagement.clear();
-        config.allowedKeyManagement.set(KeyMgmt.WPA_EAP);
-        assertEquals(mSsid + KeyMgmt.strings[KeyMgmt.WPA_EAP],
-                config.getSsidAndSecurityTypeString());
-
-        config.wepKeys[0] = "TestWep";
-        config.allowedKeyManagement.clear();
-        assertEquals(mSsid + "WEP", config.getSsidAndSecurityTypeString());
-
-        // set WEP key and give a valid index.
-        config.wepKeys[0] = null;
-        config.wepKeys[2] = "TestWep";
-        config.wepTxKeyIndex = 2;
-        config.allowedKeyManagement.clear();
-        assertEquals(mSsid + "WEP", config.getSsidAndSecurityTypeString());
-
-        // set WEP key but does not give a valid index.
-        config.wepKeys[0] = null;
-        config.wepKeys[2] = "TestWep";
-        config.wepTxKeyIndex = 0;
-        config.allowedKeyManagement.clear();
-        config.allowedKeyManagement.set(KeyMgmt.OWE);
-        assertEquals(mSsid + KeyMgmt.strings[KeyMgmt.OWE], config.getSsidAndSecurityTypeString());
-
-        config.wepKeys[0] = null;
-        config.wepTxKeyIndex = 0;
-        config.allowedKeyManagement.clear();
-        config.allowedKeyManagement.set(KeyMgmt.OWE);
-        assertEquals(mSsid + KeyMgmt.strings[KeyMgmt.OWE], config.getSsidAndSecurityTypeString());
-
-        config.allowedKeyManagement.clear();
-        config.allowedKeyManagement.set(KeyMgmt.SAE);
-        assertEquals(mSsid + KeyMgmt.strings[KeyMgmt.SAE], config.getSsidAndSecurityTypeString());
-
-        config.allowedKeyManagement.clear();
-        config.allowedKeyManagement.set(KeyMgmt.SUITE_B_192);
-        assertEquals(mSsid + KeyMgmt.strings[KeyMgmt.SUITE_B_192],
-                config.getSsidAndSecurityTypeString());
-
-        config.allowedKeyManagement.clear();
-        config.allowedKeyManagement.set(KeyMgmt.NONE);
-        assertEquals(mSsid + KeyMgmt.strings[KeyMgmt.NONE], config.getSsidAndSecurityTypeString());
-
-        config.allowedKeyManagement.clear();
-        config.allowedKeyManagement.set(KeyMgmt.WAPI_PSK);
-        assertEquals(mSsid + KeyMgmt.strings[KeyMgmt.WAPI_PSK],
-                config.getSsidAndSecurityTypeString());
-
-        config.allowedKeyManagement.clear();
-        config.allowedKeyManagement.set(KeyMgmt.WAPI_CERT);
-        assertEquals(mSsid + KeyMgmt.strings[KeyMgmt.WAPI_CERT],
-                config.getSsidAndSecurityTypeString());
-    }
-
-    /**
-     * Ensure that the {@link NetworkSelectionStatus.DisableReasonInfo}s are populated in
-     * {@link NetworkSelectionStatus#DISABLE_REASON_INFOS} for reason codes from 0 to
-     * {@link NetworkSelectionStatus#NETWORK_SELECTION_DISABLED_MAX} - 1.
-     */
-    @Test
-    public void testNetworkSelectionDisableReasonInfosPopulated() {
-        assertEquals(NetworkSelectionStatus.NETWORK_SELECTION_DISABLED_MAX,
-                NetworkSelectionStatus.DISABLE_REASON_INFOS.size());
-        for (int i = 0; i < NetworkSelectionStatus.NETWORK_SELECTION_DISABLED_MAX; i++) {
-            assertNotNull(NetworkSelectionStatus.DISABLE_REASON_INFOS.get(i));
-        }
-    }
-
-    /**
-     * Ensure that {@link NetworkSelectionStatus#getMaxNetworkSelectionDisableReason()} returns
-     * the maximum disable reason.
-     */
-    @Test
-    public void testNetworkSelectionGetMaxNetworkSelectionDisableReason() {
-        int maxReason = Integer.MIN_VALUE;
-        for (int i = 0; i < NetworkSelectionStatus.DISABLE_REASON_INFOS.size(); i++) {
-            int reason = NetworkSelectionStatus.DISABLE_REASON_INFOS.keyAt(i);
-            maxReason = Math.max(maxReason, reason);
-        }
-        assertEquals(maxReason, NetworkSelectionStatus.getMaxNetworkSelectionDisableReason());
-    }
-
-    /**
-     * Ensure that {@link WifiConfiguration#setSecurityParams(int)} sets up the
-     * {@link WifiConfiguration} object correctly for SAE security type.
-     * @throws Exception
-     */
-    @Test
-    public void testSetSecurityParamsForSae() throws Exception {
-        WifiConfiguration config = new WifiConfiguration();
-
-        config.setSecurityParams(SECURITY_TYPE_SAE);
-
-        assertTrue(config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.SAE));
-        assertTrue(config.allowedPairwiseCiphers.get(WifiConfiguration.PairwiseCipher.CCMP));
-        assertTrue(config.allowedPairwiseCiphers.get(WifiConfiguration.PairwiseCipher.GCMP_256));
-        assertTrue(config.allowedGroupCiphers.get(WifiConfiguration.GroupCipher.CCMP));
-        assertTrue(config.allowedGroupCiphers.get(WifiConfiguration.GroupCipher.GCMP_256));
-        assertTrue(config.requirePmf);
-    }
-
-    /**
-     * Ensure that {@link WifiConfiguration#setSecurityParams(int)} sets up the
-     * {@link WifiConfiguration} object correctly for OWE security type.
-     * @throws Exception
-     */
-    @Test
-    public void testSetSecurityParamsForOwe() throws Exception {
-        WifiConfiguration config = new WifiConfiguration();
-
-        config.setSecurityParams(SECURITY_TYPE_OWE);
-
-        assertTrue(config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.OWE));
-        assertTrue(config.allowedPairwiseCiphers.get(WifiConfiguration.PairwiseCipher.CCMP));
-        assertTrue(config.allowedPairwiseCiphers.get(WifiConfiguration.PairwiseCipher.GCMP_256));
-        assertTrue(config.allowedGroupCiphers.get(WifiConfiguration.GroupCipher.CCMP));
-        assertTrue(config.allowedGroupCiphers.get(WifiConfiguration.GroupCipher.GCMP_256));
-        assertTrue(config.requirePmf);
-    }
-
-    /**
-     * Ensure that {@link WifiConfiguration#setSecurityParams(int)} sets up the
-     * {@link WifiConfiguration} object correctly for Suite-B security type.
-     * @throws Exception
-     */
-    @Test
-    public void testSetSecurityParamsForSuiteB() throws Exception {
-        WifiConfiguration config = new WifiConfiguration();
-
-        config.setSecurityParams(SECURITY_TYPE_EAP_SUITE_B);
-
-        assertTrue(config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.SUITE_B_192));
-        assertTrue(config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_EAP));
-        assertTrue(config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.IEEE8021X));
-        assertTrue(config.allowedPairwiseCiphers.get(WifiConfiguration.PairwiseCipher.GCMP_256));
-        assertTrue(config.allowedGroupCiphers.get(WifiConfiguration.GroupCipher.GCMP_256));
-        assertTrue(config.allowedGroupManagementCiphers
-                .get(WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256));
-        assertTrue(config.requirePmf);
-    }
-
-    /**
-     * Test that the NetworkSelectionStatus Builder returns the same values that was set, and that
-     * calling build multiple times returns different instances.
-     */
-    @Test
-    public void testNetworkSelectionStatusBuilder() throws Exception {
-        NetworkSelectionStatus.Builder builder = new NetworkSelectionStatus.Builder()
-                .setNetworkSelectionDisableReason(
-                        NetworkSelectionStatus.DISABLED_ASSOCIATION_REJECTION)
-                .setNetworkSelectionStatus(
-                        NetworkSelectionStatus.NETWORK_SELECTION_PERMANENTLY_DISABLED);
-
-        NetworkSelectionStatus status1 = builder.build();
-
-        assertEquals(NetworkSelectionStatus.DISABLED_ASSOCIATION_REJECTION,
-                status1.getNetworkSelectionDisableReason());
-        assertEquals(NetworkSelectionStatus.NETWORK_SELECTION_PERMANENTLY_DISABLED,
-                status1.getNetworkSelectionStatus());
-
-        NetworkSelectionStatus status2 = builder
-                .setNetworkSelectionDisableReason(NetworkSelectionStatus.DISABLED_BY_WRONG_PASSWORD)
-                .build();
-
-        // different instances
-        assertNotSame(status1, status2);
-
-        // assert that status1 didn't change
-        assertEquals(NetworkSelectionStatus.DISABLED_ASSOCIATION_REJECTION,
-                status1.getNetworkSelectionDisableReason());
-        assertEquals(NetworkSelectionStatus.NETWORK_SELECTION_PERMANENTLY_DISABLED,
-                status1.getNetworkSelectionStatus());
-
-        // assert that status2 changed
-        assertEquals(NetworkSelectionStatus.DISABLED_BY_WRONG_PASSWORD,
-                status2.getNetworkSelectionDisableReason());
-        assertEquals(NetworkSelectionStatus.NETWORK_SELECTION_PERMANENTLY_DISABLED,
-                status2.getNetworkSelectionStatus());
-    }
-
-    @Test
-    public void testNeedsPreSharedKey() throws Exception {
-        WifiConfiguration configuration = new WifiConfiguration();
-
-        configuration.setSecurityParams(SECURITY_TYPE_PSK);
-        assertTrue(configuration.needsPreSharedKey());
-
-        configuration.setSecurityParams(SECURITY_TYPE_SAE);
-        assertTrue(configuration.needsPreSharedKey());
-
-        configuration.setSecurityParams(SECURITY_TYPE_WAPI_PSK);
-        assertTrue(configuration.needsPreSharedKey());
-
-        configuration.setSecurityParams(SECURITY_TYPE_OPEN);
-        assertFalse(configuration.needsPreSharedKey());
-
-        configuration.setSecurityParams(SECURITY_TYPE_OWE);
-        assertFalse(configuration.needsPreSharedKey());
-
-        configuration.setSecurityParams(SECURITY_TYPE_EAP);
-        assertFalse(configuration.needsPreSharedKey());
-
-        configuration.setSecurityParams(SECURITY_TYPE_EAP_SUITE_B);
-        assertFalse(configuration.needsPreSharedKey());
-    }
-
-    @Test
-    public void testGetAuthType() throws Exception {
-        WifiConfiguration configuration = new WifiConfiguration();
-
-        configuration.setSecurityParams(SECURITY_TYPE_PSK);
-        assertEquals(KeyMgmt.WPA_PSK, configuration.getAuthType());
-
-        configuration.setSecurityParams(SECURITY_TYPE_SAE);
-        assertEquals(KeyMgmt.SAE, configuration.getAuthType());
-
-        configuration.setSecurityParams(SECURITY_TYPE_WAPI_PSK);
-        assertEquals(KeyMgmt.WAPI_PSK, configuration.getAuthType());
-
-        configuration.setSecurityParams(SECURITY_TYPE_OPEN);
-        assertEquals(KeyMgmt.NONE, configuration.getAuthType());
-
-        configuration.setSecurityParams(SECURITY_TYPE_OWE);
-        assertEquals(KeyMgmt.OWE, configuration.getAuthType());
-
-        configuration.setSecurityParams(SECURITY_TYPE_EAP);
-        assertEquals(KeyMgmt.WPA_EAP, configuration.getAuthType());
-
-        configuration.setSecurityParams(SECURITY_TYPE_EAP_SUITE_B);
-        assertEquals(KeyMgmt.SUITE_B_192, configuration.getAuthType());
-
-        configuration.setSecurityParams(SECURITY_TYPE_WAPI_CERT);
-        assertEquals(KeyMgmt.WAPI_CERT, configuration.getAuthType());
-    }
-
-    @Test (expected = IllegalStateException.class)
-    public void testGetAuthTypeFailure1() throws Exception {
-        WifiConfiguration configuration = new WifiConfiguration();
-
-        configuration.setSecurityParams(SECURITY_TYPE_PSK);
-        configuration.allowedKeyManagement.set(KeyMgmt.IEEE8021X);
-        configuration.getAuthType();
-    }
-
-    @Test (expected = IllegalStateException.class)
-    public void testGetAuthTypeFailure2() throws Exception {
-        WifiConfiguration configuration = new WifiConfiguration();
-
-        configuration.allowedKeyManagement.set(KeyMgmt.IEEE8021X);
-        configuration.allowedKeyManagement.set(KeyMgmt.WPA_EAP);
-        configuration.allowedKeyManagement.set(KeyMgmt.SAE);
-        configuration.getAuthType();
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/WifiEnterpriseConfigTest.java b/wifi/tests/src/android/net/wifi/WifiEnterpriseConfigTest.java
deleted file mode 100644
index 62485ec..0000000
--- a/wifi/tests/src/android/net/wifi/WifiEnterpriseConfigTest.java
+++ /dev/null
@@ -1,577 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package android.net.wifi;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import android.net.wifi.WifiEnterpriseConfig.Eap;
-import android.net.wifi.WifiEnterpriseConfig.Phase2;
-import android.os.Parcel;
-import android.security.Credentials;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.security.PrivateKey;
-import java.security.cert.X509Certificate;
-
-/**
- * Unit tests for {@link android.net.wifi.WifiEnterpriseConfig}.
- */
-@SmallTest
-public class WifiEnterpriseConfigTest {
-    // Maintain a ground truth of the keystore uri prefix which is expected by wpa_supplicant.
-    public static final String KEYSTORE_URI = "keystore://";
-    public static final String CA_CERT_PREFIX = KEYSTORE_URI + Credentials.CA_CERTIFICATE;
-    public static final String KEYSTORES_URI = "keystores://";
-    private static final String TEST_DOMAIN_SUFFIX_MATCH = "domainSuffixMatch";
-
-    private WifiEnterpriseConfig mEnterpriseConfig;
-
-    @Before
-    public void setUp() throws Exception {
-        mEnterpriseConfig = new WifiEnterpriseConfig();
-    }
-
-    @Test
-    public void testGetEmptyCaCertificate() {
-        // A newly-constructed WifiEnterpriseConfig object should have no CA certificate.
-        assertNull(mEnterpriseConfig.getCaCertificate());
-        assertNull(mEnterpriseConfig.getCaCertificates());
-        // Setting CA certificate to null explicitly.
-        mEnterpriseConfig.setCaCertificate(null);
-        assertNull(mEnterpriseConfig.getCaCertificate());
-        // Setting CA certificate to null using setCaCertificates().
-        mEnterpriseConfig.setCaCertificates(null);
-        assertNull(mEnterpriseConfig.getCaCertificates());
-        // Setting CA certificate to zero-length array.
-        mEnterpriseConfig.setCaCertificates(new X509Certificate[0]);
-        assertNull(mEnterpriseConfig.getCaCertificates());
-    }
-
-    @Test
-    public void testSetGetSingleCaCertificate() {
-        X509Certificate cert0 = FakeKeys.CA_CERT0;
-        mEnterpriseConfig.setCaCertificate(cert0);
-        assertEquals(mEnterpriseConfig.getCaCertificate(), cert0);
-    }
-
-    @Test
-    public void testSetGetMultipleCaCertificates() {
-        X509Certificate cert0 = FakeKeys.CA_CERT0;
-        X509Certificate cert1 = FakeKeys.CA_CERT1;
-        mEnterpriseConfig.setCaCertificates(new X509Certificate[] {cert0, cert1});
-        X509Certificate[] result = mEnterpriseConfig.getCaCertificates();
-        assertEquals(result.length, 2);
-        assertTrue(result[0] == cert0 && result[1] == cert1);
-    }
-
-    @Test
-    public void testSetClientKeyEntryWithNull() {
-        mEnterpriseConfig.setClientKeyEntry(null, null);
-        assertNull(mEnterpriseConfig.getClientCertificateChain());
-        assertNull(mEnterpriseConfig.getClientCertificate());
-        mEnterpriseConfig.setClientKeyEntryWithCertificateChain(null, null);
-        assertNull(mEnterpriseConfig.getClientCertificateChain());
-        assertNull(mEnterpriseConfig.getClientCertificate());
-
-        // Setting the client certificate to null should clear the existing chain.
-        PrivateKey clientKey = FakeKeys.RSA_KEY1;
-        X509Certificate clientCert0 = FakeKeys.CLIENT_CERT;
-        X509Certificate clientCert1 = FakeKeys.CA_CERT1;
-        mEnterpriseConfig.setClientKeyEntry(clientKey, clientCert0);
-        assertNotNull(mEnterpriseConfig.getClientCertificate());
-        mEnterpriseConfig.setClientKeyEntry(null, null);
-        assertNull(mEnterpriseConfig.getClientCertificate());
-        assertNull(mEnterpriseConfig.getClientCertificateChain());
-
-        // Setting the chain to null should clear the existing chain.
-        X509Certificate[] clientChain = new X509Certificate[] {clientCert0, clientCert1};
-        mEnterpriseConfig.setClientKeyEntryWithCertificateChain(clientKey, clientChain);
-        assertNotNull(mEnterpriseConfig.getClientCertificateChain());
-        mEnterpriseConfig.setClientKeyEntryWithCertificateChain(null, null);
-        assertNull(mEnterpriseConfig.getClientCertificate());
-        assertNull(mEnterpriseConfig.getClientCertificateChain());
-    }
-
-    @Test
-    public void testSetClientCertificateChain() {
-        PrivateKey clientKey = FakeKeys.RSA_KEY1;
-        X509Certificate cert0 = FakeKeys.CLIENT_CERT;
-        X509Certificate cert1 = FakeKeys.CA_CERT1;
-        X509Certificate[] clientChain = new X509Certificate[] {cert0, cert1};
-        mEnterpriseConfig.setClientKeyEntryWithCertificateChain(clientKey, clientChain);
-        X509Certificate[] result = mEnterpriseConfig.getClientCertificateChain();
-        assertEquals(result.length, 2);
-        assertTrue(result[0] == cert0 && result[1] == cert1);
-        assertTrue(mEnterpriseConfig.getClientCertificate() == cert0);
-    }
-
-    private boolean isClientCertificateChainInvalid(X509Certificate[] clientChain) {
-        boolean exceptionThrown = false;
-        try {
-            PrivateKey clientKey = FakeKeys.RSA_KEY1;
-            mEnterpriseConfig.setClientKeyEntryWithCertificateChain(clientKey, clientChain);
-        } catch (IllegalArgumentException e) {
-            exceptionThrown = true;
-        }
-        return exceptionThrown;
-    }
-
-    @Test
-    public void testSetInvalidClientCertificateChain() {
-        X509Certificate clientCert = FakeKeys.CLIENT_CERT;
-        X509Certificate caCert = FakeKeys.CA_CERT1;
-        assertTrue("Invalid client certificate",
-                isClientCertificateChainInvalid(new X509Certificate[] {caCert, caCert}));
-        assertTrue("Invalid CA certificate",
-                isClientCertificateChainInvalid(new X509Certificate[] {clientCert, clientCert}));
-        assertTrue("Both certificates invalid",
-                isClientCertificateChainInvalid(new X509Certificate[] {caCert, clientCert}));
-    }
-
-    @Test
-    public void testSaveSingleCaCertificateAlias() {
-        final String alias = "single_alias 0";
-        mEnterpriseConfig.setCaCertificateAliases(new String[] {alias});
-        assertEquals(getCaCertField(), CA_CERT_PREFIX + alias);
-    }
-
-    @Test
-    public void testLoadSingleCaCertificateAlias() {
-        final String alias = "single_alias 1";
-        setCaCertField(CA_CERT_PREFIX + alias);
-        String[] aliases = mEnterpriseConfig.getCaCertificateAliases();
-        assertEquals(aliases.length, 1);
-        assertEquals(aliases[0], alias);
-    }
-
-    @Test
-    public void testSaveMultipleCaCertificates() {
-        final String alias0 = "single_alias 0";
-        final String alias1 = "single_alias 1";
-        mEnterpriseConfig.setCaCertificateAliases(new String[] {alias0, alias1});
-        assertEquals(getCaCertField(), String.format("%s%s %s",
-                KEYSTORES_URI,
-                WifiEnterpriseConfig.encodeCaCertificateAlias(Credentials.CA_CERTIFICATE + alias0),
-                WifiEnterpriseConfig.encodeCaCertificateAlias(Credentials.CA_CERTIFICATE + alias1)));
-    }
-
-    @Test
-    public void testLoadMultipleCaCertificates() {
-        final String alias0 = "single_alias 0";
-        final String alias1 = "single_alias 1";
-        setCaCertField(String.format("%s%s %s",
-                KEYSTORES_URI,
-                WifiEnterpriseConfig.encodeCaCertificateAlias(Credentials.CA_CERTIFICATE + alias0),
-                WifiEnterpriseConfig.encodeCaCertificateAlias(Credentials.CA_CERTIFICATE + alias1)));
-        String[] aliases = mEnterpriseConfig.getCaCertificateAliases();
-        assertEquals(aliases.length, 2);
-        assertEquals(aliases[0], alias0);
-        assertEquals(aliases[1], alias1);
-    }
-
-    private String getCaCertField() {
-        return mEnterpriseConfig.getFieldValue(WifiEnterpriseConfig.CA_CERT_KEY);
-    }
-
-    private void setCaCertField(String value) {
-        mEnterpriseConfig.setFieldValue(WifiEnterpriseConfig.CA_CERT_KEY, value);
-    }
-
-    // Retrieves the value for a specific key supplied to wpa_supplicant.
-    private class SupplicantConfigExtractor implements WifiEnterpriseConfig.SupplicantSaver {
-        private String mValue = null;
-        private String mKey;
-
-        SupplicantConfigExtractor(String key) {
-            mKey = key;
-        }
-
-        @Override
-        public boolean saveValue(String key, String value) {
-            if (key.equals(mKey)) {
-                mValue = value;
-            }
-            return true;
-        }
-
-        public String getValue() {
-            return mValue;
-        }
-    }
-
-    private String getSupplicantEapMethod() {
-        SupplicantConfigExtractor entryExtractor = new SupplicantConfigExtractor(
-                WifiEnterpriseConfig.EAP_KEY);
-        mEnterpriseConfig.saveToSupplicant(entryExtractor);
-        return entryExtractor.getValue();
-    }
-
-    private String getSupplicantPhase2Method() {
-        SupplicantConfigExtractor entryExtractor = new SupplicantConfigExtractor(
-                WifiEnterpriseConfig.PHASE2_KEY);
-        mEnterpriseConfig.saveToSupplicant(entryExtractor);
-        return entryExtractor.getValue();
-    }
-
-    /** Verifies the default value for EAP outer and inner methods */
-    @Test
-    public void eapInnerDefault() {
-        assertEquals(null, getSupplicantEapMethod());
-        assertEquals(null, getSupplicantPhase2Method());
-    }
-
-    /** Verifies that the EAP inner method is reset when we switch to TLS */
-    @Test
-    public void eapPhase2MethodForTls() {
-        // Initially select an EAP method that supports an phase2.
-        mEnterpriseConfig.setEapMethod(Eap.PEAP);
-        mEnterpriseConfig.setPhase2Method(Phase2.MSCHAPV2);
-        assertEquals("PEAP", getSupplicantEapMethod());
-        assertEquals("\"auth=MSCHAPV2\"", getSupplicantPhase2Method());
-
-        // Change the EAP method to another type which supports a phase2.
-        mEnterpriseConfig.setEapMethod(Eap.TTLS);
-        assertEquals("TTLS", getSupplicantEapMethod());
-        assertEquals("\"auth=MSCHAPV2\"", getSupplicantPhase2Method());
-
-        // Change the EAP method to TLS which does not support a phase2.
-        mEnterpriseConfig.setEapMethod(Eap.TLS);
-        assertEquals(null, getSupplicantPhase2Method());
-    }
-
-    /** Verfies that the EAP inner method is reset when we switch phase2 to NONE */
-    @Test
-    public void eapPhase2None() {
-        // Initially select an EAP method that supports an phase2.
-        mEnterpriseConfig.setEapMethod(Eap.PEAP);
-        mEnterpriseConfig.setPhase2Method(Phase2.MSCHAPV2);
-        assertEquals("PEAP", getSupplicantEapMethod());
-        assertEquals("\"auth=MSCHAPV2\"", getSupplicantPhase2Method());
-
-        // Change the phase2 method to NONE and ensure the value is cleared.
-        mEnterpriseConfig.setPhase2Method(Phase2.NONE);
-        assertEquals(null, getSupplicantPhase2Method());
-    }
-
-    /** Verfies that the correct "autheap" parameter is supplied for TTLS/GTC. */
-    @Test
-    public void peapGtcToTtls() {
-        mEnterpriseConfig.setEapMethod(Eap.PEAP);
-        mEnterpriseConfig.setPhase2Method(Phase2.GTC);
-        assertEquals("PEAP", getSupplicantEapMethod());
-        assertEquals("\"auth=GTC\"", getSupplicantPhase2Method());
-
-        mEnterpriseConfig.setEapMethod(Eap.TTLS);
-        assertEquals("TTLS", getSupplicantEapMethod());
-        assertEquals("\"autheap=GTC\"", getSupplicantPhase2Method());
-    }
-
-    /** Verfies that the correct "auth" parameter is supplied for PEAP/GTC. */
-    @Test
-    public void ttlsGtcToPeap() {
-        mEnterpriseConfig.setEapMethod(Eap.TTLS);
-        mEnterpriseConfig.setPhase2Method(Phase2.GTC);
-        assertEquals("TTLS", getSupplicantEapMethod());
-        assertEquals("\"autheap=GTC\"", getSupplicantPhase2Method());
-
-        mEnterpriseConfig.setEapMethod(Eap.PEAP);
-        assertEquals("PEAP", getSupplicantEapMethod());
-        assertEquals("\"auth=GTC\"", getSupplicantPhase2Method());
-    }
-
-    /** Verfies PEAP/SIM, PEAP/AKA, PEAP/AKA'. */
-    @Test
-    public void peapSimAkaAkaPrime() {
-        mEnterpriseConfig.setEapMethod(Eap.PEAP);
-        mEnterpriseConfig.setPhase2Method(Phase2.SIM);
-        assertEquals("PEAP", getSupplicantEapMethod());
-        assertEquals("\"auth=SIM\"", getSupplicantPhase2Method());
-
-        mEnterpriseConfig.setPhase2Method(Phase2.AKA);
-        assertEquals("\"auth=AKA\"", getSupplicantPhase2Method());
-
-        mEnterpriseConfig.setPhase2Method(Phase2.AKA_PRIME);
-        assertEquals("\"auth=AKA'\"", getSupplicantPhase2Method());
-    }
-
-    /**
-     * Verifies that the copy constructor preseves both the masked password and inner method
-     * information.
-     */
-    @Test
-    public void copyConstructor() {
-        WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
-        enterpriseConfig.setPassword("*");
-        enterpriseConfig.setEapMethod(Eap.TTLS);
-        enterpriseConfig.setPhase2Method(Phase2.GTC);
-        mEnterpriseConfig = new WifiEnterpriseConfig(enterpriseConfig);
-        assertEquals("TTLS", getSupplicantEapMethod());
-        assertEquals("\"autheap=GTC\"", getSupplicantPhase2Method());
-        assertEquals("*", mEnterpriseConfig.getPassword());
-    }
-
-    /**
-     * Verifies that the copy from external ignores masked passwords and preserves the
-     * inner method information.
-     */
-    @Test
-    public void copyFromExternal() {
-        WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
-        enterpriseConfig.setPassword("*");
-        enterpriseConfig.setEapMethod(Eap.TTLS);
-        enterpriseConfig.setPhase2Method(Phase2.GTC);
-        enterpriseConfig.setOcsp(WifiEnterpriseConfig.OCSP_REQUIRE_CERT_STATUS);
-        mEnterpriseConfig = new WifiEnterpriseConfig();
-        mEnterpriseConfig.copyFromExternal(enterpriseConfig, "*");
-        assertEquals("TTLS", getSupplicantEapMethod());
-        assertEquals("\"autheap=GTC\"", getSupplicantPhase2Method());
-        assertNotEquals("*", mEnterpriseConfig.getPassword());
-        assertEquals(enterpriseConfig.getOcsp(), mEnterpriseConfig.getOcsp());
-    }
-
-    /** Verfies that parceling a WifiEnterpriseConfig preseves method information. */
-    @Test
-    public void parcelConstructor() {
-        WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
-        enterpriseConfig.setEapMethod(Eap.TTLS);
-        enterpriseConfig.setPhase2Method(Phase2.GTC);
-        Parcel parcel = Parcel.obtain();
-        enterpriseConfig.writeToParcel(parcel, 0);
-        parcel.setDataPosition(0);  // Allow parcel to be read from the beginning.
-        mEnterpriseConfig = WifiEnterpriseConfig.CREATOR.createFromParcel(parcel);
-        assertEquals("TTLS", getSupplicantEapMethod());
-        assertEquals("\"autheap=GTC\"", getSupplicantPhase2Method());
-    }
-
-    /**
-     * Verifies that parceling a WifiEnterpriseConfig preserves the key
-     * and certificates information.
-     */
-    @Test
-    public void parcelConfigWithKeyAndCerts() throws Exception {
-        WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
-        PrivateKey clientKey = FakeKeys.RSA_KEY1;
-        X509Certificate clientCert = FakeKeys.CLIENT_CERT;
-        X509Certificate[] caCerts = new X509Certificate[] {FakeKeys.CA_CERT0, FakeKeys.CA_CERT1};
-        enterpriseConfig.setClientKeyEntry(clientKey, clientCert);
-        enterpriseConfig.setCaCertificates(caCerts);
-        Parcel parcel = Parcel.obtain();
-        enterpriseConfig.writeToParcel(parcel, 0);
-
-        parcel.setDataPosition(0);  // Allow parcel to be read from the beginning.
-        mEnterpriseConfig = WifiEnterpriseConfig.CREATOR.createFromParcel(parcel);
-        PrivateKey actualClientKey = mEnterpriseConfig.getClientPrivateKey();
-        X509Certificate actualClientCert = mEnterpriseConfig.getClientCertificate();
-        X509Certificate[] actualCaCerts = mEnterpriseConfig.getCaCertificates();
-
-        /* Verify client private key. */
-        assertNotNull(actualClientKey);
-        assertEquals(clientKey.getAlgorithm(), actualClientKey.getAlgorithm());
-        assertArrayEquals(clientKey.getEncoded(), actualClientKey.getEncoded());
-
-        /* Verify client certificate. */
-        assertNotNull(actualClientCert);
-        assertArrayEquals(clientCert.getEncoded(), actualClientCert.getEncoded());
-
-        /* Verify CA certificates. */
-        assertNotNull(actualCaCerts);
-        assertEquals(caCerts.length, actualCaCerts.length);
-        for (int i = 0; i < caCerts.length; i++) {
-            assertNotNull(actualCaCerts[i]);
-            assertArrayEquals(caCerts[i].getEncoded(), actualCaCerts[i].getEncoded());
-        }
-    }
-
-    /** Verifies proper operation of the getKeyId() method. */
-    @Test
-    public void getKeyId() {
-        assertEquals("NULL", mEnterpriseConfig.getKeyId(null));
-        WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
-        enterpriseConfig.setEapMethod(Eap.TTLS);
-        enterpriseConfig.setPhase2Method(Phase2.GTC);
-        assertEquals("TTLS_GTC", mEnterpriseConfig.getKeyId(enterpriseConfig));
-        mEnterpriseConfig.setEapMethod(Eap.PEAP);
-        mEnterpriseConfig.setPhase2Method(Phase2.MSCHAPV2);
-        assertEquals("PEAP_MSCHAPV2", mEnterpriseConfig.getKeyId(enterpriseConfig));
-    }
-
-    /** Verifies that passwords are not displayed in toString. */
-    @Test
-    public void passwordNotInToString() {
-        String password = "supersecret";
-        mEnterpriseConfig.setPassword(password);
-        assertFalse(mEnterpriseConfig.toString().contains(password));
-    }
-
-    /** Verifies that certificate ownership flag is set correctly */
-    @Test
-    public void testIsAppInstalledDeviceKeyAndCert() {
-        // First make sure that app didn't install anything
-        assertFalse(mEnterpriseConfig.isAppInstalledDeviceKeyAndCert());
-        assertFalse(mEnterpriseConfig.isAppInstalledCaCert());
-
-        // Then app loads keys via the enterprise config API
-        PrivateKey clientKey = FakeKeys.RSA_KEY1;
-        X509Certificate cert0 = FakeKeys.CLIENT_CERT;
-        X509Certificate cert1 = FakeKeys.CA_CERT1;
-        X509Certificate[] clientChain = new X509Certificate[] {cert0, cert1};
-        mEnterpriseConfig.setClientKeyEntryWithCertificateChain(clientKey, clientChain);
-        X509Certificate[] result = mEnterpriseConfig.getClientCertificateChain();
-        assertEquals(result.length, 2);
-        assertTrue(result[0] == cert0 && result[1] == cert1);
-        assertTrue(mEnterpriseConfig.getClientCertificate() == cert0);
-
-        // Make sure it is the owner now
-        assertTrue(mEnterpriseConfig.isAppInstalledDeviceKeyAndCert());
-        assertFalse(mEnterpriseConfig.isAppInstalledCaCert());
-    }
-
-    /** Verifies that certificate ownership flag is set correctly */
-    @Test
-    public void testIsAppInstalledCaCert() {
-        // First make sure that app didn't install anything
-        assertFalse(mEnterpriseConfig.isAppInstalledDeviceKeyAndCert());
-        assertFalse(mEnterpriseConfig.isAppInstalledCaCert());
-
-        // Then app loads CA cert via the enterprise config API
-        X509Certificate cert = FakeKeys.CA_CERT1;
-        mEnterpriseConfig.setCaCertificate(cert);
-        X509Certificate result = mEnterpriseConfig.getCaCertificate();
-        assertTrue(result == cert);
-
-        // Make sure it is the owner now
-        assertFalse(mEnterpriseConfig.isAppInstalledDeviceKeyAndCert());
-        assertTrue(mEnterpriseConfig.isAppInstalledCaCert());
-    }
-
-    /** Verifies that certificate ownership flag is set correctly */
-    @Test
-    public void testIsAppInstalledCaCerts() {
-        // First make sure that app didn't install anything
-        assertFalse(mEnterpriseConfig.isAppInstalledDeviceKeyAndCert());
-        assertFalse(mEnterpriseConfig.isAppInstalledCaCert());
-
-        // Then app loads CA cert via the enterprise config API
-        X509Certificate cert0 = FakeKeys.CA_CERT0;
-        X509Certificate cert1 = FakeKeys.CA_CERT1;
-        X509Certificate[] cert = new X509Certificate[] {cert0, cert1};
-
-        mEnterpriseConfig.setCaCertificates(cert);
-        X509Certificate[] result = mEnterpriseConfig.getCaCertificates();
-        assertEquals(result.length, 2);
-        assertTrue(result[0] == cert0 && result[1] == cert1);
-//        assertTrue(mEnterpriseConfig.getClientCertificate() == cert0);
-
-        // Make sure it is the owner now
-        assertFalse(mEnterpriseConfig.isAppInstalledDeviceKeyAndCert());
-        assertTrue(mEnterpriseConfig.isAppInstalledCaCert());
-    }
-
-    /** Verifies that OCSP value is set correctly. */
-    @Test
-    public void testOcspSetGet() throws Exception {
-        WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
-
-        enterpriseConfig.setOcsp(WifiEnterpriseConfig.OCSP_NONE);
-        assertEquals(WifiEnterpriseConfig.OCSP_NONE, enterpriseConfig.getOcsp());
-
-        enterpriseConfig.setOcsp(WifiEnterpriseConfig.OCSP_REQUIRE_CERT_STATUS);
-        assertEquals(WifiEnterpriseConfig.OCSP_REQUIRE_CERT_STATUS, enterpriseConfig.getOcsp());
-
-        enterpriseConfig.setOcsp(WifiEnterpriseConfig.OCSP_REQUEST_CERT_STATUS);
-        assertEquals(WifiEnterpriseConfig.OCSP_REQUEST_CERT_STATUS, enterpriseConfig.getOcsp());
-
-        enterpriseConfig.setOcsp(WifiEnterpriseConfig.OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS);
-        assertEquals(WifiEnterpriseConfig.OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS,
-                enterpriseConfig.getOcsp());
-    }
-
-    /** Verifies that an exception is thrown when invalid OCSP is set. */
-    @Test
-    public void testInvalidOcspValue() {
-        WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
-        try {
-            enterpriseConfig.setOcsp(-1);
-            fail("Should raise an IllegalArgumentException here.");
-        } catch (IllegalArgumentException e) {
-            // expected exception.
-        }
-    }
-
-    /** Verifies that the EAP inner method is reset when we switch to Unauth-TLS */
-    @Test
-    public void eapPhase2MethodForUnauthTls() {
-        // Initially select an EAP method that supports an phase2.
-        mEnterpriseConfig.setEapMethod(Eap.PEAP);
-        mEnterpriseConfig.setPhase2Method(Phase2.MSCHAPV2);
-        assertEquals("PEAP", getSupplicantEapMethod());
-        assertEquals("\"auth=MSCHAPV2\"", getSupplicantPhase2Method());
-
-        // Change the EAP method to another type which supports a phase2.
-        mEnterpriseConfig.setEapMethod(Eap.TTLS);
-        assertEquals("TTLS", getSupplicantEapMethod());
-        assertEquals("\"auth=MSCHAPV2\"", getSupplicantPhase2Method());
-
-        // Change the EAP method to Unauth-TLS which does not support a phase2.
-        mEnterpriseConfig.setEapMethod(Eap.UNAUTH_TLS);
-        assertEquals(null, getSupplicantPhase2Method());
-    }
-
-    @Test
-    public void testIsEnterpriseConfigSecure() {
-        WifiEnterpriseConfig baseConfig = new WifiEnterpriseConfig();
-        baseConfig.setEapMethod(Eap.PEAP);
-        baseConfig.setPhase2Method(Phase2.MSCHAPV2);
-        assertTrue(baseConfig.isInsecure());
-
-        WifiEnterpriseConfig noMatchConfig = new WifiEnterpriseConfig(baseConfig);
-        noMatchConfig.setCaCertificate(FakeKeys.CA_CERT0);
-        // Missing match is insecure.
-        assertTrue(noMatchConfig.isInsecure());
-
-        WifiEnterpriseConfig noCaConfig = new WifiEnterpriseConfig(baseConfig);
-        noCaConfig.setDomainSuffixMatch(TEST_DOMAIN_SUFFIX_MATCH);
-        // Missing CA certificate is insecure.
-        assertTrue(noCaConfig.isInsecure());
-
-        WifiEnterpriseConfig secureConfig = new WifiEnterpriseConfig();
-        secureConfig.setEapMethod(Eap.PEAP);
-        secureConfig.setPhase2Method(Phase2.MSCHAPV2);
-        secureConfig.setCaCertificate(FakeKeys.CA_CERT0);
-        secureConfig.setDomainSuffixMatch(TEST_DOMAIN_SUFFIX_MATCH);
-        assertFalse(secureConfig.isInsecure());
-
-        WifiEnterpriseConfig secureConfigWithCaAlias = new WifiEnterpriseConfig();
-        secureConfigWithCaAlias.setEapMethod(Eap.PEAP);
-        secureConfigWithCaAlias.setPhase2Method(Phase2.MSCHAPV2);
-        secureConfigWithCaAlias.setCaCertificateAliases(new String[]{"alias1", "alisa2"});
-        secureConfigWithCaAlias.setDomainSuffixMatch(TEST_DOMAIN_SUFFIX_MATCH);
-        assertFalse(secureConfigWithCaAlias.isInsecure());
-    }
-
-}
diff --git a/wifi/tests/src/android/net/wifi/WifiInfoTest.java b/wifi/tests/src/android/net/wifi/WifiInfoTest.java
deleted file mode 100644
index 311bbc4..0000000
--- a/wifi/tests/src/android/net/wifi/WifiInfoTest.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNotSame;
-import static org.junit.Assert.assertTrue;
-
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-import java.nio.charset.StandardCharsets;
-
-/**
- * Unit tests for {@link android.net.wifi.WifiInfo}.
- */
-@SmallTest
-public class WifiInfoTest {
-    private static final long TEST_TX_SUCCESS = 1;
-    private static final long TEST_TX_RETRIES = 2;
-    private static final long TEST_TX_BAD = 3;
-    private static final long TEST_RX_SUCCESS = 4;
-    private static final String TEST_PACKAGE_NAME = "com.test.example";
-    private static final String TEST_FQDN = "test.com";
-    private static final String TEST_PROVIDER_NAME = "test";
-    private static final int TEST_WIFI_STANDARD = ScanResult.WIFI_STANDARD_11AC;
-    private static final int TEST_MAX_SUPPORTED_TX_LINK_SPEED_MBPS = 866;
-    private static final int TEST_MAX_SUPPORTED_RX_LINK_SPEED_MBPS = 1200;
-    private static final String TEST_SSID = "Test123";
-    private static final String TEST_BSSID = "12:12:12:12:12:12";
-    private static final int TEST_RSSI = -60;
-    private static final int TEST_NETWORK_ID = 5;
-    private static final int TEST_NETWORK_ID2 = 6;
-
-    /**
-     *  Verify parcel write/read with WifiInfo.
-     */
-    @Test
-    public void testWifiInfoParcelWriteRead() throws Exception {
-        WifiInfo writeWifiInfo = new WifiInfo();
-        writeWifiInfo.txSuccess = TEST_TX_SUCCESS;
-        writeWifiInfo.txRetries = TEST_TX_RETRIES;
-        writeWifiInfo.txBad = TEST_TX_BAD;
-        writeWifiInfo.rxSuccess = TEST_RX_SUCCESS;
-        writeWifiInfo.setTrusted(true);
-        writeWifiInfo.setOsuAp(true);
-        writeWifiInfo.setFQDN(TEST_FQDN);
-        writeWifiInfo.setProviderFriendlyName(TEST_PROVIDER_NAME);
-        writeWifiInfo.setRequestingPackageName(TEST_PACKAGE_NAME);
-        writeWifiInfo.setWifiStandard(TEST_WIFI_STANDARD);
-        writeWifiInfo.setMaxSupportedTxLinkSpeedMbps(TEST_MAX_SUPPORTED_TX_LINK_SPEED_MBPS);
-        writeWifiInfo.setMaxSupportedRxLinkSpeedMbps(TEST_MAX_SUPPORTED_RX_LINK_SPEED_MBPS);
-
-        Parcel parcel = Parcel.obtain();
-        writeWifiInfo.writeToParcel(parcel, 0);
-        // Rewind the pointer to the head of the parcel.
-        parcel.setDataPosition(0);
-        WifiInfo readWifiInfo = WifiInfo.CREATOR.createFromParcel(parcel);
-
-        assertNotNull(readWifiInfo);
-        assertEquals(TEST_TX_SUCCESS, readWifiInfo.txSuccess);
-        assertEquals(TEST_TX_RETRIES, readWifiInfo.txRetries);
-        assertEquals(TEST_TX_BAD, readWifiInfo.txBad);
-        assertEquals(TEST_RX_SUCCESS, readWifiInfo.rxSuccess);
-        assertTrue(readWifiInfo.isTrusted());
-        assertTrue(readWifiInfo.isOsuAp());
-        assertTrue(readWifiInfo.isPasspointAp());
-        assertEquals(TEST_PACKAGE_NAME, readWifiInfo.getRequestingPackageName());
-        assertEquals(TEST_FQDN, readWifiInfo.getPasspointFqdn());
-        assertEquals(TEST_PROVIDER_NAME, readWifiInfo.getPasspointProviderFriendlyName());
-        assertEquals(TEST_WIFI_STANDARD, readWifiInfo.getWifiStandard());
-        assertEquals(TEST_MAX_SUPPORTED_TX_LINK_SPEED_MBPS,
-                readWifiInfo.getMaxSupportedTxLinkSpeedMbps());
-        assertEquals(TEST_MAX_SUPPORTED_RX_LINK_SPEED_MBPS,
-                readWifiInfo.getMaxSupportedRxLinkSpeedMbps());
-    }
-
-    /**
-     *  Verify values after reset()
-     */
-    @Test
-    public void testWifiInfoResetValue() throws Exception {
-        WifiInfo wifiInfo = new WifiInfo();
-        wifiInfo.reset();
-        assertEquals(WifiInfo.LINK_SPEED_UNKNOWN, wifiInfo.getMaxSupportedTxLinkSpeedMbps());
-        assertEquals(WifiInfo.LINK_SPEED_UNKNOWN, wifiInfo.getMaxSupportedRxLinkSpeedMbps());
-        assertEquals(WifiInfo.LINK_SPEED_UNKNOWN, wifiInfo.getTxLinkSpeedMbps());
-        assertEquals(WifiInfo.LINK_SPEED_UNKNOWN, wifiInfo.getRxLinkSpeedMbps());
-        assertEquals(WifiInfo.INVALID_RSSI, wifiInfo.getRssi());
-        assertEquals(WifiManager.UNKNOWN_SSID, wifiInfo.getSSID());
-        assertEquals(null, wifiInfo.getBSSID());
-        assertEquals(-1, wifiInfo.getNetworkId());
-    }
-
-    /**
-     * Test that the WifiInfo Builder returns the same values that was set, and that
-     * calling build multiple times returns different instances.
-     */
-    @Test
-    public void testWifiInfoBuilder() throws Exception {
-        WifiInfo.Builder builder = new WifiInfo.Builder()
-                .setSsid(TEST_SSID.getBytes(StandardCharsets.UTF_8))
-                .setBssid(TEST_BSSID)
-                .setRssi(TEST_RSSI)
-                .setNetworkId(TEST_NETWORK_ID);
-
-        WifiInfo info1 = builder.build();
-
-        assertEquals("\"" + TEST_SSID + "\"", info1.getSSID());
-        assertEquals(TEST_BSSID, info1.getBSSID());
-        assertEquals(TEST_RSSI, info1.getRssi());
-        assertEquals(TEST_NETWORK_ID, info1.getNetworkId());
-
-        WifiInfo info2 = builder
-                .setNetworkId(TEST_NETWORK_ID2)
-                .build();
-
-        // different instances
-        assertNotSame(info1, info2);
-
-        // assert that info1 didn't change
-        assertEquals("\"" + TEST_SSID + "\"", info1.getSSID());
-        assertEquals(TEST_BSSID, info1.getBSSID());
-        assertEquals(TEST_RSSI, info1.getRssi());
-        assertEquals(TEST_NETWORK_ID, info1.getNetworkId());
-
-        // assert that info2 changed
-        assertEquals("\"" + TEST_SSID + "\"", info2.getSSID());
-        assertEquals(TEST_BSSID, info2.getBSSID());
-        assertEquals(TEST_RSSI, info2.getRssi());
-        assertEquals(TEST_NETWORK_ID2, info2.getNetworkId());
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
deleted file mode 100644
index 1398bfe..0000000
--- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java
+++ /dev/null
@@ -1,2389 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import static android.net.wifi.WifiConfiguration.METERED_OVERRIDE_METERED;
-import static android.net.wifi.WifiManager.ActionListener;
-import static android.net.wifi.WifiManager.BUSY;
-import static android.net.wifi.WifiManager.ERROR;
-import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_GENERIC;
-import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_INCOMPATIBLE_MODE;
-import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_NO_CHANNEL;
-import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_TETHERING_DISALLOWED;
-import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.REQUEST_REGISTERED;
-import static android.net.wifi.WifiManager.NOT_AUTHORIZED;
-import static android.net.wifi.WifiManager.OnWifiActivityEnergyInfoListener;
-import static android.net.wifi.WifiManager.SAP_START_FAILURE_GENERAL;
-import static android.net.wifi.WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS;
-import static android.net.wifi.WifiManager.STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION;
-import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED;
-import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLING;
-import static android.net.wifi.WifiManager.WIFI_AP_STATE_FAILED;
-import static android.net.wifi.WifiManager.WIFI_FEATURE_DPP;
-import static android.net.wifi.WifiManager.WIFI_FEATURE_OWE;
-import static android.net.wifi.WifiManager.WIFI_FEATURE_P2P;
-import static android.net.wifi.WifiManager.WIFI_FEATURE_PASSPOINT;
-import static android.net.wifi.WifiManager.WIFI_FEATURE_SCANNER;
-import static android.net.wifi.WifiManager.WIFI_FEATURE_WPA3_SAE;
-import static android.net.wifi.WifiManager.WIFI_FEATURE_WPA3_SUITE_B;
-import static android.net.wifi.WifiManager.WpsCallback;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.nullable;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.anyInt;
-import static org.mockito.Mockito.anyList;
-import static org.mockito.Mockito.anyString;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
-
-import android.app.ActivityManager;
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.net.DhcpInfo;
-import android.net.MacAddress;
-import android.net.wifi.WifiManager.LocalOnlyHotspotCallback;
-import android.net.wifi.WifiManager.LocalOnlyHotspotObserver;
-import android.net.wifi.WifiManager.LocalOnlyHotspotReservation;
-import android.net.wifi.WifiManager.LocalOnlyHotspotSubscription;
-import android.net.wifi.WifiManager.NetworkRequestMatchCallback;
-import android.net.wifi.WifiManager.NetworkRequestUserSelectionCallback;
-import android.net.wifi.WifiManager.OnWifiUsabilityStatsListener;
-import android.net.wifi.WifiManager.ScanResultsCallback;
-import android.net.wifi.WifiManager.SoftApCallback;
-import android.net.wifi.WifiManager.SuggestionConnectionStatusListener;
-import android.net.wifi.WifiManager.TrafficStateCallback;
-import android.net.wifi.WifiManager.WifiConnectedNetworkScorer;
-import android.os.Binder;
-import android.os.Build;
-import android.os.Handler;
-import android.os.HandlerExecutor;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.os.connectivity.WifiActivityEnergyInfo;
-import android.os.test.TestLooper;
-import android.util.SparseArray;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.InOrder;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.concurrent.Executor;
-
-/**
- * Unit tests for {@link android.net.wifi.WifiManager}.
- */
-@SmallTest
-public class WifiManagerTest {
-
-    private static final int ERROR_NOT_SET = -1;
-    private static final int ERROR_TEST_REASON = 5;
-    private static final int TEST_UID = 14553;
-    private static final int TEST_NETWORK_ID = 143;
-    private static final String TEST_PACKAGE_NAME = "TestPackage";
-    private static final String TEST_FEATURE_ID = "TestFeature";
-    private static final String TEST_COUNTRY_CODE = "US";
-    private static final String[] TEST_MAC_ADDRESSES = {"da:a1:19:0:0:0"};
-    private static final int TEST_AP_FREQUENCY = 2412;
-    private static final int TEST_AP_BANDWIDTH = SoftApInfo.CHANNEL_WIDTH_20MHZ;
-
-    @Mock Context mContext;
-    @Mock android.net.wifi.IWifiManager mWifiService;
-    @Mock ApplicationInfo mApplicationInfo;
-    @Mock WifiConfiguration mApConfig;
-    @Mock SoftApCallback mSoftApCallback;
-    @Mock TrafficStateCallback mTrafficStateCallback;
-    @Mock NetworkRequestMatchCallback mNetworkRequestMatchCallback;
-    @Mock OnWifiUsabilityStatsListener mOnWifiUsabilityStatsListener;
-    @Mock OnWifiActivityEnergyInfoListener mOnWifiActivityEnergyInfoListener;
-    @Mock SuggestionConnectionStatusListener mListener;
-    @Mock Runnable mRunnable;
-    @Mock Executor mExecutor;
-    @Mock Executor mAnotherExecutor;
-    @Mock ActivityManager mActivityManager;
-    @Mock WifiConnectedNetworkScorer mWifiConnectedNetworkScorer;
-
-    private Handler mHandler;
-    private TestLooper mLooper;
-    private WifiManager mWifiManager;
-    private WifiNetworkSuggestion mWifiNetworkSuggestion;
-    private ScanResultsCallback mScanResultsCallback;
-    private WifiActivityEnergyInfo mWifiActivityEnergyInfo;
-
-    /**
-     * Util function to check public field which used for softap  in WifiConfiguration
-     * same as the value in SoftApConfiguration.
-     *
-     */
-    private boolean compareWifiAndSoftApConfiguration(
-            SoftApConfiguration softApConfig, WifiConfiguration wifiConfig) {
-        if (!Objects.equals(wifiConfig.SSID, softApConfig.getSsid())) {
-            return false;
-        }
-        if (!Objects.equals(wifiConfig.BSSID, softApConfig.getBssid())) {
-            return false;
-        }
-        if (!Objects.equals(wifiConfig.preSharedKey, softApConfig.getPassphrase())) {
-            return false;
-        }
-
-        if (wifiConfig.hiddenSSID != softApConfig.isHiddenSsid()) {
-            return false;
-        }
-        switch (softApConfig.getSecurityType()) {
-            case SoftApConfiguration.SECURITY_TYPE_OPEN:
-                if (wifiConfig.getAuthType() != WifiConfiguration.KeyMgmt.NONE) {
-                    return false;
-                }
-                break;
-            case SoftApConfiguration.SECURITY_TYPE_WPA2_PSK:
-                if (wifiConfig.getAuthType() != WifiConfiguration.KeyMgmt.WPA2_PSK) {
-                    return false;
-                }
-                break;
-            default:
-                return false;
-        }
-        return true;
-    }
-
-    private SoftApConfiguration generatorTestSoftApConfig() {
-        return new SoftApConfiguration.Builder()
-                .setSsid("TestSSID")
-                .setPassphrase("TestPassphrase", SoftApConfiguration.SECURITY_TYPE_WPA2_PSK)
-                .build();
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-        mLooper = new TestLooper();
-        mHandler = spy(new Handler(mLooper.getLooper()));
-        mApplicationInfo.targetSdkVersion = Build.VERSION_CODES.Q;
-        when(mContext.getApplicationInfo()).thenReturn(mApplicationInfo);
-        when(mContext.getOpPackageName()).thenReturn(TEST_PACKAGE_NAME);
-        mWifiManager = new WifiManager(mContext, mWifiService, mLooper.getLooper());
-        verify(mWifiService).getVerboseLoggingLevel();
-        mWifiNetworkSuggestion = new WifiNetworkSuggestion();
-        mScanResultsCallback = new ScanResultsCallback() {
-            @Override
-            public void onScanResultsAvailable() {
-                mRunnable.run();
-            }
-        };
-        mWifiActivityEnergyInfo = new WifiActivityEnergyInfo(0, 0, 0, 0, 0, 0);
-    }
-
-    /**
-     * Check the call to startSoftAp calls WifiService to startSoftAp with the provided
-     * WifiConfiguration.  Verify that the return value is propagated to the caller.
-     */
-    @Test
-    public void testStartSoftApCallsServiceWithWifiConfig() throws Exception {
-        when(mWifiService.startSoftAp(eq(mApConfig))).thenReturn(true);
-        assertTrue(mWifiManager.startSoftAp(mApConfig));
-
-        when(mWifiService.startSoftAp(eq(mApConfig))).thenReturn(false);
-        assertFalse(mWifiManager.startSoftAp(mApConfig));
-    }
-
-    /**
-     * Check the call to startSoftAp calls WifiService to startSoftAp with a null config.  Verify
-     * that the return value is propagated to the caller.
-     */
-    @Test
-    public void testStartSoftApCallsServiceWithNullConfig() throws Exception {
-        when(mWifiService.startSoftAp(eq(null))).thenReturn(true);
-        assertTrue(mWifiManager.startSoftAp(null));
-
-        when(mWifiService.startSoftAp(eq(null))).thenReturn(false);
-        assertFalse(mWifiManager.startSoftAp(null));
-    }
-
-    /**
-     * Check the call to stopSoftAp calls WifiService to stopSoftAp.
-     */
-    @Test
-    public void testStopSoftApCallsService() throws Exception {
-        when(mWifiService.stopSoftAp()).thenReturn(true);
-        assertTrue(mWifiManager.stopSoftAp());
-
-        when(mWifiService.stopSoftAp()).thenReturn(false);
-        assertFalse(mWifiManager.stopSoftAp());
-    }
-
-    /**
-     * Check the call to startSoftAp calls WifiService to startSoftAp with the provided
-     * WifiConfiguration.  Verify that the return value is propagated to the caller.
-     */
-    @Test
-    public void testStartTetheredHotspotCallsServiceWithSoftApConfig() throws Exception {
-        SoftApConfiguration softApConfig = generatorTestSoftApConfig();
-        when(mWifiService.startTetheredHotspot(eq(softApConfig))).thenReturn(true);
-        assertTrue(mWifiManager.startTetheredHotspot(softApConfig));
-
-        when(mWifiService.startTetheredHotspot(eq(softApConfig))).thenReturn(false);
-        assertFalse(mWifiManager.startTetheredHotspot(softApConfig));
-    }
-
-    /**
-     * Check the call to startSoftAp calls WifiService to startSoftAp with a null config.  Verify
-     * that the return value is propagated to the caller.
-     */
-    @Test
-    public void testStartTetheredHotspotCallsServiceWithNullConfig() throws Exception {
-        when(mWifiService.startTetheredHotspot(eq(null))).thenReturn(true);
-        assertTrue(mWifiManager.startTetheredHotspot(null));
-
-        when(mWifiService.startTetheredHotspot(eq(null))).thenReturn(false);
-        assertFalse(mWifiManager.startTetheredHotspot(null));
-    }
-
-    /**
-     * Test creation of a LocalOnlyHotspotReservation and verify that close properly calls
-     * WifiService.stopLocalOnlyHotspot.
-     */
-    @Test
-    public void testCreationAndCloseOfLocalOnlyHotspotReservation() throws Exception {
-        SoftApConfiguration softApConfig = generatorTestSoftApConfig();
-        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(),
-                nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED);
-        mWifiManager.startLocalOnlyHotspot(callback, mHandler);
-
-        callback.onStarted(mWifiManager.new LocalOnlyHotspotReservation(softApConfig));
-
-        assertEquals(softApConfig, callback.mRes.getSoftApConfiguration());
-        WifiConfiguration wifiConfig = callback.mRes.getWifiConfiguration();
-        assertTrue(compareWifiAndSoftApConfiguration(softApConfig, wifiConfig));
-
-        callback.mRes.close();
-        verify(mWifiService).stopLocalOnlyHotspot();
-    }
-
-    /**
-     * Verify stopLOHS is called when try-with-resources is used properly.
-     */
-    @Test
-    public void testLocalOnlyHotspotReservationCallsStopProperlyInTryWithResources()
-            throws Exception {
-        SoftApConfiguration softApConfig = generatorTestSoftApConfig();
-        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(),
-                nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED);
-        mWifiManager.startLocalOnlyHotspot(callback, mHandler);
-
-        callback.onStarted(mWifiManager.new LocalOnlyHotspotReservation(softApConfig));
-
-        try (WifiManager.LocalOnlyHotspotReservation res = callback.mRes) {
-            assertEquals(softApConfig, res.getSoftApConfiguration());
-            WifiConfiguration wifiConfig = callback.mRes.getWifiConfiguration();
-            assertTrue(compareWifiAndSoftApConfiguration(softApConfig, wifiConfig));
-        }
-
-        verify(mWifiService).stopLocalOnlyHotspot();
-    }
-
-    /**
-     * Test creation of a LocalOnlyHotspotSubscription.
-     * TODO: when registrations are tracked, verify removal on close.
-     */
-    @Test
-    public void testCreationOfLocalOnlyHotspotSubscription() throws Exception {
-        try (WifiManager.LocalOnlyHotspotSubscription sub =
-                     mWifiManager.new LocalOnlyHotspotSubscription()) {
-            sub.close();
-        }
-    }
-
-    public class TestLocalOnlyHotspotCallback extends LocalOnlyHotspotCallback {
-        public boolean mOnStartedCalled = false;
-        public boolean mOnStoppedCalled = false;
-        public int mFailureReason = -1;
-        public LocalOnlyHotspotReservation mRes = null;
-        public long mCallingThreadId = -1;
-
-        @Override
-        public void onStarted(LocalOnlyHotspotReservation r) {
-            mRes = r;
-            mOnStartedCalled = true;
-            mCallingThreadId = Thread.currentThread().getId();
-        }
-
-        @Override
-        public void onStopped() {
-            mOnStoppedCalled = true;
-            mCallingThreadId = Thread.currentThread().getId();
-        }
-
-        @Override
-        public void onFailed(int reason) {
-            mFailureReason = reason;
-            mCallingThreadId = Thread.currentThread().getId();
-        }
-    }
-
-    /**
-     * Verify callback is properly plumbed when called.
-     */
-    @Test
-    public void testLocalOnlyHotspotCallback() {
-        SoftApConfiguration softApConfig = generatorTestSoftApConfig();
-        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        assertFalse(callback.mOnStartedCalled);
-        assertFalse(callback.mOnStoppedCalled);
-        assertEquals(ERROR_NOT_SET, callback.mFailureReason);
-        assertEquals(null, callback.mRes);
-
-        // test onStarted
-        WifiManager.LocalOnlyHotspotReservation res =
-                mWifiManager.new LocalOnlyHotspotReservation(softApConfig);
-        callback.onStarted(res);
-        assertEquals(res, callback.mRes);
-        assertTrue(callback.mOnStartedCalled);
-        assertFalse(callback.mOnStoppedCalled);
-        assertEquals(ERROR_NOT_SET, callback.mFailureReason);
-
-        // test onStopped
-        callback.onStopped();
-        assertEquals(res, callback.mRes);
-        assertTrue(callback.mOnStartedCalled);
-        assertTrue(callback.mOnStoppedCalled);
-        assertEquals(ERROR_NOT_SET, callback.mFailureReason);
-
-        // test onFailed
-        callback.onFailed(ERROR_TEST_REASON);
-        assertEquals(res, callback.mRes);
-        assertTrue(callback.mOnStartedCalled);
-        assertTrue(callback.mOnStoppedCalled);
-        assertEquals(ERROR_TEST_REASON, callback.mFailureReason);
-    }
-
-    public class TestLocalOnlyHotspotObserver extends LocalOnlyHotspotObserver {
-        public boolean mOnRegistered = false;
-        public boolean mOnStartedCalled = false;
-        public boolean mOnStoppedCalled = false;
-        public SoftApConfiguration mConfig = null;
-        public LocalOnlyHotspotSubscription mSub = null;
-        public long mCallingThreadId = -1;
-
-        @Override
-        public void onRegistered(LocalOnlyHotspotSubscription sub) {
-            mOnRegistered = true;
-            mSub = sub;
-            mCallingThreadId = Thread.currentThread().getId();
-        }
-
-        @Override
-        public void onStarted(SoftApConfiguration config) {
-            mOnStartedCalled = true;
-            mConfig = config;
-            mCallingThreadId = Thread.currentThread().getId();
-        }
-
-        @Override
-        public void onStopped() {
-            mOnStoppedCalled = true;
-            mCallingThreadId = Thread.currentThread().getId();
-        }
-    }
-
-    /**
-     * Verify observer is properly plumbed when called.
-     */
-    @Test
-    public void testLocalOnlyHotspotObserver() {
-        TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
-        SoftApConfiguration softApConfig = generatorTestSoftApConfig();
-        assertFalse(observer.mOnRegistered);
-        assertFalse(observer.mOnStartedCalled);
-        assertFalse(observer.mOnStoppedCalled);
-        assertEquals(null, observer.mConfig);
-        assertEquals(null, observer.mSub);
-
-        WifiManager.LocalOnlyHotspotSubscription sub =
-                mWifiManager.new LocalOnlyHotspotSubscription();
-        observer.onRegistered(sub);
-        assertTrue(observer.mOnRegistered);
-        assertFalse(observer.mOnStartedCalled);
-        assertFalse(observer.mOnStoppedCalled);
-        assertEquals(null, observer.mConfig);
-        assertEquals(sub, observer.mSub);
-
-        observer.onStarted(softApConfig);
-        assertTrue(observer.mOnRegistered);
-        assertTrue(observer.mOnStartedCalled);
-        assertFalse(observer.mOnStoppedCalled);
-        assertEquals(softApConfig, observer.mConfig);
-        assertEquals(sub, observer.mSub);
-
-        observer.onStopped();
-        assertTrue(observer.mOnRegistered);
-        assertTrue(observer.mOnStartedCalled);
-        assertTrue(observer.mOnStoppedCalled);
-        assertEquals(softApConfig, observer.mConfig);
-        assertEquals(sub, observer.mSub);
-    }
-
-    /**
-     * Verify call to startLocalOnlyHotspot goes to WifiServiceImpl.
-     */
-    @Test
-    public void testStartLocalOnlyHotspot() throws Exception {
-        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        mWifiManager.startLocalOnlyHotspot(callback, mHandler);
-
-        verify(mWifiService).startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class),
-                anyString(), nullable(String.class), eq(null));
-    }
-
-    /**
-     * Verify a SecurityException is thrown for callers without proper permissions for
-     * startLocalOnlyHotspot.
-     */
-    @Test(expected = SecurityException.class)
-    public void testStartLocalOnlyHotspotThrowsSecurityException() throws Exception {
-        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        doThrow(new SecurityException()).when(mWifiService).startLocalOnlyHotspot(
-                any(ILocalOnlyHotspotCallback.class), anyString(), nullable(String.class),
-                eq(null));
-        mWifiManager.startLocalOnlyHotspot(callback, mHandler);
-    }
-
-    /**
-     * Verify an IllegalStateException is thrown for callers that already have a pending request for
-     * startLocalOnlyHotspot.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testStartLocalOnlyHotspotThrowsIllegalStateException() throws Exception {
-        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        doThrow(new IllegalStateException()).when(mWifiService).startLocalOnlyHotspot(
-                any(ILocalOnlyHotspotCallback.class), anyString(), nullable(String.class),
-                eq(null));
-        mWifiManager.startLocalOnlyHotspot(callback, mHandler);
-    }
-
-    /**
-     * Verify that the handler provided by the caller is used for the callbacks.
-     */
-    @Test
-    public void testCorrectLooperIsUsedForHandler() throws Exception {
-        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(),
-                nullable(String.class), eq(null))).thenReturn(ERROR_INCOMPATIBLE_MODE);
-        mWifiManager.startLocalOnlyHotspot(callback, mHandler);
-        mLooper.dispatchAll();
-        assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason);
-        verify(mContext, never()).getMainLooper();
-        verify(mContext, never()).getMainExecutor();
-    }
-
-    /**
-     * Verify that the main looper's thread is used if a handler is not provided by the reqiestomg
-     * application.
-     */
-    @Test
-    public void testMainLooperIsUsedWhenHandlerNotProvided() throws Exception {
-        // record thread from looper.getThread and check ids.
-        TestLooper altLooper = new TestLooper();
-        when(mContext.getMainExecutor()).thenReturn(altLooper.getNewExecutor());
-        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(),
-                nullable(String.class), eq(null))).thenReturn(ERROR_INCOMPATIBLE_MODE);
-        mWifiManager.startLocalOnlyHotspot(callback, null);
-        altLooper.dispatchAll();
-        assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason);
-        assertEquals(altLooper.getLooper().getThread().getId(), callback.mCallingThreadId);
-        verify(mContext).getMainExecutor();
-    }
-
-    /**
-     * Verify the LOHS onStarted callback is triggered when WifiManager receives a HOTSPOT_STARTED
-     * message from WifiServiceImpl.
-     */
-    @Test
-    public void testOnStartedIsCalledWithReservation() throws Exception {
-        SoftApConfiguration softApConfig = generatorTestSoftApConfig();
-        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        TestLooper callbackLooper = new TestLooper();
-        Handler callbackHandler = new Handler(callbackLooper.getLooper());
-        ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback =
-                ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class);
-        when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString(),
-                nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED);
-        mWifiManager.startLocalOnlyHotspot(callback, callbackHandler);
-        callbackLooper.dispatchAll();
-        mLooper.dispatchAll();
-        assertFalse(callback.mOnStartedCalled);
-        assertEquals(null, callback.mRes);
-        // now trigger the callback
-        internalCallback.getValue().onHotspotStarted(softApConfig);
-        mLooper.dispatchAll();
-        callbackLooper.dispatchAll();
-        assertTrue(callback.mOnStartedCalled);
-        assertEquals(softApConfig, callback.mRes.getSoftApConfiguration());
-        WifiConfiguration wifiConfig = callback.mRes.getWifiConfiguration();
-        assertTrue(compareWifiAndSoftApConfiguration(softApConfig, wifiConfig));
-    }
-
-    /**
-     * Verify the LOHS onStarted callback is triggered when WifiManager receives a HOTSPOT_STARTED
-     * message from WifiServiceImpl when softap enabled with SAE security type.
-     */
-    @Test
-    public void testOnStartedIsCalledWithReservationAndSaeSoftApConfig() throws Exception {
-        SoftApConfiguration softApConfig = new SoftApConfiguration.Builder()
-                .setSsid("TestSSID")
-                .setPassphrase("TestPassphrase", SoftApConfiguration.SECURITY_TYPE_WPA3_SAE)
-                .build();
-        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        TestLooper callbackLooper = new TestLooper();
-        Handler callbackHandler = new Handler(callbackLooper.getLooper());
-        ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback =
-                ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class);
-        when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString(),
-                nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED);
-        mWifiManager.startLocalOnlyHotspot(callback, callbackHandler);
-        callbackLooper.dispatchAll();
-        mLooper.dispatchAll();
-        assertFalse(callback.mOnStartedCalled);
-        assertEquals(null, callback.mRes);
-        // now trigger the callback
-        internalCallback.getValue().onHotspotStarted(softApConfig);
-        mLooper.dispatchAll();
-        callbackLooper.dispatchAll();
-        assertTrue(callback.mOnStartedCalled);
-        assertEquals(softApConfig, callback.mRes.getSoftApConfiguration());
-        assertEquals(null, callback.mRes.getWifiConfiguration());
-    }
-
-    /**
-     * Verify onFailed is called if WifiServiceImpl sends a HOTSPOT_STARTED message with a null
-     * config.
-     */
-    @Test
-    public void testOnStartedIsCalledWithNullConfig() throws Exception {
-        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        TestLooper callbackLooper = new TestLooper();
-        Handler callbackHandler = new Handler(callbackLooper.getLooper());
-        ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback =
-                ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class);
-        when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString(),
-                nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED);
-        mWifiManager.startLocalOnlyHotspot(callback, callbackHandler);
-        callbackLooper.dispatchAll();
-        mLooper.dispatchAll();
-        assertFalse(callback.mOnStartedCalled);
-        assertEquals(null, callback.mRes);
-        // now trigger the callback
-        internalCallback.getValue().onHotspotStarted(null);
-        mLooper.dispatchAll();
-        callbackLooper.dispatchAll();
-        assertFalse(callback.mOnStartedCalled);
-        assertEquals(ERROR_GENERIC, callback.mFailureReason);
-    }
-
-    /**
-     * Verify onStopped is called if WifiServiceImpl sends a HOTSPOT_STOPPED message.
-     */
-    @Test
-    public void testOnStoppedIsCalled() throws Exception {
-        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        TestLooper callbackLooper = new TestLooper();
-        Handler callbackHandler = new Handler(callbackLooper.getLooper());
-        ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback =
-                ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class);
-        when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString(),
-                nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED);
-        mWifiManager.startLocalOnlyHotspot(callback, callbackHandler);
-        callbackLooper.dispatchAll();
-        mLooper.dispatchAll();
-        assertFalse(callback.mOnStoppedCalled);
-        // now trigger the callback
-        internalCallback.getValue().onHotspotStopped();
-        mLooper.dispatchAll();
-        callbackLooper.dispatchAll();
-        assertTrue(callback.mOnStoppedCalled);
-    }
-
-    /**
-     * Verify onFailed is called if WifiServiceImpl sends a HOTSPOT_FAILED message.
-     */
-    @Test
-    public void testOnFailedIsCalled() throws Exception {
-        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        TestLooper callbackLooper = new TestLooper();
-        Handler callbackHandler = new Handler(callbackLooper.getLooper());
-        ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback =
-                ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class);
-        when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString(),
-                nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED);
-        mWifiManager.startLocalOnlyHotspot(callback, callbackHandler);
-        callbackLooper.dispatchAll();
-        mLooper.dispatchAll();
-        assertEquals(ERROR_NOT_SET, callback.mFailureReason);
-        // now trigger the callback
-        internalCallback.getValue().onHotspotFailed(ERROR_NO_CHANNEL);
-        mLooper.dispatchAll();
-        callbackLooper.dispatchAll();
-        assertEquals(ERROR_NO_CHANNEL, callback.mFailureReason);
-    }
-
-    /**
-     * Verify callback triggered from startLocalOnlyHotspot with an incompatible mode failure.
-     */
-    @Test
-    public void testLocalOnlyHotspotCallbackFullOnIncompatibleMode() throws Exception {
-        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(),
-                nullable(String.class), eq(null))).thenReturn(ERROR_INCOMPATIBLE_MODE);
-        mWifiManager.startLocalOnlyHotspot(callback, mHandler);
-        mLooper.dispatchAll();
-        assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason);
-        assertFalse(callback.mOnStartedCalled);
-        assertFalse(callback.mOnStoppedCalled);
-        assertEquals(null, callback.mRes);
-    }
-
-    /**
-     * Verify callback triggered from startLocalOnlyHotspot with a tethering disallowed failure.
-     */
-    @Test
-    public void testLocalOnlyHotspotCallbackFullOnTetheringDisallowed() throws Exception {
-        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(),
-                nullable(String.class), eq(null))).thenReturn(ERROR_TETHERING_DISALLOWED);
-        mWifiManager.startLocalOnlyHotspot(callback, mHandler);
-        mLooper.dispatchAll();
-        assertEquals(ERROR_TETHERING_DISALLOWED, callback.mFailureReason);
-        assertFalse(callback.mOnStartedCalled);
-        assertFalse(callback.mOnStoppedCalled);
-        assertEquals(null, callback.mRes);
-    }
-
-    /**
-     * Verify a SecurityException resulting from an application without necessary permissions will
-     * bubble up through the call to start LocalOnlyHotspot and will not trigger other callbacks.
-     */
-    @Test(expected = SecurityException.class)
-    public void testLocalOnlyHotspotCallbackFullOnSecurityException() throws Exception {
-        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        doThrow(new SecurityException()).when(mWifiService).startLocalOnlyHotspot(
-                any(ILocalOnlyHotspotCallback.class), anyString(), nullable(String.class),
-                eq(null));
-        try {
-            mWifiManager.startLocalOnlyHotspot(callback, mHandler);
-        } catch (SecurityException e) {
-            assertEquals(ERROR_NOT_SET, callback.mFailureReason);
-            assertFalse(callback.mOnStartedCalled);
-            assertFalse(callback.mOnStoppedCalled);
-            assertEquals(null, callback.mRes);
-            throw e;
-        }
-
-    }
-
-    /**
-     * Verify the handler passed to startLocalOnlyHotspot is correctly used for callbacks when
-     * SoftApMode fails due to a underlying error.
-     */
-    @Test
-    public void testLocalOnlyHotspotCallbackFullOnNoChannelError() throws Exception {
-        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(),
-                nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED);
-        mWifiManager.startLocalOnlyHotspot(callback, mHandler);
-        mLooper.dispatchAll();
-        //assertEquals(ERROR_NO_CHANNEL, callback.mFailureReason);
-        assertFalse(callback.mOnStartedCalled);
-        assertFalse(callback.mOnStoppedCalled);
-        assertEquals(null, callback.mRes);
-    }
-
-    /**
-     * Verify that the call to cancel a LOHS request does call stopLOHS.
-     */
-    @Test
-    public void testCancelLocalOnlyHotspotRequestCallsStopOnWifiService() throws Exception {
-        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(),
-                nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED);
-        mWifiManager.startLocalOnlyHotspot(callback, mHandler);
-        mWifiManager.cancelLocalOnlyHotspotRequest();
-        verify(mWifiService).stopLocalOnlyHotspot();
-    }
-
-    /**
-     * Verify that we do not crash if cancelLocalOnlyHotspotRequest is called without an existing
-     * callback stored.
-     */
-    @Test
-    public void testCancelLocalOnlyHotspotReturnsWithoutExistingRequest() {
-        mWifiManager.cancelLocalOnlyHotspotRequest();
-    }
-
-    /**
-     * Verify that the callback is not triggered if the LOHS request was already cancelled.
-     */
-    @Test
-    public void testCallbackAfterLocalOnlyHotspotWasCancelled() throws Exception {
-        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(),
-                nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED);
-        mWifiManager.startLocalOnlyHotspot(callback, mHandler);
-        mWifiManager.cancelLocalOnlyHotspotRequest();
-        verify(mWifiService).stopLocalOnlyHotspot();
-        mLooper.dispatchAll();
-        assertEquals(ERROR_NOT_SET, callback.mFailureReason);
-        assertFalse(callback.mOnStartedCalled);
-        assertFalse(callback.mOnStoppedCalled);
-        assertEquals(null, callback.mRes);
-    }
-
-    /**
-     * Verify that calling cancel LOHS request does not crash if an error callback was already
-     * handled.
-     */
-    @Test
-    public void testCancelAfterLocalOnlyHotspotCallbackTriggered() throws Exception {
-        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(),
-                nullable(String.class), eq(null))).thenReturn(ERROR_INCOMPATIBLE_MODE);
-        mWifiManager.startLocalOnlyHotspot(callback, mHandler);
-        mLooper.dispatchAll();
-        assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason);
-        assertFalse(callback.mOnStartedCalled);
-        assertFalse(callback.mOnStoppedCalled);
-        assertEquals(null, callback.mRes);
-        mWifiManager.cancelLocalOnlyHotspotRequest();
-        verify(mWifiService, never()).stopLocalOnlyHotspot();
-    }
-
-    @Test
-    public void testStartLocalOnlyHotspotForwardsCustomConfig() throws Exception {
-        SoftApConfiguration customConfig = new SoftApConfiguration.Builder()
-                .setSsid("customSsid")
-                .build();
-        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        mWifiManager.startLocalOnlyHotspot(customConfig, mExecutor, callback);
-        verify(mWifiService).startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class),
-                anyString(), nullable(String.class), eq(customConfig));
-    }
-
-    /**
-     * Verify the watchLocalOnlyHotspot call goes to WifiServiceImpl.
-     */
-    @Test
-    public void testWatchLocalOnlyHotspot() throws Exception {
-        TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
-
-        mWifiManager.watchLocalOnlyHotspot(observer, mHandler);
-        verify(mWifiService).startWatchLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class));
-    }
-
-    /**
-     * Verify a SecurityException is thrown for callers without proper permissions for
-     * startWatchLocalOnlyHotspot.
-     */
-    @Test(expected = SecurityException.class)
-    public void testStartWatchLocalOnlyHotspotThrowsSecurityException() throws Exception {
-        TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
-        doThrow(new SecurityException()).when(mWifiService)
-                .startWatchLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class));
-        mWifiManager.watchLocalOnlyHotspot(observer, mHandler);
-    }
-
-    /**
-     * Verify an IllegalStateException is thrown for callers that already have a pending request for
-     * watchLocalOnlyHotspot.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testStartWatchLocalOnlyHotspotThrowsIllegalStateException() throws Exception {
-        TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
-        doThrow(new IllegalStateException()).when(mWifiService)
-                .startWatchLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class));
-        mWifiManager.watchLocalOnlyHotspot(observer, mHandler);
-    }
-
-    /**
-     * Verify an IllegalArgumentException is thrown if callback is not provided.
-     */
-    @Test
-    public void registerSoftApCallbackThrowsIllegalArgumentExceptionOnNullArgumentForCallback() {
-        try {
-            mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), null);
-            fail("expected IllegalArgumentException");
-        } catch (IllegalArgumentException expected) {
-        }
-    }
-
-    /**
-     * Verify an IllegalArgumentException is thrown if executor is null.
-     */
-    @Test
-    public void registerSoftApCallbackThrowsIllegalArgumentExceptionOnNullArgumentForExecutor() {
-        try {
-            mWifiManager.registerSoftApCallback(null, mSoftApCallback);
-            fail("expected IllegalArgumentException");
-        } catch (IllegalArgumentException expected) {
-        }
-    }
-
-    /**
-     * Verify an IllegalArgumentException is thrown if callback is not provided.
-     */
-    @Test
-    public void unregisterSoftApCallbackThrowsIllegalArgumentExceptionOnNullArgumentForCallback() {
-        try {
-            mWifiManager.unregisterSoftApCallback(null);
-            fail("expected IllegalArgumentException");
-        } catch (IllegalArgumentException expected) {
-        }
-    }
-
-    /**
-     * Verify the call to registerSoftApCallback goes to WifiServiceImpl.
-     */
-    @Test
-    public void registerSoftApCallbackCallGoesToWifiServiceImpl() throws Exception {
-        mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
-        verify(mWifiService).registerSoftApCallback(any(IBinder.class),
-                any(ISoftApCallback.Stub.class), anyInt());
-    }
-
-    /**
-     * Verify the call to unregisterSoftApCallback goes to WifiServiceImpl.
-     */
-    @Test
-    public void unregisterSoftApCallbackCallGoesToWifiServiceImpl() throws Exception {
-        ArgumentCaptor<Integer> callbackIdentifier = ArgumentCaptor.forClass(Integer.class);
-        mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
-        verify(mWifiService).registerSoftApCallback(any(IBinder.class),
-                any(ISoftApCallback.Stub.class), callbackIdentifier.capture());
-
-        mWifiManager.unregisterSoftApCallback(mSoftApCallback);
-        verify(mWifiService).unregisterSoftApCallback(eq((int) callbackIdentifier.getValue()));
-    }
-
-    /*
-     * Verify client-provided callback is being called through callback proxy
-     */
-    @Test
-    public void softApCallbackProxyCallsOnStateChanged() throws Exception {
-        ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor =
-                ArgumentCaptor.forClass(ISoftApCallback.Stub.class);
-        mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
-        verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(),
-                anyInt());
-
-        callbackCaptor.getValue().onStateChanged(WIFI_AP_STATE_ENABLED, 0);
-        mLooper.dispatchAll();
-        verify(mSoftApCallback).onStateChanged(WIFI_AP_STATE_ENABLED, 0);
-    }
-
-    /*
-     * Verify client-provided callback is being called through callback proxy
-     */
-    @Test
-    public void softApCallbackProxyCallsOnConnectedClientsChanged() throws Exception {
-        ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor =
-                ArgumentCaptor.forClass(ISoftApCallback.Stub.class);
-        mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
-        verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(),
-                anyInt());
-
-        final List<WifiClient> testClients = new ArrayList();
-        callbackCaptor.getValue().onConnectedClientsChanged(testClients);
-        mLooper.dispatchAll();
-        verify(mSoftApCallback).onConnectedClientsChanged(testClients);
-    }
-
-
-    /*
-     * Verify client-provided callback is being called through callback proxy
-     */
-    @Test
-    public void softApCallbackProxyCallsOnSoftApInfoChanged() throws Exception {
-        SoftApInfo testSoftApInfo = new SoftApInfo();
-        testSoftApInfo.setFrequency(TEST_AP_FREQUENCY);
-        testSoftApInfo.setBandwidth(TEST_AP_BANDWIDTH);
-        ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor =
-                ArgumentCaptor.forClass(ISoftApCallback.Stub.class);
-        mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
-        verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(),
-                anyInt());
-
-        callbackCaptor.getValue().onInfoChanged(testSoftApInfo);
-        mLooper.dispatchAll();
-        verify(mSoftApCallback).onInfoChanged(testSoftApInfo);
-    }
-
-
-    /*
-     * Verify client-provided callback is being called through callback proxy
-     */
-    @Test
-    public void softApCallbackProxyCallsOnCapabilityChanged() throws Exception {
-        SoftApCapability testSoftApCapability = new SoftApCapability(0);
-        testSoftApCapability.setMaxSupportedClients(10);
-        ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor =
-                ArgumentCaptor.forClass(ISoftApCallback.Stub.class);
-        mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
-        verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(),
-                anyInt());
-
-        callbackCaptor.getValue().onCapabilityChanged(testSoftApCapability);
-        mLooper.dispatchAll();
-        verify(mSoftApCallback).onCapabilityChanged(testSoftApCapability);
-    }
-
-    /*
-     * Verify client-provided callback is being called through callback proxy
-     */
-    @Test
-    public void softApCallbackProxyCallsOnBlockedClientConnecting() throws Exception {
-        WifiClient testWifiClient = new WifiClient(MacAddress.fromString("22:33:44:55:66:77"));
-        ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor =
-                ArgumentCaptor.forClass(ISoftApCallback.Stub.class);
-        mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
-        verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(),
-                anyInt());
-
-        callbackCaptor.getValue().onBlockedClientConnecting(testWifiClient,
-                WifiManager.SAP_CLIENT_BLOCK_REASON_CODE_NO_MORE_STAS);
-        mLooper.dispatchAll();
-        verify(mSoftApCallback).onBlockedClientConnecting(testWifiClient,
-                WifiManager.SAP_CLIENT_BLOCK_REASON_CODE_NO_MORE_STAS);
-    }
-
-    /*
-     * Verify client-provided callback is being called through callback proxy on multiple events
-     */
-    @Test
-    public void softApCallbackProxyCallsOnMultipleUpdates() throws Exception {
-        SoftApInfo testSoftApInfo = new SoftApInfo();
-        testSoftApInfo.setFrequency(TEST_AP_FREQUENCY);
-        testSoftApInfo.setBandwidth(TEST_AP_BANDWIDTH);
-        SoftApCapability testSoftApCapability = new SoftApCapability(0);
-        testSoftApCapability.setMaxSupportedClients(10);
-        ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor =
-                ArgumentCaptor.forClass(ISoftApCallback.Stub.class);
-        mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
-        verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(),
-                anyInt());
-
-        final List<WifiClient> testClients = new ArrayList();
-        callbackCaptor.getValue().onStateChanged(WIFI_AP_STATE_ENABLING, 0);
-        callbackCaptor.getValue().onConnectedClientsChanged(testClients);
-        callbackCaptor.getValue().onInfoChanged(testSoftApInfo);
-        callbackCaptor.getValue().onStateChanged(WIFI_AP_STATE_FAILED, SAP_START_FAILURE_GENERAL);
-        callbackCaptor.getValue().onCapabilityChanged(testSoftApCapability);
-
-
-        mLooper.dispatchAll();
-        verify(mSoftApCallback).onStateChanged(WIFI_AP_STATE_ENABLING, 0);
-        verify(mSoftApCallback).onConnectedClientsChanged(testClients);
-        verify(mSoftApCallback).onInfoChanged(testSoftApInfo);
-        verify(mSoftApCallback).onStateChanged(WIFI_AP_STATE_FAILED, SAP_START_FAILURE_GENERAL);
-        verify(mSoftApCallback).onCapabilityChanged(testSoftApCapability);
-    }
-
-    /*
-     * Verify client-provided callback is being called on the correct thread
-     */
-    @Test
-    public void softApCallbackIsCalledOnCorrectThread() throws Exception {
-        ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor =
-                ArgumentCaptor.forClass(ISoftApCallback.Stub.class);
-        TestLooper altLooper = new TestLooper();
-        Handler altHandler = new Handler(altLooper.getLooper());
-        mWifiManager.registerSoftApCallback(new HandlerExecutor(altHandler), mSoftApCallback);
-        verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(),
-                anyInt());
-
-        callbackCaptor.getValue().onStateChanged(WIFI_AP_STATE_ENABLED, 0);
-        altLooper.dispatchAll();
-        verify(mSoftApCallback).onStateChanged(WIFI_AP_STATE_ENABLED, 0);
-    }
-
-    /**
-     * Verify that the handler provided by the caller is used for registering soft AP callback.
-     */
-    @Test
-    public void testCorrectLooperIsUsedForSoftApCallbackHandler() throws Exception {
-        mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
-        mLooper.dispatchAll();
-        verify(mWifiService).registerSoftApCallback(any(IBinder.class),
-                any(ISoftApCallback.Stub.class), anyInt());
-        verify(mContext, never()).getMainLooper();
-        verify(mContext, never()).getMainExecutor();
-    }
-
-    /**
-     * Verify that the handler provided by the caller is used for the observer.
-     */
-    @Test
-    public void testCorrectLooperIsUsedForObserverHandler() throws Exception {
-        TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
-        mWifiManager.watchLocalOnlyHotspot(observer, mHandler);
-        mLooper.dispatchAll();
-        assertTrue(observer.mOnRegistered);
-        verify(mContext, never()).getMainLooper();
-        verify(mContext, never()).getMainExecutor();
-    }
-
-    /**
-     * Verify that the main looper's thread is used if a handler is not provided by the requesting
-     * application.
-     */
-    @Test
-    public void testMainLooperIsUsedWhenHandlerNotProvidedForObserver() throws Exception {
-        // record thread from looper.getThread and check ids.
-        TestLooper altLooper = new TestLooper();
-        when(mContext.getMainExecutor()).thenReturn(altLooper.getNewExecutor());
-        TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
-        mWifiManager.watchLocalOnlyHotspot(observer, null);
-        altLooper.dispatchAll();
-        assertTrue(observer.mOnRegistered);
-        assertEquals(altLooper.getLooper().getThread().getId(), observer.mCallingThreadId);
-        verify(mContext).getMainExecutor();
-    }
-
-    /**
-     * Verify the LOHS onRegistered observer callback is triggered when WifiManager receives a
-     * HOTSPOT_OBSERVER_REGISTERED message from WifiServiceImpl.
-     */
-    @Test
-    public void testOnRegisteredIsCalledWithSubscription() throws Exception {
-        TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
-        TestLooper observerLooper = new TestLooper();
-        Handler observerHandler = new Handler(observerLooper.getLooper());
-        assertFalse(observer.mOnRegistered);
-        assertEquals(null, observer.mSub);
-        mWifiManager.watchLocalOnlyHotspot(observer, observerHandler);
-        verify(mWifiService).startWatchLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class));
-        // now trigger the callback
-        observerLooper.dispatchAll();
-        mLooper.dispatchAll();
-        assertTrue(observer.mOnRegistered);
-        assertNotNull(observer.mSub);
-    }
-
-    /**
-     * Verify the LOHS onStarted observer callback is triggered when WifiManager receives a
-     * HOTSPOT_STARTED message from WifiServiceImpl.
-     */
-    @Test
-    public void testObserverOnStartedIsCalledWithWifiConfig() throws Exception {
-        SoftApConfiguration softApConfig = generatorTestSoftApConfig();
-        TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
-        TestLooper observerLooper = new TestLooper();
-        Handler observerHandler = new Handler(observerLooper.getLooper());
-        mWifiManager.watchLocalOnlyHotspot(observer, observerHandler);
-        ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback =
-                ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class);
-        verify(mWifiService).startWatchLocalOnlyHotspot(internalCallback.capture());
-        observerLooper.dispatchAll();
-        mLooper.dispatchAll();
-        assertFalse(observer.mOnStartedCalled);
-        // now trigger the callback
-        internalCallback.getValue().onHotspotStarted(softApConfig);
-        mLooper.dispatchAll();
-        observerLooper.dispatchAll();
-        assertTrue(observer.mOnStartedCalled);
-        assertEquals(softApConfig, observer.mConfig);
-    }
-
-    /**
-     * Verify the LOHS onStarted observer callback is triggered not when WifiManager receives a
-     * HOTSPOT_STARTED message from WifiServiceImpl with a null config.
-     */
-    @Test
-    public void testObserverOnStartedNotCalledWithNullConfig() throws Exception {
-        TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
-        TestLooper observerLooper = new TestLooper();
-        Handler observerHandler = new Handler(observerLooper.getLooper());
-        mWifiManager.watchLocalOnlyHotspot(observer, observerHandler);
-        ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback =
-                ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class);
-        verify(mWifiService).startWatchLocalOnlyHotspot(internalCallback.capture());
-        observerLooper.dispatchAll();
-        mLooper.dispatchAll();
-        assertFalse(observer.mOnStartedCalled);
-        // now trigger the callback
-        internalCallback.getValue().onHotspotStarted(null);
-        mLooper.dispatchAll();
-        observerLooper.dispatchAll();
-        assertFalse(observer.mOnStartedCalled);
-        assertEquals(null, observer.mConfig);
-    }
-
-
-    /**
-     * Verify the LOHS onStopped observer callback is triggered when WifiManager receives a
-     * HOTSPOT_STOPPED message from WifiServiceImpl.
-     */
-    @Test
-    public void testObserverOnStoppedIsCalled() throws Exception {
-        TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
-        TestLooper observerLooper = new TestLooper();
-        Handler observerHandler = new Handler(observerLooper.getLooper());
-        mWifiManager.watchLocalOnlyHotspot(observer, observerHandler);
-        ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback =
-                ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class);
-        verify(mWifiService).startWatchLocalOnlyHotspot(internalCallback.capture());
-        observerLooper.dispatchAll();
-        mLooper.dispatchAll();
-        assertFalse(observer.mOnStoppedCalled);
-        // now trigger the callback
-        internalCallback.getValue().onHotspotStopped();
-        mLooper.dispatchAll();
-        observerLooper.dispatchAll();
-        assertTrue(observer.mOnStoppedCalled);
-    }
-
-    /**
-     * Verify WifiServiceImpl is not called if there is not a registered LOHS observer callback.
-     */
-    @Test
-    public void testUnregisterWifiServiceImplNotCalledWithoutRegisteredObserver() throws Exception {
-        mWifiManager.unregisterLocalOnlyHotspotObserver();
-        verifyZeroInteractions(mWifiService);
-    }
-
-    /**
-     * Verify WifiServiceImpl is called when there is a registered LOHS observer callback.
-     */
-    @Test
-    public void testUnregisterWifiServiceImplCalledWithRegisteredObserver() throws Exception {
-        TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
-        TestLooper observerLooper = new TestLooper();
-        Handler observerHandler = new Handler(observerLooper.getLooper());
-        mWifiManager.watchLocalOnlyHotspot(observer, observerHandler);
-        mWifiManager.unregisterLocalOnlyHotspotObserver();
-        verify(mWifiService).stopWatchLocalOnlyHotspot();
-    }
-
-    /**
-     * Test that calls to get the current WPS config token return null and do not have any
-     * interactions with WifiServiceImpl.
-     */
-    @Test
-    public void testGetCurrentNetworkWpsNfcConfigurationTokenReturnsNull() {
-        assertNull(mWifiManager.getCurrentNetworkWpsNfcConfigurationToken());
-        verifyNoMoreInteractions(mWifiService);
-    }
-
-
-    class WpsCallbackTester extends WpsCallback {
-        public boolean mStarted = false;
-        public boolean mSucceeded = false;
-        public boolean mFailed = false;
-        public int mFailureCode = -1;
-
-        @Override
-        public void onStarted(String pin) {
-            mStarted = true;
-        }
-
-        @Override
-        public void onSucceeded() {
-            mSucceeded = true;
-        }
-
-        @Override
-        public void onFailed(int reason) {
-            mFailed = true;
-            mFailureCode = reason;
-        }
-
-    }
-
-    /**
-     * Verify that a call to start WPS immediately returns a failure.
-     */
-    @Test
-    public void testStartWpsImmediatelyFailsWithCallback() {
-        WpsCallbackTester wpsCallback = new WpsCallbackTester();
-        mWifiManager.startWps(null, wpsCallback);
-        assertTrue(wpsCallback.mFailed);
-        assertEquals(ERROR, wpsCallback.mFailureCode);
-        assertFalse(wpsCallback.mStarted);
-        assertFalse(wpsCallback.mSucceeded);
-        verifyNoMoreInteractions(mWifiService);
-    }
-
-    /**
-     * Verify that a call to start WPS does not go to WifiServiceImpl if we do not have a callback.
-     */
-    @Test
-    public void testStartWpsDoesNotCallWifiServiceImpl() {
-        mWifiManager.startWps(null, null);
-        verifyNoMoreInteractions(mWifiService);
-    }
-
-    /**
-     * Verify that a call to cancel WPS immediately returns a failure.
-     */
-    @Test
-    public void testCancelWpsImmediatelyFailsWithCallback() {
-        WpsCallbackTester wpsCallback = new WpsCallbackTester();
-        mWifiManager.cancelWps(wpsCallback);
-        assertTrue(wpsCallback.mFailed);
-        assertEquals(ERROR, wpsCallback.mFailureCode);
-        assertFalse(wpsCallback.mStarted);
-        assertFalse(wpsCallback.mSucceeded);
-        verifyNoMoreInteractions(mWifiService);
-    }
-
-    /**
-     * Verify that a call to cancel WPS does not go to WifiServiceImpl if we do not have a callback.
-     */
-    @Test
-    public void testCancelWpsDoesNotCallWifiServiceImpl() {
-        mWifiManager.cancelWps(null);
-        verifyNoMoreInteractions(mWifiService);
-    }
-
-    /**
-     * Verify that a successful call properly returns true.
-     */
-    @Test
-    public void testSetWifiApConfigurationSuccessReturnsTrue() throws Exception {
-        WifiConfiguration apConfig = new WifiConfiguration();
-
-        when(mWifiService.setWifiApConfiguration(eq(apConfig), eq(TEST_PACKAGE_NAME)))
-                .thenReturn(true);
-        assertTrue(mWifiManager.setWifiApConfiguration(apConfig));
-    }
-
-    /**
-     * Verify that a failed call properly returns false.
-     */
-    @Test
-    public void testSetWifiApConfigurationFailureReturnsFalse() throws Exception {
-        WifiConfiguration apConfig = new WifiConfiguration();
-
-        when(mWifiService.setWifiApConfiguration(eq(apConfig), eq(TEST_PACKAGE_NAME)))
-                .thenReturn(false);
-        assertFalse(mWifiManager.setWifiApConfiguration(apConfig));
-    }
-
-    /**
-     * Verify Exceptions are rethrown when underlying calls to WifiService throw exceptions.
-     */
-    @Test
-    public void testSetWifiApConfigurationRethrowsException() throws Exception {
-        doThrow(new SecurityException()).when(mWifiService).setWifiApConfiguration(any(), any());
-
-        try {
-            mWifiManager.setWifiApConfiguration(new WifiConfiguration());
-            fail("setWifiApConfiguration should rethrow Exceptions from WifiService");
-        } catch (SecurityException e) { }
-    }
-
-    /**
-     * Verify that a successful call properly returns true.
-     */
-    @Test
-    public void testSetSoftApConfigurationSuccessReturnsTrue() throws Exception {
-        SoftApConfiguration apConfig = generatorTestSoftApConfig();
-
-        when(mWifiService.setSoftApConfiguration(eq(apConfig), eq(TEST_PACKAGE_NAME)))
-                .thenReturn(true);
-        assertTrue(mWifiManager.setSoftApConfiguration(apConfig));
-    }
-
-    /**
-     * Verify that a failed call properly returns false.
-     */
-    @Test
-    public void testSetSoftApConfigurationFailureReturnsFalse() throws Exception {
-        SoftApConfiguration apConfig = generatorTestSoftApConfig();
-
-        when(mWifiService.setSoftApConfiguration(eq(apConfig), eq(TEST_PACKAGE_NAME)))
-                .thenReturn(false);
-        assertFalse(mWifiManager.setSoftApConfiguration(apConfig));
-    }
-
-    /**
-     * Verify Exceptions are rethrown when underlying calls to WifiService throw exceptions.
-     */
-    @Test
-    public void testSetSoftApConfigurationRethrowsException() throws Exception {
-        doThrow(new SecurityException()).when(mWifiService).setSoftApConfiguration(any(), any());
-
-        try {
-            mWifiManager.setSoftApConfiguration(generatorTestSoftApConfig());
-            fail("setWifiApConfiguration should rethrow Exceptions from WifiService");
-        } catch (SecurityException e) { }
-    }
-
-    /**
-     * Check the call to startScan calls WifiService.
-     */
-    @Test
-    public void testStartScan() throws Exception {
-        when(mWifiService.startScan(eq(TEST_PACKAGE_NAME), nullable(String.class))).thenReturn(
-                true);
-        assertTrue(mWifiManager.startScan());
-
-        when(mWifiService.startScan(eq(TEST_PACKAGE_NAME), nullable(String.class))).thenReturn(
-                false);
-        assertFalse(mWifiManager.startScan());
-    }
-
-    /**
-     * Verify main looper is used when handler is not provided.
-     */
-    @Test
-    public void registerTrafficStateCallbackUsesMainLooperOnNullArgumentForHandler()
-            throws Exception {
-        ArgumentCaptor<ITrafficStateCallback.Stub> callbackCaptor =
-                ArgumentCaptor.forClass(ITrafficStateCallback.Stub.class);
-        mWifiManager.registerTrafficStateCallback(
-                new HandlerExecutor(new Handler(mLooper.getLooper())), mTrafficStateCallback);
-        verify(mWifiService).registerTrafficStateCallback(
-                any(IBinder.class), callbackCaptor.capture(), anyInt());
-
-        assertEquals(0, mLooper.dispatchAll());
-        callbackCaptor.getValue().onStateChanged(TrafficStateCallback.DATA_ACTIVITY_INOUT);
-        assertEquals(1, mLooper.dispatchAll());
-        verify(mTrafficStateCallback).onStateChanged(TrafficStateCallback.DATA_ACTIVITY_INOUT);
-    }
-
-    /**
-     * Verify the call to unregisterTrafficStateCallback goes to WifiServiceImpl.
-     */
-    @Test
-    public void unregisterTrafficStateCallbackCallGoesToWifiServiceImpl() throws Exception {
-        ArgumentCaptor<Integer> callbackIdentifier = ArgumentCaptor.forClass(Integer.class);
-        mWifiManager.registerTrafficStateCallback(new HandlerExecutor(mHandler),
-                mTrafficStateCallback);
-        verify(mWifiService).registerTrafficStateCallback(any(IBinder.class),
-                any(ITrafficStateCallback.Stub.class), callbackIdentifier.capture());
-
-        mWifiManager.unregisterTrafficStateCallback(mTrafficStateCallback);
-        verify(mWifiService).unregisterTrafficStateCallback(
-                eq((int) callbackIdentifier.getValue()));
-    }
-
-    /*
-     * Verify client-provided callback is being called through callback proxy on multiple events
-     */
-    @Test
-    public void trafficStateCallbackProxyCallsOnMultipleUpdates() throws Exception {
-        ArgumentCaptor<ITrafficStateCallback.Stub> callbackCaptor =
-                ArgumentCaptor.forClass(ITrafficStateCallback.Stub.class);
-        mWifiManager.registerTrafficStateCallback(new HandlerExecutor(mHandler),
-                mTrafficStateCallback);
-        verify(mWifiService).registerTrafficStateCallback(
-                any(IBinder.class), callbackCaptor.capture(), anyInt());
-
-        InOrder inOrder = inOrder(mTrafficStateCallback);
-
-        callbackCaptor.getValue().onStateChanged(TrafficStateCallback.DATA_ACTIVITY_IN);
-        callbackCaptor.getValue().onStateChanged(TrafficStateCallback.DATA_ACTIVITY_INOUT);
-        callbackCaptor.getValue().onStateChanged(TrafficStateCallback.DATA_ACTIVITY_OUT);
-
-        mLooper.dispatchAll();
-        inOrder.verify(mTrafficStateCallback).onStateChanged(
-                TrafficStateCallback.DATA_ACTIVITY_IN);
-        inOrder.verify(mTrafficStateCallback).onStateChanged(
-                TrafficStateCallback.DATA_ACTIVITY_INOUT);
-        inOrder.verify(mTrafficStateCallback).onStateChanged(
-                TrafficStateCallback.DATA_ACTIVITY_OUT);
-    }
-
-    /**
-     * Verify client-provided callback is being called on the correct thread
-     */
-    @Test
-    public void trafficStateCallbackIsCalledOnCorrectThread() throws Exception {
-        ArgumentCaptor<ITrafficStateCallback.Stub> callbackCaptor =
-                ArgumentCaptor.forClass(ITrafficStateCallback.Stub.class);
-        TestLooper altLooper = new TestLooper();
-        Handler altHandler = new Handler(altLooper.getLooper());
-        mWifiManager.registerTrafficStateCallback(new HandlerExecutor(altHandler),
-                mTrafficStateCallback);
-        verify(mContext, never()).getMainLooper();
-        verify(mContext, never()).getMainExecutor();
-        verify(mWifiService).registerTrafficStateCallback(
-                any(IBinder.class), callbackCaptor.capture(), anyInt());
-
-        assertEquals(0, altLooper.dispatchAll());
-        callbackCaptor.getValue().onStateChanged(TrafficStateCallback.DATA_ACTIVITY_INOUT);
-        assertEquals(1, altLooper.dispatchAll());
-        verify(mTrafficStateCallback).onStateChanged(TrafficStateCallback.DATA_ACTIVITY_INOUT);
-    }
-
-    /**
-     * Verify the call to registerNetworkRequestMatchCallback goes to WifiServiceImpl.
-     */
-    @Test
-    public void registerNetworkRequestMatchCallbackCallGoesToWifiServiceImpl()
-            throws Exception {
-        ArgumentCaptor<INetworkRequestMatchCallback.Stub> callbackCaptor =
-                ArgumentCaptor.forClass(INetworkRequestMatchCallback.Stub.class);
-        mWifiManager.registerNetworkRequestMatchCallback(
-                new HandlerExecutor(new Handler(mLooper.getLooper())),
-                mNetworkRequestMatchCallback);
-        verify(mWifiService).registerNetworkRequestMatchCallback(
-                any(IBinder.class), callbackCaptor.capture(), anyInt());
-
-        INetworkRequestUserSelectionCallback iUserSelectionCallback =
-                mock(INetworkRequestUserSelectionCallback.class);
-
-        assertEquals(0, mLooper.dispatchAll());
-
-        callbackCaptor.getValue().onAbort();
-        assertEquals(1, mLooper.dispatchAll());
-        verify(mNetworkRequestMatchCallback).onAbort();
-
-        callbackCaptor.getValue().onMatch(new ArrayList<ScanResult>());
-        assertEquals(1, mLooper.dispatchAll());
-        verify(mNetworkRequestMatchCallback).onMatch(anyList());
-
-        callbackCaptor.getValue().onUserSelectionConnectSuccess(new WifiConfiguration());
-        assertEquals(1, mLooper.dispatchAll());
-        verify(mNetworkRequestMatchCallback).onUserSelectionConnectSuccess(
-                any(WifiConfiguration.class));
-
-        callbackCaptor.getValue().onUserSelectionConnectFailure(new WifiConfiguration());
-        assertEquals(1, mLooper.dispatchAll());
-        verify(mNetworkRequestMatchCallback).onUserSelectionConnectFailure(
-                any(WifiConfiguration.class));
-    }
-
-    /**
-     * Verify the call to unregisterNetworkRequestMatchCallback goes to WifiServiceImpl.
-     */
-    @Test
-    public void unregisterNetworkRequestMatchCallbackCallGoesToWifiServiceImpl() throws Exception {
-        ArgumentCaptor<Integer> callbackIdentifier = ArgumentCaptor.forClass(Integer.class);
-        mWifiManager.registerNetworkRequestMatchCallback(new HandlerExecutor(mHandler),
-                mNetworkRequestMatchCallback);
-        verify(mWifiService).registerNetworkRequestMatchCallback(
-                any(IBinder.class), any(INetworkRequestMatchCallback.class),
-                callbackIdentifier.capture());
-
-        mWifiManager.unregisterNetworkRequestMatchCallback(mNetworkRequestMatchCallback);
-        verify(mWifiService).unregisterNetworkRequestMatchCallback(
-                eq((int) callbackIdentifier.getValue()));
-    }
-
-    /**
-     * Verify the call to NetworkRequestUserSelectionCallback goes to
-     * WifiServiceImpl.
-     */
-    @Test
-    public void networkRequestUserSelectionCallbackCallGoesToWifiServiceImpl()
-            throws Exception {
-        ArgumentCaptor<INetworkRequestMatchCallback.Stub> callbackCaptor =
-                ArgumentCaptor.forClass(INetworkRequestMatchCallback.Stub.class);
-        mWifiManager.registerNetworkRequestMatchCallback(
-                new HandlerExecutor(new Handler(mLooper.getLooper())),
-                mNetworkRequestMatchCallback);
-        verify(mWifiService).registerNetworkRequestMatchCallback(
-                any(IBinder.class), callbackCaptor.capture(), anyInt());
-
-        INetworkRequestUserSelectionCallback iUserSelectionCallback =
-                mock(INetworkRequestUserSelectionCallback.class);
-        ArgumentCaptor<NetworkRequestUserSelectionCallback> userSelectionCallbackCaptor =
-                ArgumentCaptor.forClass(NetworkRequestUserSelectionCallback.class);
-        callbackCaptor.getValue().onUserSelectionCallbackRegistration(
-                iUserSelectionCallback);
-        assertEquals(1, mLooper.dispatchAll());
-        verify(mNetworkRequestMatchCallback).onUserSelectionCallbackRegistration(
-                userSelectionCallbackCaptor.capture());
-
-        WifiConfiguration selected = new WifiConfiguration();
-        userSelectionCallbackCaptor.getValue().select(selected);
-        verify(iUserSelectionCallback).select(selected);
-
-        userSelectionCallbackCaptor.getValue().reject();
-        verify(iUserSelectionCallback).reject();
-    }
-
-    /**
-     * Check the call to getAllMatchingWifiConfigs calls getAllMatchingFqdnsForScanResults and
-     * getWifiConfigsForPasspointProfiles of WifiService in order.
-     */
-    @Test
-    public void testGetAllMatchingWifiConfigs() throws Exception {
-        Map<String, List<ScanResult>> passpointProfiles = new HashMap<>();
-        passpointProfiles.put("www.test.com_987a69bca26", new ArrayList<>());
-        when(mWifiService.getAllMatchingPasspointProfilesForScanResults(
-                any(List.class))).thenReturn(passpointProfiles);
-        InOrder inOrder = inOrder(mWifiService);
-
-        mWifiManager.getAllMatchingWifiConfigs(new ArrayList<>());
-
-        inOrder.verify(mWifiService).getAllMatchingPasspointProfilesForScanResults(any(List.class));
-        inOrder.verify(mWifiService).getWifiConfigsForPasspointProfiles(any(List.class));
-    }
-
-    /**
-     * Check the call to getMatchingOsuProviders calls getMatchingOsuProviders of WifiService
-     * with the provided a list of ScanResult.
-     */
-    @Test
-    public void testGetMatchingOsuProviders() throws Exception {
-        mWifiManager.getMatchingOsuProviders(new ArrayList<>());
-
-        verify(mWifiService).getMatchingOsuProviders(any(List.class));
-    }
-
-    /**
-     * Verify calls to {@link WifiManager#addNetworkSuggestions(List)},
-     * {@link WifiManager#getNetworkSuggestions()} and
-     * {@link WifiManager#removeNetworkSuggestions(List)}.
-     */
-    @Test
-    public void addGetRemoveNetworkSuggestions() throws Exception {
-        List<WifiNetworkSuggestion> testList = new ArrayList<>();
-        when(mWifiService.addNetworkSuggestions(any(List.class), anyString(),
-                nullable(String.class))).thenReturn(STATUS_NETWORK_SUGGESTIONS_SUCCESS);
-        when(mWifiService.removeNetworkSuggestions(any(List.class), anyString())).thenReturn(
-                STATUS_NETWORK_SUGGESTIONS_SUCCESS);
-        when(mWifiService.getNetworkSuggestions(anyString()))
-                .thenReturn(testList);
-
-        assertEquals(STATUS_NETWORK_SUGGESTIONS_SUCCESS,
-                mWifiManager.addNetworkSuggestions(testList));
-        verify(mWifiService).addNetworkSuggestions(anyList(), eq(TEST_PACKAGE_NAME),
-                nullable(String.class));
-
-        assertEquals(testList, mWifiManager.getNetworkSuggestions());
-        verify(mWifiService).getNetworkSuggestions(eq(TEST_PACKAGE_NAME));
-
-        assertEquals(STATUS_NETWORK_SUGGESTIONS_SUCCESS,
-                mWifiManager.removeNetworkSuggestions(new ArrayList<>()));
-        verify(mWifiService).removeNetworkSuggestions(anyList(), eq(TEST_PACKAGE_NAME));
-    }
-
-    /**
-     * Verify call to {@link WifiManager#getMaxNumberOfNetworkSuggestionsPerApp()}.
-     */
-    @Test
-    public void getMaxNumberOfNetworkSuggestionsPerApp() {
-        when(mContext.getSystemServiceName(ActivityManager.class))
-                .thenReturn(Context.ACTIVITY_SERVICE);
-        when(mContext.getSystemService(Context.ACTIVITY_SERVICE))
-                .thenReturn(mActivityManager);
-        when(mActivityManager.isLowRamDevice()).thenReturn(true);
-        assertEquals(256, mWifiManager.getMaxNumberOfNetworkSuggestionsPerApp());
-
-        when(mActivityManager.isLowRamDevice()).thenReturn(false);
-        assertEquals(1024, mWifiManager.getMaxNumberOfNetworkSuggestionsPerApp());
-    }
-
-    /**
-     * Verify getting the factory MAC address.
-     */
-    @Test
-    public void testGetFactoryMacAddress() throws Exception {
-        when(mWifiService.getFactoryMacAddresses()).thenReturn(TEST_MAC_ADDRESSES);
-        assertArrayEquals(TEST_MAC_ADDRESSES, mWifiManager.getFactoryMacAddresses());
-        verify(mWifiService).getFactoryMacAddresses();
-    }
-
-    /**
-     * Verify the call to addOnWifiUsabilityStatsListener goes to WifiServiceImpl.
-     */
-    @Test
-    public void addOnWifiUsabilityStatsListeneroesToWifiServiceImpl() throws Exception {
-        mExecutor = new SynchronousExecutor();
-        mWifiManager.addOnWifiUsabilityStatsListener(mExecutor, mOnWifiUsabilityStatsListener);
-        verify(mWifiService).addOnWifiUsabilityStatsListener(any(IBinder.class),
-                any(IOnWifiUsabilityStatsListener.Stub.class), anyInt());
-    }
-
-    /**
-     * Verify the call to removeOnWifiUsabilityStatsListener goes to WifiServiceImpl.
-     */
-    @Test
-    public void removeOnWifiUsabilityListenerGoesToWifiServiceImpl() throws Exception {
-        ArgumentCaptor<Integer> listenerIdentifier = ArgumentCaptor.forClass(Integer.class);
-        mExecutor = new SynchronousExecutor();
-        mWifiManager.addOnWifiUsabilityStatsListener(mExecutor, mOnWifiUsabilityStatsListener);
-        verify(mWifiService).addOnWifiUsabilityStatsListener(any(IBinder.class),
-                any(IOnWifiUsabilityStatsListener.Stub.class), listenerIdentifier.capture());
-
-        mWifiManager.removeOnWifiUsabilityStatsListener(mOnWifiUsabilityStatsListener);
-        verify(mWifiService).removeOnWifiUsabilityStatsListener(
-                eq((int) listenerIdentifier.getValue()));
-    }
-
-    /**
-     * Test behavior of isEnhancedOpenSupported
-     */
-    @Test
-    public void testIsEnhancedOpenSupported() throws Exception {
-        when(mWifiService.getSupportedFeatures())
-                .thenReturn(new Long(WIFI_FEATURE_OWE));
-        assertTrue(mWifiManager.isEnhancedOpenSupported());
-        when(mWifiService.getSupportedFeatures())
-                .thenReturn(new Long(~WIFI_FEATURE_OWE));
-        assertFalse(mWifiManager.isEnhancedOpenSupported());
-    }
-
-    /**
-     * Test behavior of isWpa3SaeSupported
-     */
-    @Test
-    public void testIsWpa3SaeSupported() throws Exception {
-        when(mWifiService.getSupportedFeatures())
-                .thenReturn(new Long(WIFI_FEATURE_WPA3_SAE));
-        assertTrue(mWifiManager.isWpa3SaeSupported());
-        when(mWifiService.getSupportedFeatures())
-                .thenReturn(new Long(~WIFI_FEATURE_WPA3_SAE));
-        assertFalse(mWifiManager.isWpa3SaeSupported());
-    }
-
-    /**
-     * Test behavior of isWpa3SuiteBSupported
-     */
-    @Test
-    public void testIsWpa3SuiteBSupported() throws Exception {
-        when(mWifiService.getSupportedFeatures())
-                .thenReturn(new Long(WIFI_FEATURE_WPA3_SUITE_B));
-        assertTrue(mWifiManager.isWpa3SuiteBSupported());
-        when(mWifiService.getSupportedFeatures())
-                .thenReturn(new Long(~WIFI_FEATURE_WPA3_SUITE_B));
-        assertFalse(mWifiManager.isWpa3SuiteBSupported());
-    }
-
-    /**
-     * Test behavior of isEasyConnectSupported
-     */
-    @Test
-    public void testIsEasyConnectSupported() throws Exception {
-        when(mWifiService.getSupportedFeatures())
-                .thenReturn(new Long(WIFI_FEATURE_DPP));
-        assertTrue(mWifiManager.isEasyConnectSupported());
-        when(mWifiService.getSupportedFeatures())
-                .thenReturn(new Long(~WIFI_FEATURE_DPP));
-        assertFalse(mWifiManager.isEasyConnectSupported());
-    }
-
-    /**
-     * Test behavior of {@link WifiManager#addNetwork(WifiConfiguration)}
-     */
-    @Test
-    public void testAddNetwork() throws Exception {
-        WifiConfiguration configuration = new WifiConfiguration();
-        when(mWifiService.addOrUpdateNetwork(any(), anyString()))
-                .thenReturn(TEST_NETWORK_ID);
-
-        assertEquals(mWifiManager.addNetwork(configuration), TEST_NETWORK_ID);
-        verify(mWifiService).addOrUpdateNetwork(configuration, mContext.getOpPackageName());
-
-        // send a null config
-        assertEquals(mWifiManager.addNetwork(null), -1);
-    }
-
-    /**
-     * Test behavior of {@link WifiManager#addNetwork(WifiConfiguration)}
-     */
-    @Test
-    public void testUpdateNetwork() throws Exception {
-        WifiConfiguration configuration = new WifiConfiguration();
-        when(mWifiService.addOrUpdateNetwork(any(), anyString()))
-                .thenReturn(TEST_NETWORK_ID);
-
-        configuration.networkId = TEST_NETWORK_ID;
-        assertEquals(mWifiManager.updateNetwork(configuration), TEST_NETWORK_ID);
-        verify(mWifiService).addOrUpdateNetwork(configuration, mContext.getOpPackageName());
-
-        // config with invalid network ID
-        configuration.networkId = -1;
-        assertEquals(mWifiManager.updateNetwork(configuration), -1);
-
-        // send a null config
-        assertEquals(mWifiManager.updateNetwork(null), -1);
-    }
-
-    /**
-     * Test behavior of {@link WifiManager#enableNetwork(int, boolean)}
-     */
-    @Test
-    public void testEnableNetwork() throws Exception {
-        when(mWifiService.enableNetwork(anyInt(), anyBoolean(), anyString()))
-                .thenReturn(true);
-        assertTrue(mWifiManager.enableNetwork(TEST_NETWORK_ID, true));
-        verify(mWifiService).enableNetwork(TEST_NETWORK_ID, true, mContext.getOpPackageName());
-    }
-
-    /**
-     * Test behavior of {@link WifiManager#disableNetwork(int)}
-     */
-    @Test
-    public void testDisableNetwork() throws Exception {
-        when(mWifiService.disableNetwork(anyInt(), anyString()))
-                .thenReturn(true);
-        assertTrue(mWifiManager.disableNetwork(TEST_NETWORK_ID));
-        verify(mWifiService).disableNetwork(TEST_NETWORK_ID, mContext.getOpPackageName());
-    }
-
-    /**
-     * Test behavior of {@link WifiManager#allowAutojoin(int, boolean)}
-     * @throws Exception
-     */
-    @Test
-    public void testAllowAutojoin() throws Exception {
-        mWifiManager.allowAutojoin(1, true);
-        verify(mWifiService).allowAutojoin(1, true);
-    }
-
-    /**
-     * Test behavior of {@link WifiManager#allowAutojoinPasspoint(String, boolean)}
-     * @throws Exception
-     */
-    @Test
-    public void testAllowAutojoinPasspoint() throws Exception {
-        final String fqdn = "FullyQualifiedDomainName";
-        mWifiManager.allowAutojoinPasspoint(fqdn, true);
-        verify(mWifiService).allowAutojoinPasspoint(fqdn, true);
-    }
-
-    /**
-     * Test behavior of
-     * {@link WifiManager#setMacRandomizationSettingPasspointEnabled(String, boolean)}
-     */
-    @Test
-    public void testSetMacRandomizationSettingPasspointEnabled() throws Exception {
-        final String fqdn = "FullyQualifiedDomainName";
-        mWifiManager.setMacRandomizationSettingPasspointEnabled(fqdn, true);
-        verify(mWifiService).setMacRandomizationSettingPasspointEnabled(fqdn, true);
-    }
-
-    /**
-     * Test behavior of
-     * {@link WifiManager#setMacRandomizationSettingPasspointEnabled(String, boolean)}
-     */
-    @Test
-    public void testSetPasspointMeteredOverride() throws Exception {
-        final String fqdn = "FullyQualifiedDomainName";
-        mWifiManager.setPasspointMeteredOverride(fqdn, METERED_OVERRIDE_METERED);
-        verify(mWifiService).setPasspointMeteredOverride(fqdn, METERED_OVERRIDE_METERED);
-    }
-
-    /**
-     * Test behavior of {@link WifiManager#disconnect()}
-     */
-    @Test
-    public void testDisconnect() throws Exception {
-        when(mWifiService.disconnect(anyString())).thenReturn(true);
-        assertTrue(mWifiManager.disconnect());
-        verify(mWifiService).disconnect(mContext.getOpPackageName());
-    }
-
-    /**
-     * Test behavior of {@link WifiManager#reconnect()}
-     */
-    @Test
-    public void testReconnect() throws Exception {
-        when(mWifiService.reconnect(anyString())).thenReturn(true);
-        assertTrue(mWifiManager.reconnect());
-        verify(mWifiService).reconnect(mContext.getOpPackageName());
-    }
-
-    /**
-     * Test behavior of {@link WifiManager#reassociate()}
-     */
-    @Test
-    public void testReassociate() throws Exception {
-        when(mWifiService.reassociate(anyString())).thenReturn(true);
-        assertTrue(mWifiManager.reassociate());
-        verify(mWifiService).reassociate(mContext.getOpPackageName());
-    }
-
-    /**
-     * Test behavior of {@link WifiManager#getSupportedFeatures()}
-     */
-    @Test
-    public void testGetSupportedFeatures() throws Exception {
-        long supportedFeatures =
-                WIFI_FEATURE_SCANNER
-                        | WIFI_FEATURE_PASSPOINT
-                        | WIFI_FEATURE_P2P;
-        when(mWifiService.getSupportedFeatures())
-                .thenReturn(Long.valueOf(supportedFeatures));
-
-        assertTrue(mWifiManager.isWifiScannerSupported());
-        assertTrue(mWifiManager.isPasspointSupported());
-        assertTrue(mWifiManager.isP2pSupported());
-        assertFalse(mWifiManager.isPortableHotspotSupported());
-        assertFalse(mWifiManager.isDeviceToDeviceRttSupported());
-        assertFalse(mWifiManager.isDeviceToApRttSupported());
-        assertFalse(mWifiManager.isPreferredNetworkOffloadSupported());
-        assertFalse(mWifiManager.isAdditionalStaSupported());
-        assertFalse(mWifiManager.isTdlsSupported());
-        assertFalse(mWifiManager.isOffChannelTdlsSupported());
-        assertFalse(mWifiManager.isEnhancedPowerReportingSupported());
-    }
-
-    /**
-     * Tests that passing a null Executor to {@link WifiManager#getWifiActivityEnergyInfoAsync}
-     * throws an exception.
-     */
-    @Test(expected = NullPointerException.class)
-    public void testGetWifiActivityInfoNullExecutor() throws Exception {
-        mWifiManager.getWifiActivityEnergyInfoAsync(null, mOnWifiActivityEnergyInfoListener);
-    }
-
-    /**
-     * Tests that passing a null listener to {@link WifiManager#getWifiActivityEnergyInfoAsync}
-     * throws an exception.
-     */
-    @Test(expected = NullPointerException.class)
-    public void testGetWifiActivityInfoNullListener() throws Exception {
-        mWifiManager.getWifiActivityEnergyInfoAsync(mExecutor, null);
-    }
-
-    /** Tests that the listener runs on the correct Executor. */
-    @Test
-    public void testGetWifiActivityInfoRunsOnCorrectExecutor() throws Exception {
-        mWifiManager.getWifiActivityEnergyInfoAsync(mExecutor, mOnWifiActivityEnergyInfoListener);
-        ArgumentCaptor<IOnWifiActivityEnergyInfoListener> listenerCaptor =
-                ArgumentCaptor.forClass(IOnWifiActivityEnergyInfoListener.class);
-        verify(mWifiService).getWifiActivityEnergyInfoAsync(listenerCaptor.capture());
-        IOnWifiActivityEnergyInfoListener listener = listenerCaptor.getValue();
-        listener.onWifiActivityEnergyInfo(mWifiActivityEnergyInfo);
-        verify(mExecutor).execute(any());
-
-        // ensure that the executor is only triggered once
-        listener.onWifiActivityEnergyInfo(mWifiActivityEnergyInfo);
-        verify(mExecutor).execute(any());
-    }
-
-    /** Tests that the correct listener runs. */
-    @Test
-    public void testGetWifiActivityInfoRunsCorrectListener() throws Exception {
-        int[] flag = {0};
-        mWifiManager.getWifiActivityEnergyInfoAsync(
-                new SynchronousExecutor(), info -> flag[0]++);
-        ArgumentCaptor<IOnWifiActivityEnergyInfoListener> listenerCaptor =
-                ArgumentCaptor.forClass(IOnWifiActivityEnergyInfoListener.class);
-        verify(mWifiService).getWifiActivityEnergyInfoAsync(listenerCaptor.capture());
-        IOnWifiActivityEnergyInfoListener listener = listenerCaptor.getValue();
-        listener.onWifiActivityEnergyInfo(mWifiActivityEnergyInfo);
-        assertEquals(1, flag[0]);
-
-        // ensure that the listener is only triggered once
-        listener.onWifiActivityEnergyInfo(mWifiActivityEnergyInfo);
-        assertEquals(1, flag[0]);
-    }
-
-    /**
-     * Test behavior of {@link WifiManager#getConnectionInfo()}
-     */
-    @Test
-    public void testGetConnectionInfo() throws Exception {
-        WifiInfo wifiInfo = new WifiInfo();
-        when(mWifiService.getConnectionInfo(anyString(), nullable(String.class))).thenReturn(
-                wifiInfo);
-
-        assertEquals(wifiInfo, mWifiManager.getConnectionInfo());
-    }
-
-    /**
-     * Test behavior of {@link WifiManager#is5GHzBandSupported()}
-     */
-    @Test
-    public void testIs5GHzBandSupported() throws Exception {
-        when(mWifiService.is5GHzBandSupported()).thenReturn(true);
-        assertTrue(mWifiManager.is5GHzBandSupported());
-        verify(mWifiService).is5GHzBandSupported();
-    }
-
-    /**
-     * Test behavior of {@link WifiManager#is6GHzBandSupported()}
-     */
-    @Test
-    public void testIs6GHzBandSupported() throws Exception {
-        when(mWifiService.is6GHzBandSupported()).thenReturn(true);
-        assertTrue(mWifiManager.is6GHzBandSupported());
-        verify(mWifiService).is6GHzBandSupported();
-    }
-
-    /**
-     * Test behavior of {@link WifiManager#isWifiStandardSupported()}
-     */
-    @Test
-    public void testIsWifiStandardSupported() throws Exception {
-        int standard = ScanResult.WIFI_STANDARD_11AX;
-        when(mWifiService.isWifiStandardSupported(standard)).thenReturn(true);
-        assertTrue(mWifiManager.isWifiStandardSupported(standard));
-        verify(mWifiService).isWifiStandardSupported(standard);
-    }
-
-    /**
-     * Test behavior of {@link WifiManager#getDhcpInfo()}
-     */
-    @Test
-    public void testGetDhcpInfo() throws Exception {
-        DhcpInfo dhcpInfo = new DhcpInfo();
-
-        when(mWifiService.getDhcpInfo()).thenReturn(dhcpInfo);
-        assertEquals(dhcpInfo, mWifiManager.getDhcpInfo());
-        verify(mWifiService).getDhcpInfo();
-    }
-
-    /**
-     * Test behavior of {@link WifiManager#setWifiEnabled(boolean)}
-     */
-    @Test
-    public void testSetWifiEnabled() throws Exception {
-        when(mWifiService.setWifiEnabled(anyString(), anyBoolean())).thenReturn(true);
-        assertTrue(mWifiManager.setWifiEnabled(true));
-        verify(mWifiService).setWifiEnabled(mContext.getOpPackageName(), true);
-        assertTrue(mWifiManager.setWifiEnabled(false));
-        verify(mWifiService).setWifiEnabled(mContext.getOpPackageName(), false);
-    }
-
-    /**
-     * Test behavior of {@link WifiManager#connect(int, ActionListener)}
-     */
-    @Test
-    public void testConnectWithListener() throws Exception {
-        ActionListener externalListener = mock(ActionListener.class);
-        mWifiManager.connect(TEST_NETWORK_ID, externalListener);
-
-        ArgumentCaptor<IActionListener> binderListenerCaptor =
-                ArgumentCaptor.forClass(IActionListener.class);
-        verify(mWifiService).connect(eq(null), eq(TEST_NETWORK_ID), any(Binder.class),
-                binderListenerCaptor.capture(), anyInt());
-        assertNotNull(binderListenerCaptor.getValue());
-
-        // Trigger on success.
-        binderListenerCaptor.getValue().onSuccess();
-        mLooper.dispatchAll();
-        verify(externalListener).onSuccess();
-
-        // Trigger on failure.
-        binderListenerCaptor.getValue().onFailure(BUSY);
-        mLooper.dispatchAll();
-        verify(externalListener).onFailure(BUSY);
-    }
-
-    /**
-     * Test behavior of {@link WifiManager#connect(int, ActionListener)}
-     */
-    @Test
-    public void testConnectWithListenerHandleSecurityException() throws Exception {
-        doThrow(new SecurityException()).when(mWifiService)
-                .connect(eq(null), anyInt(), any(IBinder.class),
-                        any(IActionListener.class), anyInt());
-        ActionListener externalListener = mock(ActionListener.class);
-        mWifiManager.connect(TEST_NETWORK_ID, externalListener);
-
-        mLooper.dispatchAll();
-        verify(externalListener).onFailure(NOT_AUTHORIZED);
-    }
-
-    /**
-     * Test behavior of {@link WifiManager#connect(int, ActionListener)}
-     */
-    @Test
-    public void testConnectWithListenerHandleRemoteException() throws Exception {
-        doThrow(new RemoteException()).when(mWifiService)
-                .connect(eq(null), anyInt(), any(IBinder.class),
-                        any(IActionListener.class), anyInt());
-        ActionListener externalListener = mock(ActionListener.class);
-        mWifiManager.connect(TEST_NETWORK_ID, externalListener);
-
-        mLooper.dispatchAll();
-        verify(externalListener).onFailure(ERROR);
-    }
-
-    /**
-     * Test behavior of {@link WifiManager#connect(int, ActionListener)}
-     */
-    @Test
-    public void testConnectWithoutListener() throws Exception {
-        WifiConfiguration configuration = new WifiConfiguration();
-        mWifiManager.connect(configuration, null);
-
-        verify(mWifiService).connect(configuration, WifiConfiguration.INVALID_NETWORK_ID, null,
-                null, 0);
-    }
-
-    /**
-     * Verify an IllegalArgumentException is thrown if callback is not provided.
-     */
-    @Test(expected = IllegalArgumentException.class)
-    public void testRegisterScanResultsCallbackWithNullCallback() throws Exception {
-        mWifiManager.registerScanResultsCallback(mExecutor, null);
-    }
-
-    /**
-     * Verify an IllegalArgumentException is thrown if executor is not provided.
-     */
-    @Test(expected = IllegalArgumentException.class)
-    public void testRegisterCallbackWithNullExecutor() throws Exception {
-        mWifiManager.registerScanResultsCallback(null, mScanResultsCallback);
-    }
-
-    /**
-     * Verify client provided callback is being called to the right callback.
-     */
-    @Test
-    public void testAddScanResultsCallbackAndReceiveEvent() throws Exception {
-        ArgumentCaptor<IScanResultsCallback.Stub> callbackCaptor =
-                ArgumentCaptor.forClass(IScanResultsCallback.Stub.class);
-        mWifiManager.registerScanResultsCallback(new SynchronousExecutor(), mScanResultsCallback);
-        verify(mWifiService).registerScanResultsCallback(callbackCaptor.capture());
-        callbackCaptor.getValue().onScanResultsAvailable();
-        verify(mRunnable).run();
-    }
-
-    /**
-     * Verify client provided callback is being called to the right executor.
-     */
-    @Test
-    public void testRegisterScanResultsCallbackWithTheTargetExecutor() throws Exception {
-        ArgumentCaptor<IScanResultsCallback.Stub> callbackCaptor =
-                ArgumentCaptor.forClass(IScanResultsCallback.Stub.class);
-        mWifiManager.registerScanResultsCallback(mExecutor, mScanResultsCallback);
-        verify(mWifiService).registerScanResultsCallback(callbackCaptor.capture());
-        mWifiManager.registerScanResultsCallback(mAnotherExecutor, mScanResultsCallback);
-        callbackCaptor.getValue().onScanResultsAvailable();
-        verify(mExecutor, never()).execute(any(Runnable.class));
-        verify(mAnotherExecutor).execute(any(Runnable.class));
-    }
-
-    /**
-     * Verify client register unregister then register again, to ensure callback still works.
-     */
-    @Test
-    public void testRegisterUnregisterThenRegisterAgainWithScanResultCallback() throws Exception {
-        ArgumentCaptor<IScanResultsCallback.Stub> callbackCaptor =
-                ArgumentCaptor.forClass(IScanResultsCallback.Stub.class);
-        mWifiManager.registerScanResultsCallback(new SynchronousExecutor(), mScanResultsCallback);
-        verify(mWifiService).registerScanResultsCallback(callbackCaptor.capture());
-        mWifiManager.unregisterScanResultsCallback(mScanResultsCallback);
-        callbackCaptor.getValue().onScanResultsAvailable();
-        verify(mRunnable, never()).run();
-        mWifiManager.registerScanResultsCallback(new SynchronousExecutor(), mScanResultsCallback);
-        callbackCaptor.getValue().onScanResultsAvailable();
-        verify(mRunnable).run();
-    }
-
-    /**
-     * Verify client unregisterScanResultsCallback.
-     */
-    @Test
-    public void testUnregisterScanResultsCallback() throws Exception {
-        mWifiManager.unregisterScanResultsCallback(mScanResultsCallback);
-        verify(mWifiService).unregisterScanResultsCallback(any());
-    }
-
-    /**
-     * Verify client unregisterScanResultsCallback with null callback will cause an exception.
-     */
-    @Test(expected = IllegalArgumentException.class)
-    public void testUnregisterScanResultsCallbackWithNullCallback() throws Exception {
-        mWifiManager.unregisterScanResultsCallback(null);
-    }
-
-    /**
-     * Verify an IllegalArgumentException is thrown if executor not provided.
-     */
-    @Test(expected = IllegalArgumentException.class)
-    public void testAddSuggestionConnectionStatusListenerWithNullExecutor() {
-        mWifiManager.addSuggestionConnectionStatusListener(null, mListener);
-    }
-
-    /**
-     * Verify an IllegalArgumentException is thrown if listener is not provided.
-     */
-    @Test(expected = IllegalArgumentException.class)
-    public void testAddSuggestionConnectionStatusListenerWithNullListener() {
-        mWifiManager.addSuggestionConnectionStatusListener(mExecutor, null);
-    }
-
-    /**
-     * Verify client provided listener is being called to the right listener.
-     */
-    @Test
-    public void testAddSuggestionConnectionStatusListenerAndReceiveEvent() throws Exception {
-        int errorCode = STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION;
-        ArgumentCaptor<ISuggestionConnectionStatusListener.Stub> callbackCaptor =
-                ArgumentCaptor.forClass(ISuggestionConnectionStatusListener.Stub.class);
-        Executor executor = new SynchronousExecutor();
-        mWifiManager.addSuggestionConnectionStatusListener(executor, mListener);
-        verify(mWifiService).registerSuggestionConnectionStatusListener(any(IBinder.class),
-                callbackCaptor.capture(), anyInt(), anyString(), nullable(String.class));
-        callbackCaptor.getValue().onConnectionStatus(mWifiNetworkSuggestion, errorCode);
-        verify(mListener).onConnectionStatus(any(WifiNetworkSuggestion.class), eq(errorCode));
-    }
-
-    /**
-     * Verify client provided listener is being called to the right executor.
-     */
-    @Test
-    public void testAddSuggestionConnectionStatusListenerWithTheTargetExecutor() throws Exception {
-        int errorCode = STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION;
-        ArgumentCaptor<ISuggestionConnectionStatusListener.Stub> callbackCaptor =
-                ArgumentCaptor.forClass(ISuggestionConnectionStatusListener.Stub.class);
-        mWifiManager.addSuggestionConnectionStatusListener(mExecutor, mListener);
-        verify(mWifiService).registerSuggestionConnectionStatusListener(any(IBinder.class),
-                callbackCaptor.capture(), anyInt(), anyString(), nullable(String.class));
-        callbackCaptor.getValue().onConnectionStatus(any(WifiNetworkSuggestion.class), errorCode);
-        verify(mExecutor).execute(any(Runnable.class));
-    }
-
-    /**
-     * Verify an IllegalArgumentException is thrown if listener is not provided.
-     */
-    @Test(expected = IllegalArgumentException.class)
-    public void testRemoveSuggestionConnectionListenerWithNullListener() {
-        mWifiManager.removeSuggestionConnectionStatusListener(null);
-    }
-
-    /**
-     * Verify removeSuggestionConnectionListener.
-     */
-    @Test
-    public void testRemoveSuggestionConnectionListener() throws Exception {
-        mWifiManager.removeSuggestionConnectionStatusListener(mListener);
-        verify(mWifiService).unregisterSuggestionConnectionStatusListener(anyInt(), anyString());
-    }
-
-    /** Test {@link WifiManager#calculateSignalLevel(int)} */
-    @Test
-    public void testCalculateSignalLevel() throws Exception {
-        when(mWifiService.calculateSignalLevel(anyInt())).thenReturn(3);
-        int actual = mWifiManager.calculateSignalLevel(-60);
-        verify(mWifiService).calculateSignalLevel(-60);
-        assertEquals(3, actual);
-    }
-
-    /** Test {@link WifiManager#getMaxSignalLevel()} */
-    @Test
-    public void testGetMaxSignalLevel() throws Exception {
-        when(mWifiService.calculateSignalLevel(anyInt())).thenReturn(4);
-        int actual = mWifiManager.getMaxSignalLevel();
-        verify(mWifiService).calculateSignalLevel(Integer.MAX_VALUE);
-        assertEquals(4, actual);
-    }
-
-    /*
-     * Test behavior of isWapiSupported
-     * @throws Exception
-     */
-    @Test
-    public void testIsWapiSupported() throws Exception {
-        when(mWifiService.getSupportedFeatures())
-                .thenReturn(new Long(WifiManager.WIFI_FEATURE_WAPI));
-        assertTrue(mWifiManager.isWapiSupported());
-        when(mWifiService.getSupportedFeatures())
-                .thenReturn(new Long(~WifiManager.WIFI_FEATURE_WAPI));
-        assertFalse(mWifiManager.isWapiSupported());
-    }
-
-    /*
-     * Test that DPP channel list is parsed correctly
-     */
-    @Test
-    public void testparseDppChannelList() throws Exception {
-        String channelList = "81/1,2,3,4,5,6,7,8,9,10,11,115/36,40,44,48";
-        SparseArray<int[]> expectedResult = new SparseArray<>();
-        expectedResult.append(81, new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11});
-        expectedResult.append(115, new int[]{36, 40, 44, 48});
-
-        SparseArray<int[]> result = WifiManager.parseDppChannelList(channelList);
-        assertEquals(expectedResult.size(), result.size());
-
-        int index = 0;
-        int key;
-
-        // Compare the two primitive int arrays
-        do {
-            try {
-                key = result.keyAt(index);
-            } catch (java.lang.ArrayIndexOutOfBoundsException e) {
-                break;
-            }
-            int[] expected = expectedResult.get(key);
-            int[] output = result.get(key);
-            assertEquals(expected.length, output.length);
-            for (int i = 0; i < output.length; i++) {
-                assertEquals(expected[i], output[i]);
-            }
-            index++;
-        } while (true);
-    }
-
-    /*
-     * Test that DPP channel list parser gracefully fails for invalid input
-     */
-    @Test
-    public void testparseDppChannelListWithInvalidFormats() throws Exception {
-        String channelList = "1,2,3,4,5,6,7,8,9,10,11,36,40,44,48";
-        SparseArray<int[]> result = WifiManager.parseDppChannelList(channelList);
-        assertEquals(result.size(), 0);
-
-        channelList = "ajgalskgjalskjg3-09683dh";
-        result = WifiManager.parseDppChannelList(channelList);
-        assertEquals(result.size(), 0);
-
-        channelList = "13/abc,46////";
-        result = WifiManager.parseDppChannelList(channelList);
-        assertEquals(result.size(), 0);
-
-        channelList = "11/4,5,13/";
-        result = WifiManager.parseDppChannelList(channelList);
-        assertEquals(result.size(), 0);
-
-        channelList = "/24,6";
-        result = WifiManager.parseDppChannelList(channelList);
-        assertEquals(result.size(), 0);
-    }
-
-    /**
-     * Test getWifiConfigsForMatchedNetworkSuggestions for given scanResults.
-     */
-    @Test
-    public void testGetWifiConfigsForMatchedNetworkSuggestions() throws Exception {
-        List<WifiConfiguration> testResults = new ArrayList<>();
-        testResults.add(new WifiConfiguration());
-
-        when(mWifiService.getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(any(List.class)))
-                .thenReturn(testResults);
-        assertEquals(testResults, mWifiManager
-                .getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(new ArrayList<>()));
-    }
-
-    /**
-     * Verify the call to setWifiConnectedNetworkScorer goes to WifiServiceImpl.
-     */
-    @Test
-    public void setWifiConnectedNetworkScorerGoesToWifiServiceImpl() throws Exception {
-        mExecutor = new SynchronousExecutor();
-        mWifiManager.setWifiConnectedNetworkScorer(mExecutor, mWifiConnectedNetworkScorer);
-        verify(mWifiService).setWifiConnectedNetworkScorer(any(IBinder.class),
-                any(IWifiConnectedNetworkScorer.Stub.class));
-    }
-
-    /**
-     * Verify the call to clearWifiConnectedNetworkScorer goes to WifiServiceImpl.
-     */
-    @Test
-    public void clearWifiConnectedNetworkScorerGoesToWifiServiceImpl() throws Exception {
-        mExecutor = new SynchronousExecutor();
-        mWifiManager.setWifiConnectedNetworkScorer(mExecutor, mWifiConnectedNetworkScorer);
-        verify(mWifiService).setWifiConnectedNetworkScorer(any(IBinder.class),
-                any(IWifiConnectedNetworkScorer.Stub.class));
-
-        mWifiManager.clearWifiConnectedNetworkScorer();
-        verify(mWifiService).clearWifiConnectedNetworkScorer();
-    }
-
-    /**
-     * Verify that Wi-Fi connected scorer receives score update observer after registeration.
-     */
-    @Test
-    public void verifyScorerReceiveScoreUpdateObserverAfterRegistration() throws Exception {
-        mExecutor = new SynchronousExecutor();
-        mWifiManager.setWifiConnectedNetworkScorer(mExecutor, mWifiConnectedNetworkScorer);
-        ArgumentCaptor<IWifiConnectedNetworkScorer.Stub> scorerCaptor =
-                ArgumentCaptor.forClass(IWifiConnectedNetworkScorer.Stub.class);
-        verify(mWifiService).setWifiConnectedNetworkScorer(any(IBinder.class),
-                scorerCaptor.capture());
-        scorerCaptor.getValue().onSetScoreUpdateObserver(any());
-        mLooper.dispatchAll();
-        verify(mWifiConnectedNetworkScorer).onSetScoreUpdateObserver(any());
-    }
-
-    /**
-     * Verify that Wi-Fi connected scorer receives session ID when onStart/onStop methods
-     * are called.
-     */
-    @Test
-    public void verifyScorerReceiveSessionIdWhenStartStopIsCalled() throws Exception {
-        mExecutor = new SynchronousExecutor();
-        mWifiManager.setWifiConnectedNetworkScorer(mExecutor, mWifiConnectedNetworkScorer);
-        ArgumentCaptor<IWifiConnectedNetworkScorer.Stub> callbackCaptor =
-                ArgumentCaptor.forClass(IWifiConnectedNetworkScorer.Stub.class);
-        verify(mWifiService).setWifiConnectedNetworkScorer(any(IBinder.class),
-                callbackCaptor.capture());
-        callbackCaptor.getValue().onStart(0);
-        callbackCaptor.getValue().onStop(10);
-        mLooper.dispatchAll();
-        verify(mWifiConnectedNetworkScorer).onStart(0);
-        verify(mWifiConnectedNetworkScorer).onStop(10);
-    }
-
-    @Test
-    public void testScanThrottle() throws Exception {
-        mWifiManager.setScanThrottleEnabled(true);
-        verify(mWifiService).setScanThrottleEnabled(true);
-
-        when(mWifiService.isScanThrottleEnabled()).thenReturn(false);
-        assertFalse(mWifiManager.isScanThrottleEnabled());
-        verify(mWifiService).isScanThrottleEnabled();
-    }
-
-    @Test
-    public void testAutoWakeup() throws Exception {
-        mWifiManager.setAutoWakeupEnabled(true);
-        verify(mWifiService).setAutoWakeupEnabled(true);
-
-        when(mWifiService.isAutoWakeupEnabled()).thenReturn(false);
-        assertFalse(mWifiManager.isAutoWakeupEnabled());
-        verify(mWifiService).isAutoWakeupEnabled();
-    }
-
-
-    @Test
-    public void testScanAvailable() throws Exception {
-        mWifiManager.setScanAlwaysAvailable(true);
-        verify(mWifiService).setScanAlwaysAvailable(true);
-
-        when(mWifiService.isScanAlwaysAvailable()).thenReturn(false);
-        assertFalse(mWifiManager.isScanAlwaysAvailable());
-        verify(mWifiService).isScanAlwaysAvailable();
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkAgentSpecifierTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkAgentSpecifierTest.java
deleted file mode 100644
index d479aac..0000000
--- a/wifi/tests/src/android/net/wifi/WifiNetworkAgentSpecifierTest.java
+++ /dev/null
@@ -1,395 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import android.net.MacAddress;
-import android.net.MatchAllNetworkSpecifier;
-import android.os.Parcel;
-import android.os.PatternMatcher;
-import android.util.Pair;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-/**
- * Unit tests for {@link android.net.wifi.WifiNetworkAgentSpecifier}.
- */
-@SmallTest
-public class WifiNetworkAgentSpecifierTest {
-    private static final String TEST_SSID = "Test123";
-    private static final String TEST_SSID_PATTERN = "Test";
-    private static final String TEST_SSID_1 = "456test";
-    private static final String TEST_BSSID = "12:12:12:aa:0b:c0";
-    private static final String TEST_BSSID_OUI_BASE_ADDRESS = "12:12:12:00:00:00";
-    private static final String TEST_BSSID_OUI_MASK = "ff:ff:ff:00:00:00";
-    private static final String TEST_BSSID_1 = "aa:cc:12:aa:0b:c0";
-    private static final String TEST_PRESHARED_KEY = "\"Test123\"";
-
-    /**
-     * Validate that parcel marshalling/unmarshalling works
-     */
-    @Test
-    public void testWifiNetworkAgentSpecifierParcel() {
-        WifiNetworkAgentSpecifier specifier = createDefaultNetworkAgentSpecifier();
-
-        Parcel parcelW = Parcel.obtain();
-        specifier.writeToParcel(parcelW, 0);
-        byte[] bytes = parcelW.marshall();
-        parcelW.recycle();
-
-        Parcel parcelR = Parcel.obtain();
-        parcelR.unmarshall(bytes, 0, bytes.length);
-        parcelR.setDataPosition(0);
-        WifiNetworkAgentSpecifier parcelSpecifier =
-                WifiNetworkAgentSpecifier.CREATOR.createFromParcel(parcelR);
-
-        assertEquals(specifier, parcelSpecifier);
-    }
-
-    /**
-     * Validate NetworkAgentSpecifier equals with itself.
-     * a) Create network agent specifier 1 for WPA_PSK network
-     * b) Create network agent specifier 2 with the same params as specifier 1.
-     * c) Ensure that the specifier 2 equals specifier 1.
-     */
-    @Test
-    public void testWifiNetworkAgentSpecifierEqualsSame() {
-        WifiNetworkAgentSpecifier specifier1 = createDefaultNetworkAgentSpecifier();
-        WifiNetworkAgentSpecifier specifier2 = createDefaultNetworkAgentSpecifier();
-
-        assertTrue(specifier2.equals(specifier1));
-    }
-
-    /**
-     * Validate NetworkAgentSpecifier equals between instances of {@link WifiNetworkAgentSpecifier}.
-     * a) Create network agent specifier 1 for WPA_PSK network
-     * b) Create network agent specifier 2 with different key mgmt params.
-     * c) Ensure that the specifier 2 does not equal specifier 1.
-     */
-    @Test
-    public void testWifiNetworkAgentSpecifierDoesNotEqualsWhenKeyMgmtDifferent() {
-        WifiConfiguration wifiConfiguration1 = createDefaultWifiConfiguration();
-        WifiNetworkAgentSpecifier specifier1 =
-                new WifiNetworkAgentSpecifier(
-                        wifiConfiguration1);
-
-        WifiConfiguration wifiConfiguration2 = new WifiConfiguration(wifiConfiguration1);
-        wifiConfiguration2.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
-        WifiNetworkAgentSpecifier specifier2 =
-                new WifiNetworkAgentSpecifier(
-                        wifiConfiguration2);
-
-        assertFalse(specifier2.equals(specifier1));
-    }
-
-    /**
-     * Validate NetworkAgentSpecifier equals between instances of {@link WifiNetworkAgentSpecifier}.
-     * a) Create network agent specifier 1 for WPA_PSK network
-     * b) Create network agent specifier 2 with different SSID.
-     * c) Ensure that the specifier 2 does not equal specifier 1.
-     */
-    @Test
-    public void testWifiNetworkAgentSpecifierDoesNotSatisifyWhenSsidDifferent() {
-        WifiConfiguration wifiConfiguration1 = createDefaultWifiConfiguration();
-        WifiNetworkAgentSpecifier specifier1 =
-                new WifiNetworkAgentSpecifier(
-                        wifiConfiguration1);
-
-        WifiConfiguration wifiConfiguration2 = new WifiConfiguration(wifiConfiguration1);
-        wifiConfiguration2.SSID = TEST_SSID_1;
-        WifiNetworkAgentSpecifier specifier2 =
-                new WifiNetworkAgentSpecifier(
-                        wifiConfiguration2);
-
-        assertFalse(specifier2.equals(specifier1));
-    }
-
-    /**
-     * Validate NetworkAgentSpecifier equals between instances of {@link WifiNetworkAgentSpecifier}.
-     * a) Create network agent specifier 1 for WPA_PSK network
-     * b) Create network agent specifier 2 with different BSSID.
-     * c) Ensure that the specifier 2 does not equal specifier 1.
-     */
-    @Test
-    public void testWifiNetworkAgentSpecifierDoesNotSatisifyWhenBssidDifferent() {
-        WifiConfiguration wifiConfiguration1 = createDefaultWifiConfiguration();
-        WifiNetworkAgentSpecifier specifier1 =
-                new WifiNetworkAgentSpecifier(
-                        wifiConfiguration1);
-
-        WifiConfiguration wifiConfiguration2 = new WifiConfiguration(wifiConfiguration1);
-        wifiConfiguration2.BSSID = TEST_BSSID_1;
-        WifiNetworkAgentSpecifier specifier2 =
-                new WifiNetworkAgentSpecifier(
-                        wifiConfiguration2);
-
-        assertFalse(specifier2.equals(specifier1));
-    }
-
-    /**
-     * Validate NetworkAgentSpecifier matching.
-     * a) Create a network agent specifier for WPA_PSK network
-     * b) Ensure that the specifier matches {@code null} and {@link MatchAllNetworkSpecifier}
-     * specifiers.
-     */
-    @Test
-    public void testWifiNetworkAgentSpecifierSatisifiesNullAndAllMatch() {
-        WifiNetworkAgentSpecifier specifier = createDefaultNetworkAgentSpecifier();
-
-        assertTrue(specifier.canBeSatisfiedBy(null));
-        assertTrue(specifier.canBeSatisfiedBy(new MatchAllNetworkSpecifier()));
-    }
-
-    /**
-     * Validate NetworkAgentSpecifier matching with itself.
-     * a) Create network agent specifier 1 for WPA_PSK network
-     * b) Create network agent specifier 2 with the same params as specifier 1.
-     * c) Ensure that the agent specifier is satisfied by itself.
-     */
-    @Test
-    public void testWifiNetworkAgentSpecifierDoesSatisifySame() {
-        WifiNetworkAgentSpecifier specifier1 = createDefaultNetworkAgentSpecifier();
-        WifiNetworkAgentSpecifier specifier2 = createDefaultNetworkAgentSpecifier();
-
-        assertTrue(specifier2.canBeSatisfiedBy(specifier1));
-    }
-
-    /**
-     * Validate {@link WifiNetworkAgentSpecifier} with {@link WifiNetworkSpecifier} matching.
-     * a) Create network agent specifier for WPA_PSK network
-     * b) Create network specifier with matching SSID pattern.
-     * c) Ensure that the agent specifier is satisfied by specifier.
-     */
-    @Test
-    public void
-            testWifiNetworkAgentSpecifierSatisfiesNetworkSpecifierWithSsidPattern() {
-        WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier = createDefaultNetworkAgentSpecifier();
-
-        PatternMatcher ssidPattern =
-                new PatternMatcher(TEST_SSID_PATTERN, PatternMatcher.PATTERN_PREFIX);
-        Pair<MacAddress, MacAddress> bssidPattern =
-                Pair.create(WifiManager.ALL_ZEROS_MAC_ADDRESS, WifiManager.ALL_ZEROS_MAC_ADDRESS);
-        WifiConfiguration wificonfigurationNetworkSpecifier = new WifiConfiguration();
-        wificonfigurationNetworkSpecifier.allowedKeyManagement
-                .set(WifiConfiguration.KeyMgmt.WPA_PSK);
-        WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
-                ssidPattern,
-                bssidPattern,
-                wificonfigurationNetworkSpecifier);
-
-        assertTrue(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier));
-        assertTrue(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier));
-    }
-
-    /**
-     * Validate {@link WifiNetworkAgentSpecifier} with {@link WifiNetworkSpecifier} matching.
-     * a) Create network agent specifier for WPA_PSK network
-     * b) Create network specifier with matching BSSID pattern.
-     * c) Ensure that the agent specifier is satisfied by specifier.
-     */
-    @Test
-    public void
-            testWifiNetworkAgentSpecifierSatisfiesNetworkSpecifierWithBssidPattern() {
-        WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier = createDefaultNetworkAgentSpecifier();
-
-        PatternMatcher ssidPattern =
-                new PatternMatcher(".*", PatternMatcher.PATTERN_SIMPLE_GLOB);
-        Pair<MacAddress, MacAddress> bssidPattern =
-                Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
-                        MacAddress.fromString(TEST_BSSID_OUI_MASK));
-        WifiConfiguration wificonfigurationNetworkSpecifier = new WifiConfiguration();
-        wificonfigurationNetworkSpecifier.allowedKeyManagement
-                .set(WifiConfiguration.KeyMgmt.WPA_PSK);
-        WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
-                ssidPattern,
-                bssidPattern,
-                wificonfigurationNetworkSpecifier);
-
-        assertTrue(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier));
-        assertTrue(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier));
-    }
-
-    /**
-     * Validate {@link WifiNetworkAgentSpecifier} with {@link WifiNetworkSpecifier} matching.
-     * a) Create network agent specifier for WPA_PSK network
-     * b) Create network specifier with matching SSID & BSSID pattern.
-     * c) Ensure that the agent specifier is satisfied by specifier.
-     */
-    @Test
-    public void
-            testWifiNetworkAgentSpecifierSatisfiesNetworkSpecifierWithSsidAndBssidPattern() {
-        WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier = createDefaultNetworkAgentSpecifier();
-
-        PatternMatcher ssidPattern =
-                new PatternMatcher(TEST_SSID_PATTERN, PatternMatcher.PATTERN_PREFIX);
-        Pair<MacAddress, MacAddress> bssidPattern =
-                Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
-                        MacAddress.fromString(TEST_BSSID_OUI_MASK));
-        WifiConfiguration wificonfigurationNetworkSpecifier = new WifiConfiguration();
-        wificonfigurationNetworkSpecifier.allowedKeyManagement
-                .set(WifiConfiguration.KeyMgmt.WPA_PSK);
-        WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
-                ssidPattern,
-                bssidPattern,
-                wificonfigurationNetworkSpecifier);
-
-        assertTrue(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier));
-        assertTrue(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier));
-    }
-
-    /**
-     * Validate {@link WifiNetworkAgentSpecifier} with {@link WifiNetworkSpecifier} matching.
-     * a) Create network agent specifier for WPA_PSK network
-     * b) Create network specifier with non-matching SSID pattern.
-     * c) Ensure that the agent specifier is not satisfied by specifier.
-     */
-    @Test
-    public void
-            testWifiNetworkAgentSpecifierDoesNotSatisfyNetworkSpecifierWithSsidPattern() {
-        WifiConfiguration wifiConfigurationNetworkAgent = createDefaultWifiConfiguration();
-        wifiConfigurationNetworkAgent.SSID = "\"" + TEST_SSID_1 + "\"";
-        WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier =
-                new WifiNetworkAgentSpecifier(
-                        wifiConfigurationNetworkAgent);
-
-        PatternMatcher ssidPattern =
-                new PatternMatcher(TEST_SSID_PATTERN, PatternMatcher.PATTERN_PREFIX);
-        Pair<MacAddress, MacAddress> bssidPattern =
-                Pair.create(WifiManager.ALL_ZEROS_MAC_ADDRESS, WifiManager.ALL_ZEROS_MAC_ADDRESS);
-        WifiConfiguration wificonfigurationNetworkSpecifier = new WifiConfiguration();
-        wificonfigurationNetworkSpecifier.allowedKeyManagement
-                .set(WifiConfiguration.KeyMgmt.WPA_PSK);
-        WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
-                ssidPattern,
-                bssidPattern,
-                wificonfigurationNetworkSpecifier);
-
-        assertFalse(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier));
-        assertFalse(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier));
-    }
-
-    /**
-     * Validate {@link WifiNetworkAgentSpecifier} with {@link WifiNetworkSpecifier} matching.
-     * a) Create network agent specifier for WPA_PSK network
-     * b) Create network specifier with non-matching BSSID pattern.
-     * c) Ensure that the agent specifier is not satisfied by specifier.
-     */
-    @Test
-    public void
-            testWifiNetworkAgentSpecifierDoesNotSatisfyNetworkSpecifierWithBssidPattern() {
-        WifiConfiguration wifiConfigurationNetworkAgent = createDefaultWifiConfiguration();
-        wifiConfigurationNetworkAgent.BSSID = TEST_BSSID_1;
-        WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier =
-                new WifiNetworkAgentSpecifier(
-                        wifiConfigurationNetworkAgent);
-
-        PatternMatcher ssidPattern =
-                new PatternMatcher(".*", PatternMatcher.PATTERN_SIMPLE_GLOB);
-        Pair<MacAddress, MacAddress> bssidPattern =
-                Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
-                        MacAddress.fromString(TEST_BSSID_OUI_MASK));
-        WifiConfiguration wificonfigurationNetworkSpecifier = new WifiConfiguration();
-        wificonfigurationNetworkSpecifier.allowedKeyManagement
-                .set(WifiConfiguration.KeyMgmt.WPA_PSK);
-        WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
-                ssidPattern,
-                bssidPattern,
-                wificonfigurationNetworkSpecifier);
-
-        assertFalse(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier));
-        assertFalse(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier));
-    }
-
-    /**
-     * Validate {@link WifiNetworkAgentSpecifier} with {@link WifiNetworkSpecifier} matching.
-     * a) Create network agent specifier for WPA_PSK network
-     * b) Create network specifier with non-matching SSID and BSSID pattern.
-     * c) Ensure that the agent specifier is not satisfied by specifier.
-     */
-    @Test
-    public void
-            testWifiNetworkAgentSpecifierDoesNotSatisfyNetworkSpecifierWithSsidAndBssidPattern() {
-        WifiConfiguration wifiConfigurationNetworkAgent = createDefaultWifiConfiguration();
-        wifiConfigurationNetworkAgent.BSSID = TEST_BSSID_1;
-        WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier =
-                new WifiNetworkAgentSpecifier(
-                        wifiConfigurationNetworkAgent);
-
-        PatternMatcher ssidPattern =
-                new PatternMatcher(TEST_SSID_PATTERN, PatternMatcher.PATTERN_PREFIX);
-        Pair<MacAddress, MacAddress> bssidPattern =
-                Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
-                        MacAddress.fromString(TEST_BSSID_OUI_MASK));
-        WifiConfiguration wificonfigurationNetworkSpecifier = new WifiConfiguration();
-        wificonfigurationNetworkSpecifier.allowedKeyManagement
-                .set(WifiConfiguration.KeyMgmt.WPA_PSK);
-        WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
-                ssidPattern,
-                bssidPattern,
-                wificonfigurationNetworkSpecifier);
-
-        assertFalse(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier));
-        assertFalse(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier));
-    }
-
-    /**
-     * Validate {@link WifiNetworkAgentSpecifier} with {@link WifiNetworkSpecifier} matching.
-     * a) Create network agent specifier for WPA_PSK network
-     * b) Create network specifier with matching SSID and BSSID pattern, but different key mgmt.
-     * c) Ensure that the agent specifier is not satisfied by specifier.
-     */
-    @Test
-    public void
-            testWifiNetworkAgentSpecifierDoesNotSatisfyNetworkSpecifierWithDifferentKeyMgmt() {
-        WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier = createDefaultNetworkAgentSpecifier();
-
-        PatternMatcher ssidPattern =
-                new PatternMatcher(TEST_SSID_PATTERN, PatternMatcher.PATTERN_PREFIX);
-        Pair<MacAddress, MacAddress> bssidPattern =
-                Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
-                        MacAddress.fromString(TEST_BSSID_OUI_MASK));
-        WifiConfiguration wificonfigurationNetworkSpecifier = new WifiConfiguration();
-        wificonfigurationNetworkSpecifier.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
-        WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
-                ssidPattern,
-                bssidPattern,
-                wificonfigurationNetworkSpecifier);
-
-        assertFalse(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier));
-        assertFalse(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier));
-    }
-
-
-    private WifiConfiguration createDefaultWifiConfiguration() {
-        WifiConfiguration wifiConfiguration = new WifiConfiguration();
-        wifiConfiguration.SSID = "\"" + TEST_SSID + "\"";
-        wifiConfiguration.BSSID = TEST_BSSID;
-        wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
-        wifiConfiguration.preSharedKey = TEST_PRESHARED_KEY;
-        return wifiConfiguration;
-    }
-
-    private WifiNetworkAgentSpecifier createDefaultNetworkAgentSpecifier() {
-        return new WifiNetworkAgentSpecifier(createDefaultWifiConfiguration());
-    }
-
-}
diff --git a/wifi/non-updatable/tests/src/android/net/wifi/WifiNetworkScoreCacheTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkScoreCacheTest.java
similarity index 100%
rename from wifi/non-updatable/tests/src/android/net/wifi/WifiNetworkScoreCacheTest.java
rename to wifi/tests/src/android/net/wifi/WifiNetworkScoreCacheTest.java
diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java
deleted file mode 100644
index 6f47f3d..0000000
--- a/wifi/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java
+++ /dev/null
@@ -1,617 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import static android.os.PatternMatcher.PATTERN_LITERAL;
-import static android.os.PatternMatcher.PATTERN_PREFIX;
-import static android.os.PatternMatcher.PATTERN_SIMPLE_GLOB;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import android.net.MacAddress;
-import android.net.MatchAllNetworkSpecifier;
-import android.net.NetworkSpecifier;
-import android.os.Parcel;
-import android.os.PatternMatcher;
-import android.util.Pair;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-import java.security.cert.X509Certificate;
-
-/**
- * Unit tests for {@link android.net.wifi.WifiNetworkSpecifier}.
- */
-@SmallTest
-public class WifiNetworkSpecifierTest {
-    private static final String TEST_SSID = "Test123";
-    private static final String TEST_BSSID_OUI_BASE_ADDRESS = "12:12:12:00:00:00";
-    private static final String TEST_BSSID_OUI_MASK = "ff:ff:ff:00:00:00";
-    private static final String TEST_BSSID = "12:12:12:12:12:12";
-    private static final String TEST_PRESHARED_KEY = "\"Test123\"";
-    private static final String TEST_DOMAIN_SUFFIX_MATCH = "domainSuffixMatch";
-
-    /**
-     * Validate correctness of WifiNetworkSpecifier object created by
-     * {@link WifiNetworkSpecifier.Builder#build()} for open network with SSID pattern.
-     */
-    @Test
-    public void testWifiNetworkSpecifierBuilderForOpenNetworkWithSsidPattern() {
-        NetworkSpecifier specifier = new WifiNetworkSpecifier.Builder()
-                .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_PREFIX))
-                .build();
-
-        assertTrue(specifier instanceof WifiNetworkSpecifier);
-        WifiNetworkSpecifier wifiNetworkSpecifier = (WifiNetworkSpecifier) specifier;
-
-        assertEquals(TEST_SSID, wifiNetworkSpecifier.ssidPatternMatcher.getPath());
-        assertEquals(PATTERN_PREFIX, wifiNetworkSpecifier.ssidPatternMatcher.getType());
-        assertEquals(WifiManager.ALL_ZEROS_MAC_ADDRESS,
-                wifiNetworkSpecifier.bssidPatternMatcher.first);
-        assertEquals(WifiManager.ALL_ZEROS_MAC_ADDRESS,
-                wifiNetworkSpecifier.bssidPatternMatcher.second);
-        assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement
-                .get(WifiConfiguration.KeyMgmt.NONE));
-    }
-
-    /**
-     * Validate correctness of WifiNetworkSpecifier object created by
-     * {@link WifiNetworkSpecifier.Builder#build()} for WPA_PSK network with BSSID
-     * pattern.
-     */
-    @Test
-    public void testWifiNetworkSpecifierBuilderForWpa2PskNetworkWithBssidPattern() {
-        NetworkSpecifier specifier = new WifiNetworkSpecifier.Builder()
-                .setBssidPattern(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
-                        MacAddress.fromString(TEST_BSSID_OUI_MASK))
-                .setWpa2Passphrase(TEST_PRESHARED_KEY)
-                .build();
-
-        assertTrue(specifier instanceof WifiNetworkSpecifier);
-        WifiNetworkSpecifier wifiNetworkSpecifier = (WifiNetworkSpecifier) specifier;
-
-        assertEquals(".*", wifiNetworkSpecifier.ssidPatternMatcher.getPath());
-        assertEquals(PATTERN_SIMPLE_GLOB, wifiNetworkSpecifier.ssidPatternMatcher.getType());
-        assertEquals(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
-                wifiNetworkSpecifier.bssidPatternMatcher.first);
-        assertEquals(MacAddress.fromString(TEST_BSSID_OUI_MASK),
-                wifiNetworkSpecifier.bssidPatternMatcher.second);
-        assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement
-                .get(WifiConfiguration.KeyMgmt.WPA_PSK));
-        assertEquals("\"" + TEST_PRESHARED_KEY + "\"",
-                wifiNetworkSpecifier.wifiConfiguration.preSharedKey);
-    }
-
-    /**
-     * Validate correctness of WifiNetworkSpecifier object created by
-     * {@link WifiNetworkSpecifier.Builder#build()} for WPA_EAP network with
-     * SSID and BSSID pattern.
-     */
-    @Test
-    public void testWifiNetworkSpecifierBuilderForWpa2EapHiddenNetworkWithSsidAndBssid() {
-        WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
-        enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
-        enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.GTC);
-
-        NetworkSpecifier specifier = new WifiNetworkSpecifier.Builder()
-                .setSsid(TEST_SSID)
-                .setBssid(MacAddress.fromString(TEST_BSSID))
-                .setWpa2EnterpriseConfig(enterpriseConfig)
-                .setIsHiddenSsid(true)
-                .build();
-
-        assertTrue(specifier instanceof WifiNetworkSpecifier);
-        WifiNetworkSpecifier wifiNetworkSpecifier = (WifiNetworkSpecifier) specifier;
-
-        assertEquals(TEST_SSID, wifiNetworkSpecifier.ssidPatternMatcher.getPath());
-        assertEquals(PATTERN_LITERAL, wifiNetworkSpecifier.ssidPatternMatcher.getType());
-        assertEquals(MacAddress.fromString(TEST_BSSID),
-                wifiNetworkSpecifier.bssidPatternMatcher.first);
-        assertEquals(MacAddress.BROADCAST_ADDRESS,
-                wifiNetworkSpecifier.bssidPatternMatcher.second);
-        assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement
-                .get(WifiConfiguration.KeyMgmt.WPA_EAP));
-        assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement
-                .get(WifiConfiguration.KeyMgmt.IEEE8021X));
-        assertTrue(wifiNetworkSpecifier.wifiConfiguration.hiddenSSID);
-        assertEquals(enterpriseConfig.getEapMethod(),
-                wifiNetworkSpecifier.wifiConfiguration.enterpriseConfig.getEapMethod());
-        assertEquals(enterpriseConfig.getPhase2Method(),
-                wifiNetworkSpecifier.wifiConfiguration.enterpriseConfig.getPhase2Method());
-    }
-
-    /**
-     * Validate correctness of WifiNetworkSuggestion object created by
-     * {@link WifiNetworkSuggestion.Builder#build()} for WPA3-Enterprise network.
-     */
-    @Test
-    public void testWifiNetworkSuggestionBuilderForWpa3EapNetwork() {
-        WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
-        enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
-        enterpriseConfig.setCaCertificate(FakeKeys.CA_CERT0);
-        enterpriseConfig.setDomainSuffixMatch(TEST_DOMAIN_SUFFIX_MATCH);
-
-        NetworkSpecifier specifier = new WifiNetworkSpecifier.Builder()
-                .setSsid(TEST_SSID)
-                .setWpa3EnterpriseConfig(enterpriseConfig)
-                .build();
-
-        assertTrue(specifier instanceof WifiNetworkSpecifier);
-        WifiNetworkSpecifier wifiNetworkSpecifier = (WifiNetworkSpecifier) specifier;
-
-        assertEquals("\"" + TEST_SSID + "\"", wifiNetworkSpecifier.wifiConfiguration.SSID);
-        assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement
-                .get(WifiConfiguration.KeyMgmt.IEEE8021X));
-        assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement
-                .get(WifiConfiguration.KeyMgmt.WPA_EAP));
-        assertFalse(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement
-                .get(WifiConfiguration.KeyMgmt.SUITE_B_192));
-        assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedGroupCiphers
-                .get(WifiConfiguration.GroupCipher.CCMP));
-        assertTrue(wifiNetworkSpecifier.wifiConfiguration.requirePmf);
-        assertNull(wifiNetworkSpecifier.wifiConfiguration.preSharedKey);
-        assertNotNull(wifiNetworkSpecifier.wifiConfiguration.enterpriseConfig);
-    }
-
-    /**
-     * Validate correctness of WifiNetworkSuggestion object created by
-     * {@link WifiNetworkSuggestion.Builder#build()} for WPA3-Enterprise 192-bit RSA SuiteB network.
-     */
-    @Test
-    public void testWifiNetworkSuggestionBuilderForWpa3SuiteBRsaEapNetwork() {
-        WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
-        enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
-        enterpriseConfig.setCaCertificate(FakeKeys.CA_SUITE_B_RSA3072_CERT);
-        enterpriseConfig.setClientKeyEntryWithCertificateChain(FakeKeys.CLIENT_SUITE_B_RSA3072_KEY,
-                new X509Certificate[] {FakeKeys.CLIENT_SUITE_B_RSA3072_CERT});
-
-        enterpriseConfig.setDomainSuffixMatch(TEST_DOMAIN_SUFFIX_MATCH);
-
-        NetworkSpecifier specifier = new WifiNetworkSpecifier.Builder()
-                .setSsid(TEST_SSID)
-                .setWpa3EnterpriseConfig(enterpriseConfig)
-                .build();
-
-        assertTrue(specifier instanceof WifiNetworkSpecifier);
-        WifiNetworkSpecifier wifiNetworkSpecifier = (WifiNetworkSpecifier) specifier;
-
-        assertEquals("\"" + TEST_SSID + "\"", wifiNetworkSpecifier.wifiConfiguration.SSID);
-        assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement
-                .get(WifiConfiguration.KeyMgmt.SUITE_B_192));
-        assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedGroupCiphers
-                .get(WifiConfiguration.GroupCipher.GCMP_256));
-        assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedGroupManagementCiphers
-                .get(WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256));
-        assertTrue(wifiNetworkSpecifier.wifiConfiguration.requirePmf);
-        assertNull(wifiNetworkSpecifier.wifiConfiguration.preSharedKey);
-        assertNotNull(wifiNetworkSpecifier.wifiConfiguration.enterpriseConfig);
-    }
-
-    /**
-     * Validate correctness of WifiNetworkSuggestion object created by
-     * {@link WifiNetworkSuggestion.Builder#build()} for WPA3-Enterprise 192-bit ECC SuiteB network.
-     */
-    @Test
-    public void testWifiNetworkSuggestionBuilderForWpa3SuiteBEccEapNetwork() {
-        WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
-        enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
-        enterpriseConfig.setCaCertificate(FakeKeys.CA_SUITE_B_ECDSA_CERT);
-        enterpriseConfig.setClientKeyEntryWithCertificateChain(FakeKeys.CLIENT_SUITE_B_ECC_KEY,
-                new X509Certificate[] {FakeKeys.CLIENT_SUITE_B_ECDSA_CERT});
-
-        enterpriseConfig.setDomainSuffixMatch(TEST_DOMAIN_SUFFIX_MATCH);
-
-        NetworkSpecifier specifier = new WifiNetworkSpecifier.Builder()
-                .setSsid(TEST_SSID)
-                .setWpa3EnterpriseConfig(enterpriseConfig)
-                .build();
-
-        assertTrue(specifier instanceof WifiNetworkSpecifier);
-        WifiNetworkSpecifier wifiNetworkSpecifier = (WifiNetworkSpecifier) specifier;
-
-        assertEquals("\"" + TEST_SSID + "\"", wifiNetworkSpecifier.wifiConfiguration.SSID);
-        assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement
-                .get(WifiConfiguration.KeyMgmt.SUITE_B_192));
-        assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedGroupCiphers
-                .get(WifiConfiguration.GroupCipher.GCMP_256));
-        assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedGroupManagementCiphers
-                .get(WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256));
-        assertTrue(wifiNetworkSpecifier.wifiConfiguration.requirePmf);
-        assertNull(wifiNetworkSpecifier.wifiConfiguration.preSharedKey);
-        assertNotNull(wifiNetworkSpecifier.wifiConfiguration.enterpriseConfig);
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSpecifier.Builder#setSsid(String)} throws an exception
-     * when the string is not Unicode.
-     */
-    @Test(expected = IllegalArgumentException.class)
-    public void testWifiNetworkSpecifierBuilderSetSsidWithNonUnicodeString() {
-        new WifiNetworkSpecifier.Builder()
-                .setSsid("\ud800")
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSpecifier.Builder#setWpa2Passphrase(String)} throws an exception
-     * when the string is not ASCII encodable.
-     */
-    @Test(expected = IllegalArgumentException.class)
-    public void testWifiNetworkSpecifierSetWpa2PasphraseWithNonAsciiString() {
-        new WifiNetworkSpecifier.Builder()
-                .setSsid(TEST_SSID)
-                .setWpa2Passphrase("salvē")
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
-     * when neither SSID nor BSSID patterns were set.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testWifiNetworkSpecifierBuilderWithNoSsidAndBssidPattern() {
-        new WifiNetworkSpecifier.Builder().build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
-     * when match-all SSID pattern is set.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testWifiNetworkSpecifierBuilderWithMatchAllSsidPattern1() {
-        new WifiNetworkSpecifier.Builder()
-                .setSsidPattern(new PatternMatcher(".*", PATTERN_SIMPLE_GLOB))
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
-     * when match-all SSID pattern is set.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testWifiNetworkSpecifierBuilderWithMatchAllSsidPattern2() {
-        new WifiNetworkSpecifier.Builder()
-                .setSsidPattern(new PatternMatcher(".*", PatternMatcher.PATTERN_ADVANCED_GLOB))
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
-     * when match-all SSID pattern is set.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testWifiNetworkSpecifierBuilderWithMatchAllSsidPattern3() {
-        new WifiNetworkSpecifier.Builder()
-                .setSsidPattern(new PatternMatcher("", PATTERN_PREFIX))
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
-     * when match-all BSSID pattern is set.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testWifiNetworkSpecifierBuilderWithMatchAllBssidPattern() {
-        new WifiNetworkSpecifier.Builder()
-                .setBssidPattern(WifiManager.ALL_ZEROS_MAC_ADDRESS,
-                        WifiManager.ALL_ZEROS_MAC_ADDRESS)
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
-     * when match-none SSID pattern is set.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testWifiNetworkSpecifierBuilderWithMatchNoneSsidPattern1() {
-        new WifiNetworkSpecifier.Builder()
-                .setSsidPattern(new PatternMatcher("", PatternMatcher.PATTERN_LITERAL))
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
-     * when match-none SSID pattern is set.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testWifiNetworkSpecifierBuilderWithMatchNoneSsidPattern2() {
-        new WifiNetworkSpecifier.Builder()
-                .setSsid("")
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
-     * when match-none BSSID pattern is set.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testWifiNetworkSpecifierBuilderWithMatchNoneBssidPattern1() {
-        new WifiNetworkSpecifier.Builder()
-                .setBssidPattern(MacAddress.BROADCAST_ADDRESS, MacAddress.BROADCAST_ADDRESS)
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
-     * when match-none BSSID pattern is set.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testWifiNetworkSpecifierBuilderWithMatchNoneBssidPattern2() {
-        new WifiNetworkSpecifier.Builder()
-                .setBssid(MacAddress.BROADCAST_ADDRESS)
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
-     * when match-none BSSID pattern is set.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testWifiNetworkSpecifierBuilderWithMatchNoneBssidPattern3() {
-        new WifiNetworkSpecifier.Builder()
-                .setBssid(WifiManager.ALL_ZEROS_MAC_ADDRESS)
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
-     * when SSID pattern is set for hidden network.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testWifiNetworkSpecifierBuilderWithBssidMatchPatternForHiddenNetwork() {
-        new WifiNetworkSpecifier.Builder()
-                .setBssidPattern(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
-                        MacAddress.fromString(TEST_BSSID_OUI_MASK))
-                .setIsHiddenSsid(true)
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
-     * when both {@link WifiNetworkSpecifier.Builder#setWpa2Passphrase(String)} and
-     * {@link WifiNetworkSpecifier.Builder#setWpa2EnterpriseConfig(WifiEnterpriseConfig)} are
-     * invoked.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testWifiNetworkSpecifierBuilderWithBothWpa2PasphraseAndEnterpriseConfig() {
-        new WifiNetworkSpecifier.Builder()
-                .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_LITERAL))
-                .setWpa2Passphrase(TEST_PRESHARED_KEY)
-                .setWpa2EnterpriseConfig(new WifiEnterpriseConfig())
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
-     * when SSID pattern is set for hidden network.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testWifiNetworkSpecifierBuilderWithSsidMatchPatternForHiddenNetwork() {
-        new WifiNetworkSpecifier.Builder()
-                .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_PREFIX))
-                .setIsHiddenSsid(true)
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
-     * when both {@link WifiNetworkSpecifier.Builder#setWpa2Passphrase(String)} and
-     * {@link WifiNetworkSpecifier.Builder#setWpa3Passphrase(String)} are invoked.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testWifiNetworkSpecifierBuilderWithBothWpa2PasphraseAndWpa3Passphrase() {
-        new WifiNetworkSpecifier.Builder()
-                .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_LITERAL))
-                .setWpa2Passphrase(TEST_PRESHARED_KEY)
-                .setWpa3Passphrase(TEST_PRESHARED_KEY)
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
-     * when both {@link WifiNetworkSpecifier.Builder#setWpa3Passphrase(String)} and
-     * {@link WifiNetworkSpecifier.Builder#setWpa3EnterpriseConfig(WifiEnterpriseConfig)} are
-     * invoked.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testWifiNetworkSpecifierBuilderWithBothWpa3PasphraseAndEnterprise() {
-        new WifiNetworkSpecifier.Builder()
-                .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_LITERAL))
-                .setWpa3Passphrase(TEST_PRESHARED_KEY)
-                .setWpa3EnterpriseConfig(new WifiEnterpriseConfig())
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
-     * when both {@link WifiNetworkSpecifier.Builder#setWpa3Passphrase(String)} and
-     * {@link WifiNetworkSpecifier.Builder#setIsEnhancedOpen(boolean)} are invoked.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testWifiNetworkSpecifierBuilderWithBothWpa3PasphraseAndEnhancedOpen() {
-        new WifiNetworkSpecifier.Builder()
-                .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_LITERAL))
-                .setWpa3Passphrase(TEST_PRESHARED_KEY)
-                .setIsEnhancedOpen(true)
-                .build();
-    }
-
-    /**
-     * Validate that parcel marshalling/unmarshalling works
-     */
-    @Test
-    public void testWifiNetworkSpecifierParcel() {
-        WifiConfiguration wifiConfiguration = new WifiConfiguration();
-        wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
-        wifiConfiguration.preSharedKey = TEST_PRESHARED_KEY;
-        WifiNetworkSpecifier specifier =
-                new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
-                        Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
-                                MacAddress.fromString(TEST_BSSID_OUI_MASK)),
-                        wifiConfiguration);
-
-        Parcel parcelW = Parcel.obtain();
-        specifier.writeToParcel(parcelW, 0);
-        byte[] bytes = parcelW.marshall();
-        parcelW.recycle();
-
-        Parcel parcelR = Parcel.obtain();
-        parcelR.unmarshall(bytes, 0, bytes.length);
-        parcelR.setDataPosition(0);
-        WifiNetworkSpecifier parcelSpecifier =
-                WifiNetworkSpecifier.CREATOR.createFromParcel(parcelR);
-
-        assertEquals(specifier, parcelSpecifier);
-    }
-
-    /**
-     * Validate NetworkSpecifier matching.
-     * a) Create a network specifier for WPA_PSK network
-     * b) Ensure that the specifier does not match {@code null} and {@link MatchAllNetworkSpecifier}
-     * specifiers.
-     */
-    @Test
-    public void testWifiNetworkSpecifierDoesNotSatisfyNullAndAllMatch() {
-        WifiConfiguration wifiConfiguration = new WifiConfiguration();
-        wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
-        wifiConfiguration.preSharedKey = TEST_PRESHARED_KEY;
-        WifiNetworkSpecifier specifier =
-                new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
-                        Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
-                                MacAddress.fromString(TEST_BSSID_OUI_MASK)),
-                        wifiConfiguration);
-
-        assertFalse(specifier.canBeSatisfiedBy(null));
-        assertFalse(specifier.canBeSatisfiedBy(new MatchAllNetworkSpecifier()));
-    }
-
-    /**
-     * Validate NetworkSpecifier matching.
-     * a) Create network specifier 1 for WPA_PSK network
-     * b) Create network specifier 2 with the same params as specifier 1.
-     * c) Ensure that the specifier 2 is satisfied by specifier 1.
-     */
-    @Test
-    public void testWifiNetworkSpecifierSatisfiesSame() {
-        WifiConfiguration wifiConfiguration = new WifiConfiguration();
-        wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
-        wifiConfiguration.preSharedKey = TEST_PRESHARED_KEY;
-
-        WifiNetworkSpecifier specifier1 =
-                new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
-                        Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
-                                MacAddress.fromString(TEST_BSSID_OUI_MASK)),
-                        wifiConfiguration);
-
-        WifiNetworkSpecifier specifier2 =
-                new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
-                        Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
-                                MacAddress.fromString(TEST_BSSID_OUI_MASK)),
-                        wifiConfiguration);
-
-        assertTrue(specifier2.canBeSatisfiedBy(specifier1));
-    }
-
-    /**
-     * Validate NetworkSpecifier matching.
-     * a) Create network specifier 1 for WPA_PSK network
-     * b) Create network specifier 2 with different key mgmt params.
-     * c) Ensure that the specifier 2 is not satisfied by specifier 1.
-     */
-    @Test
-    public void testWifiNetworkSpecifierDoesNotSatisfyWhenKeyMgmtDifferent() {
-        WifiConfiguration wifiConfiguration1 = new WifiConfiguration();
-        wifiConfiguration1.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
-        wifiConfiguration1.preSharedKey = TEST_PRESHARED_KEY;
-
-        WifiNetworkSpecifier specifier1 =
-                new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
-                        Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
-                                MacAddress.fromString(TEST_BSSID_OUI_MASK)),
-                        wifiConfiguration1);
-
-        WifiConfiguration wifiConfiguration2 = new WifiConfiguration();
-        wifiConfiguration2.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
-        WifiNetworkSpecifier specifier2 =
-                new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
-                        Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
-                                MacAddress.fromString(TEST_BSSID_OUI_MASK)),
-                        wifiConfiguration2);
-
-        assertFalse(specifier2.canBeSatisfiedBy(specifier1));
-    }
-
-    /**
-     * Validate NetworkSpecifier matching.
-     * a) Create network specifier 1 for WPA_PSK network
-     * b) Create network specifier 2 with different SSID pattern.
-     * c) Ensure that the specifier 2 is not satisfied by specifier 1.
-     */
-    @Test
-    public void testWifiNetworkSpecifierDoesNotSatisfyWhenSsidDifferent() {
-        WifiConfiguration wifiConfiguration = new WifiConfiguration();
-        wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
-        wifiConfiguration.preSharedKey = TEST_PRESHARED_KEY;
-
-        WifiNetworkSpecifier specifier1 =
-                new WifiNetworkSpecifier(new PatternMatcher("", PATTERN_LITERAL),
-                        Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
-                                MacAddress.fromString(TEST_BSSID_OUI_MASK)),
-                        wifiConfiguration);
-
-        WifiNetworkSpecifier specifier2 =
-                new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
-                        Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
-                                MacAddress.fromString(TEST_BSSID_OUI_MASK)),
-                        wifiConfiguration);
-
-        assertFalse(specifier2.canBeSatisfiedBy(specifier1));
-    }
-
-    /**
-     * Validate NetworkSpecifier matching.
-     * a) Create network specifier 1 for WPA_PSK network
-     * b) Create network specifier 2 with different BSSID pattern.
-     * c) Ensure that the specifier 2 is not satisfied by specifier 1.
-     */
-    @Test
-    public void testWifiNetworkSpecifierDoesNotSatisfyWhenBssidDifferent() {
-        WifiConfiguration wifiConfiguration = new WifiConfiguration();
-        wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
-        wifiConfiguration.preSharedKey = TEST_PRESHARED_KEY;
-
-        WifiNetworkSpecifier specifier1 =
-                new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
-                        Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
-                                MacAddress.fromString(TEST_BSSID_OUI_MASK)),
-                        wifiConfiguration);
-
-        WifiNetworkSpecifier specifier2 =
-                new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
-                        Pair.create(WifiManager.ALL_ZEROS_MAC_ADDRESS,
-                                WifiManager.ALL_ZEROS_MAC_ADDRESS),
-                        wifiConfiguration);
-
-        assertFalse(specifier2.canBeSatisfiedBy(specifier1));
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java
deleted file mode 100644
index 6d5b9b9..0000000
--- a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java
+++ /dev/null
@@ -1,976 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import static org.junit.Assert.*;
-
-import android.net.MacAddress;
-import android.net.wifi.hotspot2.PasspointConfiguration;
-import android.net.wifi.hotspot2.PasspointTestUtils;
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-import java.security.cert.X509Certificate;
-
-/**
- * Unit tests for {@link android.net.wifi.WifiNetworkSuggestion}.
- */
-@SmallTest
-public class WifiNetworkSuggestionTest {
-    private static final String TEST_SSID = "\"Test123\"";
-    private static final String TEST_BSSID = "12:12:12:12:12:12";
-    private static final String TEST_SSID_1 = "\"Test1234\"";
-    private static final String TEST_PRESHARED_KEY = "Test123";
-    private static final String TEST_FQDN = "fqdn";
-    private static final String TEST_WAPI_CERT_SUITE = "suite";
-    private static final String TEST_DOMAIN_SUFFIX_MATCH = "domainSuffixMatch";
-
-    /**
-     * Validate correctness of WifiNetworkSuggestion object created by
-     * {@link WifiNetworkSuggestion.Builder#build()} for Open network which requires
-     * app interaction.
-     */
-    @Test
-    public void testWifiNetworkSuggestionBuilderForOpenNetworkWithReqAppInteraction() {
-        WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
-                .setSsid(TEST_SSID)
-                .setIsAppInteractionRequired(true)
-                .build();
-
-        assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID);
-        assertTrue(suggestion.wifiConfiguration.allowedKeyManagement
-                .get(WifiConfiguration.KeyMgmt.NONE));
-        assertTrue(suggestion.isAppInteractionRequired);
-        assertFalse(suggestion.isUserInteractionRequired);
-        assertEquals(WifiConfiguration.METERED_OVERRIDE_NONE,
-                suggestion.wifiConfiguration.meteredOverride);
-        assertEquals(-1, suggestion.wifiConfiguration.priority);
-        assertFalse(suggestion.isUserAllowedToManuallyConnect);
-        assertTrue(suggestion.isInitialAutoJoinEnabled);
-        assertNull(suggestion.getEnterpriseConfig());
-    }
-
-    /**
-     * Validate correctness of WifiNetworkSuggestion object created by
-     * {@link WifiNetworkSuggestion.Builder#build()} for WPA_EAP network which requires
-     * app interaction, not share credential and has a priority of zero set.
-     */
-    @Test
-    public void
-            testWifiNetworkSuggestionBuilderForWpa2EapNetworkWithPriorityAndReqAppInteraction() {
-        WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
-                .setSsid(TEST_SSID)
-                .setWpa2Passphrase(TEST_PRESHARED_KEY)
-                .setIsAppInteractionRequired(true)
-                .setCredentialSharedWithUser(false)
-                .setPriority(0)
-                .build();
-
-        assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID);
-        assertTrue(suggestion.wifiConfiguration.allowedKeyManagement
-                .get(WifiConfiguration.KeyMgmt.WPA_PSK));
-        assertEquals("\"" + TEST_PRESHARED_KEY + "\"",
-                suggestion.wifiConfiguration.preSharedKey);
-        assertTrue(suggestion.isAppInteractionRequired);
-        assertFalse(suggestion.isUserInteractionRequired);
-        assertEquals(WifiConfiguration.METERED_OVERRIDE_NONE,
-                suggestion.wifiConfiguration.meteredOverride);
-        assertEquals(0, suggestion.wifiConfiguration.priority);
-        assertFalse(suggestion.isUserAllowedToManuallyConnect);
-        assertTrue(suggestion.isInitialAutoJoinEnabled);
-        assertNull(suggestion.getEnterpriseConfig());
-    }
-
-    /**
-     * Validate correctness of WifiNetworkSuggestion object created by
-     * {@link WifiNetworkSuggestion.Builder#build()} for WPA_PSK network which requires
-     * user interaction and is metered.
-     */
-    @Test
-    public void
-            testWifiNetworkSuggestionBuilderForWpa2PskNetworkWithMeteredAndReqUserInteraction() {
-        WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
-                .setSsid(TEST_SSID)
-                .setWpa2Passphrase(TEST_PRESHARED_KEY)
-                .setIsUserInteractionRequired(true)
-                .setIsInitialAutojoinEnabled(false)
-                .setIsMetered(true)
-                .build();
-
-        assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID);
-        assertTrue(suggestion.wifiConfiguration.allowedKeyManagement
-                .get(WifiConfiguration.KeyMgmt.WPA_PSK));
-        assertEquals("\"" + TEST_PRESHARED_KEY + "\"",
-                suggestion.wifiConfiguration.preSharedKey);
-        assertFalse(suggestion.isAppInteractionRequired);
-        assertTrue(suggestion.isUserInteractionRequired);
-        assertEquals(WifiConfiguration.METERED_OVERRIDE_METERED,
-                suggestion.wifiConfiguration.meteredOverride);
-        assertEquals(-1, suggestion.wifiConfiguration.priority);
-        assertTrue(suggestion.isUserAllowedToManuallyConnect);
-        assertFalse(suggestion.isInitialAutoJoinEnabled);
-        assertNull(suggestion.getEnterpriseConfig());
-    }
-
-    /**
-     * Validate correctness of WifiNetworkSuggestion object created by
-     * {@link WifiNetworkSuggestion.Builder#build()} for WPA_PSK network which requires
-     * user interaction and is not metered.
-     */
-    @Test
-    public void
-            testWifiNetworkSuggestionBuilderForWpa2PskNetworkWithNotMeteredAndReqUserInteraction() {
-        WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
-                .setSsid(TEST_SSID)
-                .setWpa2Passphrase(TEST_PRESHARED_KEY)
-                .setIsUserInteractionRequired(true)
-                .setIsInitialAutojoinEnabled(false)
-                .setIsMetered(false)
-                .build();
-
-        assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID);
-        assertTrue(suggestion.wifiConfiguration.allowedKeyManagement
-                .get(WifiConfiguration.KeyMgmt.WPA_PSK));
-        assertEquals("\"" + TEST_PRESHARED_KEY + "\"",
-                suggestion.wifiConfiguration.preSharedKey);
-        assertFalse(suggestion.isAppInteractionRequired);
-        assertTrue(suggestion.isUserInteractionRequired);
-        assertEquals(WifiConfiguration.METERED_OVERRIDE_NOT_METERED,
-                suggestion.wifiConfiguration.meteredOverride);
-        assertEquals(-1, suggestion.wifiConfiguration.priority);
-        assertTrue(suggestion.isUserAllowedToManuallyConnect);
-        assertFalse(suggestion.isInitialAutoJoinEnabled);
-        assertNull(suggestion.getEnterpriseConfig());
-    }
-
-    /**
-     * Validate correctness of WifiNetworkSuggestion object created by
-     * {@link WifiNetworkSuggestion.Builder#build()} for OWE network.
-     */
-    @Test
-    public void testWifiNetworkSuggestionBuilderForEnhancedOpenNetworkWithBssid() {
-        WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
-                .setSsid(TEST_SSID)
-                .setBssid(MacAddress.fromString(TEST_BSSID))
-                .setIsEnhancedOpen(true)
-                .build();
-
-        assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID);
-        assertEquals(TEST_BSSID, suggestion.wifiConfiguration.BSSID);
-        assertTrue(suggestion.wifiConfiguration.allowedKeyManagement
-                .get(WifiConfiguration.KeyMgmt.OWE));
-        assertNull(suggestion.wifiConfiguration.preSharedKey);
-        assertTrue(suggestion.wifiConfiguration.requirePmf);
-        assertFalse(suggestion.isUserAllowedToManuallyConnect);
-        assertTrue(suggestion.isInitialAutoJoinEnabled);
-        assertNull(suggestion.getEnterpriseConfig());
-    }
-
-    /**
-     * Validate correctness of WifiNetworkSuggestion object created by
-     * {@link WifiNetworkSuggestion.Builder#build()} for SAE network.
-     */
-    @Test
-    public void testWifiNetworkSuggestionBuilderForWpa3PskNetwork() {
-        WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
-                .setSsid(TEST_SSID)
-                .setWpa3Passphrase(TEST_PRESHARED_KEY)
-                .setCredentialSharedWithUser(true)
-                .setIsInitialAutojoinEnabled(false)
-                .build();
-
-        assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID);
-        assertTrue(suggestion.wifiConfiguration.allowedKeyManagement
-                .get(WifiConfiguration.KeyMgmt.SAE));
-        assertEquals("\"" + TEST_PRESHARED_KEY + "\"",
-                suggestion.wifiConfiguration.preSharedKey);
-        assertTrue(suggestion.wifiConfiguration.requirePmf);
-        assertTrue(suggestion.isUserAllowedToManuallyConnect);
-        assertFalse(suggestion.isInitialAutoJoinEnabled);
-        assertNull(suggestion.getEnterpriseConfig());
-    }
-
-    /**
-     * Validate correctness of WifiNetworkSuggestion object created by
-     * {@link WifiNetworkSuggestion.Builder#build()} for WPA3-Enterprise network.
-     */
-    @Test
-    public void testWifiNetworkSuggestionBuilderForWpa3EapNetwork() {
-        WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
-        enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
-        enterpriseConfig.setCaCertificate(FakeKeys.CA_CERT0);
-        enterpriseConfig.setDomainSuffixMatch(TEST_DOMAIN_SUFFIX_MATCH);
-
-        WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
-                .setSsid(TEST_SSID)
-                .setWpa3EnterpriseConfig(enterpriseConfig)
-                .build();
-
-        assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID);
-        assertTrue(suggestion.wifiConfiguration.allowedKeyManagement
-                .get(WifiConfiguration.KeyMgmt.IEEE8021X));
-        assertTrue(suggestion.wifiConfiguration.allowedKeyManagement
-                .get(WifiConfiguration.KeyMgmt.WPA_EAP));
-        assertFalse(suggestion.wifiConfiguration.allowedKeyManagement
-                .get(WifiConfiguration.KeyMgmt.SUITE_B_192));
-        assertTrue(suggestion.wifiConfiguration.allowedGroupCiphers
-                .get(WifiConfiguration.GroupCipher.CCMP));
-        assertTrue(suggestion.wifiConfiguration.requirePmf);
-        assertNull(suggestion.wifiConfiguration.preSharedKey);
-        // allowedSuiteBCiphers are set according to the loaded certificate and cannot be tested
-        // here.
-        assertTrue(suggestion.isUserAllowedToManuallyConnect);
-        assertTrue(suggestion.isInitialAutoJoinEnabled);
-        assertNotNull(suggestion.getEnterpriseConfig());
-    }
-
-    /**
-     * Validate correctness of WifiNetworkSuggestion object created by
-     * {@link WifiNetworkSuggestion.Builder#build()} for WPA3-Enterprise 192-bit RSA SuiteB network.
-     */
-    @Test
-    public void testWifiNetworkSuggestionBuilderForWpa3SuiteBRsaEapNetwork() {
-        WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
-        enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
-        enterpriseConfig.setCaCertificate(FakeKeys.CA_SUITE_B_RSA3072_CERT);
-        enterpriseConfig.setClientKeyEntryWithCertificateChain(FakeKeys.CLIENT_SUITE_B_RSA3072_KEY,
-                new X509Certificate[] {FakeKeys.CLIENT_SUITE_B_RSA3072_CERT});
-
-        enterpriseConfig.setDomainSuffixMatch(TEST_DOMAIN_SUFFIX_MATCH);
-
-        WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
-                .setSsid(TEST_SSID)
-                .setWpa3EnterpriseConfig(enterpriseConfig)
-                .build();
-
-        assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID);
-        assertTrue(suggestion.wifiConfiguration.allowedKeyManagement
-                .get(WifiConfiguration.KeyMgmt.SUITE_B_192));
-        assertTrue(suggestion.wifiConfiguration.allowedGroupCiphers
-                .get(WifiConfiguration.GroupCipher.GCMP_256));
-        assertTrue(suggestion.wifiConfiguration.allowedGroupManagementCiphers
-                .get(WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256));
-        assertTrue(suggestion.wifiConfiguration.requirePmf);
-        assertNull(suggestion.wifiConfiguration.preSharedKey);
-        // allowedSuiteBCiphers are set according to the loaded certificate and cannot be tested
-        // here.
-        assertTrue(suggestion.isUserAllowedToManuallyConnect);
-        assertTrue(suggestion.isInitialAutoJoinEnabled);
-        assertNotNull(suggestion.getEnterpriseConfig());
-    }
-
-    /**
-     * Validate correctness of WifiNetworkSuggestion object created by
-     * {@link WifiNetworkSuggestion.Builder#build()} for WPA3-Enterprise 192-bit ECC SuiteB network.
-     */
-    @Test
-    public void testWifiNetworkSuggestionBuilderForWpa3SuiteBEccEapNetwork() {
-        WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
-        enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
-        enterpriseConfig.setCaCertificate(FakeKeys.CA_SUITE_B_ECDSA_CERT);
-        enterpriseConfig.setClientKeyEntryWithCertificateChain(FakeKeys.CLIENT_SUITE_B_ECC_KEY,
-                new X509Certificate[] {FakeKeys.CLIENT_SUITE_B_ECDSA_CERT});
-
-        enterpriseConfig.setDomainSuffixMatch(TEST_DOMAIN_SUFFIX_MATCH);
-
-        WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
-                .setSsid(TEST_SSID)
-                .setWpa3EnterpriseConfig(enterpriseConfig)
-                .build();
-
-        assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID);
-        assertTrue(suggestion.wifiConfiguration.allowedKeyManagement
-                .get(WifiConfiguration.KeyMgmt.SUITE_B_192));
-        assertTrue(suggestion.wifiConfiguration.allowedGroupCiphers
-                .get(WifiConfiguration.GroupCipher.GCMP_256));
-        assertTrue(suggestion.wifiConfiguration.allowedGroupManagementCiphers
-                .get(WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256));
-        assertTrue(suggestion.wifiConfiguration.requirePmf);
-        assertNull(suggestion.wifiConfiguration.preSharedKey);
-        // allowedSuiteBCiphers are set according to the loaded certificate and cannot be tested
-        // here.
-        assertTrue(suggestion.isUserAllowedToManuallyConnect);
-        assertTrue(suggestion.isInitialAutoJoinEnabled);
-        assertNotNull(suggestion.getEnterpriseConfig());
-    }
-
-    /**
-     * Ensure create enterprise suggestion requires CA, when CA certificate is missing, will throw
-     * an exception.
-     */
-    @Test (expected = IllegalArgumentException.class)
-    public void testWifiNetworkSuggestionBuilderForEapNetworkWithoutCa() {
-        WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
-        enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
-        enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.GTC);
-        enterpriseConfig.setDomainSuffixMatch(TEST_DOMAIN_SUFFIX_MATCH);
-
-        WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
-                .setSsid(TEST_SSID)
-                .setWpa2EnterpriseConfig(enterpriseConfig)
-                .build();
-    }
-
-    /**
-     * Ensure create enterprise suggestion requires CA, when both domain suffix and alt subject
-     * match are missing, will throw an exception.
-     */
-    @Test (expected = IllegalArgumentException.class)
-    public void testWifiNetworkSuggestionBuilderForEapNetworkWithoutMatch() {
-        WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
-        enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
-        enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.GTC);
-        enterpriseConfig.setCaCertificate(FakeKeys.CA_CERT0);
-
-        WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
-                .setSsid(TEST_SSID)
-                .setWpa3EnterpriseConfig(enterpriseConfig)
-                .build();
-    }
-
-    /**
-     * Validate correctness of WifiNetworkSuggestion object created by
-     * {@link WifiNetworkSuggestion.Builder#build()} for WAPI-PSK network.
-     */
-    @Test
-    public void testWifiNetworkSuggestionBuilderForWapiPskNetwork() {
-        WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
-                .setSsid(TEST_SSID)
-                .setWapiPassphrase(TEST_PRESHARED_KEY)
-                .build();
-
-        assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID);
-        assertTrue(suggestion.wifiConfiguration.allowedKeyManagement
-                .get(WifiConfiguration.KeyMgmt.WAPI_PSK));
-        assertTrue(suggestion.wifiConfiguration.allowedPairwiseCiphers
-                .get(WifiConfiguration.PairwiseCipher.SMS4));
-        assertTrue(suggestion.wifiConfiguration.allowedGroupCiphers
-                .get(WifiConfiguration.GroupCipher.SMS4));
-        assertEquals("\"" + TEST_PRESHARED_KEY + "\"",
-                suggestion.wifiConfiguration.preSharedKey);
-        assertNull(suggestion.getEnterpriseConfig());
-    }
-
-
-    /**
-     * Validate correctness of WifiNetworkSuggestion object created by
-     * {@link WifiNetworkSuggestion.Builder#build()} for WAPI-CERT network.
-     */
-    @Test
-    public void testWifiNetworkSuggestionBuilderForWapiCertNetwork() {
-        WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
-        enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.WAPI_CERT);
-        enterpriseConfig.setWapiCertSuite(TEST_WAPI_CERT_SUITE);
-        WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
-                .setSsid(TEST_SSID)
-                .setWapiEnterpriseConfig(enterpriseConfig)
-                .build();
-
-        assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID);
-        assertTrue(suggestion.wifiConfiguration.allowedKeyManagement
-                .get(WifiConfiguration.KeyMgmt.WAPI_CERT));
-        assertTrue(suggestion.wifiConfiguration.allowedPairwiseCiphers
-                .get(WifiConfiguration.PairwiseCipher.SMS4));
-        assertTrue(suggestion.wifiConfiguration.allowedGroupCiphers
-                .get(WifiConfiguration.GroupCipher.SMS4));
-        assertNull(suggestion.wifiConfiguration.preSharedKey);
-        assertNotNull(suggestion.wifiConfiguration.enterpriseConfig);
-        assertEquals(WifiEnterpriseConfig.Eap.WAPI_CERT,
-                suggestion.wifiConfiguration.enterpriseConfig.getEapMethod());
-        assertEquals(TEST_WAPI_CERT_SUITE,
-                suggestion.wifiConfiguration.enterpriseConfig.getWapiCertSuite());
-        assertNotNull(suggestion.getEnterpriseConfig());
-    }
-
-    /**
-     * Validate correctness of WifiNetworkSuggestion object created by
-     * {@link WifiNetworkSuggestion.Builder#build()} for WAPI-CERT network
-     * which selects the certificate suite automatically.
-     */
-    @Test
-    public void testWifiNetworkSuggestionBuilderForWapiCertAutoNetwork() {
-        WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
-        enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.WAPI_CERT);
-        WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
-                .setSsid(TEST_SSID)
-                .setWapiEnterpriseConfig(enterpriseConfig)
-                .build();
-
-        assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID);
-        assertTrue(suggestion.wifiConfiguration.allowedKeyManagement
-                .get(WifiConfiguration.KeyMgmt.WAPI_CERT));
-        assertTrue(suggestion.wifiConfiguration.allowedPairwiseCiphers
-                .get(WifiConfiguration.PairwiseCipher.SMS4));
-        assertTrue(suggestion.wifiConfiguration.allowedGroupCiphers
-                .get(WifiConfiguration.GroupCipher.SMS4));
-        assertNull(suggestion.wifiConfiguration.preSharedKey);
-        assertNotNull(suggestion.wifiConfiguration.enterpriseConfig);
-        assertEquals(WifiEnterpriseConfig.Eap.WAPI_CERT,
-                suggestion.wifiConfiguration.enterpriseConfig.getEapMethod());
-        assertEquals("",
-                suggestion.wifiConfiguration.enterpriseConfig.getWapiCertSuite());
-        assertNotNull(suggestion.getEnterpriseConfig());
-    }
-
-    /**
-     * Validate correctness of WifiNetworkSuggestion object created by
-     * {@link WifiNetworkSuggestion.Builder#build()} for Passpoint network which requires
-     *  app interaction and metered.
-     */
-    @Test
-    public void testWifiNetworkSuggestionBuilderForPasspointNetworkWithReqAppInteractionMetered() {
-        PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig();
-        WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
-                .setPasspointConfig(passpointConfiguration)
-                .setIsAppInteractionRequired(true)
-                .setIsMetered(true)
-                .build();
-        assertEquals(TEST_FQDN, suggestion.wifiConfiguration.FQDN);
-        assertTrue(suggestion.isAppInteractionRequired);
-        assertEquals(suggestion.wifiConfiguration.meteredOverride,
-                WifiConfiguration.METERED_OVERRIDE_METERED);
-        assertEquals(suggestion.getPasspointConfig().getMeteredOverride(),
-                WifiConfiguration.METERED_OVERRIDE_METERED);
-        assertTrue(suggestion.isUserAllowedToManuallyConnect);
-        assertNull(suggestion.getEnterpriseConfig());
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSuggestion.Builder#setSsid(String)} throws an exception
-     * when the string is not Unicode.
-     */
-    @Test(expected = IllegalArgumentException.class)
-    public void testWifiNetworkSuggestionBuilderSetSsidWithNonUnicodeString() {
-        new WifiNetworkSuggestion.Builder()
-                .setSsid("\ud800")
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSuggestion.Builder#setWpa2Passphrase(String)} throws an exception
-     * when the string is not ASCII encodable.
-     */
-    @Test(expected = IllegalArgumentException.class)
-    public void testWifiNetworkSuggestionBuilderSetWpa2PasphraseWithNonAsciiString() {
-        new WifiNetworkSuggestion.Builder()
-                .setSsid(TEST_SSID)
-                .setWpa2Passphrase("salvē")
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSuggestion.Builder#setPasspointConfig(PasspointConfiguration)}}
-     * throws an exception when the PasspointConfiguration is not valid.
-     */
-    @Test(expected = IllegalArgumentException.class)
-    public void testWifiNetworkSuggestionBuilderSetPasspointConfigWithNonValid() {
-        PasspointConfiguration passpointConfiguration = new PasspointConfiguration();
-        new WifiNetworkSuggestion.Builder()
-                .setPasspointConfig(passpointConfiguration)
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
-     * when {@link WifiNetworkSuggestion.Builder#setSsid(String)} is not set.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testWifiNetworkSuggestionBuilderWithNoSsid() {
-        new WifiNetworkSuggestion.Builder()
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
-     * when {@link WifiNetworkSuggestion.Builder#setSsid(String)} is invoked with an invalid value.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testWifiNetworkSuggestionBuilderWithInvalidSsid() {
-        new WifiNetworkSuggestion.Builder()
-                .setSsid("")
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
-     * when {@link WifiNetworkSuggestion.Builder#setBssid(MacAddress)} is invoked with an invalid
-     * value.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testWifiNetworkSuggestionBuilderWithInvalidBroadcastBssid() {
-        new WifiNetworkSuggestion.Builder()
-                .setSsid(TEST_SSID)
-                .setBssid(MacAddress.BROADCAST_ADDRESS)
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
-     * when {@link WifiNetworkSuggestion.Builder#setBssid(MacAddress)} is invoked with an invalid
-     * value.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testWifiNetworkSuggestionBuilderWithInvalidAllZeroBssid() {
-        new WifiNetworkSuggestion.Builder()
-                .setSsid(TEST_SSID)
-                .setBssid(WifiManager.ALL_ZEROS_MAC_ADDRESS)
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSuggestion.Builder#setPriority(int)} throws an exception
-     * when the value is negative.
-     */
-    @Test(expected = IllegalArgumentException.class)
-    public void testWifiNetworkSuggestionBuilderWithInvalidPriority() {
-        new WifiNetworkSuggestion.Builder()
-                .setSsid(TEST_SSID)
-                .setPriority(-2)
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
-     * when both {@link WifiNetworkSuggestion.Builder#setWpa2Passphrase(String)} and
-     * {@link WifiNetworkSuggestion.Builder#setWpa3Passphrase(String)} are invoked.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testWifiNetworkSuggestionBuilderWithBothWpa2PasphraseAndWpa3Passphrase() {
-        new WifiNetworkSuggestion.Builder()
-                .setSsid(TEST_SSID)
-                .setWpa2Passphrase(TEST_PRESHARED_KEY)
-                .setWpa3Passphrase(TEST_PRESHARED_KEY)
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
-     * when both {@link WifiNetworkSuggestion.Builder#setWpa3Passphrase(String)} and
-     * {@link WifiNetworkSuggestion.Builder#setWpa3EnterpriseConfig(WifiEnterpriseConfig)} are
-     * invoked.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testWifiNetworkSuggestionBuilderWithBothWpa3PasphraseAndEnterprise() {
-        new WifiNetworkSuggestion.Builder()
-                .setSsid(TEST_SSID)
-                .setWpa3Passphrase(TEST_PRESHARED_KEY)
-                .setWpa3EnterpriseConfig(new WifiEnterpriseConfig())
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
-     * when both {@link WifiNetworkSuggestion.Builder#setWpa3Passphrase(String)} and
-     * {@link WifiNetworkSuggestion.Builder#setIsEnhancedOpen(boolean)} are invoked.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testWifiNetworkSuggestionBuilderWithBothWpa3PasphraseAndEnhancedOpen() {
-        new WifiNetworkSuggestion.Builder()
-                .setSsid(TEST_SSID)
-                .setWpa3Passphrase(TEST_PRESHARED_KEY)
-                .setIsEnhancedOpen(true)
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
-     * when both {@link WifiNetworkSuggestion.Builder#setSsid(String)} and
-     * {@link WifiNetworkSuggestion.Builder#setPasspointConfig(PasspointConfiguration)} are invoked.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testWifiNetworkSuggestionBuilderWithBothSsidAndPasspointConfig() {
-        PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig();
-        new WifiNetworkSuggestion.Builder()
-                .setSsid(TEST_SSID)
-                .setPasspointConfig(passpointConfiguration)
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
-     * when both {@link WifiNetworkSuggestion.Builder#setWpa2Passphrase(String)} and
-     * {@link WifiNetworkSuggestion.Builder#setPasspointConfig(PasspointConfiguration)} are invoked.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testWifiNetworkSuggestionBuilderWithBothWpa2PassphraseAndPasspointConfig() {
-        PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig();
-        new WifiNetworkSuggestion.Builder()
-                .setWpa2Passphrase(TEST_PRESHARED_KEY)
-                .setPasspointConfig(passpointConfiguration)
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
-     * when both {@link WifiNetworkSuggestion.Builder#setWpa3Passphrase(String)} and
-     * {@link WifiNetworkSuggestion.Builder#setPasspointConfig(PasspointConfiguration)} are invoked.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testWifiNetworkSuggestionBuilderWithBothWpa3PassphraseAndPasspointConfig() {
-        PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig();
-        new WifiNetworkSuggestion.Builder()
-                .setWpa3Passphrase(TEST_PRESHARED_KEY)
-                .setPasspointConfig(passpointConfiguration)
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
-     * when both {@link WifiNetworkSuggestion.Builder#setWpa3EnterpriseConfig(WifiEnterpriseConfig)}
-     * and {@link WifiNetworkSuggestion.Builder#setPasspointConfig(PasspointConfiguration)} are
-     * invoked.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testWifiNetworkSuggestionBuilderWithBothEnterpriseAndPasspointConfig() {
-        PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig();
-        new WifiNetworkSuggestion.Builder()
-                .setWpa3EnterpriseConfig(new WifiEnterpriseConfig())
-                .setPasspointConfig(passpointConfiguration)
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
-     * when both {@link WifiNetworkSuggestion.Builder#setIsEnhancedOpen(boolean)} and
-     * {@link WifiNetworkSuggestion.Builder#setPasspointConfig(PasspointConfiguration)} are invoked.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testWifiNetworkSuggestionBuilderWithBothEnhancedOpenAndPasspointConfig() {
-        PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig();
-        new WifiNetworkSuggestion.Builder()
-                .setIsEnhancedOpen(true)
-                .setPasspointConfig(passpointConfiguration)
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
-     * when both {@link WifiNetworkSuggestion.Builder#setIsHiddenSsid(boolean)} and
-     * {@link WifiNetworkSuggestion.Builder#setPasspointConfig(PasspointConfiguration)} are invoked.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testWifiNetworkSuggestionBuilderWithBothHiddenSsidAndPasspointConfig() {
-        PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig();
-        new WifiNetworkSuggestion.Builder()
-                .setIsHiddenSsid(true)
-                .setPasspointConfig(passpointConfiguration)
-                .build();
-    }
-
-    /**
-     * Check that parcel marshalling/unmarshalling works
-     */
-    @Test
-    public void testWifiNetworkSuggestionParcel() {
-        WifiConfiguration configuration = new WifiConfiguration();
-        configuration.SSID = TEST_SSID;
-        configuration.BSSID = TEST_BSSID;
-        configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
-        WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion(
-                configuration, null, false, true, true, true);
-
-        Parcel parcelW = Parcel.obtain();
-        suggestion.writeToParcel(parcelW, 0);
-        byte[] bytes = parcelW.marshall();
-        parcelW.recycle();
-
-        Parcel parcelR = Parcel.obtain();
-        parcelR.unmarshall(bytes, 0, bytes.length);
-        parcelR.setDataPosition(0);
-        WifiNetworkSuggestion parcelSuggestion =
-                WifiNetworkSuggestion.CREATOR.createFromParcel(parcelR);
-
-        // Two suggestion objects are considered equal if they point to the same network (i.e same
-        // SSID + keyMgmt + same UID). |isAppInteractionRequired| & |isUserInteractionRequired| are
-        // not considered for equality and hence needs to be checked for explicitly below.
-        assertEquals(suggestion, parcelSuggestion);
-        assertEquals(suggestion.hashCode(), parcelSuggestion.hashCode());
-        assertEquals(suggestion.isAppInteractionRequired,
-                parcelSuggestion.isAppInteractionRequired);
-        assertEquals(suggestion.isUserInteractionRequired,
-                parcelSuggestion.isUserInteractionRequired);
-        assertEquals(suggestion.isInitialAutoJoinEnabled,
-                parcelSuggestion.isInitialAutoJoinEnabled);
-    }
-
-    /**
-     * Check that parcel marshalling/unmarshalling works
-     */
-    @Test
-    public void testPasspointNetworkSuggestionParcel() {
-        PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig();
-        WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
-                .setPasspointConfig(passpointConfiguration)
-                .build();
-
-        Parcel parcelW = Parcel.obtain();
-        suggestion.writeToParcel(parcelW, 0);
-        byte[] bytes = parcelW.marshall();
-        parcelW.recycle();
-
-        Parcel parcelR = Parcel.obtain();
-        parcelR.unmarshall(bytes, 0, bytes.length);
-        parcelR.setDataPosition(0);
-        WifiNetworkSuggestion parcelSuggestion =
-                WifiNetworkSuggestion.CREATOR.createFromParcel(parcelR);
-
-        // Two suggestion objects are considered equal if they point to the same network (i.e same
-        // SSID + keyMgmt + same UID). |isAppInteractionRequired| & |isUserInteractionRequired| are
-        // not considered for equality and hence needs to be checked for explicitly below.
-        assertEquals(suggestion, parcelSuggestion);
-        assertEquals(suggestion.hashCode(), parcelSuggestion.hashCode());
-        assertEquals(suggestion.isAppInteractionRequired,
-                parcelSuggestion.isAppInteractionRequired);
-        assertEquals(suggestion.isUserInteractionRequired,
-                parcelSuggestion.isUserInteractionRequired);
-        assertEquals(suggestion.isInitialAutoJoinEnabled,
-                parcelSuggestion.isInitialAutoJoinEnabled);
-    }
-
-    /**
-     * Check NetworkSuggestion equals returns {@code true} for 2 network suggestions with the same
-     * SSID, BSSID, key mgmt and UID.
-     */
-    @Test
-    public void testWifiNetworkSuggestionEqualsSame() {
-        WifiConfiguration configuration = new WifiConfiguration();
-        configuration.SSID = TEST_SSID;
-        configuration.BSSID = TEST_BSSID;
-        configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
-        WifiNetworkSuggestion suggestion =
-                new WifiNetworkSuggestion(configuration, null, true, false, true, true);
-
-        WifiConfiguration configuration1 = new WifiConfiguration();
-        configuration1.SSID = TEST_SSID;
-        configuration1.BSSID = TEST_BSSID;
-        configuration1.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
-        WifiNetworkSuggestion suggestion1 =
-                new WifiNetworkSuggestion(configuration1, null, false, true, true, true);
-
-        assertEquals(suggestion, suggestion1);
-        assertEquals(suggestion.hashCode(), suggestion1.hashCode());
-    }
-
-    /**
-     * Check NetworkSuggestion equals returns {@code false} for 2 network suggestions with the same
-     * BSSID, key mgmt and UID, but different SSID.
-     */
-    @Test
-    public void testWifiNetworkSuggestionEqualsFailsWhenSsidIsDifferent() {
-        WifiConfiguration configuration = new WifiConfiguration();
-        configuration.SSID = TEST_SSID;
-        configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
-        WifiNetworkSuggestion suggestion =
-                new WifiNetworkSuggestion(configuration, null, false, false, true, true);
-
-        WifiConfiguration configuration1 = new WifiConfiguration();
-        configuration1.SSID = TEST_SSID_1;
-        configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
-        WifiNetworkSuggestion suggestion1 =
-                new WifiNetworkSuggestion(configuration1, null, false, false, true, true);
-
-        assertNotEquals(suggestion, suggestion1);
-    }
-
-    /**
-     * Check NetworkSuggestion equals returns {@code false} for 2 network suggestions with the same
-     * SSID, key mgmt and UID, but different BSSID.
-     */
-    @Test
-    public void testWifiNetworkSuggestionEqualsFailsWhenBssidIsDifferent() {
-        WifiConfiguration configuration = new WifiConfiguration();
-        configuration.SSID = TEST_SSID;
-        configuration.BSSID = TEST_BSSID;
-        configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
-        WifiNetworkSuggestion suggestion =
-                new WifiNetworkSuggestion(configuration, null,  false, false, true, true);
-
-        WifiConfiguration configuration1 = new WifiConfiguration();
-        configuration1.SSID = TEST_SSID;
-        configuration1.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
-        WifiNetworkSuggestion suggestion1 =
-                new WifiNetworkSuggestion(configuration1, null, false, false, true, true);
-
-        assertNotEquals(suggestion, suggestion1);
-    }
-
-    /**
-     * Check NetworkSuggestion equals returns {@code false} for 2 network suggestions with the same
-     * SSID, BSSID and UID, but different key mgmt.
-     */
-    @Test
-    public void testWifiNetworkSuggestionEqualsFailsWhenKeyMgmtIsDifferent() {
-        WifiConfiguration configuration = new WifiConfiguration();
-        configuration.SSID = TEST_SSID;
-        configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
-        WifiNetworkSuggestion suggestion =
-                new WifiNetworkSuggestion(configuration, null, false, false, true, true);
-
-        WifiConfiguration configuration1 = new WifiConfiguration();
-        configuration1.SSID = TEST_SSID;
-        configuration1.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
-        WifiNetworkSuggestion suggestion1 =
-                new WifiNetworkSuggestion(configuration1, null, false, false, true, true);
-
-        assertNotEquals(suggestion, suggestion1);
-    }
-
-    /**
-     * Check NetworkSuggestion equals returns {@code true} for 2 Passpoint network suggestions with
-     * same FQDN.
-     */
-    @Test
-    public void testPasspointNetworkSuggestionEqualsSameWithSameFQDN() {
-        PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig();
-        PasspointConfiguration passpointConfiguration1 = PasspointTestUtils.createConfig();
-        WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
-                .setPasspointConfig(passpointConfiguration)
-                .build();
-        WifiNetworkSuggestion suggestion1 = new WifiNetworkSuggestion.Builder()
-                .setPasspointConfig(passpointConfiguration1)
-                .build();
-        assertEquals(suggestion, suggestion1);
-        assertEquals(suggestion.hashCode(), suggestion1.hashCode());
-    }
-
-    /**
-     * Check NetworkSuggestion equals returns {@code false} for 2 Passpoint network suggestions with
-     * different FQDN.
-     */
-    @Test
-    public void testPasspointNetworkSuggestionNotEqualsSameWithDifferentFQDN() {
-        PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig();
-        PasspointConfiguration passpointConfiguration1 = PasspointTestUtils.createConfig();
-        passpointConfiguration1.getHomeSp().setFqdn(TEST_FQDN + 1);
-
-        WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
-                .setPasspointConfig(passpointConfiguration)
-                .build();
-        WifiNetworkSuggestion suggestion1 = new WifiNetworkSuggestion.Builder()
-                .setPasspointConfig(passpointConfiguration1)
-                .build();
-        assertNotEquals(suggestion, suggestion1);
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
-     * when {@link WifiNetworkSuggestion.Builder#setCredentialSharedWithUser(boolean)} to
-     * true on a open network suggestion.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testSetCredentialSharedWithUserWithOpenNetwork() {
-        WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
-                .setSsid(TEST_SSID)
-                .setCredentialSharedWithUser(true)
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
-     * when {@link WifiNetworkSuggestion.Builder#setIsInitialAutojoinEnabled(boolean)} to
-     * false on a open network suggestion.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testSetIsAutoJoinDisabledWithOpenNetwork() {
-        new WifiNetworkSuggestion.Builder()
-                .setSsid(TEST_SSID)
-                .setIsInitialAutojoinEnabled(false)
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
-     * when set both {@link WifiNetworkSuggestion.Builder#setIsInitialAutojoinEnabled(boolean)}
-     * and {@link WifiNetworkSuggestion.Builder#setCredentialSharedWithUser(boolean)} (boolean)}
-     * to false on a network suggestion.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testSetIsAutoJoinDisabledWithSecureNetworkNotSharedWithUser() {
-        new WifiNetworkSuggestion.Builder()
-                .setSsid(TEST_SSID)
-                .setWpa2Passphrase(TEST_PRESHARED_KEY)
-                .setCredentialSharedWithUser(false)
-                .setIsInitialAutojoinEnabled(false)
-                .build();
-    }
-
-    /**
-     * Validate {@link WifiNetworkSuggestion.Builder#setCredentialSharedWithUser(boolean)} set the
-     * correct value to the WifiConfiguration.
-     */
-    @Test
-    public void testSetIsNetworkAsUntrusted() {
-        WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
-                .setSsid(TEST_SSID)
-                .setWpa2Passphrase(TEST_PRESHARED_KEY)
-                .setUntrusted(true)
-                .build();
-        assertTrue(suggestion.isUntrusted());
-        assertFalse(suggestion.isUserAllowedToManuallyConnect);
-    }
-
-    /**
-     * Validate {@link WifiNetworkSuggestion.Builder#setCredentialSharedWithUser(boolean)} set the
-     * correct value to the WifiConfiguration.
-     * Also the {@link WifiNetworkSuggestion#isUserAllowedToManuallyConnect} should be false;
-     */
-    @Test
-    public void testSetIsNetworkAsUntrustedOnPasspointNetwork() {
-        PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig();
-        WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
-                .setPasspointConfig(passpointConfiguration)
-                .setUntrusted(true)
-                .build();
-        assertTrue(suggestion.isUntrusted());
-        assertFalse(suggestion.isUserAllowedToManuallyConnect);
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
-     * when set {@link WifiNetworkSuggestion.Builder#setUntrusted(boolean)} to true and
-     * set {@link WifiNetworkSuggestion.Builder#setCredentialSharedWithUser(boolean)} to true
-     * together.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testSetCredentialSharedWithUserWithSetIsNetworkAsUntrusted() {
-        new WifiNetworkSuggestion.Builder()
-                .setSsid(TEST_SSID)
-                .setWpa2Passphrase(TEST_PRESHARED_KEY)
-                .setCredentialSharedWithUser(true)
-                .setUntrusted(true)
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
-     * when set both {@link WifiNetworkSuggestion.Builder#setIsInitialAutojoinEnabled(boolean)}
-     * and {@link WifiNetworkSuggestion.Builder#setCredentialSharedWithUser(boolean)} (boolean)}
-     * to false on a passpoint suggestion.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testSetIsAutoJoinDisabledWithSecureNetworkNotSharedWithUserForPasspoint() {
-        PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig();
-        new WifiNetworkSuggestion.Builder()
-                .setPasspointConfig(passpointConfiguration)
-                .setCredentialSharedWithUser(false)
-                .setIsInitialAutojoinEnabled(false)
-                .build();
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/WifiScannerTest.java b/wifi/tests/src/android/net/wifi/WifiScannerTest.java
deleted file mode 100644
index b68616f..0000000
--- a/wifi/tests/src/android/net/wifi/WifiScannerTest.java
+++ /dev/null
@@ -1,634 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.validateMockitoUsage;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.net.wifi.WifiScanner.PnoSettings;
-import android.net.wifi.WifiScanner.PnoSettings.PnoNetwork;
-import android.net.wifi.WifiScanner.ScanData;
-import android.net.wifi.WifiScanner.ScanListener;
-import android.net.wifi.WifiScanner.ScanSettings;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.Parcel;
-import android.os.test.TestLooper;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.internal.util.test.BidirectionalAsyncChannelServer;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.mockito.Spy;
-
-import java.util.Arrays;
-import java.util.concurrent.Executor;
-
-/**
- * Unit tests for {@link android.net.wifi.WifiScanner}.
- */
-@SmallTest
-public class WifiScannerTest {
-    @Mock
-    private Context mContext;
-    @Mock
-    private IWifiScanner mService;
-    @Spy
-    private Executor mExecutor = new SynchronousExecutor();
-    @Mock
-    private ScanListener mScanListener;
-    @Mock
-    private WifiScanner.ParcelableScanData mParcelableScanData;
-    private ScanData[] mScanData = {};
-
-    private static final boolean TEST_PNOSETTINGS_IS_CONNECTED = false;
-    private static final int TEST_PNOSETTINGS_MIN_5GHZ_RSSI = -60;
-    private static final int TEST_PNOSETTINGS_MIN_2GHZ_RSSI = -70;
-    private static final int TEST_PNOSETTINGS_MIN_6GHZ_RSSI = -55;
-    private static final String TEST_SSID_1 = "TEST1";
-    private static final String TEST_SSID_2 = "TEST2";
-    private static final int[] TEST_FREQUENCIES_1 = {};
-    private static final int[] TEST_FREQUENCIES_2 = {2500, 5124, 6245};
-    private static final String DESCRIPTION_NOT_AUTHORIZED = "Not authorized";
-
-    private WifiScanner mWifiScanner;
-    private TestLooper mLooper;
-    private Handler mHandler;
-    private BidirectionalAsyncChannelServer mBidirectionalAsyncChannelServer;
-
-    /**
-     * Setup before tests.
-     */
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-        mLooper = new TestLooper();
-        mHandler = spy(new Handler(mLooper.getLooper()));
-        mBidirectionalAsyncChannelServer = new BidirectionalAsyncChannelServer(
-                mContext, mLooper.getLooper(), mHandler);
-        when(mService.getMessenger()).thenReturn(mBidirectionalAsyncChannelServer.getMessenger());
-        mWifiScanner = new WifiScanner(mContext, mService, mLooper.getLooper());
-        mLooper.dispatchAll();
-        when(mParcelableScanData.getResults()).thenReturn(mScanData);
-    }
-
-    /**
-     * Clean up after tests.
-     */
-    @After
-    public void cleanup() {
-        validateMockitoUsage();
-    }
-
-    /**
-     * Verify parcel read/write for ScanSettings.
-     */
-    @Test
-    public void verifyScanSettingsParcelWithBand() throws Exception {
-        ScanSettings writeSettings = new ScanSettings();
-        writeSettings.type = WifiScanner.SCAN_TYPE_LOW_POWER;
-        writeSettings.band = WifiScanner.WIFI_BAND_BOTH_WITH_DFS;
-
-        ScanSettings readSettings = parcelWriteRead(writeSettings);
-        assertEquals(readSettings.type, writeSettings.type);
-        assertEquals(readSettings.band, writeSettings.band);
-        assertEquals(0, readSettings.channels.length);
-    }
-
-    /**
-     * Verify parcel read/write for ScanSettings.
-     */
-    @Test
-    public void verifyScanSettingsParcelWithChannels() throws Exception {
-        ScanSettings writeSettings = new ScanSettings();
-        writeSettings.type = WifiScanner.SCAN_TYPE_HIGH_ACCURACY;
-        writeSettings.band = WifiScanner.WIFI_BAND_UNSPECIFIED;
-        writeSettings.channels = new WifiScanner.ChannelSpec[] {
-                new WifiScanner.ChannelSpec(5),
-                new WifiScanner.ChannelSpec(7)
-        };
-
-        ScanSettings readSettings = parcelWriteRead(writeSettings);
-        assertEquals(writeSettings.type, readSettings.type);
-        assertEquals(writeSettings.band, readSettings.band);
-        assertEquals(2, readSettings.channels.length);
-        assertEquals(5, readSettings.channels[0].frequency);
-        assertEquals(7, readSettings.channels[1].frequency);
-    }
-
-    /**
-     * Write the provided {@link ScanSettings} to a parcel and deserialize it.
-     */
-    private static ScanSettings parcelWriteRead(ScanSettings writeSettings) throws Exception {
-        Parcel parcel = Parcel.obtain();
-        writeSettings.writeToParcel(parcel, 0);
-        parcel.setDataPosition(0);    // Rewind data position back to the beginning for read.
-        return ScanSettings.CREATOR.createFromParcel(parcel);
-    }
-
-    /**
-     *  PnoSettings object can be serialized and deserialized, while keeping the
-     *  values unchanged.
-     */
-    @Test
-    public void canSerializeAndDeserializePnoSettings() throws Exception {
-
-        PnoSettings pnoSettings = new PnoSettings();
-
-        PnoNetwork pnoNetwork1 = new PnoNetwork(TEST_SSID_1);
-        PnoNetwork pnoNetwork2 = new PnoNetwork(TEST_SSID_2);
-        pnoNetwork1.frequencies = TEST_FREQUENCIES_1;
-        pnoNetwork2.frequencies = TEST_FREQUENCIES_2;
-
-        pnoSettings.networkList = new PnoNetwork[]{pnoNetwork1, pnoNetwork2};
-        pnoSettings.isConnected = TEST_PNOSETTINGS_IS_CONNECTED;
-        pnoSettings.min5GHzRssi = TEST_PNOSETTINGS_MIN_5GHZ_RSSI;
-        pnoSettings.min24GHzRssi = TEST_PNOSETTINGS_MIN_2GHZ_RSSI;
-        pnoSettings.min6GHzRssi = TEST_PNOSETTINGS_MIN_6GHZ_RSSI;
-
-        Parcel parcel = Parcel.obtain();
-        pnoSettings.writeToParcel(parcel, 0);
-        // Rewind the pointer to the head of the parcel.
-        parcel.setDataPosition(0);
-        PnoSettings pnoSettingsDeserialized =
-                pnoSettings.CREATOR.createFromParcel(parcel);
-
-        assertNotNull(pnoSettingsDeserialized);
-        assertEquals(TEST_PNOSETTINGS_IS_CONNECTED, pnoSettingsDeserialized.isConnected);
-        assertEquals(TEST_PNOSETTINGS_MIN_5GHZ_RSSI, pnoSettingsDeserialized.min5GHzRssi);
-        assertEquals(TEST_PNOSETTINGS_MIN_2GHZ_RSSI, pnoSettingsDeserialized.min24GHzRssi);
-        assertEquals(TEST_PNOSETTINGS_MIN_6GHZ_RSSI, pnoSettingsDeserialized.min6GHzRssi);
-
-        // Test parsing of PnoNetwork
-        assertEquals(pnoSettings.networkList.length, pnoSettingsDeserialized.networkList.length);
-        for (int i = 0; i < pnoSettings.networkList.length; i++) {
-            PnoNetwork expected = pnoSettings.networkList[i];
-            PnoNetwork actual = pnoSettingsDeserialized.networkList[i];
-            assertEquals(expected.ssid, actual.ssid);
-            assertEquals(expected.flags, actual.flags);
-            assertEquals(expected.authBitField, actual.authBitField);
-            assertTrue(Arrays.equals(expected.frequencies, actual.frequencies));
-        }
-    }
-
-    /**
-     *  Make sure that frequencies is not null by default.
-     */
-    @Test
-    public void pnoNetworkFrequencyIsNotNull() throws Exception {
-        PnoNetwork pnoNetwork = new PnoNetwork(TEST_SSID_1);
-        assertNotNull(pnoNetwork.frequencies);
-    }
-
-    /**
-     * Verify parcel read/write for ScanData.
-     */
-    @Test
-    public void verifyScanDataParcel() throws Exception {
-        ScanData writeScanData = new ScanData(2, 0, 3,
-                WifiScanner.WIFI_BAND_BOTH_WITH_DFS, new ScanResult[0]);
-
-        ScanData readScanData = parcelWriteRead(writeScanData);
-        assertEquals(writeScanData.getId(), readScanData.getId());
-        assertEquals(writeScanData.getFlags(), readScanData.getFlags());
-        assertEquals(writeScanData.getBucketsScanned(), readScanData.getBucketsScanned());
-        assertEquals(writeScanData.getBandScanned(), readScanData.getBandScanned());
-        assertArrayEquals(writeScanData.getResults(), readScanData.getResults());
-    }
-
-    /**
-     * Write the provided {@link ScanData} to a parcel and deserialize it.
-     */
-    private static ScanData parcelWriteRead(ScanData writeScanData) throws Exception {
-        Parcel parcel = Parcel.obtain();
-        writeScanData.writeToParcel(parcel, 0);
-        parcel.setDataPosition(0);    // Rewind data position back to the beginning for read.
-        return ScanData.CREATOR.createFromParcel(parcel);
-    }
-
-
-    /**
-     * Test behavior of {@link WifiScanner#startScan(ScanSettings, ScanListener)}
-     * @throws Exception
-     */
-    @Test
-    public void testStartScan() throws Exception {
-        ScanSettings scanSettings = new ScanSettings();
-        ScanListener scanListener = mock(ScanListener.class);
-
-        mWifiScanner.startScan(scanSettings, scanListener);
-        mLooper.dispatchAll();
-
-        ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
-        verify(mHandler).handleMessage(messageArgumentCaptor.capture());
-        Message message = messageArgumentCaptor.getValue();
-        assertNotNull(message);
-
-        assertEquals(WifiScanner.CMD_START_SINGLE_SCAN, message.what);
-        assertTrue(message.obj instanceof Bundle);
-        Bundle messageBundle = (Bundle) message.obj;
-        assertEquals(scanSettings,
-                messageBundle.getParcelable(WifiScanner.SCAN_PARAMS_SCAN_SETTINGS_KEY));
-        assertNull(messageBundle.getParcelable(WifiScanner.SCAN_PARAMS_WORK_SOURCE_KEY));
-        assertEquals(mContext.getOpPackageName(),
-                messageBundle.getParcelable(WifiScanner.REQUEST_PACKAGE_NAME_KEY));
-        assertEquals(mContext.getAttributionTag(),
-                messageBundle.getParcelable(WifiScanner.REQUEST_FEATURE_ID_KEY));
-
-    }
-
-    /**
-     * Test behavior of {@link WifiScanner#stopScan(ScanListener)}
-     * @throws Exception
-     */
-    @Test
-    public void testStopScan() throws Exception {
-        ScanSettings scanSettings = new ScanSettings();
-        ScanListener scanListener = mock(ScanListener.class);
-
-        mWifiScanner.startScan(scanSettings, scanListener);
-        mLooper.dispatchAll();
-
-        mWifiScanner.stopScan(scanListener);
-        mLooper.dispatchAll();
-
-        ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
-        verify(mHandler, times(2)).handleMessage(messageArgumentCaptor.capture());
-        Message message = messageArgumentCaptor.getValue();
-        assertNotNull(message);
-
-        assertEquals(WifiScanner.CMD_STOP_SINGLE_SCAN, message.what);
-        assertTrue(message.obj instanceof Bundle);
-        Bundle messageBundle = (Bundle) message.obj;
-        assertEquals(mContext.getOpPackageName(),
-                messageBundle.getParcelable(WifiScanner.REQUEST_PACKAGE_NAME_KEY));
-        assertEquals(mContext.getAttributionTag(),
-                messageBundle.getParcelable(WifiScanner.REQUEST_FEATURE_ID_KEY));
-    }
-
-    /**
-     * Test behavior of {@link WifiScanner#startScan(ScanSettings, ScanListener)}
-     * @throws Exception
-     */
-    @Test
-    public void testStartScanListenerOnSuccess() throws Exception {
-        ScanSettings scanSettings = new ScanSettings();
-        ScanListener scanListener = mock(ScanListener.class);
-
-        mWifiScanner.startScan(scanSettings, scanListener);
-        mLooper.dispatchAll();
-
-        ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
-        verify(mHandler).handleMessage(messageArgumentCaptor.capture());
-        Message sentMessage = messageArgumentCaptor.getValue();
-        assertNotNull(sentMessage);
-
-        assertEquals(1, mBidirectionalAsyncChannelServer.getClientMessengers().size());
-        Messenger scannerMessenger =
-                mBidirectionalAsyncChannelServer.getClientMessengers().iterator().next();
-
-        Message responseMessage = Message.obtain();
-        responseMessage.what = WifiScanner.CMD_OP_SUCCEEDED;
-        responseMessage.arg2 = sentMessage.arg2;
-        scannerMessenger.send(responseMessage);
-        mLooper.dispatchAll();
-
-        verify(scanListener).onSuccess();
-    }
-
-    /**
-     * Test behavior of {@link WifiScanner#startScan(ScanSettings, ScanListener)}
-     * @throws Exception
-     */
-    @Test
-    public void testStartScanListenerOnResults() throws Exception {
-        ScanSettings scanSettings = new ScanSettings();
-        ScanListener scanListener = mock(ScanListener.class);
-
-        mWifiScanner.startScan(scanSettings, scanListener);
-        mLooper.dispatchAll();
-
-        ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
-        verify(mHandler).handleMessage(messageArgumentCaptor.capture());
-        Message sentMessage = messageArgumentCaptor.getValue();
-        assertNotNull(sentMessage);
-
-        assertEquals(1, mBidirectionalAsyncChannelServer.getClientMessengers().size());
-        Messenger scannerMessenger =
-                mBidirectionalAsyncChannelServer.getClientMessengers().iterator().next();
-
-        ScanResult scanResult = new ScanResult();
-        ScanData scanDatas[] = new ScanData[]{new ScanData(0, 0 , new ScanResult[] {scanResult})};
-        Message responseMessage = Message.obtain();
-        responseMessage.what = WifiScanner.CMD_SCAN_RESULT;
-        responseMessage.arg2 = sentMessage.arg2;
-        responseMessage.obj = new WifiScanner.ParcelableScanData(scanDatas);
-        scannerMessenger.send(responseMessage);
-        mLooper.dispatchAll();
-
-        verify(scanListener).onResults(scanDatas);
-    }
-
-    /**
-     * Test behavior of {@link WifiScanner#startDisconnectedPnoScan(ScanSettings, PnoSettings,
-     * Executor, WifiScanner.PnoScanListener)}
-     * @throws Exception
-     */
-    @Test
-    public void testStartDisconnectedPnoScan() throws Exception {
-        ScanSettings scanSettings = new ScanSettings();
-        PnoSettings pnoSettings = new PnoSettings();
-        WifiScanner.PnoScanListener pnoScanListener = mock(WifiScanner.PnoScanListener.class);
-
-        mWifiScanner.startDisconnectedPnoScan(
-                scanSettings, pnoSettings, mock(Executor.class), pnoScanListener);
-        mLooper.dispatchAll();
-
-        ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
-        verify(mHandler).handleMessage(messageArgumentCaptor.capture());
-        Message message = messageArgumentCaptor.getValue();
-        assertNotNull(message);
-
-        assertEquals(WifiScanner.CMD_START_PNO_SCAN, message.what);
-        assertTrue(message.obj instanceof Bundle);
-        Bundle messageBundle = (Bundle) message.obj;
-        assertEquals(scanSettings,
-                messageBundle.getParcelable(WifiScanner.PNO_PARAMS_SCAN_SETTINGS_KEY));
-        assertTrue(scanSettings.isPnoScan);
-        assertFalse(pnoSettings.isConnected);
-        assertEquals(pnoSettings,
-                messageBundle.getParcelable(WifiScanner.PNO_PARAMS_PNO_SETTINGS_KEY));
-    }
-
-    /**
-     * Test behavior of {@link WifiScanner#startConnectedPnoScan(ScanSettings, PnoSettings,
-     * Executor, WifiScanner.PnoScanListener)}
-     * @throws Exception
-     */
-    @Test
-    public void testStartConnectedPnoScan() throws Exception {
-        ScanSettings scanSettings = new ScanSettings();
-        PnoSettings pnoSettings = new PnoSettings();
-        WifiScanner.PnoScanListener pnoScanListener = mock(WifiScanner.PnoScanListener.class);
-
-        mWifiScanner.startConnectedPnoScan(
-                scanSettings, pnoSettings, mock(Executor.class), pnoScanListener);
-        mLooper.dispatchAll();
-
-        ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
-        verify(mHandler).handleMessage(messageArgumentCaptor.capture());
-        Message message = messageArgumentCaptor.getValue();
-        assertNotNull(message);
-
-        assertEquals(WifiScanner.CMD_START_PNO_SCAN, message.what);
-        assertTrue(message.obj instanceof Bundle);
-        Bundle messageBundle = (Bundle) message.obj;
-        assertEquals(scanSettings,
-                messageBundle.getParcelable(WifiScanner.PNO_PARAMS_SCAN_SETTINGS_KEY));
-        assertTrue(scanSettings.isPnoScan);
-        assertTrue(pnoSettings.isConnected);
-        assertEquals(pnoSettings,
-                messageBundle.getParcelable(WifiScanner.PNO_PARAMS_PNO_SETTINGS_KEY));
-    }
-
-    /**
-     * Test behavior of {@link WifiScanner#stopPnoScan(ScanListener)}
-     * Executor, WifiScanner.PnoScanListener)}
-     * @throws Exception
-     */
-    @Test
-    public void testStopPnoScan() throws Exception {
-        ScanSettings scanSettings = new ScanSettings();
-        PnoSettings pnoSettings = new PnoSettings();
-        WifiScanner.PnoScanListener pnoScanListener = mock(WifiScanner.PnoScanListener.class);
-
-        mWifiScanner.startDisconnectedPnoScan(
-                scanSettings, pnoSettings, mock(Executor.class), pnoScanListener);
-        mLooper.dispatchAll();
-        mWifiScanner.stopPnoScan(pnoScanListener);
-        mLooper.dispatchAll();
-
-        ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
-        verify(mHandler, times(2)).handleMessage(messageArgumentCaptor.capture());
-        Message message = messageArgumentCaptor.getValue();
-        assertNotNull(message);
-
-        assertEquals(WifiScanner.CMD_STOP_PNO_SCAN, message.what);
-    }
-
-    @Test
-    public void testScanDataAddResults() throws Exception {
-        ScanResult scanResult1 = new ScanResult();
-        scanResult1.SSID = TEST_SSID_1;
-        ScanData scanData = new ScanData(0, 0, new ScanResult[]{scanResult1});
-
-        ScanResult scanResult2 = new ScanResult();
-        scanResult2.SSID = TEST_SSID_2;
-        scanData.addResults(new ScanResult[]{scanResult2});
-
-        ScanResult[] consolidatedScanResults = scanData.getResults();
-        assertEquals(2, consolidatedScanResults.length);
-        assertEquals(TEST_SSID_1, consolidatedScanResults[0].SSID);
-        assertEquals(TEST_SSID_2, consolidatedScanResults[1].SSID);
-    }
-
-    @Test
-    public void testScanDataParcel() throws Exception {
-        ScanResult scanResult1 = new ScanResult();
-        scanResult1.SSID = TEST_SSID_1;
-        ScanData scanData = new ScanData(5, 4, new ScanResult[]{scanResult1});
-
-        Parcel parcel = Parcel.obtain();
-        scanData.writeToParcel(parcel, 0);
-        parcel.setDataPosition(0);    // Rewind data position back to the beginning for read.
-        ScanData readScanData = ScanData.CREATOR.createFromParcel(parcel);
-
-        assertEquals(scanData.getId(), readScanData.getId());
-        assertEquals(scanData.getFlags(), readScanData.getFlags());
-        assertEquals(scanData.getResults().length, readScanData.getResults().length);
-        assertEquals(scanData.getResults()[0].SSID, readScanData.getResults()[0].SSID);
-    }
-
-    /** Tests that upon registration success, {@link ScanListener#onSuccess()} is called. */
-    @Test
-    public void testRegisterScanListenerSuccess() throws Exception {
-        mWifiScanner.registerScanListener(mExecutor, mScanListener);
-        mLooper.dispatchAll();
-
-        ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
-        verify(mHandler).handleMessage(messageArgumentCaptor.capture());
-        Message sentMessage = messageArgumentCaptor.getValue();
-        assertNotNull(sentMessage);
-
-        assertEquals(1, mBidirectionalAsyncChannelServer.getClientMessengers().size());
-        Messenger scannerMessenger =
-                mBidirectionalAsyncChannelServer.getClientMessengers().iterator().next();
-
-        Message responseMessage = Message.obtain();
-        responseMessage.what = WifiScanner.CMD_OP_SUCCEEDED;
-        responseMessage.arg2 = sentMessage.arg2;
-        scannerMessenger.send(responseMessage);
-        mLooper.dispatchAll();
-
-        verify(mExecutor).execute(any());
-        verify(mScanListener).onSuccess();
-    }
-
-    /**
-     * Tests that upon registration failed, {@link ScanListener#onFailure(int, String)} is called.
-     */
-    @Test
-    public void testRegisterScanListenerFailed() throws Exception {
-        mWifiScanner.registerScanListener(mExecutor, mScanListener);
-        mLooper.dispatchAll();
-
-        ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
-        verify(mHandler).handleMessage(messageArgumentCaptor.capture());
-        Message sentMessage = messageArgumentCaptor.getValue();
-        assertNotNull(sentMessage);
-
-        assertEquals(1, mBidirectionalAsyncChannelServer.getClientMessengers().size());
-        Messenger scannerMessenger =
-                mBidirectionalAsyncChannelServer.getClientMessengers().iterator().next();
-
-        {
-            Message responseMessage = Message.obtain();
-            responseMessage.what = WifiScanner.CMD_OP_FAILED;
-            responseMessage.arg2 = sentMessage.arg2;
-            responseMessage.obj = new WifiScanner.OperationResult(
-                    WifiScanner.REASON_NOT_AUTHORIZED, DESCRIPTION_NOT_AUTHORIZED);
-            scannerMessenger.send(responseMessage);
-            mLooper.dispatchAll();
-        }
-
-        verify(mExecutor).execute(any());
-        verify(mScanListener).onFailure(
-                WifiScanner.REASON_NOT_AUTHORIZED, DESCRIPTION_NOT_AUTHORIZED);
-
-        // CMD_OP_FAILED should have caused the removal of the listener, verify this
-        {
-            Message responseMessage = Message.obtain();
-            responseMessage.what = WifiScanner.CMD_SCAN_RESULT;
-            responseMessage.arg2 = sentMessage.arg2;
-            responseMessage.obj = mParcelableScanData;
-            scannerMessenger.send(responseMessage);
-            mLooper.dispatchAll();
-        }
-        // execute() called once before, not called again
-        verify(mExecutor, times(1)).execute(any());
-        // onResults() never triggered
-        verify(mScanListener, never()).onResults(any());
-    }
-
-    /**
-     * Tests that when the ScanListener is triggered, {@link ScanListener#onResults(ScanData[])}
-     * is called.
-     */
-    @Test
-    public void testRegisterScanListenerReceiveScanResults() throws Exception {
-        mWifiScanner.registerScanListener(mExecutor, mScanListener);
-        mLooper.dispatchAll();
-
-        ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
-        verify(mHandler).handleMessage(messageArgumentCaptor.capture());
-        Message sentMessage = messageArgumentCaptor.getValue();
-        assertNotNull(sentMessage);
-
-        assertEquals(1, mBidirectionalAsyncChannelServer.getClientMessengers().size());
-        Messenger scannerMessenger =
-                mBidirectionalAsyncChannelServer.getClientMessengers().iterator().next();
-
-        Message responseMessage = Message.obtain();
-        responseMessage.what = WifiScanner.CMD_SCAN_RESULT;
-        responseMessage.arg2 = sentMessage.arg2;
-        responseMessage.obj = mParcelableScanData;
-        scannerMessenger.send(responseMessage);
-        mLooper.dispatchAll();
-
-        verify(mExecutor).execute(any());
-        verify(mScanListener).onResults(mScanData);
-    }
-
-    /**
-     * Tests that after unregistering a scan listener, {@link ScanListener#onResults(ScanData[])}
-     * is not called.
-     */
-    @Test
-    public void testUnregisterScanListener() throws Exception {
-        mWifiScanner.registerScanListener(mExecutor, mScanListener);
-        mWifiScanner.unregisterScanListener(mScanListener);
-        mLooper.dispatchAll();
-
-        assertEquals(1, mBidirectionalAsyncChannelServer.getClientMessengers().size());
-        Messenger scannerMessenger =
-                mBidirectionalAsyncChannelServer.getClientMessengers().iterator().next();
-
-        ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
-        verify(mHandler, times(2)).handleMessage(messageArgumentCaptor.capture());
-        Message sentMessage = messageArgumentCaptor.getValue();
-        assertNotNull(sentMessage);
-
-        Message responseMessage = Message.obtain();
-        responseMessage.what = WifiScanner.CMD_SCAN_RESULT;
-        responseMessage.obj = mParcelableScanData;
-        responseMessage.arg2 = sentMessage.arg2;
-        scannerMessenger.send(responseMessage);
-        mLooper.dispatchAll();
-
-        verify(mExecutor, never()).execute(any());
-        verify(mScanListener, never()).onResults(mScanData);
-    }
-
-    /**
-     * Tests isFullBandScan() method with and without DFS check
-     */
-    @Test
-    public void testIsFullBandScan() throws Exception {
-        assertFalse(WifiScanner.isFullBandScan(WifiScanner.WIFI_BAND_24_GHZ, true));
-        assertFalse(WifiScanner.isFullBandScan(WifiScanner.WIFI_BAND_5_GHZ, true));
-        assertFalse(WifiScanner.isFullBandScan(WifiScanner.WIFI_BAND_6_GHZ, true));
-        assertFalse(WifiScanner.isFullBandScan(
-                WifiScanner.WIFI_BAND_6_GHZ | WifiScanner.WIFI_BAND_5_GHZ, true));
-        assertTrue(WifiScanner.isFullBandScan(
-                WifiScanner.WIFI_BAND_24_GHZ | WifiScanner.WIFI_BAND_5_GHZ, true));
-        assertFalse(WifiScanner.isFullBandScan(
-                WifiScanner.WIFI_BAND_24_GHZ | WifiScanner.WIFI_BAND_5_GHZ, false));
-        assertTrue(WifiScanner.isFullBandScan(WifiScanner.WIFI_BAND_BOTH_WITH_DFS, true));
-        assertTrue(WifiScanner.isFullBandScan(WifiScanner.WIFI_BAND_BOTH_WITH_DFS, false));
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/WifiSsidTest.java b/wifi/tests/src/android/net/wifi/WifiSsidTest.java
deleted file mode 100644
index 10a37c0..0000000
--- a/wifi/tests/src/android/net/wifi/WifiSsidTest.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-import java.nio.charset.StandardCharsets;
-
-/**
- * Unit tests for {@link android.net.wifi.WifiSsid}.
- */
-@SmallTest
-public class WifiSsidTest {
-
-    private static final String TEST_SSID = "Test SSID";
-    private static final byte[] TEST_SSID_BYTES = TEST_SSID.getBytes(StandardCharsets.US_ASCII);
-
-    /**
-     * Check that createFromByteArray() works.
-     */
-    @Test
-    public void testCreateFromByteArray() {
-        WifiSsid wifiSsid = WifiSsid.createFromByteArray(TEST_SSID_BYTES);
-        assertTrue(wifiSsid != null);
-        assertEquals(TEST_SSID, wifiSsid.toString());
-    }
-
-    /**
-     * Verify that SSID created from byte array and string with the same content are equal.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void testEquals() throws Exception {
-        WifiSsid fromBytes = WifiSsid.createFromByteArray(TEST_SSID_BYTES);
-        WifiSsid fromString = WifiSsid.createFromAsciiEncoded(TEST_SSID);
-        assertTrue(fromBytes != null);
-        assertTrue(fromString != null);
-        assertEquals(fromBytes, fromString);
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/WifiUsabilityStatsEntryTest.java b/wifi/tests/src/android/net/wifi/WifiUsabilityStatsEntryTest.java
deleted file mode 100644
index 5184152..0000000
--- a/wifi/tests/src/android/net/wifi/WifiUsabilityStatsEntryTest.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.validateMockitoUsage;
-
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.MockitoAnnotations;
-
-
-/**
- * Unit tests for {@link android.net.wifi.WifiUsabilityStatsEntry}.
- */
-@SmallTest
-public class WifiUsabilityStatsEntryTest {
-
-    /**
-     * Setup before tests.
-     */
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-    }
-
-    /**
-     * Clean up after tests.
-     */
-    @After
-    public void cleanup() {
-        validateMockitoUsage();
-    }
-
-    /**
-     * Verify parcel read/write for Wifi usability stats result.
-     */
-    @Test
-    public void verifyStatsResultWriteAndThenRead() throws Exception {
-        WifiUsabilityStatsEntry writeResult = createResult();
-        WifiUsabilityStatsEntry readResult = parcelWriteRead(writeResult);
-        assertWifiUsabilityStatsEntryEquals(writeResult, readResult);
-    }
-
-    /**
-     * Write the provided {@link WifiUsabilityStatsEntry} to a parcel and deserialize it.
-     */
-    private static WifiUsabilityStatsEntry parcelWriteRead(
-            WifiUsabilityStatsEntry writeResult) throws Exception {
-        Parcel parcel = Parcel.obtain();
-        writeResult.writeToParcel(parcel, 0);
-        parcel.setDataPosition(0);    // Rewind data position back to the beginning for read.
-        return WifiUsabilityStatsEntry.CREATOR.createFromParcel(parcel);
-    }
-
-    private static WifiUsabilityStatsEntry createResult() {
-        return new WifiUsabilityStatsEntry(
-                0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
-                14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, true
-        );
-    }
-
-    private static void assertWifiUsabilityStatsEntryEquals(
-            WifiUsabilityStatsEntry expected,
-            WifiUsabilityStatsEntry actual) {
-        assertEquals(expected.getTimeStampMillis(), actual.getTimeStampMillis());
-        assertEquals(expected.getRssi(), actual.getRssi());
-        assertEquals(expected.getLinkSpeedMbps(), actual.getLinkSpeedMbps());
-        assertEquals(expected.getTotalTxSuccess(), actual.getTotalTxSuccess());
-        assertEquals(expected.getTotalTxRetries(), actual.getTotalTxRetries());
-        assertEquals(expected.getTotalTxBad(), actual.getTotalTxBad());
-        assertEquals(expected.getTotalRxSuccess(), actual.getTotalRxSuccess());
-        assertEquals(expected.getTotalRadioOnTimeMillis(), actual.getTotalRadioOnTimeMillis());
-        assertEquals(expected.getTotalRadioTxTimeMillis(), actual.getTotalRadioTxTimeMillis());
-        assertEquals(expected.getTotalRadioRxTimeMillis(), actual.getTotalRadioRxTimeMillis());
-        assertEquals(expected.getTotalScanTimeMillis(), actual.getTotalScanTimeMillis());
-        assertEquals(expected.getTotalNanScanTimeMillis(), actual.getTotalNanScanTimeMillis());
-        assertEquals(expected.getTotalBackgroundScanTimeMillis(),
-                actual.getTotalBackgroundScanTimeMillis());
-        assertEquals(expected.getTotalRoamScanTimeMillis(), actual.getTotalRoamScanTimeMillis());
-        assertEquals(expected.getTotalPnoScanTimeMillis(), actual.getTotalPnoScanTimeMillis());
-        assertEquals(expected.getTotalHotspot2ScanTimeMillis(),
-                actual.getTotalHotspot2ScanTimeMillis());
-        assertEquals(expected.getTotalCcaBusyFreqTimeMillis(),
-                actual.getTotalCcaBusyFreqTimeMillis());
-        assertEquals(expected.getTotalRadioOnFreqTimeMillis(),
-                actual.getTotalRadioOnFreqTimeMillis());
-        assertEquals(expected.getTotalBeaconRx(), actual.getTotalBeaconRx());
-        assertEquals(expected.getProbeStatusSinceLastUpdate(),
-                actual.getProbeStatusSinceLastUpdate());
-        assertEquals(expected.getProbeElapsedTimeSinceLastUpdateMillis(),
-                actual.getProbeElapsedTimeSinceLastUpdateMillis());
-        assertEquals(expected.getProbeMcsRateSinceLastUpdate(),
-                actual.getProbeMcsRateSinceLastUpdate());
-        assertEquals(expected.getRxLinkSpeedMbps(), actual.getRxLinkSpeedMbps());
-        assertEquals(expected.getCellularDataNetworkType(), actual.getCellularDataNetworkType());
-        assertEquals(expected.getCellularSignalStrengthDbm(),
-                actual.getCellularSignalStrengthDbm());
-        assertEquals(expected.getCellularSignalStrengthDb(), actual.getCellularSignalStrengthDb());
-        assertEquals(expected.isSameRegisteredCell(), actual.isSameRegisteredCell());
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/aware/TlvBufferUtilsTest.java b/wifi/tests/src/android/net/wifi/aware/TlvBufferUtilsTest.java
deleted file mode 100644
index 971aa8e..0000000
--- a/wifi/tests/src/android/net/wifi/aware/TlvBufferUtilsTest.java
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.aware;
-
-import static org.hamcrest.core.IsEqual.equalTo;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ErrorCollector;
-
-import java.nio.BufferOverflowException;
-import java.util.ArrayList;
-import java.util.List;
-
-
-/**
- * Unit test harness for TlvBufferUtils class.
- */
-@SmallTest
-public class TlvBufferUtilsTest {
-    @Rule
-    public ErrorCollector collector = new ErrorCollector();
-
-    /*
-     * TlvBufferUtils Tests
-     */
-
-    @Test
-    public void testTlvBuild() {
-        TlvBufferUtils.TlvConstructor tlv11 = new TlvBufferUtils.TlvConstructor(1, 1);
-        tlv11.allocate(15);
-        tlv11.putByte(0, (byte) 2);
-        tlv11.putByteArray(2, new byte[] {
-                0, 1, 2 });
-
-        collector.checkThat("tlv11-correct-construction",
-                tlv11.getArray(), equalTo(new byte[]{0, 1, 2, 2, 3, 0, 1, 2}));
-
-        TlvBufferUtils.TlvConstructor tlv01 = new TlvBufferUtils.TlvConstructor(0, 1);
-        tlv01.allocate(15);
-        tlv01.putByte(0, (byte) 2);
-        tlv01.putByteArray(2, new byte[] {
-                0, 1, 2 });
-
-        collector.checkThat("tlv01-correct-construction",
-                tlv01.getArray(), equalTo(new byte[] {1, 2, 3, 0, 1, 2 }));
-
-        collector.checkThat("tlv11-valid",
-                TlvBufferUtils.isValid(tlv11.getArray(), 1, 1),
-                equalTo(true));
-        collector.checkThat("tlv01-valid",
-                TlvBufferUtils.isValid(tlv01.getArray(), 0, 1),
-                equalTo(true));
-    }
-
-    /**
-     * Validate that re-using a TLV by any of the reallocation method resets it completely.
-     */
-    @Test
-    public void testTlvReuse() {
-        TlvBufferUtils.TlvConstructor tlv = new TlvBufferUtils.TlvConstructor(1, 1);
-
-        tlv.allocate(10);
-        tlv.putByte(0, (byte) 2);
-        tlv.putByte(1, (byte) 104);
-
-        collector.checkThat("initial", tlv.getArray(), equalTo(new byte[]{0, 1, 2, 1, 1, 104}));
-
-        tlv.allocate(8);
-        tlv.putByte(5, (byte) 7);
-        collector.checkThat("re-alloc", tlv.getArray(), equalTo(new byte[]{5, 1, 7}));
-    }
-
-    /**
-     * Verify that can build a valid TLV from a List of byte[].
-     */
-    @Test
-    public void testTlvListOperations() {
-        byte[] entry1 = { 1, 2, 3 };
-        byte[] entry2 = { 4, 5 };
-        byte[] entry3 = new byte[0];
-        List<byte[]> data = new ArrayList<>();
-        data.add(entry1);
-        data.add(entry2);
-        data.add(entry3);
-        data.add(null); // zero-length should work
-
-        TlvBufferUtils.TlvConstructor tlv01 = new TlvBufferUtils.TlvConstructor(0, 1);
-        tlv01.allocateAndPut(data);
-        byte[] tlvData = tlv01.getArray();
-        List<byte[]> parsedList = new TlvBufferUtils.TlvIterable(0, 1, tlvData).toList();
-
-        collector.checkThat("tlvData-correct-length", tlvData.length,
-                equalTo(entry1.length + 1 + entry2.length + 1 + entry3.length + 1 + 1));
-        collector.checkThat("parsedList-correct-length", parsedList.size(), equalTo(4));
-        collector.checkThat("parsedList-entry1", parsedList.get(0), equalTo(entry1));
-        collector.checkThat("parsedList-entry2", parsedList.get(1), equalTo(entry2));
-        collector.checkThat("parsedList-entry3", parsedList.get(2), equalTo(entry3));
-        collector.checkThat("parsedList-entry4", parsedList.get(3), equalTo(new byte[0]));
-    }
-
-    /**
-     * Verify that can parse a (correctly formatted) byte array to a list.
-     */
-    @Test
-    public void testTlvParseToList() {
-        byte[] validTlv01 = { 0, 1, 55, 2, 33, 66, 0 };
-
-        List<byte[]> parsedList = new TlvBufferUtils.TlvIterable(0, 1, validTlv01).toList();
-
-        collector.checkThat("parsedList-entry1", parsedList.get(0), equalTo(new byte[0]));
-        collector.checkThat("parsedList-entry2", parsedList.get(1), equalTo(new byte[] { 55 }));
-        collector.checkThat("parsedList-entry3", parsedList.get(2), equalTo(new byte[] { 33, 66 }));
-        collector.checkThat("parsedList-entry4", parsedList.get(3), equalTo(new byte[0]));
-    }
-
-    /**
-     * Verify that an exception is thrown when trying to parse an invalid array.
-     */
-    @Test(expected = BufferOverflowException.class)
-    public void testTlvParseToListError() {
-        byte[] invalidTlv01 = { 0, 1, 55, 2, 55, 66, 3 }; // bad data
-
-        List<byte[]> data = new TlvBufferUtils.TlvIterable(0, 1, invalidTlv01).toList();
-    }
-
-    /**
-     * Validate the API which places raw bytes into the TLV (without a TL structure).
-     */
-    @Test
-    public void testRawPuts() {
-        TlvBufferUtils.TlvConstructor tlv = new TlvBufferUtils.TlvConstructor(1, 1);
-
-        tlv.allocate(10);
-        tlv.putByte(0, (byte) 2);
-        tlv.putRawByte((byte) 55);
-        tlv.putByte(1, (byte) 104);
-        tlv.putRawByteArray(new byte[]{66, 77});
-
-        collector.checkThat("data", tlv.getArray(),
-                equalTo(new byte[]{0, 1, 2, 55, 1, 1, 104, 66, 77}));
-    }
-
-    @Test
-    public void testTlvIterate() {
-        final String ascii = "ABC";
-        final String nonAscii = "何かもっと複雑な";
-
-        TlvBufferUtils.TlvConstructor tlv22 = new TlvBufferUtils.TlvConstructor(2, 2);
-        tlv22.allocate(18);
-        tlv22.putInt(0, 2);
-        tlv22.putShort(2, (short) 3);
-        tlv22.putZeroLengthElement(55);
-
-        TlvBufferUtils.TlvIterable tlv22It = new TlvBufferUtils.TlvIterable(2, 2, tlv22.getArray());
-        int count = 0;
-        for (TlvBufferUtils.TlvElement tlv : tlv22It) {
-            if (count == 0) {
-                collector.checkThat("tlv22-correct-iteration-mType", tlv.type, equalTo(0));
-                collector.checkThat("tlv22-correct-iteration-mLength", tlv.length, equalTo(4));
-                collector.checkThat("tlv22-correct-iteration-DATA", tlv.getInt(), equalTo(2));
-            } else if (count == 1) {
-                collector.checkThat("tlv22-correct-iteration-mType", tlv.type, equalTo(2));
-                collector.checkThat("tlv22-correct-iteration-mLength", tlv.length, equalTo(2));
-                collector.checkThat("tlv22-correct-iteration-DATA", (int) tlv.getShort(),
-                        equalTo(3));
-            } else if (count == 2) {
-                collector.checkThat("tlv22-correct-iteration-mType", tlv.type, equalTo(55));
-                collector.checkThat("tlv22-correct-iteration-mLength", tlv.length, equalTo(0));
-            } else {
-                collector.checkThat("Invalid number of iterations in loop - tlv22", true,
-                        equalTo(false));
-            }
-            ++count;
-        }
-        if (count != 3) {
-            collector.checkThat("Invalid number of iterations outside loop - tlv22", true,
-                    equalTo(false));
-        }
-
-        TlvBufferUtils.TlvConstructor tlv02 = new TlvBufferUtils.TlvConstructor(0, 2);
-        tlv02.allocate(100);
-        tlv02.putByte(0, (byte) 2);
-        tlv02.putString(0, ascii);
-        tlv02.putString(0, nonAscii);
-        tlv02.putByteArray(0, new byte[]{5, 4, 3, 2, 1});
-
-        TlvBufferUtils.TlvIterable tlv02It = new TlvBufferUtils.TlvIterable(0, 2, tlv02.getArray());
-        count = 0;
-        for (TlvBufferUtils.TlvElement tlv : tlv02It) {
-            if (count == 0) {
-                collector.checkThat("tlv02-correct-iteration-mLength", tlv.length, equalTo(1));
-                collector.checkThat("tlv02-correct-iteration-DATA", (int) tlv.getByte(),
-                        equalTo(2));
-            } else if (count == 1) {
-                collector.checkThat("tlv02-correct-iteration-mLength", tlv.length,
-                        equalTo(ascii.length()));
-                collector.checkThat("tlv02-correct-iteration-DATA", tlv.getString().equals(ascii),
-                        equalTo(true));
-            } else if (count == 2) {
-                collector.checkThat("tlv02-correct-iteration-mLength", tlv.length,
-                        equalTo(nonAscii.getBytes().length));
-                collector.checkThat("tlv02-correct-iteration-DATA",
-                        tlv.getString().equals(nonAscii), equalTo(true));
-            } else if (count == 3) {
-                collector.checkThat("tlv02-correct-iteration-mLength", tlv.length,
-                        equalTo(5));
-                collector.checkThat("tlv02-correct-iteration-DATA", tlv.getRawData(),
-                        equalTo(new byte[]{5, 4, 3, 2, 1}));
-            } else {
-                collector.checkThat("Invalid number of iterations in loop - tlv02", true,
-                        equalTo(false));
-            }
-            ++count;
-        }
-        collector.checkThat("Invalid number of iterations outside loop - tlv02", count,
-                equalTo(4));
-
-        collector.checkThat("tlv22-valid",
-                TlvBufferUtils.isValid(tlv22.getArray(), 2, 2),
-                equalTo(true));
-        collector.checkThat("tlv02-valid",
-                TlvBufferUtils.isValid(tlv02.getArray(), 0, 2),
-                equalTo(true));
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testTlvInvalidSizeT1L0() {
-        TlvBufferUtils.TlvConstructor tlv10 = new TlvBufferUtils.TlvConstructor(1, 0);
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testTlvInvalidSizeTm3L2() {
-        TlvBufferUtils.TlvConstructor tlv10 = new TlvBufferUtils.TlvConstructor(-3, 2);
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testTlvInvalidSizeT1Lm2() {
-        TlvBufferUtils.TlvConstructor tlv10 = new TlvBufferUtils.TlvConstructor(1, -2);
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testTlvInvalidSizeT1L3() {
-        TlvBufferUtils.TlvConstructor tlv10 = new TlvBufferUtils.TlvConstructor(1, 3);
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testTlvInvalidSizeT3L1() {
-        TlvBufferUtils.TlvConstructor tlv10 = new TlvBufferUtils.TlvConstructor(3, 1);
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testTlvItInvalidSizeT1L0() {
-        final byte[] dummy = {
-                0, 1, 2 };
-        final int dummyLength = 3;
-        TlvBufferUtils.TlvIterable tlvIt10 = new TlvBufferUtils.TlvIterable(1, 0, dummy);
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testTlvItInvalidSizeTm3L2() {
-        final byte[] dummy = {
-                0, 1, 2 };
-        final int dummyLength = 3;
-        TlvBufferUtils.TlvIterable tlvIt10 = new TlvBufferUtils.TlvIterable(-3, 2, dummy);
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testTlvItInvalidSizeT1Lm2() {
-        final byte[] dummy = {
-                0, 1, 2 };
-        final int dummyLength = 3;
-        TlvBufferUtils.TlvIterable tlvIt10 = new TlvBufferUtils.TlvIterable(1, -2, dummy);
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testTlvItInvalidSizeT1L3() {
-        final byte[] dummy = {
-                0, 1, 2 };
-        final int dummyLength = 3;
-        TlvBufferUtils.TlvIterable tlvIt10 = new TlvBufferUtils.TlvIterable(1, 3, dummy);
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testTlvItInvalidSizeT3L1() {
-        final byte[] dummy = {
-                0, 1, 2 };
-        final int dummyLength = 3;
-        TlvBufferUtils.TlvIterable tlvIt10 = new TlvBufferUtils.TlvIterable(3, 1, dummy);
-    }
-
-    /**
-     * Validate that a malformed byte array fails the TLV validity test.
-     */
-    @Test
-    public void testTlvInvalidByteArray() {
-        TlvBufferUtils.TlvConstructor tlv01 = new TlvBufferUtils.TlvConstructor(0, 1);
-        tlv01.allocate(15);
-        tlv01.putByte(0, (byte) 2);
-        tlv01.putByteArray(2, new byte[]{0, 1, 2});
-
-        byte[] array = tlv01.getArray();
-        array[0] = 10;
-
-        collector.checkThat("tlv01-invalid",
-                TlvBufferUtils.isValid(array, 0, 1), equalTo(false));
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/aware/WifiAwareAgentNetworkSpecifierTest.java b/wifi/tests/src/android/net/wifi/aware/WifiAwareAgentNetworkSpecifierTest.java
deleted file mode 100644
index f2961db..0000000
--- a/wifi/tests/src/android/net/wifi/aware/WifiAwareAgentNetworkSpecifierTest.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.aware;
-
-import static org.hamcrest.core.IsEqual.equalTo;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ErrorCollector;
-
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * Unit test harness for WifiAwareAgentNetworkSpecifier class.
- */
-@SmallTest
-public class WifiAwareAgentNetworkSpecifierTest {
-    @Rule
-    public ErrorCollector collector = new ErrorCollector();
-
-    @Test
-    public void testParcel() {
-        final int numNs = 10;
-
-        Set<WifiAwareNetworkSpecifier> nsSet = new HashSet<>();
-        for (int i = 0; i < numNs; ++i) {
-            nsSet.add(getDummyNetworkSpecifier(10 + i));
-        }
-        WifiAwareAgentNetworkSpecifier dut = new WifiAwareAgentNetworkSpecifier(
-                nsSet.toArray(new WifiAwareNetworkSpecifier[numNs]));
-
-        Parcel parcelW = Parcel.obtain();
-        dut.writeToParcel(parcelW, 0);
-        byte[] bytes = parcelW.marshall();
-        parcelW.recycle();
-
-        Parcel parcelR = Parcel.obtain();
-        parcelR.unmarshall(bytes, 0, bytes.length);
-        parcelR.setDataPosition(0);
-        WifiAwareAgentNetworkSpecifier rereadDut =
-                WifiAwareAgentNetworkSpecifier.CREATOR.createFromParcel(parcelR);
-
-        assertEquals(dut, rereadDut);
-        assertEquals(dut.hashCode(), rereadDut.hashCode());
-
-        // Ensure that individual network specifiers are satisfied by both the original & marshaled
-        // |WifiAwareNetworkAgentSpecifier instances.
-        for (WifiAwareNetworkSpecifier ns : nsSet) {
-            assertTrue(dut.satisfiesAwareNetworkSpecifier(ns));
-            assertTrue(rereadDut.satisfiesAwareNetworkSpecifier(ns));
-        }
-    }
-
-    /**
-     * Validate that an empty agent network specifier doesn't match any base network specifier.
-     */
-    @Test
-    public void testEmptyDoesntMatchAnything() {
-        WifiAwareAgentNetworkSpecifier dut = new WifiAwareAgentNetworkSpecifier();
-        WifiAwareNetworkSpecifier ns = getDummyNetworkSpecifier(6);
-        collector.checkThat("No match expected", ns.canBeSatisfiedBy(dut), equalTo(false));
-    }
-
-    /**
-     * Validate that an agent network specifier constructed with a single entry matches that entry,
-     * and only that entry.
-     */
-    @Test
-    public void testSingleMatch() {
-        WifiAwareNetworkSpecifier nsThis = getDummyNetworkSpecifier(6);
-        WifiAwareAgentNetworkSpecifier dut = new WifiAwareAgentNetworkSpecifier(nsThis);
-        WifiAwareNetworkSpecifier nsOther = getDummyNetworkSpecifier(8);
-        collector.checkThat("Match expected", nsThis.canBeSatisfiedBy(dut), equalTo(true));
-        collector.checkThat("No match expected", nsOther.canBeSatisfiedBy(dut), equalTo(false));
-    }
-
-    /**
-     * Validate that an agent network specifier constructed with multiple entries matches all those
-     * entries - but none other.
-     */
-    @Test
-    public void testMultipleMatchesAllMembers() {
-        final int numNs = 10;
-
-        Set<WifiAwareNetworkSpecifier> nsSet = new HashSet<>();
-        for (int i = 0; i < numNs; ++i) {
-            nsSet.add(getDummyNetworkSpecifier(10 + i));
-        }
-
-        WifiAwareAgentNetworkSpecifier dut = new WifiAwareAgentNetworkSpecifier(
-                nsSet.toArray(new WifiAwareNetworkSpecifier[numNs]));
-        WifiAwareNetworkSpecifier nsOther = getDummyNetworkSpecifier(10000);
-
-        for (WifiAwareNetworkSpecifier nsThis: nsSet) {
-            collector.checkThat("Match expected", nsThis.canBeSatisfiedBy(dut), equalTo(true));
-        }
-        collector.checkThat("No match expected", nsOther.canBeSatisfiedBy(dut), equalTo(false));
-    }
-
-    /**
-     * Validate that agent network specifier matches against a super-set.
-     */
-    @Test
-    public void testMatchSuperset() {
-        final int numNs = 10;
-
-        Set<WifiAwareNetworkSpecifier> nsSet = new HashSet<>();
-        for (int i = 0; i < numNs; ++i) {
-            nsSet.add(getDummyNetworkSpecifier(10 + i));
-        }
-
-        WifiAwareAgentNetworkSpecifier oldNs = new WifiAwareAgentNetworkSpecifier(
-                nsSet.toArray(new WifiAwareNetworkSpecifier[nsSet.size()]));
-
-        nsSet.add(getDummyNetworkSpecifier(100 + numNs));
-        WifiAwareAgentNetworkSpecifier newNs = new WifiAwareAgentNetworkSpecifier(
-                nsSet.toArray(new WifiAwareNetworkSpecifier[nsSet.size()]));
-
-        collector.checkThat("Match expected", oldNs.canBeSatisfiedBy(newNs), equalTo(true));
-    }
-
-    /**
-     * Validate that agent network specifier does not match against a sub-set.
-     */
-    @Test
-    public void testNoMatchSubset() {
-        final int numNs = 10;
-
-        Set<WifiAwareNetworkSpecifier> nsSet = new HashSet<>();
-        for (int i = 0; i < numNs; ++i) {
-            nsSet.add(getDummyNetworkSpecifier(10 + i));
-        }
-
-        WifiAwareAgentNetworkSpecifier newNs = new WifiAwareAgentNetworkSpecifier(
-                nsSet.toArray(new WifiAwareNetworkSpecifier[nsSet.size()]));
-
-        nsSet.add(getDummyNetworkSpecifier(100 + numNs));
-        WifiAwareAgentNetworkSpecifier oldNs = new WifiAwareAgentNetworkSpecifier(
-                nsSet.toArray(new WifiAwareNetworkSpecifier[nsSet.size()]));
-
-        collector.checkThat("Match unexpected", oldNs.canBeSatisfiedBy(newNs), equalTo(false));
-    }
-
-    // utilities
-
-    /**
-     * Returns a WifiAwareNetworkSpecifier with dummy (but valid) entries. Each can be
-     * differentiated (made unique) by specifying a different client ID.
-     */
-    WifiAwareNetworkSpecifier getDummyNetworkSpecifier(int clientId) {
-        return new WifiAwareNetworkSpecifier(WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_OOB,
-                WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, clientId, 0, 0, new byte[6],
-                null, null, 10, 5);
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
deleted file mode 100644
index c5f9804..0000000
--- a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
+++ /dev/null
@@ -1,1639 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.aware;
-
-import static android.net.wifi.aware.WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_IB;
-
-import static org.hamcrest.core.IsEqual.equalTo;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.ArgumentMatchers.isNull;
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.net.MacAddress;
-import android.net.wifi.RttManager;
-import android.net.wifi.util.HexEncoding;
-import android.os.Build;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Parcel;
-import android.os.test.TestLooper;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ErrorCollector;
-import org.mockito.ArgumentCaptor;
-import org.mockito.InOrder;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.net.Inet6Address;
-import java.net.UnknownHostException;
-import java.util.List;
-
-/**
- * Unit test harness for WifiAwareManager class.
- */
-@SmallTest
-public class WifiAwareManagerTest {
-    private WifiAwareManager mDut;
-    private TestLooper mMockLooper;
-    private Handler mMockLooperHandler;
-
-    @Rule
-    public ErrorCollector collector = new ErrorCollector();
-
-    @Mock
-    public Context mockContext;
-
-    @Mock
-    public AttachCallback mockCallback;
-
-    @Mock
-    public DiscoverySessionCallback mockSessionCallback;
-
-    @Mock
-    public IWifiAwareManager mockAwareService;
-
-    @Mock
-    public PublishDiscoverySession mockPublishSession;
-
-    @Mock
-    public SubscribeDiscoverySession mockSubscribeSession;
-
-    @Mock
-    public RttManager.RttListener mockRttListener;
-
-    @Mock
-    public PackageManager mockPackageManager;
-
-    @Mock
-    public ApplicationInfo mockApplicationInfo;
-
-    private static final int AWARE_STATUS_ERROR = -1;
-
-    private static final byte[] PMK_VALID = "01234567890123456789012345678901".getBytes();
-    private static final byte[] PMK_INVALID = "012".getBytes();
-
-    private static final String PASSPHRASE_VALID = "SomeLongEnoughPassphrase";
-    private static final String PASSPHRASE_TOO_SHORT = "012";
-    private static final String PASSPHRASE_TOO_LONG =
-            "0123456789012345678901234567890123456789012345678901234567890123456789";
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-
-        mockApplicationInfo.targetSdkVersion = Build.VERSION_CODES.Q;
-        when(mockPackageManager.getApplicationInfo(anyString(), anyInt())).thenReturn(
-                mockApplicationInfo);
-        when(mockContext.getOpPackageName()).thenReturn("XXX");
-        when(mockContext.getPackageManager()).thenReturn(mockPackageManager);
-
-        mDut = new WifiAwareManager(mockContext, mockAwareService);
-        mMockLooper = new TestLooper();
-        mMockLooperHandler = new Handler(mMockLooper.getLooper());
-    }
-
-    /*
-     * Straight pass-through tests
-     */
-
-    /**
-     * Validate pass-through of isUsageEnabled() API.
-     */
-    @Test
-    public void testIsUsageEnable() throws Exception {
-        mDut.isAvailable();
-
-        verify(mockAwareService).isUsageEnabled();
-    }
-
-    /**
-     * Validate pass-through of getCharacteristics() API.
-     */
-    @Test
-    public void testGetCharacteristics() throws Exception {
-        mDut.getCharacteristics();
-
-        verify(mockAwareService).getCharacteristics();
-    }
-
-    /*
-     * WifiAwareEventCallbackProxy Tests
-     */
-
-    /**
-     * Validate the successful connect flow: (1) connect + success (2) publish, (3) disconnect
-     * (4) try publishing on old session (5) connect again
-     */
-    @Test
-    public void testConnectFlow() throws Exception {
-        final int clientId = 4565;
-
-        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockAwareService);
-        ArgumentCaptor<IWifiAwareEventCallback> clientProxyCallback = ArgumentCaptor
-                .forClass(IWifiAwareEventCallback.class);
-        ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
-                WifiAwareSession.class);
-        ArgumentCaptor<IBinder> binder = ArgumentCaptor.forClass(IBinder.class);
-
-        // (1) connect + success
-        mDut.attach(mockCallback, mMockLooperHandler);
-        inOrder.verify(mockAwareService).connect(binder.capture(), any(), any(),
-                clientProxyCallback.capture(), isNull(), eq(false));
-        clientProxyCallback.getValue().onConnectSuccess(clientId);
-        mMockLooper.dispatchAll();
-        inOrder.verify(mockCallback).onAttached(sessionCaptor.capture());
-        WifiAwareSession session = sessionCaptor.getValue();
-
-        // (2) publish - should succeed
-        PublishConfig publishConfig = new PublishConfig.Builder().build();
-        session.publish(publishConfig, mockSessionCallback, mMockLooperHandler);
-        inOrder.verify(mockAwareService).publish(any(), any(), eq(clientId), eq(publishConfig),
-                any());
-
-        // (3) disconnect
-        session.close();
-        inOrder.verify(mockAwareService).disconnect(eq(clientId), eq(binder.getValue()));
-
-        // (4) try publishing again - fails silently
-        session.publish(new PublishConfig.Builder().build(), mockSessionCallback,
-                mMockLooperHandler);
-
-        // (5) connect
-        mDut.attach(mockCallback, mMockLooperHandler);
-        inOrder.verify(mockAwareService).connect(binder.capture(), any(), any(), any(), isNull(),
-                eq(false));
-
-        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService);
-    }
-
-    /**
-     * Validate the failed connect flow: (1) connect + failure, (2) connect + success (3) subscribe
-     */
-    @Test
-    public void testConnectFailure() throws Exception {
-        final int clientId = 4565;
-        final int reason = AWARE_STATUS_ERROR;
-
-        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockAwareService);
-        ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
-                WifiAwareSession.class);
-        ArgumentCaptor<IWifiAwareEventCallback> clientProxyCallback = ArgumentCaptor
-                .forClass(IWifiAwareEventCallback.class);
-
-        // (1) connect + failure
-        mDut.attach(mockCallback, mMockLooperHandler);
-        inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(),
-                isNull(), eq(false));
-        clientProxyCallback.getValue().onConnectFail(reason);
-        mMockLooper.dispatchAll();
-        inOrder.verify(mockCallback).onAttachFailed();
-
-        // (2) connect + success
-        mDut.attach(mockCallback, mMockLooperHandler);
-        inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(),
-                isNull(), eq(false));
-        clientProxyCallback.getValue().onConnectSuccess(clientId);
-        mMockLooper.dispatchAll();
-        inOrder.verify(mockCallback).onAttached(sessionCaptor.capture());
-        WifiAwareSession session = sessionCaptor.getValue();
-
-        // (4) subscribe: should succeed
-        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
-        session.subscribe(subscribeConfig, mockSessionCallback, mMockLooperHandler);
-        inOrder.verify(mockAwareService).subscribe(any(), any(), eq(clientId), eq(subscribeConfig),
-                any());
-
-        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService);
-    }
-
-    /**
-     * Validate that can call connect to create multiple sessions: (1) connect
-     * + success, (2) try connect again
-     */
-    @Test
-    public void testInvalidConnectSequence() throws Exception {
-        final int clientId = 4565;
-
-        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockAwareService);
-        ArgumentCaptor<IWifiAwareEventCallback> clientProxyCallback = ArgumentCaptor
-                .forClass(IWifiAwareEventCallback.class);
-
-        // (1) connect + success
-        mDut.attach(mockCallback, mMockLooperHandler);
-        inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(),
-                isNull(), eq(false));
-        clientProxyCallback.getValue().onConnectSuccess(clientId);
-        mMockLooper.dispatchAll();
-        inOrder.verify(mockCallback).onAttached(any());
-
-        // (2) connect + success
-        mDut.attach(mockCallback, mMockLooperHandler);
-        inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(),
-                isNull(), eq(false));
-        clientProxyCallback.getValue().onConnectSuccess(clientId + 1);
-        mMockLooper.dispatchAll();
-        inOrder.verify(mockCallback).onAttached(any());
-
-        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService);
-    }
-
-    /*
-     * WifiAwareDiscoverySessionCallbackProxy Tests
-     */
-
-    /**
-     * Validate the publish flow: (0) connect + success, (1) publish, (2)
-     * success creates session, (3) pass through everything, (4) update publish
-     * through session, (5) terminate locally, (6) try another command -
-     * ignored.
-     */
-    @Test
-    public void testPublishFlow() throws Exception {
-        final int clientId = 4565;
-        final int sessionId = 123;
-        final ConfigRequest configRequest = new ConfigRequest.Builder().build();
-        final PublishConfig publishConfig = new PublishConfig.Builder().build();
-        final PeerHandle peerHandle = new PeerHandle(873);
-        final String string1 = "hey from here...";
-        final byte[] matchFilter = { 1, 12, 2, 31, 32 };
-        final int messageId = 2123;
-        final int reason = AWARE_STATUS_ERROR;
-
-        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockAwareService,
-                mockPublishSession);
-        ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
-                WifiAwareSession.class);
-        ArgumentCaptor<IWifiAwareEventCallback> clientProxyCallback = ArgumentCaptor
-                .forClass(IWifiAwareEventCallback.class);
-        ArgumentCaptor<IWifiAwareDiscoverySessionCallback> sessionProxyCallback = ArgumentCaptor
-                .forClass(IWifiAwareDiscoverySessionCallback.class);
-        ArgumentCaptor<PublishDiscoverySession> publishSession = ArgumentCaptor
-                .forClass(PublishDiscoverySession.class);
-        ArgumentCaptor<PeerHandle> peerIdCaptor = ArgumentCaptor.forClass(PeerHandle.class);
-        ArgumentCaptor<List<byte[]>> matchFilterCaptor = ArgumentCaptor.forClass(
-                (Class) List.class);
-
-        // (0) connect + success
-        mDut.attach(mMockLooperHandler, configRequest, mockCallback, null);
-        inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(),
-                eq(configRequest), eq(false));
-        clientProxyCallback.getValue().onConnectSuccess(clientId);
-        mMockLooper.dispatchAll();
-        inOrder.verify(mockCallback).onAttached(sessionCaptor.capture());
-        WifiAwareSession session = sessionCaptor.getValue();
-
-        // (1) publish
-        session.publish(publishConfig, mockSessionCallback, mMockLooperHandler);
-        inOrder.verify(mockAwareService).publish(any(), any(), eq(clientId), eq(publishConfig),
-                sessionProxyCallback.capture());
-
-        // (2) publish session created
-        sessionProxyCallback.getValue().onSessionStarted(sessionId);
-        mMockLooper.dispatchAll();
-        inOrder.verify(mockSessionCallback).onPublishStarted(publishSession.capture());
-
-        // (3) ...
-        publishSession.getValue().sendMessage(peerHandle, messageId, string1.getBytes());
-        sessionProxyCallback.getValue().onMatch(peerHandle.peerId, string1.getBytes(), matchFilter);
-        sessionProxyCallback.getValue().onMessageReceived(peerHandle.peerId, string1.getBytes());
-        sessionProxyCallback.getValue().onMessageSendFail(messageId, reason);
-        sessionProxyCallback.getValue().onMessageSendSuccess(messageId);
-        mMockLooper.dispatchAll();
-
-        inOrder.verify(mockAwareService).sendMessage(eq(clientId), eq(sessionId),
-                eq(peerHandle.peerId), eq(string1.getBytes()), eq(messageId), eq(0));
-        inOrder.verify(mockSessionCallback).onServiceDiscovered(peerIdCaptor.capture(),
-                eq(string1.getBytes()),
-                matchFilterCaptor.capture());
-
-        // note: need to capture/compare elements since the Mockito eq() is a shallow comparator
-        List<byte[]> parsedMatchFilter = new TlvBufferUtils.TlvIterable(0, 1, matchFilter).toList();
-        collector.checkThat("match-filter-size", parsedMatchFilter.size(),
-                equalTo(matchFilterCaptor.getValue().size()));
-        collector.checkThat("match-filter-entry0", parsedMatchFilter.get(0),
-                equalTo(matchFilterCaptor.getValue().get(0)));
-        collector.checkThat("match-filter-entry1", parsedMatchFilter.get(1),
-                equalTo(matchFilterCaptor.getValue().get(1)));
-
-        assertEquals(peerIdCaptor.getValue().peerId, peerHandle.peerId);
-        inOrder.verify(mockSessionCallback).onMessageReceived(peerIdCaptor.capture(),
-                eq(string1.getBytes()));
-        assertEquals(peerIdCaptor.getValue().peerId, peerHandle.peerId);
-        inOrder.verify(mockSessionCallback).onMessageSendFailed(eq(messageId));
-        inOrder.verify(mockSessionCallback).onMessageSendSucceeded(eq(messageId));
-
-        // (4) update publish
-        publishSession.getValue().updatePublish(publishConfig);
-        sessionProxyCallback.getValue().onSessionConfigFail(reason);
-        mMockLooper.dispatchAll();
-        inOrder.verify(mockAwareService).updatePublish(eq(clientId), eq(sessionId),
-                eq(publishConfig));
-        inOrder.verify(mockSessionCallback).onSessionConfigFailed();
-
-        // (5) terminate
-        publishSession.getValue().close();
-        mMockLooper.dispatchAll();
-        inOrder.verify(mockAwareService).terminateSession(clientId, sessionId);
-
-        // (6) try an update (nothing)
-        publishSession.getValue().updatePublish(publishConfig);
-        mMockLooper.dispatchAll();
-
-        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService,
-                mockPublishSession);
-    }
-
-    /**
-     * Validate race condition of session terminate and session action: (1)
-     * connect, (2) publish success + terminate, (3) update.
-     */
-    @Test
-    public void testPublishRemoteTerminate() throws Exception {
-        final int clientId = 4565;
-        final int sessionId = 123;
-        final ConfigRequest configRequest = new ConfigRequest.Builder().build();
-        final PublishConfig publishConfig = new PublishConfig.Builder().build();
-
-        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockAwareService,
-                mockPublishSession);
-        ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
-                WifiAwareSession.class);
-        ArgumentCaptor<IWifiAwareEventCallback> clientProxyCallback = ArgumentCaptor
-                .forClass(IWifiAwareEventCallback.class);
-        ArgumentCaptor<IWifiAwareDiscoverySessionCallback> sessionProxyCallback = ArgumentCaptor
-                .forClass(IWifiAwareDiscoverySessionCallback.class);
-        ArgumentCaptor<PublishDiscoverySession> publishSession = ArgumentCaptor
-                .forClass(PublishDiscoverySession.class);
-
-        // (1) connect successfully
-        mDut.attach(mMockLooperHandler, configRequest, mockCallback, null);
-        inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(),
-                eq(configRequest), eq(false));
-        clientProxyCallback.getValue().onConnectSuccess(clientId);
-        mMockLooper.dispatchAll();
-        inOrder.verify(mockCallback).onAttached(sessionCaptor.capture());
-        WifiAwareSession session = sessionCaptor.getValue();
-
-        // (2) publish: successfully - then terminated
-        session.publish(publishConfig, mockSessionCallback, mMockLooperHandler);
-        inOrder.verify(mockAwareService).publish(any(), any(), eq(clientId), eq(publishConfig),
-                sessionProxyCallback.capture());
-        sessionProxyCallback.getValue().onSessionStarted(sessionId);
-        sessionProxyCallback.getValue().onSessionTerminated(0);
-        mMockLooper.dispatchAll();
-        inOrder.verify(mockSessionCallback).onPublishStarted(publishSession.capture());
-        inOrder.verify(mockSessionCallback).onSessionTerminated();
-
-        // (3) failure when trying to update: NOP
-        publishSession.getValue().updatePublish(publishConfig);
-
-        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService,
-                mockPublishSession);
-    }
-
-    /**
-     * Validate the subscribe flow: (0) connect + success, (1) subscribe, (2)
-     * success creates session, (3) pass through everything, (4) update
-     * subscribe through session, (5) terminate locally, (6) try another command
-     * - ignored.
-     */
-    @Test
-    public void testSubscribeFlow() throws Exception {
-        final int clientId = 4565;
-        final int sessionId = 123;
-        final ConfigRequest configRequest = new ConfigRequest.Builder().build();
-        final SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
-        final PeerHandle peerHandle = new PeerHandle(873);
-        final String string1 = "hey from here...";
-        final byte[] matchFilter = { 1, 12, 3, 31, 32 }; // bad data!
-        final int messageId = 2123;
-        final int reason = AWARE_STATUS_ERROR;
-        final int distanceMm = 100;
-
-        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockAwareService,
-                mockSubscribeSession);
-        ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
-                WifiAwareSession.class);
-        ArgumentCaptor<IWifiAwareEventCallback> clientProxyCallback = ArgumentCaptor
-                .forClass(IWifiAwareEventCallback.class);
-        ArgumentCaptor<IWifiAwareDiscoverySessionCallback> sessionProxyCallback = ArgumentCaptor
-                .forClass(IWifiAwareDiscoverySessionCallback.class);
-        ArgumentCaptor<SubscribeDiscoverySession> subscribeSession = ArgumentCaptor
-                .forClass(SubscribeDiscoverySession.class);
-        ArgumentCaptor<PeerHandle> peerIdCaptor = ArgumentCaptor.forClass(PeerHandle.class);
-
-        // (0) connect + success
-        mDut.attach(mMockLooperHandler, configRequest, mockCallback, null);
-        inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(),
-                eq(configRequest), eq(false));
-        clientProxyCallback.getValue().onConnectSuccess(clientId);
-        mMockLooper.dispatchAll();
-        inOrder.verify(mockCallback).onAttached(sessionCaptor.capture());
-        WifiAwareSession session = sessionCaptor.getValue();
-
-        // (1) subscribe
-        session.subscribe(subscribeConfig, mockSessionCallback, mMockLooperHandler);
-        inOrder.verify(mockAwareService).subscribe(any(), any(), eq(clientId), eq(subscribeConfig),
-                sessionProxyCallback.capture());
-
-        // (2) subscribe session created
-        sessionProxyCallback.getValue().onSessionStarted(sessionId);
-        mMockLooper.dispatchAll();
-        inOrder.verify(mockSessionCallback).onSubscribeStarted(subscribeSession.capture());
-
-        // (3) ...
-        subscribeSession.getValue().sendMessage(peerHandle, messageId, string1.getBytes());
-        sessionProxyCallback.getValue().onMatch(peerHandle.peerId, string1.getBytes(), matchFilter);
-        sessionProxyCallback.getValue().onMatchWithDistance(peerHandle.peerId, string1.getBytes(),
-                matchFilter, distanceMm);
-        sessionProxyCallback.getValue().onMessageReceived(peerHandle.peerId, string1.getBytes());
-        sessionProxyCallback.getValue().onMessageSendFail(messageId, reason);
-        sessionProxyCallback.getValue().onMessageSendSuccess(messageId);
-        mMockLooper.dispatchAll();
-
-        inOrder.verify(mockAwareService).sendMessage(eq(clientId), eq(sessionId),
-                eq(peerHandle.peerId), eq(string1.getBytes()), eq(messageId), eq(0));
-        inOrder.verify(mockSessionCallback).onServiceDiscovered(peerIdCaptor.capture(),
-                eq(string1.getBytes()), isNull());
-        inOrder.verify(mockSessionCallback).onServiceDiscoveredWithinRange(peerIdCaptor.capture(),
-                eq(string1.getBytes()), isNull(), eq(distanceMm));
-        assertEquals((peerIdCaptor.getValue()).peerId, peerHandle.peerId);
-        inOrder.verify(mockSessionCallback).onMessageReceived(peerIdCaptor.capture(),
-                eq(string1.getBytes()));
-        assertEquals((peerIdCaptor.getValue()).peerId, peerHandle.peerId);
-        inOrder.verify(mockSessionCallback).onMessageSendFailed(eq(messageId));
-        inOrder.verify(mockSessionCallback).onMessageSendSucceeded(eq(messageId));
-
-        // (4) update subscribe
-        subscribeSession.getValue().updateSubscribe(subscribeConfig);
-        sessionProxyCallback.getValue().onSessionConfigFail(reason);
-        mMockLooper.dispatchAll();
-        inOrder.verify(mockAwareService).updateSubscribe(eq(clientId), eq(sessionId),
-                eq(subscribeConfig));
-        inOrder.verify(mockSessionCallback).onSessionConfigFailed();
-
-        // (5) terminate
-        subscribeSession.getValue().close();
-        mMockLooper.dispatchAll();
-        inOrder.verify(mockAwareService).terminateSession(clientId, sessionId);
-
-        // (6) try an update (nothing)
-        subscribeSession.getValue().updateSubscribe(subscribeConfig);
-        mMockLooper.dispatchAll();
-
-        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService,
-                mockSubscribeSession);
-    }
-
-    /**
-     * Validate race condition of session terminate and session action: (1)
-     * connect, (2) subscribe success + terminate, (3) update.
-     */
-    @Test
-    public void testSubscribeRemoteTerminate() throws Exception {
-        final int clientId = 4565;
-        final int sessionId = 123;
-        final ConfigRequest configRequest = new ConfigRequest.Builder().build();
-        final SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
-
-        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockAwareService,
-                mockSubscribeSession);
-        ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
-                WifiAwareSession.class);
-        ArgumentCaptor<IWifiAwareEventCallback> clientProxyCallback = ArgumentCaptor
-                .forClass(IWifiAwareEventCallback.class);
-        ArgumentCaptor<IWifiAwareDiscoverySessionCallback> sessionProxyCallback = ArgumentCaptor
-                .forClass(IWifiAwareDiscoverySessionCallback.class);
-        ArgumentCaptor<SubscribeDiscoverySession> subscribeSession = ArgumentCaptor
-                .forClass(SubscribeDiscoverySession.class);
-
-        // (1) connect successfully
-        mDut.attach(mMockLooperHandler, configRequest, mockCallback, null);
-        inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(),
-                eq(configRequest), eq(false));
-        clientProxyCallback.getValue().onConnectSuccess(clientId);
-        mMockLooper.dispatchAll();
-        inOrder.verify(mockCallback).onAttached(sessionCaptor.capture());
-        WifiAwareSession session = sessionCaptor.getValue();
-
-        // (2) subscribe: successfully - then terminated
-        session.subscribe(subscribeConfig, mockSessionCallback, mMockLooperHandler);
-        inOrder.verify(mockAwareService).subscribe(any(), any(), eq(clientId), eq(subscribeConfig),
-                sessionProxyCallback.capture());
-        sessionProxyCallback.getValue().onSessionStarted(sessionId);
-        sessionProxyCallback.getValue().onSessionTerminated(0);
-        mMockLooper.dispatchAll();
-        inOrder.verify(mockSessionCallback).onSubscribeStarted(subscribeSession.capture());
-        inOrder.verify(mockSessionCallback).onSessionTerminated();
-
-        // (3) failure when trying to update: NOP
-        subscribeSession.getValue().updateSubscribe(subscribeConfig);
-
-        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService,
-                mockSubscribeSession);
-    }
-
-    /*
-     * ConfigRequest Tests
-     */
-
-    @Test
-    public void testConfigRequestBuilderDefaults() {
-        ConfigRequest configRequest = new ConfigRequest.Builder().build();
-
-        collector.checkThat("mClusterHigh", ConfigRequest.CLUSTER_ID_MAX,
-                equalTo(configRequest.mClusterHigh));
-        collector.checkThat("mClusterLow", ConfigRequest.CLUSTER_ID_MIN,
-                equalTo(configRequest.mClusterLow));
-        collector.checkThat("mMasterPreference", 0,
-                equalTo(configRequest.mMasterPreference));
-        collector.checkThat("mSupport5gBand", true, equalTo(configRequest.mSupport5gBand));
-        collector.checkThat("mSupport6gBand", false, equalTo(configRequest.mSupport6gBand));
-        collector.checkThat("mDiscoveryWindowInterval.length", 3,
-                equalTo(configRequest.mDiscoveryWindowInterval.length));
-        collector.checkThat("mDiscoveryWindowInterval[2.4GHz]", ConfigRequest.DW_INTERVAL_NOT_INIT,
-                equalTo(configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_24GHZ]));
-        collector.checkThat("mDiscoveryWindowInterval[5Hz]", ConfigRequest.DW_INTERVAL_NOT_INIT,
-                equalTo(configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_5GHZ]));
-        collector.checkThat("mDiscoveryWindowInterval[6Hz]", ConfigRequest.DW_INTERVAL_NOT_INIT,
-                equalTo(configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_6GHZ]));
-    }
-
-    @Test
-    public void testConfigRequestBuilder() {
-        final int clusterHigh = 100;
-        final int clusterLow = 5;
-        final int masterPreference = 55;
-        final boolean supportBand5g = true;
-        final boolean supportBand6g = true;
-        final int dwWindow5GHz = 3;
-        final int dwWindow6GHz = 4;
-
-        ConfigRequest configRequest = new ConfigRequest.Builder().setClusterHigh(clusterHigh)
-                .setClusterLow(clusterLow).setMasterPreference(masterPreference)
-                .setSupport5gBand(supportBand5g)
-                .setSupport6gBand(supportBand6g)
-                .setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_5GHZ, dwWindow5GHz)
-                .setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_6GHZ, dwWindow6GHz)
-                .build();
-
-        collector.checkThat("mClusterHigh", clusterHigh, equalTo(configRequest.mClusterHigh));
-        collector.checkThat("mClusterLow", clusterLow, equalTo(configRequest.mClusterLow));
-        collector.checkThat("mMasterPreference", masterPreference,
-                equalTo(configRequest.mMasterPreference));
-        collector.checkThat("mSupport5gBand", supportBand5g, equalTo(configRequest.mSupport5gBand));
-        collector.checkThat("mSupport6gBand", supportBand6g, equalTo(configRequest.mSupport6gBand));
-        collector.checkThat("mDiscoveryWindowInterval.length", 3,
-                equalTo(configRequest.mDiscoveryWindowInterval.length));
-        collector.checkThat("mDiscoveryWindowInterval[2.4GHz]", ConfigRequest.DW_INTERVAL_NOT_INIT,
-                equalTo(configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_24GHZ]));
-        collector.checkThat("mDiscoveryWindowInterval[5GHz]", dwWindow5GHz,
-                equalTo(configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_5GHZ]));
-        collector.checkThat("mDiscoveryWindowInterval[6GHz]", dwWindow6GHz,
-                equalTo(configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_6GHZ]));
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testConfigRequestBuilderMasterPrefNegative() {
-        ConfigRequest.Builder builder = new ConfigRequest.Builder();
-        builder.setMasterPreference(-1);
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testConfigRequestBuilderMasterPrefReserved1() {
-        new ConfigRequest.Builder().setMasterPreference(1);
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testConfigRequestBuilderMasterPrefReserved255() {
-        new ConfigRequest.Builder().setMasterPreference(255);
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testConfigRequestBuilderMasterPrefTooLarge() {
-        new ConfigRequest.Builder().setMasterPreference(256);
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testConfigRequestBuilderClusterLowNegative() {
-        new ConfigRequest.Builder().setClusterLow(-1);
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testConfigRequestBuilderClusterHighNegative() {
-        new ConfigRequest.Builder().setClusterHigh(-1);
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testConfigRequestBuilderClusterLowAboveMax() {
-        new ConfigRequest.Builder().setClusterLow(ConfigRequest.CLUSTER_ID_MAX + 1);
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testConfigRequestBuilderClusterHighAboveMax() {
-        new ConfigRequest.Builder().setClusterHigh(ConfigRequest.CLUSTER_ID_MAX + 1);
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testConfigRequestBuilderClusterLowLargerThanHigh() {
-        new ConfigRequest.Builder().setClusterLow(100).setClusterHigh(5).build();
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testConfigRequestBuilderDwIntervalInvalidBand() {
-        new ConfigRequest.Builder().setDiscoveryWindowInterval(5, 1).build();
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testConfigRequestBuilderDwIntervalInvalidValueZero() {
-        new ConfigRequest.Builder().setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_24GHZ,
-                0).build();
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testConfigRequestBuilderDwIntervalInvalidValueLarge() {
-        new ConfigRequest.Builder().setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_5GHZ,
-                6).build();
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testConfigRequestBuilderDwIntervalInvalidValueLargeValidate() {
-        ConfigRequest cr = new ConfigRequest.Builder().build();
-        cr.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_5GHZ] = 6;
-        cr.validate();
-    }
-
-    @Test
-    public void testConfigRequestParcel() {
-        final int clusterHigh = 189;
-        final int clusterLow = 25;
-        final int masterPreference = 177;
-        final boolean supportBand5g = true;
-        final boolean supportBand6g = false;
-        final int dwWindow24GHz = 1;
-        final int dwWindow5GHz = 5;
-        final int dwWindow6GHz = 4;
-
-        ConfigRequest configRequest = new ConfigRequest.Builder().setClusterHigh(clusterHigh)
-                .setClusterLow(clusterLow).setMasterPreference(masterPreference)
-                .setSupport5gBand(supportBand5g)
-                .setSupport6gBand(supportBand6g)
-                .setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_24GHZ, dwWindow24GHz)
-                .setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_5GHZ, dwWindow5GHz)
-                .setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_6GHZ, dwWindow6GHz)
-                .build();
-
-        Parcel parcelW = Parcel.obtain();
-        configRequest.writeToParcel(parcelW, 0);
-        byte[] bytes = parcelW.marshall();
-        parcelW.recycle();
-
-        Parcel parcelR = Parcel.obtain();
-        parcelR.unmarshall(bytes, 0, bytes.length);
-        parcelR.setDataPosition(0);
-        ConfigRequest rereadConfigRequest = ConfigRequest.CREATOR.createFromParcel(parcelR);
-
-        assertEquals(configRequest, rereadConfigRequest);
-        assertEquals(configRequest.hashCode(), rereadConfigRequest.hashCode());
-    }
-
-    /*
-     * SubscribeConfig Tests
-     */
-
-    @Test
-    public void testSubscribeConfigBuilderDefaults() {
-        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
-
-        collector.checkThat("mServiceName", subscribeConfig.mServiceName, equalTo(null));
-        collector.checkThat("mServiceSpecificInfo", subscribeConfig.mServiceSpecificInfo,
-                equalTo(null));
-        collector.checkThat("mMatchFilter", subscribeConfig.mMatchFilter, equalTo(null));
-        collector.checkThat("mSubscribeType", subscribeConfig.mSubscribeType,
-                equalTo(SubscribeConfig.SUBSCRIBE_TYPE_PASSIVE));
-        collector.checkThat("mTtlSec", subscribeConfig.mTtlSec, equalTo(0));
-        collector.checkThat("mEnableTerminateNotification",
-                subscribeConfig.mEnableTerminateNotification, equalTo(true));
-        collector.checkThat("mMinDistanceCmSet", subscribeConfig.mMinDistanceMmSet, equalTo(false));
-        collector.checkThat("mMinDistanceMm", subscribeConfig.mMinDistanceMm, equalTo(0));
-        collector.checkThat("mMaxDistanceMmSet", subscribeConfig.mMaxDistanceMmSet, equalTo(false));
-        collector.checkThat("mMaxDistanceMm", subscribeConfig.mMaxDistanceMm, equalTo(0));
-    }
-
-    @Test
-    public void testSubscribeConfigBuilder() {
-        final String serviceName = "some_service_or_other";
-        final String serviceSpecificInfo = "long arbitrary string with some info";
-        final byte[] matchFilter = { 1, 16, 1, 22 };
-        final int subscribeType = SubscribeConfig.SUBSCRIBE_TYPE_PASSIVE;
-        final int subscribeTtl = 15;
-        final boolean enableTerminateNotification = false;
-        final int minDistance = 10;
-        final int maxDistance = 50;
-
-        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().setServiceName(serviceName)
-                .setServiceSpecificInfo(serviceSpecificInfo.getBytes()).setMatchFilter(
-                    new TlvBufferUtils.TlvIterable(0, 1, matchFilter).toList())
-                .setSubscribeType(subscribeType)
-                .setTtlSec(subscribeTtl)
-                .setTerminateNotificationEnabled(enableTerminateNotification)
-                .setMinDistanceMm(minDistance)
-                .setMaxDistanceMm(maxDistance).build();
-
-        collector.checkThat("mServiceName", serviceName.getBytes(),
-                equalTo(subscribeConfig.mServiceName));
-        collector.checkThat("mServiceSpecificInfo",
-                serviceSpecificInfo.getBytes(), equalTo(subscribeConfig.mServiceSpecificInfo));
-        collector.checkThat("mMatchFilter", matchFilter, equalTo(subscribeConfig.mMatchFilter));
-        collector.checkThat("mSubscribeType", subscribeType,
-                equalTo(subscribeConfig.mSubscribeType));
-        collector.checkThat("mTtlSec", subscribeTtl, equalTo(subscribeConfig.mTtlSec));
-        collector.checkThat("mEnableTerminateNotification", enableTerminateNotification,
-                equalTo(subscribeConfig.mEnableTerminateNotification));
-        collector.checkThat("mMinDistanceMmSet", true, equalTo(subscribeConfig.mMinDistanceMmSet));
-        collector.checkThat("mMinDistanceMm", minDistance, equalTo(subscribeConfig.mMinDistanceMm));
-        collector.checkThat("mMaxDistanceMmSet", true, equalTo(subscribeConfig.mMaxDistanceMmSet));
-        collector.checkThat("mMaxDistanceMm", maxDistance, equalTo(subscribeConfig.mMaxDistanceMm));
-    }
-
-    @Test
-    public void testSubscribeConfigParcel() {
-        final String serviceName = "some_service_or_other";
-        final String serviceSpecificInfo = "long arbitrary string with some info";
-        final byte[] matchFilter = { 1, 16, 1, 22 };
-        final int subscribeType = SubscribeConfig.SUBSCRIBE_TYPE_PASSIVE;
-        final int subscribeTtl = 15;
-        final boolean enableTerminateNotification = true;
-        final int minDistance = 10;
-        final int maxDistance = 50;
-
-        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().setServiceName(serviceName)
-                .setServiceSpecificInfo(serviceSpecificInfo.getBytes()).setMatchFilter(
-                        new TlvBufferUtils.TlvIterable(0, 1, matchFilter).toList())
-                .setSubscribeType(subscribeType)
-                .setTtlSec(subscribeTtl)
-                .setTerminateNotificationEnabled(enableTerminateNotification)
-                .setMinDistanceMm(minDistance)
-                .setMaxDistanceMm(maxDistance).build();
-
-        Parcel parcelW = Parcel.obtain();
-        subscribeConfig.writeToParcel(parcelW, 0);
-        byte[] bytes = parcelW.marshall();
-        parcelW.recycle();
-
-        Parcel parcelR = Parcel.obtain();
-        parcelR.unmarshall(bytes, 0, bytes.length);
-        parcelR.setDataPosition(0);
-        SubscribeConfig rereadSubscribeConfig = SubscribeConfig.CREATOR.createFromParcel(parcelR);
-
-        assertEquals(subscribeConfig, rereadSubscribeConfig);
-        assertEquals(subscribeConfig.hashCode(), rereadSubscribeConfig.hashCode());
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testSubscribeConfigBuilderBadSubscribeType() {
-        new SubscribeConfig.Builder().setSubscribeType(10);
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testSubscribeConfigBuilderNegativeTtl() {
-        new SubscribeConfig.Builder().setTtlSec(-100);
-    }
-
-    /*
-     * PublishConfig Tests
-     */
-
-    @Test
-    public void testPublishConfigBuilderDefaults() {
-        PublishConfig publishConfig = new PublishConfig.Builder().build();
-
-        collector.checkThat("mServiceName", publishConfig.mServiceName, equalTo(null));
-        collector.checkThat("mServiceSpecificInfo", publishConfig.mServiceSpecificInfo,
-                equalTo(null));
-        collector.checkThat("mMatchFilter", publishConfig.mMatchFilter, equalTo(null));
-        collector.checkThat("mPublishType", publishConfig.mPublishType,
-                equalTo(PublishConfig.PUBLISH_TYPE_UNSOLICITED));
-        collector.checkThat("mTtlSec", publishConfig.mTtlSec, equalTo(0));
-        collector.checkThat("mEnableTerminateNotification",
-                publishConfig.mEnableTerminateNotification, equalTo(true));
-        collector.checkThat("mEnableRanging", publishConfig.mEnableRanging, equalTo(false));
-    }
-
-    @Test
-    public void testPublishConfigBuilder() {
-        final String serviceName = "some_service_or_other";
-        final String serviceSpecificInfo = "long arbitrary string with some info";
-        final byte[] matchFilter = { 1, 16, 1, 22 };
-        final int publishType = PublishConfig.PUBLISH_TYPE_SOLICITED;
-        final int publishTtl = 15;
-        final boolean enableTerminateNotification = false;
-        final boolean enableRanging = true;
-
-        PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(serviceName)
-                .setServiceSpecificInfo(serviceSpecificInfo.getBytes()).setMatchFilter(
-                        new TlvBufferUtils.TlvIterable(0, 1, matchFilter).toList())
-                .setPublishType(publishType)
-                .setTtlSec(publishTtl)
-                .setTerminateNotificationEnabled(enableTerminateNotification)
-                .setRangingEnabled(enableRanging).build();
-
-        collector.checkThat("mServiceName", serviceName.getBytes(),
-                equalTo(publishConfig.mServiceName));
-        collector.checkThat("mServiceSpecificInfo",
-                serviceSpecificInfo.getBytes(), equalTo(publishConfig.mServiceSpecificInfo));
-        collector.checkThat("mMatchFilter", matchFilter, equalTo(publishConfig.mMatchFilter));
-        collector.checkThat("mPublishType", publishType, equalTo(publishConfig.mPublishType));
-        collector.checkThat("mTtlSec", publishTtl, equalTo(publishConfig.mTtlSec));
-        collector.checkThat("mEnableTerminateNotification", enableTerminateNotification,
-                equalTo(publishConfig.mEnableTerminateNotification));
-        collector.checkThat("mEnableRanging", enableRanging, equalTo(publishConfig.mEnableRanging));
-    }
-
-    @Test
-    public void testPublishConfigParcel() {
-        final String serviceName = "some_service_or_other";
-        final String serviceSpecificInfo = "long arbitrary string with some info";
-        final byte[] matchFilter = { 1, 16, 1, 22 };
-        final int publishType = PublishConfig.PUBLISH_TYPE_SOLICITED;
-        final int publishTtl = 15;
-        final boolean enableTerminateNotification = false;
-        final boolean enableRanging = true;
-
-        PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(serviceName)
-                .setServiceSpecificInfo(serviceSpecificInfo.getBytes()).setMatchFilter(
-                        new TlvBufferUtils.TlvIterable(0, 1, matchFilter).toList())
-                .setPublishType(publishType)
-                .setTtlSec(publishTtl)
-                .setTerminateNotificationEnabled(enableTerminateNotification)
-                .setRangingEnabled(enableRanging).build();
-
-        Parcel parcelW = Parcel.obtain();
-        publishConfig.writeToParcel(parcelW, 0);
-        byte[] bytes = parcelW.marshall();
-        parcelW.recycle();
-
-        Parcel parcelR = Parcel.obtain();
-        parcelR.unmarshall(bytes, 0, bytes.length);
-        parcelR.setDataPosition(0);
-        PublishConfig rereadPublishConfig = PublishConfig.CREATOR.createFromParcel(parcelR);
-
-        assertEquals(publishConfig, rereadPublishConfig);
-        assertEquals(publishConfig.hashCode(), rereadPublishConfig.hashCode());
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testPublishConfigBuilderBadPublishType() {
-        new PublishConfig.Builder().setPublishType(5);
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testPublishConfigBuilderNegativeTtl() {
-        new PublishConfig.Builder().setTtlSec(-10);
-    }
-
-    /*
-     * Data-path tests
-     */
-
-    /**
-     * Validate that correct network specifier is generated for client-based data-path.
-     */
-    @Test
-    public void testNetworkSpecifierWithClient() throws Exception {
-        final int clientId = 4565;
-        final int sessionId = 123;
-        final PeerHandle peerHandle = new PeerHandle(123412);
-        final byte[] pmk = PMK_VALID;
-        final String passphrase = PASSPHRASE_VALID;
-        final int port = 5;
-        final int transportProtocol = 10;
-        final ConfigRequest configRequest = new ConfigRequest.Builder().build();
-        final PublishConfig publishConfig = new PublishConfig.Builder().build();
-
-        mockApplicationInfo.targetSdkVersion = Build.VERSION_CODES.P;
-
-        ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
-                WifiAwareSession.class);
-        ArgumentCaptor<IWifiAwareEventCallback> clientProxyCallback = ArgumentCaptor
-                .forClass(IWifiAwareEventCallback.class);
-        ArgumentCaptor<IWifiAwareDiscoverySessionCallback> sessionProxyCallback = ArgumentCaptor
-                .forClass(IWifiAwareDiscoverySessionCallback.class);
-        ArgumentCaptor<PublishDiscoverySession> publishSession = ArgumentCaptor
-                .forClass(PublishDiscoverySession.class);
-
-        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockAwareService,
-                mockPublishSession, mockRttListener);
-
-        // (1) connect successfully
-        mDut.attach(mMockLooperHandler, configRequest, mockCallback, null);
-        inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(),
-                eq(configRequest), eq(false));
-        clientProxyCallback.getValue().onConnectSuccess(clientId);
-        mMockLooper.dispatchAll();
-        inOrder.verify(mockCallback).onAttached(sessionCaptor.capture());
-        WifiAwareSession session = sessionCaptor.getValue();
-
-        // (2) publish successfully
-        session.publish(publishConfig, mockSessionCallback, mMockLooperHandler);
-        inOrder.verify(mockAwareService).publish(any(), any(), eq(clientId), eq(publishConfig),
-                sessionProxyCallback.capture());
-        sessionProxyCallback.getValue().onSessionStarted(sessionId);
-        mMockLooper.dispatchAll();
-        inOrder.verify(mockSessionCallback).onPublishStarted(publishSession.capture());
-
-        // (3) request an open (unencrypted) network specifier from the session
-        WifiAwareNetworkSpecifier ns =
-                (WifiAwareNetworkSpecifier) publishSession.getValue().createNetworkSpecifierOpen(
-                        peerHandle);
-        WifiAwareNetworkSpecifier nsb = new WifiAwareNetworkSpecifier.Builder(
-                publishSession.getValue(), peerHandle).build();
-
-        // validate format
-        collector.checkThat("role", WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER,
-                equalTo(ns.role));
-        collector.checkThat("client_id", clientId, equalTo(ns.clientId));
-        collector.checkThat("session_id", sessionId, equalTo(ns.sessionId));
-        collector.checkThat("peer_id", peerHandle.peerId, equalTo(ns.peerId));
-
-        collector.checkThat("role", WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER,
-                equalTo(nsb.role));
-        collector.checkThat("client_id", clientId, equalTo(nsb.clientId));
-        collector.checkThat("session_id", sessionId, equalTo(nsb.sessionId));
-        collector.checkThat("peer_id", peerHandle.peerId, equalTo(nsb.peerId));
-        collector.checkThat("port", 0, equalTo(nsb.port));
-        collector.checkThat("transportProtocol", -1, equalTo(nsb.transportProtocol));
-
-        // (4) request an encrypted (PMK) network specifier from the session
-        ns = (WifiAwareNetworkSpecifier) publishSession.getValue().createNetworkSpecifierPmk(
-                peerHandle, pmk);
-        nsb = new WifiAwareNetworkSpecifier.Builder(publishSession.getValue(), peerHandle).setPmk(
-                pmk).setPort(port).setTransportProtocol(transportProtocol).build();
-
-        // validate format
-        collector.checkThat("role", WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER,
-                equalTo(ns.role));
-        collector.checkThat("client_id", clientId, equalTo(ns.clientId));
-        collector.checkThat("session_id", sessionId, equalTo(ns.sessionId));
-        collector.checkThat("peer_id", peerHandle.peerId, equalTo(ns.peerId));
-        collector.checkThat("pmk", pmk , equalTo(ns.pmk));
-
-        collector.checkThat("role", WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER,
-                equalTo(nsb.role));
-        collector.checkThat("client_id", clientId, equalTo(nsb.clientId));
-        collector.checkThat("session_id", sessionId, equalTo(nsb.sessionId));
-        collector.checkThat("peer_id", peerHandle.peerId, equalTo(nsb.peerId));
-        collector.checkThat("pmk", pmk , equalTo(nsb.pmk));
-        collector.checkThat("port", port, equalTo(nsb.port));
-        collector.checkThat("transportProtocol", transportProtocol, equalTo(nsb.transportProtocol));
-
-        // (5) request an encrypted (Passphrase) network specifier from the session
-        ns =
-                (WifiAwareNetworkSpecifier) publishSession.getValue()
-                        .createNetworkSpecifierPassphrase(
-                        peerHandle, passphrase);
-        nsb = new WifiAwareNetworkSpecifier.Builder(publishSession.getValue(),
-                peerHandle).setPskPassphrase(passphrase).setPort(port).setTransportProtocol(
-                transportProtocol).build();
-
-        // validate format
-        collector.checkThat("role", WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER,
-                equalTo(ns.role));
-        collector.checkThat("client_id", clientId, equalTo(ns.clientId));
-        collector.checkThat("session_id", sessionId, equalTo(ns.sessionId));
-        collector.checkThat("peer_id", peerHandle.peerId, equalTo(ns.peerId));
-        collector.checkThat("passphrase", passphrase, equalTo(ns.passphrase));
-
-        collector.checkThat("role", WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER,
-                equalTo(nsb.role));
-        collector.checkThat("client_id", clientId, equalTo(nsb.clientId));
-        collector.checkThat("session_id", sessionId, equalTo(nsb.sessionId));
-        collector.checkThat("peer_id", peerHandle.peerId, equalTo(nsb.peerId));
-        collector.checkThat("passphrase", passphrase, equalTo(nsb.passphrase));
-        collector.checkThat("port", port, equalTo(nsb.port));
-        collector.checkThat("transportProtocol", transportProtocol, equalTo(nsb.transportProtocol));
-
-        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService,
-                mockPublishSession, mockRttListener);
-    }
-
-    /**
-     * Validate that correct network specifier is generated for a direct data-path (i.e.
-     * specifying MAC address as opposed to a client-based oqaque specification).
-     */
-    @Test
-    public void testNetworkSpecifierDirect() throws Exception {
-        final int clientId = 134;
-        final ConfigRequest configRequest = new ConfigRequest.Builder().build();
-        final byte[] someMac = HexEncoding.decode("000102030405".toCharArray(), false);
-        final int role = WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR;
-        final byte[] pmk = PMK_VALID;
-        final String passphrase = PASSPHRASE_VALID;
-
-        ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
-                WifiAwareSession.class);
-        ArgumentCaptor<IWifiAwareEventCallback> clientProxyCallback = ArgumentCaptor
-                .forClass(IWifiAwareEventCallback.class);
-
-        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockAwareService,
-                mockPublishSession, mockRttListener);
-
-        // (1) connect successfully
-        mDut.attach(mMockLooperHandler, configRequest, mockCallback, null);
-        inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(),
-                eq(configRequest), eq(false));
-        clientProxyCallback.getValue().onConnectSuccess(clientId);
-        mMockLooper.dispatchAll();
-        inOrder.verify(mockCallback).onAttached(sessionCaptor.capture());
-        WifiAwareSession session = sessionCaptor.getValue();
-
-        // (2) request an open (unencrypted) direct network specifier
-        WifiAwareNetworkSpecifier ns =
-                (WifiAwareNetworkSpecifier) session.createNetworkSpecifierOpen(role, someMac);
-
-        // validate format
-        collector.checkThat("role", role, equalTo(ns.role));
-        collector.checkThat("client_id", clientId, equalTo(ns.clientId));
-        collector.checkThat("peer_mac", someMac, equalTo(ns.peerMac));
-
-        // (3) request an encrypted (PMK) direct network specifier
-        ns = (WifiAwareNetworkSpecifier) session.createNetworkSpecifierPmk(role, someMac, pmk);
-
-        // validate format
-        collector.checkThat("role", role, equalTo(ns.role));
-        collector.checkThat("client_id", clientId, equalTo(ns.clientId));
-        collector.checkThat("peer_mac", someMac, equalTo(ns.peerMac));
-        collector.checkThat("pmk", pmk, equalTo(ns.pmk));
-
-        // (4) request an encrypted (Passphrase) direct network specifier
-        ns = (WifiAwareNetworkSpecifier) session.createNetworkSpecifierPassphrase(role, someMac,
-                passphrase);
-
-        // validate format
-        collector.checkThat("role", role, equalTo(ns.role));
-        collector.checkThat("client_id", clientId, equalTo(ns.clientId));
-        collector.checkThat("peer_mac", someMac, equalTo(ns.peerMac));
-        collector.checkThat("passphrase", passphrase, equalTo(ns.passphrase));
-
-        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService,
-                mockPublishSession, mockRttListener);
-    }
-
-    /**
-     * Validate that a null PMK triggers an exception.
-     */
-    @Test(expected = IllegalArgumentException.class)
-    public void testNetworkSpecifierWithClientNullPmk() throws Exception {
-        executeNetworkSpecifierWithClient(new PeerHandle(123412), true, null, null, false);
-    }
-
-    /**
-     * Validate that a non-32-bytes PMK triggers an exception.
-     */
-    @Test(expected = IllegalArgumentException.class)
-    public void testNetworkSpecifierWithClientIncorrectLengthPmk() throws Exception {
-        executeNetworkSpecifierWithClient(new PeerHandle(123412), true, PMK_INVALID, null, false);
-    }
-
-    /**
-     * Validate that a null Passphrase triggers an exception.
-     */
-    @Test(expected = IllegalArgumentException.class)
-    public void testNetworkSpecifierWithClientNullPassphrase() throws Exception {
-        executeNetworkSpecifierWithClient(new PeerHandle(123412), false, null, null, false);
-    }
-
-    /**
-     * Validate that a too short Passphrase triggers an exception.
-     */
-    @Test(expected = IllegalArgumentException.class)
-    public void testNetworkSpecifierWithClientTooShortPassphrase() throws Exception {
-        executeNetworkSpecifierWithClient(new PeerHandle(123412), false, null,
-                PASSPHRASE_TOO_SHORT, false);
-    }
-
-    /**
-     * Validate that a too long Passphrase triggers an exception.
-     */
-    @Test(expected = IllegalArgumentException.class)
-    public void testNetworkSpecifierWithClientTooLongPassphrase() throws Exception {
-        executeNetworkSpecifierWithClient(new PeerHandle(123412), false, null, PASSPHRASE_TOO_LONG,
-                false);
-    }
-
-    /**
-     * Validate that a null PeerHandle triggers an exception.
-     */
-    @Test(expected = IllegalArgumentException.class)
-    public void testNetworkSpecifierWithClientNullPeer() throws Exception {
-        mockApplicationInfo.targetSdkVersion = Build.VERSION_CODES.P;
-        executeNetworkSpecifierWithClient(null, false, null, PASSPHRASE_VALID, false);
-    }
-
-    /**
-     * Validate that a null PeerHandle does not trigger an exception for legacy API.
-     */
-    @Test
-    public void testNetworkSpecifierWithClientNullPeerLegacyApi() throws Exception {
-        mockApplicationInfo.targetSdkVersion = Build.VERSION_CODES.O;
-        executeNetworkSpecifierWithClient(null, false, null, PASSPHRASE_VALID, false);
-    }
-
-    /**
-     * Validate that a null PMK triggers an exception.
-     */
-    @Test(expected = IllegalArgumentException.class)
-    public void testNetworkSpecifierWithClientNullPmkBuilder() throws Exception {
-        executeNetworkSpecifierWithClient(new PeerHandle(123412), true, null, null, true);
-    }
-
-    /**
-     * Validate that a non-32-bytes PMK triggers an exception.
-     */
-    @Test(expected = IllegalArgumentException.class)
-    public void testNetworkSpecifierWithClientIncorrectLengthPmkBuilder() throws Exception {
-        executeNetworkSpecifierWithClient(new PeerHandle(123412), true, PMK_INVALID, null, true);
-    }
-
-    /**
-     * Validate that a null Passphrase triggers an exception.
-     */
-    @Test(expected = IllegalArgumentException.class)
-    public void testNetworkSpecifierWithClientNullPassphraseBuilder() throws Exception {
-        executeNetworkSpecifierWithClient(new PeerHandle(123412), false, null, null, true);
-    }
-
-    /**
-     * Validate that a too short Passphrase triggers an exception.
-     */
-    @Test(expected = IllegalArgumentException.class)
-    public void testNetworkSpecifierWithClientTooShortPassphraseBuilder() throws Exception {
-        executeNetworkSpecifierWithClient(new PeerHandle(123412), false, null,
-                PASSPHRASE_TOO_SHORT, true);
-    }
-
-    /**
-     * Validate that a too long Passphrase triggers an exception.
-     */
-    @Test(expected = IllegalArgumentException.class)
-    public void testNetworkSpecifierWithClientTooLongPassphraseBuilder() throws Exception {
-        executeNetworkSpecifierWithClient(new PeerHandle(123412), false, null, PASSPHRASE_TOO_LONG,
-                true);
-    }
-
-    /**
-     * Validate that a null PeerHandle triggers an exception.
-     */
-    @Test(expected = IllegalArgumentException.class)
-    public void testNetworkSpecifierWithClientNullPeerBuilder() throws Exception {
-        executeNetworkSpecifierWithClient(null, false, null, PASSPHRASE_VALID, true);
-    }
-
-    /**
-     * Validate that a null PeerHandle does not trigger an exception for legacy API.
-     */
-    @Test
-    public void testNetworkSpecifierWithClientNullPeerLegacyApiBuilder() throws Exception {
-        mockApplicationInfo.targetSdkVersion = Build.VERSION_CODES.O;
-        executeNetworkSpecifierWithClient(null, false, null, PASSPHRASE_VALID, false);
-    }
-
-    @Test(expected = UnsupportedOperationException.class)
-    public void testNetworkSpecifierDeprecatedOnNewApi() throws Exception {
-        executeNetworkSpecifierWithClient(null, false, null, PASSPHRASE_VALID, false);
-    }
-
-    private void executeNetworkSpecifierWithClient(PeerHandle peerHandle, boolean doPmk, byte[] pmk,
-            String passphrase, boolean useBuilder) throws Exception {
-        final int clientId = 4565;
-        final int sessionId = 123;
-        final ConfigRequest configRequest = new ConfigRequest.Builder().build();
-        final PublishConfig publishConfig = new PublishConfig.Builder().build();
-
-        ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
-                WifiAwareSession.class);
-        ArgumentCaptor<IWifiAwareEventCallback> clientProxyCallback = ArgumentCaptor
-                .forClass(IWifiAwareEventCallback.class);
-        ArgumentCaptor<IWifiAwareDiscoverySessionCallback> sessionProxyCallback = ArgumentCaptor
-                .forClass(IWifiAwareDiscoverySessionCallback.class);
-        ArgumentCaptor<PublishDiscoverySession> publishSession = ArgumentCaptor
-                .forClass(PublishDiscoverySession.class);
-
-        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockAwareService,
-                mockPublishSession, mockRttListener);
-
-        // (1) connect successfully
-        mDut.attach(mMockLooperHandler, configRequest, mockCallback, null);
-        inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(),
-                eq(configRequest), eq(false));
-        clientProxyCallback.getValue().onConnectSuccess(clientId);
-        mMockLooper.dispatchAll();
-        inOrder.verify(mockCallback).onAttached(sessionCaptor.capture());
-        WifiAwareSession session = sessionCaptor.getValue();
-
-        // (2) publish successfully
-        session.publish(publishConfig, mockSessionCallback, mMockLooperHandler);
-        inOrder.verify(mockAwareService).publish(any(), any(), eq(clientId), eq(publishConfig),
-                sessionProxyCallback.capture());
-        sessionProxyCallback.getValue().onSessionStarted(sessionId);
-        mMockLooper.dispatchAll();
-        inOrder.verify(mockSessionCallback).onPublishStarted(publishSession.capture());
-
-        // (3) create network specifier
-        if (doPmk) {
-            if (useBuilder) {
-                new WifiAwareNetworkSpecifier.Builder(publishSession.getValue(), peerHandle).setPmk(
-                        pmk).build();
-            } else {
-                publishSession.getValue().createNetworkSpecifierPmk(peerHandle, pmk);
-            }
-        } else {
-            if (useBuilder) {
-                new WifiAwareNetworkSpecifier.Builder(publishSession.getValue(),
-                        peerHandle).setPskPassphrase(passphrase).build();
-            } else {
-                publishSession.getValue().createNetworkSpecifierPassphrase(peerHandle, passphrase);
-            }
-        }
-    }
-
-    /**
-     * Validate that a null PMK triggers an exception.
-     */
-    @Test(expected = IllegalArgumentException.class)
-    public void testNetworkSpecifierDirectNullPmk() throws Exception {
-        executeNetworkSpecifierDirect(HexEncoding.decode("000102030405".toCharArray(), false), true,
-                null, null, true);
-    }
-
-    /**
-     * Validate that a non-32-bytes PMK triggers an exception.
-     */
-    @Test(expected = IllegalArgumentException.class)
-    public void testNetworkSpecifierDirectIncorrectLengthPmk() throws Exception {
-        executeNetworkSpecifierDirect(HexEncoding.decode("000102030405".toCharArray(), false), true,
-                PMK_INVALID, null, true);
-    }
-
-    /**
-     * Validate that a null Passphrase triggers an exception.
-     */
-    @Test(expected = IllegalArgumentException.class)
-    public void testNetworkSpecifierDirectNullPassphrase() throws Exception {
-        executeNetworkSpecifierDirect(HexEncoding.decode("000102030405".toCharArray(), false),
-                false, null, null, true);
-    }
-
-    /**
-     * Validate that a too short Passphrase triggers an exception.
-     */
-    @Test(expected = IllegalArgumentException.class)
-    public void testNetworkSpecifierDirectTooShortPassphrase() throws Exception {
-        executeNetworkSpecifierDirect(HexEncoding.decode("000102030405".toCharArray(), false),
-                false, null, PASSPHRASE_TOO_SHORT, true);
-    }
-
-    /**
-     * Validate that a too long Passphrase triggers an exception.
-     */
-    @Test(expected = IllegalArgumentException.class)
-    public void testNetworkSpecifierDirectTooLongPassphrase() throws Exception {
-        executeNetworkSpecifierDirect(HexEncoding.decode("000102030405".toCharArray(), false),
-                false, null, PASSPHRASE_TOO_LONG, true);
-    }
-
-    /**
-     * Validate that a null peer MAC triggers an exception for an Initiator.
-     */
-    @Test(expected = IllegalArgumentException.class)
-    public void testNetworkSpecifierDirectNullPeerInitiator() throws Exception {
-        executeNetworkSpecifierDirect(null, false, null, PASSPHRASE_VALID, true);
-    }
-
-    /**
-     * Validate that a null peer MAC triggers an exception for a Resonder.
-     */
-    @Test(expected = IllegalArgumentException.class)
-    public void testNetworkSpecifierDirectNullPeerResponder() throws Exception {
-        executeNetworkSpecifierDirect(null, false, null, PASSPHRASE_VALID, false);
-    }
-
-    /**
-     * Validate that a null peer MAC does not trigger an exception for a Resonder on legacy API.
-     */
-    @Test
-    public void testNetworkSpecifierDirectNullPeerResponderLegacyApi() throws Exception {
-        mockApplicationInfo.targetSdkVersion = Build.VERSION_CODES.O;
-        executeNetworkSpecifierDirect(null, false, null, PASSPHRASE_VALID, false);
-    }
-
-    /**
-     * Validate that get an exception when creating a network specifier with an invalid port number
-     * (<=0).
-     */
-    @Test(expected = IllegalArgumentException.class)
-    public void testNetworkSpecifierBuilderInvalidPortNumber() throws Exception {
-        final PeerHandle peerHandle = new PeerHandle(123412);
-        final byte[] pmk = PMK_VALID;
-        final int port = 0;
-
-        DiscoverySession publishSession = executeSessionStartup(true);
-
-        WifiAwareNetworkSpecifier nsb = new WifiAwareNetworkSpecifier.Builder(publishSession,
-                peerHandle).setPmk(pmk).setPort(port).build();
-    }
-
-    /**
-     * Validate that get an exception when creating a network specifier with port information
-     * without also requesting a secure link.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testNetworkSpecifierBuilderInvalidPortOnInsecure() throws Exception {
-        final PeerHandle peerHandle = new PeerHandle(123412);
-        final int port = 5;
-
-        DiscoverySession publishSession = executeSessionStartup(true);
-
-        WifiAwareNetworkSpecifier nsb = new WifiAwareNetworkSpecifier.Builder(publishSession,
-                peerHandle).setPort(port).build();
-    }
-
-    /**
-     * Validate that get an exception when creating a network specifier with port information on
-     * a responder.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testNetworkSpecifierBuilderInvalidPortOnResponder() throws Exception {
-        final PeerHandle peerHandle = new PeerHandle(123412);
-        final int port = 5;
-
-        DiscoverySession subscribeSession = executeSessionStartup(false);
-
-        WifiAwareNetworkSpecifier nsb = new WifiAwareNetworkSpecifier.Builder(subscribeSession,
-                peerHandle).setPort(port).build();
-    }
-
-    /**
-     * Validate that get an exception when creating a network specifier with an invalid transport
-     * protocol number (not in [0, 255]).
-     */
-    @Test
-    public void testNetworkSpecifierBuilderInvalidTransportProtocolNumber() throws Exception {
-        final PeerHandle peerHandle = new PeerHandle(123412);
-        final byte[] pmk = PMK_VALID;
-        final int tpNegative = -1;
-        final int tpTooLarge = 256;
-        final int tpSmallest = 0;
-        final int tpLargest = 255;
-
-        DiscoverySession publishSession = executeSessionStartup(true);
-
-        try {
-            WifiAwareNetworkSpecifier nsb = new WifiAwareNetworkSpecifier.Builder(publishSession,
-                    peerHandle).setPmk(pmk).setTransportProtocol(tpNegative).build();
-            assertTrue("No exception on negative transport protocol!", false);
-        } catch (IllegalArgumentException e) {
-            // nop - exception is correct!
-        }
-        try {
-            WifiAwareNetworkSpecifier nsb = new WifiAwareNetworkSpecifier.Builder(publishSession,
-                    peerHandle).setPmk(pmk).setTransportProtocol(tpTooLarge).build();
-            assertTrue("No exception on >255 transport protocol!", false);
-        } catch (IllegalArgumentException e) {
-            // nop - exception is correct!
-        }
-        WifiAwareNetworkSpecifier nsb = new WifiAwareNetworkSpecifier.Builder(publishSession,
-                peerHandle).setPmk(pmk).setTransportProtocol(tpSmallest).build();
-        nsb = new WifiAwareNetworkSpecifier.Builder(publishSession, peerHandle).setPmk(
-                pmk).setTransportProtocol(tpLargest).build();
-    }
-
-    /**
-     * Validate that get an exception when creating a network specifier with transport protocol
-     * information without also requesting a secure link.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testNetworkSpecifierBuilderInvalidTransportProtocolOnInsecure() throws Exception {
-        final PeerHandle peerHandle = new PeerHandle(123412);
-        final int transportProtocol = 5;
-
-        DiscoverySession publishSession = executeSessionStartup(true);
-
-        WifiAwareNetworkSpecifier nsb = new WifiAwareNetworkSpecifier.Builder(publishSession,
-                peerHandle).setTransportProtocol(transportProtocol).build();
-    }
-
-    /**
-     * Validate that get an exception when creating a network specifier with transport protocol
-     * information on a responder.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testNetworkSpecifierBuilderInvalidTransportProtocolOnResponder() throws Exception {
-        final PeerHandle peerHandle = new PeerHandle(123412);
-        final int transportProtocol = 5;
-
-        DiscoverySession subscribeSession = executeSessionStartup(false);
-
-        WifiAwareNetworkSpecifier nsb = new WifiAwareNetworkSpecifier.Builder(subscribeSession,
-                peerHandle).setTransportProtocol(transportProtocol).build();
-    }
-
-    /*
-     * Utilities
-     */
-
-    private void executeNetworkSpecifierDirect(byte[] someMac, boolean doPmk, byte[] pmk,
-            String passphrase, boolean doInitiator) throws Exception {
-        final int clientId = 134;
-        final int role = doInitiator ? WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR
-                : WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER;
-        final ConfigRequest configRequest = new ConfigRequest.Builder().build();
-
-        ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
-                WifiAwareSession.class);
-        ArgumentCaptor<IWifiAwareEventCallback> clientProxyCallback = ArgumentCaptor
-                .forClass(IWifiAwareEventCallback.class);
-
-        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockAwareService,
-                mockPublishSession, mockRttListener);
-
-        // (1) connect successfully
-        mDut.attach(mMockLooperHandler, configRequest, mockCallback, null);
-        inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(),
-                eq(configRequest), eq(false));
-        clientProxyCallback.getValue().onConnectSuccess(clientId);
-        mMockLooper.dispatchAll();
-        inOrder.verify(mockCallback).onAttached(sessionCaptor.capture());
-
-        // (2) create network specifier
-        if (doPmk) {
-            sessionCaptor.getValue().createNetworkSpecifierPmk(role, someMac, pmk);
-        } else {
-            sessionCaptor.getValue().createNetworkSpecifierPassphrase(role, someMac, passphrase);
-        }
-    }
-
-    private DiscoverySession executeSessionStartup(boolean isPublish) throws Exception {
-        final int clientId = 4565;
-        final int sessionId = 123;
-        final PeerHandle peerHandle = new PeerHandle(123412);
-        final int port = 5;
-        final ConfigRequest configRequest = new ConfigRequest.Builder().build();
-        final SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
-        final PublishConfig publishConfig = new PublishConfig.Builder().build();
-
-        ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
-                WifiAwareSession.class);
-        ArgumentCaptor<IWifiAwareEventCallback> clientProxyCallback = ArgumentCaptor
-                .forClass(IWifiAwareEventCallback.class);
-        ArgumentCaptor<IWifiAwareDiscoverySessionCallback> sessionProxyCallback = ArgumentCaptor
-                .forClass(IWifiAwareDiscoverySessionCallback.class);
-        ArgumentCaptor<PublishDiscoverySession> publishSession = ArgumentCaptor
-                .forClass(PublishDiscoverySession.class);
-        ArgumentCaptor<SubscribeDiscoverySession> subscribeSession = ArgumentCaptor
-                .forClass(SubscribeDiscoverySession.class);
-
-
-        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockAwareService,
-                mockPublishSession, mockRttListener);
-
-        // (1) connect successfully
-        mDut.attach(mMockLooperHandler, configRequest, mockCallback, null);
-        inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(),
-                eq(configRequest), eq(false));
-        clientProxyCallback.getValue().onConnectSuccess(clientId);
-        mMockLooper.dispatchAll();
-        inOrder.verify(mockCallback).onAttached(sessionCaptor.capture());
-        WifiAwareSession session = sessionCaptor.getValue();
-
-        if (isPublish) {
-            // (2) publish successfully
-            session.publish(publishConfig, mockSessionCallback, mMockLooperHandler);
-            inOrder.verify(mockAwareService).publish(any(), any(), eq(clientId), eq(publishConfig),
-                    sessionProxyCallback.capture());
-            sessionProxyCallback.getValue().onSessionStarted(sessionId);
-            mMockLooper.dispatchAll();
-            inOrder.verify(mockSessionCallback).onPublishStarted(publishSession.capture());
-            return publishSession.getValue();
-        } else {
-            // (2) subscribe successfully
-            session.subscribe(subscribeConfig, mockSessionCallback, mMockLooperHandler);
-            inOrder.verify(mockAwareService).subscribe(any(), any(), eq(clientId),
-                    eq(subscribeConfig), sessionProxyCallback.capture());
-            sessionProxyCallback.getValue().onSessionStarted(sessionId);
-            mMockLooper.dispatchAll();
-            inOrder.verify(mockSessionCallback).onSubscribeStarted(subscribeSession.capture());
-            return subscribeSession.getValue();
-        }
-    }
-
-    // WifiAwareNetworkSpecifier && WifiAwareNetworkInfo tests
-
-    @Test
-    public void testWifiAwareNetworkSpecifierParcel() {
-        WifiAwareNetworkSpecifier ns = new WifiAwareNetworkSpecifier(NETWORK_SPECIFIER_TYPE_IB,
-                WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER, 5, 568, 334,
-                HexEncoding.decode("000102030405".toCharArray(), false),
-                "01234567890123456789012345678901".getBytes(), "blah blah", 666, 4);
-
-        Parcel parcelW = Parcel.obtain();
-        ns.writeToParcel(parcelW, 0);
-        byte[] bytes = parcelW.marshall();
-        parcelW.recycle();
-
-        Parcel parcelR = Parcel.obtain();
-        parcelR.unmarshall(bytes, 0, bytes.length);
-        parcelR.setDataPosition(0);
-        WifiAwareNetworkSpecifier rereadNs =
-                WifiAwareNetworkSpecifier.CREATOR.createFromParcel(parcelR);
-
-        assertEquals(ns, rereadNs);
-        assertEquals(ns.hashCode(), rereadNs.hashCode());
-    }
-
-    @Test
-    public void testWifiAwareNetworkCapabilitiesParcel() throws UnknownHostException {
-        final Inet6Address inet6 = MacAddress.fromString(
-                "11:22:33:44:55:66").getLinkLocalIpv6FromEui48Mac();
-        // note: dummy scope = 5
-        final Inet6Address inet6Scoped = Inet6Address.getByAddress(null, inet6.getAddress(), 5);
-        final int port = 5;
-        final int transportProtocol = 6;
-
-        assertEquals(inet6Scoped.toString(), "/fe80::1322:33ff:fe44:5566%5");
-        WifiAwareNetworkInfo cap = new WifiAwareNetworkInfo(inet6Scoped, port, transportProtocol);
-
-        Parcel parcelW = Parcel.obtain();
-        cap.writeToParcel(parcelW, 0);
-        byte[] bytes = parcelW.marshall();
-        parcelW.recycle();
-
-        Parcel parcelR = Parcel.obtain();
-        parcelR.unmarshall(bytes, 0, bytes.length);
-        parcelR.setDataPosition(0);
-        WifiAwareNetworkInfo rereadCap =
-                WifiAwareNetworkInfo.CREATOR.createFromParcel(parcelR);
-
-        assertEquals(cap.getPeerIpv6Addr().toString(), "/fe80::1322:33ff:fe44:5566%5");
-        assertEquals(cap, rereadCap);
-        assertEquals(cap.hashCode(), rereadCap.hashCode());
-    }
-
-    // ParcelablePeerHandle tests
-
-    /**
-     * Verify parceling of ParcelablePeerHandle and interoperability with PeerHandle.
-     */
-    @Test
-    public void testParcelablePeerHandleParcel() {
-        final PeerHandle peerHandle = new PeerHandle(5);
-        final ParcelablePeerHandle parcelablePeerHandle = new ParcelablePeerHandle(peerHandle);
-
-        Parcel parcelW = Parcel.obtain();
-        parcelablePeerHandle.writeToParcel(parcelW, 0);
-        byte[] bytes = parcelW.marshall();
-        parcelW.recycle();
-
-        Parcel parcelR = Parcel.obtain();
-        parcelR.unmarshall(bytes, 0, bytes.length);
-        parcelR.setDataPosition(0);
-        ParcelablePeerHandle rereadParcelablePeerHandle =
-                ParcelablePeerHandle.CREATOR.createFromParcel(parcelR);
-
-        assertEquals(peerHandle, rereadParcelablePeerHandle);
-        assertEquals(peerHandle.hashCode(), rereadParcelablePeerHandle.hashCode());
-        assertEquals(parcelablePeerHandle, rereadParcelablePeerHandle);
-        assertEquals(parcelablePeerHandle.hashCode(), rereadParcelablePeerHandle.hashCode());
-
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/ConfigParserTest.java b/wifi/tests/src/android/net/wifi/hotspot2/ConfigParserTest.java
deleted file mode 100644
index 439e672..0000000
--- a/wifi/tests/src/android/net/wifi/hotspot2/ConfigParserTest.java
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package android.net.wifi.hotspot2;
-
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import android.net.wifi.FakeKeys;
-import android.net.wifi.hotspot2.pps.Credential;
-import android.net.wifi.hotspot2.pps.HomeSp;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.util.Arrays;
-
-/**
- * Unit tests for {@link android.net.wifi.hotspot2.ConfigParser}.
- */
-@SmallTest
-public class ConfigParserTest {
-    /**
-     * Hotspot 2.0 Release 1 installation file that contains a Passpoint profile and a
-     * CA (Certificate Authority) X.509 certificate {@link FakeKeys#CA_CERT0}.
-     */
-    private static final String PASSPOINT_INSTALLATION_FILE_WITH_CA_CERT =
-            "assets/hsr1/HSR1ProfileWithCACert.base64";
-    private static final String PASSPOINT_INSTALLATION_FILE_WITH_UNENCODED_DATA =
-            "assets/hsr1/HSR1ProfileWithCACert.conf";
-    private static final String PASSPOINT_INSTALLATION_FILE_WITH_INVALID_PART =
-            "assets/hsr1/HSR1ProfileWithNonBase64Part.base64";
-    private static final String PASSPOINT_INSTALLATION_FILE_WITH_MISSING_BOUNDARY =
-            "assets/hsr1/HSR1ProfileWithMissingBoundary.base64";
-    private static final String PASSPOINT_INSTALLATION_FILE_WITH_INVALID_CONTENT_TYPE =
-            "assets/hsr1/HSR1ProfileWithInvalidContentType.base64";
-    private static final String PASSPOINT_INSTALLATION_FILE_WITHOUT_PROFILE =
-            "assets/hsr1/HSR1ProfileWithoutProfile.base64";
-    private static final String PASSPOINT_INSTALLATION_FILE_WITH_UPDATE_ID =
-            "assets/hsr1/HSR1ProfileWithUpdateIdentifier.base64";
-
-    /**
-     * Read the content of the given resource file into a String.
-     *
-     * @param filename String name of the file
-     * @return String
-     * @throws IOException
-     */
-    private String loadResourceFile(String filename) throws IOException {
-        InputStream in = getClass().getClassLoader().getResourceAsStream(filename);
-        BufferedReader reader = new BufferedReader(new InputStreamReader(in));
-        StringBuilder builder = new StringBuilder();
-        String line;
-        while ((line = reader.readLine()) != null) {
-            builder.append(line).append("\n");
-        }
-
-        return builder.toString();
-    }
-
-    /**
-     * Generate a {@link PasspointConfiguration} that matches the configuration specified in the
-     * XML file {@link #PASSPOINT_INSTALLATION_FILE_WITH_CA_CERT}.
-     *
-     * @return {@link PasspointConfiguration}
-     */
-    private PasspointConfiguration generateConfigurationFromProfile() {
-        PasspointConfiguration config = new PasspointConfiguration();
-
-        // HomeSP configuration.
-        HomeSp homeSp = new HomeSp();
-        homeSp.setFriendlyName("Example Network");
-        homeSp.setFqdn("hotspot.example.net");
-        homeSp.setRoamingConsortiumOis(new long[] {0x112233L, 0x445566L});
-        config.setHomeSp(homeSp);
-
-        // Credential configuration.
-        Credential credential = new Credential();
-        credential.setRealm("example.com");
-        Credential.UserCredential userCredential = new Credential.UserCredential();
-        userCredential.setUsername("user");
-        userCredential.setPassword("cGFzc3dvcmQ=");
-        userCredential.setEapType(21);
-        userCredential.setNonEapInnerMethod("MS-CHAP-V2");
-        credential.setUserCredential(userCredential);
-        Credential.CertificateCredential certCredential = new Credential.CertificateCredential();
-        certCredential.setCertType("x509v3");
-        byte[] certSha256Fingerprint = new byte[32];
-        Arrays.fill(certSha256Fingerprint, (byte)0x1f);
-        certCredential.setCertSha256Fingerprint(certSha256Fingerprint);
-        credential.setCertCredential(certCredential);
-        Credential.SimCredential simCredential = new Credential.SimCredential();
-        simCredential.setImsi("123456*");
-        simCredential.setEapType(23);
-        credential.setSimCredential(simCredential);
-        credential.setCaCertificate(FakeKeys.CA_CERT0);
-        config.setCredential(credential);
-        return config;
-    }
-
-    /**
-     * Verify a valid installation file is parsed successfully with the matching contents.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void parseConfigFile() throws Exception {
-        String configStr = loadResourceFile(PASSPOINT_INSTALLATION_FILE_WITH_CA_CERT);
-        PasspointConfiguration expectedConfig = generateConfigurationFromProfile();
-        PasspointConfiguration actualConfig =
-                ConfigParser.parsePasspointConfig(
-                        "application/x-wifi-config", configStr.getBytes());
-        assertTrue(actualConfig.equals(expectedConfig));
-    }
-
-    /**
-     * Verify that parsing an installation file with invalid MIME type will fail.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void parseConfigFileWithInvalidMimeType() throws Exception {
-        String configStr = loadResourceFile(PASSPOINT_INSTALLATION_FILE_WITH_CA_CERT);
-        assertNull(ConfigParser.parsePasspointConfig(
-                "application/wifi-config", configStr.getBytes()));
-    }
-
-    /**
-     * Verify that parsing an un-encoded installation file will fail.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void parseConfigFileWithUnencodedData() throws Exception {
-        String configStr = loadResourceFile(PASSPOINT_INSTALLATION_FILE_WITH_UNENCODED_DATA);
-        assertNull(ConfigParser.parsePasspointConfig(
-                "application/x-wifi-config", configStr.getBytes()));
-    }
-
-    /**
-     * Verify that parsing an installation file that contains a non-base64 part will fail.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void parseConfigFileWithInvalidPart() throws Exception {
-        String configStr = loadResourceFile(PASSPOINT_INSTALLATION_FILE_WITH_INVALID_PART);
-        assertNull(ConfigParser.parsePasspointConfig(
-                "application/x-wifi-config", configStr.getBytes()));
-    }
-
-    /**
-     * Verify that parsing an installation file that contains a missing boundary string will fail.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void parseConfigFileWithMissingBoundary() throws Exception {
-        String configStr = loadResourceFile(PASSPOINT_INSTALLATION_FILE_WITH_MISSING_BOUNDARY);
-        assertNull(ConfigParser.parsePasspointConfig(
-                "application/x-wifi-config", configStr.getBytes()));
-    }
-
-    /**
-     * Verify that parsing an installation file that contains a MIME part with an invalid content
-     * type will fail.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void parseConfigFileWithInvalidContentType() throws Exception {
-        String configStr = loadResourceFile(PASSPOINT_INSTALLATION_FILE_WITH_INVALID_CONTENT_TYPE);
-        assertNull(ConfigParser.parsePasspointConfig(
-                "application/x-wifi-config", configStr.getBytes()));
-    }
-
-    /**
-     * Verify that parsing an installation file that doesn't contain a Passpoint profile will fail.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void parseConfigFileWithoutPasspointProfile() throws Exception {
-        String configStr = loadResourceFile(PASSPOINT_INSTALLATION_FILE_WITHOUT_PROFILE);
-        assertNull(ConfigParser.parsePasspointConfig(
-                "application/x-wifi-config", configStr.getBytes()));
-    }
-
-    /**
-     * Verify a valid installation file is parsed successfully with the matching contents, and that
-     * Update identifier is cleared.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void parseConfigFileWithUpdateIdentifier() throws Exception {
-        String configStr = loadResourceFile(PASSPOINT_INSTALLATION_FILE_WITH_UPDATE_ID);
-        PasspointConfiguration expectedConfig = generateConfigurationFromProfile();
-        PasspointConfiguration actualConfig =
-                ConfigParser.parsePasspointConfig(
-                        "application/x-wifi-config", configStr.getBytes());
-        // Expected configuration does not contain an update identifier
-        assertTrue(actualConfig.equals(expectedConfig));
-    }
-}
\ No newline at end of file
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/OsuProviderTest.java b/wifi/tests/src/android/net/wifi/hotspot2/OsuProviderTest.java
deleted file mode 100644
index 2ded849..0000000
--- a/wifi/tests/src/android/net/wifi/hotspot2/OsuProviderTest.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package android.net.wifi.hotspot2;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import android.net.Uri;
-import android.net.wifi.WifiSsid;
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Unit tests for {@link android.net.wifi.hotspot2.OsuProvider}.
- */
-@SmallTest
-public class OsuProviderTest {
-    private static final WifiSsid TEST_SSID =
-            WifiSsid.createFromByteArray("TEST SSID".getBytes(StandardCharsets.UTF_8));
-    private static final String TEST_FRIENDLY_NAME = "Friendly Name";
-    private static final Map<String, String> TEST_FRIENDLY_NAMES =
-            new HashMap<String, String>() {
-                {
-                    put("en", TEST_FRIENDLY_NAME);
-                    put("kr", TEST_FRIENDLY_NAME + 2);
-                    put("jp", TEST_FRIENDLY_NAME + 3);
-                }
-            };
-
-    private static final String TEST_SERVICE_DESCRIPTION = "Dummy Service";
-    private static final Uri TEST_SERVER_URI = Uri.parse("https://test.com");
-    private static final String TEST_NAI = "test.access.com";
-    private static final List<Integer> TEST_METHOD_LIST =
-            Arrays.asList(OsuProvider.METHOD_SOAP_XML_SPP);
-
-    /**
-     * Verify parcel write and read consistency for the given {@link OsuProvider}.
-     *
-     * @param writeInfo The {@link OsuProvider} to verify
-     * @throws Exception
-     */
-    private static void verifyParcel(OsuProvider writeInfo) throws Exception {
-        Parcel parcel = Parcel.obtain();
-        writeInfo.writeToParcel(parcel, 0);
-
-        parcel.setDataPosition(0);    // Rewind data position back to the beginning for read.
-        OsuProvider readInfo = OsuProvider.CREATOR.createFromParcel(parcel);
-
-        assertEquals(writeInfo, readInfo);
-        assertEquals(writeInfo.hashCode(), readInfo.hashCode());
-    }
-
-    /**
-     * Verify parcel read/write for an OSU provider containing no information.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void verifyParcelWithEmptyProviderInfo() throws Exception {
-        verifyParcel(new OsuProvider((WifiSsid) null, null, null, null, null, null));
-    }
-
-    /**
-     * Verify parcel read/write for an OSU provider containing full information.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void verifyParcelWithFullProviderInfo() throws Exception {
-        verifyParcel(new OsuProvider(TEST_SSID, TEST_FRIENDLY_NAMES,
-                TEST_SERVICE_DESCRIPTION, TEST_SERVER_URI, TEST_NAI, TEST_METHOD_LIST));
-    }
-
-    /**
-     * Verify copy constructor with a null source.
-     * @throws Exception
-     */
-    @Test
-    public void verifyCopyConstructorWithNullSource() throws Exception {
-        OsuProvider expected = new OsuProvider((WifiSsid) null, null, null, null, null, null);
-        assertEquals(expected, new OsuProvider(null));
-    }
-
-    /**
-     * Verify copy constructor with a valid source.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void verifyCopyConstructorWithValidSource() throws Exception {
-        OsuProvider source = new OsuProvider(TEST_SSID, TEST_FRIENDLY_NAMES,
-                TEST_SERVICE_DESCRIPTION, TEST_SERVER_URI, TEST_NAI, TEST_METHOD_LIST);
-        assertEquals(source, new OsuProvider(source));
-    }
-
-    /**
-     * Verify getter methods.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void verifyGetters() throws Exception {
-        OsuProvider provider = new OsuProvider(TEST_SSID, TEST_FRIENDLY_NAMES,
-                TEST_SERVICE_DESCRIPTION, TEST_SERVER_URI, TEST_NAI, TEST_METHOD_LIST);
-
-        assertTrue(TEST_SSID.equals(provider.getOsuSsid()));
-        assertTrue(TEST_FRIENDLY_NAME.equals(provider.getFriendlyName()));
-        assertTrue(TEST_FRIENDLY_NAMES.equals(provider.getFriendlyNameList()));
-        assertTrue(TEST_SERVICE_DESCRIPTION.equals(provider.getServiceDescription()));
-        assertTrue(TEST_SERVER_URI.equals(provider.getServerUri()));
-        assertTrue(TEST_NAI.equals(provider.getNetworkAccessIdentifier()));
-        assertTrue(TEST_METHOD_LIST.equals(provider.getMethodList()));
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java
deleted file mode 100644
index 8270d64..0000000
--- a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java
+++ /dev/null
@@ -1,626 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package android.net.wifi.hotspot2;
-
-import static android.net.wifi.WifiConfiguration.METERED_OVERRIDE_NONE;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertTrue;
-
-import android.net.wifi.EAPConstants;
-import android.net.wifi.FakeKeys;
-import android.net.wifi.hotspot2.pps.Credential;
-import android.net.wifi.hotspot2.pps.HomeSp;
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-import java.nio.charset.StandardCharsets;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.X509Certificate;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Unit tests for {@link android.net.wifi.hotspot2.PasspointConfiguration}.
- */
-@SmallTest
-public class PasspointConfigurationTest {
-    private static final int MAX_URL_BYTES = 1023;
-    private static final int CERTIFICATE_FINGERPRINT_BYTES = 32;
-
-    /**
-     * Verify parcel write and read consistency for the given configuration.
-     *
-     * @param writeConfig The configuration to verify
-     * @throws Exception
-     */
-    private static void verifyParcel(PasspointConfiguration writeConfig) throws Exception {
-        Parcel parcel = Parcel.obtain();
-        writeConfig.writeToParcel(parcel, 0);
-
-        parcel.setDataPosition(0);    // Rewind data position back to the beginning for read.
-        PasspointConfiguration readConfig =
-                PasspointConfiguration.CREATOR.createFromParcel(parcel);
-        assertTrue(readConfig.equals(writeConfig));
-    }
-
-    /**
-     * Verify parcel read/write for a default configuration.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void verifyParcelWithDefault() throws Exception {
-        verifyParcel(new PasspointConfiguration());
-    }
-
-    /**
-     * Verify parcel read/write for a configuration that contained the full configuration.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void verifyParcelWithFullConfiguration() throws Exception {
-        verifyParcel(PasspointTestUtils.createConfig());
-    }
-
-    /**
-     * Verify parcel read/write for a configuration that doesn't contain a list of service names.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void verifyParcelWithoutServiceNames() throws Exception {
-        PasspointConfiguration config = PasspointTestUtils.createConfig();
-        config.setServiceFriendlyNames(null);
-        verifyParcel(config);
-    }
-
-    /**
-     * Verify parcel read/write for a configuration that doesn't contain HomeSP.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void verifyParcelWithoutHomeSP() throws Exception {
-        PasspointConfiguration config = PasspointTestUtils.createConfig();
-        config.setHomeSp(null);
-        verifyParcel(config);
-    }
-
-    /**
-     * Verify parcel read/write for a configuration that doesn't contain Credential.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void verifyParcelWithoutCredential() throws Exception {
-        PasspointConfiguration config = PasspointTestUtils.createConfig();
-        config.setCredential(null);
-        verifyParcel(config);
-    }
-
-    /**
-     * Verify parcel read/write for a configuration that doesn't contain Policy.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void verifyParcelWithoutPolicy() throws Exception {
-        PasspointConfiguration config = PasspointTestUtils.createConfig();
-        config.setPolicy(null);
-        verifyParcel(config);
-    }
-
-    /**
-     * Verify parcel read/write for a configuration that doesn't contain subscription update.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void verifyParcelWithoutSubscriptionUpdate() throws Exception {
-        PasspointConfiguration config = PasspointTestUtils.createConfig();
-        config.setSubscriptionUpdate(null);
-        verifyParcel(config);
-    }
-
-    /**
-     * Verify parcel read/write for a configuration that doesn't contain trust root certificate
-     * list.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void verifyParcelWithoutTrustRootCertList() throws Exception {
-        PasspointConfiguration config = PasspointTestUtils.createConfig();
-        config.setTrustRootCertList(null);
-        verifyParcel(config);
-    }
-
-    /**
-     * Verify parcel read/write for a configuration that doesn't contain AAA server trusted names
-     * list.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void verifyParcelWithoutAaaServerTrustedNames() throws Exception {
-        PasspointConfiguration config = PasspointTestUtils.createConfig();
-        config.setAaaServerTrustedNames(null);
-        verifyParcel(config);
-    }
-
-    /**
-     * Verify that a default/empty configuration is invalid.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateDefaultConfig() throws Exception {
-        PasspointConfiguration config = new PasspointConfiguration();
-
-        assertFalse(config.validate());
-        assertFalse(config.validateForR2());
-        assertTrue(config.isAutojoinEnabled());
-        assertTrue(config.isMacRandomizationEnabled());
-        assertTrue(config.getMeteredOverride() == METERED_OVERRIDE_NONE);
-    }
-
-    /**
-     * Verify that a configuration containing all fields is valid for R1/R2.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateFullConfig() throws Exception {
-        PasspointConfiguration config = PasspointTestUtils.createConfig();
-
-        assertTrue(config.validate());
-        assertFalse(config.isOsuProvisioned());
-    }
-
-    /**
-     * Verify that a configuration containing all fields except for UpdateIdentifier is valid for
-     * R1, but invalid for R2.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateFullConfigWithoutUpdateIdentifier() throws Exception {
-        PasspointConfiguration config = PasspointTestUtils.createConfig();
-        config.setUpdateIdentifier(Integer.MIN_VALUE);
-
-        assertTrue(config.validate());
-        assertFalse(config.validateForR2());
-    }
-
-    /**
-     * Verify that a configuration without Credential is invalid.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateConfigWithoutCredential() throws Exception {
-        PasspointConfiguration config = PasspointTestUtils.createConfig();
-        config.setCredential(null);
-
-        assertFalse(config.validate());
-        assertFalse(config.validateForR2());
-    }
-
-    /**
-     * Verify that a configuration without HomeSP is invalid.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateConfigWithoutHomeSp() throws Exception {
-        PasspointConfiguration config = PasspointTestUtils.createConfig();
-        config.setHomeSp(null);
-
-        assertFalse(config.validate());
-        assertFalse(config.validateForR2());
-    }
-
-    /**
-     * Verify that a configuration without Policy is valid, since Policy configurations
-     * are optional for R1 and R2.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateConfigWithoutPolicy() throws Exception {
-        PasspointConfiguration config = PasspointTestUtils.createConfig();
-        config.setPolicy(null);
-
-        assertTrue(config.validate());
-    }
-
-    /**
-     * Verify that a configuration without subscription update is valid for R1 and invalid for R2,
-     * since subscription update configuration is only applicable for R2.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateConfigWithoutSubscriptionUpdate() throws Exception {
-        PasspointConfiguration config = PasspointTestUtils.createConfig();
-        config.setSubscriptionUpdate(null);
-
-        assertTrue(config.validate());
-        assertFalse(config.validateForR2());
-    }
-
-    /**
-     * Verify that a configuration without AAA server trusted names is valid for R1 and R2,
-     * since AAA server trusted names are optional for R1 and R2.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateConfigWithoutAaaServerTrustedNames() throws Exception {
-        PasspointConfiguration config = PasspointTestUtils.createConfig();
-        config.setAaaServerTrustedNames(null);
-
-        assertTrue(config.validate());
-    }
-
-    /**
-     * Verify that a configuration with a trust root certificate URL exceeding the max size
-     * is invalid.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateConfigWithInvalidTrustRootCertUrl() throws Exception {
-        PasspointConfiguration config = PasspointTestUtils.createConfig();
-        byte[] rawUrlBytes = new byte[MAX_URL_BYTES + 1];
-        Map<String, byte[]> trustRootCertList = new HashMap<>();
-        Arrays.fill(rawUrlBytes, (byte) 'a');
-        trustRootCertList.put(new String(rawUrlBytes, StandardCharsets.UTF_8),
-                new byte[CERTIFICATE_FINGERPRINT_BYTES]);
-        config.setTrustRootCertList(trustRootCertList);
-
-        assertFalse(config.validate());
-
-        trustRootCertList = new HashMap<>();
-        trustRootCertList.put(null, new byte[CERTIFICATE_FINGERPRINT_BYTES]);
-        config.setTrustRootCertList(trustRootCertList);
-
-        assertFalse(config.validate());
-        assertFalse(config.validateForR2());
-    }
-
-    /**
-     * Verify that a configuration with an invalid trust root certificate fingerprint is invalid.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateConfigWithInvalidTrustRootCertFingerprint() throws Exception {
-        PasspointConfiguration config = PasspointTestUtils.createConfig();
-        Map<String, byte[]> trustRootCertList = new HashMap<>();
-        trustRootCertList.put("test.cert.com", new byte[CERTIFICATE_FINGERPRINT_BYTES + 1]);
-        config.setTrustRootCertList(trustRootCertList);
-        assertFalse(config.validate());
-
-        trustRootCertList = new HashMap<>();
-        trustRootCertList.put("test.cert.com", new byte[CERTIFICATE_FINGERPRINT_BYTES - 1]);
-        config.setTrustRootCertList(trustRootCertList);
-        assertFalse(config.validate());
-
-        trustRootCertList = new HashMap<>();
-        trustRootCertList.put("test.cert.com", null);
-        config.setTrustRootCertList(trustRootCertList);
-        assertFalse(config.validate());
-        assertFalse(config.validateForR2());
-    }
-
-    /**
-     * Verify that copy constructor works when pass in a null source.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateCopyConstructorWithNullSource() throws Exception {
-        PasspointConfiguration copyConfig = new PasspointConfiguration(null);
-        PasspointConfiguration defaultConfig = new PasspointConfiguration();
-        assertTrue(copyConfig.equals(defaultConfig));
-    }
-
-    /**
-     * Verify that copy constructor works when pass in a valid source.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateCopyConstructorWithValidSource() throws Exception {
-        PasspointConfiguration sourceConfig = PasspointTestUtils.createConfig();
-        PasspointConfiguration copyConfig = new PasspointConfiguration(sourceConfig);
-        assertTrue(copyConfig.equals(sourceConfig));
-    }
-
-    /**
-     * Verify that a configuration containing all fields is valid for R2.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateFullR2Config() throws Exception {
-        PasspointConfiguration config = PasspointTestUtils.createR2Config();
-        assertTrue(config.validate());
-        assertTrue(config.validateForR2());
-        assertTrue(config.isOsuProvisioned());
-    }
-
-    /**
-     * Verify that the unique identifier generated is identical for two instances
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateUniqueId() throws Exception {
-        PasspointConfiguration config1 = PasspointTestUtils.createConfig();
-        PasspointConfiguration config2 = PasspointTestUtils.createConfig();
-
-        assertEquals(config1.getUniqueId(), config2.getUniqueId());
-    }
-
-    /**
-     * Verify that the unique identifier generated is the same for two instances with different
-     * HomeSp node but same FQDN
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateUniqueIdDifferentHomeSpSameFqdn() throws Exception {
-        PasspointConfiguration config1 = PasspointTestUtils.createConfig();
-
-        // Modify config2's RCOIs and friendly name to a different set of values
-        PasspointConfiguration config2 = PasspointTestUtils.createConfig();
-        HomeSp homeSp = config2.getHomeSp();
-        homeSp.setRoamingConsortiumOis(new long[] {0xaa, 0xbb});
-        homeSp.setFriendlyName("Some other name");
-        config2.setHomeSp(homeSp);
-
-        assertEquals(config1.getUniqueId(), config2.getUniqueId());
-    }
-
-    /**
-     * Verify that the unique identifier generated is different for two instances with the same
-     * HomeSp node but different FQDN
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateUniqueIdSameHomeSpDifferentFqdn() throws Exception {
-        PasspointConfiguration config1 = PasspointTestUtils.createConfig();
-
-        // Modify config2's FQDN to a different value
-        PasspointConfiguration config2 = PasspointTestUtils.createConfig();
-        HomeSp homeSp = config2.getHomeSp();
-        homeSp.setFqdn("fqdn2.com");
-        config2.setHomeSp(homeSp);
-
-        assertNotEquals(config1.getUniqueId(), config2.getUniqueId());
-    }
-
-    /**
-     * Verify that the unique identifier generated is different for two instances with different
-     * SIM Credential node
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateUniqueIdDifferentSimCredential() throws Exception {
-        PasspointConfiguration config1 = PasspointTestUtils.createConfig();
-
-        // Modify config2's realm and SIM credential to a different set of values
-        PasspointConfiguration config2 = PasspointTestUtils.createConfig();
-        Credential credential = config2.getCredential();
-        credential.setRealm("realm2.example.com");
-        credential.getSimCredential().setImsi("350460*");
-        config2.setCredential(credential);
-
-        assertNotEquals(config1.getUniqueId(), config2.getUniqueId());
-    }
-
-    /**
-     * Verify that the unique identifier generated is different for two instances with different
-     * Realm in the Credential node
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateUniqueIdDifferentRealm() throws Exception {
-        PasspointConfiguration config1 = PasspointTestUtils.createConfig();
-
-        // Modify config2's realm to a different set of values
-        PasspointConfiguration config2 = PasspointTestUtils.createConfig();
-        Credential credential = config2.getCredential();
-        credential.setRealm("realm2.example.com");
-        config2.setCredential(credential);
-
-        assertNotEquals(config1.getUniqueId(), config2.getUniqueId());
-    }
-
-    /**
-     * Verify that the unique identifier generated is the same for two instances with different
-     * password and same username in the User Credential node
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateUniqueIdSameUserInUserCredential() throws Exception {
-        PasspointConfiguration config1 = PasspointTestUtils.createConfig();
-        Credential credential = createCredentialWithUserCredential("user", "passwd");
-        config1.setCredential(credential);
-
-        // Modify config2's Passpowrd to a different set of values
-        PasspointConfiguration config2 = PasspointTestUtils.createConfig();
-        credential = createCredentialWithUserCredential("user", "newpasswd");
-        config2.setCredential(credential);
-
-        assertEquals(config1.getUniqueId(), config2.getUniqueId());
-    }
-
-    /**
-     * Verify that the unique identifier generated is different for two instances with different
-     * username in the User Credential node
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateUniqueIdDifferentUserCredential() throws Exception {
-        PasspointConfiguration config1 = PasspointTestUtils.createConfig();
-        Credential credential = createCredentialWithUserCredential("user", "passwd");
-        config1.setCredential(credential);
-
-        // Modify config2's username to a different value
-        PasspointConfiguration config2 = PasspointTestUtils.createConfig();
-        credential = createCredentialWithUserCredential("user2", "passwd");
-        config2.setCredential(credential);
-
-        assertNotEquals(config1.getUniqueId(), config2.getUniqueId());
-    }
-
-    /**
-     * Verify that the unique identifier generated is different for two instances with different
-     * Cert Credential node
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateUniqueIdDifferentCertCredential() throws Exception {
-        PasspointConfiguration config1 = PasspointTestUtils.createConfig();
-        Credential credential = createCredentialWithCertificateCredential(true, true);
-        config1.setCredential(credential);
-
-        // Modify config2's cert credential to a different set of values
-        PasspointConfiguration config2 = PasspointTestUtils.createConfig();
-        credential = createCredentialWithCertificateCredential(false, false);
-        config2.setCredential(credential);
-
-        assertNotEquals(config1.getUniqueId(), config2.getUniqueId());
-    }
-
-    /**
-     * Helper function for generating certificate credential for testing.
-     *
-     * @return {@link Credential}
-     */
-    private static Credential createCredentialWithCertificateCredential(Boolean useCaCert0,
-            Boolean useCert0)
-            throws NoSuchAlgorithmException, CertificateEncodingException {
-        Credential.CertificateCredential certCred = new Credential.CertificateCredential();
-        certCred.setCertType("x509v3");
-        if (useCert0) {
-            certCred.setCertSha256Fingerprint(
-                    MessageDigest.getInstance("SHA-256").digest(FakeKeys.CLIENT_CERT.getEncoded()));
-        } else {
-            certCred.setCertSha256Fingerprint(MessageDigest.getInstance("SHA-256")
-                    .digest(FakeKeys.CLIENT_SUITE_B_RSA3072_CERT.getEncoded()));
-        }
-        return createCredential(null, certCred, null, new X509Certificate[] {FakeKeys.CLIENT_CERT},
-                FakeKeys.RSA_KEY1, useCaCert0 ? FakeKeys.CA_CERT0 : FakeKeys.CA_CERT1);
-    }
-
-    /**
-     * Helper function for generating user credential for testing.
-     *
-     * @return {@link Credential}
-     */
-    private static Credential createCredentialWithUserCredential(String username, String password) {
-        Credential.UserCredential userCred = new Credential.UserCredential();
-        userCred.setUsername(username);
-        userCred.setPassword(password);
-        userCred.setMachineManaged(true);
-        userCred.setAbleToShare(true);
-        userCred.setSoftTokenApp("TestApp");
-        userCred.setEapType(EAPConstants.EAP_TTLS);
-        userCred.setNonEapInnerMethod("MS-CHAP");
-        return createCredential(userCred, null, null, null, null, FakeKeys.CA_CERT0);
-    }
-
-    /**
-     * Helper function for generating Credential for testing.
-     *
-     * @param userCred Instance of UserCredential
-     * @param certCred Instance of CertificateCredential
-     * @param simCred Instance of SimCredential
-     * @param clientCertificateChain Chain of client certificates
-     * @param clientPrivateKey Client private key
-     * @param caCerts CA certificates
-     * @return {@link Credential}
-     */
-    private static Credential createCredential(Credential.UserCredential userCred,
-            Credential.CertificateCredential certCred,
-            Credential.SimCredential simCred,
-            X509Certificate[] clientCertificateChain, PrivateKey clientPrivateKey,
-            X509Certificate... caCerts) {
-        Credential cred = new Credential();
-        cred.setCreationTimeInMillis(123455L);
-        cred.setExpirationTimeInMillis(2310093L);
-        cred.setRealm("realm");
-        cred.setCheckAaaServerCertStatus(true);
-        cred.setUserCredential(userCred);
-        cred.setCertCredential(certCred);
-        cred.setSimCredential(simCred);
-        if (caCerts != null && caCerts.length == 1) {
-            cred.setCaCertificate(caCerts[0]);
-        } else {
-            cred.setCaCertificates(caCerts);
-        }
-        cred.setClientCertificateChain(clientCertificateChain);
-        cred.setClientPrivateKey(clientPrivateKey);
-        return cred;
-    }
-
-    /**
-     * Verify that the unique identifier API generates an exception if HomeSP is not initialized.
-     *
-     * @throws Exception
-     */
-    @Test (expected = IllegalStateException.class)
-    public void validateUniqueIdExceptionWithEmptyHomeSp() throws Exception {
-        PasspointConfiguration config = PasspointTestUtils.createConfig();
-        config.setHomeSp(null);
-        String uniqueId = config.getUniqueId();
-    }
-
-    /**
-     * Verify that the unique identifier API generates an exception if Credential is not
-     * initialized.
-     *
-     * @throws Exception
-     */
-    @Test (expected = IllegalStateException.class)
-    public void validateUniqueIdExceptionWithEmptyCredential() throws Exception {
-        PasspointConfiguration config = PasspointTestUtils.createConfig();
-        config.setCredential(null);
-        String uniqueId = config.getUniqueId();
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/PasspointTestUtils.java b/wifi/tests/src/android/net/wifi/hotspot2/PasspointTestUtils.java
deleted file mode 100644
index 8d55acb..0000000
--- a/wifi/tests/src/android/net/wifi/hotspot2/PasspointTestUtils.java
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.hotspot2;
-
-import android.net.wifi.EAPConstants;
-import android.net.wifi.hotspot2.pps.Credential;
-import android.net.wifi.hotspot2.pps.HomeSp;
-import android.net.wifi.hotspot2.pps.Policy;
-import android.net.wifi.hotspot2.pps.UpdateParameter;
-import android.util.Base64;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class PasspointTestUtils {
-    private static final int CERTIFICATE_FINGERPRINT_BYTES = 32;
-
-    /**
-     * Utility function for creating a {@link android.net.wifi.hotspot2.pps.HomeSP}.
-     *
-     * @return {@link android.net.wifi.hotspot2.pps.HomeSP}
-     */
-    private static HomeSp createHomeSp() {
-        HomeSp homeSp = new HomeSp();
-        homeSp.setFqdn("fqdn");
-        homeSp.setFriendlyName("friendly name");
-        homeSp.setRoamingConsortiumOis(new long[] {0x55, 0x66});
-        return homeSp;
-    }
-
-    /**
-     * Utility function for creating a {@link android.net.wifi.hotspot2.pps.Credential}.
-     *
-     * @return {@link android.net.wifi.hotspot2.pps.Credential}
-     */
-    private static Credential createCredential() {
-        Credential cred = new Credential();
-        cred.setRealm("realm");
-        cred.setUserCredential(null);
-        cred.setCertCredential(null);
-        cred.setSimCredential(new Credential.SimCredential());
-        cred.getSimCredential().setImsi("1234*");
-        cred.getSimCredential().setEapType(EAPConstants.EAP_SIM);
-        cred.setCaCertificate(null);
-        cred.setClientCertificateChain(null);
-        cred.setClientPrivateKey(null);
-        return cred;
-    }
-
-    /**
-     * Helper function for creating a {@link Policy} for testing.
-     *
-     * @return {@link Policy}
-     */
-    private static Policy createPolicy() {
-        Policy policy = new Policy();
-        policy.setMinHomeDownlinkBandwidth(123);
-        policy.setMinHomeUplinkBandwidth(345);
-        policy.setMinRoamingDownlinkBandwidth(567);
-        policy.setMinRoamingUplinkBandwidth(789);
-        policy.setMaximumBssLoadValue(12);
-        policy.setExcludedSsidList(new String[] {"ssid1", "ssid2"});
-        HashMap<Integer, String> requiredProtoPortMap = new HashMap<>();
-        requiredProtoPortMap.put(12, "23,342,123");
-        requiredProtoPortMap.put(23, "789,372,1235");
-        policy.setRequiredProtoPortMap(requiredProtoPortMap);
-
-        List<Policy.RoamingPartner> preferredRoamingPartnerList = new ArrayList<>();
-        Policy.RoamingPartner partner1 = new Policy.RoamingPartner();
-        partner1.setFqdn("partner1.com");
-        partner1.setFqdnExactMatch(true);
-        partner1.setPriority(12);
-        partner1.setCountries("us,jp");
-        Policy.RoamingPartner partner2 = new Policy.RoamingPartner();
-        partner2.setFqdn("partner2.com");
-        partner2.setFqdnExactMatch(false);
-        partner2.setPriority(42);
-        partner2.setCountries("ca,fr");
-        preferredRoamingPartnerList.add(partner1);
-        preferredRoamingPartnerList.add(partner2);
-        policy.setPreferredRoamingPartnerList(preferredRoamingPartnerList);
-
-        UpdateParameter policyUpdate = new UpdateParameter();
-        policyUpdate.setUpdateIntervalInMinutes(1712);
-        policyUpdate.setUpdateMethod(UpdateParameter.UPDATE_METHOD_OMADM);
-        policyUpdate.setRestriction(UpdateParameter.UPDATE_RESTRICTION_HOMESP);
-        policyUpdate.setServerUri("policy.update.com");
-        policyUpdate.setUsername("username");
-        policyUpdate.setBase64EncodedPassword(
-                Base64.encodeToString("password".getBytes(), Base64.DEFAULT));
-        policyUpdate.setTrustRootCertUrl("trust.cert.com");
-        policyUpdate.setTrustRootCertSha256Fingerprint(
-                new byte[CERTIFICATE_FINGERPRINT_BYTES]);
-        policy.setPolicyUpdate(policyUpdate);
-
-        return policy;
-    }
-
-    private static UpdateParameter createSubscriptionUpdate() {
-        UpdateParameter subUpdate = new UpdateParameter();
-        subUpdate.setUpdateIntervalInMinutes(9021);
-        subUpdate.setUpdateMethod(UpdateParameter.UPDATE_METHOD_SSP);
-        subUpdate.setRestriction(UpdateParameter.UPDATE_RESTRICTION_ROAMING_PARTNER);
-        subUpdate.setServerUri("subscription.update.com");
-        subUpdate.setUsername("subUsername");
-        subUpdate.setBase64EncodedPassword(
-                Base64.encodeToString("subPassword".getBytes(), Base64.DEFAULT));
-        subUpdate.setTrustRootCertUrl("subscription.trust.cert.com");
-        subUpdate.setTrustRootCertSha256Fingerprint(new byte[CERTIFICATE_FINGERPRINT_BYTES]);
-        return subUpdate;
-    }
-    /**
-     * Helper function for creating a {@link PasspointConfiguration} for testing.
-     *
-     * @return {@link PasspointConfiguration}
-     */
-    public static PasspointConfiguration createConfig() {
-        PasspointConfiguration config = new PasspointConfiguration();
-        config.setHomeSp(createHomeSp());
-        config.setAaaServerTrustedNames(
-                new String[] {"trusted.fqdn.com", "another-trusted.fqdn.com"});
-        config.setCredential(createCredential());
-        config.setPolicy(createPolicy());
-        config.setSubscriptionUpdate(createSubscriptionUpdate());
-        Map<String, byte[]> trustRootCertList = new HashMap<>();
-        trustRootCertList.put("trustRoot.cert1.com",
-                new byte[CERTIFICATE_FINGERPRINT_BYTES]);
-        trustRootCertList.put("trustRoot.cert2.com",
-                new byte[CERTIFICATE_FINGERPRINT_BYTES]);
-        config.setTrustRootCertList(trustRootCertList);
-        config.setCredentialPriority(120);
-        config.setSubscriptionCreationTimeInMillis(231200);
-        config.setSubscriptionExpirationTimeInMillis(2134232);
-        config.setSubscriptionType("Gold");
-        config.setUsageLimitUsageTimePeriodInMinutes(3600);
-        config.setUsageLimitStartTimeInMillis(124214213);
-        config.setUsageLimitDataLimit(14121);
-        config.setUsageLimitTimeLimitInMinutes(78912);
-        Map<String, String> friendlyNames = new HashMap<>();
-        friendlyNames.put("en", "ServiceName1");
-        friendlyNames.put("kr", "ServiceName2");
-        config.setServiceFriendlyNames(friendlyNames);
-        return config;
-    }
-
-    /**
-     * Helper function for creating an R2 {@link PasspointConfiguration} for testing.
-     *
-     * @return {@link PasspointConfiguration}
-     */
-    public static PasspointConfiguration createR2Config() {
-        PasspointConfiguration config = createConfig();
-        config.setUpdateIdentifier(1234);
-        return config;
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/omadm/PpsMoParserTest.java b/wifi/tests/src/android/net/wifi/hotspot2/omadm/PpsMoParserTest.java
deleted file mode 100644
index 1ac9cb8..0000000
--- a/wifi/tests/src/android/net/wifi/hotspot2/omadm/PpsMoParserTest.java
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.hotspot2.omadm;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import android.net.wifi.hotspot2.PasspointConfiguration;
-import android.net.wifi.hotspot2.pps.Credential;
-import android.net.wifi.hotspot2.pps.HomeSp;
-import android.net.wifi.hotspot2.pps.Policy;
-import android.net.wifi.hotspot2.pps.UpdateParameter;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Unit tests for {@link android.net.wifi.hotspot2.omadm.PpsMoParser}.
- */
-@SmallTest
-public class PpsMoParserTest {
-    private static final String VALID_PPS_MO_XML_FILE = "assets/pps/PerProviderSubscription.xml";
-    private static final String PPS_MO_XML_FILE_DUPLICATE_HOMESP =
-            "assets/pps/PerProviderSubscription_DuplicateHomeSP.xml";
-    private static final String PPS_MO_XML_FILE_DUPLICATE_VALUE =
-            "assets/pps/PerProviderSubscription_DuplicateValue.xml";
-    private static final String PPS_MO_XML_FILE_MISSING_VALUE =
-            "assets/pps/PerProviderSubscription_MissingValue.xml";
-    private static final String PPS_MO_XML_FILE_MISSING_NAME =
-            "assets/pps/PerProviderSubscription_MissingName.xml";
-    private static final String PPS_MO_XML_FILE_INVALID_NODE =
-            "assets/pps/PerProviderSubscription_InvalidNode.xml";
-    private static final String PPS_MO_XML_FILE_INVALID_NAME =
-            "assets/pps/PerProviderSubscription_InvalidName.xml";
-
-    /**
-     * Read the content of the given resource file into a String.
-     *
-     * @param filename String name of the file
-     * @return String
-     * @throws IOException
-     */
-    private String loadResourceFile(String filename) throws IOException {
-        InputStream in = getClass().getClassLoader().getResourceAsStream(filename);
-        BufferedReader reader = new BufferedReader(new InputStreamReader(in));
-        StringBuilder builder = new StringBuilder();
-        String line;
-        while ((line = reader.readLine()) != null) {
-            builder.append(line).append("\n");
-        }
-
-        return builder.toString();
-    }
-
-    /**
-     * Generate a {@link PasspointConfiguration} that matches the configuration specified in the
-     * XML file {@link #VALID_PPS_MO_XML_FILE}.
-     *
-     * @return {@link PasspointConfiguration}
-     */
-    private PasspointConfiguration generateConfigurationFromPPSMOTree() throws Exception {
-        DateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
-        byte[] certFingerprint = new byte[32];
-        Arrays.fill(certFingerprint, (byte) 0x1f);
-
-        PasspointConfiguration config = new PasspointConfiguration();
-        config.setUpdateIdentifier(12);
-        config.setCredentialPriority(99);
-
-        // AAA Server trust root.
-        Map<String, byte[]> trustRootCertList = new HashMap<>();
-        trustRootCertList.put("server1.trust.root.com", certFingerprint);
-        config.setTrustRootCertList(trustRootCertList);
-
-        // Subscription update.
-        UpdateParameter subscriptionUpdate = new UpdateParameter();
-        subscriptionUpdate.setUpdateIntervalInMinutes(120);
-        subscriptionUpdate.setUpdateMethod(UpdateParameter.UPDATE_METHOD_SSP);
-        subscriptionUpdate.setRestriction(UpdateParameter.UPDATE_RESTRICTION_ROAMING_PARTNER);
-        subscriptionUpdate.setServerUri("subscription.update.com");
-        subscriptionUpdate.setUsername("subscriptionUser");
-        subscriptionUpdate.setBase64EncodedPassword("subscriptionPass");
-        subscriptionUpdate.setTrustRootCertUrl("subscription.update.cert.com");
-        subscriptionUpdate.setTrustRootCertSha256Fingerprint(certFingerprint);
-        config.setSubscriptionUpdate(subscriptionUpdate);
-
-        // Subscription parameters.
-        config.setSubscriptionCreationTimeInMillis(format.parse("2016-02-01T10:00:00Z").getTime());
-        config.setSubscriptionExpirationTimeInMillis(format.parse("2016-03-01T10:00:00Z").getTime());
-        config.setSubscriptionType("Gold");
-        config.setUsageLimitDataLimit(921890);
-        config.setUsageLimitStartTimeInMillis(format.parse("2016-12-01T10:00:00Z").getTime());
-        config.setUsageLimitTimeLimitInMinutes(120);
-        config.setUsageLimitUsageTimePeriodInMinutes(99910);
-
-        // HomeSP configuration.
-        HomeSp homeSp = new HomeSp();
-        homeSp.setFriendlyName("Century House");
-        homeSp.setFqdn("mi6.co.uk");
-        homeSp.setRoamingConsortiumOis(new long[] {0x112233L, 0x445566L});
-        homeSp.setIconUrl("icon.test.com");
-        Map<String, Long> homeNetworkIds = new HashMap<>();
-        homeNetworkIds.put("TestSSID", 0x12345678L);
-        homeNetworkIds.put("NullHESSID", null);
-        homeSp.setHomeNetworkIds(homeNetworkIds);
-        homeSp.setMatchAllOis(new long[] {0x11223344});
-        homeSp.setMatchAnyOis(new long[] {0x55667788});
-        homeSp.setOtherHomePartners(new String[] {"other.fqdn.com"});
-        config.setHomeSp(homeSp);
-
-        config.setAaaServerTrustedNames(
-                new String[] {"trusted.fqdn.com", "another-trusted.fqdn.com"});
-
-        // Credential configuration.
-        Credential credential = new Credential();
-        credential.setCreationTimeInMillis(format.parse("2016-01-01T10:00:00Z").getTime());
-        credential.setExpirationTimeInMillis(format.parse("2016-02-01T10:00:00Z").getTime());
-        credential.setRealm("shaken.stirred.com");
-        credential.setCheckAaaServerCertStatus(true);
-        Credential.UserCredential userCredential = new Credential.UserCredential();
-        userCredential.setUsername("james");
-        userCredential.setPassword("Ym9uZDAwNw==");
-        userCredential.setMachineManaged(true);
-        userCredential.setSoftTokenApp("TestApp");
-        userCredential.setAbleToShare(true);
-        userCredential.setEapType(21);
-        userCredential.setNonEapInnerMethod("MS-CHAP-V2");
-        credential.setUserCredential(userCredential);
-        Credential.CertificateCredential certCredential = new Credential.CertificateCredential();
-        certCredential.setCertType("x509v3");
-        certCredential.setCertSha256Fingerprint(certFingerprint);
-        credential.setCertCredential(certCredential);
-        Credential.SimCredential simCredential = new Credential.SimCredential();
-        simCredential.setImsi("imsi");
-        simCredential.setEapType(24);
-        credential.setSimCredential(simCredential);
-        config.setCredential(credential);
-
-        // Policy configuration.
-        Policy policy = new Policy();
-        List<Policy.RoamingPartner> preferredRoamingPartnerList = new ArrayList<>();
-        Policy.RoamingPartner partner1 = new Policy.RoamingPartner();
-        partner1.setFqdn("test1.fqdn.com");
-        partner1.setFqdnExactMatch(true);
-        partner1.setPriority(127);
-        partner1.setCountries("us,fr");
-        Policy.RoamingPartner partner2 = new Policy.RoamingPartner();
-        partner2.setFqdn("test2.fqdn.com");
-        partner2.setFqdnExactMatch(false);
-        partner2.setPriority(200);
-        partner2.setCountries("*");
-        preferredRoamingPartnerList.add(partner1);
-        preferredRoamingPartnerList.add(partner2);
-        policy.setPreferredRoamingPartnerList(preferredRoamingPartnerList);
-        policy.setMinHomeDownlinkBandwidth(23412);
-        policy.setMinHomeUplinkBandwidth(9823);
-        policy.setMinRoamingDownlinkBandwidth(9271);
-        policy.setMinRoamingUplinkBandwidth(2315);
-        policy.setExcludedSsidList(new String[] {"excludeSSID"});
-        Map<Integer, String> requiredProtoPortMap = new HashMap<>();
-        requiredProtoPortMap.put(12, "34,92,234");
-        policy.setRequiredProtoPortMap(requiredProtoPortMap);
-        policy.setMaximumBssLoadValue(23);
-        UpdateParameter policyUpdate = new UpdateParameter();
-        policyUpdate.setUpdateIntervalInMinutes(120);
-        policyUpdate.setUpdateMethod(UpdateParameter.UPDATE_METHOD_OMADM);
-        policyUpdate.setRestriction(UpdateParameter.UPDATE_RESTRICTION_HOMESP);
-        policyUpdate.setServerUri("policy.update.com");
-        policyUpdate.setUsername("updateUser");
-        policyUpdate.setBase64EncodedPassword("updatePass");
-        policyUpdate.setTrustRootCertUrl("update.cert.com");
-        policyUpdate.setTrustRootCertSha256Fingerprint(certFingerprint);
-        policy.setPolicyUpdate(policyUpdate);
-        config.setPolicy(policy);
-        return config;
-    }
-
-    /**
-     * Parse and verify all supported fields under PPS MO tree.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void parseValidPPSMOTree() throws Exception {
-        String ppsMoTree = loadResourceFile(VALID_PPS_MO_XML_FILE);
-        PasspointConfiguration expectedConfig = generateConfigurationFromPPSMOTree();
-        PasspointConfiguration actualConfig = PpsMoParser.parseMoText(ppsMoTree);
-        assertTrue(actualConfig.equals(expectedConfig));
-    }
-
-    @Test
-    public void parseNullPPSMOTree() throws Exception {
-        assertEquals(null, PpsMoParser.parseMoText(null));
-    }
-
-    @Test
-    public void parseEmptyPPSMOTree() throws Exception {
-        assertEquals(null, PpsMoParser.parseMoText(new String()));
-    }
-
-    @Test
-    public void parsePPSMOTreeWithDuplicateHomeSP() throws Exception {
-        assertEquals(null, PpsMoParser.parseMoText(
-                loadResourceFile(PPS_MO_XML_FILE_DUPLICATE_HOMESP)));
-    }
-
-    @Test
-    public void parsePPSMOTreeWithDuplicateValue() throws Exception {
-        assertEquals(null, PpsMoParser.parseMoText(
-                loadResourceFile(PPS_MO_XML_FILE_DUPLICATE_VALUE)));
-    }
-
-    @Test
-    public void parsePPSMOTreeWithMissingValue() throws Exception {
-        assertEquals(null, PpsMoParser.parseMoText(
-                loadResourceFile(PPS_MO_XML_FILE_MISSING_VALUE)));
-    }
-
-    @Test
-    public void parsePPSMOTreeWithMissingName() throws Exception {
-        assertEquals(null, PpsMoParser.parseMoText(
-                loadResourceFile(PPS_MO_XML_FILE_MISSING_NAME)));
-    }
-
-    @Test
-    public void parsePPSMOTreeWithInvalidNode() throws Exception {
-        assertEquals(null, PpsMoParser.parseMoText(
-                loadResourceFile(PPS_MO_XML_FILE_INVALID_NODE)));
-    }
-
-    @Test
-    public void parsePPSMOTreeWithInvalidName() throws Exception {
-        assertEquals(null, PpsMoParser.parseMoText(
-                loadResourceFile(PPS_MO_XML_FILE_INVALID_NAME)));
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/omadm/XMLParserTest.java b/wifi/tests/src/android/net/wifi/hotspot2/omadm/XMLParserTest.java
deleted file mode 100644
index 85d0a90..0000000
--- a/wifi/tests/src/android/net/wifi/hotspot2/omadm/XMLParserTest.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.hotspot2.omadm;
-
-import static org.junit.Assert.assertTrue;
-
-import android.net.wifi.hotspot2.omadm.XMLNode;
-import android.net.wifi.hotspot2.omadm.XMLParser;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.xml.sax.SAXException;
-
-import java.io.IOException;
-
-/**
- * Unit tests for {@link android.net.wifi.hotspot2.omadm.XMLParser}.
- */
-@SmallTest
-public class XMLParserTest {
-    XMLParser mParser;
-
-    private static XMLNode createNode(XMLNode parent, String tag, String text) {
-        XMLNode node = new XMLNode(parent, tag);
-        node.addText(text);
-        if (parent != null)
-            parent.addChild(node);
-        node.close();
-        return node;
-    }
-
-    /**
-     * Setup before tests.
-     */
-    @Before
-    public void setUp() throws Exception {
-        mParser = new XMLParser();
-    }
-
-    @Test(expected = IOException.class)
-    public void parseNullXML() throws Exception {
-        mParser.parse(null);
-    }
-
-    @Test(expected = IOException.class)
-    public void parseEmptyXML() throws Exception {
-        mParser.parse(new String());
-    }
-
-    @Test(expected = SAXException.class)
-    public void parseMalformedXML() throws Exception {
-        String malformedXmlTree = "<root><child1>test1</child2></root>";
-        mParser.parse(malformedXmlTree);
-    }
-
-    @Test
-    public void parseValidXMLTree() throws Exception {
-        String xmlTree = "<root><child1>test1</child1><child2>test2</child2></root>";
-
-        // Construct the expected XML tree.
-        XMLNode expectedRoot = createNode(null, "root", "");
-        createNode(expectedRoot, "child1", "test1");
-        createNode(expectedRoot, "child2", "test2");
-
-        XMLNode actualRoot = mParser.parse(xmlTree);
-        assertTrue(actualRoot.equals(expectedRoot));
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java b/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java
deleted file mode 100644
index a44df40..0000000
--- a/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java
+++ /dev/null
@@ -1,636 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package android.net.wifi.hotspot2.pps;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertTrue;
-
-import android.net.wifi.EAPConstants;
-import android.net.wifi.FakeKeys;
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.X509Certificate;
-
-/**
- * Unit tests for {@link android.net.wifi.hotspot2.pps.CredentialTest}.
- */
-@SmallTest
-public class CredentialTest {
-    /**
-     * Helper function for generating Credential for testing.
-     *
-     * @param userCred Instance of UserCredential
-     * @param certCred Instance of CertificateCredential
-     * @param simCred Instance of SimCredential
-     * @param clientCertificateChain Chain of client certificates
-     * @param clientPrivateKey Client private key
-     * @param caCerts CA certificates
-     * @return {@link Credential}
-     */
-    private static Credential createCredential(Credential.UserCredential userCred,
-            Credential.CertificateCredential certCred,
-            Credential.SimCredential simCred,
-            X509Certificate[] clientCertificateChain, PrivateKey clientPrivateKey,
-            X509Certificate... caCerts) {
-        Credential cred = new Credential();
-        cred.setCreationTimeInMillis(123455L);
-        cred.setExpirationTimeInMillis(2310093L);
-        cred.setRealm("realm");
-        cred.setCheckAaaServerCertStatus(true);
-        cred.setUserCredential(userCred);
-        cred.setCertCredential(certCred);
-        cred.setSimCredential(simCred);
-        if (caCerts != null && caCerts.length == 1) {
-            cred.setCaCertificate(caCerts[0]);
-        } else {
-            cred.setCaCertificates(caCerts);
-        }
-        cred.setClientCertificateChain(clientCertificateChain);
-        cred.setClientPrivateKey(clientPrivateKey);
-        return cred;
-    }
-
-    /**
-     * Helper function for generating certificate credential for testing.
-     *
-     * @return {@link Credential}
-     */
-    private static Credential createCredentialWithCertificateCredential()
-            throws NoSuchAlgorithmException, CertificateEncodingException {
-        Credential.CertificateCredential certCred = new Credential.CertificateCredential();
-        certCred.setCertType("x509v3");
-        certCred.setCertSha256Fingerprint(
-                MessageDigest.getInstance("SHA-256").digest(FakeKeys.CLIENT_CERT.getEncoded()));
-        return createCredential(null, certCred, null, new X509Certificate[] {FakeKeys.CLIENT_CERT},
-                FakeKeys.RSA_KEY1, FakeKeys.CA_CERT0, FakeKeys.CA_CERT1);
-    }
-
-    /**
-     * Helper function for generating SIM credential for testing.
-     *
-     * @return {@link Credential}
-     */
-    private static Credential createCredentialWithSimCredential() {
-        Credential.SimCredential simCred = new Credential.SimCredential();
-        simCred.setImsi("1234*");
-        simCred.setEapType(EAPConstants.EAP_SIM);
-        return createCredential(null, null, simCred, null, null, (X509Certificate[]) null);
-    }
-
-    /**
-     * Helper function for generating user credential for testing.
-     *
-     * @return {@link Credential}
-     */
-    private static Credential createCredentialWithUserCredential() {
-        Credential.UserCredential userCred = new Credential.UserCredential();
-        userCred.setUsername("username");
-        userCred.setPassword("password");
-        userCred.setMachineManaged(true);
-        userCred.setAbleToShare(true);
-        userCred.setSoftTokenApp("TestApp");
-        userCred.setEapType(EAPConstants.EAP_TTLS);
-        userCred.setNonEapInnerMethod("MS-CHAP");
-        return createCredential(userCred, null, null, null, null, FakeKeys.CA_CERT0);
-    }
-
-    private static void verifyParcel(Credential writeCred) {
-        Parcel parcel = Parcel.obtain();
-        writeCred.writeToParcel(parcel, 0);
-
-        parcel.setDataPosition(0);    // Rewind data position back to the beginning for read.
-        Credential readCred = Credential.CREATOR.createFromParcel(parcel);
-        assertTrue(readCred.equals(writeCred));
-        assertEquals(writeCred.hashCode(), readCred.hashCode());
-    }
-
-    /**
-     * Verify parcel read/write for a default/empty credential.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void verifyParcelWithDefault() throws Exception {
-        verifyParcel(new Credential());
-    }
-
-    /**
-     * Verify parcel read/write for a certificate credential.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void verifyParcelWithCertificateCredential() throws Exception {
-        verifyParcel(createCredentialWithCertificateCredential());
-    }
-
-    /**
-     * Verify parcel read/write for a SIM credential.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void verifyParcelWithSimCredential() throws Exception {
-        verifyParcel(createCredentialWithSimCredential());
-    }
-
-    /**
-     * Verify parcel read/write for a user credential.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void verifyParcelWithUserCredential() throws Exception {
-        verifyParcel(createCredentialWithUserCredential());
-    }
-
-    /**
-     * Verify a valid user credential.
-     * @throws Exception
-     */
-    @Test
-    public void validateUserCredential() throws Exception {
-        Credential cred = createCredentialWithUserCredential();
-
-        // For R1 validation
-        assertTrue(cred.validate());
-
-        // For R2 validation
-        assertTrue(cred.validate());
-    }
-
-    /**
-     * Verify that a user credential without CA Certificate is valid.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateUserCredentialWithoutCaCert() throws Exception {
-        Credential cred = createCredentialWithUserCredential();
-        cred.setCaCertificate(null);
-
-        // Accept a configuration with no CA certificate, the system will use the default cert store
-        assertTrue(cred.validate());
-    }
-
-    /**
-     * Verify that a user credential with EAP type other than EAP-TTLS is invalid.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateUserCredentialWithEapTls() throws Exception {
-        Credential cred = createCredentialWithUserCredential();
-        cred.getUserCredential().setEapType(EAPConstants.EAP_TLS);
-
-        // For R1 validation
-        assertFalse(cred.validate());
-
-        // For R2 validation
-        assertFalse(cred.validate());
-    }
-
-
-    /**
-     * Verify that a user credential without realm is invalid.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateUserCredentialWithoutRealm() throws Exception {
-        Credential cred = createCredentialWithUserCredential();
-        cred.setRealm(null);
-
-        // For R1 validation
-        assertFalse(cred.validate());
-
-        // For R2 validation
-        assertFalse(cred.validate());
-    }
-
-    /**
-     * Verify that a user credential without username is invalid.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateUserCredentialWithoutUsername() throws Exception {
-        Credential cred = createCredentialWithUserCredential();
-        cred.getUserCredential().setUsername(null);
-
-        // For R1 validation
-        assertFalse(cred.validate());
-
-        // For R2 validation
-        assertFalse(cred.validate());
-    }
-
-    /**
-     * Verify that a user credential without password is invalid.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateUserCredentialWithoutPassword() throws Exception {
-        Credential cred = createCredentialWithUserCredential();
-        cred.getUserCredential().setPassword(null);
-
-        // For R1 validation
-        assertFalse(cred.validate());
-
-        // For R2 validation
-        assertFalse(cred.validate());
-    }
-
-    /**
-     * Verify that a user credential without auth methoh (non-EAP inner method) is invalid.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateUserCredentialWithoutAuthMethod() throws Exception {
-        Credential cred = createCredentialWithUserCredential();
-        cred.getUserCredential().setNonEapInnerMethod(null);
-
-        // For R1 validation
-        assertFalse(cred.validate());
-
-        // For R2 validation
-        assertFalse(cred.validate());
-    }
-
-    /**
-     * Verify a certificate credential. CA Certificate, client certificate chain,
-     * and client private key are all required.  Also the digest for client
-     * certificate must match the fingerprint specified in the certificate credential.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateCertCredential() throws Exception {
-        Credential cred = createCredentialWithCertificateCredential();
-
-        // For R1 validation
-        assertTrue(cred.validate());
-
-        // For R2 validation
-        assertTrue(cred.validate());
-    }
-
-    /**
-     * Verify that an certificate credential without CA Certificate is invalid.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateCertCredentialWithoutCaCert() throws Exception {
-        Credential cred = createCredentialWithCertificateCredential();
-        cred.setCaCertificate(null);
-
-        // Accept a configuration with no CA certificate, the system will use the default cert store
-        assertTrue(cred.validate());
-    }
-
-    /**
-     * Verify that a certificate credential without client certificate chain is invalid.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateCertCredentialWithoutClientCertChain() throws Exception {
-        Credential cred = createCredentialWithCertificateCredential();
-        cred.setClientCertificateChain(null);
-
-        // For R1 validation
-        assertFalse(cred.validate());
-
-        // For R2 validation
-        assertFalse(cred.validate());
-    }
-
-    /**
-     * Verify that a certificate credential without client private key is invalid.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateCertCredentialWithoutClientPrivateKey() throws Exception {
-        Credential cred = createCredentialWithCertificateCredential();
-        cred.setClientPrivateKey(null);
-
-        // For R1 validation
-        assertFalse(cred.validate());
-
-        // For R2 validation
-        assertFalse(cred.validate());
-    }
-
-    /**
-     * Verify that a certificate credential with mismatch client certificate fingerprint
-     * is invalid.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateCertCredentialWithMismatchFingerprint() throws Exception {
-        Credential cred = createCredentialWithCertificateCredential();
-        cred.getCertCredential().setCertSha256Fingerprint(new byte[32]);
-
-        // For R1 validation
-        assertFalse(cred.validate());
-
-        // For R2 validation
-        assertFalse(cred.validate());
-    }
-
-    /**
-     * Verify a SIM credential using EAP-SIM.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateSimCredentialWithEapSim() throws Exception {
-        Credential cred = createCredentialWithSimCredential();
-
-        // For R1 validation
-        assertTrue(cred.validate());
-
-        // For R2 validation
-        assertTrue(cred.validate());
-    }
-
-    /**
-     * Verify a SIM credential using EAP-AKA.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateSimCredentialWithEapAka() throws Exception {
-        Credential cred = createCredentialWithSimCredential();
-        cred.getSimCredential().setEapType(EAPConstants.EAP_AKA);
-
-        // For R1 validation
-        assertTrue(cred.validate());
-
-        // For R2 validation
-        assertTrue(cred.validate());
-    }
-
-    /**
-     * Verify a SIM credential using EAP-AKA-PRIME.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateSimCredentialWithEapAkaPrime() throws Exception {
-        Credential cred = createCredentialWithSimCredential();
-        cred.getSimCredential().setEapType(EAPConstants.EAP_AKA_PRIME);
-
-        // For R1 validation
-        assertTrue(cred.validate());
-
-        // For R2 validation
-        assertTrue(cred.validate());
-    }
-
-    /**
-     * Verify that a SIM credential without IMSI is invalid.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateSimCredentialWithoutIMSI() throws Exception {
-        Credential cred = createCredentialWithSimCredential();
-        cred.getSimCredential().setImsi(null);
-
-        // For R1 validation
-        assertFalse(cred.validate());
-
-        // For R2 validation
-        assertFalse(cred.validate());
-    }
-
-    /**
-     * Verify that a SIM credential with an invalid IMSI is invalid.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateSimCredentialWithInvalidIMSI() throws Exception {
-        Credential cred = createCredentialWithSimCredential();
-        cred.getSimCredential().setImsi("dummy");
-
-        // For R1 validation
-        assertFalse(cred.validate());
-
-        // For R2 validation
-        assertFalse(cred.validate());
-    }
-
-    /**
-     * Verify that a SIM credential with invalid EAP type is invalid.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateSimCredentialWithEapTls() throws Exception {
-        Credential cred = createCredentialWithSimCredential();
-        cred.getSimCredential().setEapType(EAPConstants.EAP_TLS);
-
-        // For R1 validation
-        assertFalse(cred.validate());
-
-        // For R2 validation
-        assertFalse(cred.validate());
-    }
-
-    /**
-     * Verify that a credential contained both a user and a SIM credential is invalid.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateCredentialWithUserAndSimCredential() throws Exception {
-        Credential cred = createCredentialWithUserCredential();
-        // Setup SIM credential.
-        Credential.SimCredential simCredential = new Credential.SimCredential();
-        simCredential.setImsi("1234*");
-        simCredential.setEapType(EAPConstants.EAP_SIM);
-        cred.setSimCredential(simCredential);
-
-        // For R1 validation
-        assertFalse(cred.validate());
-
-        // For R2 validation
-        assertFalse(cred.validate());
-    }
-
-    /**
-     * Verify that copy constructor works when pass in a null source.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateCopyConstructorWithNullSource() throws Exception {
-        Credential copyCred = new Credential(null);
-        Credential defaultCred = new Credential();
-        assertTrue(copyCred.equals(defaultCred));
-    }
-
-    /**
-     * Verify that copy constructor works when pass in a source with user credential.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateCopyConstructorWithSourceWithUserCred() throws Exception {
-        Credential sourceCred = createCredentialWithUserCredential();
-        Credential copyCred = new Credential(sourceCred);
-        assertTrue(copyCred.equals(sourceCred));
-    }
-
-    /**
-     * Verify that copy constructor works when pass in a source with certificate credential.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateCopyConstructorWithSourceWithCertCred() throws Exception {
-        Credential sourceCred = createCredentialWithCertificateCredential();
-        Credential copyCred = new Credential(sourceCred);
-        assertTrue(copyCred.equals(sourceCred));
-    }
-
-    /**
-     * Verify that copy constructor works when pass in a source with SIM credential.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateCopyConstructorWithSourceWithSimCred() throws Exception {
-        Credential sourceCred = createCredentialWithSimCredential();
-        Credential copyCred = new Credential(sourceCred);
-        assertTrue(copyCred.equals(sourceCred));
-    }
-
-    /**
-     * Verify that two certificates are identical.
-     */
-    @Test
-    public void validateTwoCertificateIdentical() {
-        assertTrue(Credential.isX509CertificateEquals(FakeKeys.CA_CERT1, FakeKeys.CA_CERT1));
-    }
-
-    /**
-     * Verify that two certificates are different.
-     */
-    @Test
-    public void validateTwoCertificateDifferent() {
-        assertFalse(Credential.isX509CertificateEquals(FakeKeys.CA_CERT0, FakeKeys.CA_CERT1));
-    }
-
-    /**
-     * Verify that unique identifiers are the same for objects with the same credentials
-     */
-    @Test
-    public void testUniqueIdSameCredentialTypes() throws Exception {
-        assertEquals(createCredentialWithSimCredential().getUniqueId(),
-                createCredentialWithSimCredential().getUniqueId());
-        assertEquals(createCredentialWithCertificateCredential().getUniqueId(),
-                createCredentialWithCertificateCredential().getUniqueId());
-        assertEquals(createCredentialWithUserCredential().getUniqueId(),
-                createCredentialWithUserCredential().getUniqueId());
-    }
-
-    /**
-     * Verify that unique identifiers are different for each credential
-     */
-    @Test
-    public void testUniqueIdDifferentForDifferentCredentialTypes() throws Exception {
-        Credential simCred = createCredentialWithSimCredential();
-        Credential certCred = createCredentialWithCertificateCredential();
-        Credential userCred = createCredentialWithUserCredential();
-
-        assertNotEquals(simCred.getUniqueId(), userCred.getUniqueId());
-        assertNotEquals(simCred.getUniqueId(), certCred.getUniqueId());
-        assertNotEquals(certCred.getUniqueId(), userCred.getUniqueId());
-    }
-
-    /**
-     * Verify that unique identifiers are different for a credential with different values
-     */
-    @Test
-    public void testUniqueIdDifferentForSimCredentialsWithDifferentValues() throws Exception {
-        Credential simCred1 = createCredentialWithSimCredential();
-        Credential simCred2 = createCredentialWithSimCredential();
-        simCred2.getSimCredential().setImsi("567890*");
-
-        assertNotEquals(simCred1.getUniqueId(), simCred2.getUniqueId());
-    }
-
-    /**
-     * Verify that unique identifiers are different for a credential with different username
-     */
-    @Test
-    public void testUniqueIdDifferentForUserCredentialsWithDifferentUsername() throws Exception {
-        Credential userCred1 = createCredentialWithUserCredential();
-        Credential userCred2 = createCredentialWithUserCredential();
-        userCred2.getUserCredential().setUsername("anotheruser");
-
-        assertNotEquals(userCred1.getUniqueId(), userCred2.getUniqueId());
-    }
-
-    /**
-     * Verify that unique identifiers are different for a credential with different password and
-     * other values other than username
-     */
-    @Test
-    public void testUniqueIdSameForUserCredentialsWithDifferentPassword() throws Exception {
-        Credential userCred1 = createCredentialWithUserCredential();
-        Credential userCred2 = createCredentialWithUserCredential();
-        userCred2.getUserCredential().setPassword("someotherpassword!");
-        userCred2.getUserCredential().setMachineManaged(false);
-        userCred2.getUserCredential().setAbleToShare(false);
-        userCred2.getUserCredential().setSoftTokenApp("TestApp2");
-        userCred2.getUserCredential().setNonEapInnerMethod("PAP");
-
-        assertEquals(userCred1.getUniqueId(), userCred2.getUniqueId());
-    }
-
-    /**
-     * Verify that unique identifiers are different for a cert credential with different values
-     */
-    @Test
-    public void testUniqueIdDifferentForCertCredentialsWithDifferentValues() throws Exception {
-        Credential certCred1 = createCredentialWithCertificateCredential();
-        Credential certCred2 = createCredentialWithCertificateCredential();
-        certCred2.getCertCredential().setCertSha256Fingerprint(
-                MessageDigest.getInstance("SHA-256").digest(FakeKeys.CA_CERT0.getEncoded()));
-
-        assertNotEquals(certCred1.getUniqueId(), certCred2.getUniqueId());
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/pps/HomeSpTest.java b/wifi/tests/src/android/net/wifi/hotspot2/pps/HomeSpTest.java
deleted file mode 100644
index 93d471a..0000000
--- a/wifi/tests/src/android/net/wifi/hotspot2/pps/HomeSpTest.java
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package android.net.wifi.hotspot2.pps;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Unit tests for {@link android.net.wifi.hotspot2.pps.HomeSp}.
- */
-@SmallTest
-public class HomeSpTest {
-
-    /**
-     * Helper function for creating a map of home network IDs for testing.
-     *
-     * @return Map of home network IDs
-     */
-    private static Map<String, Long> createHomeNetworkIds() {
-        Map<String, Long> homeNetworkIds = new HashMap<>();
-        homeNetworkIds.put("ssid", 0x1234L);
-        homeNetworkIds.put("nullhessid", null);
-        return homeNetworkIds;
-    }
-
-    /**
-     * Helper function for creating a HomeSp for testing.
-     *
-     * @param homeNetworkIds The map of home network IDs associated with HomeSp
-     * @return {@link HomeSp}
-     */
-    private static HomeSp createHomeSp(Map<String, Long> homeNetworkIds) {
-        HomeSp homeSp = new HomeSp();
-        homeSp.setFqdn("fqdn");
-        homeSp.setFriendlyName("friendly name");
-        homeSp.setIconUrl("icon.url");
-        homeSp.setHomeNetworkIds(homeNetworkIds);
-        homeSp.setMatchAllOis(new long[] {0x11L, 0x22L});
-        homeSp.setMatchAnyOis(new long[] {0x33L, 0x44L});
-        homeSp.setOtherHomePartners(new String[] {"partner1", "partner2"});
-        homeSp.setRoamingConsortiumOis(new long[] {0x55, 0x66});
-        return homeSp;
-    }
-
-    /**
-     * Helper function for creating a HomeSp with home network IDs for testing.
-     *
-     * @return {@link HomeSp}
-     */
-    private static HomeSp createHomeSpWithHomeNetworkIds() {
-        return createHomeSp(createHomeNetworkIds());
-    }
-
-    /**
-     * Helper function for creating a HomeSp without home network IDs for testing.
-     *
-     * @return {@link HomeSp}
-     */
-    private static HomeSp createHomeSpWithoutHomeNetworkIds() {
-        return createHomeSp(null);
-    }
-
-    /**
-     * Helper function for verifying HomeSp after parcel write then read.
-     * @param writeHomeSp
-     * @throws Exception
-     */
-    private static void verifyParcel(HomeSp writeHomeSp) throws Exception {
-        Parcel parcel = Parcel.obtain();
-        writeHomeSp.writeToParcel(parcel, 0);
-
-        parcel.setDataPosition(0);    // Rewind data position back to the beginning for read.
-        HomeSp readHomeSp = HomeSp.CREATOR.createFromParcel(parcel);
-        assertTrue(readHomeSp.equals(writeHomeSp));
-    }
-
-    /**
-     * Verify parcel read/write for an empty HomeSp.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void verifyParcelWithEmptyHomeSp() throws Exception {
-        verifyParcel(new HomeSp());
-    }
-
-    /**
-     * Verify parcel read/write for a HomeSp containing Home Network IDs.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void verifyParcelWithHomeNetworkIds() throws Exception {
-        verifyParcel(createHomeSpWithHomeNetworkIds());
-    }
-
-    /**
-     * Verify parcel read/write for a HomeSp without Home Network IDs.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void verifyParcelWithoutHomeNetworkIds() throws Exception {
-        verifyParcel(createHomeSpWithoutHomeNetworkIds());
-    }
-
-    /**
-     * Verify that a HomeSp is valid when both FQDN and Friendly Name
-     * are provided.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateValidHomeSp() throws Exception {
-        HomeSp homeSp = createHomeSpWithHomeNetworkIds();
-        assertTrue(homeSp.validate());
-    }
-
-    /**
-     * Verify that a HomeSp is not valid when FQDN is not provided
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateHomeSpWithoutFqdn() throws Exception {
-        HomeSp homeSp = createHomeSpWithHomeNetworkIds();
-        homeSp.setFqdn(null);
-        assertFalse(homeSp.validate());
-    }
-
-    /**
-     * Verify that a HomeSp is not valid when Friendly Name is not provided
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateHomeSpWithoutFriendlyName() throws Exception {
-        HomeSp homeSp = createHomeSpWithHomeNetworkIds();
-        homeSp.setFriendlyName(null);
-        assertFalse(homeSp.validate());
-    }
-
-    /**
-     * Verify that a HomeSp is valid when the optional Home Network IDs are
-     * not provided.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateHomeSpWithoutHomeNetworkIds() throws Exception {
-        HomeSp homeSp = createHomeSpWithoutHomeNetworkIds();
-        assertTrue(homeSp.validate());
-    }
-
-    /**
-     * Verify that a HomeSp is invalid when the optional Home Network IDs
-     * contained an invalid SSID (exceeding maximum number of bytes).
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateHomeSpWithInvalidHomeNetworkIds() throws Exception {
-        HomeSp homeSp = createHomeSpWithoutHomeNetworkIds();
-        // HomeNetworkID with SSID exceeding the maximum length.
-        Map<String, Long> homeNetworkIds = new HashMap<>();
-        byte[] rawSsidBytes = new byte[33];
-        Arrays.fill(rawSsidBytes, (byte) 'a');
-        homeNetworkIds.put(new String(rawSsidBytes, StandardCharsets.UTF_8), 0x1234L);
-        homeSp.setHomeNetworkIds(homeNetworkIds);
-        assertFalse(homeSp.validate());
-    }
-
-    /**
-     * Verify that copy constructor works when pass in a null source.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateCopyConstructorFromNullSource() throws Exception {
-        HomeSp copySp = new HomeSp(null);
-        HomeSp defaultSp = new HomeSp();
-        assertTrue(copySp.equals(defaultSp));
-    }
-
-    /**
-     * Verify that copy constructor works when pass in a valid source.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateCopyConstructorFromValidSource() throws Exception {
-        HomeSp sourceSp = createHomeSpWithHomeNetworkIds();
-        HomeSp copySp = new HomeSp(sourceSp);
-        assertTrue(copySp.equals(sourceSp));
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/pps/PolicyTest.java b/wifi/tests/src/android/net/wifi/hotspot2/pps/PolicyTest.java
deleted file mode 100644
index 980b199..0000000
--- a/wifi/tests/src/android/net/wifi/hotspot2/pps/PolicyTest.java
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package android.net.wifi.hotspot2.pps;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import android.os.Parcel;
-import android.util.Base64;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Unit tests for {@link android.net.wifi.hotspot2.pps.Policy}.
- */
-@SmallTest
-public class PolicyTest {
-    private static final int MAX_NUMBER_OF_EXCLUDED_SSIDS = 128;
-    private static final int MAX_SSID_BYTES = 32;
-    private static final int MAX_PORT_STRING_BYTES = 64;
-
-    /**
-     * Helper function for creating a {@link Policy} for testing.
-     *
-     * @return {@link Policy}
-     */
-    private static Policy createPolicy() {
-        Policy policy = new Policy();
-        policy.setMinHomeDownlinkBandwidth(123);
-        policy.setMinHomeUplinkBandwidth(345);
-        policy.setMinRoamingDownlinkBandwidth(567);
-        policy.setMinRoamingUplinkBandwidth(789);
-        policy.setExcludedSsidList(new String[] {"ssid1", "ssid2"});
-        Map<Integer, String> requiredProtoPortMap = new HashMap<>();
-        requiredProtoPortMap.put(12, "23,342,123");
-        requiredProtoPortMap.put(23, "789,372,1235");
-        policy.setRequiredProtoPortMap(requiredProtoPortMap);
-        policy.setMaximumBssLoadValue(12);
-
-        List<Policy.RoamingPartner> preferredRoamingPartnerList = new ArrayList<>();
-        Policy.RoamingPartner partner1 = new Policy.RoamingPartner();
-        partner1.setFqdn("partner1.com");
-        partner1.setFqdnExactMatch(true);
-        partner1.setPriority(12);
-        partner1.setCountries("us,jp");
-        Policy.RoamingPartner partner2 = new Policy.RoamingPartner();
-        partner2.setFqdn("partner2.com");
-        partner2.setFqdnExactMatch(false);
-        partner2.setPriority(42);
-        partner2.setCountries("ca,fr");
-        preferredRoamingPartnerList.add(partner1);
-        preferredRoamingPartnerList.add(partner2);
-        policy.setPreferredRoamingPartnerList(preferredRoamingPartnerList);
-
-        UpdateParameter policyUpdate = new UpdateParameter();
-        policyUpdate.setUpdateIntervalInMinutes(1712);
-        policyUpdate.setUpdateMethod(UpdateParameter.UPDATE_METHOD_OMADM);
-        policyUpdate.setRestriction(UpdateParameter.UPDATE_RESTRICTION_HOMESP);
-        policyUpdate.setServerUri("policy.update.com");
-        policyUpdate.setUsername("username");
-        policyUpdate.setBase64EncodedPassword(
-                Base64.encodeToString("password".getBytes(), Base64.DEFAULT));
-        policyUpdate.setTrustRootCertUrl("trust.cert.com");
-        policyUpdate.setTrustRootCertSha256Fingerprint(new byte[32]);
-        policy.setPolicyUpdate(policyUpdate);
-
-        return policy;
-    }
-
-    /**
-     * Helper function for verifying Policy after parcel write then read.
-     * @param policyToWrite
-     * @throws Exception
-     */
-    private static void verifyParcel(Policy policyToWrite) throws Exception {
-        Parcel parcel = Parcel.obtain();
-        policyToWrite.writeToParcel(parcel, 0);
-
-        parcel.setDataPosition(0);    // Rewind data position back to the beginning for read.
-        Policy policyFromRead = Policy.CREATOR.createFromParcel(parcel);
-        assertTrue(policyFromRead.equals(policyToWrite));
-    }
-
-    /**
-     * Verify parcel read/write for an empty Policy.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void verifyParcelWithEmptyPolicy() throws Exception {
-        verifyParcel(new Policy());
-    }
-
-    /**
-     * Verify parcel read/write for a Policy with all fields set.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void verifyParcelWithFullPolicy() throws Exception {
-        verifyParcel(createPolicy());
-    }
-
-    /**
-     * Verify parcel read/write for a Policy without protocol port map.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void verifyParcelWithoutProtoPortMap() throws Exception {
-        Policy policy = createPolicy();
-        policy.setRequiredProtoPortMap(null);
-        verifyParcel(policy);
-    }
-
-    /**
-     * Verify parcel read/write for a Policy without preferred roaming partner list.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void verifyParcelWithoutPreferredRoamingPartnerList() throws Exception {
-        Policy policy = createPolicy();
-        policy.setPreferredRoamingPartnerList(null);
-        verifyParcel(policy);
-    }
-
-    /**
-     * Verify parcel read/write for a Policy without policy update parameters.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void verifyParcelWithoutPolicyUpdate() throws Exception {
-        Policy policy = createPolicy();
-        policy.setPolicyUpdate(null);
-        verifyParcel(policy);
-    }
-
-    /**
-     * Verify that policy created using copy constructor with null source should be the same
-     * as the policy created using default constructor.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void verifyCopyConstructionWithNullSource() throws Exception {
-        Policy copyPolicy = new Policy(null);
-        Policy defaultPolicy = new Policy();
-        assertTrue(defaultPolicy.equals(copyPolicy));
-    }
-
-    /**
-     * Verify that policy created using copy constructor with a valid source should be the
-     * same as the source.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void verifyCopyConstructionWithFullPolicy() throws Exception {
-        Policy policy = createPolicy();
-        Policy copyPolicy = new Policy(policy);
-        assertTrue(policy.equals(copyPolicy));
-    }
-
-    /**
-     * Verify that a default policy (with no informatio) is invalid.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validatePolicyWithDefault() throws Exception {
-        Policy policy = new Policy();
-        assertFalse(policy.validate());
-    }
-
-    /**
-     * Verify that a policy created using {@link #createPolicy} is valid, since all fields are
-     * filled in with valid values.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validatePolicyWithFullPolicy() throws Exception {
-        assertTrue(createPolicy().validate());
-    }
-
-    /**
-     * Verify that a policy without policy update parameters is invalid.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validatePolicyWithoutPolicyUpdate() throws Exception {
-        Policy policy = createPolicy();
-        policy.setPolicyUpdate(null);
-        assertFalse(policy.validate());
-    }
-
-    /**
-     * Verify that a policy with invalid policy update parameters is invalid.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validatePolicyWithInvalidPolicyUpdate() throws Exception {
-        Policy policy = createPolicy();
-        policy.setPolicyUpdate(new UpdateParameter());
-        assertFalse(policy.validate());
-    }
-
-    /**
-     * Verify that a policy with a preferred roaming partner with FQDN not specified is invalid.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validatePolicyWithRoamingPartnerWithoutFQDN() throws Exception {
-        Policy policy = createPolicy();
-        Policy.RoamingPartner partner = new Policy.RoamingPartner();
-        partner.setFqdnExactMatch(true);
-        partner.setPriority(12);
-        partner.setCountries("us,jp");
-        policy.getPreferredRoamingPartnerList().add(partner);
-        assertFalse(policy.validate());
-    }
-
-    /**
-     * Verify that a policy with a preferred roaming partner with countries not specified is
-     * invalid.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validatePolicyWithRoamingPartnerWithoutCountries() throws Exception {
-        Policy policy = createPolicy();
-        Policy.RoamingPartner partner = new Policy.RoamingPartner();
-        partner.setFqdn("test.com");
-        partner.setFqdnExactMatch(true);
-        partner.setPriority(12);
-        policy.getPreferredRoamingPartnerList().add(partner);
-        assertFalse(policy.validate());
-    }
-
-    /**
-     * Verify that a policy with a proto-port tuple that contains an invalid port string is
-     * invalid.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validatePolicyWithInvalidPortStringInProtoPortMap() throws Exception {
-        Policy policy = createPolicy();
-        byte[] rawPortBytes = new byte[MAX_PORT_STRING_BYTES + 1];
-        policy.getRequiredProtoPortMap().put(
-                324, new String(rawPortBytes, StandardCharsets.UTF_8));
-        assertFalse(policy.validate());
-    }
-
-    /**
-     * Verify that a policy with number of excluded SSIDs exceeded the max is invalid.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validatePolicyWithSsidExclusionListSizeExceededMax() throws Exception {
-        Policy policy = createPolicy();
-        String[] excludedSsidList = new String[MAX_NUMBER_OF_EXCLUDED_SSIDS + 1];
-        Arrays.fill(excludedSsidList, "ssid");
-        policy.setExcludedSsidList(excludedSsidList);
-        assertFalse(policy.validate());
-    }
-
-    /**
-     * Verify that a policy with an invalid SSID in the excluded SSID list is invalid.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validatePolicyWithInvalidSsid() throws Exception {
-        Policy policy = createPolicy();
-        byte[] rawSsidBytes = new byte[MAX_SSID_BYTES + 1];
-        Arrays.fill(rawSsidBytes, (byte) 'a');
-        String[] excludedSsidList = new String[] {
-                new String(rawSsidBytes, StandardCharsets.UTF_8)};
-        policy.setExcludedSsidList(excludedSsidList);
-        assertFalse(policy.validate());
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/pps/UpdateParameterTest.java b/wifi/tests/src/android/net/wifi/hotspot2/pps/UpdateParameterTest.java
deleted file mode 100644
index 07cb151..0000000
--- a/wifi/tests/src/android/net/wifi/hotspot2/pps/UpdateParameterTest.java
+++ /dev/null
@@ -1,349 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package android.net.wifi.hotspot2.pps;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import android.net.wifi.FakeKeys;
-import android.os.Parcel;
-import android.util.Base64;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-
-/**
- * Unit tests for {@link android.net.wifi.hotspot2.pps.UpdateParameter}.
- */
-@SmallTest
-public class UpdateParameterTest {
-    private static final int MAX_URI_BYTES = 1023;
-    private static final int MAX_URL_BYTES = 1023;
-    private static final int MAX_USERNAME_BYTES = 63;
-    private static final int MAX_PASSWORD_BYTES = 255;
-    private static final int CERTIFICATE_SHA256_BYTES = 32;
-
-    /**
-     * Helper function for creating a {@link UpdateParameter} for testing.
-     *
-     * @return {@link UpdateParameter}
-     */
-    private static UpdateParameter createUpdateParameter() {
-        UpdateParameter updateParam = new UpdateParameter();
-        updateParam.setUpdateIntervalInMinutes(1712);
-        updateParam.setUpdateMethod(UpdateParameter.UPDATE_METHOD_OMADM);
-        updateParam.setRestriction(UpdateParameter.UPDATE_RESTRICTION_HOMESP);
-        updateParam.setServerUri("server.pdate.com");
-        updateParam.setUsername("username");
-        updateParam.setBase64EncodedPassword(
-                Base64.encodeToString("password".getBytes(), Base64.DEFAULT));
-        updateParam.setTrustRootCertUrl("trust.cert.com");
-        updateParam.setTrustRootCertSha256Fingerprint(new byte[32]);
-        updateParam.setCaCertificate(FakeKeys.CA_CERT0);
-        return updateParam;
-    }
-
-    /**
-     * Helper function for verifying UpdateParameter after parcel write then read.
-     * @param paramToWrite The UpdateParamter to verify
-     * @throws Exception
-     */
-    private static void verifyParcel(UpdateParameter paramToWrite) throws Exception {
-        Parcel parcel = Parcel.obtain();
-        paramToWrite.writeToParcel(parcel, 0);
-
-        parcel.setDataPosition(0);    // Rewind data position back to the beginning for read.
-        UpdateParameter paramFromRead = UpdateParameter.CREATOR.createFromParcel(parcel);
-        assertTrue(paramFromRead.equals(paramToWrite));
-        assertEquals(paramToWrite.hashCode(), paramFromRead.hashCode());
-    }
-
-    /**
-     * Verify parcel read/write for an empty UpdateParameter.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void verifyParcelWithEmptyUpdateParameter() throws Exception {
-        verifyParcel(new UpdateParameter());
-    }
-
-    /**
-     * Verify parcel read/write for a UpdateParameter with all fields set.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void verifyParcelWithFullUpdateParameter() throws Exception {
-        verifyParcel(createUpdateParameter());
-    }
-
-    /**
-     * Verify that UpdateParameter created using copy constructor with null source should be the
-     * same as the UpdateParameter created using default constructor.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void verifyCopyConstructionWithNullSource() throws Exception {
-        UpdateParameter copyParam = new UpdateParameter(null);
-        UpdateParameter defaultParam = new UpdateParameter();
-        assertTrue(defaultParam.equals(copyParam));
-    }
-
-    /**
-     * Verify that UpdateParameter created using copy constructor with a valid source should be the
-     * same as the source.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void verifyCopyConstructionWithFullUpdateParameter() throws Exception {
-        UpdateParameter origParam = createUpdateParameter();
-        UpdateParameter copyParam = new UpdateParameter(origParam);
-        assertTrue(origParam.equals(copyParam));
-    }
-
-    /**
-     * Verify that a default UpdateParameter is invalid.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateUpdateParameterWithDefault() throws Exception {
-        UpdateParameter updateParam = new UpdateParameter();
-        assertFalse(updateParam.validate());
-    }
-
-    /**
-     * Verify that an UpdateParameter created using {@link #createUpdateParameter} is valid,
-     * since all fields are filled in with valid values.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateUpdateParameterWithFullPolicy() throws Exception {
-        assertTrue(createUpdateParameter().validate());
-    }
-
-    /**
-     * Verify that an UpdateParameter with an unknown update method is invalid.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateUpdateParameterWithUnknowMethod() throws Exception {
-        UpdateParameter updateParam = createUpdateParameter();
-        updateParam.setUpdateMethod("adsfasd");
-        assertFalse(updateParam.validate());
-    }
-
-    /**
-     * Verify that an UpdateParameter with an unknown restriction is invalid.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateUpdateParameterWithUnknowRestriction() throws Exception {
-        UpdateParameter updateParam = createUpdateParameter();
-        updateParam.setRestriction("adsfasd");
-        assertFalse(updateParam.validate());
-    }
-
-    /**
-     * Verify that an UpdateParameter with an username exceeding maximum size is invalid.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateUpdateParameterWithUsernameExceedingMaxSize() throws Exception {
-        UpdateParameter updateParam = createUpdateParameter();
-        byte[] rawUsernameBytes = new byte[MAX_USERNAME_BYTES + 1];
-        Arrays.fill(rawUsernameBytes, (byte) 'a');
-        updateParam.setUsername(new String(rawUsernameBytes, StandardCharsets.UTF_8));
-        assertFalse(updateParam.validate());
-    }
-
-    /**
-     * Verify that an UpdateParameter with an empty username is invalid.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateUpdateParameterWithEmptyUsername() throws Exception {
-        UpdateParameter updateParam = createUpdateParameter();
-        updateParam.setUsername(null);
-        assertFalse(updateParam.validate());
-    }
-
-    /**
-     * Verify that an UpdateParameter with a password exceeding maximum size is invalid.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateUpdateParameterWithPasswordExceedingMaxSize() throws Exception {
-        UpdateParameter updateParam = createUpdateParameter();
-        byte[] rawPasswordBytes = new byte[MAX_PASSWORD_BYTES + 1];
-        Arrays.fill(rawPasswordBytes, (byte) 'a');
-        updateParam.setBase64EncodedPassword(new String(rawPasswordBytes, StandardCharsets.UTF_8));
-        assertFalse(updateParam.validate());
-    }
-
-    /**
-     * Verify that an UpdateParameter with an empty password is invalid.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateUpdateParameterWithEmptyPassword() throws Exception {
-        UpdateParameter updateParam = createUpdateParameter();
-        updateParam.setBase64EncodedPassword(null);
-        assertFalse(updateParam.validate());
-    }
-
-    /**
-     * Verify that an UpdateParameter with a Base64 encoded password that contained invalid padding
-     * is invalid.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateUpdateParameterWithPasswordContainedInvalidPadding() throws Exception {
-        UpdateParameter updateParam = createUpdateParameter();
-        updateParam.setBase64EncodedPassword(updateParam.getBase64EncodedPassword() + "=");
-        assertFalse(updateParam.validate());
-    }
-
-    /**
-     * Verify that an UpdateParameter without trust root certificate URL is invalid.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateUpdateParameterWithoutTrustRootCertUrl() throws Exception {
-        UpdateParameter updateParam = createUpdateParameter();
-        updateParam.setTrustRootCertUrl(null);
-        assertFalse(updateParam.validate());
-    }
-
-    /**
-     * Verify that an UpdateParameter with invalid trust root certificate URL is invalid.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateUpdateParameterWithInvalidTrustRootCertUrl() throws Exception {
-        UpdateParameter updateParam = createUpdateParameter();
-        byte[] rawUrlBytes = new byte[MAX_URL_BYTES + 1];
-        Arrays.fill(rawUrlBytes, (byte) 'a');
-        updateParam.setTrustRootCertUrl(new String(rawUrlBytes, StandardCharsets.UTF_8));
-        assertFalse(updateParam.validate());
-    }
-
-    /**
-     * Verify that an UpdateParameter without trust root certificate SHA-256 fingerprint is
-     * invalid.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateUpdateParameterWithouttrustRootCertSha256Fingerprint() throws Exception {
-        UpdateParameter updateParam = createUpdateParameter();
-        updateParam.setTrustRootCertSha256Fingerprint(null);
-        assertFalse(updateParam.validate());
-    }
-
-    /**
-     * Verify that an UpdateParameter with an incorrect size trust root certificate SHA-256
-     * fingerprint is invalid.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateUpdateParameterWithInvalidtrustRootCertSha256Fingerprint() throws Exception {
-        UpdateParameter updateParam = createUpdateParameter();
-        updateParam.setTrustRootCertSha256Fingerprint(new byte[CERTIFICATE_SHA256_BYTES + 1]);
-        assertFalse(updateParam.validate());
-
-        updateParam.setTrustRootCertSha256Fingerprint(new byte[CERTIFICATE_SHA256_BYTES - 1]);
-        assertFalse(updateParam.validate());
-    }
-
-    /**
-     * Verify that an UpdateParameter without server URI is invalid.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateUpdateParameterWithoutServerUri() throws Exception {
-        UpdateParameter updateParam = createUpdateParameter();
-        updateParam.setServerUri(null);
-        assertFalse(updateParam.validate());
-    }
-
-    /**
-     * Verify that an UpdateParameter with an invalid server URI is invalid.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validatePolicyWithInvalidServerUri() throws Exception {
-        UpdateParameter updateParam = createUpdateParameter();
-        byte[] rawUriBytes = new byte[MAX_URI_BYTES + 1];
-        Arrays.fill(rawUriBytes, (byte) 'a');
-        updateParam.setServerUri(new String(rawUriBytes, StandardCharsets.UTF_8));
-        assertFalse(updateParam.validate());
-    }
-
-    /**
-     * Verify that an UpdateParameter with update interval set to "never" will not perform
-     * validation on other parameters, since update is not applicable in this case.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateUpdateParameterWithNoServerCheck() throws Exception {
-        UpdateParameter updateParam = new UpdateParameter();
-        updateParam.setUpdateIntervalInMinutes(UpdateParameter.UPDATE_CHECK_INTERVAL_NEVER);
-        updateParam.setUsername(null);
-        updateParam.setBase64EncodedPassword(null);
-        updateParam.setUpdateMethod(null);
-        updateParam.setRestriction(null);
-        updateParam.setServerUri(null);
-        updateParam.setTrustRootCertUrl(null);
-        updateParam.setTrustRootCertSha256Fingerprint(null);
-        assertTrue(updateParam.validate());
-    }
-
-    /**
-     * Verify that an UpdateParameter with unset update interval is invalid.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void validateUpdateParameterWithoutUpdateInterval() throws Exception {
-        UpdateParameter updateParam = createUpdateParameter();
-        updateParam.setUpdateIntervalInMinutes(Long.MIN_VALUE);
-        assertFalse(updateParam.validate());
-    }
-}
diff --git a/wifi/non-updatable/tests/src/android/net/wifi/nl80211/DeviceWiphyCapabilitiesTest.java b/wifi/tests/src/android/net/wifi/nl80211/DeviceWiphyCapabilitiesTest.java
similarity index 100%
rename from wifi/non-updatable/tests/src/android/net/wifi/nl80211/DeviceWiphyCapabilitiesTest.java
rename to wifi/tests/src/android/net/wifi/nl80211/DeviceWiphyCapabilitiesTest.java
diff --git a/wifi/non-updatable/tests/src/android/net/wifi/nl80211/NativeScanResultTest.java b/wifi/tests/src/android/net/wifi/nl80211/NativeScanResultTest.java
similarity index 100%
rename from wifi/non-updatable/tests/src/android/net/wifi/nl80211/NativeScanResultTest.java
rename to wifi/tests/src/android/net/wifi/nl80211/NativeScanResultTest.java
diff --git a/wifi/non-updatable/tests/src/android/net/wifi/nl80211/PnoSettingsTest.java b/wifi/tests/src/android/net/wifi/nl80211/PnoSettingsTest.java
similarity index 100%
rename from wifi/non-updatable/tests/src/android/net/wifi/nl80211/PnoSettingsTest.java
rename to wifi/tests/src/android/net/wifi/nl80211/PnoSettingsTest.java
diff --git a/wifi/non-updatable/tests/src/android/net/wifi/nl80211/SingleScanSettingsTest.java b/wifi/tests/src/android/net/wifi/nl80211/SingleScanSettingsTest.java
similarity index 100%
rename from wifi/non-updatable/tests/src/android/net/wifi/nl80211/SingleScanSettingsTest.java
rename to wifi/tests/src/android/net/wifi/nl80211/SingleScanSettingsTest.java
diff --git a/wifi/non-updatable/tests/src/android/net/wifi/nl80211/WifiNl80211ManagerTest.java b/wifi/tests/src/android/net/wifi/nl80211/WifiNl80211ManagerTest.java
similarity index 100%
rename from wifi/non-updatable/tests/src/android/net/wifi/nl80211/WifiNl80211ManagerTest.java
rename to wifi/tests/src/android/net/wifi/nl80211/WifiNl80211ManagerTest.java
diff --git a/wifi/tests/src/android/net/wifi/p2p/WifiP2pConfigTest.java b/wifi/tests/src/android/net/wifi/p2p/WifiP2pConfigTest.java
deleted file mode 100644
index 6199325..0000000
--- a/wifi/tests/src/android/net/wifi/p2p/WifiP2pConfigTest.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-/**
- * Unit test harness for {@link android.net.wifi.p2p.WifiP2pConfig}
- */
-@SmallTest
-public class WifiP2pConfigTest {
-
-    private static final String DEVICE_ADDRESS = "aa:bb:cc:dd:ee:ff";
-    /**
-     * Check network name setter
-     */
-    @Test
-    public void testBuilderInvalidNetworkName() throws Exception {
-        WifiP2pConfig.Builder b = new WifiP2pConfig.Builder();
-
-        // sunny case
-        try {
-            b.setNetworkName("DIRECT-ab-Hello");
-        } catch (IllegalArgumentException e) {
-            fail("Unexpected IllegalArgumentException");
-        }
-
-        // sunny case, no trailing string
-        try {
-            b.setNetworkName("DIRECT-WR");
-        } catch (IllegalArgumentException e) {
-            fail("Unexpected IllegalArgumentException");
-        }
-
-        // sunny case with maximum bytes for the network name
-        try {
-            b.setNetworkName("DIRECT-abcdefghijklmnopqrstuvwxy");
-        } catch (IllegalArgumentException e) {
-            fail("Unexpected IllegalArgumentException");
-        }
-
-        // less than 9 characters.
-        try {
-            b.setNetworkName("DIRECT-z");
-            fail("expected IllegalArgumentException");
-        } catch (IllegalArgumentException e) { }
-
-        // not starts with DIRECT-xy.
-        try {
-            b.setNetworkName("ABCDEFGHIJK");
-            fail("expected IllegalArgumentException");
-        } catch (IllegalArgumentException e) { }
-
-        // not starts with uppercase DIRECT-xy
-        try {
-            b.setNetworkName("direct-ab");
-            fail("expected IllegalArgumentException");
-        } catch (IllegalArgumentException e) { }
-
-        // x and y are not selected from upper case letters, lower case letters or
-        // numbers.
-        try {
-            b.setNetworkName("direct-a?");
-            fail("expected IllegalArgumentException");
-        } catch (IllegalArgumentException e) { }
-
-        // over maximum bytes
-        try {
-            b.setNetworkName("DIRECT-abcdefghijklmnopqrstuvwxyz");
-            fail("expected IllegalArgumentException");
-        } catch (IllegalArgumentException e) { }
-    }
-
-    /**
-     * Check passphrase setter
-     */
-    @Test
-    public void testBuilderInvalidPassphrase() throws Exception {
-        WifiP2pConfig.Builder b = new WifiP2pConfig.Builder();
-
-        // sunny case
-        try {
-            b.setPassphrase("abcd1234");
-        } catch (IllegalArgumentException e) {
-            fail("Unexpected IllegalArgumentException");
-        }
-
-        // null string.
-        try {
-            b.setPassphrase(null);
-            fail("should throw IllegalArgumentException");
-        } catch (IllegalArgumentException e) {
-            // expected exception.
-        }
-
-        // less than 8 characters.
-        try {
-            b.setPassphrase("12abcde");
-            fail("should throw IllegalArgumentException");
-        } catch (IllegalArgumentException e) {
-            // expected exception.
-        }
-
-        // more than 63 characters.
-        try {
-            b.setPassphrase(
-                    "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890+/");
-            fail("should throw IllegalArgumentException");
-        } catch (IllegalArgumentException e) {
-            // expected exception.
-        }
-    }
-
-    @Test
-    /*
-     * Verify WifiP2pConfig basic operations
-     */
-    public void testWifiP2pConfig() throws Exception {
-        WifiP2pConfig config = new WifiP2pConfig();
-        config.deviceAddress = DEVICE_ADDRESS;
-
-        WifiP2pConfig copiedConfig = new WifiP2pConfig(config);
-        // no equals operator, use toString for comparison.
-        assertEquals(config.toString(), copiedConfig.toString());
-
-        Parcel parcelW = Parcel.obtain();
-        config.writeToParcel(parcelW, 0);
-        byte[] bytes = parcelW.marshall();
-        parcelW.recycle();
-
-        Parcel parcelR = Parcel.obtain();
-        parcelR.unmarshall(bytes, 0, bytes.length);
-        parcelR.setDataPosition(0);
-        WifiP2pConfig configFromParcel = WifiP2pConfig.CREATOR.createFromParcel(parcelR);
-
-        // no equals operator, use toString for comparison.
-        assertEquals(config.toString(), configFromParcel.toString());
-
-    }
-
-    @Test
-    /*
-     * Verify WifiP2pConfig invalidate API
-     */
-    public void testInvalidate() throws Exception {
-        WifiP2pConfig config = new WifiP2pConfig();
-        config.deviceAddress = DEVICE_ADDRESS;
-        config.invalidate();
-        assertEquals("", config.deviceAddress);
-    }
-
-}
diff --git a/wifi/tests/src/android/net/wifi/p2p/WifiP2pDeviceListTest.java b/wifi/tests/src/android/net/wifi/p2p/WifiP2pDeviceListTest.java
deleted file mode 100644
index 22936bd..0000000
--- a/wifi/tests/src/android/net/wifi/p2p/WifiP2pDeviceListTest.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p;
-
-import static org.junit.Assert.assertEquals;
-
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-/**
- * Unit test harness for {@link android.net.wifi.p2p.WifiP2pDeviceList}
- */
-@SmallTest
-public class WifiP2pDeviceListTest {
-
-    private static final WifiP2pDevice TEST_DEVICE_1 = new WifiP2pDevice("aa:bb:cc:dd:ee:ff");
-    private static final WifiP2pDevice TEST_DEVICE_2 = new WifiP2pDevice("aa:bb:cc:dd:ee:f1");
-    private static final WifiP2pDevice TEST_DEVICE_3 = new WifiP2pDevice("11:22:33:44:55:66");
-    private static final WifiP2pDevice TEST_DEVICE_4 = new WifiP2pDevice("a0:b0:c0:d0:e0:f0");
-
-    /**
-     * Verify basic operations.
-     */
-    @Test
-    public void testListOperations() throws Exception {
-        WifiP2pDeviceList list = new WifiP2pDeviceList();
-        list.update(TEST_DEVICE_1);
-        list.update(TEST_DEVICE_2);
-        list.update(TEST_DEVICE_3);
-        assertEquals(3, list.getDeviceList().size());
-
-        assertEquals(TEST_DEVICE_1, list.get(TEST_DEVICE_1.deviceAddress));
-        assertEquals(null, list.get(TEST_DEVICE_4.deviceAddress));
-
-        list.remove(TEST_DEVICE_2.deviceAddress);
-        assertEquals(null, list.get(TEST_DEVICE_2.deviceAddress));
-
-        list.remove(TEST_DEVICE_3);
-        assertEquals(null, list.get(TEST_DEVICE_3.deviceAddress));
-
-        assertEquals(1, list.getDeviceList().size());
-
-        list.clear();
-        assertEquals(0, list.getDeviceList().size());
-
-        Parcel parcelW = Parcel.obtain();
-        list.writeToParcel(parcelW, 0);
-        byte[] bytes = parcelW.marshall();
-        parcelW.recycle();
-
-        Parcel parcelR = Parcel.obtain();
-        parcelR.unmarshall(bytes, 0, bytes.length);
-        parcelR.setDataPosition(0);
-        WifiP2pDeviceList fromParcel = WifiP2pDeviceList.CREATOR.createFromParcel(parcelR);
-
-        assertEquals(list.toString(), fromParcel.toString());
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/p2p/WifiP2pDeviceTest.java b/wifi/tests/src/android/net/wifi/p2p/WifiP2pDeviceTest.java
deleted file mode 100644
index 6edc287..0000000
--- a/wifi/tests/src/android/net/wifi/p2p/WifiP2pDeviceTest.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-/**
- * Unit test harness for {@link android.net.wifi.p2p.WifiP2pDevice}
- */
-@SmallTest
-public class WifiP2pDeviceTest {
-
-    /**
-     * Compare two p2p devices.
-     *
-     * @param devA is the first device to be compared
-     * @param devB is the second device to be compared
-     */
-    private void compareWifiP2pDevices(WifiP2pDevice devA, WifiP2pDevice devB) {
-        assertEquals(devA.deviceName, devB.deviceName);
-        assertEquals(devA.deviceAddress, devB.deviceAddress);
-        assertEquals(devA.primaryDeviceType, devB.primaryDeviceType);
-        assertEquals(devA.secondaryDeviceType, devB.secondaryDeviceType);
-        assertEquals(devA.wpsConfigMethodsSupported, devB.wpsConfigMethodsSupported);
-        assertEquals(devA.deviceCapability, devB.deviceCapability);
-        assertEquals(devA.groupCapability, devB.groupCapability);
-        assertEquals(devA.status, devB.status);
-        if (devA.wfdInfo != null) {
-            assertEquals(devA.wfdInfo.isEnabled(), devB.wfdInfo.isEnabled());
-            assertEquals(devA.wfdInfo.getDeviceInfoHex(), devB.wfdInfo.getDeviceInfoHex());
-            assertEquals(devA.wfdInfo.getControlPort(), devB.wfdInfo.getControlPort());
-            assertEquals(devA.wfdInfo.getMaxThroughput(), devB.wfdInfo.getMaxThroughput());
-        } else {
-            assertEquals(devA.wfdInfo, devB.wfdInfo);
-        }
-    }
-
-    /**
-     * Check equals and hashCode consistency
-     */
-    @Test
-    public void testEqualsWithHashCode() throws Exception {
-        WifiP2pDevice dev_a = new WifiP2pDevice();
-        dev_a.deviceAddress = new String("02:90:4c:a0:92:54");
-        WifiP2pDevice dev_b = new WifiP2pDevice();
-        dev_b.deviceAddress = new String("02:90:4c:a0:92:54");
-
-        assertTrue(dev_a.equals(dev_b));
-        assertEquals(dev_a.hashCode(), dev_b.hashCode());
-    }
-
-    /**
-     * Check the copy constructor with default values.
-     */
-    @Test
-    public void testCopyConstructorWithDefaultValues() throws Exception {
-        WifiP2pDevice device = new WifiP2pDevice();
-        WifiP2pDevice copy = new WifiP2pDevice(device);
-        compareWifiP2pDevices(device, copy);
-    }
-
-    /**
-     * Check the copy constructor with updated values.
-     */
-    @Test
-    public void testCopyConstructorWithUpdatedValues() throws Exception {
-        WifiP2pDevice device = new WifiP2pDevice();
-        device.deviceName = "deviceName";
-        device.deviceAddress = "11:22:33:44:55:66";
-        device.primaryDeviceType = "primaryDeviceType";
-        device.secondaryDeviceType = "secondaryDeviceType";
-        device.wpsConfigMethodsSupported = 0x0008;
-        device.deviceCapability = 1;
-        device.groupCapability = 1;
-        device.status = WifiP2pDevice.CONNECTED;
-        device.wfdInfo = new WifiP2pWfdInfo();
-        WifiP2pDevice copy = new WifiP2pDevice(device);
-        compareWifiP2pDevices(device, copy);
-    }
-
-    /**
-     * Check the copy constructor when the wfdInfo of the source object is null.
-     */
-    @Test
-    public void testCopyConstructorWithNullWfdInfo() throws Exception {
-        WifiP2pDevice device = new WifiP2pDevice();
-        device.deviceName = "deviceName";
-        device.deviceAddress = "11:22:33:44:55:66";
-        device.primaryDeviceType = "primaryDeviceType";
-        device.secondaryDeviceType = "secondaryDeviceType";
-        device.wpsConfigMethodsSupported = 0x0008;
-        device.deviceCapability = 1;
-        device.groupCapability = 1;
-        device.status = WifiP2pDevice.CONNECTED;
-        device.wfdInfo = null;
-        WifiP2pDevice copy = new WifiP2pDevice(device);
-        compareWifiP2pDevices(device, copy);
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/p2p/WifiP2pGroupListTest.java b/wifi/tests/src/android/net/wifi/p2p/WifiP2pGroupListTest.java
deleted file mode 100644
index 2402f5b..0000000
--- a/wifi/tests/src/android/net/wifi/p2p/WifiP2pGroupListTest.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Unit test harness for {@link android.net.wifi.p2p.WifiP2pGroupList}
- */
-@SmallTest
-public class WifiP2pGroupListTest {
-
-    private static final WifiP2pDevice TEST_GROUP_OWNER_1 = new WifiP2pDevice("aa:bb:cc:dd:ee:f0");
-    private static final WifiP2pDevice TEST_GROUP_OWNER_2 = new WifiP2pDevice("aa:bb:cc:dd:ee:f1");
-    private static final WifiP2pDevice TEST_GROUP_OWNER_3 = new WifiP2pDevice("aa:bb:cc:dd:ee:f2");
-    private static final WifiP2pDevice TEST_GROUP_OWNER_OTHER =
-            new WifiP2pDevice("aa:bb:cc:dd:ee:f3");
-
-    private WifiP2pGroup mTestGroup1;
-    private WifiP2pGroup mTestGroup2;
-    private WifiP2pGroup mTestGroup3;
-    private WifiP2pGroup mTestGroup4;
-
-    private WifiP2pGroup createGroup(
-            int networkId, String networkName,
-            String passphrase, boolean isGo,
-            WifiP2pDevice goDev) {
-        WifiP2pGroup group = new WifiP2pGroup();
-        group.setNetworkId(networkId);
-        group.setNetworkName(networkName);
-        group.setPassphrase(passphrase);
-        group.setIsGroupOwner(isGo);
-        group.setOwner(goDev);
-        return group;
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        mTestGroup1 = createGroup(0, "testGroup1", "12345678", false, TEST_GROUP_OWNER_1);
-        mTestGroup2 = createGroup(1, "testGroup2", "12345678", true, TEST_GROUP_OWNER_2);
-        mTestGroup3 = createGroup(2, "testGroup3", "12345678", false, TEST_GROUP_OWNER_3);
-        mTestGroup4 = createGroup(3, "testGroup4", "12345678", false, TEST_GROUP_OWNER_1);
-    }
-
-    /**
-     * Verify basic operations.
-     */
-    @Test
-    public void testListOperations() throws Exception {
-        WifiP2pGroupList list = new WifiP2pGroupList();
-        list.add(mTestGroup1);
-        list.add(mTestGroup2);
-        list.add(mTestGroup3);
-        list.add(mTestGroup4);
-        assertEquals(4, list.getGroupList().size());
-
-        // in list
-        assertEquals(mTestGroup2.getNetworkId(),
-                list.getNetworkId(TEST_GROUP_OWNER_2.deviceAddress));
-        assertEquals(TEST_GROUP_OWNER_2.deviceAddress,
-                list.getOwnerAddr(mTestGroup2.getNetworkId()));
-        // not in list
-        assertEquals(-1, list.getNetworkId(TEST_GROUP_OWNER_OTHER.deviceAddress));
-        // if there are groups with the same GO, return the first one found.
-        assertEquals(mTestGroup1.getNetworkId(),
-                list.getNetworkId(TEST_GROUP_OWNER_1.deviceAddress));
-        // identify groups with the same GO, but different network names.
-        assertEquals(mTestGroup4.getNetworkId(),
-                list.getNetworkId(TEST_GROUP_OWNER_1.deviceAddress, "testGroup4"));
-
-        list.remove(mTestGroup3.getNetworkId());
-        assertEquals(-1, list.getNetworkId(TEST_GROUP_OWNER_3.deviceAddress));
-        assertFalse(list.contains(mTestGroup3.getNetworkId()));
-
-        assertEquals(3, list.getGroupList().size());
-
-        Parcel parcelW = Parcel.obtain();
-        list.writeToParcel(parcelW, 0);
-        byte[] bytes = parcelW.marshall();
-        parcelW.recycle();
-
-        Parcel parcelR = Parcel.obtain();
-        parcelR.unmarshall(bytes, 0, bytes.length);
-        parcelR.setDataPosition(0);
-        WifiP2pGroupList fromParcel = WifiP2pGroupList.CREATOR.createFromParcel(parcelR);
-
-        assertEquals(list.toString(), fromParcel.toString());
-
-        list.clear();
-        assertEquals(0, list.getGroupList().size());
-
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/p2p/WifiP2pGroupTest.java b/wifi/tests/src/android/net/wifi/p2p/WifiP2pGroupTest.java
deleted file mode 100644
index 9473e42..0000000
--- a/wifi/tests/src/android/net/wifi/p2p/WifiP2pGroupTest.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-/**
- * Unit test harness for {@link android.net.wifi.p2p.WifiP2pGroup}
- */
-@SmallTest
-public class WifiP2pGroupTest {
-
-    private static final String INTERFACE = "p2p-p2p0-3";
-    private static final int NETWORK_ID = 9;
-    private static final String NETWORK_NAME = "DIRECT-xy-Hello";
-    private static final String PASSPHRASE = "HelloWorld";
-    private static final WifiP2pDevice GROUP_OWNER = new WifiP2pDevice("de:ad:be:ef:00:01");
-    private static final int FREQUENCY = 5300;
-    private static final WifiP2pDevice CLIENT_1 = new WifiP2pDevice("aa:bb:cc:dd:ee:01");
-    private static final WifiP2pDevice CLIENT_2 = new WifiP2pDevice("aa:bb:cc:dd:ee:02");
-
-    /**
-     * Verify setter/getter functions.
-     */
-    @Test
-    public void testSetterGetter() throws Exception {
-        WifiP2pGroup group = new WifiP2pGroup();
-
-        group.setInterface(INTERFACE);
-        group.setNetworkId(NETWORK_ID);
-        group.setNetworkName(NETWORK_NAME);
-        group.setPassphrase(PASSPHRASE);
-        group.setIsGroupOwner(false);
-        group.setOwner(GROUP_OWNER);
-        group.setFrequency(FREQUENCY);
-        group.addClient(CLIENT_1.deviceAddress);
-        group.addClient(CLIENT_2);
-
-        assertEquals(INTERFACE, group.getInterface());
-        assertEquals(NETWORK_ID, group.getNetworkId());
-        assertEquals(NETWORK_NAME, group.getNetworkName());
-        assertEquals(PASSPHRASE, group.getPassphrase());
-        assertFalse(group.isGroupOwner());
-        assertEquals(GROUP_OWNER, group.getOwner());
-        assertEquals(FREQUENCY, group.getFrequency());
-
-        assertFalse(group.isClientListEmpty());
-        assertTrue(group.contains(CLIENT_1));
-
-        assertEquals(2, group.getClientList().size());
-
-        group.removeClient(CLIENT_1);
-        group.removeClient(CLIENT_2.deviceAddress);
-        assertFalse(group.contains(CLIENT_1));
-        assertTrue(group.isClientListEmpty());
-
-        Parcel parcelW = Parcel.obtain();
-        group.writeToParcel(parcelW, 0);
-        byte[] bytes = parcelW.marshall();
-        parcelW.recycle();
-
-        Parcel parcelR = Parcel.obtain();
-        parcelR.unmarshall(bytes, 0, bytes.length);
-        parcelR.setDataPosition(0);
-        WifiP2pGroup fromParcel = WifiP2pGroup.CREATOR.createFromParcel(parcelR);
-
-        assertEquals(group.toString(), fromParcel.toString());
-
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/p2p/WifiP2pInfoTest.java b/wifi/tests/src/android/net/wifi/p2p/WifiP2pInfoTest.java
deleted file mode 100644
index e207ca1..0000000
--- a/wifi/tests/src/android/net/wifi/p2p/WifiP2pInfoTest.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p;
-
-import static org.junit.Assert.assertEquals;
-
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.net.InetAddress;
-
-/**
- * Unit test harness for {@link android.net.wifi.p2p.WifiP2pInfo}
- */
-@SmallTest
-public class WifiP2pInfoTest {
-
-    private InetAddress mGroupOnwerIpv4Address;
-
-    @Before
-    public void setUp() throws Exception {
-        byte[] ipv4 = {(byte) 192, (byte) 168, (byte) 49, (byte) 1};
-        mGroupOnwerIpv4Address = InetAddress.getByAddress(ipv4);
-    }
-
-    /**
-     * Verifies copy constructor.
-     */
-    @Test
-    public void testCopyOperator() throws Exception {
-        WifiP2pInfo info = new WifiP2pInfo();
-        info.groupFormed = true;
-        info.isGroupOwner = true;
-        info.groupOwnerAddress = mGroupOnwerIpv4Address;
-
-        WifiP2pInfo copiedInfo = new WifiP2pInfo(info);
-
-        // no equals operator, use toString for data comparison.
-        assertEquals(info.toString(), copiedInfo.toString());
-    }
-
-    /**
-     * Verifies parcel serialization/deserialization.
-     */
-    @Test
-    public void testParcelOperation() throws Exception {
-        WifiP2pInfo info = new WifiP2pInfo();
-        info.groupFormed = true;
-        info.isGroupOwner = true;
-        info.groupOwnerAddress = mGroupOnwerIpv4Address;
-
-        Parcel parcelW = Parcel.obtain();
-        info.writeToParcel(parcelW, 0);
-        byte[] bytes = parcelW.marshall();
-        parcelW.recycle();
-
-        Parcel parcelR = Parcel.obtain();
-        parcelR.unmarshall(bytes, 0, bytes.length);
-        parcelR.setDataPosition(0);
-        WifiP2pInfo fromParcel = WifiP2pInfo.CREATOR.createFromParcel(parcelR);
-
-        // no equals operator, use toString for data comparison.
-        assertEquals(info.toString(), fromParcel.toString());
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/p2p/WifiP2pManagerTest.java b/wifi/tests/src/android/net/wifi/p2p/WifiP2pManagerTest.java
deleted file mode 100644
index 9e8dca4..0000000
--- a/wifi/tests/src/android/net/wifi/p2p/WifiP2pManagerTest.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.verify;
-
-import android.content.Context;
-import android.os.test.TestLooper;
-
-import androidx.test.filters.SmallTest;
-
-import libcore.junit.util.ResourceLeakageDetector;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-/**
- * Unit test harness for WifiP2pManager.
- */
-@SmallTest
-public class WifiP2pManagerTest {
-    private WifiP2pManager mDut;
-    private TestLooper mTestLooper;
-
-    @Mock
-    public Context mContextMock;
-    @Mock
-    IWifiP2pManager mP2pServiceMock;
-
-    @Rule
-    public ResourceLeakageDetector.LeakageDetectorRule leakageDetectorRule =
-            ResourceLeakageDetector.getRule();
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-
-        mDut = new WifiP2pManager(mP2pServiceMock);
-        mTestLooper = new TestLooper();
-    }
-
-    /**
-     * Validate that on finalize we close the channel and flag a resource leakage.
-     */
-    @Test
-    public void testChannelFinalize() throws Exception {
-        try (WifiP2pManager.Channel channel = new WifiP2pManager.Channel(mContextMock,
-                mTestLooper.getLooper(), null, null, mDut)) {
-            leakageDetectorRule.assertUnreleasedResourceCount(channel, 1);
-        }
-    }
-
-    /**
-     * Validate that when close is called on a channel it frees up resources (i.e. don't
-     * get flagged again on finalize).
-     */
-    @Test
-    public void testChannelClose() throws Exception {
-        WifiP2pManager.Channel channel = new WifiP2pManager.Channel(mContextMock,
-                mTestLooper.getLooper(), null, null, mDut);
-
-        channel.close();
-        verify(mP2pServiceMock).close(any());
-
-        leakageDetectorRule.assertUnreleasedResourceCount(channel, 0);
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/p2p/WifiP2pProvDiscEventTest.java b/wifi/tests/src/android/net/wifi/p2p/WifiP2pProvDiscEventTest.java
deleted file mode 100644
index e3b10a7..0000000
--- a/wifi/tests/src/android/net/wifi/p2p/WifiP2pProvDiscEventTest.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-/**
- * Unit test harness for {@link android.net.wifi.p2p.WifiP2pProvDiscEvent}
- */
-@SmallTest
-public class WifiP2pProvDiscEventTest {
-
-    private static final String DEVICE_ADDRESS = "aa:bb:cc:dd:ee:ff";
-    private static final String EVENT_PBC_REQ_STRING = "P2P-PROV-DISC-PBC-REQ";
-    private static final String EVENT_PBC_RSP_STRING = "P2P-PROV-DISC-PBC-RESP";
-    private static final String EVENT_ENTER_PIN_STRING = "P2P-PROV-DISC-ENTER-PIN";
-    private static final String EVENT_SHOW_PIN_STRING = "P2P-PROV-DISC-SHOW-PIN";
-    private static final String TEST_PIN = "44490607";
-
-    /**
-     * Test parsing PBC request event.
-     */
-    @Test
-    public void testPbcReqEvent() throws Exception {
-        WifiP2pProvDiscEvent event =
-                new WifiP2pProvDiscEvent(EVENT_PBC_REQ_STRING + " " + DEVICE_ADDRESS);
-        assertEquals(WifiP2pProvDiscEvent.PBC_REQ, event.event);
-        assertEquals(DEVICE_ADDRESS, event.device.deviceAddress);
-    }
-
-
-    /**
-     * Test parsing PBC response event.
-     */
-    @Test
-    public void testPbcRespEvent() throws Exception {
-        WifiP2pProvDiscEvent event =
-                new WifiP2pProvDiscEvent(EVENT_PBC_RSP_STRING + " " + DEVICE_ADDRESS);
-        assertEquals(WifiP2pProvDiscEvent.PBC_RSP, event.event);
-        assertEquals(DEVICE_ADDRESS, event.device.deviceAddress);
-    }
-
-    /**
-     * Test parsing ENTER-PIN event.
-     */
-    @Test
-    public void testEnterPinEvent() throws Exception {
-        WifiP2pProvDiscEvent event =
-                new WifiP2pProvDiscEvent(EVENT_ENTER_PIN_STRING + " " + DEVICE_ADDRESS);
-        assertEquals(WifiP2pProvDiscEvent.ENTER_PIN, event.event);
-        assertEquals(DEVICE_ADDRESS, event.device.deviceAddress);
-    }
-
-    /**
-     * Test parsing SHOW-PIN event.
-     */
-    @Test
-    public void testShowPinEvent() throws Exception {
-        WifiP2pProvDiscEvent event =
-                new WifiP2pProvDiscEvent(
-                        EVENT_SHOW_PIN_STRING + " " + DEVICE_ADDRESS + " " + TEST_PIN);
-        assertEquals(WifiP2pProvDiscEvent.SHOW_PIN, event.event);
-        assertEquals(DEVICE_ADDRESS, event.device.deviceAddress);
-        assertEquals(TEST_PIN, event.pin);
-    }
-
-    /**
-     * Test parsing malformed input.
-     */
-    @Test
-    public void testMalformedInput() throws Exception {
-        try {
-            WifiP2pProvDiscEvent event = new WifiP2pProvDiscEvent("OneToken");
-            fail("Should throw IllegalArgumentException exception.");
-        } catch (IllegalArgumentException ex) {
-            // expected exception.
-        }
-    }
-
-    /**
-     * Test parsing malformed event.
-     */
-    @Test
-    public void testMalformedEvent() throws Exception {
-        try {
-            WifiP2pProvDiscEvent event = new WifiP2pProvDiscEvent("XXX " + DEVICE_ADDRESS);
-            fail("Should throw IllegalArgumentException exception.");
-        } catch (IllegalArgumentException ex) {
-            // expected exception.
-        }
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/p2p/WifiP2pWfdInfoTest.java b/wifi/tests/src/android/net/wifi/p2p/WifiP2pWfdInfoTest.java
deleted file mode 100644
index 2a9b36b..0000000
--- a/wifi/tests/src/android/net/wifi/p2p/WifiP2pWfdInfoTest.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Unit test harness for {@link android.net.wifi.p2p.WifiP2pWfdInfo}
- */
-@SmallTest
-public class WifiP2pWfdInfoTest {
-
-    private static final int TEST_CTRL_PORT = 9999;
-    private static final int TEST_MAX_TPUT = 1024;
-
-    private WifiP2pWfdInfo mSourceInfo = new WifiP2pWfdInfo(
-            0,
-            TEST_CTRL_PORT,
-            TEST_MAX_TPUT);
-
-    @Before
-    public void setUp() {
-        // initialize device info flags.
-        mSourceInfo.setDeviceType(WifiP2pWfdInfo.DEVICE_TYPE_WFD_SOURCE);
-        mSourceInfo.setSessionAvailable(true);
-        mSourceInfo.setContentProtectionSupported(true);
-    }
-
-    /**
-     * Verifies setters/getters.
-     */
-    @Test
-    public void testSettersGetters() throws Exception {
-        WifiP2pWfdInfo info = new WifiP2pWfdInfo();
-
-        info.setEnabled(true);
-        assertTrue(info.isEnabled());
-
-        info.setDeviceType(WifiP2pWfdInfo.DEVICE_TYPE_WFD_SOURCE);
-        assertEquals(WifiP2pWfdInfo.DEVICE_TYPE_WFD_SOURCE, info.getDeviceType());
-
-        info.setSessionAvailable(true);
-        assertTrue(info.isSessionAvailable());
-
-        info.setContentProtectionSupported(true);
-        assertTrue(info.isContentProtectionSupported());
-
-        info.setControlPort(TEST_CTRL_PORT);
-        assertEquals(TEST_CTRL_PORT, info.getControlPort());
-
-        info.setMaxThroughput(TEST_MAX_TPUT);
-        assertEquals(TEST_MAX_TPUT, info.getMaxThroughput());
-
-        assertEquals("0110270f0400", info.getDeviceInfoHex());
-    }
-
-    /**
-     * Verifies copy constructor.
-     */
-    @Test
-    public void testCopyOperator() throws Exception {
-        WifiP2pWfdInfo copiedInfo = new WifiP2pWfdInfo(mSourceInfo);
-
-        // no equals operator, use toString for data comparison.
-        assertEquals(mSourceInfo.toString(), copiedInfo.toString());
-    }
-
-    /**
-     * Verifies parcel serialization/deserialization.
-     */
-    @Test
-    public void testParcelOperation() throws Exception {
-        Parcel parcelW = Parcel.obtain();
-        mSourceInfo.writeToParcel(parcelW, 0);
-        byte[] bytes = parcelW.marshall();
-        parcelW.recycle();
-
-        Parcel parcelR = Parcel.obtain();
-        parcelR.unmarshall(bytes, 0, bytes.length);
-        parcelR.setDataPosition(0);
-        WifiP2pWfdInfo fromParcel = WifiP2pWfdInfo.CREATOR.createFromParcel(parcelR);
-
-        // no equals operator, use toString for data comparison.
-        assertEquals(mSourceInfo.toString(), fromParcel.toString());
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfoTest.java b/wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfoTest.java
deleted file mode 100644
index e1cffee..0000000
--- a/wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfoTest.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p.nsd;
-
-import static org.junit.Assert.fail;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Unit test harness for {@link android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceInfo}
- */
-@SmallTest
-public class WifiP2pDnsSdServiceInfoTest {
-
-    private static final String INSTANCE_NAME = "MyPrinter";
-    private static final String SERVICE_TYPE = "_ipp._tcp";
-    private static final String TXTRECORD_PROP_AVAILABLE = "available";
-    private static final String TXTRECORD_PROP_AVAILABLE_VISABLE = "visable";
-
-    private Map<String, String> mTxtMap = new HashMap<>();
-
-    @Before
-    public void setUp() throws Exception {
-        mTxtMap.put(TXTRECORD_PROP_AVAILABLE, TXTRECORD_PROP_AVAILABLE_VISABLE);
-    }
-
-    /**
-     * Verify newInstance API
-     */
-    @Test
-    public void testNewInstance() throws Exception {
-        WifiP2pDnsSdServiceInfo info = null;
-
-        // the least arguments
-        info = WifiP2pDnsSdServiceInfo.newInstance(
-                INSTANCE_NAME,
-                SERVICE_TYPE,
-                null);
-
-        // all arguments are given.
-        info = WifiP2pDnsSdServiceInfo.newInstance(
-                INSTANCE_NAME,
-                SERVICE_TYPE,
-                mTxtMap);
-
-        // failure case due to no instance name.
-        try {
-            info = WifiP2pDnsSdServiceInfo.newInstance(
-                    null,
-                    SERVICE_TYPE,
-                    null);
-            fail("should throw IllegalArgumentException");
-        } catch (IllegalArgumentException ex) {
-            // expected exception.
-        }
-
-        // failure case due to no service type.
-        try {
-            info = WifiP2pDnsSdServiceInfo.newInstance(
-                    INSTANCE_NAME,
-                    null,
-                    null);
-            fail("should throw IllegalArgumentException");
-        } catch (IllegalArgumentException ex) {
-            // expected exception.
-        }
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceRequestTest.java b/wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceRequestTest.java
deleted file mode 100644
index 7d46a5f..0000000
--- a/wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceRequestTest.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p.nsd;
-
-import static org.junit.Assert.fail;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-/**
- * Unit test harness for {@link android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceRequest}
- */
-@SmallTest
-public class WifiP2pDnsSdServiceRequestTest {
-
-    private static final String SERVICE_NAME = "MyPrinter";
-    private static final String SERVICE_TYPE = "_ipp._tcp";
-
-    @Test
-    public void testNewInstance() throws Exception {
-        WifiP2pDnsSdServiceRequest request = null;
-
-        // default new instance
-        request = WifiP2pDnsSdServiceRequest.newInstance();
-
-        // set service type
-        request = WifiP2pDnsSdServiceRequest.newInstance(SERVICE_TYPE);
-
-        // set service type
-        request = WifiP2pDnsSdServiceRequest.newInstance(SERVICE_NAME, SERVICE_TYPE);
-
-        // failure case due to null service type
-        try {
-            request = WifiP2pDnsSdServiceRequest.newInstance(null);
-            fail("should throw IllegalArgumentException");
-        } catch (IllegalArgumentException ex) {
-            // expected exception.
-        }
-
-        // failure case due to null service name
-        try {
-            request = WifiP2pDnsSdServiceRequest.newInstance(SERVICE_NAME, null);
-            fail("should throw IllegalArgumentException");
-        } catch (IllegalArgumentException ex) {
-            // expected exception.
-        }
-
-        // failure case due to null service type
-        try {
-            request = WifiP2pDnsSdServiceRequest.newInstance(null, SERVICE_TYPE);
-            fail("should throw IllegalArgumentException");
-        } catch (IllegalArgumentException ex) {
-            // expected exception.
-        }
-
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceInfoTest.java b/wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceInfoTest.java
deleted file mode 100644
index 49ead11..0000000
--- a/wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceInfoTest.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p.nsd;
-
-import static org.junit.Assert.fail;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Unit test harness for {@link android.net.wifi.p2p.nsd.WifiP2pUpnpServiceInfo}
- */
-@SmallTest
-public class WifiP2pUpnpServiceInfoTest {
-
-    private static final String UUID = "6859dede-8574-59ab-9332-123456789012";
-    private static final String DEVICE = "aa:bb:cc:dd:ee:ff";
-
-    private List<String> mServiceList = new ArrayList<>();
-
-    @Before
-    public void setUp() throws Exception {
-        mServiceList.add("urn:schemas-upnp-org:service:ContentDirectory:1");
-    }
-
-    /**
-     * Verify newInstance API
-     */
-    @Test
-    public void testNewInstance() throws Exception {
-        WifiP2pUpnpServiceInfo info = null;
-
-        // the least arguments
-        info = WifiP2pUpnpServiceInfo.newInstance(
-                UUID, DEVICE, null);
-
-        // all arguments are given.
-        info = WifiP2pUpnpServiceInfo.newInstance(
-                UUID, DEVICE, mServiceList);
-
-        // failure case due to no UUID.
-        try {
-            info = WifiP2pUpnpServiceInfo.newInstance(
-                    null, DEVICE, null);
-            fail("should throw IllegalArgumentException");
-        } catch (IllegalArgumentException ex) {
-            // expected exception.
-        }
-
-        // failure case due to no device.
-        try {
-            info = WifiP2pUpnpServiceInfo.newInstance(
-                    UUID,
-                    null,
-                    null);
-            fail("should throw IllegalArgumentException");
-        } catch (IllegalArgumentException ex) {
-            // expected exception.
-        }
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceRequestTest.java b/wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceRequestTest.java
deleted file mode 100644
index 79930dc..0000000
--- a/wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceRequestTest.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p.nsd;
-
-import static org.junit.Assert.fail;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-/**
- * Unit test harness for {@link android.net.wifi.p2p.nsd.WifiP2pUpnpServiceRequest}
- */
-@SmallTest
-public class WifiP2pUpnpServiceRequestTest {
-
-    @Test
-    public void testNewInstance() throws Exception {
-        WifiP2pUpnpServiceRequest request = null;
-
-        // Create a service discovery request to search all UPnP services.
-        request = WifiP2pUpnpServiceRequest.newInstance();
-
-        // Create a service discovery request to search specified UPnP services.
-        request = WifiP2pUpnpServiceRequest.newInstance("ssdp:all");
-
-        // failure case due to null target string
-        try {
-            request = WifiP2pUpnpServiceRequest.newInstance(null);
-            fail("should throw IllegalArgumentException");
-        } catch (IllegalArgumentException ex) {
-            // expected exception.
-        }
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/rtt/CivicLocationTest.java b/wifi/tests/src/android/net/wifi/rtt/CivicLocationTest.java
deleted file mode 100644
index f746fb7..0000000
--- a/wifi/tests/src/android/net/wifi/rtt/CivicLocationTest.java
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.rtt;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertNull;
-import static junit.framework.Assert.assertTrue;
-
-import android.location.Address;
-import android.os.Parcel;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/**
- * Tests for {@link CivicLocation}.
- */
-@RunWith(JUnit4.class)
-public class CivicLocationTest {
-    private static final String sUsCountryCode = "US";
-
-    private static final byte[] sEmptyBuffer = {};
-
-    private static final byte[] sTestCivicLocationBuffer = {
-            (byte) 17,
-            (byte) 3,
-            (byte) 'a',
-            (byte) 'b',
-            (byte) 'c',
-            (byte) 4,
-            (byte) 4,
-            (byte) 'd',
-            (byte) 'e',
-            (byte) 'f',
-            (byte) 'g',
-            (byte) 12,
-            (byte) 1,
-            (byte) 'h'
-    };
-
-    private static final byte[] sTestCivicLocationBufferWithAddress = {
-            (byte) CivicLocationKeys.HNO,
-            (byte) 2,
-            (byte) '1',
-            (byte) '5',
-            (byte) CivicLocationKeys.PRIMARY_ROAD_NAME,
-            (byte) 4,
-            (byte) 'A',
-            (byte) 'l',
-            (byte) 't',
-            (byte) 'o',
-            (byte) CivicLocationKeys.STREET_NAME_POST_MODIFIER,
-            (byte) 4,
-            (byte) 'R',
-            (byte) 'o',
-            (byte) 'a',
-            (byte) 'd',
-            (byte) CivicLocationKeys.CITY,
-            (byte) 8,
-            (byte) 'M',
-            (byte) 't',
-            (byte) 'n',
-            (byte) ' ',
-            (byte) 'V',
-            (byte) 'i',
-            (byte) 'e',
-            (byte) 'w',
-            (byte) CivicLocationKeys.STATE,
-            (byte) 2,
-            (byte) 'C',
-            (byte) 'A',
-            (byte) CivicLocationKeys.POSTAL_CODE,
-            (byte) 5,
-            (byte) '9',
-            (byte) '4',
-            (byte) '0',
-            (byte) '4',
-            (byte) '3'
-    };
-
-    /**
-     * Test inValid for null CountryCode.
-     */
-    @Test
-    public void testCivicLocationNullCountryCode() {
-        CivicLocation civicLocation = new CivicLocation(sTestCivicLocationBuffer, null);
-
-        boolean valid = civicLocation.isValid();
-
-        assertFalse(valid);
-    }
-
-    /**
-     * Test inValid for CountryCode too short.
-     */
-    @Test
-    public void testCivicLocationCountryCodeTooShort() {
-        CivicLocation civicLocation = new CivicLocation(sTestCivicLocationBuffer, "X");
-
-        boolean valid = civicLocation.isValid();
-
-        assertFalse(valid);
-    }
-
-    /**
-     * Test inValid for CountryCode too long.
-     */
-    @Test
-    public void testCivicLocationCountryCodeTooLong() {
-        CivicLocation civicLocation = new CivicLocation(sTestCivicLocationBuffer, "XYZ");
-
-        boolean valid = civicLocation.isValid();
-
-        assertFalse(valid);
-    }
-
-    /**
-     * Test inValid for null CivicLocation Buffer
-     */
-    @Test
-    public void testCivicLocationNullBuffer() {
-        CivicLocation civicLocation = new CivicLocation(null, sUsCountryCode);
-
-        boolean valid = civicLocation.isValid();
-
-        assertFalse(valid);
-    }
-
-    /**
-     * Test inValid for Empty CivicLocation Buffer.
-     */
-    @Test
-    public void testCivicLocationEmptyBuffer() {
-        CivicLocation civicLocation = new CivicLocation(sEmptyBuffer, sUsCountryCode);
-
-        boolean valid = civicLocation.isValid();
-
-        assertFalse(valid);
-    }
-
-    /**
-     * Test for valid CivicLocationBuffer and Country Code.
-     */
-    @Test
-    public void testCivicLocationValid() {
-        CivicLocation civicLocation = new CivicLocation(sTestCivicLocationBuffer, sUsCountryCode);
-
-        boolean valid = civicLocation.isValid();
-
-        assertTrue(valid);
-    }
-
-    /**
-     * Test toString Representation
-     */
-    @Test
-    public void testCivicLocationToString() {
-        CivicLocation civicLocation = new CivicLocation(sTestCivicLocationBuffer, sUsCountryCode);
-
-        String str = civicLocation.toString();
-
-        assertEquals("{4=defg, 12=h, 17=abc}", str);
-    }
-
-    /**
-     * Test the toString
-     */
-    @Test
-    public void testCivicLocationgetElementValue() {
-        CivicLocation civicLocation = new CivicLocation(sTestCivicLocationBuffer, sUsCountryCode);
-
-        String value1 = civicLocation.getCivicElementValue(4);
-        String value2 = civicLocation.getCivicElementValue(17);
-        String value3 = civicLocation.getCivicElementValue(12);
-        String value4 = civicLocation.getCivicElementValue(156); // not in test data
-        String value5 = civicLocation.getCivicElementValue(276); // greater than key index
-
-        assertEquals("defg", value1);
-        assertEquals("abc", value2);
-        assertEquals("h", value3);
-        assertNull(value4);
-        assertNull(value5);
-    }
-
-    /* Test toAddress representation */
-    @Test
-    public void testCivicLocationToAddress() {
-        CivicLocation civicLocation =
-                new CivicLocation(sTestCivicLocationBufferWithAddress, sUsCountryCode);
-
-        Address address = civicLocation.toAddress();
-
-        assertEquals("", address.getAddressLine(0));
-        assertEquals("15 Alto", address.getAddressLine(1));
-        assertEquals("Mtn View", address.getAddressLine(2));
-        assertEquals("CA 94043", address.getAddressLine(3));
-        assertEquals("US", address.getAddressLine(4));
-    }
-
-    /**
-     * Test toString Representation
-     */
-    @Test
-    public void testCivicLocationToString2() {
-        CivicLocation civicLocation =
-                new CivicLocation(sTestCivicLocationBufferWithAddress, sUsCountryCode);
-
-        String str = civicLocation.toString();
-
-        assertEquals("{1=CA, 3=Mtn View, 19=15, 24=94043, 34=Alto, 39=Road}", str);
-    }
-
-    /** Test object is Parcellable */
-    @Test
-    public void testCivicLocationParcelable() {
-        CivicLocation civicLocation =
-                new CivicLocation(sTestCivicLocationBufferWithAddress, sUsCountryCode);
-
-        Parcel parcel = Parcel.obtain();
-        civicLocation.writeToParcel(parcel, 0);
-        parcel.setDataPosition(0);
-        CivicLocation civicLocationFromParcel =
-                CivicLocation.CREATOR.createFromParcel(parcel);
-
-        assertEquals(civicLocationFromParcel, civicLocation);
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/rtt/ResponderLocationTest.java b/wifi/tests/src/android/net/wifi/rtt/ResponderLocationTest.java
deleted file mode 100644
index 271339c..0000000
--- a/wifi/tests/src/android/net/wifi/rtt/ResponderLocationTest.java
+++ /dev/null
@@ -1,589 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.rtt;
-
-import android.location.Address;
-import android.location.Location;
-import android.net.MacAddress;
-import android.os.Parcel;
-import android.util.SparseArray;
-import android.webkit.MimeTypeMap;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-import java.util.List;
-
-/**
- * Tests for {@link ResponderLocation}.
- */
-@RunWith(JUnit4.class)
-public class ResponderLocationTest {
-    private static final double LATLNG_TOLERANCE_DEGREES = 0.000_000_05D; // 5E-8 = 6mm of meridian
-    private static final double ALT_TOLERANCE_METERS = 0.01;
-    private static final double HEIGHT_TOLERANCE_METERS = 0.01;
-    private static final int INDEX_ELEMENT_TYPE = 2;
-    private static final int INDEX_SUBELEMENT_TYPE = 0;
-    private static final int INDEX_SUBELEMENT_LENGTH = 1;
-
-    /* Test Buffers */
-
-    private static final byte[] sTestLciIeHeader = {
-            (byte) 0x01, (byte) 0x00, (byte) 0x08 // LCI Information Element (IE)
-    };
-
-    private static final byte[] sTestLciShortBuffer = {
-        (byte) 0x00
-    };
-
-    private static final byte[] sTestLciSE = {
-            (byte) 0x00, // Subelement LCI
-            (byte) 16,   // Subelement LCI length always = 16
-            (byte) 0x52,
-            (byte) 0x83,
-            (byte) 0x4d,
-            (byte) 0x12,
-            (byte) 0xef,
-            (byte) 0xd2,
-            (byte) 0xb0,
-            (byte) 0x8b,
-            (byte) 0x9b,
-            (byte) 0x4b,
-            (byte) 0xf1,
-            (byte) 0xcc,
-            (byte) 0x2c,
-            (byte) 0x00,
-            (byte) 0x00,
-            (byte) 0x41
-    };
-
-    private static final byte[] sTestZHeightSE = {
-            (byte) 0x04, // Subelement Z
-            (byte) 6, // Length always 6
-            (byte) 0x00, // LSB STA Floor Info (2 bytes)
-            (byte) 0x01, // MSB
-            (byte) 0xcd, // LSB Height(m) (3 bytes)
-            (byte) 0x2c,
-            (byte) 0x00, // MSB Height(m)
-            (byte) 0x0e, // STA Height Uncertainty
-    };
-
-    private static final byte[] sTestUsageSE1 = {
-            (byte) 0x06, // Subelement Usage Rights
-            (byte) 1, // Length 1 (with no retention limit)
-            (byte) 0x01, // Retransmit ok, No expiration, no extra info available
-    };
-
-    private static final byte[] sTestUsageSE2 = {
-            (byte) 0x06, // Subelement Usage Rights
-            (byte) 3,    // Length 3 (including retention limit)
-            (byte) 0x06, // Retransmit not ok, Expiration, extra info available
-            (byte) 0x00, // LSB expiration time  (0x8000 = 32768 hrs)
-            (byte) 0x80  // MSB expiration time
-    };
-
-    private static final byte[] sTestBssidListSE = {
-            (byte) 0x07, // Subelement BSSID list
-            (byte) 13, // length dependent on number of BSSIDs in list
-            (byte) 0x00, // List is explicit; no expansion of list required
-            (byte) 0x01, // BSSID #1 (MSB)
-            (byte) 0x02,
-            (byte) 0x03,
-            (byte) 0x04,
-            (byte) 0x05,
-            (byte) 0x06, // (LSB)
-            (byte) 0xf1, // BSSID #2 (MSB)
-            (byte) 0xf2,
-            (byte) 0xf3,
-            (byte) 0xf4,
-            (byte) 0xf5,
-            (byte) 0xf6 // (LSB)
-    };
-
-    private static final byte[] sTestLcrBufferHeader = {
-            (byte) 0x01, (byte) 0x00, (byte) 0x0b,
-    };
-
-    private static final byte[] sEmptyBuffer = {};
-
-    private static final byte[] sTestCivicLocationSEWithAddress = {
-            (byte) 0, // Civic Location Subelement
-            (byte) 39, // Length of subelement value
-            (byte) 'U', // CountryCodeChar1
-            (byte) 'S', // CountryCodeChar2
-            (byte) CivicLocationKeys.HNO,
-            (byte) 2,
-            (byte) '1',
-            (byte) '5',
-            (byte) CivicLocationKeys.PRIMARY_ROAD_NAME,
-            (byte) 4,
-            (byte) 'A',
-            (byte) 'l',
-            (byte) 't',
-            (byte) 'o',
-            (byte) CivicLocationKeys.STREET_NAME_POST_MODIFIER,
-            (byte) 4,
-            (byte) 'R',
-            (byte) 'o',
-            (byte) 'a',
-            (byte) 'd',
-            (byte) CivicLocationKeys.CITY,
-            (byte) 8,
-            (byte) 'M',
-            (byte) 't',
-            (byte) 'n',
-            (byte) ' ',
-            (byte) 'V',
-            (byte) 'i',
-            (byte) 'e',
-            (byte) 'w',
-            (byte) CivicLocationKeys.STATE,
-            (byte) 2,
-            (byte) 'C',
-            (byte) 'A',
-            (byte) CivicLocationKeys.POSTAL_CODE,
-            (byte) 5,
-            (byte) '9',
-            (byte) '4',
-            (byte) '0',
-            (byte) '4',
-            (byte) '3'
-    };
-
-    // Buffer representing: "https://map.com/mall.jpg"
-    private static final byte[] sTestMapUrlSE = {
-            (byte) 5, // Map URL Subelement
-            (byte) 25,
-            (byte) 0, // MAP_TYPE_URL_DEFINED
-            (byte) 'h',
-            (byte) 't',
-            (byte) 't',
-            (byte) 'p',
-            (byte) 's',
-            (byte) ':',
-            (byte) '/',
-            (byte) '/',
-            (byte) 'm',
-            (byte) 'a',
-            (byte) 'p',
-            (byte) '.',
-            (byte) 'c',
-            (byte) 'o',
-            (byte) 'm',
-            (byte) '/',
-            (byte) 'm',
-            (byte) 'a',
-            (byte) 'l',
-            (byte) 'l',
-            (byte) '.',
-            (byte) 'j',
-            (byte) 'p',
-            (byte) 'g'
-    };
-
-    /**
-     * Test if the lci and lcr buffers are null.
-     */
-    @Test
-    public void testIfLciOrLcrIsNull() {
-        ResponderLocation responderLocation = new ResponderLocation(null, null);
-
-        boolean valid = responderLocation.isValid();
-        boolean lciValid = responderLocation.isLciSubelementValid();
-        boolean zValid = responderLocation.isZaxisSubelementValid();
-
-        assertFalse(valid);
-        assertFalse(lciValid);
-        assertFalse(zValid);
-    }
-
-    /**
-     * Test if the lci and lcr buffers are empty.
-     */
-    @Test
-    public void testIfLciOrLcrIsEmpty() {
-        ResponderLocation responderLocation = new ResponderLocation(sEmptyBuffer, sEmptyBuffer);
-
-        boolean valid = responderLocation.isValid();
-        boolean lciValid = responderLocation.isLciSubelementValid();
-        boolean zValid = responderLocation.isZaxisSubelementValid();
-
-        assertFalse(valid);
-        assertFalse(lciValid);
-        assertFalse(zValid);
-    }
-
-    /**
-     * Test if the lci subelement only has one byte
-     */
-    @Test
-    public void testIfLciShortBuffer() {
-        byte[] testLciBuffer = concatenateArrays(sTestLciIeHeader, sTestLciShortBuffer);
-        ResponderLocation responderLocation =
-                new ResponderLocation(testLciBuffer, sTestLcrBufferHeader);
-
-        boolean valid = responderLocation.isValid();
-        boolean lciValid = responderLocation.isLciSubelementValid();
-        boolean zValid = responderLocation.isZaxisSubelementValid();
-
-        assertFalse(valid);
-        assertFalse(lciValid);
-        assertFalse(zValid);
-    }
-
-    /**
-     * Test that the example buffer contains a valid LCI Subelement.
-     */
-    @Test
-    public void testLciValidSubelement() {
-        byte[] testLciBuffer = concatenateArrays(sTestLciIeHeader, sTestLciSE);
-        ResponderLocation responderLocation =
-                new ResponderLocation(testLciBuffer, sTestLcrBufferHeader);
-
-        boolean valid = responderLocation.isValid();
-        boolean lciValid = responderLocation.isLciSubelementValid();
-        boolean zValid = responderLocation.isZaxisSubelementValid();
-        Location location = responderLocation.toLocation();
-
-        assertTrue(valid);
-        assertTrue(lciValid);
-        assertFalse(zValid);
-        assertEquals(0.0009765625D, responderLocation.getLatitudeUncertainty());
-        assertEquals(-33.8570095D, responderLocation.getLatitude(),
-                LATLNG_TOLERANCE_DEGREES);
-        assertEquals(0.0009765625D, responderLocation.getLongitudeUncertainty());
-        assertEquals(151.2152005D, responderLocation.getLongitude(),
-                LATLNG_TOLERANCE_DEGREES);
-        assertEquals(1, responderLocation.getAltitudeType());
-        assertEquals(64.0, responderLocation.getAltitudeUncertainty());
-        assertEquals(11.2, responderLocation.getAltitude(), ALT_TOLERANCE_METERS);
-        assertEquals(1, responderLocation.getDatum()); // WGS84
-        assertEquals(false, responderLocation.getRegisteredLocationAgreementIndication());
-        assertEquals(false, responderLocation.getRegisteredLocationDseIndication());
-        assertEquals(false, responderLocation.getDependentStationIndication());
-        assertEquals(1, responderLocation.getLciVersion());
-
-        // Testing Location Object
-        assertEquals(-33.8570095D, location.getLatitude(),
-                LATLNG_TOLERANCE_DEGREES);
-        assertEquals(151.2152005D, location.getLongitude(),
-                LATLNG_TOLERANCE_DEGREES);
-        assertEquals((0.0009765625D + 0.0009765625D) / 2, location.getAccuracy(),
-                LATLNG_TOLERANCE_DEGREES);
-        assertEquals(11.2, location.getAltitude(), ALT_TOLERANCE_METERS);
-        assertEquals(64.0, location.getVerticalAccuracyMeters(), ALT_TOLERANCE_METERS);
-    }
-
-    /**
-     * Test for an invalid LCI element.
-     */
-    @Test
-    public void testLciInvalidElement() {
-        byte[] testBuffer = concatenateArrays(sTestLciIeHeader, sTestLciSE);
-        testBuffer[INDEX_ELEMENT_TYPE] = (byte) 0xFF;
-        ResponderLocation responderLocation =
-                new ResponderLocation(testBuffer, sTestLcrBufferHeader);
-
-        boolean valid = responderLocation.isValid();
-        boolean lciValid = responderLocation.isLciSubelementValid();
-        boolean zValid = responderLocation.isZaxisSubelementValid();
-
-        assertFalse(valid);
-        assertFalse(lciValid);
-        assertFalse(zValid);
-    }
-
-    /**
-     * Test for an invalid subelement type.
-     */
-    @Test
-    public void testSkipLciSubElementUnusedOrUnknown() {
-        byte[] testLciBuffer = concatenateArrays(sTestLciIeHeader, sTestLciSE);
-        // Corrupt the subelement type to an unknown type.
-        testLciBuffer[sTestLciIeHeader.length + INDEX_SUBELEMENT_TYPE] = (byte) 0x77;
-        ResponderLocation responderLocation =
-                new ResponderLocation(testLciBuffer, sTestLcrBufferHeader);
-
-        boolean valid = responderLocation.isValid();
-        boolean lciValid = responderLocation.isLciSubelementValid();
-        boolean zValid = responderLocation.isZaxisSubelementValid();
-
-        assertFalse(valid);
-        assertFalse(lciValid);
-        assertFalse(zValid);
-    }
-
-    /**
-     * Test for a subelement LCI length too small.
-     */
-    @Test
-    public void testInvalidLciSubElementLengthTooSmall() {
-        byte[] testLciBuffer = concatenateArrays(sTestLciIeHeader, sTestLciSE);
-        // Corrupt the length making it too small.
-        testLciBuffer[sTestLciIeHeader.length + INDEX_SUBELEMENT_LENGTH] = (byte) 0x01;
-        ResponderLocation responderLocation =
-                new ResponderLocation(testLciBuffer, sTestLcrBufferHeader);
-
-        boolean valid = responderLocation.isValid();
-        boolean lciValid = responderLocation.isLciSubelementValid();
-        boolean zValid = responderLocation.isZaxisSubelementValid();
-
-        assertFalse(valid);
-        assertFalse(lciValid);
-        assertFalse(zValid);
-    }
-
-    /**
-     * Test for a subelement LCI length too big.
-     */
-    @Test
-    public void testInvalidLciSubElementLengthTooBig() {
-        byte[] testLciBuffer = concatenateArrays(sTestLciIeHeader, sTestLciSE);
-        // Corrupt the length making it too big.
-        testLciBuffer[sTestLciIeHeader.length + INDEX_SUBELEMENT_TYPE] = (byte) 0x11;
-        ResponderLocation responderLocation =
-                new ResponderLocation(testLciBuffer, sTestLcrBufferHeader);
-
-        boolean valid = responderLocation.isValid();
-        boolean lciValid = responderLocation.isLciSubelementValid();
-        boolean zValid = responderLocation.isZaxisSubelementValid();
-
-        assertFalse(valid);
-        assertFalse(lciValid);
-        assertFalse(zValid);
-    }
-
-    /**
-     * Test for a valid Z (Height) subelement following an LCI subelement.
-     */
-    @Test
-    public void testLciValidZBufferSEAfterLci() {
-        byte[] testBufferTmp = concatenateArrays(sTestLciIeHeader, sTestLciSE);
-        byte[] testBuffer = concatenateArrays(testBufferTmp, sTestZHeightSE);
-        ResponderLocation responderLocation =
-                new ResponderLocation(testBuffer, sTestLcrBufferHeader);
-
-        boolean isValid = responderLocation.isValid();
-        boolean isZValid = responderLocation.isZaxisSubelementValid();
-        boolean isLciValid = responderLocation.isLciSubelementValid();
-        double staFloorNumber = responderLocation.getFloorNumber();
-        double staHeightAboveFloorMeters = responderLocation.getHeightAboveFloorMeters();
-        double staHeightAboveFloorUncertaintyMeters =
-                responderLocation.getHeightAboveFloorUncertaintyMeters();
-
-        assertTrue(isValid);
-        assertTrue(isZValid);
-        assertTrue(isLciValid);
-        assertEquals(4.0, staFloorNumber);
-        assertEquals(2.8, staHeightAboveFloorMeters, HEIGHT_TOLERANCE_METERS);
-        assertEquals(0.125, staHeightAboveFloorUncertaintyMeters);
-    }
-
-    /**
-     * Test for a valid Usage Policy that is unrestrictive
-     */
-    @Test
-    public void testLciOpenUsagePolicy() {
-        byte[] testBufferTmp = concatenateArrays(sTestLciIeHeader, sTestLciSE);
-        byte[] testBuffer = concatenateArrays(testBufferTmp, sTestUsageSE1);
-        ResponderLocation responderLocation =
-                new ResponderLocation(testBuffer, sTestLcrBufferHeader);
-
-        boolean valid = responderLocation.isValid();
-        boolean retransmit = responderLocation.getRetransmitPolicyIndication();
-        boolean expiration = responderLocation.getRetentionExpiresIndication();
-        boolean extraInfo = responderLocation.getExtraInfoOnAssociationIndication();
-
-        assertTrue(valid);
-        assertTrue(retransmit);
-        assertFalse(expiration);
-        assertFalse(extraInfo);
-    }
-
-    /**
-     * Test for a valid Usage Policy that is restrictive
-     */
-    @Test
-    public void testLciRestrictiveUsagePolicy() {
-        byte[] testBufferTmp = concatenateArrays(sTestLciIeHeader, sTestLciSE);
-        byte[] testBuffer = concatenateArrays(testBufferTmp, sTestUsageSE2);
-        ResponderLocation responderLocation =
-                new ResponderLocation(testBuffer, sTestLcrBufferHeader);
-
-        boolean valid = responderLocation.isValid();
-        boolean retransmit = responderLocation.getRetransmitPolicyIndication();
-        boolean expiration = responderLocation.getRetentionExpiresIndication();
-        boolean extraInfo = responderLocation.getExtraInfoOnAssociationIndication();
-
-        assertFalse(valid);
-        assertFalse(retransmit);
-        assertTrue(expiration);
-        assertTrue(extraInfo);
-    }
-
-    /**
-     * Test for a valid BSSID element following an LCI subelement.
-     */
-    @Test
-    public void testLciBssidListSEAfterLci() {
-        byte[] testBufferTmp = concatenateArrays(sTestLciIeHeader, sTestLciSE);
-        byte[] testBuffer = concatenateArrays(testBufferTmp, sTestBssidListSE);
-        ResponderLocation responderLocation =
-                new ResponderLocation(testBuffer, sTestLcrBufferHeader);
-
-        boolean valid = responderLocation.isValid();
-        List<MacAddress> bssidList = responderLocation.getColocatedBssids();
-
-        assertTrue(valid);
-        assertEquals(2, bssidList.size());
-        MacAddress macAddress1 = bssidList.get(0);
-        assertEquals("01:02:03:04:05:06", macAddress1.toString());
-        MacAddress macAddress2 = bssidList.get(1);
-        assertEquals("f1:f2:f3:f4:f5:f6", macAddress2.toString());
-    }
-
-    /**
-     * Test for a valid BSSID element before and LCI element
-     */
-    @Test
-    public void testLciBssidListSEBeforeLci() {
-        byte[] testBufferTmp = concatenateArrays(sTestLciIeHeader, sTestBssidListSE);
-        byte[] testBuffer = concatenateArrays(testBufferTmp, sTestLciSE);
-        ResponderLocation responderLocation =
-                new ResponderLocation(testBuffer, sTestLcrBufferHeader);
-
-        boolean valid = responderLocation.isValid();
-        List<MacAddress> bssidList = responderLocation.getColocatedBssids();
-
-        assertTrue(valid);
-        assertEquals(2, bssidList.size());
-        MacAddress macAddress1 = bssidList.get(0);
-        assertEquals("01:02:03:04:05:06", macAddress1.toString());
-        MacAddress macAddress2 = bssidList.get(1);
-        assertEquals("f1:f2:f3:f4:f5:f6", macAddress2.toString());
-    }
-
-    /**
-     * Test that a valid address can be extracted from a valid lcr buffer with Civic Location.
-     */
-    @Test
-    public void testLcrTestCivicLocationAddress() {
-        byte[] testLciBuffer = concatenateArrays(sTestLciIeHeader, sTestLciSE);
-        byte[] testLcrBuffer =
-                concatenateArrays(sTestLcrBufferHeader, sTestCivicLocationSEWithAddress);
-        ResponderLocation responderLocation = new ResponderLocation(testLciBuffer, testLcrBuffer);
-
-        boolean valid = responderLocation.isValid();
-        String countryCode = responderLocation.getCivicLocationCountryCode();
-        Address address = responderLocation.toCivicLocationAddress();
-
-        assertTrue(valid);
-        assertEquals("US", countryCode);
-        assertEquals("", address.getAddressLine(0));
-        assertEquals("15 Alto", address.getAddressLine(1));
-        assertEquals("Mtn View", address.getAddressLine(2));
-        assertEquals("CA 94043", address.getAddressLine(3));
-        assertEquals("US", address.getAddressLine(4));
-    }
-
-    /**
-     * Test that a Civic Location sparseArray can be extracted from a valid lcr buffer.
-     */
-    @Test
-    public void testLcrTestCivicLocationSparseArray() {
-        byte[] testLciBuffer = concatenateArrays(sTestLciIeHeader, sTestLciSE);
-        byte[] testLcrBuffer =
-                concatenateArrays(sTestLcrBufferHeader, sTestCivicLocationSEWithAddress);
-        ResponderLocation responderLocation = new ResponderLocation(testLciBuffer, testLcrBuffer);
-
-        boolean valid = responderLocation.isValid();
-        SparseArray<String> civicLocationSparseArray = responderLocation
-                .toCivicLocationSparseArray();
-
-        assertTrue(valid);
-        assertEquals("15", civicLocationSparseArray.get(CivicLocationKeys.HNO));
-        assertEquals("Alto",
-                civicLocationSparseArray.get(CivicLocationKeys.PRIMARY_ROAD_NAME));
-        assertEquals("Road",
-                civicLocationSparseArray.get(CivicLocationKeys.STREET_NAME_POST_MODIFIER));
-        assertEquals("Mtn View", civicLocationSparseArray.get(CivicLocationKeys.CITY));
-        assertEquals("94043", civicLocationSparseArray.get(CivicLocationKeys.POSTAL_CODE));
-    }
-
-    /**
-     * Test that a URL can be extracted from a valid lcr buffer with a map image subelement.
-     */
-    @Test
-    public void testLcrCheckMapUriIsValid() {
-        byte[] testLciBuffer = concatenateArrays(sTestLciIeHeader, sTestLciSE);
-        byte[] testLcrBuffer = concatenateArrays(sTestLcrBufferHeader, sTestMapUrlSE);
-        ResponderLocation responderLocation = new ResponderLocation(testLciBuffer, testLcrBuffer);
-
-        boolean valid = responderLocation.isValid();
-        String mapImageMimeType = responderLocation.getMapImageMimeType();
-        String urlString = "";
-        if (responderLocation.getMapImageUri() != null) {
-            urlString = responderLocation.getMapImageUri().toString();
-        }
-
-        assertTrue(valid);
-        MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton();
-        assertEquals(mimeTypeMap.getMimeTypeFromExtension("jpg"), mapImageMimeType);
-        assertEquals("https://map.com/mall.jpg", urlString);
-    }
-
-    /**
-     * Test the object is parcelable
-     */
-    @Test
-    public void testResponderLocationParcelable() {
-        byte[] testLciBuffer = concatenateArrays(sTestLciIeHeader, sTestLciSE);
-        ResponderLocation responderLocation =
-                new ResponderLocation(testLciBuffer, sTestLcrBufferHeader);
-
-        Parcel parcel = Parcel.obtain();
-        responderLocation.writeToParcel(parcel, 0);
-        parcel.setDataPosition(0);
-        ResponderLocation responderLocationFromParcel =
-                ResponderLocation.CREATOR.createFromParcel(parcel);
-
-        assertEquals(responderLocationFromParcel, responderLocation);
-    }
-
-    /* Helper Method */
-
-    /**
-     * Concatenate two arrays.
-     *
-     * @param a first array
-     * @param b second array
-     * @return a third array which is the concatenation of the two array params
-     */
-    private byte[] concatenateArrays(byte[] a, byte[] b) {
-        int aLen = a.length;
-        int bLen = b.length;
-        byte[] c = new byte[aLen + bLen];
-        System.arraycopy(a, 0, c, 0, aLen);
-        System.arraycopy(b, 0, c, aLen, bLen);
-        return c;
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/rtt/WifiRttManagerTest.java b/wifi/tests/src/android/net/wifi/rtt/WifiRttManagerTest.java
deleted file mode 100644
index e6eae416..0000000
--- a/wifi/tests/src/android/net/wifi/rtt/WifiRttManagerTest.java
+++ /dev/null
@@ -1,395 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.rtt;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.net.MacAddress;
-import android.net.wifi.ScanResult;
-import android.net.wifi.aware.PeerHandle;
-import android.os.IBinder;
-import android.os.Parcel;
-import android.os.test.TestLooper;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.Executor;
-
-/**
- * Unit test harness for WifiRttManager class.
- */
-@SmallTest
-public class WifiRttManagerTest {
-    private WifiRttManager mDut;
-    private TestLooper mMockLooper;
-    private Executor mMockLooperExecutor;
-
-    private final String packageName = "some.package.name.for.rtt.app";
-    private final String featureId = "some.feature.id.in.rtt.app";
-
-    @Mock
-    public Context mockContext;
-
-    @Mock
-    public IWifiRttManager mockRttService;
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-
-        mDut = new WifiRttManager(mockContext, mockRttService);
-        mMockLooper = new TestLooper();
-        mMockLooperExecutor = mMockLooper.getNewExecutor();
-
-        when(mockContext.getOpPackageName()).thenReturn(packageName);
-        when(mockContext.getAttributionTag()).thenReturn(featureId);
-    }
-
-    /**
-     * Validate ranging call flow with successful results.
-     */
-    @Test
-    public void testRangeSuccess() throws Exception {
-        RangingRequest request = new RangingRequest.Builder().build();
-        List<RangingResult> results = new ArrayList<>();
-        results.add(
-                new RangingResult(RangingResult.STATUS_SUCCESS, MacAddress.BROADCAST_ADDRESS, 15, 5,
-                        10, 8, 5, null, null, null, 666));
-        RangingResultCallback callbackMock = mock(RangingResultCallback.class);
-        ArgumentCaptor<IRttCallback> callbackCaptor = ArgumentCaptor.forClass(IRttCallback.class);
-
-        // verify ranging request passed to service
-        mDut.startRanging(request, mMockLooperExecutor, callbackMock);
-        verify(mockRttService).startRanging(any(IBinder.class), eq(packageName), eq(featureId),
-                eq(null),  eq(request), callbackCaptor.capture());
-
-        // service calls back with success
-        callbackCaptor.getValue().onRangingResults(results);
-        mMockLooper.dispatchAll();
-        verify(callbackMock).onRangingResults(results);
-
-        verifyNoMoreInteractions(mockRttService, callbackMock);
-    }
-
-    /**
-     * Validate ranging call flow which failed.
-     */
-    @Test
-    public void testRangeFail() throws Exception {
-        int failureCode = RangingResultCallback.STATUS_CODE_FAIL;
-
-        RangingRequest request = new RangingRequest.Builder().build();
-        RangingResultCallback callbackMock = mock(RangingResultCallback.class);
-        ArgumentCaptor<IRttCallback> callbackCaptor = ArgumentCaptor.forClass(IRttCallback.class);
-
-        // verify ranging request passed to service
-        mDut.startRanging(request, mMockLooperExecutor, callbackMock);
-        verify(mockRttService).startRanging(any(IBinder.class), eq(packageName), eq(featureId),
-                eq(null), eq(request), callbackCaptor.capture());
-
-        // service calls back with failure code
-        callbackCaptor.getValue().onRangingFailure(failureCode);
-        mMockLooper.dispatchAll();
-        verify(callbackMock).onRangingFailure(failureCode);
-
-        verifyNoMoreInteractions(mockRttService, callbackMock);
-    }
-
-    /**
-     * Validate that RangingRequest parcel works (produces same object on write/read).
-     */
-    @Test
-    public void testRangingRequestParcel() {
-        // Note: not validating parcel code of ScanResult (assumed to work)
-        ScanResult scanResult1 = new ScanResult();
-        scanResult1.BSSID = "00:01:02:03:04:05";
-        ScanResult scanResult2 = new ScanResult();
-        scanResult2.BSSID = "06:07:08:09:0A:0B";
-        ScanResult scanResult3 = new ScanResult();
-        scanResult3.BSSID = "AA:BB:CC:DD:EE:FF";
-        List<ScanResult> scanResults2and3 = new ArrayList<>(2);
-        scanResults2and3.add(scanResult2);
-        scanResults2and3.add(scanResult3);
-        MacAddress mac1 = MacAddress.fromString("00:01:02:03:04:05");
-        PeerHandle peerHandle1 = new PeerHandle(12);
-
-        RangingRequest.Builder builder = new RangingRequest.Builder();
-        builder.addAccessPoint(scanResult1);
-        builder.addAccessPoints(scanResults2and3);
-        builder.addWifiAwarePeer(mac1);
-        builder.addWifiAwarePeer(peerHandle1);
-        RangingRequest request = builder.build();
-
-        Parcel parcelW = Parcel.obtain();
-        request.writeToParcel(parcelW, 0);
-        byte[] bytes = parcelW.marshall();
-        parcelW.recycle();
-
-        Parcel parcelR = Parcel.obtain();
-        parcelR.unmarshall(bytes, 0, bytes.length);
-        parcelR.setDataPosition(0);
-        RangingRequest rereadRequest = RangingRequest.CREATOR.createFromParcel(parcelR);
-
-        assertEquals(request, rereadRequest);
-    }
-
-    /**
-     * Validate that can request as many range operation as the upper limit on number of requests.
-     */
-    @Test
-    public void testRangingRequestAtLimit() {
-        ScanResult scanResult = new ScanResult();
-        scanResult.BSSID = "AA:BB:CC:DD:EE:FF";
-        List<ScanResult> scanResultList = new ArrayList<>();
-        for (int i = 0; i < RangingRequest.getMaxPeers() - 3; ++i) {
-            scanResultList.add(scanResult);
-        }
-        MacAddress mac1 = MacAddress.fromString("00:01:02:03:04:05");
-
-        // create request
-        RangingRequest.Builder builder = new RangingRequest.Builder();
-        builder.addAccessPoint(scanResult);
-        builder.addAccessPoints(scanResultList);
-        builder.addAccessPoint(scanResult);
-        builder.addWifiAwarePeer(mac1);
-        RangingRequest request = builder.build();
-
-        // verify request
-        request.enforceValidity(true);
-    }
-
-    /**
-     * Validate that limit on number of requests is applied.
-     */
-    @Test(expected = IllegalArgumentException.class)
-    public void testRangingRequestPastLimit() {
-        ScanResult scanResult = new ScanResult();
-        scanResult.BSSID = "00:01:02:03:04:05";
-        List<ScanResult> scanResultList = new ArrayList<>();
-        for (int i = 0; i < RangingRequest.getMaxPeers() - 2; ++i) {
-            scanResultList.add(scanResult);
-        }
-        MacAddress mac1 = MacAddress.fromString("00:01:02:03:04:05");
-
-        // create request
-        RangingRequest.Builder builder = new RangingRequest.Builder();
-        builder.addAccessPoint(scanResult);
-        builder.addAccessPoints(scanResultList);
-        builder.addAccessPoint(scanResult);
-        builder.addWifiAwarePeer(mac1);
-        RangingRequest request = builder.build();
-
-        // verify request
-        request.enforceValidity(true);
-    }
-
-    /**
-     * Validate that Aware requests are invalid on devices which do not support Aware
-     */
-    @Test(expected = IllegalArgumentException.class)
-    public void testRangingRequestWithAwareWithNoAwareSupport() {
-        // create request
-        RangingRequest.Builder builder = new RangingRequest.Builder();
-        builder.addWifiAwarePeer(new PeerHandle(10));
-        RangingRequest request = builder.build();
-
-        // verify request
-        request.enforceValidity(false);
-    }
-
-    /**
-     * Validate that RangingResults parcel works (produces same object on write/read).
-     */
-    @Test
-    public void testRangingResultsParcel() {
-        int status = RangingResult.STATUS_SUCCESS;
-        final MacAddress mac = MacAddress.fromString("00:01:02:03:04:05");
-        PeerHandle peerHandle = new PeerHandle(10);
-        int distanceCm = 105;
-        int distanceStdDevCm = 10;
-        int rssi = 5;
-        int numAttemptedMeasurements = 8;
-        int numSuccessfulMeasurements = 3;
-        long timestamp = System.currentTimeMillis();
-        byte[] lci = { 0x5, 0x6, 0x7 };
-        byte[] lcr = { 0x1, 0x2, 0x3, 0xA, 0xB, 0xC };
-
-        // RangingResults constructed with a MAC address
-        RangingResult result = new RangingResult(status, mac, distanceCm, distanceStdDevCm, rssi,
-                numAttemptedMeasurements, numSuccessfulMeasurements, lci, lcr, null, timestamp);
-
-        Parcel parcelW = Parcel.obtain();
-        result.writeToParcel(parcelW, 0);
-        byte[] bytes = parcelW.marshall();
-        parcelW.recycle();
-
-        Parcel parcelR = Parcel.obtain();
-        parcelR.unmarshall(bytes, 0, bytes.length);
-        parcelR.setDataPosition(0);
-        RangingResult rereadResult = RangingResult.CREATOR.createFromParcel(parcelR);
-
-        assertEquals(result, rereadResult);
-
-        // RangingResults constructed with a PeerHandle
-        result = new RangingResult(status, peerHandle, distanceCm, distanceStdDevCm, rssi,
-                numAttemptedMeasurements, numSuccessfulMeasurements, null, null, null, timestamp);
-
-        parcelW = Parcel.obtain();
-        result.writeToParcel(parcelW, 0);
-        bytes = parcelW.marshall();
-        parcelW.recycle();
-
-        parcelR = Parcel.obtain();
-        parcelR.unmarshall(bytes, 0, bytes.length);
-        parcelR.setDataPosition(0);
-        rereadResult = RangingResult.CREATOR.createFromParcel(parcelR);
-
-        assertEquals(result, rereadResult);
-    }
-
-    /**
-     * Validate that RangingResults tests equal even if LCI/LCR is empty (length == 0) and null.
-     */
-    @Test
-    public void testRangingResultsEqualityLciLcr() {
-        int status = RangingResult.STATUS_SUCCESS;
-        final MacAddress mac = MacAddress.fromString("00:01:02:03:04:05");
-        PeerHandle peerHandle = new PeerHandle(10);
-        int distanceCm = 105;
-        int distanceStdDevCm = 10;
-        int rssi = 5;
-        int numAttemptedMeasurements = 10;
-        int numSuccessfulMeasurements = 3;
-        long timestamp = System.currentTimeMillis();
-        byte[] lci = { };
-        byte[] lcr = { };
-
-        RangingResult rr1 = new RangingResult(status, mac, distanceCm, distanceStdDevCm, rssi,
-                numAttemptedMeasurements, numSuccessfulMeasurements, lci, lcr, null, timestamp);
-        RangingResult rr2 = new RangingResult(status, mac, distanceCm, distanceStdDevCm, rssi,
-                numAttemptedMeasurements, numSuccessfulMeasurements, null, null, null, timestamp);
-
-        assertEquals(rr1, rr2);
-    }
-
-    /**
-     * Validate that ResponderConfig parcel works (produces same object on write/read).
-     */
-    @Test
-    public void testResponderConfigParcel() {
-        // ResponderConfig constructed with a MAC address
-        ResponderConfig config = new ResponderConfig(MacAddress.fromString("00:01:02:03:04:05"),
-                ResponderConfig.RESPONDER_AP, true, ResponderConfig.CHANNEL_WIDTH_80MHZ, 2134, 2345,
-                2555, ResponderConfig.PREAMBLE_LEGACY);
-
-        Parcel parcelW = Parcel.obtain();
-        config.writeToParcel(parcelW, 0);
-        byte[] bytes = parcelW.marshall();
-        parcelW.recycle();
-
-        Parcel parcelR = Parcel.obtain();
-        parcelR.unmarshall(bytes, 0, bytes.length);
-        parcelR.setDataPosition(0);
-        ResponderConfig rereadConfig = ResponderConfig.CREATOR.createFromParcel(parcelR);
-
-        assertEquals(config, rereadConfig);
-
-        // ResponderConfig constructed with a PeerHandle
-        config = new ResponderConfig(new PeerHandle(10), ResponderConfig.RESPONDER_AWARE, false,
-                ResponderConfig.CHANNEL_WIDTH_80MHZ_PLUS_MHZ, 5555, 6666, 7777,
-                ResponderConfig.PREAMBLE_VHT);
-
-        parcelW = Parcel.obtain();
-        config.writeToParcel(parcelW, 0);
-        bytes = parcelW.marshall();
-        parcelW.recycle();
-
-        parcelR = Parcel.obtain();
-        parcelR.unmarshall(bytes, 0, bytes.length);
-        parcelR.setDataPosition(0);
-        rereadConfig = ResponderConfig.CREATOR.createFromParcel(parcelR);
-
-        assertEquals(config, rereadConfig);
-    }
-
-    /**
-     * Validate preamble selection from ScanResults.
-     */
-    @Test
-    public void testResponderPreambleSelection() {
-        ScanResult.InformationElement htCap = new ScanResult.InformationElement();
-        htCap.id = ScanResult.InformationElement.EID_HT_CAPABILITIES;
-
-        ScanResult.InformationElement vhtCap = new ScanResult.InformationElement();
-        vhtCap.id = ScanResult.InformationElement.EID_VHT_CAPABILITIES;
-
-        ScanResult.InformationElement vsa = new ScanResult.InformationElement();
-        vsa.id = ScanResult.InformationElement.EID_VSA;
-
-        // no IE
-        ScanResult scan = new ScanResult();
-        scan.BSSID = "00:01:02:03:04:05";
-        scan.informationElements = null;
-        scan.channelWidth = ResponderConfig.CHANNEL_WIDTH_80MHZ;
-
-        ResponderConfig config = ResponderConfig.fromScanResult(scan);
-
-        assertEquals(ResponderConfig.PREAMBLE_VHT, config.preamble);
-
-        // IE with HT & VHT
-        scan.channelWidth = ResponderConfig.CHANNEL_WIDTH_40MHZ;
-
-        scan.informationElements = new ScanResult.InformationElement[2];
-        scan.informationElements[0] = htCap;
-        scan.informationElements[1] = vhtCap;
-
-        config = ResponderConfig.fromScanResult(scan);
-
-        assertEquals(ResponderConfig.PREAMBLE_VHT, config.preamble);
-
-        // IE with some entries but no HT or VHT
-        scan.informationElements[0] = vsa;
-        scan.informationElements[1] = vsa;
-
-        config = ResponderConfig.fromScanResult(scan);
-
-        assertEquals(ResponderConfig.PREAMBLE_LEGACY, config.preamble);
-
-        // IE with HT
-        scan.informationElements[0] = vsa;
-        scan.informationElements[1] = htCap;
-
-        config = ResponderConfig.fromScanResult(scan);
-
-        assertEquals(ResponderConfig.PREAMBLE_HT, config.preamble);
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/util/HexEncodingTest.java b/wifi/tests/src/android/net/wifi/util/HexEncodingTest.java
deleted file mode 100644
index 0d75138..0000000
--- a/wifi/tests/src/android/net/wifi/util/HexEncodingTest.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.util;
-
-import static android.net.wifi.util.HexEncoding.decode;
-import static android.net.wifi.util.HexEncoding.encode;
-import static android.net.wifi.util.HexEncoding.encodeToString;
-
-import junit.framework.TestCase;
-
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.Locale;
-
-/** Copied from {@link libcore.libcore.util.HexEncodingTest}. */
-public class HexEncodingTest extends TestCase {
-
-    public void testEncodeByte() {
-        Object[][] testCases = new Object[][]{
-                {0x01, "01"},
-                {0x09, "09"},
-                {0x0A, "0A"},
-                {0x0F, "0F"},
-                {0x10, "10"},
-                {0x1F, "1F"},
-                {0x20, "20"},
-                {0x7F, "7F"},
-                {0x80, "80"},
-                {0xFF, "FF"},
-        };
-        for (Object[] testCase : testCases) {
-            Number toEncode = (Number) testCase[0];
-            String expected = (String) testCase[1];
-
-            String actualUpper = encodeToString(toEncode.byteValue(), true /* upperCase */);
-            assertEquals(upper(expected), actualUpper);
-
-            String actualLower = encodeToString(toEncode.byteValue(), false /* upperCase */);
-            assertEquals(lower(expected), actualLower);
-        }
-    }
-
-    public void testEncodeBytes() {
-        Object[][] testCases = new Object[][]{
-                {"avocados".getBytes(StandardCharsets.UTF_8), "61766F6361646F73"},
-        };
-
-        for (Object[] testCase : testCases) {
-            byte[] bytes = (byte[]) testCase[0];
-            String encodedLower = lower((String) testCase[1]);
-            String encodedUpper = upper((String) testCase[1]);
-
-            assertArraysEqual(encodedUpper.toCharArray(), encode(bytes));
-            assertArraysEqual(encodedUpper.toCharArray(), encode(bytes, true /* upperCase */));
-            assertArraysEqual(encodedLower.toCharArray(), encode(bytes, false /* upperCase */));
-
-            assertArraysEqual(bytes, decode(encode(bytes), false /* allowSingleChar */));
-
-            // Make sure we can handle lower case hex encodings as well.
-            assertArraysEqual(bytes,
-                    decode(encodedLower.toCharArray(), false /* allowSingleChar */));
-        }
-    }
-
-    public void testDecode_allow4Bit() {
-        assertArraysEqual(new byte[]{6}, decode("6".toCharArray(), true));
-        assertArraysEqual(new byte[]{6, 0x76}, decode("676".toCharArray(), true));
-    }
-
-    public void testDecode_disallow4Bit() {
-        try {
-            decode("676".toCharArray(), false /* allowSingleChar */);
-            fail();
-        } catch (IllegalArgumentException expected) {
-        }
-    }
-
-    public void testDecode_invalid() {
-        try {
-            decode("DEADBARD".toCharArray(), false /* allowSingleChar */);
-            fail();
-        } catch (IllegalArgumentException expected) {
-        }
-
-        // This demonstrates a difference in behaviour from apache commons : apache
-        // commons uses Character.isDigit and would successfully decode a string with
-        // arabic and devanagari characters.
-        try {
-            decode("६१٧٥٥F6361646F73".toCharArray(), false /* allowSingleChar */);
-            fail();
-        } catch (IllegalArgumentException expected) {
-        }
-
-        try {
-            decode("#%6361646F73".toCharArray(), false /* allowSingleChar */);
-            fail();
-        } catch (IllegalArgumentException expected) {
-        }
-    }
-
-    private static void assertArraysEqual(char[] lhs, char[] rhs) {
-        assertEquals(new String(lhs), new String(rhs));
-    }
-
-    private static void assertArraysEqual(byte[] lhs, byte[] rhs) {
-        assertEquals(Arrays.toString(lhs), Arrays.toString(rhs));
-    }
-
-    private static String lower(String string) {
-        return string.toLowerCase(Locale.ROOT);
-    }
-
-    private static String upper(String string) {
-        return string.toUpperCase(Locale.ROOT);
-    }
-}
