diff --git a/Android.bp b/Android.bp
index d234411..1493f15 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1239,6 +1239,7 @@
     visibility: [
         "//frameworks/base/wifi",
         "//frameworks/base/services/net",
+        "//packages/modules/Wifi/framework",
     ],
 }
 
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/wifi/Android.bp b/wifi/Android.bp
deleted file mode 100644
index 49138ab..0000000
--- a/wifi/Android.bp
+++ /dev/null
@@ -1,154 +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__",
-
-    "//packages/modules/Wifi/framework/tests",
-    "//packages/modules/Wifi/service/tests/wifitests:__subpackages__",
-
-    "//external/robolectric-shadows:__subpackages__",
-    "//frameworks/base/packages/SettingsLib/tests/integ",
-    "//external/sl4a:__subpackages__",
-    "//packages/apps/Settings/tests/robotests", // TODO(b/161767237): remove
-]
-
-// defaults shared between `framework-wifi` & `framework-wifi-pre-jarjar`
-// java_sdk_library `framework-wifi` needs sources to generate stubs, so it cannot reuse
-// `framework-wifi-pre-jarjar`
-java_defaults {
-    name: "framework-wifi-defaults",
-    defaults: ["wifi-module-sdk-version-defaults"],
-    static_libs: [
-        "framework-wifi-util-lib",
-        "android.hardware.wifi-V1.0-java-constants",
-        "modules-utils-build",
-    ],
-    libs: [
-        "unsupportedappusage", // for android.compat.annotation.UnsupportedAppUsage
-    ],
-    srcs: [
-        ":framework-wifi-updatable-sources",
-        ":framework-wifi-util-lib-aidls",
-    ],
-}
-
-// 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: ["framework-wifi-defaults"],
-    sdk_version: "module_current",
-    libs: ["framework-annotations-lib"],
-    // java_api_finder must accompany `srcs` (`srcs` defined in `framework-wifi-defaults`)
-    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",
-        "framework-wifi-defaults",
-    ],
-
-    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/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 57055f7..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.nsd;
-
-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 e4d28bb..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.nsd;
-
-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 28224cf..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 android.net.TransportInfo {
-    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 @Deprecated 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 afc39b9..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 android.net.TransportInfo {
-    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 7b84d57..0000000
--- a/wifi/jarjar-rules.txt
+++ /dev/null
@@ -1,123 +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.TcpKeepalivePacketDataParcelable* 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
-rule android.net.networkstack.aidl.** 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.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 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
-
-# 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
-rule com.android.modules.utils.** com.android.wifi.x.@0
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 f96d037c..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 3f79364..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(maxTargetSdk = 30, trackingBug = 170729553)
-    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 034defb..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("RequiresPermission")
-    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 5589bd13..0000000
--- a/wifi/java/android/net/wifi/ScanResult.java
+++ /dev/null
@@ -1,1160 +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.Build;
-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(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    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(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-        public static final int EID_SSID = 0;
-        /** @hide */
-        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-        public static final int EID_SUPPORTED_RATES = 1;
-        /** @hide */
-        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-        public static final int EID_TIM = 5;
-        /** @hide */
-        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-        public static final int EID_BSS_LOAD = 11;
-        /** @hide */
-        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-        public static final int EID_ERP = 42;
-        /** @hide */
-        public static final int EID_HT_CAPABILITIES = 45;
-        /** @hide */
-        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-        public static final int EID_RSN = 48;
-        /** @hide */
-        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-        public static final int EID_EXTENDED_SUPPORTED_RATES = 50;
-        /** @hide */
-        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-        public static final int EID_HT_OPERATION = 61;
-        /** @hide */
-        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-        public static final int EID_INTERWORKING = 107;
-        /** @hide */
-        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-        public static final int EID_ROAMING_CONSORTIUM = 111;
-        /** @hide */
-        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-        public static final int EID_EXTENDED_CAPS = 127;
-        /** @hide */
-        public static final int EID_VHT_CAPABILITIES = 191;
-        /** @hide */
-        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-        public static final int EID_VHT_OPERATION = 192;
-        /** @hide */
-        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-        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 d2ff658..0000000
--- a/wifi/java/android/net/wifi/SoftApConfiguration.java
+++ /dev/null
@@ -1,973 +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.CharsetEncoder;
-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);
-                final CharsetEncoder asciiEncoder = StandardCharsets.US_ASCII.newEncoder();
-                if (!asciiEncoder.canEncode(passphrase)) {
-                    throw new IllegalArgumentException("passphrase not ASCII encodable");
-                }
-                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 93c6358..0000000
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ /dev/null
@@ -1,2987 +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(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    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(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    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(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    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) {
-            throw new IllegalStateException("More than one auth type set");
-        }
-        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 90edc45..0000000
--- a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
+++ /dev/null
@@ -1,1494 +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;
-    }
-
-    /**
-     * 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;
-    }
-
-    /**
-     * 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 7437082..0000000
--- a/wifi/java/android/net/wifi/WifiInfo.java
+++ /dev/null
@@ -1,1146 +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.net.TransportInfo;
-import android.os.Build;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-
-import com.android.modules.utils.build.SdkLevel;
-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;
-import java.util.Objects;
-
-/**
- * Describes the state of any Wi-Fi connection that is active or
- * is in the process of being set up.
- *
- * In the connected state, access to location sensitive fields requires
- * the same permissions as {@link WifiManager#getScanResults}. If such access is not allowed,
- * {@link #getSSID} will return {@link WifiManager#UNKNOWN_SSID} and
- * {@link #getBSSID} will return {@code "02:00:00:00:00:00"}.
- * {@link #getNetworkId()} will return {@code -1}.
- * {@link #getPasspointFqdn()} will return null.
- * {@link #getPasspointProviderFriendlyName()} will return null.
- */
-public class WifiInfo implements TransportInfo, 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;
-    }
-
-    @Override
-    public boolean equals(Object that) {
-        if (this == that) return true;
-
-        // Potential API behavior change, so don't change behavior on older devices.
-        if (!SdkLevel.isAtLeastS()) return false;
-
-        if (!(that instanceof WifiInfo)) return false;
-
-        WifiInfo thatWifiInfo = (WifiInfo) that;
-        return Objects.equals(mWifiSsid, thatWifiInfo.mWifiSsid)
-                && Objects.equals(mBSSID, thatWifiInfo.mBSSID)
-                && Objects.equals(mNetworkId, thatWifiInfo.mNetworkId)
-                && Objects.equals(mRssi, thatWifiInfo.mRssi)
-                && Objects.equals(mSupplicantState, thatWifiInfo.mSupplicantState)
-                && Objects.equals(mLinkSpeed, thatWifiInfo.mLinkSpeed)
-                && Objects.equals(mTxLinkSpeed, thatWifiInfo.mTxLinkSpeed)
-                && Objects.equals(mRxLinkSpeed, thatWifiInfo.mRxLinkSpeed)
-                && Objects.equals(mFrequency, thatWifiInfo.mFrequency)
-                && Objects.equals(mIpAddress, thatWifiInfo.mIpAddress)
-                && Objects.equals(mMacAddress, thatWifiInfo.mMacAddress)
-                && Objects.equals(mMeteredHint, thatWifiInfo.mMeteredHint)
-                && Objects.equals(mEphemeral, thatWifiInfo.mEphemeral)
-                && Objects.equals(mTrusted, thatWifiInfo.mTrusted)
-                && Objects.equals(mRequestingPackageName, thatWifiInfo.mRequestingPackageName)
-                && Objects.equals(mOsuAp, thatWifiInfo.mOsuAp)
-                && Objects.equals(mFqdn, thatWifiInfo.mFqdn)
-                && Objects.equals(mProviderFriendlyName, thatWifiInfo.mProviderFriendlyName)
-                && Objects.equals(txBad, thatWifiInfo.txBad)
-                && Objects.equals(txRetries, thatWifiInfo.txRetries)
-                && Objects.equals(txSuccess, thatWifiInfo.txSuccess)
-                && Objects.equals(rxSuccess, thatWifiInfo.rxSuccess)
-                && Objects.equals(mLostTxPacketsPerSecond, thatWifiInfo.mLostTxPacketsPerSecond)
-                && Objects.equals(mTxRetriedTxPacketsPerSecond,
-                thatWifiInfo.mTxRetriedTxPacketsPerSecond)
-                && Objects.equals(mSuccessfulTxPacketsPerSecond,
-                thatWifiInfo.mSuccessfulTxPacketsPerSecond)
-                && Objects.equals(mSuccessfulRxPacketsPerSecond,
-                thatWifiInfo.mSuccessfulRxPacketsPerSecond)
-                && Objects.equals(score, thatWifiInfo.score)
-                && Objects.equals(mWifiStandard, thatWifiInfo.mWifiStandard)
-                && Objects.equals(mMaxSupportedTxLinkSpeed, thatWifiInfo.mMaxSupportedTxLinkSpeed)
-                && Objects.equals(mMaxSupportedRxLinkSpeed, thatWifiInfo.mMaxSupportedRxLinkSpeed)
-                && Objects.equals(mPasspointUniqueId, thatWifiInfo.mPasspointUniqueId);
-    }
-
-    @Override
-    public int hashCode() {
-        // Potential API behavior change, so don't change behavior on older devices.
-        if (!SdkLevel.isAtLeastS()) return System.identityHashCode(this);
-
-        return Objects.hash(mWifiSsid,
-                mBSSID,
-                mNetworkId,
-                mRssi,
-                mSupplicantState,
-                mLinkSpeed,
-                mTxLinkSpeed,
-                mRxLinkSpeed,
-                mFrequency,
-                mIpAddress,
-                mMacAddress,
-                mMeteredHint,
-                mEphemeral,
-                mTrusted,
-                mRequestingPackageName,
-                mOsuAp,
-                mFqdn,
-                mProviderFriendlyName,
-                txBad,
-                txRetries,
-                txSuccess,
-                rxSuccess,
-                mLostTxPacketsPerSecond,
-                mTxRetriedTxPacketsPerSecond,
-                mSuccessfulTxPacketsPerSecond,
-                mSuccessfulRxPacketsPerSecond,
-                score,
-                mWifiStandard,
-                mMaxSupportedTxLinkSpeed,
-                mMaxSupportedRxLinkSpeed,
-                mPasspointUniqueId);
-    }
-}
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
deleted file mode 100644
index 3ae2520..0000000
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ /dev/null
@@ -1,6272 +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.ConnectivityManager.NetworkCallback;
-import android.net.DhcpInfo;
-import android.net.MacAddress;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-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(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    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(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    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>
-     *
-     * @return the Wi-Fi information, contained in {@link WifiInfo}.
-     *
-     * @deprecated Starting with {@link Build.VERSION_CODES#S}, WifiInfo retrieval is moved to
-     * {@link ConnectivityManager} API surface. WifiInfo is attached in
-     * {@link NetworkCapabilities#getTransportInfo()} which is available via callback in
-     * {@link NetworkCallback#onCapabilitiesChanged(Network, NetworkCapabilities)} or on-demand from
-     * {@link ConnectivityManager#getNetworkCapabilities(Network)}.
-     *
-     *</p>
-     * Usage example:
-     * <pre>{@code
-     * final NetworkRequest request =
-     *      new NetworkRequest.Builder()
-     *      .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
-     *      .build();
-     * final ConnectivityManager connectivityManager =
-     *      context.getSystemService(ConnectivityManager.class);
-     * final NetworkCallback networkCallback = new NetworkCallback() {
-     *      ...
-     *      {@literal @}Override
-     *      void onAvailable(Network network) {}
-     *
-     *      {@literal @}Override
-     *      void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) {
-     *          WifiInfo wifiInfo = (WifiInfo) networkCapabilities.getTransportInfo();
-     *      }
-     *      // etc.
-     * };
-     * connectivityManager.requestNetwork(request, networkCallback); // For request
-     * connectivityManager.registerNetworkCallback(request, networkCallback); // For listen
-     * }</pre>
-     * <p>
-     * <b>Compatibility Note:</b>
-     * <li>Apps can continue using this API, however newer features
-     * such as ability to mask out location sensitive data in WifiInfo will not be supported
-     * via this API. </li>
-     * </p>
-     */
-    @Deprecated
-    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 4163c88..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("RequiresPermission")
-    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("RequiresPermission")
-    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("RequiresPermission")
-    public void stopTrackingWifiChange(WifiChangeListener listener) {
-        throw new UnsupportedOperationException();
-    }
-
-    /** @hide */
-    @SystemApi
-    @Deprecated
-    @SuppressLint("RequiresPermission")
-    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("RequiresPermission")
-    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("RequiresPermission")
-    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 3ece93d..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 d3a6bac..0000000
--- a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java
+++ /dev/null
@@ -1,506 +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.Build;
-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(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    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 567637a..0000000
--- a/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java
+++ /dev/null
@@ -1,435 +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.Build;
-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(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    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 e7866e6..0000000
--- a/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java
+++ /dev/null
@@ -1,219 +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.Build;
-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(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    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 5a27087..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(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    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(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-        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(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    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(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    @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 5d018e7..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(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    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 dea0477..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(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    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 b21d39d..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/tests/Android.bp b/wifi/tests/Android.bp
deleted file mode 100644
index 0e58740..0000000
--- a/wifi/tests/Android.bp
+++ /dev/null
@@ -1,56 +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.
-
-// Make test APK
-// ============================================================
-
-android_test {
-    name: "FrameworksWifiApiTests",
-
-    defaults: ["framework-wifi-test-defaults"],
-
-    srcs: ["**/*.java"],
-
-    jacoco: {
-        include_filter: ["android.net.wifi.*"],
-        // TODO(b/147521214) need to exclude test classes
-        exclude_filter: [],
-    },
-
-    static_libs: [
-        "androidx.test.rules",
-        "core-test-rules",
-        "frameworks-base-testutils",
-        "guava",
-        "mockito-target-minus-junit4",
-        "modules-utils-build",
-        "net-tests-utils",
-        "net-utils-framework-common",
-        "truth-prebuilt",
-    ],
-
-    libs: [
-        "android.test.runner",
-        "android.test.base",
-    ],
-
-    test_suites: [
-        "device-tests",
-        "mts",
-    ],
-
-    // static libs used by both framework-wifi & FrameworksWifiApiTests. Need to rename test usage
-    // to a different package name to prevent conflict with the copy in production code.
-    jarjar_rules: "test-jarjar-rules.txt",
-}
diff --git a/wifi/tests/AndroidManifest.xml b/wifi/tests/AndroidManifest.xml
deleted file mode 100644
index b6c38bc..0000000
--- a/wifi/tests/AndroidManifest.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
-  ~ 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
-  -->
-
-<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">
-            <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 API Tests">
-    </instrumentation>
-
-</manifest>
diff --git a/wifi/tests/AndroidTest.xml b/wifi/tests/AndroidTest.xml
deleted file mode 100644
index 34e2e3a..0000000
--- a/wifi/tests/AndroidTest.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-<configuration description="Runs Frameworks Wifi API Tests.">
-    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
-        <option name="test-file-name" value="FrameworksWifiApiTests.apk" />
-    </target_preparer>
-
-    <option name="test-suite-tag" value="apct" />
-    <option name="test-tag" value="FrameworksWifiApiTests" />
-    <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
deleted file mode 100644
index f909404..0000000
--- a/wifi/tests/README.md
+++ /dev/null
@@ -1,31 +0,0 @@
-# Wifi Unit Tests
-This package contains unit tests for 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/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/tests/src/android/net/wifi/SoftApConfigurationTest.java b/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java
deleted file mode 100644
index 2d7e535..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).isNotSameInstanceAs(original);
-        assertThat(unparceled).isEqualTo(original);
-        assertThat(unparceled.hashCode()).isEqualTo(original.hashCode());
-
-        SoftApConfiguration copy = new SoftApConfiguration.Builder(original).build();
-        assertThat(copy).isNotSameInstanceAs(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).isNotSameInstanceAs(original);
-        assertThat(unparceled).isEqualTo(original);
-        assertThat(unparceled.hashCode()).isEqualTo(original.hashCode());
-
-        SoftApConfiguration copy = new SoftApConfiguration.Builder(original).build();
-        assertThat(copy).isNotSameInstanceAs(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).isNotSameInstanceAs(original);
-        assertThat(unparceled).isEqualTo(original);
-        assertThat(unparceled.hashCode()).isEqualTo(original.hashCode());
-
-        SoftApConfiguration copy = new SoftApConfiguration.Builder(original).build();
-        assertThat(copy).isNotSameInstanceAs(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).isNotSameInstanceAs(original);
-        assertThat(unparceled).isEqualTo(original);
-        assertThat(unparceled.hashCode()).isEqualTo(original.hashCode());
-
-        SoftApConfiguration copy = new SoftApConfiguration.Builder(original).build();
-        assertThat(copy).isNotSameInstanceAs(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).isNotSameInstanceAs(original);
-        assertThat(unparceled).isEqualTo(original);
-        assertThat(unparceled.hashCode()).isEqualTo(original.hashCode());
-
-        SoftApConfiguration copy = new SoftApConfiguration.Builder(original).build();
-        assertThat(copy).isNotSameInstanceAs(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 890d3d3..0000000
--- a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java
+++ /dev/null
@@ -1,541 +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_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());
-    }
-}
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 9787cc0..0000000
--- a/wifi/tests/src/android/net/wifi/WifiInfoTest.java
+++ /dev/null
@@ -1,232 +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.assertNotEquals;
-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 com.android.modules.utils.build.SdkLevel;
-
-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());
-    }
-
-    @Test
-    public void testWifiInfoEquals() 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();
-        WifiInfo info2 = builder.build();
-        if (SdkLevel.isAtLeastS()) {
-            assertEquals(info1, info2);
-        } else {
-            assertNotEquals(info1, info2);
-        }
-
-        info1.setTrusted(false);
-        // Same behavior pre-S & post-S.
-        assertNotEquals(info1, info2);
-
-        info2.setTrusted(false);
-        if (SdkLevel.isAtLeastS()) {
-            assertEquals(info1, info2);
-        } else {
-            assertNotEquals(info1, info2);
-        }
-
-        info1.setSSID(WifiSsid.createFromHex(null));
-        // Same behavior pre-S & post-S.
-        assertNotEquals(info1, info2);
-
-        info2.setSSID(WifiSsid.createFromHex(null));
-        if (SdkLevel.isAtLeastS()) {
-            assertEquals(info1, info2);
-        } else {
-            assertNotEquals(info1, info2);
-        }
-    }
-
-    @Test
-    public void testWifiInfoHashcode() 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();
-        WifiInfo info2 = builder.build();
-        if (SdkLevel.isAtLeastS()) {
-            assertEquals(info1.hashCode(), info2.hashCode());
-        } else {
-            assertNotEquals(info1.hashCode(), info2.hashCode());
-        }
-
-        info1.setTrusted(false);
-        // Same behavior pre-S & post-S.
-        assertNotEquals(info1.hashCode(), info2.hashCode());
-
-        info2.setTrusted(false);
-        if (SdkLevel.isAtLeastS()) {
-            assertEquals(info1.hashCode(), info2.hashCode());
-        } else {
-            assertNotEquals(info1.hashCode(), info2.hashCode());
-        }
-
-        info1.setSSID(WifiSsid.createFromHex(null));
-        // Same behavior pre-S & post-S.
-        assertNotEquals(info1.hashCode(), info2.hashCode());
-
-        info2.setSSID(WifiSsid.createFromHex(null));
-        if (SdkLevel.isAtLeastS()) {
-            assertEquals(info1.hashCode(), info2.hashCode());
-        } else {
-            assertNotEquals(info1.hashCode(), info2.hashCode());
-        }
-    }
-}
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/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 00a0442..0000000
--- a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java
+++ /dev/null
@@ -1,965 +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);
-    }
-
-    /**
-     * 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);
-    }
-
-    /**
-     * 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);
-    }
-
-    /**
-     * 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);
-    }
-
-    /**
-     * 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);
-    }
-
-    /**
-     * 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);
-    }
-
-    /**
-     * 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);
-    }
-
-    /**
-     * 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);
-    }
-
-
-    /**
-     * 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());
-    }
-
-    /**
-     * 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());
-    }
-
-    /**
-     * 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);
-    }
-
-    /**
-     * 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 79e95e8..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[] testTlv = {
-                0, 1, 2 };
-        final int testLength = 3;
-        TlvBufferUtils.TlvIterable tlvIt10 = new TlvBufferUtils.TlvIterable(1, 0, testTlv);
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testTlvItInvalidSizeTm3L2() {
-        final byte[] testTlv = {
-                0, 1, 2 };
-        final int testLength = 3;
-        TlvBufferUtils.TlvIterable tlvIt10 = new TlvBufferUtils.TlvIterable(-3, 2, testTlv);
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testTlvItInvalidSizeT1Lm2() {
-        final byte[] testTlv = {
-                0, 1, 2 };
-        final int testLength = 3;
-        TlvBufferUtils.TlvIterable tlvIt10 = new TlvBufferUtils.TlvIterable(1, -2, testTlv);
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testTlvItInvalidSizeT1L3() {
-        final byte[] testTlv = {
-                0, 1, 2 };
-        final int testLength = 3;
-        TlvBufferUtils.TlvIterable tlvIt10 = new TlvBufferUtils.TlvIterable(1, 3, testTlv);
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testTlvItInvalidSizeT3L1() {
-        final byte[] testTlv = {
-                0, 1, 2 };
-        final int testLength = 3;
-        TlvBufferUtils.TlvIterable tlvIt10 = new TlvBufferUtils.TlvIterable(3, 1, testTlv);
-    }
-
-    /**
-     * 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 b65de6b..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(getMockNetworkSpecifier(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 = getMockNetworkSpecifier(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 = getMockNetworkSpecifier(6);
-        WifiAwareAgentNetworkSpecifier dut = new WifiAwareAgentNetworkSpecifier(nsThis);
-        WifiAwareNetworkSpecifier nsOther = getMockNetworkSpecifier(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(getMockNetworkSpecifier(10 + i));
-        }
-
-        WifiAwareAgentNetworkSpecifier dut = new WifiAwareAgentNetworkSpecifier(
-                nsSet.toArray(new WifiAwareNetworkSpecifier[numNs]));
-        WifiAwareNetworkSpecifier nsOther = getMockNetworkSpecifier(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(getMockNetworkSpecifier(10 + i));
-        }
-
-        WifiAwareAgentNetworkSpecifier oldNs = new WifiAwareAgentNetworkSpecifier(
-                nsSet.toArray(new WifiAwareNetworkSpecifier[nsSet.size()]));
-
-        nsSet.add(getMockNetworkSpecifier(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(getMockNetworkSpecifier(10 + i));
-        }
-
-        WifiAwareAgentNetworkSpecifier newNs = new WifiAwareAgentNetworkSpecifier(
-                nsSet.toArray(new WifiAwareNetworkSpecifier[nsSet.size()]));
-
-        nsSet.add(getMockNetworkSpecifier(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 mock (but valid) entries. Each can be
-     * differentiated (made unique) by specifying a different client ID.
-     */
-    WifiAwareNetworkSpecifier getMockNetworkSpecifier(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 43d728b..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: placeholder 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/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);
-    }
-}
diff --git a/wifi/tests/test-jarjar-rules.txt b/wifi/tests/test-jarjar-rules.txt
deleted file mode 100644
index 41b97ab..0000000
--- a/wifi/tests/test-jarjar-rules.txt
+++ /dev/null
@@ -1 +0,0 @@
-rule com.android.modules.utils.** com.android.wifi.test.x.@0
