diff --git a/Android.bp b/Android.bp
index d234411..36c2fa8 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1239,6 +1239,7 @@
     visibility: [
         "//frameworks/base/wifi",
         "//frameworks/base/services/net",
+        "//packages/modules/Wifi/framework",
     ],
 }
 
@@ -1263,7 +1264,10 @@
         "core/java/com/android/internal/util/StateMachine.java",
         "core/java/com/android/internal/util/WakeupMessage.java",
     ],
-    visibility: ["//frameworks/opt/net/wifi/service"],
+    visibility: [
+        "//frameworks/opt/net/wifi/service",
+        "//packages/modules/Wifi/service",
+    ],
 }
 
 // TODO(b/145644363): move this to under StubLibraries.bp or ApiDocs.bp
diff --git a/StubLibraries.bp b/StubLibraries.bp
index d4abeee..ed8781e 100644
--- a/StubLibraries.bp
+++ b/StubLibraries.bp
@@ -47,7 +47,6 @@
         "core/java/**/*.logtags",
         ":opt-telephony-srcs",
         ":opt-net-voip-srcs",
-        ":art.module.public.api{.public.stubs.source}",
         "**/package.html",
     ],
     sdk_version: "none",
@@ -240,6 +239,7 @@
     name: "android_stubs_current",
     srcs: [ ":api-stubs-docs-non-updatable" ],
     static_libs: [
+        "art.module.public.api.stubs",
         "conscrypt.module.public.api.stubs",
         "framework-media.stubs",
         "framework-mediaprovider.stubs",
@@ -258,6 +258,7 @@
     name: "android_system_stubs_current",
     srcs: [ ":system-api-stubs-docs-non-updatable" ],
     static_libs: [
+        "art.module.public.api.stubs",
         "conscrypt.module.public.api.stubs",
         "framework-media.stubs.system",
         "framework-mediaprovider.stubs.system",
@@ -292,6 +293,7 @@
     static_libs: [
         // Modules do not have test APIs, but we want to include their SystemApis, like we include
         // the SystemApi of framework-non-updatable-sources.
+        "art.module.public.api.stubs",
         "conscrypt.module.public.api.stubs",
         "framework-media.stubs.system",
         "framework-mediaprovider.stubs.system",
@@ -328,25 +330,12 @@
         "android_stubs_dists_default",
     ],
     libs: ["sdk_system_29_android"],
+    static_libs: ["art.module.public.api.stubs"],
     dist: {
         dir: "apistubs/android/module-lib",
     },
 }
 
-java_library_static {
-    name: "android_non_updatable_stubs_current",
-    srcs: [":api-stubs-docs-non-updatable"],
-    defaults: ["android_defaults_stubs_current"],
-    libs: ["sdk_system_29_android"],
-}
-
-java_library_static {
-    name: "android_system_non_updatable_stubs_current",
-    srcs: [":system-api-stubs-docs-non-updatable"],
-    defaults: ["android_defaults_stubs_current"],
-    libs: ["sdk_system_29_android"],
-}
-
 /////////////////////////////////////////////////////////////////////
 // hwbinder.stubs provides APIs required for building HIDL Java
 // libraries.
diff --git a/apex/permission/service/Android.bp b/apex/permission/service/Android.bp
index b7d8433..6e04edf 100644
--- a/apex/permission/service/Android.bp
+++ b/apex/permission/service/Android.bp
@@ -39,4 +39,6 @@
         "test_com.android.permission",
     ],
     installable: true,
+    // We don't have last-api tracking files for the public part of this jar's API.
+    unsafe_ignore_missing_latest_api: true,
 }
diff --git a/api/Android.bp b/api/Android.bp
index f11cd49..9a157b8 100644
--- a/api/Android.bp
+++ b/api/Android.bp
@@ -28,6 +28,7 @@
 genrule {
     name: "frameworks-base-api-current.txt",
     srcs: [
+        ":art.module.public.api{.public.api.txt}",
         ":conscrypt.module.public.api{.public.api.txt}",
         ":framework-media{.public.api.txt}",
         ":framework-mediaprovider{.public.api.txt}",
@@ -64,6 +65,7 @@
     name: "frameworks-base-api-current.srcjar",
     srcs: [
         ":api-stubs-docs-non-updatable",
+        ":art.module.public.api{.public.stubs.source}",
         ":conscrypt.module.public.api{.public.stubs.source}",
         ":framework-media{.public.stubs.source}",
         ":framework-mediaprovider{.public.stubs.source}",
@@ -83,6 +85,7 @@
 genrule {
     name: "frameworks-base-api-removed.txt",
     srcs: [
+        ":art.module.public.api{.public.removed-api.txt}",
         ":conscrypt.module.public.api{.public.removed-api.txt}",
         ":framework-media{.public.removed-api.txt}",
         ":framework-mediaprovider{.public.removed-api.txt}",
diff --git a/core/api/current.txt b/core/api/current.txt
index c79d4b8050..8681d41 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -19373,14 +19373,17 @@
   public class AudioManager {
     method @Deprecated public int abandonAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener);
     method public int abandonAudioFocusRequest(@NonNull android.media.AudioFocusRequest);
+    method public void addOnCommunicationDeviceChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.OnCommunicationDeviceChangedListener);
     method public void adjustStreamVolume(int, int, int);
     method public void adjustSuggestedStreamVolume(int, int, int);
     method public void adjustVolume(int, int);
+    method public void clearDeviceForCommunication();
     method public void dispatchMediaKeyEvent(android.view.KeyEvent);
     method public int generateAudioSessionId();
     method @NonNull public java.util.List<android.media.AudioPlaybackConfiguration> getActivePlaybackConfigurations();
     method @NonNull public java.util.List<android.media.AudioRecordingConfiguration> getActiveRecordingConfigurations();
     method public int getAllowedCapturePolicy();
+    method @Nullable public android.media.AudioDeviceInfo getDeviceForCommunication();
     method public android.media.AudioDeviceInfo[] getDevices(int);
     method public java.util.List<android.media.MicrophoneInfo> getMicrophones() throws java.io.IOException;
     method public int getMode();
@@ -19415,11 +19418,13 @@
     method @Deprecated public void registerMediaButtonEventReceiver(android.app.PendingIntent);
     method @Deprecated public void registerRemoteControlClient(android.media.RemoteControlClient);
     method @Deprecated public boolean registerRemoteController(android.media.RemoteController);
+    method public void removeOnCommunicationDeviceChangedListener(@NonNull android.media.AudioManager.OnCommunicationDeviceChangedListener);
     method @Deprecated public int requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, int, int);
     method public int requestAudioFocus(@NonNull android.media.AudioFocusRequest);
     method public void setAllowedCapturePolicy(int);
     method @Deprecated public void setBluetoothA2dpOn(boolean);
     method public void setBluetoothScoOn(boolean);
+    method public boolean setDeviceForCommunication(@NonNull android.media.AudioDeviceInfo);
     method public void setMicrophoneMute(boolean);
     method public void setMode(int);
     method public void setParameters(String);
@@ -19554,6 +19559,10 @@
     method public void onAudioFocusChange(int);
   }
 
+  public static interface AudioManager.OnCommunicationDeviceChangedListener {
+    method public void onCommunicationDeviceChanged(@Nullable android.media.AudioDeviceInfo);
+  }
+
   public final class AudioMetadata {
     method @NonNull public static android.media.AudioMetadataMap createMap();
   }
@@ -38109,708 +38118,6 @@
 
 }
 
-package android.system {
-
-  public final class ErrnoException extends java.lang.Exception {
-    ctor public ErrnoException(String, int);
-    ctor public ErrnoException(String, int, Throwable);
-    method @NonNull public java.io.IOException rethrowAsIOException() throws java.io.IOException;
-    method @NonNull public java.net.SocketException rethrowAsSocketException() throws java.net.SocketException;
-    field public final int errno;
-  }
-
-  public class Int64Ref {
-    ctor public Int64Ref(long);
-    field public long value;
-  }
-
-  public final class Os {
-    method public static java.io.FileDescriptor accept(java.io.FileDescriptor, java.net.InetSocketAddress) throws android.system.ErrnoException, java.net.SocketException;
-    method public static boolean access(String, int) throws android.system.ErrnoException;
-    method public static void bind(java.io.FileDescriptor, java.net.InetAddress, int) throws android.system.ErrnoException, java.net.SocketException;
-    method public static void bind(@NonNull java.io.FileDescriptor, @NonNull java.net.SocketAddress) throws android.system.ErrnoException, java.net.SocketException;
-    method public static void chmod(String, int) throws android.system.ErrnoException;
-    method public static void chown(String, int, int) throws android.system.ErrnoException;
-    method public static void close(java.io.FileDescriptor) throws android.system.ErrnoException;
-    method public static void connect(java.io.FileDescriptor, java.net.InetAddress, int) throws android.system.ErrnoException, java.net.SocketException;
-    method public static void connect(@NonNull java.io.FileDescriptor, @NonNull java.net.SocketAddress) throws android.system.ErrnoException, java.net.SocketException;
-    method public static java.io.FileDescriptor dup(java.io.FileDescriptor) throws android.system.ErrnoException;
-    method public static java.io.FileDescriptor dup2(java.io.FileDescriptor, int) throws android.system.ErrnoException;
-    method public static String[] environ();
-    method public static void execv(String, String[]) throws android.system.ErrnoException;
-    method public static void execve(String, String[], String[]) throws android.system.ErrnoException;
-    method public static void fchmod(java.io.FileDescriptor, int) throws android.system.ErrnoException;
-    method public static void fchown(java.io.FileDescriptor, int, int) throws android.system.ErrnoException;
-    method public static int fcntlInt(@NonNull java.io.FileDescriptor, int, int) throws android.system.ErrnoException;
-    method public static void fdatasync(java.io.FileDescriptor) throws android.system.ErrnoException;
-    method public static android.system.StructStat fstat(java.io.FileDescriptor) throws android.system.ErrnoException;
-    method public static android.system.StructStatVfs fstatvfs(java.io.FileDescriptor) throws android.system.ErrnoException;
-    method public static void fsync(java.io.FileDescriptor) throws android.system.ErrnoException;
-    method public static void ftruncate(java.io.FileDescriptor, long) throws android.system.ErrnoException;
-    method public static String gai_strerror(int);
-    method public static int getegid();
-    method public static String getenv(String);
-    method public static int geteuid();
-    method public static int getgid();
-    method public static java.net.SocketAddress getpeername(java.io.FileDescriptor) throws android.system.ErrnoException;
-    method public static int getpid();
-    method public static int getppid();
-    method public static java.net.SocketAddress getsockname(java.io.FileDescriptor) throws android.system.ErrnoException;
-    method @NonNull public static android.system.StructTimeval getsockoptTimeval(@NonNull java.io.FileDescriptor, int, int) throws android.system.ErrnoException;
-    method public static int gettid();
-    method public static int getuid();
-    method public static byte[] getxattr(String, String) throws android.system.ErrnoException;
-    method public static String if_indextoname(int);
-    method public static int if_nametoindex(String);
-    method public static java.net.InetAddress inet_pton(int, String);
-    method public static boolean isatty(java.io.FileDescriptor);
-    method public static void kill(int, int) throws android.system.ErrnoException;
-    method public static void lchown(String, int, int) throws android.system.ErrnoException;
-    method public static void link(String, String) throws android.system.ErrnoException;
-    method public static void listen(java.io.FileDescriptor, int) throws android.system.ErrnoException;
-    method public static String[] listxattr(String) throws android.system.ErrnoException;
-    method public static long lseek(java.io.FileDescriptor, long, int) throws android.system.ErrnoException;
-    method public static android.system.StructStat lstat(String) throws android.system.ErrnoException;
-    method @NonNull public static java.io.FileDescriptor memfd_create(@NonNull String, int) throws android.system.ErrnoException;
-    method public static void mincore(long, long, byte[]) throws android.system.ErrnoException;
-    method public static void mkdir(String, int) throws android.system.ErrnoException;
-    method public static void mkfifo(String, int) throws android.system.ErrnoException;
-    method public static void mlock(long, long) throws android.system.ErrnoException;
-    method public static long mmap(long, long, int, int, java.io.FileDescriptor, long) throws android.system.ErrnoException;
-    method public static void msync(long, long, int) throws android.system.ErrnoException;
-    method public static void munlock(long, long) throws android.system.ErrnoException;
-    method public static void munmap(long, long) throws android.system.ErrnoException;
-    method public static java.io.FileDescriptor open(String, int, int) throws android.system.ErrnoException;
-    method public static java.io.FileDescriptor[] pipe() throws android.system.ErrnoException;
-    method public static int poll(android.system.StructPollfd[], int) throws android.system.ErrnoException;
-    method public static void posix_fallocate(java.io.FileDescriptor, long, long) throws android.system.ErrnoException;
-    method public static int prctl(int, long, long, long, long) throws android.system.ErrnoException;
-    method public static int pread(java.io.FileDescriptor, java.nio.ByteBuffer, long) throws android.system.ErrnoException, java.io.InterruptedIOException;
-    method public static int pread(java.io.FileDescriptor, byte[], int, int, long) throws android.system.ErrnoException, java.io.InterruptedIOException;
-    method public static int pwrite(java.io.FileDescriptor, java.nio.ByteBuffer, long) throws android.system.ErrnoException, java.io.InterruptedIOException;
-    method public static int pwrite(java.io.FileDescriptor, byte[], int, int, long) throws android.system.ErrnoException, java.io.InterruptedIOException;
-    method public static int read(java.io.FileDescriptor, java.nio.ByteBuffer) throws android.system.ErrnoException, java.io.InterruptedIOException;
-    method public static int read(java.io.FileDescriptor, byte[], int, int) throws android.system.ErrnoException, java.io.InterruptedIOException;
-    method public static String readlink(String) throws android.system.ErrnoException;
-    method public static int readv(java.io.FileDescriptor, Object[], int[], int[]) throws android.system.ErrnoException, java.io.InterruptedIOException;
-    method public static int recvfrom(java.io.FileDescriptor, java.nio.ByteBuffer, int, java.net.InetSocketAddress) throws android.system.ErrnoException, java.net.SocketException;
-    method public static int recvfrom(java.io.FileDescriptor, byte[], int, int, int, java.net.InetSocketAddress) throws android.system.ErrnoException, java.net.SocketException;
-    method public static void remove(String) throws android.system.ErrnoException;
-    method public static void removexattr(String, String) throws android.system.ErrnoException;
-    method public static void rename(String, String) throws android.system.ErrnoException;
-    method public static long sendfile(java.io.FileDescriptor, java.io.FileDescriptor, android.system.Int64Ref, long) throws android.system.ErrnoException;
-    method public static int sendto(java.io.FileDescriptor, java.nio.ByteBuffer, int, java.net.InetAddress, int) throws android.system.ErrnoException, java.net.SocketException;
-    method public static int sendto(java.io.FileDescriptor, byte[], int, int, int, java.net.InetAddress, int) throws android.system.ErrnoException, java.net.SocketException;
-    method public static int sendto(@NonNull java.io.FileDescriptor, @NonNull byte[], int, int, int, @Nullable java.net.SocketAddress) throws android.system.ErrnoException, java.net.SocketException;
-    method @Deprecated public static void setegid(int) throws android.system.ErrnoException;
-    method public static void setenv(String, String, boolean) throws android.system.ErrnoException;
-    method @Deprecated public static void seteuid(int) throws android.system.ErrnoException;
-    method @Deprecated public static void setgid(int) throws android.system.ErrnoException;
-    method public static int setsid() throws android.system.ErrnoException;
-    method public static void setsockoptInt(java.io.FileDescriptor, int, int, int) throws android.system.ErrnoException;
-    method public static void setsockoptTimeval(@NonNull java.io.FileDescriptor, int, int, @NonNull android.system.StructTimeval) throws android.system.ErrnoException;
-    method @Deprecated public static void setuid(int) throws android.system.ErrnoException;
-    method public static void setxattr(String, String, byte[], int) throws android.system.ErrnoException;
-    method public static void shutdown(java.io.FileDescriptor, int) throws android.system.ErrnoException;
-    method public static java.io.FileDescriptor socket(int, int, int) throws android.system.ErrnoException;
-    method public static void socketpair(int, int, int, java.io.FileDescriptor, java.io.FileDescriptor) throws android.system.ErrnoException;
-    method public static android.system.StructStat stat(String) throws android.system.ErrnoException;
-    method public static android.system.StructStatVfs statvfs(String) throws android.system.ErrnoException;
-    method public static String strerror(int);
-    method public static String strsignal(int);
-    method public static void symlink(String, String) throws android.system.ErrnoException;
-    method public static long sysconf(int);
-    method public static void tcdrain(java.io.FileDescriptor) throws android.system.ErrnoException;
-    method public static void tcsendbreak(java.io.FileDescriptor, int) throws android.system.ErrnoException;
-    method public static int umask(int);
-    method public static android.system.StructUtsname uname();
-    method public static void unsetenv(String) throws android.system.ErrnoException;
-    method public static int write(java.io.FileDescriptor, java.nio.ByteBuffer) throws android.system.ErrnoException, java.io.InterruptedIOException;
-    method public static int write(java.io.FileDescriptor, byte[], int, int) throws android.system.ErrnoException, java.io.InterruptedIOException;
-    method public static int writev(java.io.FileDescriptor, Object[], int[], int[]) throws android.system.ErrnoException, java.io.InterruptedIOException;
-  }
-
-  public final class OsConstants {
-    method public static boolean S_ISBLK(int);
-    method public static boolean S_ISCHR(int);
-    method public static boolean S_ISDIR(int);
-    method public static boolean S_ISFIFO(int);
-    method public static boolean S_ISLNK(int);
-    method public static boolean S_ISREG(int);
-    method public static boolean S_ISSOCK(int);
-    method public static boolean WCOREDUMP(int);
-    method public static int WEXITSTATUS(int);
-    method public static boolean WIFEXITED(int);
-    method public static boolean WIFSIGNALED(int);
-    method public static boolean WIFSTOPPED(int);
-    method public static int WSTOPSIG(int);
-    method public static int WTERMSIG(int);
-    method public static String errnoName(int);
-    method public static String gaiName(int);
-    field public static final int AF_INET;
-    field public static final int AF_INET6;
-    field public static final int AF_NETLINK;
-    field public static final int AF_PACKET;
-    field public static final int AF_UNIX;
-    field public static final int AF_UNSPEC;
-    field public static final int AI_ADDRCONFIG;
-    field public static final int AI_ALL;
-    field public static final int AI_CANONNAME;
-    field public static final int AI_NUMERICHOST;
-    field public static final int AI_NUMERICSERV;
-    field public static final int AI_PASSIVE;
-    field public static final int AI_V4MAPPED;
-    field public static final int ARPHRD_ETHER;
-    field public static final int CAP_AUDIT_CONTROL;
-    field public static final int CAP_AUDIT_WRITE;
-    field public static final int CAP_BLOCK_SUSPEND;
-    field public static final int CAP_CHOWN;
-    field public static final int CAP_DAC_OVERRIDE;
-    field public static final int CAP_DAC_READ_SEARCH;
-    field public static final int CAP_FOWNER;
-    field public static final int CAP_FSETID;
-    field public static final int CAP_IPC_LOCK;
-    field public static final int CAP_IPC_OWNER;
-    field public static final int CAP_KILL;
-    field public static final int CAP_LAST_CAP;
-    field public static final int CAP_LEASE;
-    field public static final int CAP_LINUX_IMMUTABLE;
-    field public static final int CAP_MAC_ADMIN;
-    field public static final int CAP_MAC_OVERRIDE;
-    field public static final int CAP_MKNOD;
-    field public static final int CAP_NET_ADMIN;
-    field public static final int CAP_NET_BIND_SERVICE;
-    field public static final int CAP_NET_BROADCAST;
-    field public static final int CAP_NET_RAW;
-    field public static final int CAP_SETFCAP;
-    field public static final int CAP_SETGID;
-    field public static final int CAP_SETPCAP;
-    field public static final int CAP_SETUID;
-    field public static final int CAP_SYSLOG;
-    field public static final int CAP_SYS_ADMIN;
-    field public static final int CAP_SYS_BOOT;
-    field public static final int CAP_SYS_CHROOT;
-    field public static final int CAP_SYS_MODULE;
-    field public static final int CAP_SYS_NICE;
-    field public static final int CAP_SYS_PACCT;
-    field public static final int CAP_SYS_PTRACE;
-    field public static final int CAP_SYS_RAWIO;
-    field public static final int CAP_SYS_RESOURCE;
-    field public static final int CAP_SYS_TIME;
-    field public static final int CAP_SYS_TTY_CONFIG;
-    field public static final int CAP_WAKE_ALARM;
-    field public static final int E2BIG;
-    field public static final int EACCES;
-    field public static final int EADDRINUSE;
-    field public static final int EADDRNOTAVAIL;
-    field public static final int EAFNOSUPPORT;
-    field public static final int EAGAIN;
-    field public static final int EAI_AGAIN;
-    field public static final int EAI_BADFLAGS;
-    field public static final int EAI_FAIL;
-    field public static final int EAI_FAMILY;
-    field public static final int EAI_MEMORY;
-    field public static final int EAI_NODATA;
-    field public static final int EAI_NONAME;
-    field public static final int EAI_OVERFLOW;
-    field public static final int EAI_SERVICE;
-    field public static final int EAI_SOCKTYPE;
-    field public static final int EAI_SYSTEM;
-    field public static final int EALREADY;
-    field public static final int EBADF;
-    field public static final int EBADMSG;
-    field public static final int EBUSY;
-    field public static final int ECANCELED;
-    field public static final int ECHILD;
-    field public static final int ECONNABORTED;
-    field public static final int ECONNREFUSED;
-    field public static final int ECONNRESET;
-    field public static final int EDEADLK;
-    field public static final int EDESTADDRREQ;
-    field public static final int EDOM;
-    field public static final int EDQUOT;
-    field public static final int EEXIST;
-    field public static final int EFAULT;
-    field public static final int EFBIG;
-    field public static final int EHOSTUNREACH;
-    field public static final int EIDRM;
-    field public static final int EILSEQ;
-    field public static final int EINPROGRESS;
-    field public static final int EINTR;
-    field public static final int EINVAL;
-    field public static final int EIO;
-    field public static final int EISCONN;
-    field public static final int EISDIR;
-    field public static final int ELOOP;
-    field public static final int EMFILE;
-    field public static final int EMLINK;
-    field public static final int EMSGSIZE;
-    field public static final int EMULTIHOP;
-    field public static final int ENAMETOOLONG;
-    field public static final int ENETDOWN;
-    field public static final int ENETRESET;
-    field public static final int ENETUNREACH;
-    field public static final int ENFILE;
-    field public static final int ENOBUFS;
-    field public static final int ENODATA;
-    field public static final int ENODEV;
-    field public static final int ENOENT;
-    field public static final int ENOEXEC;
-    field public static final int ENOLCK;
-    field public static final int ENOLINK;
-    field public static final int ENOMEM;
-    field public static final int ENOMSG;
-    field public static final int ENOPROTOOPT;
-    field public static final int ENOSPC;
-    field public static final int ENOSR;
-    field public static final int ENOSTR;
-    field public static final int ENOSYS;
-    field public static final int ENOTCONN;
-    field public static final int ENOTDIR;
-    field public static final int ENOTEMPTY;
-    field public static final int ENOTSOCK;
-    field public static final int ENOTSUP;
-    field public static final int ENOTTY;
-    field public static final int ENXIO;
-    field public static final int EOPNOTSUPP;
-    field public static final int EOVERFLOW;
-    field public static final int EPERM;
-    field public static final int EPIPE;
-    field public static final int EPROTO;
-    field public static final int EPROTONOSUPPORT;
-    field public static final int EPROTOTYPE;
-    field public static final int ERANGE;
-    field public static final int EROFS;
-    field public static final int ESPIPE;
-    field public static final int ESRCH;
-    field public static final int ESTALE;
-    field public static final int ETH_P_ALL;
-    field public static final int ETH_P_ARP;
-    field public static final int ETH_P_IP;
-    field public static final int ETH_P_IPV6;
-    field public static final int ETIME;
-    field public static final int ETIMEDOUT;
-    field public static final int ETXTBSY;
-    field public static final int EXDEV;
-    field public static final int EXIT_FAILURE;
-    field public static final int EXIT_SUCCESS;
-    field public static final int FD_CLOEXEC;
-    field public static final int FIONREAD;
-    field public static final int F_DUPFD;
-    field public static final int F_DUPFD_CLOEXEC;
-    field public static final int F_GETFD;
-    field public static final int F_GETFL;
-    field public static final int F_GETLK;
-    field public static final int F_GETLK64;
-    field public static final int F_GETOWN;
-    field public static final int F_OK;
-    field public static final int F_RDLCK;
-    field public static final int F_SETFD;
-    field public static final int F_SETFL;
-    field public static final int F_SETLK;
-    field public static final int F_SETLK64;
-    field public static final int F_SETLKW;
-    field public static final int F_SETLKW64;
-    field public static final int F_SETOWN;
-    field public static final int F_UNLCK;
-    field public static final int F_WRLCK;
-    field public static final int ICMP6_ECHO_REPLY;
-    field public static final int ICMP6_ECHO_REQUEST;
-    field public static final int ICMP_ECHO;
-    field public static final int ICMP_ECHOREPLY;
-    field public static final int IFA_F_DADFAILED;
-    field public static final int IFA_F_DEPRECATED;
-    field public static final int IFA_F_HOMEADDRESS;
-    field public static final int IFA_F_NODAD;
-    field public static final int IFA_F_OPTIMISTIC;
-    field public static final int IFA_F_PERMANENT;
-    field public static final int IFA_F_SECONDARY;
-    field public static final int IFA_F_TEMPORARY;
-    field public static final int IFA_F_TENTATIVE;
-    field public static final int IFF_ALLMULTI;
-    field public static final int IFF_AUTOMEDIA;
-    field public static final int IFF_BROADCAST;
-    field public static final int IFF_DEBUG;
-    field public static final int IFF_DYNAMIC;
-    field public static final int IFF_LOOPBACK;
-    field public static final int IFF_MASTER;
-    field public static final int IFF_MULTICAST;
-    field public static final int IFF_NOARP;
-    field public static final int IFF_NOTRAILERS;
-    field public static final int IFF_POINTOPOINT;
-    field public static final int IFF_PORTSEL;
-    field public static final int IFF_PROMISC;
-    field public static final int IFF_RUNNING;
-    field public static final int IFF_SLAVE;
-    field public static final int IFF_UP;
-    field public static final int IPPROTO_ICMP;
-    field public static final int IPPROTO_ICMPV6;
-    field public static final int IPPROTO_IP;
-    field public static final int IPPROTO_IPV6;
-    field public static final int IPPROTO_RAW;
-    field public static final int IPPROTO_TCP;
-    field public static final int IPPROTO_UDP;
-    field public static final int IPV6_CHECKSUM;
-    field public static final int IPV6_MULTICAST_HOPS;
-    field public static final int IPV6_MULTICAST_IF;
-    field public static final int IPV6_MULTICAST_LOOP;
-    field public static final int IPV6_RECVDSTOPTS;
-    field public static final int IPV6_RECVHOPLIMIT;
-    field public static final int IPV6_RECVHOPOPTS;
-    field public static final int IPV6_RECVPKTINFO;
-    field public static final int IPV6_RECVRTHDR;
-    field public static final int IPV6_RECVTCLASS;
-    field public static final int IPV6_TCLASS;
-    field public static final int IPV6_UNICAST_HOPS;
-    field public static final int IPV6_V6ONLY;
-    field public static final int IP_MULTICAST_IF;
-    field public static final int IP_MULTICAST_LOOP;
-    field public static final int IP_MULTICAST_TTL;
-    field public static final int IP_TOS;
-    field public static final int IP_TTL;
-    field public static final int MAP_ANONYMOUS;
-    field public static final int MAP_FIXED;
-    field public static final int MAP_PRIVATE;
-    field public static final int MAP_SHARED;
-    field public static final int MCAST_BLOCK_SOURCE;
-    field public static final int MCAST_JOIN_GROUP;
-    field public static final int MCAST_JOIN_SOURCE_GROUP;
-    field public static final int MCAST_LEAVE_GROUP;
-    field public static final int MCAST_LEAVE_SOURCE_GROUP;
-    field public static final int MCAST_UNBLOCK_SOURCE;
-    field public static final int MCL_CURRENT;
-    field public static final int MCL_FUTURE;
-    field public static final int MFD_CLOEXEC;
-    field public static final int MSG_CTRUNC;
-    field public static final int MSG_DONTROUTE;
-    field public static final int MSG_EOR;
-    field public static final int MSG_OOB;
-    field public static final int MSG_PEEK;
-    field public static final int MSG_TRUNC;
-    field public static final int MSG_WAITALL;
-    field public static final int MS_ASYNC;
-    field public static final int MS_INVALIDATE;
-    field public static final int MS_SYNC;
-    field public static final int NETLINK_INET_DIAG;
-    field public static final int NETLINK_NETFILTER;
-    field public static final int NETLINK_ROUTE;
-    field public static final int NI_DGRAM;
-    field public static final int NI_NAMEREQD;
-    field public static final int NI_NOFQDN;
-    field public static final int NI_NUMERICHOST;
-    field public static final int NI_NUMERICSERV;
-    field public static final int O_ACCMODE;
-    field public static final int O_APPEND;
-    field public static final int O_CLOEXEC;
-    field public static final int O_CREAT;
-    field public static final int O_DSYNC;
-    field public static final int O_EXCL;
-    field public static final int O_NOCTTY;
-    field public static final int O_NOFOLLOW;
-    field public static final int O_NONBLOCK;
-    field public static final int O_RDONLY;
-    field public static final int O_RDWR;
-    field public static final int O_SYNC;
-    field public static final int O_TRUNC;
-    field public static final int O_WRONLY;
-    field public static final int POLLERR;
-    field public static final int POLLHUP;
-    field public static final int POLLIN;
-    field public static final int POLLNVAL;
-    field public static final int POLLOUT;
-    field public static final int POLLPRI;
-    field public static final int POLLRDBAND;
-    field public static final int POLLRDNORM;
-    field public static final int POLLWRBAND;
-    field public static final int POLLWRNORM;
-    field public static final int PROT_EXEC;
-    field public static final int PROT_NONE;
-    field public static final int PROT_READ;
-    field public static final int PROT_WRITE;
-    field public static final int PR_GET_DUMPABLE;
-    field public static final int PR_SET_DUMPABLE;
-    field public static final int PR_SET_NO_NEW_PRIVS;
-    field public static final int RTMGRP_NEIGH;
-    field public static final int RT_SCOPE_HOST;
-    field public static final int RT_SCOPE_LINK;
-    field public static final int RT_SCOPE_NOWHERE;
-    field public static final int RT_SCOPE_SITE;
-    field public static final int RT_SCOPE_UNIVERSE;
-    field public static final int R_OK;
-    field public static final int SEEK_CUR;
-    field public static final int SEEK_END;
-    field public static final int SEEK_SET;
-    field public static final int SHUT_RD;
-    field public static final int SHUT_RDWR;
-    field public static final int SHUT_WR;
-    field public static final int SIGABRT;
-    field public static final int SIGALRM;
-    field public static final int SIGBUS;
-    field public static final int SIGCHLD;
-    field public static final int SIGCONT;
-    field public static final int SIGFPE;
-    field public static final int SIGHUP;
-    field public static final int SIGILL;
-    field public static final int SIGINT;
-    field public static final int SIGIO;
-    field public static final int SIGKILL;
-    field public static final int SIGPIPE;
-    field public static final int SIGPROF;
-    field public static final int SIGPWR;
-    field public static final int SIGQUIT;
-    field public static final int SIGRTMAX;
-    field public static final int SIGRTMIN;
-    field public static final int SIGSEGV;
-    field public static final int SIGSTKFLT;
-    field public static final int SIGSTOP;
-    field public static final int SIGSYS;
-    field public static final int SIGTERM;
-    field public static final int SIGTRAP;
-    field public static final int SIGTSTP;
-    field public static final int SIGTTIN;
-    field public static final int SIGTTOU;
-    field public static final int SIGURG;
-    field public static final int SIGUSR1;
-    field public static final int SIGUSR2;
-    field public static final int SIGVTALRM;
-    field public static final int SIGWINCH;
-    field public static final int SIGXCPU;
-    field public static final int SIGXFSZ;
-    field public static final int SIOCGIFADDR;
-    field public static final int SIOCGIFBRDADDR;
-    field public static final int SIOCGIFDSTADDR;
-    field public static final int SIOCGIFNETMASK;
-    field public static final int SOCK_CLOEXEC;
-    field public static final int SOCK_DGRAM;
-    field public static final int SOCK_NONBLOCK;
-    field public static final int SOCK_RAW;
-    field public static final int SOCK_SEQPACKET;
-    field public static final int SOCK_STREAM;
-    field public static final int SOL_SOCKET;
-    field public static final int SO_BINDTODEVICE;
-    field public static final int SO_BROADCAST;
-    field public static final int SO_DEBUG;
-    field public static final int SO_DONTROUTE;
-    field public static final int SO_ERROR;
-    field public static final int SO_KEEPALIVE;
-    field public static final int SO_LINGER;
-    field public static final int SO_OOBINLINE;
-    field public static final int SO_PASSCRED;
-    field public static final int SO_PEERCRED;
-    field public static final int SO_RCVBUF;
-    field public static final int SO_RCVLOWAT;
-    field public static final int SO_RCVTIMEO;
-    field public static final int SO_REUSEADDR;
-    field public static final int SO_SNDBUF;
-    field public static final int SO_SNDLOWAT;
-    field public static final int SO_SNDTIMEO;
-    field public static final int SO_TYPE;
-    field public static final int STDERR_FILENO;
-    field public static final int STDIN_FILENO;
-    field public static final int STDOUT_FILENO;
-    field public static final int ST_MANDLOCK;
-    field public static final int ST_NOATIME;
-    field public static final int ST_NODEV;
-    field public static final int ST_NODIRATIME;
-    field public static final int ST_NOEXEC;
-    field public static final int ST_NOSUID;
-    field public static final int ST_RDONLY;
-    field public static final int ST_RELATIME;
-    field public static final int ST_SYNCHRONOUS;
-    field public static final int S_IFBLK;
-    field public static final int S_IFCHR;
-    field public static final int S_IFDIR;
-    field public static final int S_IFIFO;
-    field public static final int S_IFLNK;
-    field public static final int S_IFMT;
-    field public static final int S_IFREG;
-    field public static final int S_IFSOCK;
-    field public static final int S_IRGRP;
-    field public static final int S_IROTH;
-    field public static final int S_IRUSR;
-    field public static final int S_IRWXG;
-    field public static final int S_IRWXO;
-    field public static final int S_IRWXU;
-    field public static final int S_ISGID;
-    field public static final int S_ISUID;
-    field public static final int S_ISVTX;
-    field public static final int S_IWGRP;
-    field public static final int S_IWOTH;
-    field public static final int S_IWUSR;
-    field public static final int S_IXGRP;
-    field public static final int S_IXOTH;
-    field public static final int S_IXUSR;
-    field public static final int TCP_NODELAY;
-    field public static final int TCP_USER_TIMEOUT;
-    field public static final int WCONTINUED;
-    field public static final int WEXITED;
-    field public static final int WNOHANG;
-    field public static final int WNOWAIT;
-    field public static final int WSTOPPED;
-    field public static final int WUNTRACED;
-    field public static final int W_OK;
-    field public static final int X_OK;
-    field public static final int _SC_2_CHAR_TERM;
-    field public static final int _SC_2_C_BIND;
-    field public static final int _SC_2_C_DEV;
-    field public static final int _SC_2_C_VERSION;
-    field public static final int _SC_2_FORT_DEV;
-    field public static final int _SC_2_FORT_RUN;
-    field public static final int _SC_2_LOCALEDEF;
-    field public static final int _SC_2_SW_DEV;
-    field public static final int _SC_2_UPE;
-    field public static final int _SC_2_VERSION;
-    field public static final int _SC_AIO_LISTIO_MAX;
-    field public static final int _SC_AIO_MAX;
-    field public static final int _SC_AIO_PRIO_DELTA_MAX;
-    field public static final int _SC_ARG_MAX;
-    field public static final int _SC_ASYNCHRONOUS_IO;
-    field public static final int _SC_ATEXIT_MAX;
-    field public static final int _SC_AVPHYS_PAGES;
-    field public static final int _SC_BC_BASE_MAX;
-    field public static final int _SC_BC_DIM_MAX;
-    field public static final int _SC_BC_SCALE_MAX;
-    field public static final int _SC_BC_STRING_MAX;
-    field public static final int _SC_CHILD_MAX;
-    field public static final int _SC_CLK_TCK;
-    field public static final int _SC_COLL_WEIGHTS_MAX;
-    field public static final int _SC_DELAYTIMER_MAX;
-    field public static final int _SC_EXPR_NEST_MAX;
-    field public static final int _SC_FSYNC;
-    field public static final int _SC_GETGR_R_SIZE_MAX;
-    field public static final int _SC_GETPW_R_SIZE_MAX;
-    field public static final int _SC_IOV_MAX;
-    field public static final int _SC_JOB_CONTROL;
-    field public static final int _SC_LINE_MAX;
-    field public static final int _SC_LOGIN_NAME_MAX;
-    field public static final int _SC_MAPPED_FILES;
-    field public static final int _SC_MEMLOCK;
-    field public static final int _SC_MEMLOCK_RANGE;
-    field public static final int _SC_MEMORY_PROTECTION;
-    field public static final int _SC_MESSAGE_PASSING;
-    field public static final int _SC_MQ_OPEN_MAX;
-    field public static final int _SC_MQ_PRIO_MAX;
-    field public static final int _SC_NGROUPS_MAX;
-    field public static final int _SC_NPROCESSORS_CONF;
-    field public static final int _SC_NPROCESSORS_ONLN;
-    field public static final int _SC_OPEN_MAX;
-    field public static final int _SC_PAGESIZE;
-    field public static final int _SC_PAGE_SIZE;
-    field public static final int _SC_PASS_MAX;
-    field public static final int _SC_PHYS_PAGES;
-    field public static final int _SC_PRIORITIZED_IO;
-    field public static final int _SC_PRIORITY_SCHEDULING;
-    field public static final int _SC_REALTIME_SIGNALS;
-    field public static final int _SC_RE_DUP_MAX;
-    field public static final int _SC_RTSIG_MAX;
-    field public static final int _SC_SAVED_IDS;
-    field public static final int _SC_SEMAPHORES;
-    field public static final int _SC_SEM_NSEMS_MAX;
-    field public static final int _SC_SEM_VALUE_MAX;
-    field public static final int _SC_SHARED_MEMORY_OBJECTS;
-    field public static final int _SC_SIGQUEUE_MAX;
-    field public static final int _SC_STREAM_MAX;
-    field public static final int _SC_SYNCHRONIZED_IO;
-    field public static final int _SC_THREADS;
-    field public static final int _SC_THREAD_ATTR_STACKADDR;
-    field public static final int _SC_THREAD_ATTR_STACKSIZE;
-    field public static final int _SC_THREAD_DESTRUCTOR_ITERATIONS;
-    field public static final int _SC_THREAD_KEYS_MAX;
-    field public static final int _SC_THREAD_PRIORITY_SCHEDULING;
-    field public static final int _SC_THREAD_PRIO_INHERIT;
-    field public static final int _SC_THREAD_PRIO_PROTECT;
-    field public static final int _SC_THREAD_SAFE_FUNCTIONS;
-    field public static final int _SC_THREAD_STACK_MIN;
-    field public static final int _SC_THREAD_THREADS_MAX;
-    field public static final int _SC_TIMERS;
-    field public static final int _SC_TIMER_MAX;
-    field public static final int _SC_TTY_NAME_MAX;
-    field public static final int _SC_TZNAME_MAX;
-    field public static final int _SC_VERSION;
-    field public static final int _SC_XBS5_ILP32_OFF32;
-    field public static final int _SC_XBS5_ILP32_OFFBIG;
-    field public static final int _SC_XBS5_LP64_OFF64;
-    field public static final int _SC_XBS5_LPBIG_OFFBIG;
-    field public static final int _SC_XOPEN_CRYPT;
-    field public static final int _SC_XOPEN_ENH_I18N;
-    field public static final int _SC_XOPEN_LEGACY;
-    field public static final int _SC_XOPEN_REALTIME;
-    field public static final int _SC_XOPEN_REALTIME_THREADS;
-    field public static final int _SC_XOPEN_SHM;
-    field public static final int _SC_XOPEN_UNIX;
-    field public static final int _SC_XOPEN_VERSION;
-    field public static final int _SC_XOPEN_XCU_VERSION;
-  }
-
-  public final class StructPollfd {
-    ctor public StructPollfd();
-    field public short events;
-    field public java.io.FileDescriptor fd;
-    field public short revents;
-    field public Object userData;
-  }
-
-  public final class StructStat {
-    ctor public StructStat(long, long, int, long, int, int, long, long, long, long, long, long, long);
-    ctor public StructStat(long, long, int, long, int, int, long, long, android.system.StructTimespec, android.system.StructTimespec, android.system.StructTimespec, long, long);
-    field public final android.system.StructTimespec st_atim;
-    field public final long st_atime;
-    field public final long st_blksize;
-    field public final long st_blocks;
-    field public final android.system.StructTimespec st_ctim;
-    field public final long st_ctime;
-    field public final long st_dev;
-    field public final int st_gid;
-    field public final long st_ino;
-    field public final int st_mode;
-    field public final android.system.StructTimespec st_mtim;
-    field public final long st_mtime;
-    field public final long st_nlink;
-    field public final long st_rdev;
-    field public final long st_size;
-    field public final int st_uid;
-  }
-
-  public final class StructStatVfs {
-    ctor public StructStatVfs(long, long, long, long, long, long, long, long, long, long, long);
-    field public final long f_bavail;
-    field public final long f_bfree;
-    field public final long f_blocks;
-    field public final long f_bsize;
-    field public final long f_favail;
-    field public final long f_ffree;
-    field public final long f_files;
-    field public final long f_flag;
-    field public final long f_frsize;
-    field public final long f_fsid;
-    field public final long f_namemax;
-  }
-
-  public final class StructTimespec implements java.lang.Comparable<android.system.StructTimespec> {
-    ctor public StructTimespec(long, long);
-    method public int compareTo(android.system.StructTimespec);
-    field public final long tv_nsec;
-    field public final long tv_sec;
-  }
-
-  public final class StructTimeval {
-    method @NonNull public static android.system.StructTimeval fromMillis(long);
-    method public long toMillis();
-    field public final long tv_sec;
-    field public final long tv_usec;
-  }
-
-  public final class StructUtsname {
-    ctor public StructUtsname(String, String, String, String, String);
-    field public final String machine;
-    field public final String nodename;
-    field public final String release;
-    field public final String sysname;
-    field public final String version;
-  }
-
-}
-
 package android.telecom {
 
   public final class Call {
@@ -41765,7 +41072,7 @@
     method @Deprecated public String iccTransmitApduLogicalChannel(int, int, int, int, int, int, String);
     method public boolean isConcurrentVoiceAndDataSupported();
     method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_NETWORK_STATE, android.Manifest.permission.READ_PHONE_STATE, "android.permission.READ_PRIVILEGED_PHONE_STATE"}) public boolean isDataConnectionAllowed();
-    method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_NETWORK_STATE, android.Manifest.permission.MODIFY_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isDataEnabled();
+    method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_NETWORK_STATE, android.Manifest.permission.MODIFY_PHONE_STATE}) public boolean isDataEnabled();
     method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_NETWORK_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isDataEnabledForReason(int);
     method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_NETWORK_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isDataRoamingEnabled();
     method public boolean isEmergencyNumber(@NonNull String);
@@ -55192,16952 +54499,6 @@
 
 }
 
-package dalvik.annotation {
-
-  @Deprecated @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Target({java.lang.annotation.ElementType.ANNOTATION_TYPE}) public @interface TestTarget {
-    method @Deprecated public abstract String conceptName() default "";
-    method @Deprecated public abstract Class<?>[] methodArgs() default {};
-    method @Deprecated public abstract String methodName() default "";
-  }
-
-  @Deprecated @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE}) public @interface TestTargetClass {
-    method @Deprecated public abstract Class<?> value();
-  }
-
-}
-
-package dalvik.bytecode {
-
-  public final class OpcodeInfo {
-    field public static final int MAXIMUM_PACKED_VALUE;
-    field public static final int MAXIMUM_VALUE;
-  }
-
-  public interface Opcodes {
-    field public static final int OP_ADD_DOUBLE = 171; // 0xab
-    field public static final int OP_ADD_DOUBLE_2ADDR = 203; // 0xcb
-    field public static final int OP_ADD_FLOAT = 166; // 0xa6
-    field public static final int OP_ADD_FLOAT_2ADDR = 198; // 0xc6
-    field public static final int OP_ADD_INT = 144; // 0x90
-    field public static final int OP_ADD_INT_2ADDR = 176; // 0xb0
-    field public static final int OP_ADD_INT_LIT16 = 208; // 0xd0
-    field public static final int OP_ADD_INT_LIT8 = 216; // 0xd8
-    field public static final int OP_ADD_LONG = 155; // 0x9b
-    field public static final int OP_ADD_LONG_2ADDR = 187; // 0xbb
-    field public static final int OP_AGET = 68; // 0x44
-    field public static final int OP_AGET_BOOLEAN = 71; // 0x47
-    field public static final int OP_AGET_BYTE = 72; // 0x48
-    field public static final int OP_AGET_CHAR = 73; // 0x49
-    field public static final int OP_AGET_OBJECT = 70; // 0x46
-    field public static final int OP_AGET_SHORT = 74; // 0x4a
-    field public static final int OP_AGET_WIDE = 69; // 0x45
-    field public static final int OP_AND_INT = 149; // 0x95
-    field public static final int OP_AND_INT_2ADDR = 181; // 0xb5
-    field public static final int OP_AND_INT_LIT16 = 213; // 0xd5
-    field public static final int OP_AND_INT_LIT8 = 221; // 0xdd
-    field public static final int OP_AND_LONG = 160; // 0xa0
-    field public static final int OP_AND_LONG_2ADDR = 192; // 0xc0
-    field public static final int OP_APUT = 75; // 0x4b
-    field public static final int OP_APUT_BOOLEAN = 78; // 0x4e
-    field public static final int OP_APUT_BYTE = 79; // 0x4f
-    field public static final int OP_APUT_CHAR = 80; // 0x50
-    field public static final int OP_APUT_OBJECT = 77; // 0x4d
-    field public static final int OP_APUT_SHORT = 81; // 0x51
-    field public static final int OP_APUT_WIDE = 76; // 0x4c
-    field public static final int OP_ARRAY_LENGTH = 33; // 0x21
-    field @Deprecated public static final int OP_BREAKPOINT = 236; // 0xec
-    field public static final int OP_CHECK_CAST = 31; // 0x1f
-    field public static final int OP_CHECK_CAST_JUMBO = 511; // 0x1ff
-    field public static final int OP_CMPG_DOUBLE = 48; // 0x30
-    field public static final int OP_CMPG_FLOAT = 46; // 0x2e
-    field public static final int OP_CMPL_DOUBLE = 47; // 0x2f
-    field public static final int OP_CMPL_FLOAT = 45; // 0x2d
-    field public static final int OP_CMP_LONG = 49; // 0x31
-    field public static final int OP_CONST = 20; // 0x14
-    field public static final int OP_CONST_16 = 19; // 0x13
-    field public static final int OP_CONST_4 = 18; // 0x12
-    field public static final int OP_CONST_CLASS = 28; // 0x1c
-    field public static final int OP_CONST_CLASS_JUMBO = 255; // 0xff
-    field public static final int OP_CONST_HIGH16 = 21; // 0x15
-    field public static final int OP_CONST_METHOD_HANDLE = 254; // 0xfe
-    field public static final int OP_CONST_METHOD_TYPE = 255; // 0xff
-    field public static final int OP_CONST_STRING = 26; // 0x1a
-    field public static final int OP_CONST_STRING_JUMBO = 27; // 0x1b
-    field public static final int OP_CONST_WIDE = 24; // 0x18
-    field public static final int OP_CONST_WIDE_16 = 22; // 0x16
-    field public static final int OP_CONST_WIDE_32 = 23; // 0x17
-    field public static final int OP_CONST_WIDE_HIGH16 = 25; // 0x19
-    field public static final int OP_DIV_DOUBLE = 174; // 0xae
-    field public static final int OP_DIV_DOUBLE_2ADDR = 206; // 0xce
-    field public static final int OP_DIV_FLOAT = 169; // 0xa9
-    field public static final int OP_DIV_FLOAT_2ADDR = 201; // 0xc9
-    field public static final int OP_DIV_INT = 147; // 0x93
-    field public static final int OP_DIV_INT_2ADDR = 179; // 0xb3
-    field public static final int OP_DIV_INT_LIT16 = 211; // 0xd3
-    field public static final int OP_DIV_INT_LIT8 = 219; // 0xdb
-    field public static final int OP_DIV_LONG = 158; // 0x9e
-    field public static final int OP_DIV_LONG_2ADDR = 190; // 0xbe
-    field public static final int OP_DOUBLE_TO_FLOAT = 140; // 0x8c
-    field public static final int OP_DOUBLE_TO_INT = 138; // 0x8a
-    field public static final int OP_DOUBLE_TO_LONG = 139; // 0x8b
-    field @Deprecated public static final int OP_EXECUTE_INLINE = 238; // 0xee
-    field @Deprecated public static final int OP_EXECUTE_INLINE_RANGE = 239; // 0xef
-    field public static final int OP_FILLED_NEW_ARRAY = 36; // 0x24
-    field public static final int OP_FILLED_NEW_ARRAY_JUMBO = 1535; // 0x5ff
-    field public static final int OP_FILLED_NEW_ARRAY_RANGE = 37; // 0x25
-    field public static final int OP_FILL_ARRAY_DATA = 38; // 0x26
-    field public static final int OP_FLOAT_TO_DOUBLE = 137; // 0x89
-    field public static final int OP_FLOAT_TO_INT = 135; // 0x87
-    field public static final int OP_FLOAT_TO_LONG = 136; // 0x88
-    field public static final int OP_GOTO = 40; // 0x28
-    field public static final int OP_GOTO_16 = 41; // 0x29
-    field public static final int OP_GOTO_32 = 42; // 0x2a
-    field public static final int OP_IF_EQ = 50; // 0x32
-    field public static final int OP_IF_EQZ = 56; // 0x38
-    field public static final int OP_IF_GE = 53; // 0x35
-    field public static final int OP_IF_GEZ = 59; // 0x3b
-    field public static final int OP_IF_GT = 54; // 0x36
-    field public static final int OP_IF_GTZ = 60; // 0x3c
-    field public static final int OP_IF_LE = 55; // 0x37
-    field public static final int OP_IF_LEZ = 61; // 0x3d
-    field public static final int OP_IF_LT = 52; // 0x34
-    field public static final int OP_IF_LTZ = 58; // 0x3a
-    field public static final int OP_IF_NE = 51; // 0x33
-    field public static final int OP_IF_NEZ = 57; // 0x39
-    field public static final int OP_IGET = 82; // 0x52
-    field public static final int OP_IGET_BOOLEAN = 85; // 0x55
-    field public static final int OP_IGET_BOOLEAN_JUMBO = 2559; // 0x9ff
-    field public static final int OP_IGET_BYTE = 86; // 0x56
-    field public static final int OP_IGET_BYTE_JUMBO = 2815; // 0xaff
-    field public static final int OP_IGET_CHAR = 87; // 0x57
-    field public static final int OP_IGET_CHAR_JUMBO = 3071; // 0xbff
-    field public static final int OP_IGET_JUMBO = 1791; // 0x6ff
-    field public static final int OP_IGET_OBJECT = 84; // 0x54
-    field public static final int OP_IGET_OBJECT_JUMBO = 2303; // 0x8ff
-    field @Deprecated public static final int OP_IGET_OBJECT_QUICK = 244; // 0xf4
-    field @Deprecated public static final int OP_IGET_QUICK = 242; // 0xf2
-    field public static final int OP_IGET_SHORT = 88; // 0x58
-    field public static final int OP_IGET_SHORT_JUMBO = 3327; // 0xcff
-    field public static final int OP_IGET_WIDE = 83; // 0x53
-    field public static final int OP_IGET_WIDE_JUMBO = 2047; // 0x7ff
-    field @Deprecated public static final int OP_IGET_WIDE_QUICK = 243; // 0xf3
-    field @Deprecated public static final int OP_IGET_WIDE_VOLATILE = 232; // 0xe8
-    field public static final int OP_INSTANCE_OF = 32; // 0x20
-    field public static final int OP_INSTANCE_OF_JUMBO = 767; // 0x2ff
-    field public static final int OP_INT_TO_BYTE = 141; // 0x8d
-    field public static final int OP_INT_TO_CHAR = 142; // 0x8e
-    field public static final int OP_INT_TO_DOUBLE = 131; // 0x83
-    field public static final int OP_INT_TO_FLOAT = 130; // 0x82
-    field public static final int OP_INT_TO_LONG = 129; // 0x81
-    field public static final int OP_INT_TO_SHORT = 143; // 0x8f
-    field public static final int OP_INVOKE_CUSTOM = 252; // 0xfc
-    field public static final int OP_INVOKE_CUSTOM_RANGE = 253; // 0xfd
-    field public static final int OP_INVOKE_DIRECT = 112; // 0x70
-    field @Deprecated public static final int OP_INVOKE_DIRECT_EMPTY = 240; // 0xf0
-    field public static final int OP_INVOKE_DIRECT_JUMBO = 9471; // 0x24ff
-    field public static final int OP_INVOKE_DIRECT_RANGE = 118; // 0x76
-    field public static final int OP_INVOKE_INTERFACE = 114; // 0x72
-    field public static final int OP_INVOKE_INTERFACE_JUMBO = 9983; // 0x26ff
-    field public static final int OP_INVOKE_INTERFACE_RANGE = 120; // 0x78
-    field public static final int OP_INVOKE_POLYMORPHIC = 250; // 0xfa
-    field public static final int OP_INVOKE_POLYMORPHIC_RANGE = 251; // 0xfb
-    field public static final int OP_INVOKE_STATIC = 113; // 0x71
-    field public static final int OP_INVOKE_STATIC_JUMBO = 9727; // 0x25ff
-    field public static final int OP_INVOKE_STATIC_RANGE = 119; // 0x77
-    field public static final int OP_INVOKE_SUPER = 111; // 0x6f
-    field public static final int OP_INVOKE_SUPER_JUMBO = 9215; // 0x23ff
-    field @Deprecated public static final int OP_INVOKE_SUPER_QUICK = 250; // 0xfa
-    field @Deprecated public static final int OP_INVOKE_SUPER_QUICK_RANGE = 251; // 0xfb
-    field public static final int OP_INVOKE_SUPER_RANGE = 117; // 0x75
-    field public static final int OP_INVOKE_VIRTUAL = 110; // 0x6e
-    field public static final int OP_INVOKE_VIRTUAL_JUMBO = 8959; // 0x22ff
-    field @Deprecated public static final int OP_INVOKE_VIRTUAL_QUICK = 248; // 0xf8
-    field @Deprecated public static final int OP_INVOKE_VIRTUAL_QUICK_RANGE = 249; // 0xf9
-    field public static final int OP_INVOKE_VIRTUAL_RANGE = 116; // 0x74
-    field public static final int OP_IPUT = 89; // 0x59
-    field public static final int OP_IPUT_BOOLEAN = 92; // 0x5c
-    field public static final int OP_IPUT_BOOLEAN_JUMBO = 4351; // 0x10ff
-    field public static final int OP_IPUT_BYTE = 93; // 0x5d
-    field public static final int OP_IPUT_BYTE_JUMBO = 4607; // 0x11ff
-    field public static final int OP_IPUT_CHAR = 94; // 0x5e
-    field public static final int OP_IPUT_CHAR_JUMBO = 4863; // 0x12ff
-    field public static final int OP_IPUT_JUMBO = 3583; // 0xdff
-    field public static final int OP_IPUT_OBJECT = 91; // 0x5b
-    field public static final int OP_IPUT_OBJECT_JUMBO = 4095; // 0xfff
-    field @Deprecated public static final int OP_IPUT_OBJECT_QUICK = 247; // 0xf7
-    field @Deprecated public static final int OP_IPUT_QUICK = 245; // 0xf5
-    field public static final int OP_IPUT_SHORT = 95; // 0x5f
-    field public static final int OP_IPUT_SHORT_JUMBO = 5119; // 0x13ff
-    field public static final int OP_IPUT_WIDE = 90; // 0x5a
-    field public static final int OP_IPUT_WIDE_JUMBO = 3839; // 0xeff
-    field @Deprecated public static final int OP_IPUT_WIDE_QUICK = 246; // 0xf6
-    field @Deprecated public static final int OP_IPUT_WIDE_VOLATILE = 233; // 0xe9
-    field public static final int OP_LONG_TO_DOUBLE = 134; // 0x86
-    field public static final int OP_LONG_TO_FLOAT = 133; // 0x85
-    field public static final int OP_LONG_TO_INT = 132; // 0x84
-    field public static final int OP_MONITOR_ENTER = 29; // 0x1d
-    field public static final int OP_MONITOR_EXIT = 30; // 0x1e
-    field public static final int OP_MOVE = 1; // 0x1
-    field public static final int OP_MOVE_16 = 3; // 0x3
-    field public static final int OP_MOVE_EXCEPTION = 13; // 0xd
-    field public static final int OP_MOVE_FROM16 = 2; // 0x2
-    field public static final int OP_MOVE_OBJECT = 7; // 0x7
-    field public static final int OP_MOVE_OBJECT_16 = 9; // 0x9
-    field public static final int OP_MOVE_OBJECT_FROM16 = 8; // 0x8
-    field public static final int OP_MOVE_RESULT = 10; // 0xa
-    field public static final int OP_MOVE_RESULT_OBJECT = 12; // 0xc
-    field public static final int OP_MOVE_RESULT_WIDE = 11; // 0xb
-    field public static final int OP_MOVE_WIDE = 4; // 0x4
-    field public static final int OP_MOVE_WIDE_16 = 6; // 0x6
-    field public static final int OP_MOVE_WIDE_FROM16 = 5; // 0x5
-    field public static final int OP_MUL_DOUBLE = 173; // 0xad
-    field public static final int OP_MUL_DOUBLE_2ADDR = 205; // 0xcd
-    field public static final int OP_MUL_FLOAT = 168; // 0xa8
-    field public static final int OP_MUL_FLOAT_2ADDR = 200; // 0xc8
-    field public static final int OP_MUL_INT = 146; // 0x92
-    field public static final int OP_MUL_INT_2ADDR = 178; // 0xb2
-    field public static final int OP_MUL_INT_LIT16 = 210; // 0xd2
-    field public static final int OP_MUL_INT_LIT8 = 218; // 0xda
-    field public static final int OP_MUL_LONG = 157; // 0x9d
-    field public static final int OP_MUL_LONG_2ADDR = 189; // 0xbd
-    field public static final int OP_NEG_DOUBLE = 128; // 0x80
-    field public static final int OP_NEG_FLOAT = 127; // 0x7f
-    field public static final int OP_NEG_INT = 123; // 0x7b
-    field public static final int OP_NEG_LONG = 125; // 0x7d
-    field public static final int OP_NEW_ARRAY = 35; // 0x23
-    field public static final int OP_NEW_ARRAY_JUMBO = 1279; // 0x4ff
-    field public static final int OP_NEW_INSTANCE = 34; // 0x22
-    field public static final int OP_NEW_INSTANCE_JUMBO = 1023; // 0x3ff
-    field public static final int OP_NOP = 0; // 0x0
-    field public static final int OP_NOT_INT = 124; // 0x7c
-    field public static final int OP_NOT_LONG = 126; // 0x7e
-    field public static final int OP_OR_INT = 150; // 0x96
-    field public static final int OP_OR_INT_2ADDR = 182; // 0xb6
-    field public static final int OP_OR_INT_LIT16 = 214; // 0xd6
-    field public static final int OP_OR_INT_LIT8 = 222; // 0xde
-    field public static final int OP_OR_LONG = 161; // 0xa1
-    field public static final int OP_OR_LONG_2ADDR = 193; // 0xc1
-    field public static final int OP_PACKED_SWITCH = 43; // 0x2b
-    field public static final int OP_REM_DOUBLE = 175; // 0xaf
-    field public static final int OP_REM_DOUBLE_2ADDR = 207; // 0xcf
-    field public static final int OP_REM_FLOAT = 170; // 0xaa
-    field public static final int OP_REM_FLOAT_2ADDR = 202; // 0xca
-    field public static final int OP_REM_INT = 148; // 0x94
-    field public static final int OP_REM_INT_2ADDR = 180; // 0xb4
-    field public static final int OP_REM_INT_LIT16 = 212; // 0xd4
-    field public static final int OP_REM_INT_LIT8 = 220; // 0xdc
-    field public static final int OP_REM_LONG = 159; // 0x9f
-    field public static final int OP_REM_LONG_2ADDR = 191; // 0xbf
-    field public static final int OP_RETURN = 15; // 0xf
-    field public static final int OP_RETURN_OBJECT = 17; // 0x11
-    field public static final int OP_RETURN_VOID = 14; // 0xe
-    field public static final int OP_RETURN_WIDE = 16; // 0x10
-    field public static final int OP_RSUB_INT = 209; // 0xd1
-    field public static final int OP_RSUB_INT_LIT8 = 217; // 0xd9
-    field public static final int OP_SGET = 96; // 0x60
-    field public static final int OP_SGET_BOOLEAN = 99; // 0x63
-    field public static final int OP_SGET_BOOLEAN_JUMBO = 6143; // 0x17ff
-    field public static final int OP_SGET_BYTE = 100; // 0x64
-    field public static final int OP_SGET_BYTE_JUMBO = 6399; // 0x18ff
-    field public static final int OP_SGET_CHAR = 101; // 0x65
-    field public static final int OP_SGET_CHAR_JUMBO = 6655; // 0x19ff
-    field public static final int OP_SGET_JUMBO = 5375; // 0x14ff
-    field public static final int OP_SGET_OBJECT = 98; // 0x62
-    field public static final int OP_SGET_OBJECT_JUMBO = 5887; // 0x16ff
-    field public static final int OP_SGET_SHORT = 102; // 0x66
-    field public static final int OP_SGET_SHORT_JUMBO = 6911; // 0x1aff
-    field public static final int OP_SGET_WIDE = 97; // 0x61
-    field public static final int OP_SGET_WIDE_JUMBO = 5631; // 0x15ff
-    field @Deprecated public static final int OP_SGET_WIDE_VOLATILE = 234; // 0xea
-    field public static final int OP_SHL_INT = 152; // 0x98
-    field public static final int OP_SHL_INT_2ADDR = 184; // 0xb8
-    field public static final int OP_SHL_INT_LIT8 = 224; // 0xe0
-    field public static final int OP_SHL_LONG = 163; // 0xa3
-    field public static final int OP_SHL_LONG_2ADDR = 195; // 0xc3
-    field public static final int OP_SHR_INT = 153; // 0x99
-    field public static final int OP_SHR_INT_2ADDR = 185; // 0xb9
-    field public static final int OP_SHR_INT_LIT8 = 225; // 0xe1
-    field public static final int OP_SHR_LONG = 164; // 0xa4
-    field public static final int OP_SHR_LONG_2ADDR = 196; // 0xc4
-    field public static final int OP_SPARSE_SWITCH = 44; // 0x2c
-    field public static final int OP_SPUT = 103; // 0x67
-    field public static final int OP_SPUT_BOOLEAN = 106; // 0x6a
-    field public static final int OP_SPUT_BOOLEAN_JUMBO = 7935; // 0x1eff
-    field public static final int OP_SPUT_BYTE = 107; // 0x6b
-    field public static final int OP_SPUT_BYTE_JUMBO = 8191; // 0x1fff
-    field public static final int OP_SPUT_CHAR = 108; // 0x6c
-    field public static final int OP_SPUT_CHAR_JUMBO = 8447; // 0x20ff
-    field public static final int OP_SPUT_JUMBO = 7167; // 0x1bff
-    field public static final int OP_SPUT_OBJECT = 105; // 0x69
-    field public static final int OP_SPUT_OBJECT_JUMBO = 7679; // 0x1dff
-    field public static final int OP_SPUT_SHORT = 109; // 0x6d
-    field public static final int OP_SPUT_SHORT_JUMBO = 8703; // 0x21ff
-    field public static final int OP_SPUT_WIDE = 104; // 0x68
-    field public static final int OP_SPUT_WIDE_JUMBO = 7423; // 0x1cff
-    field @Deprecated public static final int OP_SPUT_WIDE_VOLATILE = 235; // 0xeb
-    field public static final int OP_SUB_DOUBLE = 172; // 0xac
-    field public static final int OP_SUB_DOUBLE_2ADDR = 204; // 0xcc
-    field public static final int OP_SUB_FLOAT = 167; // 0xa7
-    field public static final int OP_SUB_FLOAT_2ADDR = 199; // 0xc7
-    field public static final int OP_SUB_INT = 145; // 0x91
-    field public static final int OP_SUB_INT_2ADDR = 177; // 0xb1
-    field public static final int OP_SUB_LONG = 156; // 0x9c
-    field public static final int OP_SUB_LONG_2ADDR = 188; // 0xbc
-    field public static final int OP_THROW = 39; // 0x27
-    field @Deprecated public static final int OP_THROW_VERIFICATION_ERROR = 237; // 0xed
-    field public static final int OP_USHR_INT = 154; // 0x9a
-    field public static final int OP_USHR_INT_2ADDR = 186; // 0xba
-    field public static final int OP_USHR_INT_LIT8 = 226; // 0xe2
-    field public static final int OP_USHR_LONG = 165; // 0xa5
-    field public static final int OP_USHR_LONG_2ADDR = 197; // 0xc5
-    field public static final int OP_XOR_INT = 151; // 0x97
-    field public static final int OP_XOR_INT_2ADDR = 183; // 0xb7
-    field public static final int OP_XOR_INT_LIT16 = 215; // 0xd7
-    field public static final int OP_XOR_INT_LIT8 = 223; // 0xdf
-    field public static final int OP_XOR_LONG = 162; // 0xa2
-    field public static final int OP_XOR_LONG_2ADDR = 194; // 0xc2
-  }
-
-}
-
-package dalvik.system {
-
-  public class BaseDexClassLoader extends java.lang.ClassLoader {
-    ctor public BaseDexClassLoader(String, java.io.File, String, ClassLoader);
-    method public String findLibrary(String);
-    method protected java.util.Enumeration<java.net.URL> findResources(String);
-  }
-
-  public final class DelegateLastClassLoader extends dalvik.system.PathClassLoader {
-    ctor public DelegateLastClassLoader(String, ClassLoader);
-    ctor public DelegateLastClassLoader(String, String, ClassLoader);
-    ctor public DelegateLastClassLoader(@NonNull String, @Nullable String, @Nullable ClassLoader, boolean);
-  }
-
-  public class DexClassLoader extends dalvik.system.BaseDexClassLoader {
-    ctor public DexClassLoader(String, String, String, ClassLoader);
-  }
-
-  @Deprecated public final class DexFile {
-    ctor @Deprecated public DexFile(java.io.File) throws java.io.IOException;
-    ctor @Deprecated public DexFile(String) throws java.io.IOException;
-    method @Deprecated public void close() throws java.io.IOException;
-    method @Deprecated public java.util.Enumeration<java.lang.String> entries();
-    method @Deprecated public String getName();
-    method @Deprecated public static boolean isDexOptNeeded(String) throws java.io.FileNotFoundException, java.io.IOException;
-    method @Deprecated public Class loadClass(String, ClassLoader);
-    method @Deprecated public static dalvik.system.DexFile loadDex(String, String, int) throws java.io.IOException;
-  }
-
-  public final class InMemoryDexClassLoader extends dalvik.system.BaseDexClassLoader {
-    ctor public InMemoryDexClassLoader(@NonNull java.nio.ByteBuffer[], @Nullable String, @Nullable ClassLoader);
-    ctor public InMemoryDexClassLoader(@NonNull java.nio.ByteBuffer[], @Nullable ClassLoader);
-    ctor public InMemoryDexClassLoader(@NonNull java.nio.ByteBuffer, @Nullable ClassLoader);
-  }
-
-  public class PathClassLoader extends dalvik.system.BaseDexClassLoader {
-    ctor public PathClassLoader(String, ClassLoader);
-    ctor public PathClassLoader(String, String, ClassLoader);
-  }
-
-}
-
-package java.awt.font {
-
-  public final class NumericShaper implements java.io.Serializable {
-    method public static java.awt.font.NumericShaper getContextualShaper(int);
-    method public static java.awt.font.NumericShaper getContextualShaper(java.util.Set<java.awt.font.NumericShaper.Range>);
-    method public static java.awt.font.NumericShaper getContextualShaper(int, int);
-    method public static java.awt.font.NumericShaper getContextualShaper(java.util.Set<java.awt.font.NumericShaper.Range>, java.awt.font.NumericShaper.Range);
-    method public java.util.Set<java.awt.font.NumericShaper.Range> getRangeSet();
-    method public int getRanges();
-    method public static java.awt.font.NumericShaper getShaper(int);
-    method public static java.awt.font.NumericShaper getShaper(java.awt.font.NumericShaper.Range);
-    method public boolean isContextual();
-    method public void shape(char[], int, int);
-    method public void shape(char[], int, int, int);
-    method public void shape(char[], int, int, java.awt.font.NumericShaper.Range);
-    field public static final int ALL_RANGES = 524287; // 0x7ffff
-    field public static final int ARABIC = 2; // 0x2
-    field public static final int BENGALI = 16; // 0x10
-    field public static final int DEVANAGARI = 8; // 0x8
-    field public static final int EASTERN_ARABIC = 4; // 0x4
-    field public static final int ETHIOPIC = 65536; // 0x10000
-    field public static final int EUROPEAN = 1; // 0x1
-    field public static final int GUJARATI = 64; // 0x40
-    field public static final int GURMUKHI = 32; // 0x20
-    field public static final int KANNADA = 1024; // 0x400
-    field public static final int KHMER = 131072; // 0x20000
-    field public static final int LAO = 8192; // 0x2000
-    field public static final int MALAYALAM = 2048; // 0x800
-    field public static final int MONGOLIAN = 262144; // 0x40000
-    field public static final int MYANMAR = 32768; // 0x8000
-    field public static final int ORIYA = 128; // 0x80
-    field public static final int TAMIL = 256; // 0x100
-    field public static final int TELUGU = 512; // 0x200
-    field public static final int THAI = 4096; // 0x1000
-    field public static final int TIBETAN = 16384; // 0x4000
-  }
-
-  public enum NumericShaper.Range {
-    enum_constant public static final java.awt.font.NumericShaper.Range ARABIC;
-    enum_constant public static final java.awt.font.NumericShaper.Range BALINESE;
-    enum_constant public static final java.awt.font.NumericShaper.Range BENGALI;
-    enum_constant public static final java.awt.font.NumericShaper.Range CHAM;
-    enum_constant public static final java.awt.font.NumericShaper.Range DEVANAGARI;
-    enum_constant public static final java.awt.font.NumericShaper.Range EASTERN_ARABIC;
-    enum_constant public static final java.awt.font.NumericShaper.Range ETHIOPIC;
-    enum_constant public static final java.awt.font.NumericShaper.Range EUROPEAN;
-    enum_constant public static final java.awt.font.NumericShaper.Range GUJARATI;
-    enum_constant public static final java.awt.font.NumericShaper.Range GURMUKHI;
-    enum_constant public static final java.awt.font.NumericShaper.Range JAVANESE;
-    enum_constant public static final java.awt.font.NumericShaper.Range KANNADA;
-    enum_constant public static final java.awt.font.NumericShaper.Range KAYAH_LI;
-    enum_constant public static final java.awt.font.NumericShaper.Range KHMER;
-    enum_constant public static final java.awt.font.NumericShaper.Range LAO;
-    enum_constant public static final java.awt.font.NumericShaper.Range LEPCHA;
-    enum_constant public static final java.awt.font.NumericShaper.Range LIMBU;
-    enum_constant public static final java.awt.font.NumericShaper.Range MALAYALAM;
-    enum_constant public static final java.awt.font.NumericShaper.Range MEETEI_MAYEK;
-    enum_constant public static final java.awt.font.NumericShaper.Range MONGOLIAN;
-    enum_constant public static final java.awt.font.NumericShaper.Range MYANMAR;
-    enum_constant public static final java.awt.font.NumericShaper.Range MYANMAR_SHAN;
-    enum_constant public static final java.awt.font.NumericShaper.Range NEW_TAI_LUE;
-    enum_constant public static final java.awt.font.NumericShaper.Range NKO;
-    enum_constant public static final java.awt.font.NumericShaper.Range OL_CHIKI;
-    enum_constant public static final java.awt.font.NumericShaper.Range ORIYA;
-    enum_constant public static final java.awt.font.NumericShaper.Range SAURASHTRA;
-    enum_constant public static final java.awt.font.NumericShaper.Range SUNDANESE;
-    enum_constant public static final java.awt.font.NumericShaper.Range TAI_THAM_HORA;
-    enum_constant public static final java.awt.font.NumericShaper.Range TAI_THAM_THAM;
-    enum_constant public static final java.awt.font.NumericShaper.Range TAMIL;
-    enum_constant public static final java.awt.font.NumericShaper.Range TELUGU;
-    enum_constant public static final java.awt.font.NumericShaper.Range THAI;
-    enum_constant public static final java.awt.font.NumericShaper.Range TIBETAN;
-    enum_constant public static final java.awt.font.NumericShaper.Range VAI;
-  }
-
-  public final class TextAttribute extends java.text.AttributedCharacterIterator.Attribute {
-    ctor protected TextAttribute(String);
-    field public static final java.awt.font.TextAttribute BACKGROUND;
-    field public static final java.awt.font.TextAttribute BIDI_EMBEDDING;
-    field public static final java.awt.font.TextAttribute CHAR_REPLACEMENT;
-    field public static final java.awt.font.TextAttribute FAMILY;
-    field public static final java.awt.font.TextAttribute FONT;
-    field public static final java.awt.font.TextAttribute FOREGROUND;
-    field public static final java.awt.font.TextAttribute INPUT_METHOD_HIGHLIGHT;
-    field public static final java.awt.font.TextAttribute INPUT_METHOD_UNDERLINE;
-    field public static final java.awt.font.TextAttribute JUSTIFICATION;
-    field public static final Float JUSTIFICATION_FULL;
-    field public static final Float JUSTIFICATION_NONE;
-    field public static final java.awt.font.TextAttribute KERNING;
-    field public static final Integer KERNING_ON;
-    field public static final java.awt.font.TextAttribute LIGATURES;
-    field public static final Integer LIGATURES_ON;
-    field public static final java.awt.font.TextAttribute NUMERIC_SHAPING;
-    field public static final java.awt.font.TextAttribute POSTURE;
-    field public static final Float POSTURE_OBLIQUE;
-    field public static final Float POSTURE_REGULAR;
-    field public static final java.awt.font.TextAttribute RUN_DIRECTION;
-    field public static final Boolean RUN_DIRECTION_LTR;
-    field public static final Boolean RUN_DIRECTION_RTL;
-    field public static final java.awt.font.TextAttribute SIZE;
-    field public static final java.awt.font.TextAttribute STRIKETHROUGH;
-    field public static final Boolean STRIKETHROUGH_ON;
-    field public static final java.awt.font.TextAttribute SUPERSCRIPT;
-    field public static final Integer SUPERSCRIPT_SUB;
-    field public static final Integer SUPERSCRIPT_SUPER;
-    field public static final java.awt.font.TextAttribute SWAP_COLORS;
-    field public static final Boolean SWAP_COLORS_ON;
-    field public static final java.awt.font.TextAttribute TRACKING;
-    field public static final Float TRACKING_LOOSE;
-    field public static final Float TRACKING_TIGHT;
-    field public static final java.awt.font.TextAttribute TRANSFORM;
-    field public static final java.awt.font.TextAttribute UNDERLINE;
-    field public static final Integer UNDERLINE_LOW_DASHED;
-    field public static final Integer UNDERLINE_LOW_DOTTED;
-    field public static final Integer UNDERLINE_LOW_GRAY;
-    field public static final Integer UNDERLINE_LOW_ONE_PIXEL;
-    field public static final Integer UNDERLINE_LOW_TWO_PIXEL;
-    field public static final Integer UNDERLINE_ON;
-    field public static final java.awt.font.TextAttribute WEIGHT;
-    field public static final Float WEIGHT_BOLD;
-    field public static final Float WEIGHT_DEMIBOLD;
-    field public static final Float WEIGHT_DEMILIGHT;
-    field public static final Float WEIGHT_EXTRABOLD;
-    field public static final Float WEIGHT_EXTRA_LIGHT;
-    field public static final Float WEIGHT_HEAVY;
-    field public static final Float WEIGHT_LIGHT;
-    field public static final Float WEIGHT_MEDIUM;
-    field public static final Float WEIGHT_REGULAR;
-    field public static final Float WEIGHT_SEMIBOLD;
-    field public static final Float WEIGHT_ULTRABOLD;
-    field public static final java.awt.font.TextAttribute WIDTH;
-    field public static final Float WIDTH_CONDENSED;
-    field public static final Float WIDTH_EXTENDED;
-    field public static final Float WIDTH_REGULAR;
-    field public static final Float WIDTH_SEMI_CONDENSED;
-    field public static final Float WIDTH_SEMI_EXTENDED;
-  }
-
-}
-
-package java.beans {
-
-  public class IndexedPropertyChangeEvent extends java.beans.PropertyChangeEvent {
-    ctor public IndexedPropertyChangeEvent(Object, String, Object, Object, int);
-    method public int getIndex();
-  }
-
-  public class PropertyChangeEvent extends java.util.EventObject {
-    ctor public PropertyChangeEvent(Object, String, Object, Object);
-    method public Object getNewValue();
-    method public Object getOldValue();
-    method public Object getPropagationId();
-    method public String getPropertyName();
-    method public void setPropagationId(Object);
-  }
-
-  public interface PropertyChangeListener extends java.util.EventListener {
-    method public void propertyChange(java.beans.PropertyChangeEvent);
-  }
-
-  public class PropertyChangeListenerProxy extends java.util.EventListenerProxy<java.beans.PropertyChangeListener> implements java.beans.PropertyChangeListener {
-    ctor public PropertyChangeListenerProxy(String, java.beans.PropertyChangeListener);
-    method public String getPropertyName();
-    method public void propertyChange(java.beans.PropertyChangeEvent);
-  }
-
-  public class PropertyChangeSupport implements java.io.Serializable {
-    ctor public PropertyChangeSupport(Object);
-    method public void addPropertyChangeListener(java.beans.PropertyChangeListener);
-    method public void addPropertyChangeListener(String, java.beans.PropertyChangeListener);
-    method public void fireIndexedPropertyChange(String, int, Object, Object);
-    method public void fireIndexedPropertyChange(String, int, int, int);
-    method public void fireIndexedPropertyChange(String, int, boolean, boolean);
-    method public void firePropertyChange(String, Object, Object);
-    method public void firePropertyChange(String, int, int);
-    method public void firePropertyChange(String, boolean, boolean);
-    method public void firePropertyChange(java.beans.PropertyChangeEvent);
-    method public java.beans.PropertyChangeListener[] getPropertyChangeListeners();
-    method public java.beans.PropertyChangeListener[] getPropertyChangeListeners(String);
-    method public boolean hasListeners(String);
-    method public void removePropertyChangeListener(java.beans.PropertyChangeListener);
-    method public void removePropertyChangeListener(String, java.beans.PropertyChangeListener);
-  }
-
-}
-
-package java.io {
-
-  public class BufferedInputStream extends java.io.FilterInputStream {
-    ctor public BufferedInputStream(java.io.InputStream);
-    ctor public BufferedInputStream(java.io.InputStream, int);
-    field protected volatile byte[] buf;
-    field protected int count;
-    field protected int marklimit;
-    field protected int markpos;
-    field protected int pos;
-  }
-
-  public class BufferedOutputStream extends java.io.FilterOutputStream {
-    ctor public BufferedOutputStream(java.io.OutputStream);
-    ctor public BufferedOutputStream(java.io.OutputStream, int);
-    field protected byte[] buf;
-    field protected int count;
-  }
-
-  public class BufferedReader extends java.io.Reader {
-    ctor public BufferedReader(java.io.Reader, int);
-    ctor public BufferedReader(java.io.Reader);
-    method public void close() throws java.io.IOException;
-    method public java.util.stream.Stream<java.lang.String> lines();
-    method public int read(char[], int, int) throws java.io.IOException;
-    method public String readLine() throws java.io.IOException;
-  }
-
-  public class BufferedWriter extends java.io.Writer {
-    ctor public BufferedWriter(java.io.Writer);
-    ctor public BufferedWriter(java.io.Writer, int);
-    method public void close() throws java.io.IOException;
-    method public void flush() throws java.io.IOException;
-    method public void newLine() throws java.io.IOException;
-    method public void write(char[], int, int) throws java.io.IOException;
-  }
-
-  public class ByteArrayInputStream extends java.io.InputStream {
-    ctor public ByteArrayInputStream(byte[]);
-    ctor public ByteArrayInputStream(byte[], int, int);
-    method public int available();
-    method public int read();
-    method public int read(byte[], int, int);
-    method public void reset();
-    method public long skip(long);
-    field protected byte[] buf;
-    field protected int count;
-    field protected int mark;
-    field protected int pos;
-  }
-
-  public class ByteArrayOutputStream extends java.io.OutputStream {
-    ctor public ByteArrayOutputStream();
-    ctor public ByteArrayOutputStream(int);
-    method public void reset();
-    method public int size();
-    method @NonNull public byte[] toByteArray();
-    method @NonNull public String toString(@NonNull String) throws java.io.UnsupportedEncodingException;
-    method @Deprecated @NonNull public String toString(int);
-    method public void write(int);
-    method public void write(@NonNull byte[], int, int);
-    method public void writeTo(@NonNull java.io.OutputStream) throws java.io.IOException;
-    field @NonNull protected byte[] buf;
-    field protected int count;
-  }
-
-  public class CharArrayReader extends java.io.Reader {
-    ctor public CharArrayReader(char[]);
-    ctor public CharArrayReader(char[], int, int);
-    method public void close();
-    method public int read(char[], int, int) throws java.io.IOException;
-    field protected char[] buf;
-    field protected int count;
-    field protected int markedPos;
-    field protected int pos;
-  }
-
-  public class CharArrayWriter extends java.io.Writer {
-    ctor public CharArrayWriter();
-    ctor public CharArrayWriter(int);
-    method public java.io.CharArrayWriter append(CharSequence);
-    method public java.io.CharArrayWriter append(CharSequence, int, int);
-    method public java.io.CharArrayWriter append(char);
-    method public void close();
-    method public void flush();
-    method public void reset();
-    method public int size();
-    method public char[] toCharArray();
-    method public void write(int);
-    method public void write(char[], int, int);
-    method public void write(String, int, int);
-    method public void writeTo(java.io.Writer) throws java.io.IOException;
-    field protected char[] buf;
-    field protected int count;
-  }
-
-  public class CharConversionException extends java.io.IOException {
-    ctor public CharConversionException();
-    ctor public CharConversionException(String);
-  }
-
-  public interface Closeable extends java.lang.AutoCloseable {
-    method public void close() throws java.io.IOException;
-  }
-
-  public final class Console implements java.io.Flushable {
-    method public void flush();
-    method public java.io.Console format(String, java.lang.Object...);
-    method public java.io.Console printf(String, java.lang.Object...);
-    method public String readLine(String, java.lang.Object...);
-    method public String readLine();
-    method public char[] readPassword(String, java.lang.Object...);
-    method public char[] readPassword();
-    method public java.io.Reader reader();
-    method public java.io.PrintWriter writer();
-  }
-
-  public interface DataInput {
-    method public boolean readBoolean() throws java.io.IOException;
-    method public byte readByte() throws java.io.IOException;
-    method public char readChar() throws java.io.IOException;
-    method public double readDouble() throws java.io.IOException;
-    method public float readFloat() throws java.io.IOException;
-    method public void readFully(byte[]) throws java.io.IOException;
-    method public void readFully(byte[], int, int) throws java.io.IOException;
-    method public int readInt() throws java.io.IOException;
-    method public String readLine() throws java.io.IOException;
-    method public long readLong() throws java.io.IOException;
-    method public short readShort() throws java.io.IOException;
-    method public String readUTF() throws java.io.IOException;
-    method public int readUnsignedByte() throws java.io.IOException;
-    method public int readUnsignedShort() throws java.io.IOException;
-    method public int skipBytes(int) throws java.io.IOException;
-  }
-
-  public class DataInputStream extends java.io.FilterInputStream implements java.io.DataInput {
-    ctor public DataInputStream(java.io.InputStream);
-    method public final int read(byte[]) throws java.io.IOException;
-    method public final int read(byte[], int, int) throws java.io.IOException;
-    method public final boolean readBoolean() throws java.io.IOException;
-    method public final byte readByte() throws java.io.IOException;
-    method public final char readChar() throws java.io.IOException;
-    method public final double readDouble() throws java.io.IOException;
-    method public final float readFloat() throws java.io.IOException;
-    method public final void readFully(byte[]) throws java.io.IOException;
-    method public final void readFully(byte[], int, int) throws java.io.IOException;
-    method public final int readInt() throws java.io.IOException;
-    method @Deprecated public final String readLine() throws java.io.IOException;
-    method public final long readLong() throws java.io.IOException;
-    method public final short readShort() throws java.io.IOException;
-    method public final String readUTF() throws java.io.IOException;
-    method public static final String readUTF(java.io.DataInput) throws java.io.IOException;
-    method public final int readUnsignedByte() throws java.io.IOException;
-    method public final int readUnsignedShort() throws java.io.IOException;
-    method public final int skipBytes(int) throws java.io.IOException;
-  }
-
-  public interface DataOutput {
-    method public void write(int) throws java.io.IOException;
-    method public void write(byte[]) throws java.io.IOException;
-    method public void write(byte[], int, int) throws java.io.IOException;
-    method public void writeBoolean(boolean) throws java.io.IOException;
-    method public void writeByte(int) throws java.io.IOException;
-    method public void writeBytes(String) throws java.io.IOException;
-    method public void writeChar(int) throws java.io.IOException;
-    method public void writeChars(String) throws java.io.IOException;
-    method public void writeDouble(double) throws java.io.IOException;
-    method public void writeFloat(float) throws java.io.IOException;
-    method public void writeInt(int) throws java.io.IOException;
-    method public void writeLong(long) throws java.io.IOException;
-    method public void writeShort(int) throws java.io.IOException;
-    method public void writeUTF(String) throws java.io.IOException;
-  }
-
-  public class DataOutputStream extends java.io.FilterOutputStream implements java.io.DataOutput {
-    ctor public DataOutputStream(java.io.OutputStream);
-    method public final int size();
-    method public final void writeBoolean(boolean) throws java.io.IOException;
-    method public final void writeByte(int) throws java.io.IOException;
-    method public final void writeBytes(String) throws java.io.IOException;
-    method public final void writeChar(int) throws java.io.IOException;
-    method public final void writeChars(String) throws java.io.IOException;
-    method public final void writeDouble(double) throws java.io.IOException;
-    method public final void writeFloat(float) throws java.io.IOException;
-    method public final void writeInt(int) throws java.io.IOException;
-    method public final void writeLong(long) throws java.io.IOException;
-    method public final void writeShort(int) throws java.io.IOException;
-    method public final void writeUTF(String) throws java.io.IOException;
-    field protected int written;
-  }
-
-  public class EOFException extends java.io.IOException {
-    ctor public EOFException();
-    ctor public EOFException(String);
-  }
-
-  public interface Externalizable extends java.io.Serializable {
-    method public void readExternal(java.io.ObjectInput) throws java.lang.ClassNotFoundException, java.io.IOException;
-    method public void writeExternal(java.io.ObjectOutput) throws java.io.IOException;
-  }
-
-  public class File implements java.lang.Comparable<java.io.File> java.io.Serializable {
-    ctor public File(@NonNull String);
-    ctor public File(@Nullable String, @NonNull String);
-    ctor public File(@Nullable java.io.File, @NonNull String);
-    ctor public File(@NonNull java.net.URI);
-    method public boolean canExecute();
-    method public boolean canRead();
-    method public boolean canWrite();
-    method public int compareTo(@NonNull java.io.File);
-    method public boolean createNewFile() throws java.io.IOException;
-    method @NonNull public static java.io.File createTempFile(@NonNull String, @Nullable String, @Nullable java.io.File) throws java.io.IOException;
-    method @NonNull public static java.io.File createTempFile(@NonNull String, @Nullable String) throws java.io.IOException;
-    method public boolean delete();
-    method public void deleteOnExit();
-    method public boolean exists();
-    method @NonNull public java.io.File getAbsoluteFile();
-    method @NonNull public String getAbsolutePath();
-    method @NonNull public java.io.File getCanonicalFile() throws java.io.IOException;
-    method @NonNull public String getCanonicalPath() throws java.io.IOException;
-    method public long getFreeSpace();
-    method @NonNull public String getName();
-    method @Nullable public String getParent();
-    method @Nullable public java.io.File getParentFile();
-    method @NonNull public String getPath();
-    method public long getTotalSpace();
-    method public long getUsableSpace();
-    method public boolean isAbsolute();
-    method public boolean isDirectory();
-    method public boolean isFile();
-    method public boolean isHidden();
-    method public long lastModified();
-    method public long length();
-    method @Nullable public String[] list();
-    method @Nullable public String[] list(@Nullable java.io.FilenameFilter);
-    method @Nullable public java.io.File[] listFiles();
-    method @Nullable public java.io.File[] listFiles(@Nullable java.io.FilenameFilter);
-    method @Nullable public java.io.File[] listFiles(@Nullable java.io.FileFilter);
-    method @NonNull public static java.io.File[] listRoots();
-    method public boolean mkdir();
-    method public boolean mkdirs();
-    method public boolean renameTo(@NonNull java.io.File);
-    method public boolean setExecutable(boolean, boolean);
-    method public boolean setExecutable(boolean);
-    method public boolean setLastModified(long);
-    method public boolean setReadOnly();
-    method public boolean setReadable(boolean, boolean);
-    method public boolean setReadable(boolean);
-    method public boolean setWritable(boolean, boolean);
-    method public boolean setWritable(boolean);
-    method @NonNull public java.nio.file.Path toPath();
-    method @NonNull public java.net.URI toURI();
-    method @Deprecated @NonNull public java.net.URL toURL() throws java.net.MalformedURLException;
-    field @NonNull public static final String pathSeparator;
-    field public static final char pathSeparatorChar;
-    field @NonNull public static final String separator;
-    field public static final char separatorChar;
-  }
-
-  public final class FileDescriptor {
-    ctor public FileDescriptor();
-    method public void sync() throws java.io.SyncFailedException;
-    method public boolean valid();
-    field public static final java.io.FileDescriptor err;
-    field public static final java.io.FileDescriptor in;
-    field public static final java.io.FileDescriptor out;
-  }
-
-  @java.lang.FunctionalInterface public interface FileFilter {
-    method public boolean accept(java.io.File);
-  }
-
-  public class FileInputStream extends java.io.InputStream {
-    ctor public FileInputStream(String) throws java.io.FileNotFoundException;
-    ctor public FileInputStream(java.io.File) throws java.io.FileNotFoundException;
-    ctor public FileInputStream(java.io.FileDescriptor);
-    method protected void finalize() throws java.io.IOException;
-    method public java.nio.channels.FileChannel getChannel();
-    method public final java.io.FileDescriptor getFD() throws java.io.IOException;
-    method public int read() throws java.io.IOException;
-  }
-
-  public class FileNotFoundException extends java.io.IOException {
-    ctor public FileNotFoundException();
-    ctor public FileNotFoundException(String);
-  }
-
-  public class FileOutputStream extends java.io.OutputStream {
-    ctor public FileOutputStream(String) throws java.io.FileNotFoundException;
-    ctor public FileOutputStream(String, boolean) throws java.io.FileNotFoundException;
-    ctor public FileOutputStream(java.io.File) throws java.io.FileNotFoundException;
-    ctor public FileOutputStream(java.io.File, boolean) throws java.io.FileNotFoundException;
-    ctor public FileOutputStream(java.io.FileDescriptor);
-    method protected void finalize() throws java.io.IOException;
-    method public java.nio.channels.FileChannel getChannel();
-    method public final java.io.FileDescriptor getFD() throws java.io.IOException;
-    method public void write(int) throws java.io.IOException;
-  }
-
-  public final class FilePermission extends java.security.Permission implements java.io.Serializable {
-    ctor public FilePermission(String, String);
-    method public String getActions();
-    method public boolean implies(java.security.Permission);
-  }
-
-  public class FileReader extends java.io.InputStreamReader {
-    ctor public FileReader(String) throws java.io.FileNotFoundException;
-    ctor public FileReader(java.io.File) throws java.io.FileNotFoundException;
-    ctor public FileReader(java.io.FileDescriptor);
-  }
-
-  public class FileWriter extends java.io.OutputStreamWriter {
-    ctor public FileWriter(String) throws java.io.IOException;
-    ctor public FileWriter(String, boolean) throws java.io.IOException;
-    ctor public FileWriter(java.io.File) throws java.io.IOException;
-    ctor public FileWriter(java.io.File, boolean) throws java.io.IOException;
-    ctor public FileWriter(java.io.FileDescriptor);
-  }
-
-  @java.lang.FunctionalInterface public interface FilenameFilter {
-    method public boolean accept(java.io.File, String);
-  }
-
-  public class FilterInputStream extends java.io.InputStream {
-    ctor protected FilterInputStream(java.io.InputStream);
-    method public int read() throws java.io.IOException;
-    field protected volatile java.io.InputStream in;
-  }
-
-  public class FilterOutputStream extends java.io.OutputStream {
-    ctor public FilterOutputStream(java.io.OutputStream);
-    method public void write(int) throws java.io.IOException;
-    field protected java.io.OutputStream out;
-  }
-
-  public abstract class FilterReader extends java.io.Reader {
-    ctor protected FilterReader(java.io.Reader);
-    method public void close() throws java.io.IOException;
-    method public int read(char[], int, int) throws java.io.IOException;
-    field protected java.io.Reader in;
-  }
-
-  public abstract class FilterWriter extends java.io.Writer {
-    ctor protected FilterWriter(java.io.Writer);
-    method public void close() throws java.io.IOException;
-    method public void flush() throws java.io.IOException;
-    method public void write(char[], int, int) throws java.io.IOException;
-    field protected java.io.Writer out;
-  }
-
-  public interface Flushable {
-    method public void flush() throws java.io.IOException;
-  }
-
-  public class IOError extends java.lang.Error {
-    ctor public IOError(Throwable);
-  }
-
-  public class IOException extends java.lang.Exception {
-    ctor public IOException();
-    ctor public IOException(String);
-    ctor public IOException(String, Throwable);
-    ctor public IOException(Throwable);
-  }
-
-  public abstract class InputStream implements java.io.Closeable {
-    ctor public InputStream();
-    method public int available() throws java.io.IOException;
-    method public void close() throws java.io.IOException;
-    method public void mark(int);
-    method public boolean markSupported();
-    method public abstract int read() throws java.io.IOException;
-    method public int read(byte[]) throws java.io.IOException;
-    method public int read(byte[], int, int) throws java.io.IOException;
-    method public void reset() throws java.io.IOException;
-    method public long skip(long) throws java.io.IOException;
-  }
-
-  public class InputStreamReader extends java.io.Reader {
-    ctor public InputStreamReader(java.io.InputStream);
-    ctor public InputStreamReader(java.io.InputStream, String) throws java.io.UnsupportedEncodingException;
-    ctor public InputStreamReader(java.io.InputStream, java.nio.charset.Charset);
-    ctor public InputStreamReader(java.io.InputStream, java.nio.charset.CharsetDecoder);
-    method public void close() throws java.io.IOException;
-    method public String getEncoding();
-    method public int read(char[], int, int) throws java.io.IOException;
-  }
-
-  public class InterruptedIOException extends java.io.IOException {
-    ctor public InterruptedIOException();
-    ctor public InterruptedIOException(String);
-    field public int bytesTransferred;
-  }
-
-  public class InvalidClassException extends java.io.ObjectStreamException {
-    ctor public InvalidClassException(String);
-    ctor public InvalidClassException(String, String);
-    field public String classname;
-  }
-
-  public class InvalidObjectException extends java.io.ObjectStreamException {
-    ctor public InvalidObjectException(String);
-  }
-
-  @Deprecated public class LineNumberInputStream extends java.io.FilterInputStream {
-    ctor @Deprecated public LineNumberInputStream(java.io.InputStream);
-    method @Deprecated public int getLineNumber();
-    method @Deprecated public void setLineNumber(int);
-  }
-
-  public class LineNumberReader extends java.io.BufferedReader {
-    ctor public LineNumberReader(java.io.Reader);
-    ctor public LineNumberReader(java.io.Reader, int);
-    method public int getLineNumber();
-    method public void setLineNumber(int);
-  }
-
-  public class NotActiveException extends java.io.ObjectStreamException {
-    ctor public NotActiveException(String);
-    ctor public NotActiveException();
-  }
-
-  public class NotSerializableException extends java.io.ObjectStreamException {
-    ctor public NotSerializableException(String);
-    ctor public NotSerializableException();
-  }
-
-  public interface ObjectInput extends java.io.DataInput java.lang.AutoCloseable {
-    method public int available() throws java.io.IOException;
-    method public void close() throws java.io.IOException;
-    method public int read() throws java.io.IOException;
-    method public int read(byte[]) throws java.io.IOException;
-    method public int read(byte[], int, int) throws java.io.IOException;
-    method public Object readObject() throws java.lang.ClassNotFoundException, java.io.IOException;
-    method public long skip(long) throws java.io.IOException;
-  }
-
-  public class ObjectInputStream extends java.io.InputStream implements java.io.ObjectInput java.io.ObjectStreamConstants {
-    ctor public ObjectInputStream(java.io.InputStream) throws java.io.IOException;
-    ctor protected ObjectInputStream() throws java.io.IOException, java.lang.SecurityException;
-    method public void defaultReadObject() throws java.lang.ClassNotFoundException, java.io.IOException;
-    method protected boolean enableResolveObject(boolean) throws java.lang.SecurityException;
-    method public int read() throws java.io.IOException;
-    method public boolean readBoolean() throws java.io.IOException;
-    method public byte readByte() throws java.io.IOException;
-    method public char readChar() throws java.io.IOException;
-    method protected java.io.ObjectStreamClass readClassDescriptor() throws java.lang.ClassNotFoundException, java.io.IOException;
-    method public double readDouble() throws java.io.IOException;
-    method public java.io.ObjectInputStream.GetField readFields() throws java.lang.ClassNotFoundException, java.io.IOException;
-    method public float readFloat() throws java.io.IOException;
-    method public void readFully(byte[]) throws java.io.IOException;
-    method public void readFully(byte[], int, int) throws java.io.IOException;
-    method public int readInt() throws java.io.IOException;
-    method @Deprecated public String readLine() throws java.io.IOException;
-    method public long readLong() throws java.io.IOException;
-    method public final Object readObject() throws java.lang.ClassNotFoundException, java.io.IOException;
-    method protected Object readObjectOverride() throws java.lang.ClassNotFoundException, java.io.IOException;
-    method public short readShort() throws java.io.IOException;
-    method protected void readStreamHeader() throws java.io.IOException, java.io.StreamCorruptedException;
-    method public String readUTF() throws java.io.IOException;
-    method public Object readUnshared() throws java.lang.ClassNotFoundException, java.io.IOException;
-    method public int readUnsignedByte() throws java.io.IOException;
-    method public int readUnsignedShort() throws java.io.IOException;
-    method public void registerValidation(java.io.ObjectInputValidation, int) throws java.io.InvalidObjectException, java.io.NotActiveException;
-    method protected Class<?> resolveClass(java.io.ObjectStreamClass) throws java.lang.ClassNotFoundException, java.io.IOException;
-    method protected Object resolveObject(Object) throws java.io.IOException;
-    method protected Class<?> resolveProxyClass(String[]) throws java.lang.ClassNotFoundException, java.io.IOException;
-    method public int skipBytes(int) throws java.io.IOException;
-  }
-
-  public abstract static class ObjectInputStream.GetField {
-    ctor public ObjectInputStream.GetField();
-    method public abstract boolean defaulted(String) throws java.io.IOException;
-    method public abstract boolean get(String, boolean) throws java.io.IOException;
-    method public abstract byte get(String, byte) throws java.io.IOException;
-    method public abstract char get(String, char) throws java.io.IOException;
-    method public abstract short get(String, short) throws java.io.IOException;
-    method public abstract int get(String, int) throws java.io.IOException;
-    method public abstract long get(String, long) throws java.io.IOException;
-    method public abstract float get(String, float) throws java.io.IOException;
-    method public abstract double get(String, double) throws java.io.IOException;
-    method public abstract Object get(String, Object) throws java.io.IOException;
-    method public abstract java.io.ObjectStreamClass getObjectStreamClass();
-  }
-
-  public interface ObjectInputValidation {
-    method public void validateObject() throws java.io.InvalidObjectException;
-  }
-
-  public interface ObjectOutput extends java.io.DataOutput java.lang.AutoCloseable {
-    method public void close() throws java.io.IOException;
-    method public void flush() throws java.io.IOException;
-    method public void writeObject(Object) throws java.io.IOException;
-  }
-
-  public class ObjectOutputStream extends java.io.OutputStream implements java.io.ObjectOutput java.io.ObjectStreamConstants {
-    ctor public ObjectOutputStream(java.io.OutputStream) throws java.io.IOException;
-    ctor protected ObjectOutputStream() throws java.io.IOException, java.lang.SecurityException;
-    method protected void annotateClass(Class<?>) throws java.io.IOException;
-    method protected void annotateProxyClass(Class<?>) throws java.io.IOException;
-    method public void defaultWriteObject() throws java.io.IOException;
-    method protected void drain() throws java.io.IOException;
-    method protected boolean enableReplaceObject(boolean) throws java.lang.SecurityException;
-    method public java.io.ObjectOutputStream.PutField putFields() throws java.io.IOException;
-    method protected Object replaceObject(Object) throws java.io.IOException;
-    method public void reset() throws java.io.IOException;
-    method public void useProtocolVersion(int) throws java.io.IOException;
-    method public void write(int) throws java.io.IOException;
-    method public void writeBoolean(boolean) throws java.io.IOException;
-    method public void writeByte(int) throws java.io.IOException;
-    method public void writeBytes(String) throws java.io.IOException;
-    method public void writeChar(int) throws java.io.IOException;
-    method public void writeChars(String) throws java.io.IOException;
-    method protected void writeClassDescriptor(java.io.ObjectStreamClass) throws java.io.IOException;
-    method public void writeDouble(double) throws java.io.IOException;
-    method public void writeFields() throws java.io.IOException;
-    method public void writeFloat(float) throws java.io.IOException;
-    method public void writeInt(int) throws java.io.IOException;
-    method public void writeLong(long) throws java.io.IOException;
-    method public final void writeObject(Object) throws java.io.IOException;
-    method protected void writeObjectOverride(Object) throws java.io.IOException;
-    method public void writeShort(int) throws java.io.IOException;
-    method protected void writeStreamHeader() throws java.io.IOException;
-    method public void writeUTF(String) throws java.io.IOException;
-    method public void writeUnshared(Object) throws java.io.IOException;
-  }
-
-  public abstract static class ObjectOutputStream.PutField {
-    ctor public ObjectOutputStream.PutField();
-    method public abstract void put(String, boolean);
-    method public abstract void put(String, byte);
-    method public abstract void put(String, char);
-    method public abstract void put(String, short);
-    method public abstract void put(String, int);
-    method public abstract void put(String, long);
-    method public abstract void put(String, float);
-    method public abstract void put(String, double);
-    method public abstract void put(String, Object);
-    method @Deprecated public abstract void write(java.io.ObjectOutput) throws java.io.IOException;
-  }
-
-  public class ObjectStreamClass implements java.io.Serializable {
-    method public Class<?> forClass();
-    method public java.io.ObjectStreamField getField(String);
-    method public java.io.ObjectStreamField[] getFields();
-    method public String getName();
-    method public long getSerialVersionUID();
-    method public static java.io.ObjectStreamClass lookup(Class<?>);
-    method public static java.io.ObjectStreamClass lookupAny(Class<?>);
-    field public static final java.io.ObjectStreamField[] NO_FIELDS;
-  }
-
-  public interface ObjectStreamConstants {
-    field public static final int PROTOCOL_VERSION_1 = 1; // 0x1
-    field public static final int PROTOCOL_VERSION_2 = 2; // 0x2
-    field public static final byte SC_BLOCK_DATA = 8; // 0x8
-    field public static final byte SC_ENUM = 16; // 0x10
-    field public static final byte SC_EXTERNALIZABLE = 4; // 0x4
-    field public static final byte SC_SERIALIZABLE = 2; // 0x2
-    field public static final byte SC_WRITE_METHOD = 1; // 0x1
-    field public static final short STREAM_MAGIC = -21267; // 0xffffaced
-    field public static final short STREAM_VERSION = 5; // 0x5
-    field public static final java.io.SerializablePermission SUBCLASS_IMPLEMENTATION_PERMISSION;
-    field public static final java.io.SerializablePermission SUBSTITUTION_PERMISSION;
-    field public static final byte TC_ARRAY = 117; // 0x75
-    field public static final byte TC_BASE = 112; // 0x70
-    field public static final byte TC_BLOCKDATA = 119; // 0x77
-    field public static final byte TC_BLOCKDATALONG = 122; // 0x7a
-    field public static final byte TC_CLASS = 118; // 0x76
-    field public static final byte TC_CLASSDESC = 114; // 0x72
-    field public static final byte TC_ENDBLOCKDATA = 120; // 0x78
-    field public static final byte TC_ENUM = 126; // 0x7e
-    field public static final byte TC_EXCEPTION = 123; // 0x7b
-    field public static final byte TC_LONGSTRING = 124; // 0x7c
-    field public static final byte TC_MAX = 126; // 0x7e
-    field public static final byte TC_NULL = 112; // 0x70
-    field public static final byte TC_OBJECT = 115; // 0x73
-    field public static final byte TC_PROXYCLASSDESC = 125; // 0x7d
-    field public static final byte TC_REFERENCE = 113; // 0x71
-    field public static final byte TC_RESET = 121; // 0x79
-    field public static final byte TC_STRING = 116; // 0x74
-    field public static final int baseWireHandle = 8257536; // 0x7e0000
-  }
-
-  public abstract class ObjectStreamException extends java.io.IOException {
-    ctor protected ObjectStreamException(String);
-    ctor protected ObjectStreamException();
-  }
-
-  public class ObjectStreamField implements java.lang.Comparable<java.lang.Object> {
-    ctor public ObjectStreamField(String, Class<?>);
-    ctor public ObjectStreamField(String, Class<?>, boolean);
-    method public int compareTo(Object);
-    method public String getName();
-    method public int getOffset();
-    method public Class<?> getType();
-    method public char getTypeCode();
-    method public String getTypeString();
-    method public boolean isPrimitive();
-    method public boolean isUnshared();
-    method protected void setOffset(int);
-  }
-
-  public class OptionalDataException extends java.io.ObjectStreamException {
-    field public boolean eof;
-    field public int length;
-  }
-
-  public abstract class OutputStream implements java.io.Closeable java.io.Flushable {
-    ctor public OutputStream();
-    method public void close() throws java.io.IOException;
-    method public void flush() throws java.io.IOException;
-    method public abstract void write(int) throws java.io.IOException;
-    method public void write(byte[]) throws java.io.IOException;
-    method public void write(byte[], int, int) throws java.io.IOException;
-  }
-
-  public class OutputStreamWriter extends java.io.Writer {
-    ctor public OutputStreamWriter(java.io.OutputStream, String) throws java.io.UnsupportedEncodingException;
-    ctor public OutputStreamWriter(java.io.OutputStream);
-    ctor public OutputStreamWriter(java.io.OutputStream, java.nio.charset.Charset);
-    ctor public OutputStreamWriter(java.io.OutputStream, java.nio.charset.CharsetEncoder);
-    method public void close() throws java.io.IOException;
-    method public void flush() throws java.io.IOException;
-    method public String getEncoding();
-    method public void write(char[], int, int) throws java.io.IOException;
-  }
-
-  public class PipedInputStream extends java.io.InputStream {
-    ctor public PipedInputStream(java.io.PipedOutputStream) throws java.io.IOException;
-    ctor public PipedInputStream(java.io.PipedOutputStream, int) throws java.io.IOException;
-    ctor public PipedInputStream();
-    ctor public PipedInputStream(int);
-    method public void connect(java.io.PipedOutputStream) throws java.io.IOException;
-    method public int read() throws java.io.IOException;
-    method protected void receive(int) throws java.io.IOException;
-    field protected static final int PIPE_SIZE = 1024; // 0x400
-    field protected byte[] buffer;
-    field protected int in;
-    field protected int out;
-  }
-
-  public class PipedOutputStream extends java.io.OutputStream {
-    ctor public PipedOutputStream(java.io.PipedInputStream) throws java.io.IOException;
-    ctor public PipedOutputStream();
-    method public void connect(java.io.PipedInputStream) throws java.io.IOException;
-    method public void write(int) throws java.io.IOException;
-  }
-
-  public class PipedReader extends java.io.Reader {
-    ctor public PipedReader(java.io.PipedWriter) throws java.io.IOException;
-    ctor public PipedReader(java.io.PipedWriter, int) throws java.io.IOException;
-    ctor public PipedReader();
-    ctor public PipedReader(int);
-    method public void close() throws java.io.IOException;
-    method public void connect(java.io.PipedWriter) throws java.io.IOException;
-    method public int read(char[], int, int) throws java.io.IOException;
-  }
-
-  public class PipedWriter extends java.io.Writer {
-    ctor public PipedWriter(java.io.PipedReader) throws java.io.IOException;
-    ctor public PipedWriter();
-    method public void close() throws java.io.IOException;
-    method public void connect(java.io.PipedReader) throws java.io.IOException;
-    method public void flush() throws java.io.IOException;
-    method public void write(char[], int, int) throws java.io.IOException;
-  }
-
-  public class PrintStream extends java.io.FilterOutputStream implements java.lang.Appendable java.io.Closeable {
-    ctor public PrintStream(java.io.OutputStream);
-    ctor public PrintStream(java.io.OutputStream, boolean);
-    ctor public PrintStream(java.io.OutputStream, boolean, String) throws java.io.UnsupportedEncodingException;
-    ctor public PrintStream(String) throws java.io.FileNotFoundException;
-    ctor public PrintStream(String, String) throws java.io.FileNotFoundException, java.io.UnsupportedEncodingException;
-    ctor public PrintStream(java.io.File) throws java.io.FileNotFoundException;
-    ctor public PrintStream(java.io.File, String) throws java.io.FileNotFoundException, java.io.UnsupportedEncodingException;
-    method public java.io.PrintStream append(CharSequence);
-    method public java.io.PrintStream append(CharSequence, int, int);
-    method public java.io.PrintStream append(char);
-    method public boolean checkError();
-    method protected void clearError();
-    method public void close();
-    method public void flush();
-    method public java.io.PrintStream format(String, java.lang.Object...);
-    method public java.io.PrintStream format(java.util.Locale, String, java.lang.Object...);
-    method public void print(boolean);
-    method public void print(char);
-    method public void print(int);
-    method public void print(long);
-    method public void print(float);
-    method public void print(double);
-    method public void print(char[]);
-    method public void print(String);
-    method public void print(Object);
-    method public java.io.PrintStream printf(String, java.lang.Object...);
-    method public java.io.PrintStream printf(java.util.Locale, String, java.lang.Object...);
-    method public void println();
-    method public void println(boolean);
-    method public void println(char);
-    method public void println(int);
-    method public void println(long);
-    method public void println(float);
-    method public void println(double);
-    method public void println(char[]);
-    method public void println(String);
-    method public void println(Object);
-    method protected void setError();
-    method public void write(int);
-    method public void write(byte[], int, int);
-  }
-
-  public class PrintWriter extends java.io.Writer {
-    ctor public PrintWriter(@NonNull java.io.Writer);
-    ctor public PrintWriter(@NonNull java.io.Writer, boolean);
-    ctor public PrintWriter(@NonNull java.io.OutputStream);
-    ctor public PrintWriter(@NonNull java.io.OutputStream, boolean);
-    ctor public PrintWriter(@NonNull String) throws java.io.FileNotFoundException;
-    ctor public PrintWriter(@NonNull String, @NonNull String) throws java.io.FileNotFoundException, java.io.UnsupportedEncodingException;
-    ctor public PrintWriter(@NonNull java.io.File) throws java.io.FileNotFoundException;
-    ctor public PrintWriter(@NonNull java.io.File, @NonNull String) throws java.io.FileNotFoundException, java.io.UnsupportedEncodingException;
-    method @NonNull public java.io.PrintWriter append(@Nullable CharSequence);
-    method @NonNull public java.io.PrintWriter append(@Nullable CharSequence, int, int);
-    method @NonNull public java.io.PrintWriter append(char);
-    method public boolean checkError();
-    method protected void clearError();
-    method public void close();
-    method public void flush();
-    method @NonNull public java.io.PrintWriter format(@NonNull String, @NonNull java.lang.Object...);
-    method @NonNull public java.io.PrintWriter format(@Nullable java.util.Locale, @NonNull String, @NonNull java.lang.Object...);
-    method public void print(boolean);
-    method public void print(char);
-    method public void print(int);
-    method public void print(long);
-    method public void print(float);
-    method public void print(double);
-    method public void print(char[]);
-    method public void print(@Nullable String);
-    method public void print(@Nullable Object);
-    method @NonNull public java.io.PrintWriter printf(@NonNull String, @NonNull java.lang.Object...);
-    method @NonNull public java.io.PrintWriter printf(@Nullable java.util.Locale, @NonNull String, @NonNull java.lang.Object...);
-    method public void println();
-    method public void println(boolean);
-    method public void println(char);
-    method public void println(int);
-    method public void println(long);
-    method public void println(float);
-    method public void println(double);
-    method public void println(char[]);
-    method public void println(@Nullable String);
-    method public void println(@Nullable Object);
-    method protected void setError();
-    method public void write(int);
-    method public void write(char[], int, int);
-    method public void write(char[]);
-    method public void write(@NonNull String, int, int);
-    method public void write(@NonNull String);
-    field protected java.io.Writer out;
-  }
-
-  public class PushbackInputStream extends java.io.FilterInputStream {
-    ctor public PushbackInputStream(java.io.InputStream, int);
-    ctor public PushbackInputStream(java.io.InputStream);
-    method public void unread(int) throws java.io.IOException;
-    method public void unread(byte[], int, int) throws java.io.IOException;
-    method public void unread(byte[]) throws java.io.IOException;
-    field protected byte[] buf;
-    field protected int pos;
-  }
-
-  public class PushbackReader extends java.io.FilterReader {
-    ctor public PushbackReader(java.io.Reader, int);
-    ctor public PushbackReader(java.io.Reader);
-    method public void unread(int) throws java.io.IOException;
-    method public void unread(char[], int, int) throws java.io.IOException;
-    method public void unread(char[]) throws java.io.IOException;
-  }
-
-  public class RandomAccessFile implements java.io.Closeable java.io.DataInput java.io.DataOutput {
-    ctor public RandomAccessFile(String, String) throws java.io.FileNotFoundException;
-    ctor public RandomAccessFile(java.io.File, String) throws java.io.FileNotFoundException;
-    method public void close() throws java.io.IOException;
-    method public final java.nio.channels.FileChannel getChannel();
-    method public final java.io.FileDescriptor getFD() throws java.io.IOException;
-    method public long getFilePointer() throws java.io.IOException;
-    method public long length() throws java.io.IOException;
-    method public int read() throws java.io.IOException;
-    method public int read(byte[], int, int) throws java.io.IOException;
-    method public int read(byte[]) throws java.io.IOException;
-    method public final boolean readBoolean() throws java.io.IOException;
-    method public final byte readByte() throws java.io.IOException;
-    method public final char readChar() throws java.io.IOException;
-    method public final double readDouble() throws java.io.IOException;
-    method public final float readFloat() throws java.io.IOException;
-    method public final void readFully(byte[]) throws java.io.IOException;
-    method public final void readFully(byte[], int, int) throws java.io.IOException;
-    method public final int readInt() throws java.io.IOException;
-    method public final String readLine() throws java.io.IOException;
-    method public final long readLong() throws java.io.IOException;
-    method public final short readShort() throws java.io.IOException;
-    method public final String readUTF() throws java.io.IOException;
-    method public final int readUnsignedByte() throws java.io.IOException;
-    method public final int readUnsignedShort() throws java.io.IOException;
-    method public void seek(long) throws java.io.IOException;
-    method public void setLength(long) throws java.io.IOException;
-    method public int skipBytes(int) throws java.io.IOException;
-    method public void write(int) throws java.io.IOException;
-    method public void write(byte[]) throws java.io.IOException;
-    method public void write(byte[], int, int) throws java.io.IOException;
-    method public final void writeBoolean(boolean) throws java.io.IOException;
-    method public final void writeByte(int) throws java.io.IOException;
-    method public final void writeBytes(String) throws java.io.IOException;
-    method public final void writeChar(int) throws java.io.IOException;
-    method public final void writeChars(String) throws java.io.IOException;
-    method public final void writeDouble(double) throws java.io.IOException;
-    method public final void writeFloat(float) throws java.io.IOException;
-    method public final void writeInt(int) throws java.io.IOException;
-    method public final void writeLong(long) throws java.io.IOException;
-    method public final void writeShort(int) throws java.io.IOException;
-    method public final void writeUTF(String) throws java.io.IOException;
-  }
-
-  public abstract class Reader implements java.io.Closeable java.lang.Readable {
-    ctor protected Reader();
-    ctor protected Reader(Object);
-    method public void mark(int) throws java.io.IOException;
-    method public boolean markSupported();
-    method public int read(java.nio.CharBuffer) throws java.io.IOException;
-    method public int read() throws java.io.IOException;
-    method public int read(char[]) throws java.io.IOException;
-    method public abstract int read(char[], int, int) throws java.io.IOException;
-    method public boolean ready() throws java.io.IOException;
-    method public void reset() throws java.io.IOException;
-    method public long skip(long) throws java.io.IOException;
-    field protected Object lock;
-  }
-
-  public class SequenceInputStream extends java.io.InputStream {
-    ctor public SequenceInputStream(java.util.Enumeration<? extends java.io.InputStream>);
-    ctor public SequenceInputStream(java.io.InputStream, java.io.InputStream);
-    method public int read() throws java.io.IOException;
-  }
-
-  public interface Serializable {
-  }
-
-  public final class SerializablePermission extends java.security.BasicPermission {
-    ctor public SerializablePermission(String);
-    ctor public SerializablePermission(String, String);
-  }
-
-  public class StreamCorruptedException extends java.io.ObjectStreamException {
-    ctor public StreamCorruptedException(String);
-    ctor public StreamCorruptedException();
-  }
-
-  public class StreamTokenizer {
-    ctor @Deprecated public StreamTokenizer(java.io.InputStream);
-    ctor public StreamTokenizer(java.io.Reader);
-    method public void commentChar(int);
-    method public void eolIsSignificant(boolean);
-    method public int lineno();
-    method public void lowerCaseMode(boolean);
-    method public int nextToken() throws java.io.IOException;
-    method public void ordinaryChar(int);
-    method public void ordinaryChars(int, int);
-    method public void parseNumbers();
-    method public void pushBack();
-    method public void quoteChar(int);
-    method public void resetSyntax();
-    method public void slashSlashComments(boolean);
-    method public void slashStarComments(boolean);
-    method public void whitespaceChars(int, int);
-    method public void wordChars(int, int);
-    field public static final int TT_EOF = -1; // 0xffffffff
-    field public static final int TT_EOL = 10; // 0xa
-    field public static final int TT_NUMBER = -2; // 0xfffffffe
-    field public static final int TT_WORD = -3; // 0xfffffffd
-    field public double nval;
-    field public String sval;
-    field public int ttype;
-  }
-
-  @Deprecated public class StringBufferInputStream extends java.io.InputStream {
-    ctor @Deprecated public StringBufferInputStream(String);
-    method @Deprecated public int available();
-    method @Deprecated public int read();
-    method @Deprecated public int read(byte[], int, int);
-    method @Deprecated public void reset();
-    method @Deprecated public long skip(long);
-    field @Deprecated protected String buffer;
-    field @Deprecated protected int count;
-    field @Deprecated protected int pos;
-  }
-
-  public class StringReader extends java.io.Reader {
-    ctor public StringReader(String);
-    method public void close();
-    method public int read(char[], int, int) throws java.io.IOException;
-  }
-
-  public class StringWriter extends java.io.Writer {
-    ctor public StringWriter();
-    ctor public StringWriter(int);
-    method public java.io.StringWriter append(CharSequence);
-    method public java.io.StringWriter append(CharSequence, int, int);
-    method public java.io.StringWriter append(char);
-    method public void close() throws java.io.IOException;
-    method public void flush();
-    method public StringBuffer getBuffer();
-    method public void write(int);
-    method public void write(char[], int, int);
-    method public void write(String);
-    method public void write(String, int, int);
-  }
-
-  public class SyncFailedException extends java.io.IOException {
-    ctor public SyncFailedException(String);
-  }
-
-  public class UTFDataFormatException extends java.io.IOException {
-    ctor public UTFDataFormatException();
-    ctor public UTFDataFormatException(String);
-  }
-
-  public class UncheckedIOException extends java.lang.RuntimeException {
-    ctor public UncheckedIOException(String, java.io.IOException);
-    ctor public UncheckedIOException(java.io.IOException);
-    method public java.io.IOException getCause();
-  }
-
-  public class UnsupportedEncodingException extends java.io.IOException {
-    ctor public UnsupportedEncodingException();
-    ctor public UnsupportedEncodingException(String);
-  }
-
-  public class WriteAbortedException extends java.io.ObjectStreamException {
-    ctor public WriteAbortedException(String, Exception);
-    field public Exception detail;
-  }
-
-  public abstract class Writer implements java.lang.Appendable java.io.Closeable java.io.Flushable {
-    ctor protected Writer();
-    ctor protected Writer(Object);
-    method public java.io.Writer append(CharSequence) throws java.io.IOException;
-    method public java.io.Writer append(CharSequence, int, int) throws java.io.IOException;
-    method public java.io.Writer append(char) throws java.io.IOException;
-    method public void write(int) throws java.io.IOException;
-    method public void write(char[]) throws java.io.IOException;
-    method public abstract void write(char[], int, int) throws java.io.IOException;
-    method public void write(String) throws java.io.IOException;
-    method public void write(String, int, int) throws java.io.IOException;
-    field protected Object lock;
-  }
-
-}
-
-package java.lang {
-
-  public class AbstractMethodError extends java.lang.IncompatibleClassChangeError {
-    ctor public AbstractMethodError();
-    ctor public AbstractMethodError(String);
-  }
-
-  public interface Appendable {
-    method @NonNull public Appendable append(@Nullable CharSequence) throws java.io.IOException;
-    method @NonNull public Appendable append(@Nullable CharSequence, int, int) throws java.io.IOException;
-    method @NonNull public Appendable append(char) throws java.io.IOException;
-  }
-
-  public class ArithmeticException extends java.lang.RuntimeException {
-    ctor public ArithmeticException();
-    ctor public ArithmeticException(String);
-  }
-
-  public class ArrayIndexOutOfBoundsException extends java.lang.IndexOutOfBoundsException {
-    ctor public ArrayIndexOutOfBoundsException();
-    ctor public ArrayIndexOutOfBoundsException(int);
-    ctor public ArrayIndexOutOfBoundsException(String);
-  }
-
-  public class ArrayStoreException extends java.lang.RuntimeException {
-    ctor public ArrayStoreException();
-    ctor public ArrayStoreException(String);
-  }
-
-  public class AssertionError extends java.lang.Error {
-    ctor public AssertionError();
-    ctor public AssertionError(Object);
-    ctor public AssertionError(boolean);
-    ctor public AssertionError(char);
-    ctor public AssertionError(int);
-    ctor public AssertionError(long);
-    ctor public AssertionError(float);
-    ctor public AssertionError(double);
-    ctor public AssertionError(String, Throwable);
-  }
-
-  public interface AutoCloseable {
-    method public void close() throws java.lang.Exception;
-  }
-
-  public final class Boolean implements java.lang.Comparable<java.lang.Boolean> java.io.Serializable {
-    ctor public Boolean(boolean);
-    ctor public Boolean(@Nullable String);
-    method public boolean booleanValue();
-    method public static int compare(boolean, boolean);
-    method public int compareTo(@NonNull Boolean);
-    method public static boolean getBoolean(@NonNull String);
-    method public static int hashCode(boolean);
-    method public static boolean logicalAnd(boolean, boolean);
-    method public static boolean logicalOr(boolean, boolean);
-    method public static boolean logicalXor(boolean, boolean);
-    method public static boolean parseBoolean(@Nullable String);
-    method @NonNull public static String toString(boolean);
-    method @NonNull public static Boolean valueOf(boolean);
-    method @NonNull public static Boolean valueOf(@Nullable String);
-    field public static final Boolean FALSE;
-    field public static final Boolean TRUE;
-    field public static final Class<java.lang.Boolean> TYPE;
-  }
-
-  public class BootstrapMethodError extends java.lang.LinkageError {
-    ctor public BootstrapMethodError();
-    ctor public BootstrapMethodError(String);
-    ctor public BootstrapMethodError(String, Throwable);
-    ctor public BootstrapMethodError(Throwable);
-  }
-
-  public final class Byte extends java.lang.Number implements java.lang.Comparable<java.lang.Byte> {
-    ctor public Byte(byte);
-    ctor public Byte(@NonNull String) throws java.lang.NumberFormatException;
-    method public static int compare(byte, byte);
-    method public int compareTo(@NonNull Byte);
-    method @NonNull public static Byte decode(@NonNull String) throws java.lang.NumberFormatException;
-    method public double doubleValue();
-    method public float floatValue();
-    method public static int hashCode(byte);
-    method public int intValue();
-    method public long longValue();
-    method public static byte parseByte(@NonNull String, int) throws java.lang.NumberFormatException;
-    method public static byte parseByte(@NonNull String) throws java.lang.NumberFormatException;
-    method @NonNull public static String toString(byte);
-    method public static int toUnsignedInt(byte);
-    method public static long toUnsignedLong(byte);
-    method @NonNull public static Byte valueOf(byte);
-    method @NonNull public static Byte valueOf(@NonNull String, int) throws java.lang.NumberFormatException;
-    method @NonNull public static Byte valueOf(@NonNull String) throws java.lang.NumberFormatException;
-    field public static final int BYTES = 1; // 0x1
-    field public static final byte MAX_VALUE = 127; // 0x7f
-    field public static final byte MIN_VALUE = -128; // 0xffffff80
-    field public static final int SIZE = 8; // 0x8
-    field public static final Class<java.lang.Byte> TYPE;
-  }
-
-  public interface CharSequence {
-    method public char charAt(int);
-    method @NonNull public default java.util.stream.IntStream chars();
-    method @NonNull public default java.util.stream.IntStream codePoints();
-    method public int length();
-    method @NonNull public CharSequence subSequence(int, int);
-    method @NonNull public String toString();
-  }
-
-  public final class Character implements java.lang.Comparable<java.lang.Character> java.io.Serializable {
-    ctor public Character(char);
-    method public static int charCount(int);
-    method public char charValue();
-    method public static int codePointAt(@NonNull CharSequence, int);
-    method public static int codePointAt(char[], int);
-    method public static int codePointAt(char[], int, int);
-    method public static int codePointBefore(@NonNull CharSequence, int);
-    method public static int codePointBefore(char[], int);
-    method public static int codePointBefore(char[], int, int);
-    method public static int codePointCount(@NonNull CharSequence, int, int);
-    method public static int codePointCount(char[], int, int);
-    method public static int compare(char, char);
-    method public int compareTo(@NonNull Character);
-    method public static int digit(char, int);
-    method public static int digit(int, int);
-    method public static char forDigit(int, int);
-    method public static byte getDirectionality(char);
-    method public static byte getDirectionality(int);
-    method @Nullable public static String getName(int);
-    method public static int getNumericValue(char);
-    method public static int getNumericValue(int);
-    method public static int getType(char);
-    method public static int getType(int);
-    method public static int hashCode(char);
-    method public static char highSurrogate(int);
-    method public static boolean isAlphabetic(int);
-    method public static boolean isBmpCodePoint(int);
-    method public static boolean isDefined(char);
-    method public static boolean isDefined(int);
-    method public static boolean isDigit(char);
-    method public static boolean isDigit(int);
-    method public static boolean isHighSurrogate(char);
-    method public static boolean isISOControl(char);
-    method public static boolean isISOControl(int);
-    method public static boolean isIdentifierIgnorable(char);
-    method public static boolean isIdentifierIgnorable(int);
-    method public static boolean isIdeographic(int);
-    method public static boolean isJavaIdentifierPart(char);
-    method public static boolean isJavaIdentifierPart(int);
-    method public static boolean isJavaIdentifierStart(char);
-    method public static boolean isJavaIdentifierStart(int);
-    method @Deprecated public static boolean isJavaLetter(char);
-    method @Deprecated public static boolean isJavaLetterOrDigit(char);
-    method public static boolean isLetter(char);
-    method public static boolean isLetter(int);
-    method public static boolean isLetterOrDigit(char);
-    method public static boolean isLetterOrDigit(int);
-    method public static boolean isLowSurrogate(char);
-    method public static boolean isLowerCase(char);
-    method public static boolean isLowerCase(int);
-    method public static boolean isMirrored(char);
-    method public static boolean isMirrored(int);
-    method @Deprecated public static boolean isSpace(char);
-    method public static boolean isSpaceChar(char);
-    method public static boolean isSpaceChar(int);
-    method public static boolean isSupplementaryCodePoint(int);
-    method public static boolean isSurrogate(char);
-    method public static boolean isSurrogatePair(char, char);
-    method public static boolean isTitleCase(char);
-    method public static boolean isTitleCase(int);
-    method public static boolean isUnicodeIdentifierPart(char);
-    method public static boolean isUnicodeIdentifierPart(int);
-    method public static boolean isUnicodeIdentifierStart(char);
-    method public static boolean isUnicodeIdentifierStart(int);
-    method public static boolean isUpperCase(char);
-    method public static boolean isUpperCase(int);
-    method public static boolean isValidCodePoint(int);
-    method public static boolean isWhitespace(char);
-    method public static boolean isWhitespace(int);
-    method public static char lowSurrogate(int);
-    method public static int offsetByCodePoints(@NonNull CharSequence, int, int);
-    method public static int offsetByCodePoints(char[], int, int, int, int);
-    method public static char reverseBytes(char);
-    method public static int toChars(int, char[], int);
-    method public static char[] toChars(int);
-    method public static int toCodePoint(char, char);
-    method public static char toLowerCase(char);
-    method public static int toLowerCase(int);
-    method @NonNull public static String toString(char);
-    method public static char toTitleCase(char);
-    method public static int toTitleCase(int);
-    method public static char toUpperCase(char);
-    method public static int toUpperCase(int);
-    method @NonNull public static Character valueOf(char);
-    field public static final int BYTES = 2; // 0x2
-    field public static final byte COMBINING_SPACING_MARK = 8; // 0x8
-    field public static final byte CONNECTOR_PUNCTUATION = 23; // 0x17
-    field public static final byte CONTROL = 15; // 0xf
-    field public static final byte CURRENCY_SYMBOL = 26; // 0x1a
-    field public static final byte DASH_PUNCTUATION = 20; // 0x14
-    field public static final byte DECIMAL_DIGIT_NUMBER = 9; // 0x9
-    field public static final byte DIRECTIONALITY_ARABIC_NUMBER = 6; // 0x6
-    field public static final byte DIRECTIONALITY_BOUNDARY_NEUTRAL = 9; // 0x9
-    field public static final byte DIRECTIONALITY_COMMON_NUMBER_SEPARATOR = 7; // 0x7
-    field public static final byte DIRECTIONALITY_EUROPEAN_NUMBER = 3; // 0x3
-    field public static final byte DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR = 4; // 0x4
-    field public static final byte DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR = 5; // 0x5
-    field public static final byte DIRECTIONALITY_LEFT_TO_RIGHT = 0; // 0x0
-    field public static final byte DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING = 14; // 0xe
-    field public static final byte DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE = 15; // 0xf
-    field public static final byte DIRECTIONALITY_NONSPACING_MARK = 8; // 0x8
-    field public static final byte DIRECTIONALITY_OTHER_NEUTRALS = 13; // 0xd
-    field public static final byte DIRECTIONALITY_PARAGRAPH_SEPARATOR = 10; // 0xa
-    field public static final byte DIRECTIONALITY_POP_DIRECTIONAL_FORMAT = 18; // 0x12
-    field public static final byte DIRECTIONALITY_RIGHT_TO_LEFT = 1; // 0x1
-    field public static final byte DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC = 2; // 0x2
-    field public static final byte DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING = 16; // 0x10
-    field public static final byte DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE = 17; // 0x11
-    field public static final byte DIRECTIONALITY_SEGMENT_SEPARATOR = 11; // 0xb
-    field public static final byte DIRECTIONALITY_UNDEFINED = -1; // 0xffffffff
-    field public static final byte DIRECTIONALITY_WHITESPACE = 12; // 0xc
-    field public static final byte ENCLOSING_MARK = 7; // 0x7
-    field public static final byte END_PUNCTUATION = 22; // 0x16
-    field public static final byte FINAL_QUOTE_PUNCTUATION = 30; // 0x1e
-    field public static final byte FORMAT = 16; // 0x10
-    field public static final byte INITIAL_QUOTE_PUNCTUATION = 29; // 0x1d
-    field public static final byte LETTER_NUMBER = 10; // 0xa
-    field public static final byte LINE_SEPARATOR = 13; // 0xd
-    field public static final byte LOWERCASE_LETTER = 2; // 0x2
-    field public static final byte MATH_SYMBOL = 25; // 0x19
-    field public static final int MAX_CODE_POINT = 1114111; // 0x10ffff
-    field public static final char MAX_HIGH_SURROGATE = 56319; // 0xdbff '\udbff'
-    field public static final char MAX_LOW_SURROGATE = 57343; // 0xdfff '\udfff'
-    field public static final int MAX_RADIX = 36; // 0x24
-    field public static final char MAX_SURROGATE = 57343; // 0xdfff '\udfff'
-    field public static final char MAX_VALUE = 65535; // 0xffff '\uffff'
-    field public static final int MIN_CODE_POINT = 0; // 0x0
-    field public static final char MIN_HIGH_SURROGATE = 55296; // 0xd800 '\ud800'
-    field public static final char MIN_LOW_SURROGATE = 56320; // 0xdc00 '\udc00'
-    field public static final int MIN_RADIX = 2; // 0x2
-    field public static final int MIN_SUPPLEMENTARY_CODE_POINT = 65536; // 0x10000
-    field public static final char MIN_SURROGATE = 55296; // 0xd800 '\ud800'
-    field public static final char MIN_VALUE = 0; // 0x0000 '\u0000'
-    field public static final byte MODIFIER_LETTER = 4; // 0x4
-    field public static final byte MODIFIER_SYMBOL = 27; // 0x1b
-    field public static final byte NON_SPACING_MARK = 6; // 0x6
-    field public static final byte OTHER_LETTER = 5; // 0x5
-    field public static final byte OTHER_NUMBER = 11; // 0xb
-    field public static final byte OTHER_PUNCTUATION = 24; // 0x18
-    field public static final byte OTHER_SYMBOL = 28; // 0x1c
-    field public static final byte PARAGRAPH_SEPARATOR = 14; // 0xe
-    field public static final byte PRIVATE_USE = 18; // 0x12
-    field public static final int SIZE = 16; // 0x10
-    field public static final byte SPACE_SEPARATOR = 12; // 0xc
-    field public static final byte START_PUNCTUATION = 21; // 0x15
-    field public static final byte SURROGATE = 19; // 0x13
-    field public static final byte TITLECASE_LETTER = 3; // 0x3
-    field public static final Class<java.lang.Character> TYPE;
-    field public static final byte UNASSIGNED = 0; // 0x0
-    field public static final byte UPPERCASE_LETTER = 1; // 0x1
-  }
-
-  public static class Character.Subset {
-    ctor protected Character.Subset(@NonNull String);
-    method public final boolean equals(@Nullable Object);
-    method public final int hashCode();
-    method @NonNull public final String toString();
-  }
-
-  public static final class Character.UnicodeBlock extends java.lang.Character.Subset {
-    method @NonNull public static java.lang.Character.UnicodeBlock forName(@NonNull String);
-    method @Nullable public static java.lang.Character.UnicodeBlock of(char);
-    method @Nullable public static java.lang.Character.UnicodeBlock of(int);
-    field public static final java.lang.Character.UnicodeBlock AEGEAN_NUMBERS;
-    field public static final java.lang.Character.UnicodeBlock ALCHEMICAL_SYMBOLS;
-    field public static final java.lang.Character.UnicodeBlock ALPHABETIC_PRESENTATION_FORMS;
-    field public static final java.lang.Character.UnicodeBlock ANCIENT_GREEK_MUSICAL_NOTATION;
-    field public static final java.lang.Character.UnicodeBlock ANCIENT_GREEK_NUMBERS;
-    field public static final java.lang.Character.UnicodeBlock ANCIENT_SYMBOLS;
-    field public static final java.lang.Character.UnicodeBlock ARABIC;
-    field public static final java.lang.Character.UnicodeBlock ARABIC_EXTENDED_A;
-    field public static final java.lang.Character.UnicodeBlock ARABIC_MATHEMATICAL_ALPHABETIC_SYMBOLS;
-    field public static final java.lang.Character.UnicodeBlock ARABIC_PRESENTATION_FORMS_A;
-    field public static final java.lang.Character.UnicodeBlock ARABIC_PRESENTATION_FORMS_B;
-    field public static final java.lang.Character.UnicodeBlock ARABIC_SUPPLEMENT;
-    field public static final java.lang.Character.UnicodeBlock ARMENIAN;
-    field public static final java.lang.Character.UnicodeBlock ARROWS;
-    field public static final java.lang.Character.UnicodeBlock AVESTAN;
-    field public static final java.lang.Character.UnicodeBlock BALINESE;
-    field public static final java.lang.Character.UnicodeBlock BAMUM;
-    field public static final java.lang.Character.UnicodeBlock BAMUM_SUPPLEMENT;
-    field public static final java.lang.Character.UnicodeBlock BASIC_LATIN;
-    field public static final java.lang.Character.UnicodeBlock BATAK;
-    field public static final java.lang.Character.UnicodeBlock BENGALI;
-    field public static final java.lang.Character.UnicodeBlock BLOCK_ELEMENTS;
-    field public static final java.lang.Character.UnicodeBlock BOPOMOFO;
-    field public static final java.lang.Character.UnicodeBlock BOPOMOFO_EXTENDED;
-    field public static final java.lang.Character.UnicodeBlock BOX_DRAWING;
-    field public static final java.lang.Character.UnicodeBlock BRAHMI;
-    field public static final java.lang.Character.UnicodeBlock BRAILLE_PATTERNS;
-    field public static final java.lang.Character.UnicodeBlock BUGINESE;
-    field public static final java.lang.Character.UnicodeBlock BUHID;
-    field public static final java.lang.Character.UnicodeBlock BYZANTINE_MUSICAL_SYMBOLS;
-    field public static final java.lang.Character.UnicodeBlock CARIAN;
-    field public static final java.lang.Character.UnicodeBlock CHAKMA;
-    field public static final java.lang.Character.UnicodeBlock CHAM;
-    field public static final java.lang.Character.UnicodeBlock CHEROKEE;
-    field public static final java.lang.Character.UnicodeBlock CJK_COMPATIBILITY;
-    field public static final java.lang.Character.UnicodeBlock CJK_COMPATIBILITY_FORMS;
-    field public static final java.lang.Character.UnicodeBlock CJK_COMPATIBILITY_IDEOGRAPHS;
-    field public static final java.lang.Character.UnicodeBlock CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT;
-    field public static final java.lang.Character.UnicodeBlock CJK_RADICALS_SUPPLEMENT;
-    field public static final java.lang.Character.UnicodeBlock CJK_STROKES;
-    field public static final java.lang.Character.UnicodeBlock CJK_SYMBOLS_AND_PUNCTUATION;
-    field public static final java.lang.Character.UnicodeBlock CJK_UNIFIED_IDEOGRAPHS;
-    field public static final java.lang.Character.UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A;
-    field public static final java.lang.Character.UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B;
-    field public static final java.lang.Character.UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_C;
-    field public static final java.lang.Character.UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_D;
-    field public static final java.lang.Character.UnicodeBlock COMBINING_DIACRITICAL_MARKS;
-    field public static final java.lang.Character.UnicodeBlock COMBINING_DIACRITICAL_MARKS_SUPPLEMENT;
-    field public static final java.lang.Character.UnicodeBlock COMBINING_HALF_MARKS;
-    field public static final java.lang.Character.UnicodeBlock COMBINING_MARKS_FOR_SYMBOLS;
-    field public static final java.lang.Character.UnicodeBlock COMMON_INDIC_NUMBER_FORMS;
-    field public static final java.lang.Character.UnicodeBlock CONTROL_PICTURES;
-    field public static final java.lang.Character.UnicodeBlock COPTIC;
-    field public static final java.lang.Character.UnicodeBlock COUNTING_ROD_NUMERALS;
-    field public static final java.lang.Character.UnicodeBlock CUNEIFORM;
-    field public static final java.lang.Character.UnicodeBlock CUNEIFORM_NUMBERS_AND_PUNCTUATION;
-    field public static final java.lang.Character.UnicodeBlock CURRENCY_SYMBOLS;
-    field public static final java.lang.Character.UnicodeBlock CYPRIOT_SYLLABARY;
-    field public static final java.lang.Character.UnicodeBlock CYRILLIC;
-    field public static final java.lang.Character.UnicodeBlock CYRILLIC_EXTENDED_A;
-    field public static final java.lang.Character.UnicodeBlock CYRILLIC_EXTENDED_B;
-    field public static final java.lang.Character.UnicodeBlock CYRILLIC_SUPPLEMENTARY;
-    field public static final java.lang.Character.UnicodeBlock DESERET;
-    field public static final java.lang.Character.UnicodeBlock DEVANAGARI;
-    field public static final java.lang.Character.UnicodeBlock DEVANAGARI_EXTENDED;
-    field public static final java.lang.Character.UnicodeBlock DINGBATS;
-    field public static final java.lang.Character.UnicodeBlock DOMINO_TILES;
-    field public static final java.lang.Character.UnicodeBlock EGYPTIAN_HIEROGLYPHS;
-    field public static final java.lang.Character.UnicodeBlock EMOTICONS;
-    field public static final java.lang.Character.UnicodeBlock ENCLOSED_ALPHANUMERICS;
-    field public static final java.lang.Character.UnicodeBlock ENCLOSED_ALPHANUMERIC_SUPPLEMENT;
-    field public static final java.lang.Character.UnicodeBlock ENCLOSED_CJK_LETTERS_AND_MONTHS;
-    field public static final java.lang.Character.UnicodeBlock ENCLOSED_IDEOGRAPHIC_SUPPLEMENT;
-    field public static final java.lang.Character.UnicodeBlock ETHIOPIC;
-    field public static final java.lang.Character.UnicodeBlock ETHIOPIC_EXTENDED;
-    field public static final java.lang.Character.UnicodeBlock ETHIOPIC_EXTENDED_A;
-    field public static final java.lang.Character.UnicodeBlock ETHIOPIC_SUPPLEMENT;
-    field public static final java.lang.Character.UnicodeBlock GENERAL_PUNCTUATION;
-    field public static final java.lang.Character.UnicodeBlock GEOMETRIC_SHAPES;
-    field public static final java.lang.Character.UnicodeBlock GEORGIAN;
-    field public static final java.lang.Character.UnicodeBlock GEORGIAN_SUPPLEMENT;
-    field public static final java.lang.Character.UnicodeBlock GLAGOLITIC;
-    field public static final java.lang.Character.UnicodeBlock GOTHIC;
-    field public static final java.lang.Character.UnicodeBlock GREEK;
-    field public static final java.lang.Character.UnicodeBlock GREEK_EXTENDED;
-    field public static final java.lang.Character.UnicodeBlock GUJARATI;
-    field public static final java.lang.Character.UnicodeBlock GURMUKHI;
-    field public static final java.lang.Character.UnicodeBlock HALFWIDTH_AND_FULLWIDTH_FORMS;
-    field public static final java.lang.Character.UnicodeBlock HANGUL_COMPATIBILITY_JAMO;
-    field public static final java.lang.Character.UnicodeBlock HANGUL_JAMO;
-    field public static final java.lang.Character.UnicodeBlock HANGUL_JAMO_EXTENDED_A;
-    field public static final java.lang.Character.UnicodeBlock HANGUL_JAMO_EXTENDED_B;
-    field public static final java.lang.Character.UnicodeBlock HANGUL_SYLLABLES;
-    field public static final java.lang.Character.UnicodeBlock HANUNOO;
-    field public static final java.lang.Character.UnicodeBlock HEBREW;
-    field public static final java.lang.Character.UnicodeBlock HIGH_PRIVATE_USE_SURROGATES;
-    field public static final java.lang.Character.UnicodeBlock HIGH_SURROGATES;
-    field public static final java.lang.Character.UnicodeBlock HIRAGANA;
-    field public static final java.lang.Character.UnicodeBlock IDEOGRAPHIC_DESCRIPTION_CHARACTERS;
-    field public static final java.lang.Character.UnicodeBlock IMPERIAL_ARAMAIC;
-    field public static final java.lang.Character.UnicodeBlock INSCRIPTIONAL_PAHLAVI;
-    field public static final java.lang.Character.UnicodeBlock INSCRIPTIONAL_PARTHIAN;
-    field public static final java.lang.Character.UnicodeBlock IPA_EXTENSIONS;
-    field public static final java.lang.Character.UnicodeBlock JAVANESE;
-    field public static final java.lang.Character.UnicodeBlock KAITHI;
-    field public static final java.lang.Character.UnicodeBlock KANA_SUPPLEMENT;
-    field public static final java.lang.Character.UnicodeBlock KANBUN;
-    field public static final java.lang.Character.UnicodeBlock KANGXI_RADICALS;
-    field public static final java.lang.Character.UnicodeBlock KANNADA;
-    field public static final java.lang.Character.UnicodeBlock KATAKANA;
-    field public static final java.lang.Character.UnicodeBlock KATAKANA_PHONETIC_EXTENSIONS;
-    field public static final java.lang.Character.UnicodeBlock KAYAH_LI;
-    field public static final java.lang.Character.UnicodeBlock KHAROSHTHI;
-    field public static final java.lang.Character.UnicodeBlock KHMER;
-    field public static final java.lang.Character.UnicodeBlock KHMER_SYMBOLS;
-    field public static final java.lang.Character.UnicodeBlock LAO;
-    field public static final java.lang.Character.UnicodeBlock LATIN_1_SUPPLEMENT;
-    field public static final java.lang.Character.UnicodeBlock LATIN_EXTENDED_A;
-    field public static final java.lang.Character.UnicodeBlock LATIN_EXTENDED_ADDITIONAL;
-    field public static final java.lang.Character.UnicodeBlock LATIN_EXTENDED_B;
-    field public static final java.lang.Character.UnicodeBlock LATIN_EXTENDED_C;
-    field public static final java.lang.Character.UnicodeBlock LATIN_EXTENDED_D;
-    field public static final java.lang.Character.UnicodeBlock LEPCHA;
-    field public static final java.lang.Character.UnicodeBlock LETTERLIKE_SYMBOLS;
-    field public static final java.lang.Character.UnicodeBlock LIMBU;
-    field public static final java.lang.Character.UnicodeBlock LINEAR_B_IDEOGRAMS;
-    field public static final java.lang.Character.UnicodeBlock LINEAR_B_SYLLABARY;
-    field public static final java.lang.Character.UnicodeBlock LISU;
-    field public static final java.lang.Character.UnicodeBlock LOW_SURROGATES;
-    field public static final java.lang.Character.UnicodeBlock LYCIAN;
-    field public static final java.lang.Character.UnicodeBlock LYDIAN;
-    field public static final java.lang.Character.UnicodeBlock MAHJONG_TILES;
-    field public static final java.lang.Character.UnicodeBlock MALAYALAM;
-    field public static final java.lang.Character.UnicodeBlock MANDAIC;
-    field public static final java.lang.Character.UnicodeBlock MATHEMATICAL_ALPHANUMERIC_SYMBOLS;
-    field public static final java.lang.Character.UnicodeBlock MATHEMATICAL_OPERATORS;
-    field public static final java.lang.Character.UnicodeBlock MEETEI_MAYEK;
-    field public static final java.lang.Character.UnicodeBlock MEETEI_MAYEK_EXTENSIONS;
-    field public static final java.lang.Character.UnicodeBlock MEROITIC_CURSIVE;
-    field public static final java.lang.Character.UnicodeBlock MEROITIC_HIEROGLYPHS;
-    field public static final java.lang.Character.UnicodeBlock MIAO;
-    field public static final java.lang.Character.UnicodeBlock MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A;
-    field public static final java.lang.Character.UnicodeBlock MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B;
-    field public static final java.lang.Character.UnicodeBlock MISCELLANEOUS_SYMBOLS;
-    field public static final java.lang.Character.UnicodeBlock MISCELLANEOUS_SYMBOLS_AND_ARROWS;
-    field public static final java.lang.Character.UnicodeBlock MISCELLANEOUS_SYMBOLS_AND_PICTOGRAPHS;
-    field public static final java.lang.Character.UnicodeBlock MISCELLANEOUS_TECHNICAL;
-    field public static final java.lang.Character.UnicodeBlock MODIFIER_TONE_LETTERS;
-    field public static final java.lang.Character.UnicodeBlock MONGOLIAN;
-    field public static final java.lang.Character.UnicodeBlock MUSICAL_SYMBOLS;
-    field public static final java.lang.Character.UnicodeBlock MYANMAR;
-    field public static final java.lang.Character.UnicodeBlock MYANMAR_EXTENDED_A;
-    field public static final java.lang.Character.UnicodeBlock NEW_TAI_LUE;
-    field public static final java.lang.Character.UnicodeBlock NKO;
-    field public static final java.lang.Character.UnicodeBlock NUMBER_FORMS;
-    field public static final java.lang.Character.UnicodeBlock OGHAM;
-    field public static final java.lang.Character.UnicodeBlock OLD_ITALIC;
-    field public static final java.lang.Character.UnicodeBlock OLD_PERSIAN;
-    field public static final java.lang.Character.UnicodeBlock OLD_SOUTH_ARABIAN;
-    field public static final java.lang.Character.UnicodeBlock OLD_TURKIC;
-    field public static final java.lang.Character.UnicodeBlock OL_CHIKI;
-    field public static final java.lang.Character.UnicodeBlock OPTICAL_CHARACTER_RECOGNITION;
-    field public static final java.lang.Character.UnicodeBlock ORIYA;
-    field public static final java.lang.Character.UnicodeBlock OSMANYA;
-    field public static final java.lang.Character.UnicodeBlock PHAGS_PA;
-    field public static final java.lang.Character.UnicodeBlock PHAISTOS_DISC;
-    field public static final java.lang.Character.UnicodeBlock PHOENICIAN;
-    field public static final java.lang.Character.UnicodeBlock PHONETIC_EXTENSIONS;
-    field public static final java.lang.Character.UnicodeBlock PHONETIC_EXTENSIONS_SUPPLEMENT;
-    field public static final java.lang.Character.UnicodeBlock PLAYING_CARDS;
-    field public static final java.lang.Character.UnicodeBlock PRIVATE_USE_AREA;
-    field public static final java.lang.Character.UnicodeBlock REJANG;
-    field public static final java.lang.Character.UnicodeBlock RUMI_NUMERAL_SYMBOLS;
-    field public static final java.lang.Character.UnicodeBlock RUNIC;
-    field public static final java.lang.Character.UnicodeBlock SAMARITAN;
-    field public static final java.lang.Character.UnicodeBlock SAURASHTRA;
-    field public static final java.lang.Character.UnicodeBlock SHARADA;
-    field public static final java.lang.Character.UnicodeBlock SHAVIAN;
-    field public static final java.lang.Character.UnicodeBlock SINHALA;
-    field public static final java.lang.Character.UnicodeBlock SMALL_FORM_VARIANTS;
-    field public static final java.lang.Character.UnicodeBlock SORA_SOMPENG;
-    field public static final java.lang.Character.UnicodeBlock SPACING_MODIFIER_LETTERS;
-    field public static final java.lang.Character.UnicodeBlock SPECIALS;
-    field public static final java.lang.Character.UnicodeBlock SUNDANESE;
-    field public static final java.lang.Character.UnicodeBlock SUNDANESE_SUPPLEMENT;
-    field public static final java.lang.Character.UnicodeBlock SUPERSCRIPTS_AND_SUBSCRIPTS;
-    field public static final java.lang.Character.UnicodeBlock SUPPLEMENTAL_ARROWS_A;
-    field public static final java.lang.Character.UnicodeBlock SUPPLEMENTAL_ARROWS_B;
-    field public static final java.lang.Character.UnicodeBlock SUPPLEMENTAL_MATHEMATICAL_OPERATORS;
-    field public static final java.lang.Character.UnicodeBlock SUPPLEMENTAL_PUNCTUATION;
-    field public static final java.lang.Character.UnicodeBlock SUPPLEMENTARY_PRIVATE_USE_AREA_A;
-    field public static final java.lang.Character.UnicodeBlock SUPPLEMENTARY_PRIVATE_USE_AREA_B;
-    field @Deprecated public static final java.lang.Character.UnicodeBlock SURROGATES_AREA;
-    field public static final java.lang.Character.UnicodeBlock SYLOTI_NAGRI;
-    field public static final java.lang.Character.UnicodeBlock SYRIAC;
-    field public static final java.lang.Character.UnicodeBlock TAGALOG;
-    field public static final java.lang.Character.UnicodeBlock TAGBANWA;
-    field public static final java.lang.Character.UnicodeBlock TAGS;
-    field public static final java.lang.Character.UnicodeBlock TAI_LE;
-    field public static final java.lang.Character.UnicodeBlock TAI_THAM;
-    field public static final java.lang.Character.UnicodeBlock TAI_VIET;
-    field public static final java.lang.Character.UnicodeBlock TAI_XUAN_JING_SYMBOLS;
-    field public static final java.lang.Character.UnicodeBlock TAKRI;
-    field public static final java.lang.Character.UnicodeBlock TAMIL;
-    field public static final java.lang.Character.UnicodeBlock TELUGU;
-    field public static final java.lang.Character.UnicodeBlock THAANA;
-    field public static final java.lang.Character.UnicodeBlock THAI;
-    field public static final java.lang.Character.UnicodeBlock TIBETAN;
-    field public static final java.lang.Character.UnicodeBlock TIFINAGH;
-    field public static final java.lang.Character.UnicodeBlock TRANSPORT_AND_MAP_SYMBOLS;
-    field public static final java.lang.Character.UnicodeBlock UGARITIC;
-    field public static final java.lang.Character.UnicodeBlock UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS;
-    field public static final java.lang.Character.UnicodeBlock UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS_EXTENDED;
-    field public static final java.lang.Character.UnicodeBlock VAI;
-    field public static final java.lang.Character.UnicodeBlock VARIATION_SELECTORS;
-    field public static final java.lang.Character.UnicodeBlock VARIATION_SELECTORS_SUPPLEMENT;
-    field public static final java.lang.Character.UnicodeBlock VEDIC_EXTENSIONS;
-    field public static final java.lang.Character.UnicodeBlock VERTICAL_FORMS;
-    field public static final java.lang.Character.UnicodeBlock YIJING_HEXAGRAM_SYMBOLS;
-    field public static final java.lang.Character.UnicodeBlock YI_RADICALS;
-    field public static final java.lang.Character.UnicodeBlock YI_SYLLABLES;
-  }
-
-  public enum Character.UnicodeScript {
-    method @NonNull public static java.lang.Character.UnicodeScript forName(@NonNull String);
-    method @NonNull public static java.lang.Character.UnicodeScript of(int);
-    enum_constant public static final java.lang.Character.UnicodeScript ARABIC;
-    enum_constant public static final java.lang.Character.UnicodeScript ARMENIAN;
-    enum_constant public static final java.lang.Character.UnicodeScript AVESTAN;
-    enum_constant public static final java.lang.Character.UnicodeScript BALINESE;
-    enum_constant public static final java.lang.Character.UnicodeScript BAMUM;
-    enum_constant public static final java.lang.Character.UnicodeScript BATAK;
-    enum_constant public static final java.lang.Character.UnicodeScript BENGALI;
-    enum_constant public static final java.lang.Character.UnicodeScript BOPOMOFO;
-    enum_constant public static final java.lang.Character.UnicodeScript BRAHMI;
-    enum_constant public static final java.lang.Character.UnicodeScript BRAILLE;
-    enum_constant public static final java.lang.Character.UnicodeScript BUGINESE;
-    enum_constant public static final java.lang.Character.UnicodeScript BUHID;
-    enum_constant public static final java.lang.Character.UnicodeScript CANADIAN_ABORIGINAL;
-    enum_constant public static final java.lang.Character.UnicodeScript CARIAN;
-    enum_constant public static final java.lang.Character.UnicodeScript CHAKMA;
-    enum_constant public static final java.lang.Character.UnicodeScript CHAM;
-    enum_constant public static final java.lang.Character.UnicodeScript CHEROKEE;
-    enum_constant public static final java.lang.Character.UnicodeScript COMMON;
-    enum_constant public static final java.lang.Character.UnicodeScript COPTIC;
-    enum_constant public static final java.lang.Character.UnicodeScript CUNEIFORM;
-    enum_constant public static final java.lang.Character.UnicodeScript CYPRIOT;
-    enum_constant public static final java.lang.Character.UnicodeScript CYRILLIC;
-    enum_constant public static final java.lang.Character.UnicodeScript DESERET;
-    enum_constant public static final java.lang.Character.UnicodeScript DEVANAGARI;
-    enum_constant public static final java.lang.Character.UnicodeScript EGYPTIAN_HIEROGLYPHS;
-    enum_constant public static final java.lang.Character.UnicodeScript ETHIOPIC;
-    enum_constant public static final java.lang.Character.UnicodeScript GEORGIAN;
-    enum_constant public static final java.lang.Character.UnicodeScript GLAGOLITIC;
-    enum_constant public static final java.lang.Character.UnicodeScript GOTHIC;
-    enum_constant public static final java.lang.Character.UnicodeScript GREEK;
-    enum_constant public static final java.lang.Character.UnicodeScript GUJARATI;
-    enum_constant public static final java.lang.Character.UnicodeScript GURMUKHI;
-    enum_constant public static final java.lang.Character.UnicodeScript HAN;
-    enum_constant public static final java.lang.Character.UnicodeScript HANGUL;
-    enum_constant public static final java.lang.Character.UnicodeScript HANUNOO;
-    enum_constant public static final java.lang.Character.UnicodeScript HEBREW;
-    enum_constant public static final java.lang.Character.UnicodeScript HIRAGANA;
-    enum_constant public static final java.lang.Character.UnicodeScript IMPERIAL_ARAMAIC;
-    enum_constant public static final java.lang.Character.UnicodeScript INHERITED;
-    enum_constant public static final java.lang.Character.UnicodeScript INSCRIPTIONAL_PAHLAVI;
-    enum_constant public static final java.lang.Character.UnicodeScript INSCRIPTIONAL_PARTHIAN;
-    enum_constant public static final java.lang.Character.UnicodeScript JAVANESE;
-    enum_constant public static final java.lang.Character.UnicodeScript KAITHI;
-    enum_constant public static final java.lang.Character.UnicodeScript KANNADA;
-    enum_constant public static final java.lang.Character.UnicodeScript KATAKANA;
-    enum_constant public static final java.lang.Character.UnicodeScript KAYAH_LI;
-    enum_constant public static final java.lang.Character.UnicodeScript KHAROSHTHI;
-    enum_constant public static final java.lang.Character.UnicodeScript KHMER;
-    enum_constant public static final java.lang.Character.UnicodeScript LAO;
-    enum_constant public static final java.lang.Character.UnicodeScript LATIN;
-    enum_constant public static final java.lang.Character.UnicodeScript LEPCHA;
-    enum_constant public static final java.lang.Character.UnicodeScript LIMBU;
-    enum_constant public static final java.lang.Character.UnicodeScript LINEAR_B;
-    enum_constant public static final java.lang.Character.UnicodeScript LISU;
-    enum_constant public static final java.lang.Character.UnicodeScript LYCIAN;
-    enum_constant public static final java.lang.Character.UnicodeScript LYDIAN;
-    enum_constant public static final java.lang.Character.UnicodeScript MALAYALAM;
-    enum_constant public static final java.lang.Character.UnicodeScript MANDAIC;
-    enum_constant public static final java.lang.Character.UnicodeScript MEETEI_MAYEK;
-    enum_constant public static final java.lang.Character.UnicodeScript MEROITIC_CURSIVE;
-    enum_constant public static final java.lang.Character.UnicodeScript MEROITIC_HIEROGLYPHS;
-    enum_constant public static final java.lang.Character.UnicodeScript MIAO;
-    enum_constant public static final java.lang.Character.UnicodeScript MONGOLIAN;
-    enum_constant public static final java.lang.Character.UnicodeScript MYANMAR;
-    enum_constant public static final java.lang.Character.UnicodeScript NEW_TAI_LUE;
-    enum_constant public static final java.lang.Character.UnicodeScript NKO;
-    enum_constant public static final java.lang.Character.UnicodeScript OGHAM;
-    enum_constant public static final java.lang.Character.UnicodeScript OLD_ITALIC;
-    enum_constant public static final java.lang.Character.UnicodeScript OLD_PERSIAN;
-    enum_constant public static final java.lang.Character.UnicodeScript OLD_SOUTH_ARABIAN;
-    enum_constant public static final java.lang.Character.UnicodeScript OLD_TURKIC;
-    enum_constant public static final java.lang.Character.UnicodeScript OL_CHIKI;
-    enum_constant public static final java.lang.Character.UnicodeScript ORIYA;
-    enum_constant public static final java.lang.Character.UnicodeScript OSMANYA;
-    enum_constant public static final java.lang.Character.UnicodeScript PHAGS_PA;
-    enum_constant public static final java.lang.Character.UnicodeScript PHOENICIAN;
-    enum_constant public static final java.lang.Character.UnicodeScript REJANG;
-    enum_constant public static final java.lang.Character.UnicodeScript RUNIC;
-    enum_constant public static final java.lang.Character.UnicodeScript SAMARITAN;
-    enum_constant public static final java.lang.Character.UnicodeScript SAURASHTRA;
-    enum_constant public static final java.lang.Character.UnicodeScript SHARADA;
-    enum_constant public static final java.lang.Character.UnicodeScript SHAVIAN;
-    enum_constant public static final java.lang.Character.UnicodeScript SINHALA;
-    enum_constant public static final java.lang.Character.UnicodeScript SORA_SOMPENG;
-    enum_constant public static final java.lang.Character.UnicodeScript SUNDANESE;
-    enum_constant public static final java.lang.Character.UnicodeScript SYLOTI_NAGRI;
-    enum_constant public static final java.lang.Character.UnicodeScript SYRIAC;
-    enum_constant public static final java.lang.Character.UnicodeScript TAGALOG;
-    enum_constant public static final java.lang.Character.UnicodeScript TAGBANWA;
-    enum_constant public static final java.lang.Character.UnicodeScript TAI_LE;
-    enum_constant public static final java.lang.Character.UnicodeScript TAI_THAM;
-    enum_constant public static final java.lang.Character.UnicodeScript TAI_VIET;
-    enum_constant public static final java.lang.Character.UnicodeScript TAKRI;
-    enum_constant public static final java.lang.Character.UnicodeScript TAMIL;
-    enum_constant public static final java.lang.Character.UnicodeScript TELUGU;
-    enum_constant public static final java.lang.Character.UnicodeScript THAANA;
-    enum_constant public static final java.lang.Character.UnicodeScript THAI;
-    enum_constant public static final java.lang.Character.UnicodeScript TIBETAN;
-    enum_constant public static final java.lang.Character.UnicodeScript TIFINAGH;
-    enum_constant public static final java.lang.Character.UnicodeScript UGARITIC;
-    enum_constant public static final java.lang.Character.UnicodeScript UNKNOWN;
-    enum_constant public static final java.lang.Character.UnicodeScript VAI;
-    enum_constant public static final java.lang.Character.UnicodeScript YI;
-  }
-
-  public final class Class<T> implements java.lang.reflect.AnnotatedElement java.lang.reflect.GenericDeclaration java.io.Serializable java.lang.reflect.Type {
-    method @NonNull public <U> Class<? extends U> asSubclass(@NonNull Class<U>);
-    method @Nullable public T cast(@Nullable Object);
-    method public boolean desiredAssertionStatus();
-    method @NonNull public static Class<?> forName(@NonNull String) throws java.lang.ClassNotFoundException;
-    method @NonNull public static Class<?> forName(@NonNull String, boolean, @Nullable ClassLoader) throws java.lang.ClassNotFoundException;
-    method @Nullable public <A extends java.lang.annotation.Annotation> A getAnnotation(@NonNull Class<A>);
-    method @NonNull public java.lang.annotation.Annotation[] getAnnotations();
-    method @NonNull public <A extends java.lang.annotation.Annotation> A[] getAnnotationsByType(@NonNull Class<A>);
-    method @Nullable public String getCanonicalName();
-    method @Nullable public ClassLoader getClassLoader();
-    method @NonNull public Class<?>[] getClasses();
-    method @Nullable public Class<?> getComponentType();
-    method @NonNull public java.lang.reflect.Constructor<T> getConstructor(@Nullable Class<?>...) throws java.lang.NoSuchMethodException, java.lang.SecurityException;
-    method @NonNull public java.lang.reflect.Constructor<?>[] getConstructors() throws java.lang.SecurityException;
-    method @Nullable public <A extends java.lang.annotation.Annotation> A getDeclaredAnnotation(@NonNull Class<A>);
-    method @NonNull public java.lang.annotation.Annotation[] getDeclaredAnnotations();
-    method @NonNull public Class<?>[] getDeclaredClasses();
-    method @NonNull public java.lang.reflect.Constructor<T> getDeclaredConstructor(@Nullable Class<?>...) throws java.lang.NoSuchMethodException, java.lang.SecurityException;
-    method @NonNull public java.lang.reflect.Constructor<?>[] getDeclaredConstructors() throws java.lang.SecurityException;
-    method @NonNull public java.lang.reflect.Field getDeclaredField(@NonNull String) throws java.lang.NoSuchFieldException;
-    method @NonNull public java.lang.reflect.Field[] getDeclaredFields();
-    method @NonNull public java.lang.reflect.Method getDeclaredMethod(@NonNull String, @Nullable Class<?>...) throws java.lang.NoSuchMethodException, java.lang.SecurityException;
-    method @NonNull public java.lang.reflect.Method[] getDeclaredMethods() throws java.lang.SecurityException;
-    method @Nullable public Class<?> getDeclaringClass();
-    method @Nullable public Class<?> getEnclosingClass();
-    method @Nullable public java.lang.reflect.Constructor<?> getEnclosingConstructor();
-    method @Nullable public java.lang.reflect.Method getEnclosingMethod();
-    method @Nullable public T[] getEnumConstants();
-    method @NonNull public java.lang.reflect.Field getField(@NonNull String) throws java.lang.NoSuchFieldException;
-    method @NonNull public java.lang.reflect.Field[] getFields() throws java.lang.SecurityException;
-    method @NonNull public java.lang.reflect.Type[] getGenericInterfaces();
-    method @Nullable public java.lang.reflect.Type getGenericSuperclass();
-    method @NonNull public Class<?>[] getInterfaces();
-    method @NonNull public java.lang.reflect.Method getMethod(@NonNull String, @Nullable Class<?>...) throws java.lang.NoSuchMethodException, java.lang.SecurityException;
-    method @NonNull public java.lang.reflect.Method[] getMethods() throws java.lang.SecurityException;
-    method public int getModifiers();
-    method @NonNull public String getName();
-    method @Nullable public Package getPackage();
-    method @NonNull public String getPackageName();
-    method @Nullable public java.security.ProtectionDomain getProtectionDomain();
-    method @Nullable public java.net.URL getResource(@NonNull String);
-    method @Nullable public java.io.InputStream getResourceAsStream(@NonNull String);
-    method @Nullable public Object[] getSigners();
-    method @NonNull public String getSimpleName();
-    method @Nullable public Class<? super T> getSuperclass();
-    method @NonNull public java.lang.reflect.TypeVariable<java.lang.Class<T>>[] getTypeParameters();
-    method public boolean isAnnotation();
-    method public boolean isAnonymousClass();
-    method public boolean isArray();
-    method public boolean isAssignableFrom(@NonNull Class<?>);
-    method public boolean isEnum();
-    method public boolean isInstance(@Nullable Object);
-    method public boolean isInterface();
-    method public boolean isLocalClass();
-    method public boolean isMemberClass();
-    method public boolean isPrimitive();
-    method public boolean isSynthetic();
-    method @NonNull public T newInstance() throws java.lang.IllegalAccessException, java.lang.InstantiationException;
-    method @NonNull public String toGenericString();
-  }
-
-  public class ClassCastException extends java.lang.RuntimeException {
-    ctor public ClassCastException();
-    ctor public ClassCastException(String);
-  }
-
-  public class ClassCircularityError extends java.lang.LinkageError {
-    ctor public ClassCircularityError();
-    ctor public ClassCircularityError(String);
-  }
-
-  public class ClassFormatError extends java.lang.LinkageError {
-    ctor public ClassFormatError();
-    ctor public ClassFormatError(String);
-  }
-
-  public abstract class ClassLoader {
-    ctor protected ClassLoader(ClassLoader);
-    ctor protected ClassLoader();
-    method public void clearAssertionStatus();
-    method @Deprecated protected final Class<?> defineClass(byte[], int, int) throws java.lang.ClassFormatError;
-    method protected final Class<?> defineClass(String, byte[], int, int) throws java.lang.ClassFormatError;
-    method protected final Class<?> defineClass(String, byte[], int, int, java.security.ProtectionDomain) throws java.lang.ClassFormatError;
-    method protected final Class<?> defineClass(String, java.nio.ByteBuffer, java.security.ProtectionDomain) throws java.lang.ClassFormatError;
-    method protected Package definePackage(String, String, String, String, String, String, String, java.net.URL) throws java.lang.IllegalArgumentException;
-    method protected Class<?> findClass(String) throws java.lang.ClassNotFoundException;
-    method protected String findLibrary(String);
-    method protected final Class<?> findLoadedClass(String);
-    method protected java.net.URL findResource(String);
-    method protected java.util.Enumeration<java.net.URL> findResources(String) throws java.io.IOException;
-    method protected final Class<?> findSystemClass(String) throws java.lang.ClassNotFoundException;
-    method protected Package getPackage(String);
-    method protected Package[] getPackages();
-    method public final ClassLoader getParent();
-    method public java.net.URL getResource(String);
-    method public java.io.InputStream getResourceAsStream(String);
-    method public java.util.Enumeration<java.net.URL> getResources(String) throws java.io.IOException;
-    method public static ClassLoader getSystemClassLoader();
-    method public static java.net.URL getSystemResource(String);
-    method public static java.io.InputStream getSystemResourceAsStream(String);
-    method public static java.util.Enumeration<java.net.URL> getSystemResources(String) throws java.io.IOException;
-    method public Class<?> loadClass(String) throws java.lang.ClassNotFoundException;
-    method protected Class<?> loadClass(String, boolean) throws java.lang.ClassNotFoundException;
-    method protected static boolean registerAsParallelCapable();
-    method protected final void resolveClass(Class<?>);
-    method public void setClassAssertionStatus(String, boolean);
-    method public void setDefaultAssertionStatus(boolean);
-    method public void setPackageAssertionStatus(String, boolean);
-    method protected final void setSigners(Class<?>, Object[]);
-  }
-
-  public class ClassNotFoundException extends java.lang.ReflectiveOperationException {
-    ctor public ClassNotFoundException();
-    ctor public ClassNotFoundException(String);
-    ctor public ClassNotFoundException(String, Throwable);
-    method public Throwable getException();
-  }
-
-  public class CloneNotSupportedException extends java.lang.Exception {
-    ctor public CloneNotSupportedException();
-    ctor public CloneNotSupportedException(String);
-  }
-
-  public interface Cloneable {
-  }
-
-  public interface Comparable<T> {
-    method public int compareTo(T);
-  }
-
-  public final class Compiler {
-    method public static Object command(Object);
-    method public static boolean compileClass(Class<?>);
-    method public static boolean compileClasses(String);
-    method public static void disable();
-    method public static void enable();
-  }
-
-  @java.lang.annotation.Documented @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Target({java.lang.annotation.ElementType.CONSTRUCTOR, java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.LOCAL_VARIABLE, java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.PACKAGE, java.lang.annotation.ElementType.PARAMETER, java.lang.annotation.ElementType.TYPE}) public @interface Deprecated {
-  }
-
-  public final class Double extends java.lang.Number implements java.lang.Comparable<java.lang.Double> {
-    ctor public Double(double);
-    ctor public Double(@NonNull String) throws java.lang.NumberFormatException;
-    method public static int compare(double, double);
-    method public int compareTo(@NonNull Double);
-    method public static long doubleToLongBits(double);
-    method public static long doubleToRawLongBits(double);
-    method public double doubleValue();
-    method public float floatValue();
-    method public static int hashCode(double);
-    method public int intValue();
-    method public static boolean isFinite(double);
-    method public static boolean isInfinite(double);
-    method public boolean isInfinite();
-    method public static boolean isNaN(double);
-    method public boolean isNaN();
-    method public static double longBitsToDouble(long);
-    method public long longValue();
-    method public static double max(double, double);
-    method public static double min(double, double);
-    method public static double parseDouble(@NonNull String) throws java.lang.NumberFormatException;
-    method public static double sum(double, double);
-    method @NonNull public static String toHexString(double);
-    method @NonNull public static String toString(double);
-    method @NonNull public static Double valueOf(@NonNull String) throws java.lang.NumberFormatException;
-    method @NonNull public static Double valueOf(double);
-    field public static final int BYTES = 8; // 0x8
-    field public static final int MAX_EXPONENT = 1023; // 0x3ff
-    field public static final double MAX_VALUE = 1.7976931348623157E308;
-    field public static final int MIN_EXPONENT = -1022; // 0xfffffc02
-    field public static final double MIN_NORMAL = 2.2250738585072014E-308;
-    field public static final double MIN_VALUE = 4.9E-324;
-    field public static final double NEGATIVE_INFINITY = (-1.0/0.0);
-    field public static final double NaN = (0.0/0.0);
-    field public static final double POSITIVE_INFINITY = (1.0/0.0);
-    field public static final int SIZE = 64; // 0x40
-    field public static final Class<java.lang.Double> TYPE;
-  }
-
-  public abstract class Enum<E extends java.lang.Enum<E>> implements java.lang.Comparable<E> java.io.Serializable {
-    ctor protected Enum(@NonNull String, int);
-    method @NonNull protected final Object clone() throws java.lang.CloneNotSupportedException;
-    method public final int compareTo(E);
-    method public final boolean equals(@Nullable Object);
-    method protected final void finalize();
-    method @NonNull public final Class<E> getDeclaringClass();
-    method public final int hashCode();
-    method @NonNull public final String name();
-    method public final int ordinal();
-    method @NonNull public static <T extends java.lang.Enum<T>> T valueOf(@NonNull Class<T>, @NonNull String);
-  }
-
-  public class EnumConstantNotPresentException extends java.lang.RuntimeException {
-    ctor public EnumConstantNotPresentException(Class<? extends java.lang.Enum>, String);
-    method public String constantName();
-    method public Class<? extends java.lang.Enum> enumType();
-  }
-
-  public class Error extends java.lang.Throwable {
-    ctor public Error();
-    ctor public Error(String);
-    ctor public Error(String, Throwable);
-    ctor public Error(Throwable);
-    ctor protected Error(String, Throwable, boolean, boolean);
-  }
-
-  public class Exception extends java.lang.Throwable {
-    ctor public Exception();
-    ctor public Exception(String);
-    ctor public Exception(String, Throwable);
-    ctor public Exception(Throwable);
-    ctor protected Exception(String, Throwable, boolean, boolean);
-  }
-
-  public class ExceptionInInitializerError extends java.lang.LinkageError {
-    ctor public ExceptionInInitializerError();
-    ctor public ExceptionInInitializerError(Throwable);
-    ctor public ExceptionInInitializerError(String);
-    method public Throwable getException();
-  }
-
-  public final class Float extends java.lang.Number implements java.lang.Comparable<java.lang.Float> {
-    ctor public Float(float);
-    ctor public Float(double);
-    ctor public Float(@NonNull String) throws java.lang.NumberFormatException;
-    method public static int compare(float, float);
-    method public int compareTo(@NonNull Float);
-    method public double doubleValue();
-    method public static int floatToIntBits(float);
-    method public static int floatToRawIntBits(float);
-    method public float floatValue();
-    method public static int hashCode(float);
-    method public static float intBitsToFloat(int);
-    method public int intValue();
-    method public static boolean isFinite(float);
-    method public static boolean isInfinite(float);
-    method public boolean isInfinite();
-    method public static boolean isNaN(float);
-    method public boolean isNaN();
-    method public long longValue();
-    method public static float max(float, float);
-    method public static float min(float, float);
-    method public static float parseFloat(@NonNull String) throws java.lang.NumberFormatException;
-    method public static float sum(float, float);
-    method @NonNull public static String toHexString(float);
-    method @NonNull public static String toString(float);
-    method @NonNull public static Float valueOf(@NonNull String) throws java.lang.NumberFormatException;
-    method @NonNull public static Float valueOf(float);
-    field public static final int BYTES = 4; // 0x4
-    field public static final int MAX_EXPONENT = 127; // 0x7f
-    field public static final float MAX_VALUE = 3.4028235E38f;
-    field public static final int MIN_EXPONENT = -126; // 0xffffff82
-    field public static final float MIN_NORMAL = 1.17549435E-38f;
-    field public static final float MIN_VALUE = 1.4E-45f;
-    field public static final float NEGATIVE_INFINITY = (-1.0f/0.0f);
-    field public static final float NaN = (0.0f/0.0f);
-    field public static final float POSITIVE_INFINITY = (1.0f/0.0f);
-    field public static final int SIZE = 32; // 0x20
-    field public static final Class<java.lang.Float> TYPE;
-  }
-
-  @java.lang.annotation.Documented @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public @interface FunctionalInterface {
-  }
-
-  public class IllegalAccessError extends java.lang.IncompatibleClassChangeError {
-    ctor public IllegalAccessError();
-    ctor public IllegalAccessError(String);
-  }
-
-  public class IllegalAccessException extends java.lang.ReflectiveOperationException {
-    ctor public IllegalAccessException();
-    ctor public IllegalAccessException(String);
-  }
-
-  public class IllegalArgumentException extends java.lang.RuntimeException {
-    ctor public IllegalArgumentException();
-    ctor public IllegalArgumentException(String);
-    ctor public IllegalArgumentException(String, Throwable);
-    ctor public IllegalArgumentException(Throwable);
-  }
-
-  public class IllegalMonitorStateException extends java.lang.RuntimeException {
-    ctor public IllegalMonitorStateException();
-    ctor public IllegalMonitorStateException(String);
-  }
-
-  public class IllegalStateException extends java.lang.RuntimeException {
-    ctor public IllegalStateException();
-    ctor public IllegalStateException(String);
-    ctor public IllegalStateException(String, Throwable);
-    ctor public IllegalStateException(Throwable);
-  }
-
-  public class IllegalThreadStateException extends java.lang.IllegalArgumentException {
-    ctor public IllegalThreadStateException();
-    ctor public IllegalThreadStateException(String);
-  }
-
-  public class IncompatibleClassChangeError extends java.lang.LinkageError {
-    ctor public IncompatibleClassChangeError();
-    ctor public IncompatibleClassChangeError(String);
-  }
-
-  public class IndexOutOfBoundsException extends java.lang.RuntimeException {
-    ctor public IndexOutOfBoundsException();
-    ctor public IndexOutOfBoundsException(String);
-  }
-
-  public class InheritableThreadLocal<T> extends java.lang.ThreadLocal<T> {
-    ctor public InheritableThreadLocal();
-    method protected T childValue(T);
-  }
-
-  public class InstantiationError extends java.lang.IncompatibleClassChangeError {
-    ctor public InstantiationError();
-    ctor public InstantiationError(String);
-  }
-
-  public class InstantiationException extends java.lang.ReflectiveOperationException {
-    ctor public InstantiationException();
-    ctor public InstantiationException(String);
-  }
-
-  public final class Integer extends java.lang.Number implements java.lang.Comparable<java.lang.Integer> {
-    ctor public Integer(int);
-    ctor public Integer(@NonNull String) throws java.lang.NumberFormatException;
-    method public static int bitCount(int);
-    method public static int compare(int, int);
-    method public int compareTo(@NonNull Integer);
-    method public static int compareUnsigned(int, int);
-    method @NonNull public static Integer decode(@NonNull String) throws java.lang.NumberFormatException;
-    method public static int divideUnsigned(int, int);
-    method public double doubleValue();
-    method public float floatValue();
-    method @Nullable public static Integer getInteger(@NonNull String);
-    method @Nullable public static Integer getInteger(@NonNull String, int);
-    method @Nullable public static Integer getInteger(@NonNull String, @Nullable Integer);
-    method public static int hashCode(int);
-    method public static int highestOneBit(int);
-    method public int intValue();
-    method public long longValue();
-    method public static int lowestOneBit(int);
-    method public static int max(int, int);
-    method public static int min(int, int);
-    method public static int numberOfLeadingZeros(int);
-    method public static int numberOfTrailingZeros(int);
-    method public static int parseInt(@NonNull String, int) throws java.lang.NumberFormatException;
-    method public static int parseInt(@NonNull String) throws java.lang.NumberFormatException;
-    method public static int parseUnsignedInt(@NonNull String, int) throws java.lang.NumberFormatException;
-    method public static int parseUnsignedInt(@NonNull String) throws java.lang.NumberFormatException;
-    method public static int remainderUnsigned(int, int);
-    method public static int reverse(int);
-    method public static int reverseBytes(int);
-    method public static int rotateLeft(int, int);
-    method public static int rotateRight(int, int);
-    method public static int signum(int);
-    method public static int sum(int, int);
-    method @NonNull public static String toBinaryString(int);
-    method @NonNull public static String toHexString(int);
-    method @NonNull public static String toOctalString(int);
-    method @NonNull public static String toString(int, int);
-    method @NonNull public static String toString(int);
-    method public static long toUnsignedLong(int);
-    method @NonNull public static String toUnsignedString(int, int);
-    method @NonNull public static String toUnsignedString(int);
-    method @NonNull public static Integer valueOf(@NonNull String, int) throws java.lang.NumberFormatException;
-    method @NonNull public static Integer valueOf(@NonNull String) throws java.lang.NumberFormatException;
-    method @NonNull public static Integer valueOf(int);
-    field public static final int BYTES = 4; // 0x4
-    field public static final int MAX_VALUE = 2147483647; // 0x7fffffff
-    field public static final int MIN_VALUE = -2147483648; // 0x80000000
-    field public static final int SIZE = 32; // 0x20
-    field public static final Class<java.lang.Integer> TYPE;
-  }
-
-  public class InternalError extends java.lang.VirtualMachineError {
-    ctor public InternalError();
-    ctor public InternalError(String);
-    ctor public InternalError(String, Throwable);
-    ctor public InternalError(Throwable);
-  }
-
-  public class InterruptedException extends java.lang.Exception {
-    ctor public InterruptedException();
-    ctor public InterruptedException(String);
-  }
-
-  public interface Iterable<T> {
-    method public default void forEach(@NonNull java.util.function.Consumer<? super T>);
-    method @NonNull public java.util.Iterator<T> iterator();
-    method @NonNull public default java.util.Spliterator<T> spliterator();
-  }
-
-  public class LinkageError extends java.lang.Error {
-    ctor public LinkageError();
-    ctor public LinkageError(String);
-    ctor public LinkageError(String, Throwable);
-  }
-
-  public final class Long extends java.lang.Number implements java.lang.Comparable<java.lang.Long> {
-    ctor public Long(long);
-    ctor public Long(@NonNull String) throws java.lang.NumberFormatException;
-    method public static int bitCount(long);
-    method public static int compare(long, long);
-    method public int compareTo(@NonNull Long);
-    method public static int compareUnsigned(long, long);
-    method @NonNull public static Long decode(@NonNull String) throws java.lang.NumberFormatException;
-    method public static long divideUnsigned(long, long);
-    method public double doubleValue();
-    method public float floatValue();
-    method @Nullable public static Long getLong(@NonNull String);
-    method @Nullable public static Long getLong(@NonNull String, long);
-    method @Nullable public static Long getLong(@NonNull String, @Nullable Long);
-    method public static int hashCode(long);
-    method public static long highestOneBit(long);
-    method public int intValue();
-    method public long longValue();
-    method public static long lowestOneBit(long);
-    method public static long max(long, long);
-    method public static long min(long, long);
-    method public static int numberOfLeadingZeros(long);
-    method public static int numberOfTrailingZeros(long);
-    method public static long parseLong(@NonNull String, int) throws java.lang.NumberFormatException;
-    method public static long parseLong(@NonNull String) throws java.lang.NumberFormatException;
-    method public static long parseUnsignedLong(@NonNull String, int) throws java.lang.NumberFormatException;
-    method public static long parseUnsignedLong(@NonNull String) throws java.lang.NumberFormatException;
-    method public static long remainderUnsigned(long, long);
-    method public static long reverse(long);
-    method public static long reverseBytes(long);
-    method public static long rotateLeft(long, int);
-    method public static long rotateRight(long, int);
-    method public static int signum(long);
-    method public static long sum(long, long);
-    method @NonNull public static String toBinaryString(long);
-    method @NonNull public static String toHexString(long);
-    method @NonNull public static String toOctalString(long);
-    method @NonNull public static String toString(long, int);
-    method @NonNull public static String toString(long);
-    method @NonNull public static String toUnsignedString(long, int);
-    method @NonNull public static String toUnsignedString(long);
-    method @NonNull public static Long valueOf(@NonNull String, int) throws java.lang.NumberFormatException;
-    method @NonNull public static Long valueOf(@NonNull String) throws java.lang.NumberFormatException;
-    method @NonNull public static Long valueOf(long);
-    field public static final int BYTES = 8; // 0x8
-    field public static final long MAX_VALUE = 9223372036854775807L; // 0x7fffffffffffffffL
-    field public static final long MIN_VALUE = -9223372036854775808L; // 0x8000000000000000L
-    field public static final int SIZE = 64; // 0x40
-    field public static final Class<java.lang.Long> TYPE;
-  }
-
-  public final class Math {
-    method public static double IEEEremainder(double, double);
-    method public static int abs(int);
-    method public static long abs(long);
-    method public static float abs(float);
-    method public static double abs(double);
-    method public static double acos(double);
-    method public static int addExact(int, int);
-    method public static long addExact(long, long);
-    method public static double asin(double);
-    method public static double atan(double);
-    method public static double atan2(double, double);
-    method public static double cbrt(double);
-    method public static double ceil(double);
-    method public static double copySign(double, double);
-    method public static float copySign(float, float);
-    method public static double cos(double);
-    method public static double cosh(double);
-    method public static int decrementExact(int);
-    method public static long decrementExact(long);
-    method public static double exp(double);
-    method public static double expm1(double);
-    method public static double floor(double);
-    method public static int floorDiv(int, int);
-    method public static long floorDiv(long, long);
-    method public static int floorMod(int, int);
-    method public static long floorMod(long, long);
-    method public static int getExponent(float);
-    method public static int getExponent(double);
-    method public static double hypot(double, double);
-    method public static int incrementExact(int);
-    method public static long incrementExact(long);
-    method public static double log(double);
-    method public static double log10(double);
-    method public static double log1p(double);
-    method public static int max(int, int);
-    method public static long max(long, long);
-    method public static float max(float, float);
-    method public static double max(double, double);
-    method public static int min(int, int);
-    method public static long min(long, long);
-    method public static float min(float, float);
-    method public static double min(double, double);
-    method public static int multiplyExact(int, int);
-    method public static long multiplyExact(long, long);
-    method public static int negateExact(int);
-    method public static long negateExact(long);
-    method public static double nextAfter(double, double);
-    method public static float nextAfter(float, double);
-    method public static double nextDown(double);
-    method public static float nextDown(float);
-    method public static double nextUp(double);
-    method public static float nextUp(float);
-    method public static double pow(double, double);
-    method public static double random();
-    method public static double rint(double);
-    method public static int round(float);
-    method public static long round(double);
-    method public static double scalb(double, int);
-    method public static float scalb(float, int);
-    method public static double signum(double);
-    method public static float signum(float);
-    method public static double sin(double);
-    method public static double sinh(double);
-    method public static double sqrt(double);
-    method public static int subtractExact(int, int);
-    method public static long subtractExact(long, long);
-    method public static double tan(double);
-    method public static double tanh(double);
-    method public static double toDegrees(double);
-    method public static int toIntExact(long);
-    method public static double toRadians(double);
-    method public static double ulp(double);
-    method public static float ulp(float);
-    field public static final double E = 2.718281828459045;
-    field public static final double PI = 3.141592653589793;
-  }
-
-  public class NegativeArraySizeException extends java.lang.RuntimeException {
-    ctor public NegativeArraySizeException();
-    ctor public NegativeArraySizeException(String);
-  }
-
-  public class NoClassDefFoundError extends java.lang.LinkageError {
-    ctor public NoClassDefFoundError();
-    ctor public NoClassDefFoundError(String);
-  }
-
-  public class NoSuchFieldError extends java.lang.IncompatibleClassChangeError {
-    ctor public NoSuchFieldError();
-    ctor public NoSuchFieldError(String);
-  }
-
-  public class NoSuchFieldException extends java.lang.ReflectiveOperationException {
-    ctor public NoSuchFieldException();
-    ctor public NoSuchFieldException(String);
-  }
-
-  public class NoSuchMethodError extends java.lang.IncompatibleClassChangeError {
-    ctor public NoSuchMethodError();
-    ctor public NoSuchMethodError(String);
-  }
-
-  public class NoSuchMethodException extends java.lang.ReflectiveOperationException {
-    ctor public NoSuchMethodException();
-    ctor public NoSuchMethodException(String);
-  }
-
-  public class NullPointerException extends java.lang.RuntimeException {
-    ctor public NullPointerException();
-    ctor public NullPointerException(String);
-  }
-
-  public abstract class Number implements java.io.Serializable {
-    ctor public Number();
-    method public byte byteValue();
-    method public abstract double doubleValue();
-    method public abstract float floatValue();
-    method public abstract int intValue();
-    method public abstract long longValue();
-    method public short shortValue();
-  }
-
-  public class NumberFormatException extends java.lang.IllegalArgumentException {
-    ctor public NumberFormatException();
-    ctor public NumberFormatException(String);
-  }
-
-  public class Object {
-    ctor public Object();
-    method @NonNull protected Object clone() throws java.lang.CloneNotSupportedException;
-    method public boolean equals(@Nullable Object);
-    method protected void finalize() throws java.lang.Throwable;
-    method @NonNull public final Class<?> getClass();
-    method public int hashCode();
-    method public final void notify();
-    method public final void notifyAll();
-    method @NonNull public String toString();
-    method public final void wait(long) throws java.lang.InterruptedException;
-    method public final void wait(long, int) throws java.lang.InterruptedException;
-    method public final void wait() throws java.lang.InterruptedException;
-  }
-
-  public class OutOfMemoryError extends java.lang.VirtualMachineError {
-    ctor public OutOfMemoryError();
-    ctor public OutOfMemoryError(String);
-  }
-
-  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @java.lang.annotation.Target(java.lang.annotation.ElementType.METHOD) public @interface Override {
-  }
-
-  public class Package implements java.lang.reflect.AnnotatedElement {
-    method public <A extends java.lang.annotation.Annotation> A getAnnotation(Class<A>);
-    method public java.lang.annotation.Annotation[] getAnnotations();
-    method public <A extends java.lang.annotation.Annotation> A[] getAnnotationsByType(Class<A>);
-    method public <A extends java.lang.annotation.Annotation> A getDeclaredAnnotation(Class<A>);
-    method public java.lang.annotation.Annotation[] getDeclaredAnnotations();
-    method public <A extends java.lang.annotation.Annotation> A[] getDeclaredAnnotationsByType(Class<A>);
-    method public String getImplementationTitle();
-    method public String getImplementationVendor();
-    method public String getImplementationVersion();
-    method public String getName();
-    method public static Package getPackage(String);
-    method public static Package[] getPackages();
-    method public String getSpecificationTitle();
-    method public String getSpecificationVendor();
-    method public String getSpecificationVersion();
-    method public boolean isCompatibleWith(String) throws java.lang.NumberFormatException;
-    method public boolean isSealed();
-    method public boolean isSealed(java.net.URL);
-  }
-
-  public abstract class Process {
-    ctor public Process();
-    method public abstract void destroy();
-    method public Process destroyForcibly();
-    method public abstract int exitValue();
-    method public abstract java.io.InputStream getErrorStream();
-    method public abstract java.io.InputStream getInputStream();
-    method public abstract java.io.OutputStream getOutputStream();
-    method public boolean isAlive();
-    method public abstract int waitFor() throws java.lang.InterruptedException;
-    method public boolean waitFor(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-  }
-
-  public final class ProcessBuilder {
-    ctor public ProcessBuilder(java.util.List<java.lang.String>);
-    ctor public ProcessBuilder(java.lang.String...);
-    method public ProcessBuilder command(java.util.List<java.lang.String>);
-    method public ProcessBuilder command(java.lang.String...);
-    method public java.util.List<java.lang.String> command();
-    method public java.io.File directory();
-    method public ProcessBuilder directory(java.io.File);
-    method public java.util.Map<java.lang.String,java.lang.String> environment();
-    method public ProcessBuilder inheritIO();
-    method public ProcessBuilder redirectError(java.lang.ProcessBuilder.Redirect);
-    method public ProcessBuilder redirectError(java.io.File);
-    method public java.lang.ProcessBuilder.Redirect redirectError();
-    method public boolean redirectErrorStream();
-    method public ProcessBuilder redirectErrorStream(boolean);
-    method public ProcessBuilder redirectInput(java.lang.ProcessBuilder.Redirect);
-    method public ProcessBuilder redirectInput(java.io.File);
-    method public java.lang.ProcessBuilder.Redirect redirectInput();
-    method public ProcessBuilder redirectOutput(java.lang.ProcessBuilder.Redirect);
-    method public ProcessBuilder redirectOutput(java.io.File);
-    method public java.lang.ProcessBuilder.Redirect redirectOutput();
-    method public Process start() throws java.io.IOException;
-  }
-
-  public abstract static class ProcessBuilder.Redirect {
-    method public static java.lang.ProcessBuilder.Redirect appendTo(java.io.File);
-    method public java.io.File file();
-    method public static java.lang.ProcessBuilder.Redirect from(java.io.File);
-    method public static java.lang.ProcessBuilder.Redirect to(java.io.File);
-    method public abstract java.lang.ProcessBuilder.Redirect.Type type();
-    field public static final java.lang.ProcessBuilder.Redirect INHERIT;
-    field public static final java.lang.ProcessBuilder.Redirect PIPE;
-  }
-
-  public enum ProcessBuilder.Redirect.Type {
-    enum_constant public static final java.lang.ProcessBuilder.Redirect.Type APPEND;
-    enum_constant public static final java.lang.ProcessBuilder.Redirect.Type INHERIT;
-    enum_constant public static final java.lang.ProcessBuilder.Redirect.Type PIPE;
-    enum_constant public static final java.lang.ProcessBuilder.Redirect.Type READ;
-    enum_constant public static final java.lang.ProcessBuilder.Redirect.Type WRITE;
-  }
-
-  public interface Readable {
-    method public int read(java.nio.CharBuffer) throws java.io.IOException;
-  }
-
-  public class ReflectiveOperationException extends java.lang.Exception {
-    ctor public ReflectiveOperationException();
-    ctor public ReflectiveOperationException(String);
-    ctor public ReflectiveOperationException(String, Throwable);
-    ctor public ReflectiveOperationException(Throwable);
-  }
-
-  @java.lang.FunctionalInterface public interface Runnable {
-    method public void run();
-  }
-
-  public class Runtime {
-    method public void addShutdownHook(Thread);
-    method public int availableProcessors();
-    method public Process exec(String) throws java.io.IOException;
-    method public Process exec(String, String[]) throws java.io.IOException;
-    method public Process exec(String, String[], java.io.File) throws java.io.IOException;
-    method public Process exec(String[]) throws java.io.IOException;
-    method public Process exec(String[], String[]) throws java.io.IOException;
-    method public Process exec(String[], String[], java.io.File) throws java.io.IOException;
-    method public void exit(int);
-    method public long freeMemory();
-    method public void gc();
-    method @Deprecated public java.io.InputStream getLocalizedInputStream(java.io.InputStream);
-    method @Deprecated public java.io.OutputStream getLocalizedOutputStream(java.io.OutputStream);
-    method public static Runtime getRuntime();
-    method public void halt(int);
-    method public void load(String);
-    method public void loadLibrary(String);
-    method public long maxMemory();
-    method public boolean removeShutdownHook(Thread);
-    method public void runFinalization();
-    method @Deprecated public static void runFinalizersOnExit(boolean);
-    method public long totalMemory();
-    method public void traceInstructions(boolean);
-    method public void traceMethodCalls(boolean);
-  }
-
-  public class RuntimeException extends java.lang.Exception {
-    ctor public RuntimeException();
-    ctor public RuntimeException(String);
-    ctor public RuntimeException(String, Throwable);
-    ctor public RuntimeException(Throwable);
-    ctor protected RuntimeException(String, Throwable, boolean, boolean);
-  }
-
-  public final class RuntimePermission extends java.security.BasicPermission {
-    ctor public RuntimePermission(String);
-    ctor public RuntimePermission(String, String);
-  }
-
-  @java.lang.annotation.Documented @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Target({java.lang.annotation.ElementType.CONSTRUCTOR, java.lang.annotation.ElementType.METHOD}) public @interface SafeVarargs {
-  }
-
-  public class SecurityException extends java.lang.RuntimeException {
-    ctor public SecurityException();
-    ctor public SecurityException(String);
-    ctor public SecurityException(String, Throwable);
-    ctor public SecurityException(Throwable);
-  }
-
-  public class SecurityManager {
-    ctor public SecurityManager();
-    method public void checkAccept(String, int);
-    method public void checkAccess(Thread);
-    method public void checkAccess(ThreadGroup);
-    method public void checkAwtEventQueueAccess();
-    method public void checkConnect(String, int);
-    method public void checkConnect(String, int, Object);
-    method public void checkCreateClassLoader();
-    method public void checkDelete(String);
-    method public void checkExec(String);
-    method public void checkExit(int);
-    method public void checkLink(String);
-    method public void checkListen(int);
-    method public void checkMemberAccess(Class<?>, int);
-    method public void checkMulticast(java.net.InetAddress);
-    method @Deprecated public void checkMulticast(java.net.InetAddress, byte);
-    method public void checkPackageAccess(String);
-    method public void checkPackageDefinition(String);
-    method public void checkPermission(java.security.Permission);
-    method public void checkPermission(java.security.Permission, Object);
-    method public void checkPrintJobAccess();
-    method public void checkPropertiesAccess();
-    method public void checkPropertyAccess(String);
-    method public void checkRead(java.io.FileDescriptor);
-    method public void checkRead(String);
-    method public void checkRead(String, Object);
-    method public void checkSecurityAccess(String);
-    method public void checkSetFactory();
-    method public void checkSystemClipboardAccess();
-    method public boolean checkTopLevelWindow(Object);
-    method public void checkWrite(java.io.FileDescriptor);
-    method public void checkWrite(String);
-    method @Deprecated protected int classDepth(String);
-    method @Deprecated protected int classLoaderDepth();
-    method @Deprecated protected ClassLoader currentClassLoader();
-    method @Deprecated protected Class<?> currentLoadedClass();
-    method protected Class[] getClassContext();
-    method @Deprecated public boolean getInCheck();
-    method public Object getSecurityContext();
-    method public ThreadGroup getThreadGroup();
-    method @Deprecated protected boolean inClass(String);
-    method @Deprecated protected boolean inClassLoader();
-    field @Deprecated protected boolean inCheck;
-  }
-
-  public final class Short extends java.lang.Number implements java.lang.Comparable<java.lang.Short> {
-    ctor public Short(short);
-    ctor public Short(String) throws java.lang.NumberFormatException;
-    method public static int compare(short, short);
-    method public int compareTo(Short);
-    method public static Short decode(String) throws java.lang.NumberFormatException;
-    method public double doubleValue();
-    method public float floatValue();
-    method public static int hashCode(short);
-    method public int intValue();
-    method public long longValue();
-    method public static short parseShort(String, int) throws java.lang.NumberFormatException;
-    method public static short parseShort(String) throws java.lang.NumberFormatException;
-    method public static short reverseBytes(short);
-    method public static String toString(short);
-    method public static int toUnsignedInt(short);
-    method public static long toUnsignedLong(short);
-    method public static Short valueOf(String, int) throws java.lang.NumberFormatException;
-    method public static Short valueOf(String) throws java.lang.NumberFormatException;
-    method public static Short valueOf(short);
-    field public static final int BYTES = 2; // 0x2
-    field public static final short MAX_VALUE = 32767; // 0x7fff
-    field public static final short MIN_VALUE = -32768; // 0xffff8000
-    field public static final int SIZE = 16; // 0x10
-    field public static final Class<java.lang.Short> TYPE;
-  }
-
-  public class StackOverflowError extends java.lang.VirtualMachineError {
-    ctor public StackOverflowError();
-    ctor public StackOverflowError(String);
-  }
-
-  public final class StackTraceElement implements java.io.Serializable {
-    ctor public StackTraceElement(String, String, String, int);
-    method public String getClassName();
-    method public String getFileName();
-    method public int getLineNumber();
-    method public String getMethodName();
-    method public boolean isNativeMethod();
-  }
-
-  public final class StrictMath {
-    method public static double IEEEremainder(double, double);
-    method public static int abs(int);
-    method public static long abs(long);
-    method public static float abs(float);
-    method public static double abs(double);
-    method public static double acos(double);
-    method public static int addExact(int, int);
-    method public static long addExact(long, long);
-    method public static double asin(double);
-    method public static double atan(double);
-    method public static double atan2(double, double);
-    method public static double cbrt(double);
-    method public static double ceil(double);
-    method public static double copySign(double, double);
-    method public static float copySign(float, float);
-    method public static double cos(double);
-    method public static double cosh(double);
-    method public static double exp(double);
-    method public static double expm1(double);
-    method public static double floor(double);
-    method public static int floorDiv(int, int);
-    method public static long floorDiv(long, long);
-    method public static int floorMod(int, int);
-    method public static long floorMod(long, long);
-    method public static int getExponent(float);
-    method public static int getExponent(double);
-    method public static double hypot(double, double);
-    method public static double log(double);
-    method public static double log10(double);
-    method public static double log1p(double);
-    method public static int max(int, int);
-    method public static long max(long, long);
-    method public static float max(float, float);
-    method public static double max(double, double);
-    method public static int min(int, int);
-    method public static long min(long, long);
-    method public static float min(float, float);
-    method public static double min(double, double);
-    method public static int multiplyExact(int, int);
-    method public static long multiplyExact(long, long);
-    method public static double nextAfter(double, double);
-    method public static float nextAfter(float, double);
-    method public static double nextDown(double);
-    method public static float nextDown(float);
-    method public static double nextUp(double);
-    method public static float nextUp(float);
-    method public static double pow(double, double);
-    method public static double random();
-    method public static double rint(double);
-    method public static int round(float);
-    method public static long round(double);
-    method public static double scalb(double, int);
-    method public static float scalb(float, int);
-    method public static double signum(double);
-    method public static float signum(float);
-    method public static double sin(double);
-    method public static double sinh(double);
-    method public static double sqrt(double);
-    method public static int subtractExact(int, int);
-    method public static long subtractExact(long, long);
-    method public static double tan(double);
-    method public static double tanh(double);
-    method public static double toDegrees(double);
-    method public static int toIntExact(long);
-    method public static double toRadians(double);
-    method public static double ulp(double);
-    method public static float ulp(float);
-    field public static final double E = 2.718281828459045;
-    field public static final double PI = 3.141592653589793;
-  }
-
-  public final class String implements java.lang.CharSequence java.lang.Comparable<java.lang.String> java.io.Serializable {
-    ctor public String();
-    ctor public String(@NonNull String);
-    ctor public String(char[]);
-    ctor public String(char[], int, int);
-    ctor public String(int[], int, int);
-    ctor @Deprecated public String(byte[], int, int, int);
-    ctor @Deprecated public String(byte[], int);
-    ctor public String(byte[], int, int, @NonNull String) throws java.io.UnsupportedEncodingException;
-    ctor public String(byte[], int, int, @NonNull java.nio.charset.Charset);
-    ctor public String(byte[], @NonNull String) throws java.io.UnsupportedEncodingException;
-    ctor public String(byte[], @NonNull java.nio.charset.Charset);
-    ctor public String(byte[], int, int);
-    ctor public String(byte[]);
-    ctor public String(@NonNull StringBuffer);
-    ctor public String(@NonNull StringBuilder);
-    method public char charAt(int);
-    method public int codePointAt(int);
-    method public int codePointBefore(int);
-    method public int codePointCount(int, int);
-    method public int compareTo(@NonNull String);
-    method public int compareToIgnoreCase(@NonNull String);
-    method @NonNull public String concat(@NonNull String);
-    method public boolean contains(@NonNull CharSequence);
-    method public boolean contentEquals(@NonNull StringBuffer);
-    method public boolean contentEquals(@NonNull CharSequence);
-    method @NonNull public static String copyValueOf(char[], int, int);
-    method @NonNull public static String copyValueOf(char[]);
-    method public boolean endsWith(@NonNull String);
-    method public boolean equalsIgnoreCase(@Nullable String);
-    method @NonNull public static String format(@NonNull String, @NonNull java.lang.Object...);
-    method @NonNull public static String format(@NonNull java.util.Locale, @NonNull String, @NonNull java.lang.Object...);
-    method @Deprecated public void getBytes(int, int, byte[], int);
-    method public byte[] getBytes(@NonNull String) throws java.io.UnsupportedEncodingException;
-    method public byte[] getBytes(@NonNull java.nio.charset.Charset);
-    method public byte[] getBytes();
-    method public void getChars(int, int, char[], int);
-    method public int indexOf(int);
-    method public int indexOf(int, int);
-    method public int indexOf(@NonNull String);
-    method public int indexOf(@NonNull String, int);
-    method @NonNull public String intern();
-    method public boolean isEmpty();
-    method @NonNull public static String join(@NonNull CharSequence, @Nullable java.lang.CharSequence...);
-    method @NonNull public static String join(@NonNull CharSequence, @NonNull Iterable<? extends java.lang.CharSequence>);
-    method public int lastIndexOf(int);
-    method public int lastIndexOf(int, int);
-    method public int lastIndexOf(@NonNull String);
-    method public int lastIndexOf(@NonNull String, int);
-    method public int length();
-    method public boolean matches(@NonNull String);
-    method public int offsetByCodePoints(int, int);
-    method public boolean regionMatches(int, @NonNull String, int, int);
-    method public boolean regionMatches(boolean, int, @NonNull String, int, int);
-    method @NonNull public String replace(char, char);
-    method @NonNull public String replace(@NonNull CharSequence, @NonNull CharSequence);
-    method @NonNull public String replaceAll(@NonNull String, @NonNull String);
-    method @NonNull public String replaceFirst(@NonNull String, @NonNull String);
-    method @NonNull public String[] split(@NonNull String, int);
-    method @NonNull public String[] split(@NonNull String);
-    method public boolean startsWith(@NonNull String, int);
-    method public boolean startsWith(@NonNull String);
-    method @NonNull public CharSequence subSequence(int, int);
-    method @NonNull public String substring(int);
-    method @NonNull public String substring(int, int);
-    method public char[] toCharArray();
-    method @NonNull public String toLowerCase(@NonNull java.util.Locale);
-    method @NonNull public String toLowerCase();
-    method @NonNull public String toUpperCase(@NonNull java.util.Locale);
-    method @NonNull public String toUpperCase();
-    method @NonNull public String trim();
-    method @NonNull public static String valueOf(@Nullable Object);
-    method @NonNull public static String valueOf(char[]);
-    method @NonNull public static String valueOf(char[], int, int);
-    method @NonNull public static String valueOf(boolean);
-    method @NonNull public static String valueOf(char);
-    method @NonNull public static String valueOf(int);
-    method @NonNull public static String valueOf(long);
-    method @NonNull public static String valueOf(float);
-    method @NonNull public static String valueOf(double);
-    field public static final java.util.Comparator<java.lang.String> CASE_INSENSITIVE_ORDER;
-  }
-
-  public final class StringBuffer implements java.lang.Appendable java.lang.CharSequence java.io.Serializable {
-    ctor public StringBuffer();
-    ctor public StringBuffer(int);
-    ctor public StringBuffer(@NonNull String);
-    ctor public StringBuffer(@NonNull CharSequence);
-    method @NonNull public StringBuffer append(@Nullable Object);
-    method @NonNull public StringBuffer append(@Nullable String);
-    method @NonNull public StringBuffer append(@Nullable StringBuffer);
-    method @NonNull public StringBuffer append(@Nullable CharSequence);
-    method @NonNull public StringBuffer append(@Nullable CharSequence, int, int);
-    method @NonNull public StringBuffer append(char[]);
-    method @NonNull public StringBuffer append(char[], int, int);
-    method @NonNull public StringBuffer append(boolean);
-    method @NonNull public StringBuffer append(char);
-    method @NonNull public StringBuffer append(int);
-    method @NonNull public StringBuffer append(long);
-    method @NonNull public StringBuffer append(float);
-    method @NonNull public StringBuffer append(double);
-    method @NonNull public StringBuffer appendCodePoint(int);
-    method public int capacity();
-    method public char charAt(int);
-    method public int codePointAt(int);
-    method public int codePointBefore(int);
-    method public int codePointCount(int, int);
-    method @NonNull public StringBuffer delete(int, int);
-    method @NonNull public StringBuffer deleteCharAt(int);
-    method public void ensureCapacity(int);
-    method public void getChars(int, int, char[], int);
-    method public int indexOf(@NonNull String);
-    method public int indexOf(@NonNull String, int);
-    method @NonNull public StringBuffer insert(int, char[], int, int);
-    method @NonNull public StringBuffer insert(int, @Nullable Object);
-    method @NonNull public StringBuffer insert(int, @Nullable String);
-    method @NonNull public StringBuffer insert(int, char[]);
-    method @NonNull public StringBuffer insert(int, @Nullable CharSequence);
-    method @NonNull public StringBuffer insert(int, @Nullable CharSequence, int, int);
-    method @NonNull public StringBuffer insert(int, boolean);
-    method @NonNull public StringBuffer insert(int, char);
-    method @NonNull public StringBuffer insert(int, int);
-    method @NonNull public StringBuffer insert(int, long);
-    method @NonNull public StringBuffer insert(int, float);
-    method @NonNull public StringBuffer insert(int, double);
-    method public int lastIndexOf(@NonNull String);
-    method public int lastIndexOf(@NonNull String, int);
-    method public int length();
-    method public int offsetByCodePoints(int, int);
-    method @NonNull public StringBuffer replace(int, int, @NonNull String);
-    method @NonNull public StringBuffer reverse();
-    method public void setCharAt(int, char);
-    method public void setLength(int);
-    method @NonNull public CharSequence subSequence(int, int);
-    method @NonNull public String substring(int);
-    method @NonNull public String substring(int, int);
-    method public void trimToSize();
-  }
-
-  public final class StringBuilder implements java.lang.Appendable java.lang.CharSequence java.io.Serializable {
-    ctor public StringBuilder();
-    ctor public StringBuilder(int);
-    ctor public StringBuilder(@NonNull String);
-    ctor public StringBuilder(@NonNull CharSequence);
-    method @NonNull public StringBuilder append(@Nullable Object);
-    method @NonNull public StringBuilder append(@Nullable String);
-    method @NonNull public StringBuilder append(@Nullable StringBuffer);
-    method @NonNull public StringBuilder append(@Nullable CharSequence);
-    method @NonNull public StringBuilder append(@Nullable CharSequence, int, int);
-    method @NonNull public StringBuilder append(char[]);
-    method @NonNull public StringBuilder append(char[], int, int);
-    method @NonNull public StringBuilder append(boolean);
-    method @NonNull public StringBuilder append(char);
-    method @NonNull public StringBuilder append(int);
-    method @NonNull public StringBuilder append(long);
-    method @NonNull public StringBuilder append(float);
-    method @NonNull public StringBuilder append(double);
-    method @NonNull public StringBuilder appendCodePoint(int);
-    method public int capacity();
-    method public char charAt(int);
-    method public int codePointAt(int);
-    method public int codePointBefore(int);
-    method public int codePointCount(int, int);
-    method @NonNull public StringBuilder delete(int, int);
-    method @NonNull public StringBuilder deleteCharAt(int);
-    method public void ensureCapacity(int);
-    method public void getChars(int, int, char[], int);
-    method public int indexOf(@NonNull String);
-    method public int indexOf(@NonNull String, int);
-    method @NonNull public StringBuilder insert(int, char[], int, int);
-    method @NonNull public StringBuilder insert(int, @Nullable Object);
-    method @NonNull public StringBuilder insert(int, @Nullable String);
-    method @NonNull public StringBuilder insert(int, char[]);
-    method @NonNull public StringBuilder insert(int, @Nullable CharSequence);
-    method @NonNull public StringBuilder insert(int, @Nullable CharSequence, int, int);
-    method @NonNull public StringBuilder insert(int, boolean);
-    method @NonNull public StringBuilder insert(int, char);
-    method @NonNull public StringBuilder insert(int, int);
-    method @NonNull public StringBuilder insert(int, long);
-    method @NonNull public StringBuilder insert(int, float);
-    method @NonNull public StringBuilder insert(int, double);
-    method public int lastIndexOf(@NonNull String);
-    method public int lastIndexOf(@NonNull String, int);
-    method public int length();
-    method public int offsetByCodePoints(int, int);
-    method @NonNull public StringBuilder replace(int, int, @NonNull String);
-    method @NonNull public StringBuilder reverse();
-    method public void setCharAt(int, char);
-    method public void setLength(int);
-    method @NonNull public CharSequence subSequence(int, int);
-    method @NonNull public String substring(int);
-    method @NonNull public String substring(int, int);
-    method public void trimToSize();
-  }
-
-  public class StringIndexOutOfBoundsException extends java.lang.IndexOutOfBoundsException {
-    ctor public StringIndexOutOfBoundsException();
-    ctor public StringIndexOutOfBoundsException(String);
-    ctor public StringIndexOutOfBoundsException(int);
-  }
-
-  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE, java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.PARAMETER, java.lang.annotation.ElementType.CONSTRUCTOR, java.lang.annotation.ElementType.LOCAL_VARIABLE}) public @interface SuppressWarnings {
-    method public abstract String[] value();
-  }
-
-  public final class System {
-    method public static void arraycopy(@NonNull Object, int, @NonNull Object, int, int);
-    method @Nullable public static String clearProperty(@NonNull String);
-    method @Nullable public static java.io.Console console();
-    method public static long currentTimeMillis();
-    method public static void exit(int);
-    method public static void gc();
-    method @NonNull public static java.util.Properties getProperties();
-    method @Nullable public static String getProperty(@NonNull String);
-    method @Nullable public static String getProperty(@NonNull String, @Nullable String);
-    method @Nullable public static SecurityManager getSecurityManager();
-    method @Nullable public static String getenv(@NonNull String);
-    method @NonNull public static java.util.Map<java.lang.String,java.lang.String> getenv();
-    method public static int identityHashCode(@Nullable Object);
-    method @Nullable public static java.nio.channels.Channel inheritedChannel() throws java.io.IOException;
-    method @NonNull public static String lineSeparator();
-    method public static void load(@NonNull String);
-    method public static void loadLibrary(@NonNull String);
-    method @NonNull public static String mapLibraryName(@NonNull String);
-    method public static long nanoTime();
-    method public static void runFinalization();
-    method @Deprecated public static void runFinalizersOnExit(boolean);
-    method public static void setErr(@Nullable java.io.PrintStream);
-    method public static void setIn(@Nullable java.io.InputStream);
-    method public static void setOut(@Nullable java.io.PrintStream);
-    method public static void setProperties(@Nullable java.util.Properties);
-    method @Nullable public static String setProperty(@NonNull String, @Nullable String);
-    method public static void setSecurityManager(@Nullable SecurityManager);
-    field public static final java.io.PrintStream err;
-    field public static final java.io.InputStream in;
-    field public static final java.io.PrintStream out;
-  }
-
-  public class Thread implements java.lang.Runnable {
-    ctor public Thread();
-    ctor public Thread(@Nullable Runnable);
-    ctor public Thread(@Nullable ThreadGroup, @Nullable Runnable);
-    ctor public Thread(@NonNull String);
-    ctor public Thread(@Nullable ThreadGroup, @NonNull String);
-    ctor public Thread(@Nullable Runnable, @NonNull String);
-    ctor public Thread(@Nullable ThreadGroup, @Nullable Runnable, @NonNull String);
-    ctor public Thread(@Nullable ThreadGroup, @Nullable Runnable, @NonNull String, long);
-    method public static int activeCount();
-    method public final void checkAccess();
-    method @Deprecated public int countStackFrames();
-    method @NonNull public static Thread currentThread();
-    method @Deprecated public void destroy();
-    method public static void dumpStack();
-    method public static int enumerate(Thread[]);
-    method @NonNull public static java.util.Map<java.lang.Thread,java.lang.StackTraceElement[]> getAllStackTraces();
-    method @Nullable public ClassLoader getContextClassLoader();
-    method @Nullable public static java.lang.Thread.UncaughtExceptionHandler getDefaultUncaughtExceptionHandler();
-    method public long getId();
-    method @NonNull public final String getName();
-    method public final int getPriority();
-    method @NonNull public StackTraceElement[] getStackTrace();
-    method @NonNull public java.lang.Thread.State getState();
-    method @Nullable public final ThreadGroup getThreadGroup();
-    method @Nullable public java.lang.Thread.UncaughtExceptionHandler getUncaughtExceptionHandler();
-    method public static boolean holdsLock(@NonNull Object);
-    method public void interrupt();
-    method public static boolean interrupted();
-    method public final boolean isAlive();
-    method public final boolean isDaemon();
-    method public boolean isInterrupted();
-    method public final void join(long) throws java.lang.InterruptedException;
-    method public final void join(long, int) throws java.lang.InterruptedException;
-    method public final void join() throws java.lang.InterruptedException;
-    method @Deprecated public final void resume();
-    method public void run();
-    method public void setContextClassLoader(@Nullable ClassLoader);
-    method public final void setDaemon(boolean);
-    method public static void setDefaultUncaughtExceptionHandler(@Nullable java.lang.Thread.UncaughtExceptionHandler);
-    method public final void setName(@NonNull String);
-    method public final void setPriority(int);
-    method public void setUncaughtExceptionHandler(@Nullable java.lang.Thread.UncaughtExceptionHandler);
-    method public static void sleep(long) throws java.lang.InterruptedException;
-    method public static void sleep(long, int) throws java.lang.InterruptedException;
-    method public void start();
-    method @Deprecated public final void stop();
-    method @Deprecated public final void stop(@Nullable Throwable);
-    method @Deprecated public final void suspend();
-    method public static void yield();
-    field public static final int MAX_PRIORITY = 10; // 0xa
-    field public static final int MIN_PRIORITY = 1; // 0x1
-    field public static final int NORM_PRIORITY = 5; // 0x5
-  }
-
-  public enum Thread.State {
-    enum_constant public static final java.lang.Thread.State BLOCKED;
-    enum_constant public static final java.lang.Thread.State NEW;
-    enum_constant public static final java.lang.Thread.State RUNNABLE;
-    enum_constant public static final java.lang.Thread.State TERMINATED;
-    enum_constant public static final java.lang.Thread.State TIMED_WAITING;
-    enum_constant public static final java.lang.Thread.State WAITING;
-  }
-
-  @java.lang.FunctionalInterface public static interface Thread.UncaughtExceptionHandler {
-    method public void uncaughtException(@NonNull Thread, @NonNull Throwable);
-  }
-
-  public class ThreadDeath extends java.lang.Error {
-    ctor public ThreadDeath();
-  }
-
-  public class ThreadGroup implements java.lang.Thread.UncaughtExceptionHandler {
-    ctor public ThreadGroup(String);
-    ctor public ThreadGroup(ThreadGroup, String);
-    method public int activeCount();
-    method public int activeGroupCount();
-    method @Deprecated public boolean allowThreadSuspension(boolean);
-    method public final void checkAccess();
-    method public final void destroy();
-    method public int enumerate(Thread[]);
-    method public int enumerate(Thread[], boolean);
-    method public int enumerate(ThreadGroup[]);
-    method public int enumerate(ThreadGroup[], boolean);
-    method public final int getMaxPriority();
-    method public final String getName();
-    method public final ThreadGroup getParent();
-    method public final void interrupt();
-    method public final boolean isDaemon();
-    method public boolean isDestroyed();
-    method public void list();
-    method public final boolean parentOf(ThreadGroup);
-    method @Deprecated public final void resume();
-    method public final void setDaemon(boolean);
-    method public final void setMaxPriority(int);
-    method @Deprecated public final void stop();
-    method @Deprecated public final void suspend();
-    method public void uncaughtException(Thread, Throwable);
-  }
-
-  public class ThreadLocal<T> {
-    ctor public ThreadLocal();
-    method @Nullable public T get();
-    method @Nullable protected T initialValue();
-    method public void remove();
-    method public void set(T);
-    method @NonNull public static <S> ThreadLocal<S> withInitial(@NonNull java.util.function.Supplier<? extends S>);
-  }
-
-  public class Throwable implements java.io.Serializable {
-    ctor public Throwable();
-    ctor public Throwable(@Nullable String);
-    ctor public Throwable(@Nullable String, @Nullable Throwable);
-    ctor public Throwable(@Nullable Throwable);
-    ctor protected Throwable(@Nullable String, @Nullable Throwable, boolean, boolean);
-    method public final void addSuppressed(@NonNull Throwable);
-    method @NonNull public Throwable fillInStackTrace();
-    method @Nullable public Throwable getCause();
-    method @Nullable public String getLocalizedMessage();
-    method @Nullable public String getMessage();
-    method @NonNull public StackTraceElement[] getStackTrace();
-    method @NonNull public final Throwable[] getSuppressed();
-    method @NonNull public Throwable initCause(@Nullable Throwable);
-    method public void printStackTrace();
-    method public void printStackTrace(@NonNull java.io.PrintStream);
-    method public void printStackTrace(@NonNull java.io.PrintWriter);
-    method public void setStackTrace(@NonNull StackTraceElement[]);
-  }
-
-  public class TypeNotPresentException extends java.lang.RuntimeException {
-    ctor public TypeNotPresentException(String, Throwable);
-    method public String typeName();
-  }
-
-  public class UnknownError extends java.lang.VirtualMachineError {
-    ctor public UnknownError();
-    ctor public UnknownError(String);
-  }
-
-  public class UnsatisfiedLinkError extends java.lang.LinkageError {
-    ctor public UnsatisfiedLinkError();
-    ctor public UnsatisfiedLinkError(String);
-  }
-
-  public class UnsupportedClassVersionError extends java.lang.ClassFormatError {
-    ctor public UnsupportedClassVersionError();
-    ctor public UnsupportedClassVersionError(String);
-  }
-
-  public class UnsupportedOperationException extends java.lang.RuntimeException {
-    ctor public UnsupportedOperationException();
-    ctor public UnsupportedOperationException(String);
-    ctor public UnsupportedOperationException(String, Throwable);
-    ctor public UnsupportedOperationException(Throwable);
-  }
-
-  public class VerifyError extends java.lang.LinkageError {
-    ctor public VerifyError();
-    ctor public VerifyError(String);
-  }
-
-  public abstract class VirtualMachineError extends java.lang.Error {
-    ctor public VirtualMachineError();
-    ctor public VirtualMachineError(String);
-    ctor public VirtualMachineError(String, Throwable);
-    ctor public VirtualMachineError(Throwable);
-  }
-
-  public final class Void {
-    field public static final Class<java.lang.Void> TYPE;
-  }
-
-}
-
-package java.lang.annotation {
-
-  public interface Annotation {
-    method public Class<? extends java.lang.annotation.Annotation> annotationType();
-    method public boolean equals(Object);
-    method public int hashCode();
-    method public String toString();
-  }
-
-  public class AnnotationFormatError extends java.lang.Error {
-    ctor public AnnotationFormatError(String);
-    ctor public AnnotationFormatError(String, Throwable);
-    ctor public AnnotationFormatError(Throwable);
-  }
-
-  public class AnnotationTypeMismatchException extends java.lang.RuntimeException {
-    ctor public AnnotationTypeMismatchException(java.lang.reflect.Method, String);
-    method public java.lang.reflect.Method element();
-    method public String foundType();
-  }
-
-  @java.lang.annotation.Documented @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Target(java.lang.annotation.ElementType.ANNOTATION_TYPE) public @interface Documented {
-  }
-
-  public enum ElementType {
-    enum_constant public static final java.lang.annotation.ElementType ANNOTATION_TYPE;
-    enum_constant public static final java.lang.annotation.ElementType CONSTRUCTOR;
-    enum_constant public static final java.lang.annotation.ElementType FIELD;
-    enum_constant public static final java.lang.annotation.ElementType LOCAL_VARIABLE;
-    enum_constant public static final java.lang.annotation.ElementType METHOD;
-    enum_constant public static final java.lang.annotation.ElementType PACKAGE;
-    enum_constant public static final java.lang.annotation.ElementType PARAMETER;
-    enum_constant public static final java.lang.annotation.ElementType TYPE;
-    enum_constant public static final java.lang.annotation.ElementType TYPE_PARAMETER;
-    enum_constant public static final java.lang.annotation.ElementType TYPE_USE;
-  }
-
-  public class IncompleteAnnotationException extends java.lang.RuntimeException {
-    ctor public IncompleteAnnotationException(Class<? extends java.lang.annotation.Annotation>, String);
-    method public Class<? extends java.lang.annotation.Annotation> annotationType();
-    method public String elementName();
-  }
-
-  @java.lang.annotation.Documented @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Target(java.lang.annotation.ElementType.ANNOTATION_TYPE) public @interface Inherited {
-  }
-
-  @java.lang.annotation.Documented @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @java.lang.annotation.Target(java.lang.annotation.ElementType.FIELD) public @interface Native {
-  }
-
-  @java.lang.annotation.Documented @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Target(java.lang.annotation.ElementType.ANNOTATION_TYPE) public @interface Repeatable {
-    method public abstract Class<? extends java.lang.annotation.Annotation> value();
-  }
-
-  @java.lang.annotation.Documented @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Target(java.lang.annotation.ElementType.ANNOTATION_TYPE) public @interface Retention {
-    method public abstract java.lang.annotation.RetentionPolicy value();
-  }
-
-  public enum RetentionPolicy {
-    enum_constant public static final java.lang.annotation.RetentionPolicy CLASS;
-    enum_constant public static final java.lang.annotation.RetentionPolicy RUNTIME;
-    enum_constant public static final java.lang.annotation.RetentionPolicy SOURCE;
-  }
-
-  @java.lang.annotation.Documented @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Target(java.lang.annotation.ElementType.ANNOTATION_TYPE) public @interface Target {
-    method public abstract java.lang.annotation.ElementType[] value();
-  }
-
-}
-
-package java.lang.invoke {
-
-  public abstract class CallSite {
-    method public abstract java.lang.invoke.MethodHandle dynamicInvoker();
-    method public abstract java.lang.invoke.MethodHandle getTarget();
-    method public abstract void setTarget(java.lang.invoke.MethodHandle);
-    method public java.lang.invoke.MethodType type();
-  }
-
-  public class ConstantCallSite extends java.lang.invoke.CallSite {
-    ctor public ConstantCallSite(java.lang.invoke.MethodHandle);
-    ctor protected ConstantCallSite(java.lang.invoke.MethodType, java.lang.invoke.MethodHandle) throws java.lang.Throwable;
-    method public final java.lang.invoke.MethodHandle dynamicInvoker();
-    method public final java.lang.invoke.MethodHandle getTarget();
-    method public final void setTarget(java.lang.invoke.MethodHandle);
-  }
-
-  public class LambdaConversionException extends java.lang.Exception {
-    ctor public LambdaConversionException();
-    ctor public LambdaConversionException(String);
-    ctor public LambdaConversionException(String, Throwable);
-    ctor public LambdaConversionException(Throwable);
-    ctor public LambdaConversionException(String, Throwable, boolean, boolean);
-  }
-
-  public abstract class MethodHandle {
-    method public java.lang.invoke.MethodHandle asCollector(Class<?>, int);
-    method public java.lang.invoke.MethodHandle asFixedArity();
-    method public java.lang.invoke.MethodHandle asSpreader(Class<?>, int);
-    method public java.lang.invoke.MethodHandle asType(java.lang.invoke.MethodType);
-    method public java.lang.invoke.MethodHandle asVarargsCollector(Class<?>);
-    method public java.lang.invoke.MethodHandle bindTo(Object);
-    method public final Object invoke(java.lang.Object...) throws java.lang.Throwable;
-    method public final Object invokeExact(java.lang.Object...) throws java.lang.Throwable;
-    method public Object invokeWithArguments(java.lang.Object...) throws java.lang.Throwable;
-    method public Object invokeWithArguments(java.util.List<?>) throws java.lang.Throwable;
-    method public boolean isVarargsCollector();
-    method public java.lang.invoke.MethodType type();
-  }
-
-  public interface MethodHandleInfo {
-    method public Class<?> getDeclaringClass();
-    method public java.lang.invoke.MethodType getMethodType();
-    method public int getModifiers();
-    method public String getName();
-    method public int getReferenceKind();
-    method public default boolean isVarArgs();
-    method @Deprecated public static boolean refKindIsField(int);
-    method @Deprecated public static boolean refKindIsValid(int);
-    method @Deprecated public static String refKindName(int);
-    method public static String referenceKindToString(int);
-    method public <T extends java.lang.reflect.Member> T reflectAs(Class<T>, java.lang.invoke.MethodHandles.Lookup);
-    method public static String toString(int, Class<?>, String, java.lang.invoke.MethodType);
-    field public static final int REF_getField = 1; // 0x1
-    field public static final int REF_getStatic = 2; // 0x2
-    field public static final int REF_invokeInterface = 9; // 0x9
-    field public static final int REF_invokeSpecial = 7; // 0x7
-    field public static final int REF_invokeStatic = 6; // 0x6
-    field public static final int REF_invokeVirtual = 5; // 0x5
-    field public static final int REF_newInvokeSpecial = 8; // 0x8
-    field public static final int REF_putField = 3; // 0x3
-    field public static final int REF_putStatic = 4; // 0x4
-  }
-
-  public class MethodHandles {
-    method public static java.lang.invoke.MethodHandle arrayElementGetter(Class<?>) throws java.lang.IllegalArgumentException;
-    method public static java.lang.invoke.MethodHandle arrayElementSetter(Class<?>) throws java.lang.IllegalArgumentException;
-    method public static java.lang.invoke.MethodHandle catchException(java.lang.invoke.MethodHandle, Class<? extends java.lang.Throwable>, java.lang.invoke.MethodHandle);
-    method public static java.lang.invoke.MethodHandle collectArguments(java.lang.invoke.MethodHandle, int, java.lang.invoke.MethodHandle);
-    method public static java.lang.invoke.MethodHandle constant(Class<?>, Object);
-    method public static java.lang.invoke.MethodHandle dropArguments(java.lang.invoke.MethodHandle, int, java.util.List<java.lang.Class<?>>);
-    method public static java.lang.invoke.MethodHandle dropArguments(java.lang.invoke.MethodHandle, int, Class<?>...);
-    method public static java.lang.invoke.MethodHandle exactInvoker(java.lang.invoke.MethodType);
-    method public static java.lang.invoke.MethodHandle explicitCastArguments(java.lang.invoke.MethodHandle, java.lang.invoke.MethodType);
-    method public static java.lang.invoke.MethodHandle filterArguments(java.lang.invoke.MethodHandle, int, java.lang.invoke.MethodHandle...);
-    method public static java.lang.invoke.MethodHandle filterReturnValue(java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle);
-    method public static java.lang.invoke.MethodHandle foldArguments(java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle);
-    method public static java.lang.invoke.MethodHandle guardWithTest(java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle);
-    method public static java.lang.invoke.MethodHandle identity(Class<?>);
-    method public static java.lang.invoke.MethodHandle insertArguments(java.lang.invoke.MethodHandle, int, java.lang.Object...);
-    method public static java.lang.invoke.MethodHandle invoker(java.lang.invoke.MethodType);
-    method public static java.lang.invoke.MethodHandles.Lookup lookup();
-    method public static java.lang.invoke.MethodHandle permuteArguments(java.lang.invoke.MethodHandle, java.lang.invoke.MethodType, int...);
-    method public static java.lang.invoke.MethodHandles.Lookup publicLookup();
-    method public static <T extends java.lang.reflect.Member> T reflectAs(Class<T>, java.lang.invoke.MethodHandle);
-    method public static java.lang.invoke.MethodHandle spreadInvoker(java.lang.invoke.MethodType, int);
-    method public static java.lang.invoke.MethodHandle throwException(Class<?>, Class<? extends java.lang.Throwable>);
-  }
-
-  public static final class MethodHandles.Lookup {
-    method public java.lang.invoke.MethodHandle bind(Object, String, java.lang.invoke.MethodType) throws java.lang.IllegalAccessException, java.lang.NoSuchMethodException;
-    method public java.lang.invoke.MethodHandle findConstructor(Class<?>, java.lang.invoke.MethodType) throws java.lang.IllegalAccessException, java.lang.NoSuchMethodException;
-    method public java.lang.invoke.MethodHandle findGetter(Class<?>, String, Class<?>) throws java.lang.IllegalAccessException, java.lang.NoSuchFieldException;
-    method public java.lang.invoke.MethodHandle findSetter(Class<?>, String, Class<?>) throws java.lang.IllegalAccessException, java.lang.NoSuchFieldException;
-    method public java.lang.invoke.MethodHandle findSpecial(Class<?>, String, java.lang.invoke.MethodType, Class<?>) throws java.lang.IllegalAccessException, java.lang.NoSuchMethodException;
-    method public java.lang.invoke.MethodHandle findStatic(Class<?>, String, java.lang.invoke.MethodType) throws java.lang.IllegalAccessException, java.lang.NoSuchMethodException;
-    method public java.lang.invoke.MethodHandle findStaticGetter(Class<?>, String, Class<?>) throws java.lang.IllegalAccessException, java.lang.NoSuchFieldException;
-    method public java.lang.invoke.MethodHandle findStaticSetter(Class<?>, String, Class<?>) throws java.lang.IllegalAccessException, java.lang.NoSuchFieldException;
-    method public java.lang.invoke.MethodHandle findVirtual(Class<?>, String, java.lang.invoke.MethodType) throws java.lang.IllegalAccessException, java.lang.NoSuchMethodException;
-    method public java.lang.invoke.MethodHandles.Lookup in(Class<?>);
-    method public Class<?> lookupClass();
-    method public int lookupModes();
-    method public java.lang.invoke.MethodHandleInfo revealDirect(java.lang.invoke.MethodHandle);
-    method public java.lang.invoke.MethodHandle unreflect(java.lang.reflect.Method) throws java.lang.IllegalAccessException;
-    method public java.lang.invoke.MethodHandle unreflectConstructor(java.lang.reflect.Constructor<?>) throws java.lang.IllegalAccessException;
-    method public java.lang.invoke.MethodHandle unreflectGetter(java.lang.reflect.Field) throws java.lang.IllegalAccessException;
-    method public java.lang.invoke.MethodHandle unreflectSetter(java.lang.reflect.Field) throws java.lang.IllegalAccessException;
-    method public java.lang.invoke.MethodHandle unreflectSpecial(java.lang.reflect.Method, Class<?>) throws java.lang.IllegalAccessException;
-    field public static final int PACKAGE = 8; // 0x8
-    field public static final int PRIVATE = 2; // 0x2
-    field public static final int PROTECTED = 4; // 0x4
-    field public static final int PUBLIC = 1; // 0x1
-  }
-
-  public final class MethodType implements java.io.Serializable {
-    method public java.lang.invoke.MethodType appendParameterTypes(Class<?>...);
-    method public java.lang.invoke.MethodType appendParameterTypes(java.util.List<java.lang.Class<?>>);
-    method public java.lang.invoke.MethodType changeParameterType(int, Class<?>);
-    method public java.lang.invoke.MethodType changeReturnType(Class<?>);
-    method public java.lang.invoke.MethodType dropParameterTypes(int, int);
-    method public java.lang.invoke.MethodType erase();
-    method public static java.lang.invoke.MethodType fromMethodDescriptorString(String, ClassLoader) throws java.lang.IllegalArgumentException, java.lang.TypeNotPresentException;
-    method public java.lang.invoke.MethodType generic();
-    method public static java.lang.invoke.MethodType genericMethodType(int, boolean);
-    method public static java.lang.invoke.MethodType genericMethodType(int);
-    method public boolean hasPrimitives();
-    method public boolean hasWrappers();
-    method public java.lang.invoke.MethodType insertParameterTypes(int, Class<?>...);
-    method public java.lang.invoke.MethodType insertParameterTypes(int, java.util.List<java.lang.Class<?>>);
-    method public static java.lang.invoke.MethodType methodType(Class<?>, Class<?>[]);
-    method public static java.lang.invoke.MethodType methodType(Class<?>, java.util.List<java.lang.Class<?>>);
-    method public static java.lang.invoke.MethodType methodType(Class<?>, Class<?>, Class<?>...);
-    method public static java.lang.invoke.MethodType methodType(Class<?>);
-    method public static java.lang.invoke.MethodType methodType(Class<?>, Class<?>);
-    method public static java.lang.invoke.MethodType methodType(Class<?>, java.lang.invoke.MethodType);
-    method public Class<?>[] parameterArray();
-    method public int parameterCount();
-    method public java.util.List<java.lang.Class<?>> parameterList();
-    method public Class<?> parameterType(int);
-    method public Class<?> returnType();
-    method public String toMethodDescriptorString();
-    method public java.lang.invoke.MethodType unwrap();
-    method public java.lang.invoke.MethodType wrap();
-  }
-
-  public class MutableCallSite extends java.lang.invoke.CallSite {
-    ctor public MutableCallSite(java.lang.invoke.MethodType);
-    ctor public MutableCallSite(java.lang.invoke.MethodHandle);
-    method public final java.lang.invoke.MethodHandle dynamicInvoker();
-    method public final java.lang.invoke.MethodHandle getTarget();
-    method public void setTarget(java.lang.invoke.MethodHandle);
-  }
-
-  public class VolatileCallSite extends java.lang.invoke.CallSite {
-    ctor public VolatileCallSite(java.lang.invoke.MethodType);
-    ctor public VolatileCallSite(java.lang.invoke.MethodHandle);
-    method public final java.lang.invoke.MethodHandle dynamicInvoker();
-    method public final java.lang.invoke.MethodHandle getTarget();
-    method public void setTarget(java.lang.invoke.MethodHandle);
-  }
-
-  public class WrongMethodTypeException extends java.lang.RuntimeException {
-    ctor public WrongMethodTypeException();
-    ctor public WrongMethodTypeException(String);
-  }
-
-}
-
-package java.lang.ref {
-
-  public class PhantomReference<T> extends java.lang.ref.Reference<T> {
-    ctor public PhantomReference(T, java.lang.ref.ReferenceQueue<? super T>);
-  }
-
-  public abstract class Reference<T> {
-    method public void clear();
-    method public boolean enqueue();
-    method public T get();
-    method public boolean isEnqueued();
-    method public static void reachabilityFence(Object);
-  }
-
-  public class ReferenceQueue<T> {
-    ctor public ReferenceQueue();
-    method public java.lang.ref.Reference<? extends T> poll();
-    method public java.lang.ref.Reference<? extends T> remove(long) throws java.lang.IllegalArgumentException, java.lang.InterruptedException;
-    method public java.lang.ref.Reference<? extends T> remove() throws java.lang.InterruptedException;
-  }
-
-  public class SoftReference<T> extends java.lang.ref.Reference<T> {
-    ctor public SoftReference(T);
-    ctor public SoftReference(T, java.lang.ref.ReferenceQueue<? super T>);
-  }
-
-  public class WeakReference<T> extends java.lang.ref.Reference<T> {
-    ctor public WeakReference(T);
-    ctor public WeakReference(T, java.lang.ref.ReferenceQueue<? super T>);
-  }
-
-}
-
-package java.lang.reflect {
-
-  public class AccessibleObject implements java.lang.reflect.AnnotatedElement {
-    ctor protected AccessibleObject();
-    method @Nullable public <T extends java.lang.annotation.Annotation> T getAnnotation(@NonNull Class<T>);
-    method @NonNull public java.lang.annotation.Annotation[] getAnnotations();
-    method @NonNull public java.lang.annotation.Annotation[] getDeclaredAnnotations();
-    method public boolean isAccessible();
-    method public static void setAccessible(java.lang.reflect.AccessibleObject[], boolean) throws java.lang.SecurityException;
-    method public void setAccessible(boolean) throws java.lang.SecurityException;
-  }
-
-  public interface AnnotatedElement {
-    method @Nullable public <T extends java.lang.annotation.Annotation> T getAnnotation(@NonNull Class<T>);
-    method @NonNull public java.lang.annotation.Annotation[] getAnnotations();
-    method public default <T extends java.lang.annotation.Annotation> T[] getAnnotationsByType(@NonNull Class<T>);
-    method @Nullable public default <T extends java.lang.annotation.Annotation> T getDeclaredAnnotation(@NonNull Class<T>);
-    method @NonNull public java.lang.annotation.Annotation[] getDeclaredAnnotations();
-    method public default <T extends java.lang.annotation.Annotation> T[] getDeclaredAnnotationsByType(@NonNull Class<T>);
-    method public default boolean isAnnotationPresent(@NonNull Class<? extends java.lang.annotation.Annotation>);
-  }
-
-  public final class Array {
-    method @Nullable public static Object get(@NonNull Object, int) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException;
-    method public static boolean getBoolean(@NonNull Object, int) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException;
-    method public static byte getByte(@NonNull Object, int) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException;
-    method public static char getChar(@NonNull Object, int) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException;
-    method public static double getDouble(@NonNull Object, int) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException;
-    method public static float getFloat(@NonNull Object, int) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException;
-    method public static int getInt(@NonNull Object, int) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException;
-    method public static int getLength(@NonNull Object);
-    method public static long getLong(@NonNull Object, int) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException;
-    method public static short getShort(@NonNull Object, int) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException;
-    method @NonNull public static Object newInstance(@NonNull Class<?>, int) throws java.lang.NegativeArraySizeException;
-    method @NonNull public static Object newInstance(@NonNull Class<?>, int...) throws java.lang.IllegalArgumentException, java.lang.NegativeArraySizeException;
-    method public static void set(@NonNull Object, int, @Nullable Object) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException;
-    method public static void setBoolean(@NonNull Object, int, boolean);
-    method public static void setByte(@NonNull Object, int, byte) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException;
-    method public static void setChar(@NonNull Object, int, char) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException;
-    method public static void setDouble(@NonNull Object, int, double) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException;
-    method public static void setFloat(@NonNull Object, int, float) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException;
-    method public static void setInt(@NonNull Object, int, int) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException;
-    method public static void setLong(@NonNull Object, int, long) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException;
-    method public static void setShort(@NonNull Object, int, short) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException;
-  }
-
-  public final class Constructor<T> extends java.lang.reflect.Executable {
-    method @NonNull public Class<T> getDeclaringClass();
-    method public Class<?>[] getExceptionTypes();
-    method public int getModifiers();
-    method @NonNull public String getName();
-    method public java.lang.annotation.Annotation[][] getParameterAnnotations();
-    method @NonNull public Class<?>[] getParameterTypes();
-    method public java.lang.reflect.TypeVariable<java.lang.reflect.Constructor<T>>[] getTypeParameters();
-    method @NonNull public T newInstance(java.lang.Object...) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException, java.lang.InstantiationException, java.lang.reflect.InvocationTargetException;
-    method @NonNull public String toGenericString();
-  }
-
-  public abstract class Executable extends java.lang.reflect.AccessibleObject implements java.lang.reflect.GenericDeclaration java.lang.reflect.Member {
-    method @NonNull public abstract Class<?>[] getExceptionTypes();
-    method @NonNull public java.lang.reflect.Type[] getGenericExceptionTypes();
-    method @NonNull public java.lang.reflect.Type[] getGenericParameterTypes();
-    method @NonNull public abstract java.lang.annotation.Annotation[][] getParameterAnnotations();
-    method public int getParameterCount();
-    method @NonNull public abstract Class<?>[] getParameterTypes();
-    method @NonNull public java.lang.reflect.Parameter[] getParameters();
-    method public final boolean isAnnotationPresent(@NonNull Class<? extends java.lang.annotation.Annotation>);
-    method public boolean isSynthetic();
-    method public boolean isVarArgs();
-    method @NonNull public abstract String toGenericString();
-  }
-
-  public final class Field extends java.lang.reflect.AccessibleObject implements java.lang.reflect.Member {
-    method @Nullable public Object get(@Nullable Object) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
-    method public boolean getBoolean(@Nullable Object) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
-    method public byte getByte(@Nullable Object) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
-    method public char getChar(@Nullable Object) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
-    method @NonNull public Class<?> getDeclaringClass();
-    method public double getDouble(@Nullable Object) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
-    method public float getFloat(@Nullable Object) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
-    method @NonNull public java.lang.reflect.Type getGenericType();
-    method public int getInt(@Nullable Object) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
-    method public long getLong(@Nullable Object) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
-    method public int getModifiers();
-    method @NonNull public String getName();
-    method public short getShort(@Nullable Object) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
-    method @NonNull public Class<?> getType();
-    method public boolean isEnumConstant();
-    method public boolean isSynthetic();
-    method public void set(@Nullable Object, @Nullable Object) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
-    method public void setBoolean(@Nullable Object, boolean) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
-    method public void setByte(@Nullable Object, byte) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
-    method public void setChar(@Nullable Object, char) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
-    method public void setDouble(@Nullable Object, double) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
-    method public void setFloat(@Nullable Object, float) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
-    method public void setInt(@Nullable Object, int) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
-    method public void setLong(@Nullable Object, long) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
-    method public void setShort(@Nullable Object, short) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
-    method @NonNull public String toGenericString();
-  }
-
-  public interface GenericArrayType extends java.lang.reflect.Type {
-    method @NonNull public java.lang.reflect.Type getGenericComponentType();
-  }
-
-  public interface GenericDeclaration extends java.lang.reflect.AnnotatedElement {
-    method @NonNull public java.lang.reflect.TypeVariable<?>[] getTypeParameters();
-  }
-
-  public class GenericSignatureFormatError extends java.lang.ClassFormatError {
-    ctor public GenericSignatureFormatError();
-    ctor public GenericSignatureFormatError(String);
-  }
-
-  public interface InvocationHandler {
-    method public Object invoke(Object, java.lang.reflect.Method, Object[]) throws java.lang.Throwable;
-  }
-
-  public class InvocationTargetException extends java.lang.ReflectiveOperationException {
-    ctor protected InvocationTargetException();
-    ctor public InvocationTargetException(Throwable);
-    ctor public InvocationTargetException(Throwable, String);
-    method public Throwable getTargetException();
-  }
-
-  public class MalformedParameterizedTypeException extends java.lang.RuntimeException {
-    ctor public MalformedParameterizedTypeException();
-  }
-
-  public class MalformedParametersException extends java.lang.RuntimeException {
-    ctor public MalformedParametersException();
-    ctor public MalformedParametersException(String);
-  }
-
-  public interface Member {
-    method @NonNull public Class<?> getDeclaringClass();
-    method public int getModifiers();
-    method @NonNull public String getName();
-    method public boolean isSynthetic();
-    field public static final int DECLARED = 1; // 0x1
-    field public static final int PUBLIC = 0; // 0x0
-  }
-
-  public final class Method extends java.lang.reflect.Executable {
-    method @NonNull public Class<?> getDeclaringClass();
-    method @Nullable public Object getDefaultValue();
-    method @NonNull public Class<?>[] getExceptionTypes();
-    method @NonNull public java.lang.reflect.Type getGenericReturnType();
-    method public int getModifiers();
-    method @NonNull public String getName();
-    method @NonNull public java.lang.annotation.Annotation[][] getParameterAnnotations();
-    method @NonNull public Class<?>[] getParameterTypes();
-    method @NonNull public Class<?> getReturnType();
-    method @NonNull public java.lang.reflect.TypeVariable<java.lang.reflect.Method>[] getTypeParameters();
-    method @Nullable public Object invoke(@Nullable Object, @Nullable java.lang.Object...) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException, java.lang.reflect.InvocationTargetException;
-    method public boolean isBridge();
-    method public boolean isDefault();
-    method @NonNull public String toGenericString();
-  }
-
-  public class Modifier {
-    ctor public Modifier();
-    method public static int classModifiers();
-    method public static int constructorModifiers();
-    method public static int fieldModifiers();
-    method public static int interfaceModifiers();
-    method public static boolean isAbstract(int);
-    method public static boolean isFinal(int);
-    method public static boolean isInterface(int);
-    method public static boolean isNative(int);
-    method public static boolean isPrivate(int);
-    method public static boolean isProtected(int);
-    method public static boolean isPublic(int);
-    method public static boolean isStatic(int);
-    method public static boolean isStrict(int);
-    method public static boolean isSynchronized(int);
-    method public static boolean isTransient(int);
-    method public static boolean isVolatile(int);
-    method public static int methodModifiers();
-    method public static int parameterModifiers();
-    method public static String toString(int);
-    field public static final int ABSTRACT = 1024; // 0x400
-    field public static final int FINAL = 16; // 0x10
-    field public static final int INTERFACE = 512; // 0x200
-    field public static final int NATIVE = 256; // 0x100
-    field public static final int PRIVATE = 2; // 0x2
-    field public static final int PROTECTED = 4; // 0x4
-    field public static final int PUBLIC = 1; // 0x1
-    field public static final int STATIC = 8; // 0x8
-    field public static final int STRICT = 2048; // 0x800
-    field public static final int SYNCHRONIZED = 32; // 0x20
-    field public static final int TRANSIENT = 128; // 0x80
-    field public static final int VOLATILE = 64; // 0x40
-  }
-
-  public final class Parameter implements java.lang.reflect.AnnotatedElement {
-    method @Nullable public <T extends java.lang.annotation.Annotation> T getAnnotation(@NonNull Class<T>);
-    method @NonNull public java.lang.annotation.Annotation[] getAnnotations();
-    method @NonNull public java.lang.annotation.Annotation[] getDeclaredAnnotations();
-    method @NonNull public java.lang.reflect.Executable getDeclaringExecutable();
-    method public int getModifiers();
-    method @NonNull public String getName();
-    method @NonNull public java.lang.reflect.Type getParameterizedType();
-    method @NonNull public Class<?> getType();
-    method public boolean isImplicit();
-    method public boolean isNamePresent();
-    method public boolean isSynthetic();
-    method public boolean isVarArgs();
-  }
-
-  public interface ParameterizedType extends java.lang.reflect.Type {
-    method @NonNull public java.lang.reflect.Type[] getActualTypeArguments();
-    method @Nullable public java.lang.reflect.Type getOwnerType();
-    method @NonNull public java.lang.reflect.Type getRawType();
-  }
-
-  public class Proxy implements java.io.Serializable {
-    ctor protected Proxy(@NonNull java.lang.reflect.InvocationHandler);
-    method @NonNull public static java.lang.reflect.InvocationHandler getInvocationHandler(@NonNull Object) throws java.lang.IllegalArgumentException;
-    method @NonNull public static Class<?> getProxyClass(@Nullable ClassLoader, @NonNull Class<?>...) throws java.lang.IllegalArgumentException;
-    method public static boolean isProxyClass(@NonNull Class<?>);
-    method @NonNull public static Object newProxyInstance(@Nullable ClassLoader, @NonNull Class<?>[], @NonNull java.lang.reflect.InvocationHandler) throws java.lang.IllegalArgumentException;
-    field protected java.lang.reflect.InvocationHandler h;
-  }
-
-  public final class ReflectPermission extends java.security.BasicPermission {
-    ctor public ReflectPermission(String);
-    ctor public ReflectPermission(String, String);
-  }
-
-  public interface Type {
-    method @NonNull public default String getTypeName();
-  }
-
-  public interface TypeVariable<D extends java.lang.reflect.GenericDeclaration> extends java.lang.reflect.Type {
-    method @NonNull public java.lang.reflect.Type[] getBounds();
-    method @NonNull public D getGenericDeclaration();
-    method @NonNull public String getName();
-  }
-
-  public class UndeclaredThrowableException extends java.lang.RuntimeException {
-    ctor public UndeclaredThrowableException(Throwable);
-    ctor public UndeclaredThrowableException(Throwable, String);
-    method public Throwable getUndeclaredThrowable();
-  }
-
-  public interface WildcardType extends java.lang.reflect.Type {
-    method @NonNull public java.lang.reflect.Type[] getLowerBounds();
-    method @NonNull public java.lang.reflect.Type[] getUpperBounds();
-  }
-
-}
-
-package java.math {
-
-  public class BigDecimal extends java.lang.Number implements java.lang.Comparable<java.math.BigDecimal> {
-    ctor public BigDecimal(char[], int, int);
-    ctor public BigDecimal(char[], int, int, java.math.MathContext);
-    ctor public BigDecimal(char[]);
-    ctor public BigDecimal(char[], java.math.MathContext);
-    ctor public BigDecimal(String);
-    ctor public BigDecimal(String, java.math.MathContext);
-    ctor public BigDecimal(double);
-    ctor public BigDecimal(double, java.math.MathContext);
-    ctor public BigDecimal(java.math.BigInteger);
-    ctor public BigDecimal(java.math.BigInteger, java.math.MathContext);
-    ctor public BigDecimal(java.math.BigInteger, int);
-    ctor public BigDecimal(java.math.BigInteger, int, java.math.MathContext);
-    ctor public BigDecimal(int);
-    ctor public BigDecimal(int, java.math.MathContext);
-    ctor public BigDecimal(long);
-    ctor public BigDecimal(long, java.math.MathContext);
-    method public java.math.BigDecimal abs();
-    method public java.math.BigDecimal abs(java.math.MathContext);
-    method public java.math.BigDecimal add(java.math.BigDecimal);
-    method public java.math.BigDecimal add(java.math.BigDecimal, java.math.MathContext);
-    method public byte byteValueExact();
-    method public int compareTo(java.math.BigDecimal);
-    method public java.math.BigDecimal divide(java.math.BigDecimal, int, int);
-    method public java.math.BigDecimal divide(java.math.BigDecimal, int, java.math.RoundingMode);
-    method public java.math.BigDecimal divide(java.math.BigDecimal, int);
-    method public java.math.BigDecimal divide(java.math.BigDecimal, java.math.RoundingMode);
-    method public java.math.BigDecimal divide(java.math.BigDecimal);
-    method public java.math.BigDecimal divide(java.math.BigDecimal, java.math.MathContext);
-    method public java.math.BigDecimal[] divideAndRemainder(java.math.BigDecimal);
-    method public java.math.BigDecimal[] divideAndRemainder(java.math.BigDecimal, java.math.MathContext);
-    method public java.math.BigDecimal divideToIntegralValue(java.math.BigDecimal);
-    method public java.math.BigDecimal divideToIntegralValue(java.math.BigDecimal, java.math.MathContext);
-    method public double doubleValue();
-    method public float floatValue();
-    method public int intValue();
-    method public int intValueExact();
-    method public long longValue();
-    method public long longValueExact();
-    method public java.math.BigDecimal max(java.math.BigDecimal);
-    method public java.math.BigDecimal min(java.math.BigDecimal);
-    method public java.math.BigDecimal movePointLeft(int);
-    method public java.math.BigDecimal movePointRight(int);
-    method public java.math.BigDecimal multiply(java.math.BigDecimal);
-    method public java.math.BigDecimal multiply(java.math.BigDecimal, java.math.MathContext);
-    method public java.math.BigDecimal negate();
-    method public java.math.BigDecimal negate(java.math.MathContext);
-    method public java.math.BigDecimal plus();
-    method public java.math.BigDecimal plus(java.math.MathContext);
-    method public java.math.BigDecimal pow(int);
-    method public java.math.BigDecimal pow(int, java.math.MathContext);
-    method public int precision();
-    method public java.math.BigDecimal remainder(java.math.BigDecimal);
-    method public java.math.BigDecimal remainder(java.math.BigDecimal, java.math.MathContext);
-    method public java.math.BigDecimal round(java.math.MathContext);
-    method public int scale();
-    method public java.math.BigDecimal scaleByPowerOfTen(int);
-    method public java.math.BigDecimal setScale(int, java.math.RoundingMode);
-    method public java.math.BigDecimal setScale(int, int);
-    method public java.math.BigDecimal setScale(int);
-    method public short shortValueExact();
-    method public int signum();
-    method public java.math.BigDecimal stripTrailingZeros();
-    method public java.math.BigDecimal subtract(java.math.BigDecimal);
-    method public java.math.BigDecimal subtract(java.math.BigDecimal, java.math.MathContext);
-    method public java.math.BigInteger toBigInteger();
-    method public java.math.BigInteger toBigIntegerExact();
-    method public String toEngineeringString();
-    method public String toPlainString();
-    method public java.math.BigDecimal ulp();
-    method public java.math.BigInteger unscaledValue();
-    method public static java.math.BigDecimal valueOf(long, int);
-    method public static java.math.BigDecimal valueOf(long);
-    method public static java.math.BigDecimal valueOf(double);
-    field public static final java.math.BigDecimal ONE;
-    field public static final int ROUND_CEILING = 2; // 0x2
-    field public static final int ROUND_DOWN = 1; // 0x1
-    field public static final int ROUND_FLOOR = 3; // 0x3
-    field public static final int ROUND_HALF_DOWN = 5; // 0x5
-    field public static final int ROUND_HALF_EVEN = 6; // 0x6
-    field public static final int ROUND_HALF_UP = 4; // 0x4
-    field public static final int ROUND_UNNECESSARY = 7; // 0x7
-    field public static final int ROUND_UP = 0; // 0x0
-    field public static final java.math.BigDecimal TEN;
-    field public static final java.math.BigDecimal ZERO;
-  }
-
-  public class BigInteger extends java.lang.Number implements java.lang.Comparable<java.math.BigInteger> {
-    ctor public BigInteger(byte[]);
-    ctor public BigInteger(int, byte[]);
-    ctor public BigInteger(@NonNull String, int);
-    ctor public BigInteger(@NonNull String);
-    ctor public BigInteger(int, @NonNull java.util.Random);
-    ctor public BigInteger(int, int, @NonNull java.util.Random);
-    method @NonNull public java.math.BigInteger abs();
-    method @NonNull public java.math.BigInteger add(@NonNull java.math.BigInteger);
-    method @NonNull public java.math.BigInteger and(@NonNull java.math.BigInteger);
-    method @NonNull public java.math.BigInteger andNot(@NonNull java.math.BigInteger);
-    method public int bitCount();
-    method public int bitLength();
-    method public byte byteValueExact();
-    method @NonNull public java.math.BigInteger clearBit(int);
-    method public int compareTo(@NonNull java.math.BigInteger);
-    method @NonNull public java.math.BigInteger divide(@NonNull java.math.BigInteger);
-    method @NonNull public java.math.BigInteger[] divideAndRemainder(@NonNull java.math.BigInteger);
-    method public double doubleValue();
-    method @NonNull public java.math.BigInteger flipBit(int);
-    method public float floatValue();
-    method @NonNull public java.math.BigInteger gcd(@NonNull java.math.BigInteger);
-    method public int getLowestSetBit();
-    method public int intValue();
-    method public int intValueExact();
-    method public boolean isProbablePrime(int);
-    method public long longValue();
-    method public long longValueExact();
-    method @NonNull public java.math.BigInteger max(@NonNull java.math.BigInteger);
-    method @NonNull public java.math.BigInteger min(@NonNull java.math.BigInteger);
-    method @NonNull public java.math.BigInteger mod(@NonNull java.math.BigInteger);
-    method @NonNull public java.math.BigInteger modInverse(@NonNull java.math.BigInteger);
-    method @NonNull public java.math.BigInteger modPow(@NonNull java.math.BigInteger, @NonNull java.math.BigInteger);
-    method @NonNull public java.math.BigInteger multiply(@NonNull java.math.BigInteger);
-    method @NonNull public java.math.BigInteger negate();
-    method @NonNull public java.math.BigInteger nextProbablePrime();
-    method @NonNull public java.math.BigInteger not();
-    method @NonNull public java.math.BigInteger or(@NonNull java.math.BigInteger);
-    method @NonNull public java.math.BigInteger pow(int);
-    method @NonNull public static java.math.BigInteger probablePrime(int, @NonNull java.util.Random);
-    method @NonNull public java.math.BigInteger remainder(@NonNull java.math.BigInteger);
-    method @NonNull public java.math.BigInteger setBit(int);
-    method @NonNull public java.math.BigInteger shiftLeft(int);
-    method @NonNull public java.math.BigInteger shiftRight(int);
-    method public short shortValueExact();
-    method public int signum();
-    method @NonNull public java.math.BigInteger subtract(@NonNull java.math.BigInteger);
-    method public boolean testBit(int);
-    method public byte[] toByteArray();
-    method @NonNull public String toString(int);
-    method @NonNull public static java.math.BigInteger valueOf(long);
-    method @NonNull public java.math.BigInteger xor(@NonNull java.math.BigInteger);
-    field @NonNull public static final java.math.BigInteger ONE;
-    field @NonNull public static final java.math.BigInteger TEN;
-    field @NonNull public static final java.math.BigInteger ZERO;
-  }
-
-  public final class MathContext implements java.io.Serializable {
-    ctor public MathContext(int);
-    ctor public MathContext(int, java.math.RoundingMode);
-    ctor public MathContext(String);
-    method public int getPrecision();
-    method public java.math.RoundingMode getRoundingMode();
-    field public static final java.math.MathContext DECIMAL128;
-    field public static final java.math.MathContext DECIMAL32;
-    field public static final java.math.MathContext DECIMAL64;
-    field public static final java.math.MathContext UNLIMITED;
-  }
-
-  public enum RoundingMode {
-    method public static java.math.RoundingMode valueOf(int);
-    enum_constant public static final java.math.RoundingMode CEILING;
-    enum_constant public static final java.math.RoundingMode DOWN;
-    enum_constant public static final java.math.RoundingMode FLOOR;
-    enum_constant public static final java.math.RoundingMode HALF_DOWN;
-    enum_constant public static final java.math.RoundingMode HALF_EVEN;
-    enum_constant public static final java.math.RoundingMode HALF_UP;
-    enum_constant public static final java.math.RoundingMode UNNECESSARY;
-    enum_constant public static final java.math.RoundingMode UP;
-  }
-
-}
-
-package java.net {
-
-  public abstract class Authenticator {
-    ctor public Authenticator();
-    method protected java.net.PasswordAuthentication getPasswordAuthentication();
-    method protected final String getRequestingHost();
-    method protected final int getRequestingPort();
-    method protected final String getRequestingPrompt();
-    method protected final String getRequestingProtocol();
-    method protected final String getRequestingScheme();
-    method protected final java.net.InetAddress getRequestingSite();
-    method protected java.net.URL getRequestingURL();
-    method protected java.net.Authenticator.RequestorType getRequestorType();
-    method public static java.net.PasswordAuthentication requestPasswordAuthentication(java.net.InetAddress, int, String, String, String);
-    method public static java.net.PasswordAuthentication requestPasswordAuthentication(String, java.net.InetAddress, int, String, String, String);
-    method public static java.net.PasswordAuthentication requestPasswordAuthentication(String, java.net.InetAddress, int, String, String, String, java.net.URL, java.net.Authenticator.RequestorType);
-    method public static void setDefault(java.net.Authenticator);
-  }
-
-  public enum Authenticator.RequestorType {
-    enum_constant public static final java.net.Authenticator.RequestorType PROXY;
-    enum_constant public static final java.net.Authenticator.RequestorType SERVER;
-  }
-
-  public class BindException extends java.net.SocketException {
-    ctor public BindException(String);
-    ctor public BindException();
-  }
-
-  public abstract class CacheRequest {
-    ctor public CacheRequest();
-    method public abstract void abort();
-    method public abstract java.io.OutputStream getBody() throws java.io.IOException;
-  }
-
-  public abstract class CacheResponse {
-    ctor public CacheResponse();
-    method public abstract java.io.InputStream getBody() throws java.io.IOException;
-    method public abstract java.util.Map<java.lang.String,java.util.List<java.lang.String>> getHeaders() throws java.io.IOException;
-  }
-
-  public class ConnectException extends java.net.SocketException {
-    ctor public ConnectException(String);
-    ctor public ConnectException();
-  }
-
-  public abstract class ContentHandler {
-    ctor public ContentHandler();
-    method public abstract Object getContent(java.net.URLConnection) throws java.io.IOException;
-    method public Object getContent(java.net.URLConnection, Class[]) throws java.io.IOException;
-  }
-
-  public interface ContentHandlerFactory {
-    method public java.net.ContentHandler createContentHandler(String);
-  }
-
-  public abstract class CookieHandler {
-    ctor public CookieHandler();
-    method public abstract java.util.Map<java.lang.String,java.util.List<java.lang.String>> get(java.net.URI, java.util.Map<java.lang.String,java.util.List<java.lang.String>>) throws java.io.IOException;
-    method public static java.net.CookieHandler getDefault();
-    method public abstract void put(java.net.URI, java.util.Map<java.lang.String,java.util.List<java.lang.String>>) throws java.io.IOException;
-    method public static void setDefault(java.net.CookieHandler);
-  }
-
-  public class CookieManager extends java.net.CookieHandler {
-    ctor public CookieManager();
-    ctor public CookieManager(java.net.CookieStore, java.net.CookiePolicy);
-    method public java.util.Map<java.lang.String,java.util.List<java.lang.String>> get(java.net.URI, java.util.Map<java.lang.String,java.util.List<java.lang.String>>) throws java.io.IOException;
-    method public java.net.CookieStore getCookieStore();
-    method public void put(java.net.URI, java.util.Map<java.lang.String,java.util.List<java.lang.String>>) throws java.io.IOException;
-    method public void setCookiePolicy(java.net.CookiePolicy);
-  }
-
-  public interface CookiePolicy {
-    method public boolean shouldAccept(java.net.URI, java.net.HttpCookie);
-    field public static final java.net.CookiePolicy ACCEPT_ALL;
-    field public static final java.net.CookiePolicy ACCEPT_NONE;
-    field public static final java.net.CookiePolicy ACCEPT_ORIGINAL_SERVER;
-  }
-
-  public interface CookieStore {
-    method public void add(java.net.URI, java.net.HttpCookie);
-    method public java.util.List<java.net.HttpCookie> get(java.net.URI);
-    method public java.util.List<java.net.HttpCookie> getCookies();
-    method public java.util.List<java.net.URI> getURIs();
-    method public boolean remove(java.net.URI, java.net.HttpCookie);
-    method public boolean removeAll();
-  }
-
-  public final class DatagramPacket {
-    ctor public DatagramPacket(byte[], int, int);
-    ctor public DatagramPacket(byte[], int);
-    ctor public DatagramPacket(byte[], int, int, java.net.InetAddress, int);
-    ctor public DatagramPacket(byte[], int, int, java.net.SocketAddress);
-    ctor public DatagramPacket(byte[], int, java.net.InetAddress, int);
-    ctor public DatagramPacket(byte[], int, java.net.SocketAddress);
-    method public java.net.InetAddress getAddress();
-    method public byte[] getData();
-    method public int getLength();
-    method public int getOffset();
-    method public int getPort();
-    method public java.net.SocketAddress getSocketAddress();
-    method public void setAddress(java.net.InetAddress);
-    method public void setData(byte[], int, int);
-    method public void setData(byte[]);
-    method public void setLength(int);
-    method public void setPort(int);
-    method public void setSocketAddress(java.net.SocketAddress);
-  }
-
-  public class DatagramSocket implements java.io.Closeable {
-    ctor public DatagramSocket() throws java.net.SocketException;
-    ctor protected DatagramSocket(java.net.DatagramSocketImpl);
-    ctor public DatagramSocket(java.net.SocketAddress) throws java.net.SocketException;
-    ctor public DatagramSocket(int) throws java.net.SocketException;
-    ctor public DatagramSocket(int, java.net.InetAddress) throws java.net.SocketException;
-    method public void bind(java.net.SocketAddress) throws java.net.SocketException;
-    method public void close();
-    method public void connect(java.net.InetAddress, int);
-    method public void connect(java.net.SocketAddress) throws java.net.SocketException;
-    method public void disconnect();
-    method public boolean getBroadcast() throws java.net.SocketException;
-    method public java.nio.channels.DatagramChannel getChannel();
-    method public java.net.InetAddress getInetAddress();
-    method public java.net.InetAddress getLocalAddress();
-    method public int getLocalPort();
-    method public java.net.SocketAddress getLocalSocketAddress();
-    method public int getPort();
-    method public int getReceiveBufferSize() throws java.net.SocketException;
-    method public java.net.SocketAddress getRemoteSocketAddress();
-    method public boolean getReuseAddress() throws java.net.SocketException;
-    method public int getSendBufferSize() throws java.net.SocketException;
-    method public int getSoTimeout() throws java.net.SocketException;
-    method public int getTrafficClass() throws java.net.SocketException;
-    method public boolean isBound();
-    method public boolean isClosed();
-    method public boolean isConnected();
-    method public void receive(java.net.DatagramPacket) throws java.io.IOException;
-    method public void send(java.net.DatagramPacket) throws java.io.IOException;
-    method public void setBroadcast(boolean) throws java.net.SocketException;
-    method public static void setDatagramSocketImplFactory(java.net.DatagramSocketImplFactory) throws java.io.IOException;
-    method public void setReceiveBufferSize(int) throws java.net.SocketException;
-    method public void setReuseAddress(boolean) throws java.net.SocketException;
-    method public void setSendBufferSize(int) throws java.net.SocketException;
-    method public void setSoTimeout(int) throws java.net.SocketException;
-    method public void setTrafficClass(int) throws java.net.SocketException;
-  }
-
-  public abstract class DatagramSocketImpl implements java.net.SocketOptions {
-    ctor public DatagramSocketImpl();
-    method protected abstract void bind(int, java.net.InetAddress) throws java.net.SocketException;
-    method protected abstract void close();
-    method protected void connect(java.net.InetAddress, int) throws java.net.SocketException;
-    method protected abstract void create() throws java.net.SocketException;
-    method protected void disconnect();
-    method protected java.io.FileDescriptor getFileDescriptor();
-    method protected int getLocalPort();
-    method @Deprecated protected abstract byte getTTL() throws java.io.IOException;
-    method protected abstract int getTimeToLive() throws java.io.IOException;
-    method protected abstract void join(java.net.InetAddress) throws java.io.IOException;
-    method protected abstract void joinGroup(java.net.SocketAddress, java.net.NetworkInterface) throws java.io.IOException;
-    method protected abstract void leave(java.net.InetAddress) throws java.io.IOException;
-    method protected abstract void leaveGroup(java.net.SocketAddress, java.net.NetworkInterface) throws java.io.IOException;
-    method protected abstract int peek(java.net.InetAddress) throws java.io.IOException;
-    method protected abstract int peekData(java.net.DatagramPacket) throws java.io.IOException;
-    method protected abstract void receive(java.net.DatagramPacket) throws java.io.IOException;
-    method protected abstract void send(java.net.DatagramPacket) throws java.io.IOException;
-    method @Deprecated protected abstract void setTTL(byte) throws java.io.IOException;
-    method protected abstract void setTimeToLive(int) throws java.io.IOException;
-    field protected java.io.FileDescriptor fd;
-    field protected int localPort;
-  }
-
-  public interface DatagramSocketImplFactory {
-    method public java.net.DatagramSocketImpl createDatagramSocketImpl();
-  }
-
-  public interface FileNameMap {
-    method public String getContentTypeFor(String);
-  }
-
-  public final class HttpCookie implements java.lang.Cloneable {
-    ctor public HttpCookie(String, String);
-    method public Object clone();
-    method public static boolean domainMatches(String, String);
-    method public String getComment();
-    method public String getCommentURL();
-    method public boolean getDiscard();
-    method public String getDomain();
-    method public long getMaxAge();
-    method public String getName();
-    method public String getPath();
-    method public String getPortlist();
-    method public boolean getSecure();
-    method public String getValue();
-    method public int getVersion();
-    method public boolean hasExpired();
-    method public boolean isHttpOnly();
-    method public static java.util.List<java.net.HttpCookie> parse(String);
-    method public void setComment(String);
-    method public void setCommentURL(String);
-    method public void setDiscard(boolean);
-    method public void setDomain(String);
-    method public void setHttpOnly(boolean);
-    method public void setMaxAge(long);
-    method public void setPath(String);
-    method public void setPortlist(String);
-    method public void setSecure(boolean);
-    method public void setValue(String);
-    method public void setVersion(int);
-  }
-
-  public class HttpRetryException extends java.io.IOException {
-    ctor public HttpRetryException(String, int);
-    ctor public HttpRetryException(String, int, String);
-    method public String getLocation();
-    method public String getReason();
-    method public int responseCode();
-  }
-
-  public abstract class HttpURLConnection extends java.net.URLConnection {
-    ctor protected HttpURLConnection(java.net.URL);
-    method public abstract void disconnect();
-    method public java.io.InputStream getErrorStream();
-    method public static boolean getFollowRedirects();
-    method public boolean getInstanceFollowRedirects();
-    method public String getRequestMethod();
-    method public int getResponseCode() throws java.io.IOException;
-    method public String getResponseMessage() throws java.io.IOException;
-    method public void setChunkedStreamingMode(int);
-    method public void setFixedLengthStreamingMode(int);
-    method public void setFixedLengthStreamingMode(long);
-    method public static void setFollowRedirects(boolean);
-    method public void setInstanceFollowRedirects(boolean);
-    method public void setRequestMethod(String) throws java.net.ProtocolException;
-    method public abstract boolean usingProxy();
-    field public static final int HTTP_ACCEPTED = 202; // 0xca
-    field public static final int HTTP_BAD_GATEWAY = 502; // 0x1f6
-    field public static final int HTTP_BAD_METHOD = 405; // 0x195
-    field public static final int HTTP_BAD_REQUEST = 400; // 0x190
-    field public static final int HTTP_CLIENT_TIMEOUT = 408; // 0x198
-    field public static final int HTTP_CONFLICT = 409; // 0x199
-    field public static final int HTTP_CREATED = 201; // 0xc9
-    field public static final int HTTP_ENTITY_TOO_LARGE = 413; // 0x19d
-    field public static final int HTTP_FORBIDDEN = 403; // 0x193
-    field public static final int HTTP_GATEWAY_TIMEOUT = 504; // 0x1f8
-    field public static final int HTTP_GONE = 410; // 0x19a
-    field public static final int HTTP_INTERNAL_ERROR = 500; // 0x1f4
-    field public static final int HTTP_LENGTH_REQUIRED = 411; // 0x19b
-    field public static final int HTTP_MOVED_PERM = 301; // 0x12d
-    field public static final int HTTP_MOVED_TEMP = 302; // 0x12e
-    field public static final int HTTP_MULT_CHOICE = 300; // 0x12c
-    field public static final int HTTP_NOT_ACCEPTABLE = 406; // 0x196
-    field public static final int HTTP_NOT_AUTHORITATIVE = 203; // 0xcb
-    field public static final int HTTP_NOT_FOUND = 404; // 0x194
-    field public static final int HTTP_NOT_IMPLEMENTED = 501; // 0x1f5
-    field public static final int HTTP_NOT_MODIFIED = 304; // 0x130
-    field public static final int HTTP_NO_CONTENT = 204; // 0xcc
-    field public static final int HTTP_OK = 200; // 0xc8
-    field public static final int HTTP_PARTIAL = 206; // 0xce
-    field public static final int HTTP_PAYMENT_REQUIRED = 402; // 0x192
-    field public static final int HTTP_PRECON_FAILED = 412; // 0x19c
-    field public static final int HTTP_PROXY_AUTH = 407; // 0x197
-    field public static final int HTTP_REQ_TOO_LONG = 414; // 0x19e
-    field public static final int HTTP_RESET = 205; // 0xcd
-    field public static final int HTTP_SEE_OTHER = 303; // 0x12f
-    field @Deprecated public static final int HTTP_SERVER_ERROR = 500; // 0x1f4
-    field public static final int HTTP_UNAUTHORIZED = 401; // 0x191
-    field public static final int HTTP_UNAVAILABLE = 503; // 0x1f7
-    field public static final int HTTP_UNSUPPORTED_TYPE = 415; // 0x19f
-    field public static final int HTTP_USE_PROXY = 305; // 0x131
-    field public static final int HTTP_VERSION = 505; // 0x1f9
-    field protected int chunkLength;
-    field protected int fixedContentLength;
-    field protected long fixedContentLengthLong;
-    field protected boolean instanceFollowRedirects;
-    field protected String method;
-    field protected int responseCode;
-    field protected String responseMessage;
-  }
-
-  public final class IDN {
-    method public static String toASCII(String, int);
-    method public static String toASCII(String);
-    method public static String toUnicode(String, int);
-    method public static String toUnicode(String);
-    field public static final int ALLOW_UNASSIGNED = 1; // 0x1
-    field public static final int USE_STD3_ASCII_RULES = 2; // 0x2
-  }
-
-  public final class Inet4Address extends java.net.InetAddress {
-  }
-
-  public final class Inet6Address extends java.net.InetAddress {
-    method public static java.net.Inet6Address getByAddress(String, byte[], java.net.NetworkInterface) throws java.net.UnknownHostException;
-    method public static java.net.Inet6Address getByAddress(String, byte[], int) throws java.net.UnknownHostException;
-    method public int getScopeId();
-    method public java.net.NetworkInterface getScopedInterface();
-    method public boolean isIPv4CompatibleAddress();
-  }
-
-  public class InetAddress implements java.io.Serializable {
-    method public byte[] getAddress();
-    method public static java.net.InetAddress[] getAllByName(String) throws java.net.UnknownHostException;
-    method public static java.net.InetAddress getByAddress(String, byte[]) throws java.net.UnknownHostException;
-    method public static java.net.InetAddress getByAddress(byte[]) throws java.net.UnknownHostException;
-    method public static java.net.InetAddress getByName(String) throws java.net.UnknownHostException;
-    method public String getCanonicalHostName();
-    method public String getHostAddress();
-    method public String getHostName();
-    method public static java.net.InetAddress getLocalHost() throws java.net.UnknownHostException;
-    method public static java.net.InetAddress getLoopbackAddress();
-    method public boolean isAnyLocalAddress();
-    method public boolean isLinkLocalAddress();
-    method public boolean isLoopbackAddress();
-    method public boolean isMCGlobal();
-    method public boolean isMCLinkLocal();
-    method public boolean isMCNodeLocal();
-    method public boolean isMCOrgLocal();
-    method public boolean isMCSiteLocal();
-    method public boolean isMulticastAddress();
-    method public boolean isReachable(int) throws java.io.IOException;
-    method public boolean isReachable(java.net.NetworkInterface, int, int) throws java.io.IOException;
-    method public boolean isSiteLocalAddress();
-  }
-
-  public class InetSocketAddress extends java.net.SocketAddress {
-    ctor public InetSocketAddress(int);
-    ctor public InetSocketAddress(java.net.InetAddress, int);
-    ctor public InetSocketAddress(String, int);
-    method public static java.net.InetSocketAddress createUnresolved(String, int);
-    method public final boolean equals(Object);
-    method public final java.net.InetAddress getAddress();
-    method public final String getHostName();
-    method public final String getHostString();
-    method public final int getPort();
-    method public final int hashCode();
-    method public final boolean isUnresolved();
-  }
-
-  public class InterfaceAddress {
-    method public java.net.InetAddress getAddress();
-    method public java.net.InetAddress getBroadcast();
-    method public short getNetworkPrefixLength();
-  }
-
-  public abstract class JarURLConnection extends java.net.URLConnection {
-    ctor protected JarURLConnection(java.net.URL) throws java.net.MalformedURLException;
-    method public java.util.jar.Attributes getAttributes() throws java.io.IOException;
-    method public java.security.cert.Certificate[] getCertificates() throws java.io.IOException;
-    method public String getEntryName();
-    method public java.util.jar.JarEntry getJarEntry() throws java.io.IOException;
-    method public abstract java.util.jar.JarFile getJarFile() throws java.io.IOException;
-    method public java.net.URL getJarFileURL();
-    method public java.util.jar.Attributes getMainAttributes() throws java.io.IOException;
-    method public java.util.jar.Manifest getManifest() throws java.io.IOException;
-    field protected java.net.URLConnection jarFileURLConnection;
-  }
-
-  public class MalformedURLException extends java.io.IOException {
-    ctor public MalformedURLException();
-    ctor public MalformedURLException(String);
-  }
-
-  public class MulticastSocket extends java.net.DatagramSocket {
-    ctor public MulticastSocket() throws java.io.IOException;
-    ctor public MulticastSocket(int) throws java.io.IOException;
-    ctor public MulticastSocket(java.net.SocketAddress) throws java.io.IOException;
-    method public java.net.InetAddress getInterface() throws java.net.SocketException;
-    method public boolean getLoopbackMode() throws java.net.SocketException;
-    method public java.net.NetworkInterface getNetworkInterface() throws java.net.SocketException;
-    method @Deprecated public byte getTTL() throws java.io.IOException;
-    method public int getTimeToLive() throws java.io.IOException;
-    method public void joinGroup(java.net.InetAddress) throws java.io.IOException;
-    method public void joinGroup(java.net.SocketAddress, java.net.NetworkInterface) throws java.io.IOException;
-    method public void leaveGroup(java.net.InetAddress) throws java.io.IOException;
-    method public void leaveGroup(java.net.SocketAddress, java.net.NetworkInterface) throws java.io.IOException;
-    method @Deprecated public void send(java.net.DatagramPacket, byte) throws java.io.IOException;
-    method public void setInterface(java.net.InetAddress) throws java.net.SocketException;
-    method public void setLoopbackMode(boolean) throws java.net.SocketException;
-    method public void setNetworkInterface(java.net.NetworkInterface) throws java.net.SocketException;
-    method @Deprecated public void setTTL(byte) throws java.io.IOException;
-    method public void setTimeToLive(int) throws java.io.IOException;
-  }
-
-  public final class NetPermission extends java.security.BasicPermission {
-    ctor public NetPermission(String);
-    ctor public NetPermission(String, String);
-  }
-
-  public final class NetworkInterface {
-    method public static java.net.NetworkInterface getByIndex(int) throws java.net.SocketException;
-    method public static java.net.NetworkInterface getByInetAddress(java.net.InetAddress) throws java.net.SocketException;
-    method public static java.net.NetworkInterface getByName(String) throws java.net.SocketException;
-    method public String getDisplayName();
-    method public byte[] getHardwareAddress() throws java.net.SocketException;
-    method public int getIndex();
-    method public java.util.Enumeration<java.net.InetAddress> getInetAddresses();
-    method public java.util.List<java.net.InterfaceAddress> getInterfaceAddresses();
-    method public int getMTU() throws java.net.SocketException;
-    method public String getName();
-    method public static java.util.Enumeration<java.net.NetworkInterface> getNetworkInterfaces() throws java.net.SocketException;
-    method public java.net.NetworkInterface getParent();
-    method public java.util.Enumeration<java.net.NetworkInterface> getSubInterfaces();
-    method public boolean isLoopback() throws java.net.SocketException;
-    method public boolean isPointToPoint() throws java.net.SocketException;
-    method public boolean isUp() throws java.net.SocketException;
-    method public boolean isVirtual();
-    method public boolean supportsMulticast() throws java.net.SocketException;
-  }
-
-  public class NoRouteToHostException extends java.net.SocketException {
-    ctor public NoRouteToHostException(String);
-    ctor public NoRouteToHostException();
-  }
-
-  public final class PasswordAuthentication {
-    ctor public PasswordAuthentication(String, char[]);
-    method public char[] getPassword();
-    method public String getUserName();
-  }
-
-  public class PortUnreachableException extends java.net.SocketException {
-    ctor public PortUnreachableException(String);
-    ctor public PortUnreachableException();
-  }
-
-  public class ProtocolException extends java.io.IOException {
-    ctor public ProtocolException(String);
-    ctor public ProtocolException();
-  }
-
-  public interface ProtocolFamily {
-    method public String name();
-  }
-
-  public class Proxy {
-    ctor public Proxy(java.net.Proxy.Type, java.net.SocketAddress);
-    method public java.net.SocketAddress address();
-    method public final boolean equals(Object);
-    method public final int hashCode();
-    method public java.net.Proxy.Type type();
-    field public static final java.net.Proxy NO_PROXY;
-  }
-
-  public enum Proxy.Type {
-    enum_constant public static final java.net.Proxy.Type DIRECT;
-    enum_constant public static final java.net.Proxy.Type HTTP;
-    enum_constant public static final java.net.Proxy.Type SOCKS;
-  }
-
-  public abstract class ProxySelector {
-    ctor public ProxySelector();
-    method public abstract void connectFailed(java.net.URI, java.net.SocketAddress, java.io.IOException);
-    method public static java.net.ProxySelector getDefault();
-    method public abstract java.util.List<java.net.Proxy> select(java.net.URI);
-    method public static void setDefault(java.net.ProxySelector);
-  }
-
-  public abstract class ResponseCache {
-    ctor public ResponseCache();
-    method public abstract java.net.CacheResponse get(java.net.URI, String, java.util.Map<java.lang.String,java.util.List<java.lang.String>>) throws java.io.IOException;
-    method public static java.net.ResponseCache getDefault();
-    method public abstract java.net.CacheRequest put(java.net.URI, java.net.URLConnection) throws java.io.IOException;
-    method public static void setDefault(java.net.ResponseCache);
-  }
-
-  public abstract class SecureCacheResponse extends java.net.CacheResponse {
-    ctor public SecureCacheResponse();
-    method public abstract String getCipherSuite();
-    method public abstract java.util.List<java.security.cert.Certificate> getLocalCertificateChain();
-    method public abstract java.security.Principal getLocalPrincipal();
-    method public abstract java.security.Principal getPeerPrincipal() throws javax.net.ssl.SSLPeerUnverifiedException;
-    method public abstract java.util.List<java.security.cert.Certificate> getServerCertificateChain() throws javax.net.ssl.SSLPeerUnverifiedException;
-  }
-
-  public class ServerSocket implements java.io.Closeable {
-    ctor public ServerSocket() throws java.io.IOException;
-    ctor public ServerSocket(int) throws java.io.IOException;
-    ctor public ServerSocket(int, int) throws java.io.IOException;
-    ctor public ServerSocket(int, int, java.net.InetAddress) throws java.io.IOException;
-    method public java.net.Socket accept() throws java.io.IOException;
-    method public void bind(java.net.SocketAddress) throws java.io.IOException;
-    method public void bind(java.net.SocketAddress, int) throws java.io.IOException;
-    method public void close() throws java.io.IOException;
-    method public java.nio.channels.ServerSocketChannel getChannel();
-    method public java.net.InetAddress getInetAddress();
-    method public int getLocalPort();
-    method public java.net.SocketAddress getLocalSocketAddress();
-    method public int getReceiveBufferSize() throws java.net.SocketException;
-    method public boolean getReuseAddress() throws java.net.SocketException;
-    method public int getSoTimeout() throws java.io.IOException;
-    method protected final void implAccept(java.net.Socket) throws java.io.IOException;
-    method public boolean isBound();
-    method public boolean isClosed();
-    method public void setPerformancePreferences(int, int, int);
-    method public void setReceiveBufferSize(int) throws java.net.SocketException;
-    method public void setReuseAddress(boolean) throws java.net.SocketException;
-    method public void setSoTimeout(int) throws java.net.SocketException;
-    method public static void setSocketFactory(java.net.SocketImplFactory) throws java.io.IOException;
-  }
-
-  public class Socket implements java.io.Closeable {
-    ctor public Socket();
-    ctor public Socket(java.net.Proxy);
-    ctor protected Socket(java.net.SocketImpl) throws java.net.SocketException;
-    ctor public Socket(String, int) throws java.io.IOException, java.net.UnknownHostException;
-    ctor public Socket(java.net.InetAddress, int) throws java.io.IOException;
-    ctor public Socket(String, int, java.net.InetAddress, int) throws java.io.IOException;
-    ctor public Socket(java.net.InetAddress, int, java.net.InetAddress, int) throws java.io.IOException;
-    ctor @Deprecated public Socket(String, int, boolean) throws java.io.IOException;
-    ctor @Deprecated public Socket(java.net.InetAddress, int, boolean) throws java.io.IOException;
-    method public void bind(java.net.SocketAddress) throws java.io.IOException;
-    method public void close() throws java.io.IOException;
-    method public void connect(java.net.SocketAddress) throws java.io.IOException;
-    method public void connect(java.net.SocketAddress, int) throws java.io.IOException;
-    method public java.nio.channels.SocketChannel getChannel();
-    method public java.net.InetAddress getInetAddress();
-    method public java.io.InputStream getInputStream() throws java.io.IOException;
-    method public boolean getKeepAlive() throws java.net.SocketException;
-    method public java.net.InetAddress getLocalAddress();
-    method public int getLocalPort();
-    method public java.net.SocketAddress getLocalSocketAddress();
-    method public boolean getOOBInline() throws java.net.SocketException;
-    method public java.io.OutputStream getOutputStream() throws java.io.IOException;
-    method public int getPort();
-    method public int getReceiveBufferSize() throws java.net.SocketException;
-    method public java.net.SocketAddress getRemoteSocketAddress();
-    method public boolean getReuseAddress() throws java.net.SocketException;
-    method public int getSendBufferSize() throws java.net.SocketException;
-    method public int getSoLinger() throws java.net.SocketException;
-    method public int getSoTimeout() throws java.net.SocketException;
-    method public boolean getTcpNoDelay() throws java.net.SocketException;
-    method public int getTrafficClass() throws java.net.SocketException;
-    method public boolean isBound();
-    method public boolean isClosed();
-    method public boolean isConnected();
-    method public boolean isInputShutdown();
-    method public boolean isOutputShutdown();
-    method public void sendUrgentData(int) throws java.io.IOException;
-    method public void setKeepAlive(boolean) throws java.net.SocketException;
-    method public void setOOBInline(boolean) throws java.net.SocketException;
-    method public void setPerformancePreferences(int, int, int);
-    method public void setReceiveBufferSize(int) throws java.net.SocketException;
-    method public void setReuseAddress(boolean) throws java.net.SocketException;
-    method public void setSendBufferSize(int) throws java.net.SocketException;
-    method public void setSoLinger(boolean, int) throws java.net.SocketException;
-    method public void setSoTimeout(int) throws java.net.SocketException;
-    method public static void setSocketImplFactory(java.net.SocketImplFactory) throws java.io.IOException;
-    method public void setTcpNoDelay(boolean) throws java.net.SocketException;
-    method public void setTrafficClass(int) throws java.net.SocketException;
-    method public void shutdownInput() throws java.io.IOException;
-    method public void shutdownOutput() throws java.io.IOException;
-  }
-
-  public abstract class SocketAddress implements java.io.Serializable {
-    ctor public SocketAddress();
-  }
-
-  public class SocketException extends java.io.IOException {
-    ctor public SocketException(String);
-    ctor public SocketException();
-  }
-
-  public abstract class SocketImpl implements java.net.SocketOptions {
-    ctor public SocketImpl();
-    method protected abstract void accept(java.net.SocketImpl) throws java.io.IOException;
-    method protected abstract int available() throws java.io.IOException;
-    method protected abstract void bind(java.net.InetAddress, int) throws java.io.IOException;
-    method protected abstract void close() throws java.io.IOException;
-    method protected abstract void connect(String, int) throws java.io.IOException;
-    method protected abstract void connect(java.net.InetAddress, int) throws java.io.IOException;
-    method protected abstract void connect(java.net.SocketAddress, int) throws java.io.IOException;
-    method protected abstract void create(boolean) throws java.io.IOException;
-    method protected java.io.FileDescriptor getFileDescriptor();
-    method protected java.net.InetAddress getInetAddress();
-    method protected abstract java.io.InputStream getInputStream() throws java.io.IOException;
-    method protected int getLocalPort();
-    method protected abstract java.io.OutputStream getOutputStream() throws java.io.IOException;
-    method protected int getPort();
-    method protected abstract void listen(int) throws java.io.IOException;
-    method protected abstract void sendUrgentData(int) throws java.io.IOException;
-    method protected void setPerformancePreferences(int, int, int);
-    method protected void shutdownInput() throws java.io.IOException;
-    method protected void shutdownOutput() throws java.io.IOException;
-    method protected boolean supportsUrgentData();
-    field protected java.net.InetAddress address;
-    field protected java.io.FileDescriptor fd;
-    field protected int localport;
-    field protected int port;
-  }
-
-  public interface SocketImplFactory {
-    method public java.net.SocketImpl createSocketImpl();
-  }
-
-  public interface SocketOption<T> {
-    method public String name();
-    method public Class<T> type();
-  }
-
-  public interface SocketOptions {
-    method public Object getOption(int) throws java.net.SocketException;
-    method public void setOption(int, Object) throws java.net.SocketException;
-    field public static final int IP_MULTICAST_IF = 16; // 0x10
-    field public static final int IP_MULTICAST_IF2 = 31; // 0x1f
-    field public static final int IP_MULTICAST_LOOP = 18; // 0x12
-    field public static final int IP_TOS = 3; // 0x3
-    field public static final int SO_BINDADDR = 15; // 0xf
-    field public static final int SO_BROADCAST = 32; // 0x20
-    field public static final int SO_KEEPALIVE = 8; // 0x8
-    field public static final int SO_LINGER = 128; // 0x80
-    field public static final int SO_OOBINLINE = 4099; // 0x1003
-    field public static final int SO_RCVBUF = 4098; // 0x1002
-    field public static final int SO_REUSEADDR = 4; // 0x4
-    field public static final int SO_SNDBUF = 4097; // 0x1001
-    field public static final int SO_TIMEOUT = 4102; // 0x1006
-    field public static final int TCP_NODELAY = 1; // 0x1
-  }
-
-  public final class SocketPermission extends java.security.Permission implements java.io.Serializable {
-    ctor public SocketPermission(String, String);
-    method public String getActions();
-    method public boolean implies(java.security.Permission);
-  }
-
-  public class SocketTimeoutException extends java.io.InterruptedIOException {
-    ctor public SocketTimeoutException(String);
-    ctor public SocketTimeoutException();
-  }
-
-  public enum StandardProtocolFamily implements java.net.ProtocolFamily {
-    enum_constant public static final java.net.StandardProtocolFamily INET;
-    enum_constant public static final java.net.StandardProtocolFamily INET6;
-  }
-
-  public final class StandardSocketOptions {
-    field public static final java.net.SocketOption<java.net.NetworkInterface> IP_MULTICAST_IF;
-    field public static final java.net.SocketOption<java.lang.Boolean> IP_MULTICAST_LOOP;
-    field public static final java.net.SocketOption<java.lang.Integer> IP_MULTICAST_TTL;
-    field public static final java.net.SocketOption<java.lang.Integer> IP_TOS;
-    field public static final java.net.SocketOption<java.lang.Boolean> SO_BROADCAST;
-    field public static final java.net.SocketOption<java.lang.Boolean> SO_KEEPALIVE;
-    field public static final java.net.SocketOption<java.lang.Integer> SO_LINGER;
-    field public static final java.net.SocketOption<java.lang.Integer> SO_RCVBUF;
-    field public static final java.net.SocketOption<java.lang.Boolean> SO_REUSEADDR;
-    field public static final java.net.SocketOption<java.lang.Integer> SO_SNDBUF;
-    field public static final java.net.SocketOption<java.lang.Boolean> TCP_NODELAY;
-  }
-
-  public final class URI implements java.lang.Comparable<java.net.URI> java.io.Serializable {
-    ctor public URI(String) throws java.net.URISyntaxException;
-    ctor public URI(String, String, String, int, String, String, String) throws java.net.URISyntaxException;
-    ctor public URI(String, String, String, String, String) throws java.net.URISyntaxException;
-    ctor public URI(String, String, String, String) throws java.net.URISyntaxException;
-    ctor public URI(String, String, String) throws java.net.URISyntaxException;
-    method public int compareTo(java.net.URI);
-    method public static java.net.URI create(String);
-    method public String getAuthority();
-    method public String getFragment();
-    method public String getHost();
-    method public String getPath();
-    method public int getPort();
-    method public String getQuery();
-    method public String getRawAuthority();
-    method public String getRawFragment();
-    method public String getRawPath();
-    method public String getRawQuery();
-    method public String getRawSchemeSpecificPart();
-    method public String getRawUserInfo();
-    method public String getScheme();
-    method public String getSchemeSpecificPart();
-    method public String getUserInfo();
-    method public boolean isAbsolute();
-    method public boolean isOpaque();
-    method public java.net.URI normalize();
-    method public java.net.URI parseServerAuthority() throws java.net.URISyntaxException;
-    method public java.net.URI relativize(java.net.URI);
-    method public java.net.URI resolve(java.net.URI);
-    method public java.net.URI resolve(String);
-    method public String toASCIIString();
-    method public java.net.URL toURL() throws java.net.MalformedURLException;
-  }
-
-  public class URISyntaxException extends java.lang.Exception {
-    ctor public URISyntaxException(String, String, int);
-    ctor public URISyntaxException(String, String);
-    method public int getIndex();
-    method public String getInput();
-    method public String getReason();
-  }
-
-  public final class URL implements java.io.Serializable {
-    ctor public URL(String, String, int, String) throws java.net.MalformedURLException;
-    ctor public URL(String, String, String) throws java.net.MalformedURLException;
-    ctor public URL(String, String, int, String, java.net.URLStreamHandler) throws java.net.MalformedURLException;
-    ctor public URL(String) throws java.net.MalformedURLException;
-    ctor public URL(java.net.URL, String) throws java.net.MalformedURLException;
-    ctor public URL(java.net.URL, String, java.net.URLStreamHandler) throws java.net.MalformedURLException;
-    method public String getAuthority();
-    method public Object getContent() throws java.io.IOException;
-    method public Object getContent(Class[]) throws java.io.IOException;
-    method public int getDefaultPort();
-    method public String getFile();
-    method public String getHost();
-    method public String getPath();
-    method public int getPort();
-    method public String getProtocol();
-    method public String getQuery();
-    method public String getRef();
-    method public String getUserInfo();
-    method public java.net.URLConnection openConnection() throws java.io.IOException;
-    method public java.net.URLConnection openConnection(java.net.Proxy) throws java.io.IOException;
-    method public java.io.InputStream openStream() throws java.io.IOException;
-    method public boolean sameFile(java.net.URL);
-    method public static void setURLStreamHandlerFactory(java.net.URLStreamHandlerFactory);
-    method public String toExternalForm();
-    method public java.net.URI toURI() throws java.net.URISyntaxException;
-  }
-
-  public class URLClassLoader extends java.security.SecureClassLoader implements java.io.Closeable {
-    ctor public URLClassLoader(java.net.URL[], ClassLoader);
-    ctor public URLClassLoader(java.net.URL[]);
-    ctor public URLClassLoader(java.net.URL[], ClassLoader, java.net.URLStreamHandlerFactory);
-    method protected void addURL(java.net.URL);
-    method public void close() throws java.io.IOException;
-    method protected Package definePackage(String, java.util.jar.Manifest, java.net.URL) throws java.lang.IllegalArgumentException;
-    method public java.net.URL findResource(String);
-    method public java.util.Enumeration<java.net.URL> findResources(String) throws java.io.IOException;
-    method public java.net.URL[] getURLs();
-    method public static java.net.URLClassLoader newInstance(java.net.URL[], ClassLoader);
-    method public static java.net.URLClassLoader newInstance(java.net.URL[]);
-  }
-
-  public abstract class URLConnection {
-    ctor protected URLConnection(java.net.URL);
-    method public void addRequestProperty(String, String);
-    method public abstract void connect() throws java.io.IOException;
-    method public boolean getAllowUserInteraction();
-    method public int getConnectTimeout();
-    method public Object getContent() throws java.io.IOException;
-    method public Object getContent(Class[]) throws java.io.IOException;
-    method public String getContentEncoding();
-    method public int getContentLength();
-    method public long getContentLengthLong();
-    method public String getContentType();
-    method public long getDate();
-    method public static boolean getDefaultAllowUserInteraction();
-    method @Deprecated public static String getDefaultRequestProperty(String);
-    method public boolean getDefaultUseCaches();
-    method public boolean getDoInput();
-    method public boolean getDoOutput();
-    method public long getExpiration();
-    method public static java.net.FileNameMap getFileNameMap();
-    method public String getHeaderField(String);
-    method public String getHeaderField(int);
-    method public long getHeaderFieldDate(String, long);
-    method public int getHeaderFieldInt(String, int);
-    method public String getHeaderFieldKey(int);
-    method public long getHeaderFieldLong(String, long);
-    method public java.util.Map<java.lang.String,java.util.List<java.lang.String>> getHeaderFields();
-    method public long getIfModifiedSince();
-    method public java.io.InputStream getInputStream() throws java.io.IOException;
-    method public long getLastModified();
-    method public java.io.OutputStream getOutputStream() throws java.io.IOException;
-    method public java.security.Permission getPermission() throws java.io.IOException;
-    method public int getReadTimeout();
-    method public java.util.Map<java.lang.String,java.util.List<java.lang.String>> getRequestProperties();
-    method public String getRequestProperty(String);
-    method public java.net.URL getURL();
-    method public boolean getUseCaches();
-    method public static String guessContentTypeFromName(String);
-    method public static String guessContentTypeFromStream(java.io.InputStream) throws java.io.IOException;
-    method public void setAllowUserInteraction(boolean);
-    method public void setConnectTimeout(int);
-    method public static void setContentHandlerFactory(java.net.ContentHandlerFactory);
-    method public static void setDefaultAllowUserInteraction(boolean);
-    method @Deprecated public static void setDefaultRequestProperty(String, String);
-    method public void setDefaultUseCaches(boolean);
-    method public void setDoInput(boolean);
-    method public void setDoOutput(boolean);
-    method public static void setFileNameMap(java.net.FileNameMap);
-    method public void setIfModifiedSince(long);
-    method public void setReadTimeout(int);
-    method public void setRequestProperty(String, String);
-    method public void setUseCaches(boolean);
-    field protected boolean allowUserInteraction;
-    field protected boolean connected;
-    field protected boolean doInput;
-    field protected boolean doOutput;
-    field protected long ifModifiedSince;
-    field protected java.net.URL url;
-    field protected boolean useCaches;
-  }
-
-  public class URLDecoder {
-    ctor public URLDecoder();
-    method @Deprecated public static String decode(String);
-    method public static String decode(String, String) throws java.io.UnsupportedEncodingException;
-  }
-
-  public class URLEncoder {
-    method @Deprecated public static String encode(String);
-    method public static String encode(String, String) throws java.io.UnsupportedEncodingException;
-  }
-
-  public abstract class URLStreamHandler {
-    ctor public URLStreamHandler();
-    method protected boolean equals(java.net.URL, java.net.URL);
-    method protected int getDefaultPort();
-    method protected java.net.InetAddress getHostAddress(java.net.URL);
-    method protected int hashCode(java.net.URL);
-    method protected boolean hostsEqual(java.net.URL, java.net.URL);
-    method protected abstract java.net.URLConnection openConnection(java.net.URL) throws java.io.IOException;
-    method protected java.net.URLConnection openConnection(java.net.URL, java.net.Proxy) throws java.io.IOException;
-    method protected void parseURL(java.net.URL, String, int, int);
-    method protected boolean sameFile(java.net.URL, java.net.URL);
-    method protected void setURL(java.net.URL, String, String, int, String, String, String, String, String);
-    method @Deprecated protected void setURL(java.net.URL, String, String, int, String, String);
-    method protected String toExternalForm(java.net.URL);
-  }
-
-  public interface URLStreamHandlerFactory {
-    method public java.net.URLStreamHandler createURLStreamHandler(String);
-  }
-
-  public class UnknownHostException extends java.io.IOException {
-    ctor public UnknownHostException(String);
-    ctor public UnknownHostException();
-  }
-
-  public class UnknownServiceException extends java.io.IOException {
-    ctor public UnknownServiceException();
-    ctor public UnknownServiceException(String);
-  }
-
-}
-
-package java.nio {
-
-  public abstract class Buffer {
-    method public abstract Object array();
-    method public abstract int arrayOffset();
-    method public final int capacity();
-    method public java.nio.Buffer clear();
-    method public java.nio.Buffer flip();
-    method public abstract boolean hasArray();
-    method public final boolean hasRemaining();
-    method public abstract boolean isDirect();
-    method public abstract boolean isReadOnly();
-    method public final int limit();
-    method public java.nio.Buffer limit(int);
-    method public java.nio.Buffer mark();
-    method public final int position();
-    method public java.nio.Buffer position(int);
-    method public final int remaining();
-    method public java.nio.Buffer reset();
-    method public java.nio.Buffer rewind();
-  }
-
-  public class BufferOverflowException extends java.lang.RuntimeException {
-    ctor public BufferOverflowException();
-  }
-
-  public class BufferUnderflowException extends java.lang.RuntimeException {
-    ctor public BufferUnderflowException();
-  }
-
-  public abstract class ByteBuffer extends java.nio.Buffer implements java.lang.Comparable<java.nio.ByteBuffer> {
-    method @NonNull public static java.nio.ByteBuffer allocate(int);
-    method @NonNull public static java.nio.ByteBuffer allocateDirect(int);
-    method @NonNull public final byte[] array();
-    method public final int arrayOffset();
-    method @NonNull public abstract java.nio.CharBuffer asCharBuffer();
-    method @NonNull public abstract java.nio.DoubleBuffer asDoubleBuffer();
-    method @NonNull public abstract java.nio.FloatBuffer asFloatBuffer();
-    method @NonNull public abstract java.nio.IntBuffer asIntBuffer();
-    method @NonNull public abstract java.nio.LongBuffer asLongBuffer();
-    method @NonNull public abstract java.nio.ByteBuffer asReadOnlyBuffer();
-    method @NonNull public abstract java.nio.ShortBuffer asShortBuffer();
-    method @NonNull public abstract java.nio.ByteBuffer compact();
-    method public int compareTo(@NonNull java.nio.ByteBuffer);
-    method @NonNull public abstract java.nio.ByteBuffer duplicate();
-    method public abstract byte get();
-    method public abstract byte get(int);
-    method @NonNull public java.nio.ByteBuffer get(@NonNull byte[], int, int);
-    method @NonNull public java.nio.ByteBuffer get(@NonNull byte[]);
-    method public abstract char getChar();
-    method public abstract char getChar(int);
-    method public abstract double getDouble();
-    method public abstract double getDouble(int);
-    method public abstract float getFloat();
-    method public abstract float getFloat(int);
-    method public abstract int getInt();
-    method public abstract int getInt(int);
-    method public abstract long getLong();
-    method public abstract long getLong(int);
-    method public abstract short getShort();
-    method public abstract short getShort(int);
-    method public final boolean hasArray();
-    method @NonNull public final java.nio.ByteOrder order();
-    method @NonNull public final java.nio.ByteBuffer order(@NonNull java.nio.ByteOrder);
-    method @NonNull public abstract java.nio.ByteBuffer put(byte);
-    method @NonNull public abstract java.nio.ByteBuffer put(int, byte);
-    method @NonNull public java.nio.ByteBuffer put(@NonNull java.nio.ByteBuffer);
-    method @NonNull public java.nio.ByteBuffer put(@NonNull byte[], int, int);
-    method @NonNull public final java.nio.ByteBuffer put(@NonNull byte[]);
-    method @NonNull public abstract java.nio.ByteBuffer putChar(char);
-    method @NonNull public abstract java.nio.ByteBuffer putChar(int, char);
-    method @NonNull public abstract java.nio.ByteBuffer putDouble(double);
-    method @NonNull public abstract java.nio.ByteBuffer putDouble(int, double);
-    method @NonNull public abstract java.nio.ByteBuffer putFloat(float);
-    method @NonNull public abstract java.nio.ByteBuffer putFloat(int, float);
-    method @NonNull public abstract java.nio.ByteBuffer putInt(int);
-    method @NonNull public abstract java.nio.ByteBuffer putInt(int, int);
-    method @NonNull public abstract java.nio.ByteBuffer putLong(long);
-    method @NonNull public abstract java.nio.ByteBuffer putLong(int, long);
-    method @NonNull public abstract java.nio.ByteBuffer putShort(short);
-    method @NonNull public abstract java.nio.ByteBuffer putShort(int, short);
-    method @NonNull public abstract java.nio.ByteBuffer slice();
-    method @NonNull public static java.nio.ByteBuffer wrap(@NonNull byte[], int, int);
-    method @NonNull public static java.nio.ByteBuffer wrap(@NonNull byte[]);
-  }
-
-  public final class ByteOrder {
-    method public static java.nio.ByteOrder nativeOrder();
-    field public static final java.nio.ByteOrder BIG_ENDIAN;
-    field public static final java.nio.ByteOrder LITTLE_ENDIAN;
-  }
-
-  public abstract class CharBuffer extends java.nio.Buffer implements java.lang.Appendable java.lang.CharSequence java.lang.Comparable<java.nio.CharBuffer> java.lang.Readable {
-    method public static java.nio.CharBuffer allocate(int);
-    method public java.nio.CharBuffer append(CharSequence);
-    method public java.nio.CharBuffer append(CharSequence, int, int);
-    method public java.nio.CharBuffer append(char);
-    method public final char[] array();
-    method public final int arrayOffset();
-    method public abstract java.nio.CharBuffer asReadOnlyBuffer();
-    method public final char charAt(int);
-    method public abstract java.nio.CharBuffer compact();
-    method public int compareTo(java.nio.CharBuffer);
-    method public abstract java.nio.CharBuffer duplicate();
-    method public abstract char get();
-    method public abstract char get(int);
-    method public java.nio.CharBuffer get(char[], int, int);
-    method public java.nio.CharBuffer get(char[]);
-    method public final boolean hasArray();
-    method public final int length();
-    method public abstract java.nio.ByteOrder order();
-    method public abstract java.nio.CharBuffer put(char);
-    method public abstract java.nio.CharBuffer put(int, char);
-    method public java.nio.CharBuffer put(java.nio.CharBuffer);
-    method public java.nio.CharBuffer put(char[], int, int);
-    method public final java.nio.CharBuffer put(char[]);
-    method public java.nio.CharBuffer put(String, int, int);
-    method public final java.nio.CharBuffer put(String);
-    method public int read(java.nio.CharBuffer) throws java.io.IOException;
-    method public abstract java.nio.CharBuffer slice();
-    method public abstract java.nio.CharBuffer subSequence(int, int);
-    method public static java.nio.CharBuffer wrap(char[], int, int);
-    method public static java.nio.CharBuffer wrap(char[]);
-    method public static java.nio.CharBuffer wrap(CharSequence, int, int);
-    method public static java.nio.CharBuffer wrap(CharSequence);
-  }
-
-  public abstract class DoubleBuffer extends java.nio.Buffer implements java.lang.Comparable<java.nio.DoubleBuffer> {
-    method public static java.nio.DoubleBuffer allocate(int);
-    method public final double[] array();
-    method public final int arrayOffset();
-    method public abstract java.nio.DoubleBuffer asReadOnlyBuffer();
-    method public abstract java.nio.DoubleBuffer compact();
-    method public int compareTo(java.nio.DoubleBuffer);
-    method public abstract java.nio.DoubleBuffer duplicate();
-    method public abstract double get();
-    method public abstract double get(int);
-    method public java.nio.DoubleBuffer get(double[], int, int);
-    method public java.nio.DoubleBuffer get(double[]);
-    method public final boolean hasArray();
-    method public abstract java.nio.ByteOrder order();
-    method public abstract java.nio.DoubleBuffer put(double);
-    method public abstract java.nio.DoubleBuffer put(int, double);
-    method public java.nio.DoubleBuffer put(java.nio.DoubleBuffer);
-    method public java.nio.DoubleBuffer put(double[], int, int);
-    method public final java.nio.DoubleBuffer put(double[]);
-    method public abstract java.nio.DoubleBuffer slice();
-    method public static java.nio.DoubleBuffer wrap(double[], int, int);
-    method public static java.nio.DoubleBuffer wrap(double[]);
-  }
-
-  public abstract class FloatBuffer extends java.nio.Buffer implements java.lang.Comparable<java.nio.FloatBuffer> {
-    method public static java.nio.FloatBuffer allocate(int);
-    method public final float[] array();
-    method public final int arrayOffset();
-    method public abstract java.nio.FloatBuffer asReadOnlyBuffer();
-    method public abstract java.nio.FloatBuffer compact();
-    method public int compareTo(java.nio.FloatBuffer);
-    method public abstract java.nio.FloatBuffer duplicate();
-    method public abstract float get();
-    method public abstract float get(int);
-    method public java.nio.FloatBuffer get(float[], int, int);
-    method public java.nio.FloatBuffer get(float[]);
-    method public final boolean hasArray();
-    method public abstract java.nio.ByteOrder order();
-    method public abstract java.nio.FloatBuffer put(float);
-    method public abstract java.nio.FloatBuffer put(int, float);
-    method public java.nio.FloatBuffer put(java.nio.FloatBuffer);
-    method public java.nio.FloatBuffer put(float[], int, int);
-    method public final java.nio.FloatBuffer put(float[]);
-    method public abstract java.nio.FloatBuffer slice();
-    method public static java.nio.FloatBuffer wrap(float[], int, int);
-    method public static java.nio.FloatBuffer wrap(float[]);
-  }
-
-  public abstract class IntBuffer extends java.nio.Buffer implements java.lang.Comparable<java.nio.IntBuffer> {
-    method public static java.nio.IntBuffer allocate(int);
-    method public final int[] array();
-    method public final int arrayOffset();
-    method public abstract java.nio.IntBuffer asReadOnlyBuffer();
-    method public abstract java.nio.IntBuffer compact();
-    method public int compareTo(java.nio.IntBuffer);
-    method public abstract java.nio.IntBuffer duplicate();
-    method public abstract int get();
-    method public abstract int get(int);
-    method public java.nio.IntBuffer get(int[], int, int);
-    method public java.nio.IntBuffer get(int[]);
-    method public final boolean hasArray();
-    method public abstract java.nio.ByteOrder order();
-    method public abstract java.nio.IntBuffer put(int);
-    method public abstract java.nio.IntBuffer put(int, int);
-    method public java.nio.IntBuffer put(java.nio.IntBuffer);
-    method public java.nio.IntBuffer put(int[], int, int);
-    method public final java.nio.IntBuffer put(int[]);
-    method public abstract java.nio.IntBuffer slice();
-    method public static java.nio.IntBuffer wrap(int[], int, int);
-    method public static java.nio.IntBuffer wrap(int[]);
-  }
-
-  public class InvalidMarkException extends java.lang.IllegalStateException {
-    ctor public InvalidMarkException();
-  }
-
-  public abstract class LongBuffer extends java.nio.Buffer implements java.lang.Comparable<java.nio.LongBuffer> {
-    method public static java.nio.LongBuffer allocate(int);
-    method public final long[] array();
-    method public final int arrayOffset();
-    method public abstract java.nio.LongBuffer asReadOnlyBuffer();
-    method public abstract java.nio.LongBuffer compact();
-    method public int compareTo(java.nio.LongBuffer);
-    method public abstract java.nio.LongBuffer duplicate();
-    method public abstract long get();
-    method public abstract long get(int);
-    method public java.nio.LongBuffer get(long[], int, int);
-    method public java.nio.LongBuffer get(long[]);
-    method public final boolean hasArray();
-    method public abstract java.nio.ByteOrder order();
-    method public abstract java.nio.LongBuffer put(long);
-    method public abstract java.nio.LongBuffer put(int, long);
-    method public java.nio.LongBuffer put(java.nio.LongBuffer);
-    method public java.nio.LongBuffer put(long[], int, int);
-    method public final java.nio.LongBuffer put(long[]);
-    method public abstract java.nio.LongBuffer slice();
-    method public static java.nio.LongBuffer wrap(long[], int, int);
-    method public static java.nio.LongBuffer wrap(long[]);
-  }
-
-  public abstract class MappedByteBuffer extends java.nio.ByteBuffer {
-    method public final java.nio.MappedByteBuffer force();
-    method public final boolean isLoaded();
-    method public final java.nio.MappedByteBuffer load();
-  }
-
-  public class ReadOnlyBufferException extends java.lang.UnsupportedOperationException {
-    ctor public ReadOnlyBufferException();
-  }
-
-  public abstract class ShortBuffer extends java.nio.Buffer implements java.lang.Comparable<java.nio.ShortBuffer> {
-    method public static java.nio.ShortBuffer allocate(int);
-    method public final short[] array();
-    method public final int arrayOffset();
-    method public abstract java.nio.ShortBuffer asReadOnlyBuffer();
-    method public abstract java.nio.ShortBuffer compact();
-    method public int compareTo(java.nio.ShortBuffer);
-    method public abstract java.nio.ShortBuffer duplicate();
-    method public abstract short get();
-    method public abstract short get(int);
-    method public java.nio.ShortBuffer get(short[], int, int);
-    method public java.nio.ShortBuffer get(short[]);
-    method public final boolean hasArray();
-    method public abstract java.nio.ByteOrder order();
-    method public abstract java.nio.ShortBuffer put(short);
-    method public abstract java.nio.ShortBuffer put(int, short);
-    method public java.nio.ShortBuffer put(java.nio.ShortBuffer);
-    method public java.nio.ShortBuffer put(short[], int, int);
-    method public final java.nio.ShortBuffer put(short[]);
-    method public abstract java.nio.ShortBuffer slice();
-    method public static java.nio.ShortBuffer wrap(short[], int, int);
-    method public static java.nio.ShortBuffer wrap(short[]);
-  }
-
-}
-
-package java.nio.channels {
-
-  public class AcceptPendingException extends java.lang.IllegalStateException {
-    ctor public AcceptPendingException();
-  }
-
-  public class AlreadyBoundException extends java.lang.IllegalStateException {
-    ctor public AlreadyBoundException();
-  }
-
-  public class AlreadyConnectedException extends java.lang.IllegalStateException {
-    ctor public AlreadyConnectedException();
-  }
-
-  public interface AsynchronousByteChannel extends java.nio.channels.AsynchronousChannel {
-    method public <A> void read(java.nio.ByteBuffer, A, java.nio.channels.CompletionHandler<java.lang.Integer,? super A>);
-    method public java.util.concurrent.Future<java.lang.Integer> read(java.nio.ByteBuffer);
-    method public <A> void write(java.nio.ByteBuffer, A, java.nio.channels.CompletionHandler<java.lang.Integer,? super A>);
-    method public java.util.concurrent.Future<java.lang.Integer> write(java.nio.ByteBuffer);
-  }
-
-  public interface AsynchronousChannel extends java.nio.channels.Channel {
-  }
-
-  public abstract class AsynchronousChannelGroup {
-    ctor protected AsynchronousChannelGroup(java.nio.channels.spi.AsynchronousChannelProvider);
-    method public abstract boolean awaitTermination(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-    method public abstract boolean isShutdown();
-    method public abstract boolean isTerminated();
-    method public final java.nio.channels.spi.AsynchronousChannelProvider provider();
-    method public abstract void shutdown();
-    method public abstract void shutdownNow() throws java.io.IOException;
-    method public static java.nio.channels.AsynchronousChannelGroup withCachedThreadPool(java.util.concurrent.ExecutorService, int) throws java.io.IOException;
-    method public static java.nio.channels.AsynchronousChannelGroup withFixedThreadPool(int, java.util.concurrent.ThreadFactory) throws java.io.IOException;
-    method public static java.nio.channels.AsynchronousChannelGroup withThreadPool(java.util.concurrent.ExecutorService) throws java.io.IOException;
-  }
-
-  public class AsynchronousCloseException extends java.nio.channels.ClosedChannelException {
-    ctor public AsynchronousCloseException();
-  }
-
-  public abstract class AsynchronousFileChannel implements java.nio.channels.AsynchronousChannel {
-    ctor protected AsynchronousFileChannel();
-    method public abstract void force(boolean) throws java.io.IOException;
-    method public abstract <A> void lock(long, long, boolean, A, java.nio.channels.CompletionHandler<java.nio.channels.FileLock,? super A>);
-    method public final <A> void lock(A, java.nio.channels.CompletionHandler<java.nio.channels.FileLock,? super A>);
-    method public abstract java.util.concurrent.Future<java.nio.channels.FileLock> lock(long, long, boolean);
-    method public final java.util.concurrent.Future<java.nio.channels.FileLock> lock();
-    method public static java.nio.channels.AsynchronousFileChannel open(java.nio.file.Path, java.util.Set<? extends java.nio.file.OpenOption>, java.util.concurrent.ExecutorService, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public static java.nio.channels.AsynchronousFileChannel open(java.nio.file.Path, java.nio.file.OpenOption...) throws java.io.IOException;
-    method public abstract <A> void read(java.nio.ByteBuffer, long, A, java.nio.channels.CompletionHandler<java.lang.Integer,? super A>);
-    method public abstract java.util.concurrent.Future<java.lang.Integer> read(java.nio.ByteBuffer, long);
-    method public abstract long size() throws java.io.IOException;
-    method public abstract java.nio.channels.AsynchronousFileChannel truncate(long) throws java.io.IOException;
-    method public abstract java.nio.channels.FileLock tryLock(long, long, boolean) throws java.io.IOException;
-    method public final java.nio.channels.FileLock tryLock() throws java.io.IOException;
-    method public abstract <A> void write(java.nio.ByteBuffer, long, A, java.nio.channels.CompletionHandler<java.lang.Integer,? super A>);
-    method public abstract java.util.concurrent.Future<java.lang.Integer> write(java.nio.ByteBuffer, long);
-  }
-
-  public abstract class AsynchronousServerSocketChannel implements java.nio.channels.AsynchronousChannel java.nio.channels.NetworkChannel {
-    ctor protected AsynchronousServerSocketChannel(java.nio.channels.spi.AsynchronousChannelProvider);
-    method public abstract <A> void accept(A, java.nio.channels.CompletionHandler<java.nio.channels.AsynchronousSocketChannel,? super A>);
-    method public abstract java.util.concurrent.Future<java.nio.channels.AsynchronousSocketChannel> accept();
-    method public final java.nio.channels.AsynchronousServerSocketChannel bind(java.net.SocketAddress) throws java.io.IOException;
-    method public abstract java.nio.channels.AsynchronousServerSocketChannel bind(java.net.SocketAddress, int) throws java.io.IOException;
-    method public static java.nio.channels.AsynchronousServerSocketChannel open(java.nio.channels.AsynchronousChannelGroup) throws java.io.IOException;
-    method public static java.nio.channels.AsynchronousServerSocketChannel open() throws java.io.IOException;
-    method public final java.nio.channels.spi.AsynchronousChannelProvider provider();
-    method public abstract <T> java.nio.channels.AsynchronousServerSocketChannel setOption(java.net.SocketOption<T>, T) throws java.io.IOException;
-  }
-
-  public abstract class AsynchronousSocketChannel implements java.nio.channels.AsynchronousByteChannel java.nio.channels.NetworkChannel {
-    ctor protected AsynchronousSocketChannel(java.nio.channels.spi.AsynchronousChannelProvider);
-    method public abstract java.nio.channels.AsynchronousSocketChannel bind(java.net.SocketAddress) throws java.io.IOException;
-    method public abstract <A> void connect(java.net.SocketAddress, A, java.nio.channels.CompletionHandler<java.lang.Void,? super A>);
-    method public abstract java.util.concurrent.Future<java.lang.Void> connect(java.net.SocketAddress);
-    method public abstract java.net.SocketAddress getRemoteAddress() throws java.io.IOException;
-    method public static java.nio.channels.AsynchronousSocketChannel open(java.nio.channels.AsynchronousChannelGroup) throws java.io.IOException;
-    method public static java.nio.channels.AsynchronousSocketChannel open() throws java.io.IOException;
-    method public final java.nio.channels.spi.AsynchronousChannelProvider provider();
-    method public abstract <A> void read(java.nio.ByteBuffer, long, java.util.concurrent.TimeUnit, A, java.nio.channels.CompletionHandler<java.lang.Integer,? super A>);
-    method public final <A> void read(java.nio.ByteBuffer, A, java.nio.channels.CompletionHandler<java.lang.Integer,? super A>);
-    method public abstract <A> void read(java.nio.ByteBuffer[], int, int, long, java.util.concurrent.TimeUnit, A, java.nio.channels.CompletionHandler<java.lang.Long,? super A>);
-    method public abstract <T> java.nio.channels.AsynchronousSocketChannel setOption(java.net.SocketOption<T>, T) throws java.io.IOException;
-    method public abstract java.nio.channels.AsynchronousSocketChannel shutdownInput() throws java.io.IOException;
-    method public abstract java.nio.channels.AsynchronousSocketChannel shutdownOutput() throws java.io.IOException;
-    method public abstract <A> void write(java.nio.ByteBuffer, long, java.util.concurrent.TimeUnit, A, java.nio.channels.CompletionHandler<java.lang.Integer,? super A>);
-    method public final <A> void write(java.nio.ByteBuffer, A, java.nio.channels.CompletionHandler<java.lang.Integer,? super A>);
-    method public abstract <A> void write(java.nio.ByteBuffer[], int, int, long, java.util.concurrent.TimeUnit, A, java.nio.channels.CompletionHandler<java.lang.Long,? super A>);
-  }
-
-  public interface ByteChannel extends java.nio.channels.ReadableByteChannel java.nio.channels.WritableByteChannel {
-  }
-
-  public class CancelledKeyException extends java.lang.IllegalStateException {
-    ctor public CancelledKeyException();
-  }
-
-  public interface Channel extends java.io.Closeable {
-    method public boolean isOpen();
-  }
-
-  public final class Channels {
-    method public static java.nio.channels.ReadableByteChannel newChannel(java.io.InputStream);
-    method public static java.nio.channels.WritableByteChannel newChannel(java.io.OutputStream);
-    method public static java.io.InputStream newInputStream(java.nio.channels.ReadableByteChannel);
-    method public static java.io.InputStream newInputStream(java.nio.channels.AsynchronousByteChannel);
-    method public static java.io.OutputStream newOutputStream(java.nio.channels.WritableByteChannel);
-    method public static java.io.OutputStream newOutputStream(java.nio.channels.AsynchronousByteChannel);
-    method public static java.io.Reader newReader(java.nio.channels.ReadableByteChannel, java.nio.charset.CharsetDecoder, int);
-    method public static java.io.Reader newReader(java.nio.channels.ReadableByteChannel, String);
-    method public static java.io.Writer newWriter(java.nio.channels.WritableByteChannel, java.nio.charset.CharsetEncoder, int);
-    method public static java.io.Writer newWriter(java.nio.channels.WritableByteChannel, String);
-  }
-
-  public class ClosedByInterruptException extends java.nio.channels.AsynchronousCloseException {
-    ctor public ClosedByInterruptException();
-  }
-
-  public class ClosedChannelException extends java.io.IOException {
-    ctor public ClosedChannelException();
-  }
-
-  public class ClosedSelectorException extends java.lang.IllegalStateException {
-    ctor public ClosedSelectorException();
-  }
-
-  public interface CompletionHandler<V, A> {
-    method public void completed(V, A);
-    method public void failed(Throwable, A);
-  }
-
-  public class ConnectionPendingException extends java.lang.IllegalStateException {
-    ctor public ConnectionPendingException();
-  }
-
-  public abstract class DatagramChannel extends java.nio.channels.spi.AbstractSelectableChannel implements java.nio.channels.ByteChannel java.nio.channels.GatheringByteChannel java.nio.channels.MulticastChannel java.nio.channels.ScatteringByteChannel {
-    ctor protected DatagramChannel(java.nio.channels.spi.SelectorProvider);
-    method public abstract java.nio.channels.DatagramChannel bind(java.net.SocketAddress) throws java.io.IOException;
-    method public abstract java.nio.channels.DatagramChannel connect(java.net.SocketAddress) throws java.io.IOException;
-    method public abstract java.nio.channels.DatagramChannel disconnect() throws java.io.IOException;
-    method public abstract java.net.SocketAddress getRemoteAddress() throws java.io.IOException;
-    method public abstract boolean isConnected();
-    method public static java.nio.channels.DatagramChannel open() throws java.io.IOException;
-    method public static java.nio.channels.DatagramChannel open(java.net.ProtocolFamily) throws java.io.IOException;
-    method public final long read(java.nio.ByteBuffer[]) throws java.io.IOException;
-    method public abstract java.net.SocketAddress receive(java.nio.ByteBuffer) throws java.io.IOException;
-    method public abstract int send(java.nio.ByteBuffer, java.net.SocketAddress) throws java.io.IOException;
-    method public abstract <T> java.nio.channels.DatagramChannel setOption(java.net.SocketOption<T>, T) throws java.io.IOException;
-    method public abstract java.net.DatagramSocket socket();
-    method public final int validOps();
-    method public final long write(java.nio.ByteBuffer[]) throws java.io.IOException;
-  }
-
-  public abstract class FileChannel extends java.nio.channels.spi.AbstractInterruptibleChannel implements java.nio.channels.GatheringByteChannel java.nio.channels.ScatteringByteChannel java.nio.channels.SeekableByteChannel {
-    ctor protected FileChannel();
-    method public abstract void force(boolean) throws java.io.IOException;
-    method public abstract java.nio.channels.FileLock lock(long, long, boolean) throws java.io.IOException;
-    method public final java.nio.channels.FileLock lock() throws java.io.IOException;
-    method public abstract java.nio.MappedByteBuffer map(java.nio.channels.FileChannel.MapMode, long, long) throws java.io.IOException;
-    method public static java.nio.channels.FileChannel open(java.nio.file.Path, java.util.Set<? extends java.nio.file.OpenOption>, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public static java.nio.channels.FileChannel open(java.nio.file.Path, java.nio.file.OpenOption...) throws java.io.IOException;
-    method public abstract java.nio.channels.FileChannel position(long) throws java.io.IOException;
-    method public final long read(java.nio.ByteBuffer[]) throws java.io.IOException;
-    method public abstract int read(java.nio.ByteBuffer, long) throws java.io.IOException;
-    method public abstract long transferFrom(java.nio.channels.ReadableByteChannel, long, long) throws java.io.IOException;
-    method public abstract long transferTo(long, long, java.nio.channels.WritableByteChannel) throws java.io.IOException;
-    method public abstract java.nio.channels.FileChannel truncate(long) throws java.io.IOException;
-    method public abstract java.nio.channels.FileLock tryLock(long, long, boolean) throws java.io.IOException;
-    method public final java.nio.channels.FileLock tryLock() throws java.io.IOException;
-    method public final long write(java.nio.ByteBuffer[]) throws java.io.IOException;
-    method public abstract int write(java.nio.ByteBuffer, long) throws java.io.IOException;
-  }
-
-  public static class FileChannel.MapMode {
-    field public static final java.nio.channels.FileChannel.MapMode PRIVATE;
-    field public static final java.nio.channels.FileChannel.MapMode READ_ONLY;
-    field public static final java.nio.channels.FileChannel.MapMode READ_WRITE;
-  }
-
-  public abstract class FileLock implements java.lang.AutoCloseable {
-    ctor protected FileLock(java.nio.channels.FileChannel, long, long, boolean);
-    ctor protected FileLock(java.nio.channels.AsynchronousFileChannel, long, long, boolean);
-    method public java.nio.channels.Channel acquiredBy();
-    method public final java.nio.channels.FileChannel channel();
-    method public final void close() throws java.io.IOException;
-    method public final boolean isShared();
-    method public abstract boolean isValid();
-    method public final boolean overlaps(long, long);
-    method public final long position();
-    method public abstract void release() throws java.io.IOException;
-    method public final long size();
-    method public final String toString();
-  }
-
-  public class FileLockInterruptionException extends java.io.IOException {
-    ctor public FileLockInterruptionException();
-  }
-
-  public interface GatheringByteChannel extends java.nio.channels.WritableByteChannel {
-    method public long write(java.nio.ByteBuffer[], int, int) throws java.io.IOException;
-    method public long write(java.nio.ByteBuffer[]) throws java.io.IOException;
-  }
-
-  public class IllegalBlockingModeException extends java.lang.IllegalStateException {
-    ctor public IllegalBlockingModeException();
-  }
-
-  public class IllegalChannelGroupException extends java.lang.IllegalArgumentException {
-    ctor public IllegalChannelGroupException();
-  }
-
-  public class IllegalSelectorException extends java.lang.IllegalArgumentException {
-    ctor public IllegalSelectorException();
-  }
-
-  public class InterruptedByTimeoutException extends java.io.IOException {
-    ctor public InterruptedByTimeoutException();
-  }
-
-  public interface InterruptibleChannel extends java.nio.channels.Channel {
-  }
-
-  public abstract class MembershipKey {
-    ctor protected MembershipKey();
-    method public abstract java.nio.channels.MembershipKey block(java.net.InetAddress) throws java.io.IOException;
-    method public abstract java.nio.channels.MulticastChannel channel();
-    method public abstract void drop();
-    method public abstract java.net.InetAddress group();
-    method public abstract boolean isValid();
-    method public abstract java.net.NetworkInterface networkInterface();
-    method public abstract java.net.InetAddress sourceAddress();
-    method public abstract java.nio.channels.MembershipKey unblock(java.net.InetAddress);
-  }
-
-  public interface MulticastChannel extends java.nio.channels.NetworkChannel {
-    method public java.nio.channels.MembershipKey join(java.net.InetAddress, java.net.NetworkInterface) throws java.io.IOException;
-    method public java.nio.channels.MembershipKey join(java.net.InetAddress, java.net.NetworkInterface, java.net.InetAddress) throws java.io.IOException;
-  }
-
-  public interface NetworkChannel extends java.nio.channels.Channel {
-    method public java.nio.channels.NetworkChannel bind(java.net.SocketAddress) throws java.io.IOException;
-    method public java.net.SocketAddress getLocalAddress() throws java.io.IOException;
-    method public <T> T getOption(java.net.SocketOption<T>) throws java.io.IOException;
-    method public <T> java.nio.channels.NetworkChannel setOption(java.net.SocketOption<T>, T) throws java.io.IOException;
-    method public java.util.Set<java.net.SocketOption<?>> supportedOptions();
-  }
-
-  public class NoConnectionPendingException extends java.lang.IllegalStateException {
-    ctor public NoConnectionPendingException();
-  }
-
-  public class NonReadableChannelException extends java.lang.IllegalStateException {
-    ctor public NonReadableChannelException();
-  }
-
-  public class NonWritableChannelException extends java.lang.IllegalStateException {
-    ctor public NonWritableChannelException();
-  }
-
-  public class NotYetBoundException extends java.lang.IllegalStateException {
-    ctor public NotYetBoundException();
-  }
-
-  public class NotYetConnectedException extends java.lang.IllegalStateException {
-    ctor public NotYetConnectedException();
-  }
-
-  public class OverlappingFileLockException extends java.lang.IllegalStateException {
-    ctor public OverlappingFileLockException();
-  }
-
-  public abstract class Pipe {
-    ctor protected Pipe();
-    method public static java.nio.channels.Pipe open() throws java.io.IOException;
-    method public abstract java.nio.channels.Pipe.SinkChannel sink();
-    method public abstract java.nio.channels.Pipe.SourceChannel source();
-  }
-
-  public abstract static class Pipe.SinkChannel extends java.nio.channels.spi.AbstractSelectableChannel implements java.nio.channels.GatheringByteChannel java.nio.channels.WritableByteChannel {
-    ctor protected Pipe.SinkChannel(java.nio.channels.spi.SelectorProvider);
-    method public final int validOps();
-  }
-
-  public abstract static class Pipe.SourceChannel extends java.nio.channels.spi.AbstractSelectableChannel implements java.nio.channels.ReadableByteChannel java.nio.channels.ScatteringByteChannel {
-    ctor protected Pipe.SourceChannel(java.nio.channels.spi.SelectorProvider);
-    method public final int validOps();
-  }
-
-  public class ReadPendingException extends java.lang.IllegalStateException {
-    ctor public ReadPendingException();
-  }
-
-  public interface ReadableByteChannel extends java.nio.channels.Channel {
-    method public int read(java.nio.ByteBuffer) throws java.io.IOException;
-  }
-
-  public interface ScatteringByteChannel extends java.nio.channels.ReadableByteChannel {
-    method public long read(java.nio.ByteBuffer[], int, int) throws java.io.IOException;
-    method public long read(java.nio.ByteBuffer[]) throws java.io.IOException;
-  }
-
-  public interface SeekableByteChannel extends java.nio.channels.ByteChannel {
-    method public long position() throws java.io.IOException;
-    method public java.nio.channels.SeekableByteChannel position(long) throws java.io.IOException;
-    method public long size() throws java.io.IOException;
-    method public java.nio.channels.SeekableByteChannel truncate(long) throws java.io.IOException;
-  }
-
-  public abstract class SelectableChannel extends java.nio.channels.spi.AbstractInterruptibleChannel implements java.nio.channels.Channel {
-    ctor protected SelectableChannel();
-    method public abstract Object blockingLock();
-    method public abstract java.nio.channels.SelectableChannel configureBlocking(boolean) throws java.io.IOException;
-    method public abstract boolean isBlocking();
-    method public abstract boolean isRegistered();
-    method public abstract java.nio.channels.SelectionKey keyFor(java.nio.channels.Selector);
-    method public abstract java.nio.channels.spi.SelectorProvider provider();
-    method public abstract java.nio.channels.SelectionKey register(java.nio.channels.Selector, int, Object) throws java.nio.channels.ClosedChannelException;
-    method public final java.nio.channels.SelectionKey register(java.nio.channels.Selector, int) throws java.nio.channels.ClosedChannelException;
-    method public abstract int validOps();
-  }
-
-  public abstract class SelectionKey {
-    ctor protected SelectionKey();
-    method public final Object attach(Object);
-    method public final Object attachment();
-    method public abstract void cancel();
-    method public abstract java.nio.channels.SelectableChannel channel();
-    method public abstract int interestOps();
-    method public abstract java.nio.channels.SelectionKey interestOps(int);
-    method public final boolean isAcceptable();
-    method public final boolean isConnectable();
-    method public final boolean isReadable();
-    method public abstract boolean isValid();
-    method public final boolean isWritable();
-    method public abstract int readyOps();
-    method public abstract java.nio.channels.Selector selector();
-    field public static final int OP_ACCEPT = 16; // 0x10
-    field public static final int OP_CONNECT = 8; // 0x8
-    field public static final int OP_READ = 1; // 0x1
-    field public static final int OP_WRITE = 4; // 0x4
-  }
-
-  public abstract class Selector implements java.io.Closeable {
-    ctor protected Selector();
-    method public abstract boolean isOpen();
-    method public abstract java.util.Set<java.nio.channels.SelectionKey> keys();
-    method public static java.nio.channels.Selector open() throws java.io.IOException;
-    method public abstract java.nio.channels.spi.SelectorProvider provider();
-    method public abstract int select(long) throws java.io.IOException;
-    method public abstract int select() throws java.io.IOException;
-    method public abstract int selectNow() throws java.io.IOException;
-    method public abstract java.util.Set<java.nio.channels.SelectionKey> selectedKeys();
-    method public abstract java.nio.channels.Selector wakeup();
-  }
-
-  public abstract class ServerSocketChannel extends java.nio.channels.spi.AbstractSelectableChannel implements java.nio.channels.NetworkChannel {
-    ctor protected ServerSocketChannel(java.nio.channels.spi.SelectorProvider);
-    method public abstract java.nio.channels.SocketChannel accept() throws java.io.IOException;
-    method public final java.nio.channels.ServerSocketChannel bind(java.net.SocketAddress) throws java.io.IOException;
-    method public abstract java.nio.channels.ServerSocketChannel bind(java.net.SocketAddress, int) throws java.io.IOException;
-    method public static java.nio.channels.ServerSocketChannel open() throws java.io.IOException;
-    method public abstract <T> java.nio.channels.ServerSocketChannel setOption(java.net.SocketOption<T>, T) throws java.io.IOException;
-    method public abstract java.net.ServerSocket socket();
-    method public final int validOps();
-  }
-
-  public class ShutdownChannelGroupException extends java.lang.IllegalStateException {
-    ctor public ShutdownChannelGroupException();
-  }
-
-  public abstract class SocketChannel extends java.nio.channels.spi.AbstractSelectableChannel implements java.nio.channels.ByteChannel java.nio.channels.GatheringByteChannel java.nio.channels.NetworkChannel java.nio.channels.ScatteringByteChannel {
-    ctor protected SocketChannel(java.nio.channels.spi.SelectorProvider);
-    method public abstract java.nio.channels.SocketChannel bind(java.net.SocketAddress) throws java.io.IOException;
-    method public abstract boolean connect(java.net.SocketAddress) throws java.io.IOException;
-    method public abstract boolean finishConnect() throws java.io.IOException;
-    method public abstract java.net.SocketAddress getRemoteAddress() throws java.io.IOException;
-    method public abstract boolean isConnected();
-    method public abstract boolean isConnectionPending();
-    method public static java.nio.channels.SocketChannel open() throws java.io.IOException;
-    method public static java.nio.channels.SocketChannel open(java.net.SocketAddress) throws java.io.IOException;
-    method public final long read(java.nio.ByteBuffer[]) throws java.io.IOException;
-    method public abstract <T> java.nio.channels.SocketChannel setOption(java.net.SocketOption<T>, T) throws java.io.IOException;
-    method public abstract java.nio.channels.SocketChannel shutdownInput() throws java.io.IOException;
-    method public abstract java.nio.channels.SocketChannel shutdownOutput() throws java.io.IOException;
-    method public abstract java.net.Socket socket();
-    method public final int validOps();
-    method public final long write(java.nio.ByteBuffer[]) throws java.io.IOException;
-  }
-
-  public class UnresolvedAddressException extends java.lang.IllegalArgumentException {
-    ctor public UnresolvedAddressException();
-  }
-
-  public class UnsupportedAddressTypeException extends java.lang.IllegalArgumentException {
-    ctor public UnsupportedAddressTypeException();
-  }
-
-  public interface WritableByteChannel extends java.nio.channels.Channel {
-    method public int write(java.nio.ByteBuffer) throws java.io.IOException;
-  }
-
-  public class WritePendingException extends java.lang.IllegalStateException {
-    ctor public WritePendingException();
-  }
-
-}
-
-package java.nio.channels.spi {
-
-  public abstract class AbstractInterruptibleChannel implements java.nio.channels.Channel java.nio.channels.InterruptibleChannel {
-    ctor protected AbstractInterruptibleChannel();
-    method protected final void begin();
-    method public final void close() throws java.io.IOException;
-    method protected final void end(boolean) throws java.nio.channels.AsynchronousCloseException;
-    method protected abstract void implCloseChannel() throws java.io.IOException;
-    method public final boolean isOpen();
-  }
-
-  public abstract class AbstractSelectableChannel extends java.nio.channels.SelectableChannel {
-    ctor protected AbstractSelectableChannel(java.nio.channels.spi.SelectorProvider);
-    method public final Object blockingLock();
-    method public final java.nio.channels.SelectableChannel configureBlocking(boolean) throws java.io.IOException;
-    method protected final void implCloseChannel() throws java.io.IOException;
-    method protected abstract void implCloseSelectableChannel() throws java.io.IOException;
-    method protected abstract void implConfigureBlocking(boolean) throws java.io.IOException;
-    method public final boolean isBlocking();
-    method public final boolean isRegistered();
-    method public final java.nio.channels.SelectionKey keyFor(java.nio.channels.Selector);
-    method public final java.nio.channels.spi.SelectorProvider provider();
-    method public final java.nio.channels.SelectionKey register(java.nio.channels.Selector, int, Object) throws java.nio.channels.ClosedChannelException;
-  }
-
-  public abstract class AbstractSelectionKey extends java.nio.channels.SelectionKey {
-    ctor protected AbstractSelectionKey();
-    method public final void cancel();
-    method public final boolean isValid();
-  }
-
-  public abstract class AbstractSelector extends java.nio.channels.Selector {
-    ctor protected AbstractSelector(java.nio.channels.spi.SelectorProvider);
-    method protected final void begin();
-    method protected final java.util.Set<java.nio.channels.SelectionKey> cancelledKeys();
-    method public final void close() throws java.io.IOException;
-    method protected final void deregister(java.nio.channels.spi.AbstractSelectionKey);
-    method protected final void end();
-    method protected abstract void implCloseSelector() throws java.io.IOException;
-    method public final boolean isOpen();
-    method public final java.nio.channels.spi.SelectorProvider provider();
-    method protected abstract java.nio.channels.SelectionKey register(java.nio.channels.spi.AbstractSelectableChannel, int, Object);
-  }
-
-  public abstract class AsynchronousChannelProvider {
-    ctor protected AsynchronousChannelProvider();
-    method public abstract java.nio.channels.AsynchronousChannelGroup openAsynchronousChannelGroup(int, java.util.concurrent.ThreadFactory) throws java.io.IOException;
-    method public abstract java.nio.channels.AsynchronousChannelGroup openAsynchronousChannelGroup(java.util.concurrent.ExecutorService, int) throws java.io.IOException;
-    method public abstract java.nio.channels.AsynchronousServerSocketChannel openAsynchronousServerSocketChannel(java.nio.channels.AsynchronousChannelGroup) throws java.io.IOException;
-    method public abstract java.nio.channels.AsynchronousSocketChannel openAsynchronousSocketChannel(java.nio.channels.AsynchronousChannelGroup) throws java.io.IOException;
-    method public static java.nio.channels.spi.AsynchronousChannelProvider provider();
-  }
-
-  public abstract class SelectorProvider {
-    ctor protected SelectorProvider();
-    method public java.nio.channels.Channel inheritedChannel() throws java.io.IOException;
-    method public abstract java.nio.channels.DatagramChannel openDatagramChannel() throws java.io.IOException;
-    method public abstract java.nio.channels.DatagramChannel openDatagramChannel(java.net.ProtocolFamily) throws java.io.IOException;
-    method public abstract java.nio.channels.Pipe openPipe() throws java.io.IOException;
-    method public abstract java.nio.channels.spi.AbstractSelector openSelector() throws java.io.IOException;
-    method public abstract java.nio.channels.ServerSocketChannel openServerSocketChannel() throws java.io.IOException;
-    method public abstract java.nio.channels.SocketChannel openSocketChannel() throws java.io.IOException;
-    method public static java.nio.channels.spi.SelectorProvider provider();
-  }
-
-}
-
-package java.nio.charset {
-
-  public class CharacterCodingException extends java.io.IOException {
-    ctor public CharacterCodingException();
-  }
-
-  public abstract class Charset implements java.lang.Comparable<java.nio.charset.Charset> {
-    ctor protected Charset(String, String[]);
-    method public final java.util.Set<java.lang.String> aliases();
-    method public static java.util.SortedMap<java.lang.String,java.nio.charset.Charset> availableCharsets();
-    method public boolean canEncode();
-    method public final int compareTo(java.nio.charset.Charset);
-    method public abstract boolean contains(java.nio.charset.Charset);
-    method public final java.nio.CharBuffer decode(java.nio.ByteBuffer);
-    method public static java.nio.charset.Charset defaultCharset();
-    method public String displayName();
-    method public String displayName(java.util.Locale);
-    method public final java.nio.ByteBuffer encode(java.nio.CharBuffer);
-    method public final java.nio.ByteBuffer encode(String);
-    method public final boolean equals(Object);
-    method public static java.nio.charset.Charset forName(String);
-    method public final int hashCode();
-    method public final boolean isRegistered();
-    method public static boolean isSupported(String);
-    method public final String name();
-    method public abstract java.nio.charset.CharsetDecoder newDecoder();
-    method public abstract java.nio.charset.CharsetEncoder newEncoder();
-    method public final String toString();
-  }
-
-  public abstract class CharsetDecoder {
-    ctor protected CharsetDecoder(java.nio.charset.Charset, float, float);
-    method public final float averageCharsPerByte();
-    method public final java.nio.charset.Charset charset();
-    method public final java.nio.charset.CoderResult decode(java.nio.ByteBuffer, java.nio.CharBuffer, boolean);
-    method public final java.nio.CharBuffer decode(java.nio.ByteBuffer) throws java.nio.charset.CharacterCodingException;
-    method protected abstract java.nio.charset.CoderResult decodeLoop(java.nio.ByteBuffer, java.nio.CharBuffer);
-    method public java.nio.charset.Charset detectedCharset();
-    method public final java.nio.charset.CoderResult flush(java.nio.CharBuffer);
-    method protected java.nio.charset.CoderResult implFlush(java.nio.CharBuffer);
-    method protected void implOnMalformedInput(java.nio.charset.CodingErrorAction);
-    method protected void implOnUnmappableCharacter(java.nio.charset.CodingErrorAction);
-    method protected void implReplaceWith(String);
-    method protected void implReset();
-    method public boolean isAutoDetecting();
-    method public boolean isCharsetDetected();
-    method public java.nio.charset.CodingErrorAction malformedInputAction();
-    method public final float maxCharsPerByte();
-    method public final java.nio.charset.CharsetDecoder onMalformedInput(java.nio.charset.CodingErrorAction);
-    method public final java.nio.charset.CharsetDecoder onUnmappableCharacter(java.nio.charset.CodingErrorAction);
-    method public final java.nio.charset.CharsetDecoder replaceWith(String);
-    method public final String replacement();
-    method public final java.nio.charset.CharsetDecoder reset();
-    method public java.nio.charset.CodingErrorAction unmappableCharacterAction();
-  }
-
-  public abstract class CharsetEncoder {
-    ctor protected CharsetEncoder(java.nio.charset.Charset, float, float, byte[]);
-    ctor protected CharsetEncoder(java.nio.charset.Charset, float, float);
-    method public final float averageBytesPerChar();
-    method public boolean canEncode(char);
-    method public boolean canEncode(CharSequence);
-    method public final java.nio.charset.Charset charset();
-    method public final java.nio.charset.CoderResult encode(java.nio.CharBuffer, java.nio.ByteBuffer, boolean);
-    method public final java.nio.ByteBuffer encode(java.nio.CharBuffer) throws java.nio.charset.CharacterCodingException;
-    method protected abstract java.nio.charset.CoderResult encodeLoop(java.nio.CharBuffer, java.nio.ByteBuffer);
-    method public final java.nio.charset.CoderResult flush(java.nio.ByteBuffer);
-    method protected java.nio.charset.CoderResult implFlush(java.nio.ByteBuffer);
-    method protected void implOnMalformedInput(java.nio.charset.CodingErrorAction);
-    method protected void implOnUnmappableCharacter(java.nio.charset.CodingErrorAction);
-    method protected void implReplaceWith(byte[]);
-    method protected void implReset();
-    method public boolean isLegalReplacement(byte[]);
-    method public java.nio.charset.CodingErrorAction malformedInputAction();
-    method public final float maxBytesPerChar();
-    method public final java.nio.charset.CharsetEncoder onMalformedInput(java.nio.charset.CodingErrorAction);
-    method public final java.nio.charset.CharsetEncoder onUnmappableCharacter(java.nio.charset.CodingErrorAction);
-    method public final java.nio.charset.CharsetEncoder replaceWith(byte[]);
-    method public final byte[] replacement();
-    method public final java.nio.charset.CharsetEncoder reset();
-    method public java.nio.charset.CodingErrorAction unmappableCharacterAction();
-  }
-
-  public class CoderMalfunctionError extends java.lang.Error {
-    ctor public CoderMalfunctionError(Exception);
-  }
-
-  public class CoderResult {
-    method public boolean isError();
-    method public boolean isMalformed();
-    method public boolean isOverflow();
-    method public boolean isUnderflow();
-    method public boolean isUnmappable();
-    method public int length();
-    method public static java.nio.charset.CoderResult malformedForLength(int);
-    method public void throwException() throws java.nio.charset.CharacterCodingException;
-    method public static java.nio.charset.CoderResult unmappableForLength(int);
-    field public static final java.nio.charset.CoderResult OVERFLOW;
-    field public static final java.nio.charset.CoderResult UNDERFLOW;
-  }
-
-  public class CodingErrorAction {
-    field public static final java.nio.charset.CodingErrorAction IGNORE;
-    field public static final java.nio.charset.CodingErrorAction REPLACE;
-    field public static final java.nio.charset.CodingErrorAction REPORT;
-  }
-
-  public class IllegalCharsetNameException extends java.lang.IllegalArgumentException {
-    ctor public IllegalCharsetNameException(String);
-    method public String getCharsetName();
-  }
-
-  public class MalformedInputException extends java.nio.charset.CharacterCodingException {
-    ctor public MalformedInputException(int);
-    method public int getInputLength();
-  }
-
-  public final class StandardCharsets {
-    field public static final java.nio.charset.Charset ISO_8859_1;
-    field public static final java.nio.charset.Charset US_ASCII;
-    field public static final java.nio.charset.Charset UTF_16;
-    field public static final java.nio.charset.Charset UTF_16BE;
-    field public static final java.nio.charset.Charset UTF_16LE;
-    field public static final java.nio.charset.Charset UTF_8;
-  }
-
-  public class UnmappableCharacterException extends java.nio.charset.CharacterCodingException {
-    ctor public UnmappableCharacterException(int);
-    method public int getInputLength();
-  }
-
-  public class UnsupportedCharsetException extends java.lang.IllegalArgumentException {
-    ctor public UnsupportedCharsetException(String);
-    method public String getCharsetName();
-  }
-
-}
-
-package java.nio.charset.spi {
-
-  public abstract class CharsetProvider {
-    ctor protected CharsetProvider();
-    method public abstract java.nio.charset.Charset charsetForName(String);
-    method public abstract java.util.Iterator<java.nio.charset.Charset> charsets();
-  }
-
-}
-
-package java.nio.file {
-
-  public class AccessDeniedException extends java.nio.file.FileSystemException {
-    ctor public AccessDeniedException(String);
-    ctor public AccessDeniedException(String, String, String);
-  }
-
-  public enum AccessMode {
-    enum_constant public static final java.nio.file.AccessMode EXECUTE;
-    enum_constant public static final java.nio.file.AccessMode READ;
-    enum_constant public static final java.nio.file.AccessMode WRITE;
-  }
-
-  public class AtomicMoveNotSupportedException extends java.nio.file.FileSystemException {
-    ctor public AtomicMoveNotSupportedException(String, String, String);
-  }
-
-  public class ClosedDirectoryStreamException extends java.lang.IllegalStateException {
-    ctor public ClosedDirectoryStreamException();
-  }
-
-  public class ClosedFileSystemException extends java.lang.IllegalStateException {
-    ctor public ClosedFileSystemException();
-  }
-
-  public class ClosedWatchServiceException extends java.lang.IllegalStateException {
-    ctor public ClosedWatchServiceException();
-  }
-
-  public interface CopyOption {
-  }
-
-  public final class DirectoryIteratorException extends java.util.ConcurrentModificationException {
-    ctor public DirectoryIteratorException(java.io.IOException);
-    method public java.io.IOException getCause();
-  }
-
-  public class DirectoryNotEmptyException extends java.nio.file.FileSystemException {
-    ctor public DirectoryNotEmptyException(String);
-  }
-
-  public interface DirectoryStream<T> extends java.io.Closeable java.lang.Iterable<T> {
-  }
-
-  @java.lang.FunctionalInterface public static interface DirectoryStream.Filter<T> {
-    method public boolean accept(T) throws java.io.IOException;
-  }
-
-  public class FileAlreadyExistsException extends java.nio.file.FileSystemException {
-    ctor public FileAlreadyExistsException(String);
-    ctor public FileAlreadyExistsException(String, String, String);
-  }
-
-  public abstract class FileStore {
-    ctor protected FileStore();
-    method public abstract Object getAttribute(String) throws java.io.IOException;
-    method public abstract <V extends java.nio.file.attribute.FileStoreAttributeView> V getFileStoreAttributeView(Class<V>);
-    method public abstract long getTotalSpace() throws java.io.IOException;
-    method public abstract long getUnallocatedSpace() throws java.io.IOException;
-    method public abstract long getUsableSpace() throws java.io.IOException;
-    method public abstract boolean isReadOnly();
-    method public abstract String name();
-    method public abstract boolean supportsFileAttributeView(Class<? extends java.nio.file.attribute.FileAttributeView>);
-    method public abstract boolean supportsFileAttributeView(String);
-    method public abstract String type();
-  }
-
-  public abstract class FileSystem implements java.io.Closeable {
-    ctor protected FileSystem();
-    method public abstract Iterable<java.nio.file.FileStore> getFileStores();
-    method public abstract java.nio.file.Path getPath(String, java.lang.String...);
-    method public abstract java.nio.file.PathMatcher getPathMatcher(String);
-    method public abstract Iterable<java.nio.file.Path> getRootDirectories();
-    method public abstract String getSeparator();
-    method public abstract java.nio.file.attribute.UserPrincipalLookupService getUserPrincipalLookupService();
-    method public abstract boolean isOpen();
-    method public abstract boolean isReadOnly();
-    method public abstract java.nio.file.WatchService newWatchService() throws java.io.IOException;
-    method public abstract java.nio.file.spi.FileSystemProvider provider();
-    method public abstract java.util.Set<java.lang.String> supportedFileAttributeViews();
-  }
-
-  public class FileSystemAlreadyExistsException extends java.lang.RuntimeException {
-    ctor public FileSystemAlreadyExistsException();
-    ctor public FileSystemAlreadyExistsException(String);
-  }
-
-  public class FileSystemException extends java.io.IOException {
-    ctor public FileSystemException(String);
-    ctor public FileSystemException(String, String, String);
-    method public String getFile();
-    method public String getOtherFile();
-    method public String getReason();
-  }
-
-  public class FileSystemLoopException extends java.nio.file.FileSystemException {
-    ctor public FileSystemLoopException(String);
-  }
-
-  public class FileSystemNotFoundException extends java.lang.RuntimeException {
-    ctor public FileSystemNotFoundException();
-    ctor public FileSystemNotFoundException(String);
-  }
-
-  public final class FileSystems {
-    method public static java.nio.file.FileSystem getDefault();
-    method public static java.nio.file.FileSystem getFileSystem(java.net.URI);
-    method public static java.nio.file.FileSystem newFileSystem(java.net.URI, java.util.Map<java.lang.String,?>) throws java.io.IOException;
-    method public static java.nio.file.FileSystem newFileSystem(java.net.URI, java.util.Map<java.lang.String,?>, ClassLoader) throws java.io.IOException;
-    method public static java.nio.file.FileSystem newFileSystem(java.nio.file.Path, ClassLoader) throws java.io.IOException;
-  }
-
-  public enum FileVisitOption {
-    enum_constant public static final java.nio.file.FileVisitOption FOLLOW_LINKS;
-  }
-
-  public enum FileVisitResult {
-    enum_constant public static final java.nio.file.FileVisitResult CONTINUE;
-    enum_constant public static final java.nio.file.FileVisitResult SKIP_SIBLINGS;
-    enum_constant public static final java.nio.file.FileVisitResult SKIP_SUBTREE;
-    enum_constant public static final java.nio.file.FileVisitResult TERMINATE;
-  }
-
-  public interface FileVisitor<T> {
-    method public java.nio.file.FileVisitResult postVisitDirectory(T, java.io.IOException) throws java.io.IOException;
-    method public java.nio.file.FileVisitResult preVisitDirectory(T, java.nio.file.attribute.BasicFileAttributes) throws java.io.IOException;
-    method public java.nio.file.FileVisitResult visitFile(T, java.nio.file.attribute.BasicFileAttributes) throws java.io.IOException;
-    method public java.nio.file.FileVisitResult visitFileFailed(T, java.io.IOException) throws java.io.IOException;
-  }
-
-  public final class Files {
-    method public static java.nio.file.Path copy(java.nio.file.Path, java.nio.file.Path, java.nio.file.CopyOption...) throws java.io.IOException;
-    method public static long copy(java.io.InputStream, java.nio.file.Path, java.nio.file.CopyOption...) throws java.io.IOException;
-    method public static long copy(java.nio.file.Path, java.io.OutputStream) throws java.io.IOException;
-    method public static java.nio.file.Path createDirectories(java.nio.file.Path, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public static java.nio.file.Path createDirectory(java.nio.file.Path, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public static java.nio.file.Path createFile(java.nio.file.Path, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public static java.nio.file.Path createLink(java.nio.file.Path, java.nio.file.Path) throws java.io.IOException;
-    method public static java.nio.file.Path createSymbolicLink(java.nio.file.Path, java.nio.file.Path, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public static java.nio.file.Path createTempDirectory(java.nio.file.Path, String, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public static java.nio.file.Path createTempDirectory(String, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public static java.nio.file.Path createTempFile(java.nio.file.Path, String, String, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public static java.nio.file.Path createTempFile(String, String, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public static void delete(java.nio.file.Path) throws java.io.IOException;
-    method public static boolean deleteIfExists(java.nio.file.Path) throws java.io.IOException;
-    method public static boolean exists(java.nio.file.Path, java.nio.file.LinkOption...);
-    method public static java.util.stream.Stream<java.nio.file.Path> find(java.nio.file.Path, int, java.util.function.BiPredicate<java.nio.file.Path,java.nio.file.attribute.BasicFileAttributes>, java.nio.file.FileVisitOption...) throws java.io.IOException;
-    method public static Object getAttribute(java.nio.file.Path, String, java.nio.file.LinkOption...) throws java.io.IOException;
-    method public static <V extends java.nio.file.attribute.FileAttributeView> V getFileAttributeView(java.nio.file.Path, Class<V>, java.nio.file.LinkOption...);
-    method public static java.nio.file.FileStore getFileStore(java.nio.file.Path) throws java.io.IOException;
-    method public static java.nio.file.attribute.FileTime getLastModifiedTime(java.nio.file.Path, java.nio.file.LinkOption...) throws java.io.IOException;
-    method public static java.nio.file.attribute.UserPrincipal getOwner(java.nio.file.Path, java.nio.file.LinkOption...) throws java.io.IOException;
-    method public static java.util.Set<java.nio.file.attribute.PosixFilePermission> getPosixFilePermissions(java.nio.file.Path, java.nio.file.LinkOption...) throws java.io.IOException;
-    method public static boolean isDirectory(java.nio.file.Path, java.nio.file.LinkOption...);
-    method public static boolean isExecutable(java.nio.file.Path);
-    method public static boolean isHidden(java.nio.file.Path) throws java.io.IOException;
-    method public static boolean isReadable(java.nio.file.Path);
-    method public static boolean isRegularFile(java.nio.file.Path, java.nio.file.LinkOption...);
-    method public static boolean isSameFile(java.nio.file.Path, java.nio.file.Path) throws java.io.IOException;
-    method public static boolean isSymbolicLink(java.nio.file.Path);
-    method public static boolean isWritable(java.nio.file.Path);
-    method public static java.util.stream.Stream<java.lang.String> lines(java.nio.file.Path, java.nio.charset.Charset) throws java.io.IOException;
-    method public static java.util.stream.Stream<java.lang.String> lines(java.nio.file.Path) throws java.io.IOException;
-    method public static java.util.stream.Stream<java.nio.file.Path> list(java.nio.file.Path) throws java.io.IOException;
-    method public static java.nio.file.Path move(java.nio.file.Path, java.nio.file.Path, java.nio.file.CopyOption...) throws java.io.IOException;
-    method public static java.io.BufferedReader newBufferedReader(java.nio.file.Path, java.nio.charset.Charset) throws java.io.IOException;
-    method public static java.io.BufferedReader newBufferedReader(java.nio.file.Path) throws java.io.IOException;
-    method public static java.io.BufferedWriter newBufferedWriter(java.nio.file.Path, java.nio.charset.Charset, java.nio.file.OpenOption...) throws java.io.IOException;
-    method public static java.io.BufferedWriter newBufferedWriter(java.nio.file.Path, java.nio.file.OpenOption...) throws java.io.IOException;
-    method public static java.nio.channels.SeekableByteChannel newByteChannel(java.nio.file.Path, java.util.Set<? extends java.nio.file.OpenOption>, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public static java.nio.channels.SeekableByteChannel newByteChannel(java.nio.file.Path, java.nio.file.OpenOption...) throws java.io.IOException;
-    method public static java.nio.file.DirectoryStream<java.nio.file.Path> newDirectoryStream(java.nio.file.Path) throws java.io.IOException;
-    method public static java.nio.file.DirectoryStream<java.nio.file.Path> newDirectoryStream(java.nio.file.Path, String) throws java.io.IOException;
-    method public static java.nio.file.DirectoryStream<java.nio.file.Path> newDirectoryStream(java.nio.file.Path, java.nio.file.DirectoryStream.Filter<? super java.nio.file.Path>) throws java.io.IOException;
-    method public static java.io.InputStream newInputStream(java.nio.file.Path, java.nio.file.OpenOption...) throws java.io.IOException;
-    method public static java.io.OutputStream newOutputStream(java.nio.file.Path, java.nio.file.OpenOption...) throws java.io.IOException;
-    method public static boolean notExists(java.nio.file.Path, java.nio.file.LinkOption...);
-    method public static String probeContentType(java.nio.file.Path) throws java.io.IOException;
-    method public static byte[] readAllBytes(java.nio.file.Path) throws java.io.IOException;
-    method public static java.util.List<java.lang.String> readAllLines(java.nio.file.Path, java.nio.charset.Charset) throws java.io.IOException;
-    method public static java.util.List<java.lang.String> readAllLines(java.nio.file.Path) throws java.io.IOException;
-    method public static <A extends java.nio.file.attribute.BasicFileAttributes> A readAttributes(java.nio.file.Path, Class<A>, java.nio.file.LinkOption...) throws java.io.IOException;
-    method public static java.util.Map<java.lang.String,java.lang.Object> readAttributes(java.nio.file.Path, String, java.nio.file.LinkOption...) throws java.io.IOException;
-    method public static java.nio.file.Path readSymbolicLink(java.nio.file.Path) throws java.io.IOException;
-    method public static java.nio.file.Path setAttribute(java.nio.file.Path, String, Object, java.nio.file.LinkOption...) throws java.io.IOException;
-    method public static java.nio.file.Path setLastModifiedTime(java.nio.file.Path, java.nio.file.attribute.FileTime) throws java.io.IOException;
-    method public static java.nio.file.Path setOwner(java.nio.file.Path, java.nio.file.attribute.UserPrincipal) throws java.io.IOException;
-    method public static java.nio.file.Path setPosixFilePermissions(java.nio.file.Path, java.util.Set<java.nio.file.attribute.PosixFilePermission>) throws java.io.IOException;
-    method public static long size(java.nio.file.Path) throws java.io.IOException;
-    method public static java.util.stream.Stream<java.nio.file.Path> walk(java.nio.file.Path, int, java.nio.file.FileVisitOption...) throws java.io.IOException;
-    method public static java.util.stream.Stream<java.nio.file.Path> walk(java.nio.file.Path, java.nio.file.FileVisitOption...) throws java.io.IOException;
-    method public static java.nio.file.Path walkFileTree(java.nio.file.Path, java.util.Set<java.nio.file.FileVisitOption>, int, java.nio.file.FileVisitor<? super java.nio.file.Path>) throws java.io.IOException;
-    method public static java.nio.file.Path walkFileTree(java.nio.file.Path, java.nio.file.FileVisitor<? super java.nio.file.Path>) throws java.io.IOException;
-    method public static java.nio.file.Path write(java.nio.file.Path, byte[], java.nio.file.OpenOption...) throws java.io.IOException;
-    method public static java.nio.file.Path write(java.nio.file.Path, Iterable<? extends java.lang.CharSequence>, java.nio.charset.Charset, java.nio.file.OpenOption...) throws java.io.IOException;
-    method public static java.nio.file.Path write(java.nio.file.Path, Iterable<? extends java.lang.CharSequence>, java.nio.file.OpenOption...) throws java.io.IOException;
-  }
-
-  public class InvalidPathException extends java.lang.IllegalArgumentException {
-    ctor public InvalidPathException(String, String, int);
-    ctor public InvalidPathException(String, String);
-    method public int getIndex();
-    method public String getInput();
-    method public String getReason();
-  }
-
-  public enum LinkOption implements java.nio.file.CopyOption java.nio.file.OpenOption {
-    enum_constant public static final java.nio.file.LinkOption NOFOLLOW_LINKS;
-  }
-
-  public final class LinkPermission extends java.security.BasicPermission {
-    ctor public LinkPermission(String);
-    ctor public LinkPermission(String, String);
-  }
-
-  public class NoSuchFileException extends java.nio.file.FileSystemException {
-    ctor public NoSuchFileException(String);
-    ctor public NoSuchFileException(String, String, String);
-  }
-
-  public class NotDirectoryException extends java.nio.file.FileSystemException {
-    ctor public NotDirectoryException(String);
-  }
-
-  public class NotLinkException extends java.nio.file.FileSystemException {
-    ctor public NotLinkException(String);
-    ctor public NotLinkException(String, String, String);
-  }
-
-  public interface OpenOption {
-  }
-
-  public interface Path extends java.lang.Comparable<java.nio.file.Path> java.lang.Iterable<java.nio.file.Path> java.nio.file.Watchable {
-    method public int compareTo(java.nio.file.Path);
-    method public boolean endsWith(java.nio.file.Path);
-    method public boolean endsWith(String);
-    method public boolean equals(Object);
-    method public java.nio.file.Path getFileName();
-    method public java.nio.file.FileSystem getFileSystem();
-    method public java.nio.file.Path getName(int);
-    method public int getNameCount();
-    method public java.nio.file.Path getParent();
-    method public java.nio.file.Path getRoot();
-    method public int hashCode();
-    method public boolean isAbsolute();
-    method public java.util.Iterator<java.nio.file.Path> iterator();
-    method public java.nio.file.Path normalize();
-    method public java.nio.file.Path relativize(java.nio.file.Path);
-    method public java.nio.file.Path resolve(java.nio.file.Path);
-    method public java.nio.file.Path resolve(String);
-    method public java.nio.file.Path resolveSibling(java.nio.file.Path);
-    method public java.nio.file.Path resolveSibling(String);
-    method public boolean startsWith(java.nio.file.Path);
-    method public boolean startsWith(String);
-    method public java.nio.file.Path subpath(int, int);
-    method public java.nio.file.Path toAbsolutePath();
-    method public java.io.File toFile();
-    method public java.nio.file.Path toRealPath(java.nio.file.LinkOption...) throws java.io.IOException;
-    method public String toString();
-    method public java.net.URI toUri();
-  }
-
-  @java.lang.FunctionalInterface public interface PathMatcher {
-    method public boolean matches(java.nio.file.Path);
-  }
-
-  public final class Paths {
-    method public static java.nio.file.Path get(String, java.lang.String...);
-    method public static java.nio.file.Path get(java.net.URI);
-  }
-
-  public class ProviderMismatchException extends java.lang.IllegalArgumentException {
-    ctor public ProviderMismatchException();
-    ctor public ProviderMismatchException(String);
-  }
-
-  public class ProviderNotFoundException extends java.lang.RuntimeException {
-    ctor public ProviderNotFoundException();
-    ctor public ProviderNotFoundException(String);
-  }
-
-  public class ReadOnlyFileSystemException extends java.lang.UnsupportedOperationException {
-    ctor public ReadOnlyFileSystemException();
-  }
-
-  public interface SecureDirectoryStream<T> extends java.nio.file.DirectoryStream<T> {
-    method public void deleteDirectory(T) throws java.io.IOException;
-    method public void deleteFile(T) throws java.io.IOException;
-    method public <V extends java.nio.file.attribute.FileAttributeView> V getFileAttributeView(Class<V>);
-    method public <V extends java.nio.file.attribute.FileAttributeView> V getFileAttributeView(T, Class<V>, java.nio.file.LinkOption...);
-    method public void move(T, java.nio.file.SecureDirectoryStream<T>, T) throws java.io.IOException;
-    method public java.nio.channels.SeekableByteChannel newByteChannel(T, java.util.Set<? extends java.nio.file.OpenOption>, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public java.nio.file.SecureDirectoryStream<T> newDirectoryStream(T, java.nio.file.LinkOption...) throws java.io.IOException;
-  }
-
-  public class SimpleFileVisitor<T> implements java.nio.file.FileVisitor<T> {
-    ctor protected SimpleFileVisitor();
-    method public java.nio.file.FileVisitResult postVisitDirectory(T, java.io.IOException) throws java.io.IOException;
-    method public java.nio.file.FileVisitResult preVisitDirectory(T, java.nio.file.attribute.BasicFileAttributes) throws java.io.IOException;
-    method public java.nio.file.FileVisitResult visitFile(T, java.nio.file.attribute.BasicFileAttributes) throws java.io.IOException;
-    method public java.nio.file.FileVisitResult visitFileFailed(T, java.io.IOException) throws java.io.IOException;
-  }
-
-  public enum StandardCopyOption implements java.nio.file.CopyOption {
-    enum_constant public static final java.nio.file.StandardCopyOption ATOMIC_MOVE;
-    enum_constant public static final java.nio.file.StandardCopyOption COPY_ATTRIBUTES;
-    enum_constant public static final java.nio.file.StandardCopyOption REPLACE_EXISTING;
-  }
-
-  public enum StandardOpenOption implements java.nio.file.OpenOption {
-    enum_constant public static final java.nio.file.StandardOpenOption APPEND;
-    enum_constant public static final java.nio.file.StandardOpenOption CREATE;
-    enum_constant public static final java.nio.file.StandardOpenOption CREATE_NEW;
-    enum_constant public static final java.nio.file.StandardOpenOption DELETE_ON_CLOSE;
-    enum_constant public static final java.nio.file.StandardOpenOption DSYNC;
-    enum_constant public static final java.nio.file.StandardOpenOption READ;
-    enum_constant public static final java.nio.file.StandardOpenOption SPARSE;
-    enum_constant public static final java.nio.file.StandardOpenOption SYNC;
-    enum_constant public static final java.nio.file.StandardOpenOption TRUNCATE_EXISTING;
-    enum_constant public static final java.nio.file.StandardOpenOption WRITE;
-  }
-
-  public final class StandardWatchEventKinds {
-    field public static final java.nio.file.WatchEvent.Kind<java.nio.file.Path> ENTRY_CREATE;
-    field public static final java.nio.file.WatchEvent.Kind<java.nio.file.Path> ENTRY_DELETE;
-    field public static final java.nio.file.WatchEvent.Kind<java.nio.file.Path> ENTRY_MODIFY;
-    field public static final java.nio.file.WatchEvent.Kind<java.lang.Object> OVERFLOW;
-  }
-
-  public interface WatchEvent<T> {
-    method public T context();
-    method public int count();
-    method public java.nio.file.WatchEvent.Kind<T> kind();
-  }
-
-  public static interface WatchEvent.Kind<T> {
-    method public String name();
-    method public Class<T> type();
-  }
-
-  public static interface WatchEvent.Modifier {
-    method public String name();
-  }
-
-  public interface WatchKey {
-    method public void cancel();
-    method public boolean isValid();
-    method public java.util.List<java.nio.file.WatchEvent<?>> pollEvents();
-    method public boolean reset();
-    method public java.nio.file.Watchable watchable();
-  }
-
-  public interface WatchService extends java.io.Closeable {
-    method public java.nio.file.WatchKey poll();
-    method public java.nio.file.WatchKey poll(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-    method public java.nio.file.WatchKey take() throws java.lang.InterruptedException;
-  }
-
-  public interface Watchable {
-    method public java.nio.file.WatchKey register(java.nio.file.WatchService, java.nio.file.WatchEvent.Kind<?>[], java.nio.file.WatchEvent.Modifier...) throws java.io.IOException;
-    method public java.nio.file.WatchKey register(java.nio.file.WatchService, java.nio.file.WatchEvent.Kind<?>...) throws java.io.IOException;
-  }
-
-}
-
-package java.nio.file.attribute {
-
-  public final class AclEntry {
-    method public java.util.Set<java.nio.file.attribute.AclEntryFlag> flags();
-    method public static java.nio.file.attribute.AclEntry.Builder newBuilder();
-    method public static java.nio.file.attribute.AclEntry.Builder newBuilder(java.nio.file.attribute.AclEntry);
-    method public java.util.Set<java.nio.file.attribute.AclEntryPermission> permissions();
-    method public java.nio.file.attribute.UserPrincipal principal();
-    method public java.nio.file.attribute.AclEntryType type();
-  }
-
-  public static final class AclEntry.Builder {
-    method public java.nio.file.attribute.AclEntry build();
-    method public java.nio.file.attribute.AclEntry.Builder setFlags(java.util.Set<java.nio.file.attribute.AclEntryFlag>);
-    method public java.nio.file.attribute.AclEntry.Builder setFlags(java.nio.file.attribute.AclEntryFlag...);
-    method public java.nio.file.attribute.AclEntry.Builder setPermissions(java.util.Set<java.nio.file.attribute.AclEntryPermission>);
-    method public java.nio.file.attribute.AclEntry.Builder setPermissions(java.nio.file.attribute.AclEntryPermission...);
-    method public java.nio.file.attribute.AclEntry.Builder setPrincipal(java.nio.file.attribute.UserPrincipal);
-    method public java.nio.file.attribute.AclEntry.Builder setType(java.nio.file.attribute.AclEntryType);
-  }
-
-  public enum AclEntryFlag {
-    enum_constant public static final java.nio.file.attribute.AclEntryFlag DIRECTORY_INHERIT;
-    enum_constant public static final java.nio.file.attribute.AclEntryFlag FILE_INHERIT;
-    enum_constant public static final java.nio.file.attribute.AclEntryFlag INHERIT_ONLY;
-    enum_constant public static final java.nio.file.attribute.AclEntryFlag NO_PROPAGATE_INHERIT;
-  }
-
-  public enum AclEntryPermission {
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission APPEND_DATA;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission DELETE;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission DELETE_CHILD;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission EXECUTE;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission READ_ACL;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission READ_ATTRIBUTES;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission READ_DATA;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission READ_NAMED_ATTRS;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission SYNCHRONIZE;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission WRITE_ACL;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission WRITE_ATTRIBUTES;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission WRITE_DATA;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission WRITE_NAMED_ATTRS;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission WRITE_OWNER;
-    field public static final java.nio.file.attribute.AclEntryPermission ADD_FILE;
-    field public static final java.nio.file.attribute.AclEntryPermission ADD_SUBDIRECTORY;
-    field public static final java.nio.file.attribute.AclEntryPermission LIST_DIRECTORY;
-  }
-
-  public enum AclEntryType {
-    enum_constant public static final java.nio.file.attribute.AclEntryType ALARM;
-    enum_constant public static final java.nio.file.attribute.AclEntryType ALLOW;
-    enum_constant public static final java.nio.file.attribute.AclEntryType AUDIT;
-    enum_constant public static final java.nio.file.attribute.AclEntryType DENY;
-  }
-
-  public interface AclFileAttributeView extends java.nio.file.attribute.FileOwnerAttributeView {
-    method public java.util.List<java.nio.file.attribute.AclEntry> getAcl() throws java.io.IOException;
-    method public void setAcl(java.util.List<java.nio.file.attribute.AclEntry>) throws java.io.IOException;
-  }
-
-  public interface AttributeView {
-    method public String name();
-  }
-
-  public interface BasicFileAttributeView extends java.nio.file.attribute.FileAttributeView {
-    method public java.nio.file.attribute.BasicFileAttributes readAttributes() throws java.io.IOException;
-    method public void setTimes(java.nio.file.attribute.FileTime, java.nio.file.attribute.FileTime, java.nio.file.attribute.FileTime) throws java.io.IOException;
-  }
-
-  public interface BasicFileAttributes {
-    method public java.nio.file.attribute.FileTime creationTime();
-    method public Object fileKey();
-    method public boolean isDirectory();
-    method public boolean isOther();
-    method public boolean isRegularFile();
-    method public boolean isSymbolicLink();
-    method public java.nio.file.attribute.FileTime lastAccessTime();
-    method public java.nio.file.attribute.FileTime lastModifiedTime();
-    method public long size();
-  }
-
-  public interface DosFileAttributeView extends java.nio.file.attribute.BasicFileAttributeView {
-    method public java.nio.file.attribute.DosFileAttributes readAttributes() throws java.io.IOException;
-    method public void setArchive(boolean) throws java.io.IOException;
-    method public void setHidden(boolean) throws java.io.IOException;
-    method public void setReadOnly(boolean) throws java.io.IOException;
-    method public void setSystem(boolean) throws java.io.IOException;
-  }
-
-  public interface DosFileAttributes extends java.nio.file.attribute.BasicFileAttributes {
-    method public boolean isArchive();
-    method public boolean isHidden();
-    method public boolean isReadOnly();
-    method public boolean isSystem();
-  }
-
-  public interface FileAttribute<T> {
-    method public String name();
-    method public T value();
-  }
-
-  public interface FileAttributeView extends java.nio.file.attribute.AttributeView {
-  }
-
-  public interface FileOwnerAttributeView extends java.nio.file.attribute.FileAttributeView {
-    method public java.nio.file.attribute.UserPrincipal getOwner() throws java.io.IOException;
-    method public void setOwner(java.nio.file.attribute.UserPrincipal) throws java.io.IOException;
-  }
-
-  public interface FileStoreAttributeView extends java.nio.file.attribute.AttributeView {
-  }
-
-  public final class FileTime implements java.lang.Comparable<java.nio.file.attribute.FileTime> {
-    method public int compareTo(java.nio.file.attribute.FileTime);
-    method public static java.nio.file.attribute.FileTime from(long, java.util.concurrent.TimeUnit);
-    method public static java.nio.file.attribute.FileTime from(java.time.Instant);
-    method public static java.nio.file.attribute.FileTime fromMillis(long);
-    method public long to(java.util.concurrent.TimeUnit);
-    method public java.time.Instant toInstant();
-    method public long toMillis();
-  }
-
-  public interface GroupPrincipal extends java.nio.file.attribute.UserPrincipal {
-  }
-
-  public interface PosixFileAttributeView extends java.nio.file.attribute.BasicFileAttributeView java.nio.file.attribute.FileOwnerAttributeView {
-    method public java.nio.file.attribute.PosixFileAttributes readAttributes() throws java.io.IOException;
-    method public void setGroup(java.nio.file.attribute.GroupPrincipal) throws java.io.IOException;
-    method public void setPermissions(java.util.Set<java.nio.file.attribute.PosixFilePermission>) throws java.io.IOException;
-  }
-
-  public interface PosixFileAttributes extends java.nio.file.attribute.BasicFileAttributes {
-    method public java.nio.file.attribute.GroupPrincipal group();
-    method public java.nio.file.attribute.UserPrincipal owner();
-    method public java.util.Set<java.nio.file.attribute.PosixFilePermission> permissions();
-  }
-
-  public enum PosixFilePermission {
-    enum_constant public static final java.nio.file.attribute.PosixFilePermission GROUP_EXECUTE;
-    enum_constant public static final java.nio.file.attribute.PosixFilePermission GROUP_READ;
-    enum_constant public static final java.nio.file.attribute.PosixFilePermission GROUP_WRITE;
-    enum_constant public static final java.nio.file.attribute.PosixFilePermission OTHERS_EXECUTE;
-    enum_constant public static final java.nio.file.attribute.PosixFilePermission OTHERS_READ;
-    enum_constant public static final java.nio.file.attribute.PosixFilePermission OTHERS_WRITE;
-    enum_constant public static final java.nio.file.attribute.PosixFilePermission OWNER_EXECUTE;
-    enum_constant public static final java.nio.file.attribute.PosixFilePermission OWNER_READ;
-    enum_constant public static final java.nio.file.attribute.PosixFilePermission OWNER_WRITE;
-  }
-
-  public final class PosixFilePermissions {
-    method public static java.nio.file.attribute.FileAttribute<java.util.Set<java.nio.file.attribute.PosixFilePermission>> asFileAttribute(java.util.Set<java.nio.file.attribute.PosixFilePermission>);
-    method public static java.util.Set<java.nio.file.attribute.PosixFilePermission> fromString(String);
-    method public static String toString(java.util.Set<java.nio.file.attribute.PosixFilePermission>);
-  }
-
-  public interface UserDefinedFileAttributeView extends java.nio.file.attribute.FileAttributeView {
-    method public void delete(String) throws java.io.IOException;
-    method public java.util.List<java.lang.String> list() throws java.io.IOException;
-    method public int read(String, java.nio.ByteBuffer) throws java.io.IOException;
-    method public int size(String) throws java.io.IOException;
-    method public int write(String, java.nio.ByteBuffer) throws java.io.IOException;
-  }
-
-  public interface UserPrincipal extends java.security.Principal {
-  }
-
-  public abstract class UserPrincipalLookupService {
-    ctor protected UserPrincipalLookupService();
-    method public abstract java.nio.file.attribute.GroupPrincipal lookupPrincipalByGroupName(String) throws java.io.IOException;
-    method public abstract java.nio.file.attribute.UserPrincipal lookupPrincipalByName(String) throws java.io.IOException;
-  }
-
-  public class UserPrincipalNotFoundException extends java.io.IOException {
-    ctor public UserPrincipalNotFoundException(String);
-    method public String getName();
-  }
-
-}
-
-package java.nio.file.spi {
-
-  public abstract class FileSystemProvider {
-    ctor protected FileSystemProvider();
-    method public abstract void checkAccess(java.nio.file.Path, java.nio.file.AccessMode...) throws java.io.IOException;
-    method public abstract void copy(java.nio.file.Path, java.nio.file.Path, java.nio.file.CopyOption...) throws java.io.IOException;
-    method public abstract void createDirectory(java.nio.file.Path, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public void createLink(java.nio.file.Path, java.nio.file.Path) throws java.io.IOException;
-    method public void createSymbolicLink(java.nio.file.Path, java.nio.file.Path, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public abstract void delete(java.nio.file.Path) throws java.io.IOException;
-    method public boolean deleteIfExists(java.nio.file.Path) throws java.io.IOException;
-    method public abstract <V extends java.nio.file.attribute.FileAttributeView> V getFileAttributeView(java.nio.file.Path, Class<V>, java.nio.file.LinkOption...);
-    method public abstract java.nio.file.FileStore getFileStore(java.nio.file.Path) throws java.io.IOException;
-    method public abstract java.nio.file.FileSystem getFileSystem(java.net.URI);
-    method public abstract java.nio.file.Path getPath(java.net.URI);
-    method public abstract String getScheme();
-    method public static java.util.List<java.nio.file.spi.FileSystemProvider> installedProviders();
-    method public abstract boolean isHidden(java.nio.file.Path) throws java.io.IOException;
-    method public abstract boolean isSameFile(java.nio.file.Path, java.nio.file.Path) throws java.io.IOException;
-    method public abstract void move(java.nio.file.Path, java.nio.file.Path, java.nio.file.CopyOption...) throws java.io.IOException;
-    method public java.nio.channels.AsynchronousFileChannel newAsynchronousFileChannel(java.nio.file.Path, java.util.Set<? extends java.nio.file.OpenOption>, java.util.concurrent.ExecutorService, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public abstract java.nio.channels.SeekableByteChannel newByteChannel(java.nio.file.Path, java.util.Set<? extends java.nio.file.OpenOption>, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public abstract java.nio.file.DirectoryStream<java.nio.file.Path> newDirectoryStream(java.nio.file.Path, java.nio.file.DirectoryStream.Filter<? super java.nio.file.Path>) throws java.io.IOException;
-    method public java.nio.channels.FileChannel newFileChannel(java.nio.file.Path, java.util.Set<? extends java.nio.file.OpenOption>, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public abstract java.nio.file.FileSystem newFileSystem(java.net.URI, java.util.Map<java.lang.String,?>) throws java.io.IOException;
-    method public java.nio.file.FileSystem newFileSystem(java.nio.file.Path, java.util.Map<java.lang.String,?>) throws java.io.IOException;
-    method public java.io.InputStream newInputStream(java.nio.file.Path, java.nio.file.OpenOption...) throws java.io.IOException;
-    method public java.io.OutputStream newOutputStream(java.nio.file.Path, java.nio.file.OpenOption...) throws java.io.IOException;
-    method public abstract <A extends java.nio.file.attribute.BasicFileAttributes> A readAttributes(java.nio.file.Path, Class<A>, java.nio.file.LinkOption...) throws java.io.IOException;
-    method public abstract java.util.Map<java.lang.String,java.lang.Object> readAttributes(java.nio.file.Path, String, java.nio.file.LinkOption...) throws java.io.IOException;
-    method public java.nio.file.Path readSymbolicLink(java.nio.file.Path) throws java.io.IOException;
-    method public abstract void setAttribute(java.nio.file.Path, String, Object, java.nio.file.LinkOption...) throws java.io.IOException;
-  }
-
-  public abstract class FileTypeDetector {
-    ctor protected FileTypeDetector();
-    method public abstract String probeContentType(java.nio.file.Path) throws java.io.IOException;
-  }
-
-}
-
-package java.security {
-
-  public final class AccessControlContext {
-    ctor public AccessControlContext(java.security.ProtectionDomain[]);
-    ctor public AccessControlContext(java.security.AccessControlContext, java.security.DomainCombiner);
-    method public void checkPermission(java.security.Permission) throws java.security.AccessControlException;
-    method public java.security.DomainCombiner getDomainCombiner();
-  }
-
-  public class AccessControlException extends java.lang.SecurityException {
-    ctor public AccessControlException(String);
-    ctor public AccessControlException(String, java.security.Permission);
-    method public java.security.Permission getPermission();
-  }
-
-  public final class AccessController {
-    method public static void checkPermission(java.security.Permission) throws java.security.AccessControlException;
-    method public static <T> T doPrivileged(java.security.PrivilegedAction<T>);
-    method public static <T> T doPrivileged(java.security.PrivilegedAction<T>, java.security.AccessControlContext);
-    method public static <T> T doPrivileged(java.security.PrivilegedExceptionAction<T>) throws java.security.PrivilegedActionException;
-    method public static <T> T doPrivileged(java.security.PrivilegedExceptionAction<T>, java.security.AccessControlContext) throws java.security.PrivilegedActionException;
-    method public static <T> T doPrivilegedWithCombiner(java.security.PrivilegedAction<T>);
-    method public static <T> T doPrivilegedWithCombiner(java.security.PrivilegedExceptionAction<T>) throws java.security.PrivilegedActionException;
-    method public static java.security.AccessControlContext getContext();
-  }
-
-  public interface AlgorithmConstraints {
-    method public boolean permits(java.util.Set<java.security.CryptoPrimitive>, String, java.security.AlgorithmParameters);
-    method public boolean permits(java.util.Set<java.security.CryptoPrimitive>, java.security.Key);
-    method public boolean permits(java.util.Set<java.security.CryptoPrimitive>, String, java.security.Key, java.security.AlgorithmParameters);
-  }
-
-  public class AlgorithmParameterGenerator {
-    ctor protected AlgorithmParameterGenerator(java.security.AlgorithmParameterGeneratorSpi, java.security.Provider, String);
-    method public final java.security.AlgorithmParameters generateParameters();
-    method public final String getAlgorithm();
-    method public static java.security.AlgorithmParameterGenerator getInstance(String) throws java.security.NoSuchAlgorithmException;
-    method public static java.security.AlgorithmParameterGenerator getInstance(String, String) throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException;
-    method public static java.security.AlgorithmParameterGenerator getInstance(String, java.security.Provider) throws java.security.NoSuchAlgorithmException;
-    method public final java.security.Provider getProvider();
-    method public final void init(int);
-    method public final void init(int, java.security.SecureRandom);
-    method public final void init(java.security.spec.AlgorithmParameterSpec) throws java.security.InvalidAlgorithmParameterException;
-    method public final void init(java.security.spec.AlgorithmParameterSpec, java.security.SecureRandom) throws java.security.InvalidAlgorithmParameterException;
-  }
-
-  public abstract class AlgorithmParameterGeneratorSpi {
-    ctor public AlgorithmParameterGeneratorSpi();
-    method protected abstract java.security.AlgorithmParameters engineGenerateParameters();
-    method protected abstract void engineInit(int, java.security.SecureRandom);
-    method protected abstract void engineInit(java.security.spec.AlgorithmParameterSpec, java.security.SecureRandom) throws java.security.InvalidAlgorithmParameterException;
-  }
-
-  public class AlgorithmParameters {
-    ctor protected AlgorithmParameters(java.security.AlgorithmParametersSpi, java.security.Provider, String);
-    method public final String getAlgorithm();
-    method public final byte[] getEncoded() throws java.io.IOException;
-    method public final byte[] getEncoded(String) throws java.io.IOException;
-    method public static java.security.AlgorithmParameters getInstance(String) throws java.security.NoSuchAlgorithmException;
-    method public static java.security.AlgorithmParameters getInstance(String, String) throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException;
-    method public static java.security.AlgorithmParameters getInstance(String, java.security.Provider) throws java.security.NoSuchAlgorithmException;
-    method public final <T extends java.security.spec.AlgorithmParameterSpec> T getParameterSpec(Class<T>) throws java.security.spec.InvalidParameterSpecException;
-    method public final java.security.Provider getProvider();
-    method public final void init(java.security.spec.AlgorithmParameterSpec) throws java.security.spec.InvalidParameterSpecException;
-    method public final void init(byte[]) throws java.io.IOException;
-    method public final void init(byte[], String) throws java.io.IOException;
-    method public final String toString();
-  }
-
-  public abstract class AlgorithmParametersSpi {
-    ctor public AlgorithmParametersSpi();
-    method protected abstract byte[] engineGetEncoded() throws java.io.IOException;
-    method protected abstract byte[] engineGetEncoded(String) throws java.io.IOException;
-    method protected abstract <T extends java.security.spec.AlgorithmParameterSpec> T engineGetParameterSpec(Class<T>) throws java.security.spec.InvalidParameterSpecException;
-    method protected abstract void engineInit(java.security.spec.AlgorithmParameterSpec) throws java.security.spec.InvalidParameterSpecException;
-    method protected abstract void engineInit(byte[]) throws java.io.IOException;
-    method protected abstract void engineInit(byte[], String) throws java.io.IOException;
-    method protected abstract String engineToString();
-  }
-
-  public final class AllPermission extends java.security.Permission {
-    ctor public AllPermission();
-    ctor public AllPermission(String, String);
-    method public String getActions();
-    method public boolean implies(java.security.Permission);
-  }
-
-  public abstract class AuthProvider extends java.security.Provider {
-    ctor protected AuthProvider(String, double, String);
-    method public abstract void login(javax.security.auth.Subject, javax.security.auth.callback.CallbackHandler) throws javax.security.auth.login.LoginException;
-    method public abstract void logout() throws javax.security.auth.login.LoginException;
-    method public abstract void setCallbackHandler(javax.security.auth.callback.CallbackHandler);
-  }
-
-  public abstract class BasicPermission extends java.security.Permission implements java.io.Serializable {
-    ctor public BasicPermission(String);
-    ctor public BasicPermission(String, String);
-    method public String getActions();
-    method public boolean implies(java.security.Permission);
-  }
-
-  @Deprecated public interface Certificate {
-    method @Deprecated public void decode(java.io.InputStream) throws java.io.IOException, java.security.KeyException;
-    method @Deprecated public void encode(java.io.OutputStream) throws java.io.IOException, java.security.KeyException;
-    method @Deprecated public String getFormat();
-    method @Deprecated public java.security.Principal getGuarantor();
-    method @Deprecated public java.security.Principal getPrincipal();
-    method @Deprecated public java.security.PublicKey getPublicKey();
-    method @Deprecated public String toString(boolean);
-  }
-
-  public final class CodeSigner implements java.io.Serializable {
-    ctor public CodeSigner(java.security.cert.CertPath, java.security.Timestamp);
-    method public java.security.cert.CertPath getSignerCertPath();
-    method public java.security.Timestamp getTimestamp();
-  }
-
-  public class CodeSource implements java.io.Serializable {
-    ctor public CodeSource(java.net.URL, java.security.cert.Certificate[]);
-    ctor public CodeSource(java.net.URL, java.security.CodeSigner[]);
-    method public final java.security.cert.Certificate[] getCertificates();
-    method public final java.security.CodeSigner[] getCodeSigners();
-    method public final java.net.URL getLocation();
-    method public boolean implies(java.security.CodeSource);
-  }
-
-  public enum CryptoPrimitive {
-    enum_constant public static final java.security.CryptoPrimitive BLOCK_CIPHER;
-    enum_constant public static final java.security.CryptoPrimitive KEY_AGREEMENT;
-    enum_constant public static final java.security.CryptoPrimitive KEY_ENCAPSULATION;
-    enum_constant public static final java.security.CryptoPrimitive KEY_WRAP;
-    enum_constant public static final java.security.CryptoPrimitive MAC;
-    enum_constant public static final java.security.CryptoPrimitive MESSAGE_DIGEST;
-    enum_constant public static final java.security.CryptoPrimitive PUBLIC_KEY_ENCRYPTION;
-    enum_constant public static final java.security.CryptoPrimitive SECURE_RANDOM;
-    enum_constant public static final java.security.CryptoPrimitive SIGNATURE;
-    enum_constant public static final java.security.CryptoPrimitive STREAM_CIPHER;
-  }
-
-  public class DigestException extends java.security.GeneralSecurityException {
-    ctor public DigestException();
-    ctor public DigestException(String);
-    ctor public DigestException(String, Throwable);
-    ctor public DigestException(Throwable);
-  }
-
-  public class DigestInputStream extends java.io.FilterInputStream {
-    ctor public DigestInputStream(java.io.InputStream, java.security.MessageDigest);
-    method public java.security.MessageDigest getMessageDigest();
-    method public void on(boolean);
-    method public void setMessageDigest(java.security.MessageDigest);
-    field protected java.security.MessageDigest digest;
-  }
-
-  public class DigestOutputStream extends java.io.FilterOutputStream {
-    ctor public DigestOutputStream(java.io.OutputStream, java.security.MessageDigest);
-    method public java.security.MessageDigest getMessageDigest();
-    method public void on(boolean);
-    method public void setMessageDigest(java.security.MessageDigest);
-    field protected java.security.MessageDigest digest;
-  }
-
-  public interface DomainCombiner {
-    method public java.security.ProtectionDomain[] combine(java.security.ProtectionDomain[], java.security.ProtectionDomain[]);
-  }
-
-  public final class DomainLoadStoreParameter implements java.security.KeyStore.LoadStoreParameter {
-    ctor public DomainLoadStoreParameter(java.net.URI, java.util.Map<java.lang.String,java.security.KeyStore.ProtectionParameter>);
-    method public java.net.URI getConfiguration();
-    method public java.security.KeyStore.ProtectionParameter getProtectionParameter();
-    method public java.util.Map<java.lang.String,java.security.KeyStore.ProtectionParameter> getProtectionParams();
-  }
-
-  public class GeneralSecurityException extends java.lang.Exception {
-    ctor public GeneralSecurityException();
-    ctor public GeneralSecurityException(String);
-    ctor public GeneralSecurityException(String, Throwable);
-    ctor public GeneralSecurityException(Throwable);
-  }
-
-  public interface Guard {
-    method public void checkGuard(Object) throws java.lang.SecurityException;
-  }
-
-  public class GuardedObject implements java.io.Serializable {
-    ctor public GuardedObject(Object, java.security.Guard);
-    method public Object getObject() throws java.lang.SecurityException;
-  }
-
-  @Deprecated public abstract class Identity implements java.security.Principal java.io.Serializable {
-    ctor @Deprecated protected Identity();
-    ctor @Deprecated public Identity(String, java.security.IdentityScope) throws java.security.KeyManagementException;
-    ctor @Deprecated public Identity(String);
-    method @Deprecated public void addCertificate(java.security.Certificate) throws java.security.KeyManagementException;
-    method @Deprecated public java.security.Certificate[] certificates();
-    method @Deprecated public final boolean equals(Object);
-    method @Deprecated public String getInfo();
-    method @Deprecated public final String getName();
-    method @Deprecated public java.security.PublicKey getPublicKey();
-    method @Deprecated public final java.security.IdentityScope getScope();
-    method @Deprecated protected boolean identityEquals(java.security.Identity);
-    method @Deprecated public void removeCertificate(java.security.Certificate) throws java.security.KeyManagementException;
-    method @Deprecated public void setInfo(String);
-    method @Deprecated public void setPublicKey(java.security.PublicKey) throws java.security.KeyManagementException;
-    method @Deprecated public String toString(boolean);
-  }
-
-  @Deprecated public abstract class IdentityScope extends java.security.Identity {
-    ctor @Deprecated protected IdentityScope();
-    ctor @Deprecated public IdentityScope(String);
-    ctor @Deprecated public IdentityScope(String, java.security.IdentityScope) throws java.security.KeyManagementException;
-    method @Deprecated public abstract void addIdentity(java.security.Identity) throws java.security.KeyManagementException;
-    method @Deprecated public abstract java.security.Identity getIdentity(String);
-    method @Deprecated public java.security.Identity getIdentity(java.security.Principal);
-    method @Deprecated public abstract java.security.Identity getIdentity(java.security.PublicKey);
-    method @Deprecated public static java.security.IdentityScope getSystemScope();
-    method @Deprecated public abstract java.util.Enumeration<java.security.Identity> identities();
-    method @Deprecated public abstract void removeIdentity(java.security.Identity) throws java.security.KeyManagementException;
-    method @Deprecated protected static void setSystemScope(java.security.IdentityScope);
-    method @Deprecated public abstract int size();
-  }
-
-  public class InvalidAlgorithmParameterException extends java.security.GeneralSecurityException {
-    ctor public InvalidAlgorithmParameterException();
-    ctor public InvalidAlgorithmParameterException(String);
-    ctor public InvalidAlgorithmParameterException(String, Throwable);
-    ctor public InvalidAlgorithmParameterException(Throwable);
-  }
-
-  public class InvalidKeyException extends java.security.KeyException {
-    ctor public InvalidKeyException();
-    ctor public InvalidKeyException(String);
-    ctor public InvalidKeyException(String, Throwable);
-    ctor public InvalidKeyException(Throwable);
-  }
-
-  public class InvalidParameterException extends java.lang.IllegalArgumentException {
-    ctor public InvalidParameterException();
-    ctor public InvalidParameterException(String);
-  }
-
-  public interface Key extends java.io.Serializable {
-    method public String getAlgorithm();
-    method public byte[] getEncoded();
-    method public String getFormat();
-    field public static final long serialVersionUID = 6603384152749567654L; // 0x5ba3eee69414eea6L
-  }
-
-  public class KeyException extends java.security.GeneralSecurityException {
-    ctor public KeyException();
-    ctor public KeyException(String);
-    ctor public KeyException(String, Throwable);
-    ctor public KeyException(Throwable);
-  }
-
-  public class KeyFactory {
-    ctor protected KeyFactory(java.security.KeyFactorySpi, java.security.Provider, String);
-    method public final java.security.PrivateKey generatePrivate(java.security.spec.KeySpec) throws java.security.spec.InvalidKeySpecException;
-    method public final java.security.PublicKey generatePublic(java.security.spec.KeySpec) throws java.security.spec.InvalidKeySpecException;
-    method public final String getAlgorithm();
-    method public static java.security.KeyFactory getInstance(String) throws java.security.NoSuchAlgorithmException;
-    method public static java.security.KeyFactory getInstance(String, String) throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException;
-    method public static java.security.KeyFactory getInstance(String, java.security.Provider) throws java.security.NoSuchAlgorithmException;
-    method public final <T extends java.security.spec.KeySpec> T getKeySpec(java.security.Key, Class<T>) throws java.security.spec.InvalidKeySpecException;
-    method public final java.security.Provider getProvider();
-    method public final java.security.Key translateKey(java.security.Key) throws java.security.InvalidKeyException;
-  }
-
-  public abstract class KeyFactorySpi {
-    ctor public KeyFactorySpi();
-    method protected abstract java.security.PrivateKey engineGeneratePrivate(java.security.spec.KeySpec) throws java.security.spec.InvalidKeySpecException;
-    method protected abstract java.security.PublicKey engineGeneratePublic(java.security.spec.KeySpec) throws java.security.spec.InvalidKeySpecException;
-    method protected abstract <T extends java.security.spec.KeySpec> T engineGetKeySpec(java.security.Key, Class<T>) throws java.security.spec.InvalidKeySpecException;
-    method protected abstract java.security.Key engineTranslateKey(java.security.Key) throws java.security.InvalidKeyException;
-  }
-
-  public class KeyManagementException extends java.security.KeyException {
-    ctor public KeyManagementException();
-    ctor public KeyManagementException(String);
-    ctor public KeyManagementException(String, Throwable);
-    ctor public KeyManagementException(Throwable);
-  }
-
-  public final class KeyPair implements java.io.Serializable {
-    ctor public KeyPair(java.security.PublicKey, java.security.PrivateKey);
-    method public java.security.PrivateKey getPrivate();
-    method public java.security.PublicKey getPublic();
-  }
-
-  public abstract class KeyPairGenerator extends java.security.KeyPairGeneratorSpi {
-    ctor protected KeyPairGenerator(String);
-    method public final java.security.KeyPair genKeyPair();
-    method public java.security.KeyPair generateKeyPair();
-    method public String getAlgorithm();
-    method public static java.security.KeyPairGenerator getInstance(String) throws java.security.NoSuchAlgorithmException;
-    method public static java.security.KeyPairGenerator getInstance(String, String) throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException;
-    method public static java.security.KeyPairGenerator getInstance(String, java.security.Provider) throws java.security.NoSuchAlgorithmException;
-    method public final java.security.Provider getProvider();
-    method public void initialize(int);
-    method public void initialize(int, java.security.SecureRandom);
-    method public void initialize(java.security.spec.AlgorithmParameterSpec) throws java.security.InvalidAlgorithmParameterException;
-  }
-
-  public abstract class KeyPairGeneratorSpi {
-    ctor public KeyPairGeneratorSpi();
-    method public abstract java.security.KeyPair generateKeyPair();
-    method public abstract void initialize(int, java.security.SecureRandom);
-    method public void initialize(java.security.spec.AlgorithmParameterSpec, java.security.SecureRandom) throws java.security.InvalidAlgorithmParameterException;
-  }
-
-  public class KeyRep implements java.io.Serializable {
-    ctor public KeyRep(java.security.KeyRep.Type, String, String, byte[]);
-    method protected Object readResolve() throws java.io.ObjectStreamException;
-  }
-
-  public enum KeyRep.Type {
-    enum_constant public static final java.security.KeyRep.Type PRIVATE;
-    enum_constant public static final java.security.KeyRep.Type PUBLIC;
-    enum_constant public static final java.security.KeyRep.Type SECRET;
-  }
-
-  public class KeyStore {
-    ctor protected KeyStore(java.security.KeyStoreSpi, java.security.Provider, String);
-    method public final java.util.Enumeration<java.lang.String> aliases() throws java.security.KeyStoreException;
-    method public final boolean containsAlias(String) throws java.security.KeyStoreException;
-    method public final void deleteEntry(String) throws java.security.KeyStoreException;
-    method public final boolean entryInstanceOf(String, Class<? extends java.security.KeyStore.Entry>) throws java.security.KeyStoreException;
-    method public final java.security.cert.Certificate getCertificate(String) throws java.security.KeyStoreException;
-    method public final String getCertificateAlias(java.security.cert.Certificate) throws java.security.KeyStoreException;
-    method public final java.security.cert.Certificate[] getCertificateChain(String) throws java.security.KeyStoreException;
-    method public final java.util.Date getCreationDate(String) throws java.security.KeyStoreException;
-    method public static final String getDefaultType();
-    method public final java.security.KeyStore.Entry getEntry(String, java.security.KeyStore.ProtectionParameter) throws java.security.KeyStoreException, java.security.NoSuchAlgorithmException, java.security.UnrecoverableEntryException;
-    method public static java.security.KeyStore getInstance(String) throws java.security.KeyStoreException;
-    method public static java.security.KeyStore getInstance(String, String) throws java.security.KeyStoreException, java.security.NoSuchProviderException;
-    method public static java.security.KeyStore getInstance(String, java.security.Provider) throws java.security.KeyStoreException;
-    method public final java.security.Key getKey(String, char[]) throws java.security.KeyStoreException, java.security.NoSuchAlgorithmException, java.security.UnrecoverableKeyException;
-    method public final java.security.Provider getProvider();
-    method public final String getType();
-    method public final boolean isCertificateEntry(String) throws java.security.KeyStoreException;
-    method public final boolean isKeyEntry(String) throws java.security.KeyStoreException;
-    method public final void load(java.io.InputStream, char[]) throws java.security.cert.CertificateException, java.io.IOException, java.security.NoSuchAlgorithmException;
-    method public final void load(java.security.KeyStore.LoadStoreParameter) throws java.security.cert.CertificateException, java.io.IOException, java.security.NoSuchAlgorithmException;
-    method public final void setCertificateEntry(String, java.security.cert.Certificate) throws java.security.KeyStoreException;
-    method public final void setEntry(String, java.security.KeyStore.Entry, java.security.KeyStore.ProtectionParameter) throws java.security.KeyStoreException;
-    method public final void setKeyEntry(String, java.security.Key, char[], java.security.cert.Certificate[]) throws java.security.KeyStoreException;
-    method public final void setKeyEntry(String, byte[], java.security.cert.Certificate[]) throws java.security.KeyStoreException;
-    method public final int size() throws java.security.KeyStoreException;
-    method public final void store(java.io.OutputStream, char[]) throws java.security.cert.CertificateException, java.io.IOException, java.security.KeyStoreException, java.security.NoSuchAlgorithmException;
-    method public final void store(java.security.KeyStore.LoadStoreParameter) throws java.security.cert.CertificateException, java.io.IOException, java.security.KeyStoreException, java.security.NoSuchAlgorithmException;
-  }
-
-  public abstract static class KeyStore.Builder {
-    ctor protected KeyStore.Builder();
-    method public abstract java.security.KeyStore getKeyStore() throws java.security.KeyStoreException;
-    method public abstract java.security.KeyStore.ProtectionParameter getProtectionParameter(String) throws java.security.KeyStoreException;
-    method public static java.security.KeyStore.Builder newInstance(java.security.KeyStore, java.security.KeyStore.ProtectionParameter);
-    method public static java.security.KeyStore.Builder newInstance(String, java.security.Provider, java.io.File, java.security.KeyStore.ProtectionParameter);
-    method public static java.security.KeyStore.Builder newInstance(String, java.security.Provider, java.security.KeyStore.ProtectionParameter);
-  }
-
-  public static class KeyStore.CallbackHandlerProtection implements java.security.KeyStore.ProtectionParameter {
-    ctor public KeyStore.CallbackHandlerProtection(javax.security.auth.callback.CallbackHandler);
-    method public javax.security.auth.callback.CallbackHandler getCallbackHandler();
-  }
-
-  public static interface KeyStore.Entry {
-    method public default java.util.Set<java.security.KeyStore.Entry.Attribute> getAttributes();
-  }
-
-  public static interface KeyStore.Entry.Attribute {
-    method public String getName();
-    method public String getValue();
-  }
-
-  public static interface KeyStore.LoadStoreParameter {
-    method public java.security.KeyStore.ProtectionParameter getProtectionParameter();
-  }
-
-  public static class KeyStore.PasswordProtection implements javax.security.auth.Destroyable java.security.KeyStore.ProtectionParameter {
-    ctor public KeyStore.PasswordProtection(char[]);
-    ctor public KeyStore.PasswordProtection(char[], String, java.security.spec.AlgorithmParameterSpec);
-    method public char[] getPassword();
-    method public String getProtectionAlgorithm();
-    method public java.security.spec.AlgorithmParameterSpec getProtectionParameters();
-  }
-
-  public static final class KeyStore.PrivateKeyEntry implements java.security.KeyStore.Entry {
-    ctor public KeyStore.PrivateKeyEntry(java.security.PrivateKey, java.security.cert.Certificate[]);
-    ctor public KeyStore.PrivateKeyEntry(java.security.PrivateKey, java.security.cert.Certificate[], java.util.Set<java.security.KeyStore.Entry.Attribute>);
-    method public java.security.cert.Certificate getCertificate();
-    method public java.security.cert.Certificate[] getCertificateChain();
-    method public java.security.PrivateKey getPrivateKey();
-  }
-
-  public static interface KeyStore.ProtectionParameter {
-  }
-
-  public static final class KeyStore.SecretKeyEntry implements java.security.KeyStore.Entry {
-    ctor public KeyStore.SecretKeyEntry(javax.crypto.SecretKey);
-    ctor public KeyStore.SecretKeyEntry(javax.crypto.SecretKey, java.util.Set<java.security.KeyStore.Entry.Attribute>);
-    method public javax.crypto.SecretKey getSecretKey();
-  }
-
-  public static final class KeyStore.TrustedCertificateEntry implements java.security.KeyStore.Entry {
-    ctor public KeyStore.TrustedCertificateEntry(java.security.cert.Certificate);
-    ctor public KeyStore.TrustedCertificateEntry(java.security.cert.Certificate, java.util.Set<java.security.KeyStore.Entry.Attribute>);
-    method public java.security.cert.Certificate getTrustedCertificate();
-  }
-
-  public class KeyStoreException extends java.security.GeneralSecurityException {
-    ctor public KeyStoreException();
-    ctor public KeyStoreException(String);
-    ctor public KeyStoreException(String, Throwable);
-    ctor public KeyStoreException(Throwable);
-  }
-
-  public abstract class KeyStoreSpi {
-    ctor public KeyStoreSpi();
-    method public abstract java.util.Enumeration<java.lang.String> engineAliases();
-    method public abstract boolean engineContainsAlias(String);
-    method public abstract void engineDeleteEntry(String) throws java.security.KeyStoreException;
-    method public boolean engineEntryInstanceOf(String, Class<? extends java.security.KeyStore.Entry>);
-    method public abstract java.security.cert.Certificate engineGetCertificate(String);
-    method public abstract String engineGetCertificateAlias(java.security.cert.Certificate);
-    method public abstract java.security.cert.Certificate[] engineGetCertificateChain(String);
-    method public abstract java.util.Date engineGetCreationDate(String);
-    method public java.security.KeyStore.Entry engineGetEntry(String, java.security.KeyStore.ProtectionParameter) throws java.security.KeyStoreException, java.security.NoSuchAlgorithmException, java.security.UnrecoverableEntryException;
-    method public abstract java.security.Key engineGetKey(String, char[]) throws java.security.NoSuchAlgorithmException, java.security.UnrecoverableKeyException;
-    method public abstract boolean engineIsCertificateEntry(String);
-    method public abstract boolean engineIsKeyEntry(String);
-    method public abstract void engineLoad(java.io.InputStream, char[]) throws java.security.cert.CertificateException, java.io.IOException, java.security.NoSuchAlgorithmException;
-    method public void engineLoad(java.security.KeyStore.LoadStoreParameter) throws java.security.cert.CertificateException, java.io.IOException, java.security.NoSuchAlgorithmException;
-    method public abstract void engineSetCertificateEntry(String, java.security.cert.Certificate) throws java.security.KeyStoreException;
-    method public void engineSetEntry(String, java.security.KeyStore.Entry, java.security.KeyStore.ProtectionParameter) throws java.security.KeyStoreException;
-    method public abstract void engineSetKeyEntry(String, java.security.Key, char[], java.security.cert.Certificate[]) throws java.security.KeyStoreException;
-    method public abstract void engineSetKeyEntry(String, byte[], java.security.cert.Certificate[]) throws java.security.KeyStoreException;
-    method public abstract int engineSize();
-    method public abstract void engineStore(java.io.OutputStream, char[]) throws java.security.cert.CertificateException, java.io.IOException, java.security.NoSuchAlgorithmException;
-    method public void engineStore(java.security.KeyStore.LoadStoreParameter) throws java.security.cert.CertificateException, java.io.IOException, java.security.NoSuchAlgorithmException;
-  }
-
-  public abstract class MessageDigest extends java.security.MessageDigestSpi {
-    ctor protected MessageDigest(@NonNull String);
-    method @NonNull public byte[] digest();
-    method public int digest(@NonNull byte[], int, int) throws java.security.DigestException;
-    method @NonNull public byte[] digest(@NonNull byte[]);
-    method @NonNull public final String getAlgorithm();
-    method public final int getDigestLength();
-    method @NonNull public static java.security.MessageDigest getInstance(@NonNull String) throws java.security.NoSuchAlgorithmException;
-    method @NonNull public static java.security.MessageDigest getInstance(@NonNull String, @NonNull String) throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException;
-    method @NonNull public static java.security.MessageDigest getInstance(@NonNull String, @NonNull java.security.Provider) throws java.security.NoSuchAlgorithmException;
-    method @NonNull public final java.security.Provider getProvider();
-    method public static boolean isEqual(@Nullable byte[], @Nullable byte[]);
-    method public void reset();
-    method public void update(byte);
-    method public void update(@NonNull byte[], int, int);
-    method public void update(@NonNull byte[]);
-    method public final void update(@NonNull java.nio.ByteBuffer);
-  }
-
-  public abstract class MessageDigestSpi {
-    ctor public MessageDigestSpi();
-    method public Object clone() throws java.lang.CloneNotSupportedException;
-    method protected abstract byte[] engineDigest();
-    method protected int engineDigest(byte[], int, int) throws java.security.DigestException;
-    method protected int engineGetDigestLength();
-    method protected abstract void engineReset();
-    method protected abstract void engineUpdate(byte);
-    method protected abstract void engineUpdate(byte[], int, int);
-    method protected void engineUpdate(java.nio.ByteBuffer);
-  }
-
-  public class NoSuchAlgorithmException extends java.security.GeneralSecurityException {
-    ctor public NoSuchAlgorithmException();
-    ctor public NoSuchAlgorithmException(String);
-    ctor public NoSuchAlgorithmException(String, Throwable);
-    ctor public NoSuchAlgorithmException(Throwable);
-  }
-
-  public class NoSuchProviderException extends java.security.GeneralSecurityException {
-    ctor public NoSuchProviderException();
-    ctor public NoSuchProviderException(String);
-  }
-
-  public final class PKCS12Attribute implements java.security.KeyStore.Entry.Attribute {
-    ctor public PKCS12Attribute(String, String);
-    ctor public PKCS12Attribute(byte[]);
-    method public byte[] getEncoded();
-    method public String getName();
-    method public String getValue();
-  }
-
-  public abstract class Permission implements java.security.Guard java.io.Serializable {
-    ctor public Permission(String);
-    method public void checkGuard(Object) throws java.lang.SecurityException;
-    method public abstract String getActions();
-    method public final String getName();
-    method public abstract boolean implies(java.security.Permission);
-    method public java.security.PermissionCollection newPermissionCollection();
-  }
-
-  public abstract class PermissionCollection implements java.io.Serializable {
-    ctor public PermissionCollection();
-    method public abstract void add(java.security.Permission);
-    method public abstract java.util.Enumeration<java.security.Permission> elements();
-    method public abstract boolean implies(java.security.Permission);
-    method public boolean isReadOnly();
-    method public void setReadOnly();
-  }
-
-  public final class Permissions extends java.security.PermissionCollection implements java.io.Serializable {
-    ctor public Permissions();
-    method public void add(java.security.Permission);
-    method public java.util.Enumeration<java.security.Permission> elements();
-    method public boolean implies(java.security.Permission);
-  }
-
-  public abstract class Policy {
-    ctor public Policy();
-    method public static java.security.Policy getInstance(String, java.security.Policy.Parameters) throws java.security.NoSuchAlgorithmException;
-    method public static java.security.Policy getInstance(String, java.security.Policy.Parameters, String) throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException;
-    method public static java.security.Policy getInstance(String, java.security.Policy.Parameters, java.security.Provider) throws java.security.NoSuchAlgorithmException;
-    method public java.security.Policy.Parameters getParameters();
-    method public java.security.PermissionCollection getPermissions(java.security.CodeSource);
-    method public java.security.PermissionCollection getPermissions(java.security.ProtectionDomain);
-    method public static java.security.Policy getPolicy();
-    method public java.security.Provider getProvider();
-    method public String getType();
-    method public boolean implies(java.security.ProtectionDomain, java.security.Permission);
-    method public void refresh();
-    method public static void setPolicy(java.security.Policy);
-    field public static final java.security.PermissionCollection UNSUPPORTED_EMPTY_COLLECTION;
-  }
-
-  public static interface Policy.Parameters {
-  }
-
-  public abstract class PolicySpi {
-    ctor public PolicySpi();
-    method protected java.security.PermissionCollection engineGetPermissions(java.security.CodeSource);
-    method protected java.security.PermissionCollection engineGetPermissions(java.security.ProtectionDomain);
-    method protected abstract boolean engineImplies(java.security.ProtectionDomain, java.security.Permission);
-    method protected void engineRefresh();
-  }
-
-  public interface Principal {
-    method public boolean equals(Object);
-    method public String getName();
-    method public int hashCode();
-    method public default boolean implies(javax.security.auth.Subject);
-    method public String toString();
-  }
-
-  public interface PrivateKey extends java.security.Key javax.security.auth.Destroyable {
-    field public static final long serialVersionUID = 6034044314589513430L; // 0x53bd3b559a12c6d6L
-  }
-
-  public interface PrivilegedAction<T> {
-    method public T run();
-  }
-
-  public class PrivilegedActionException extends java.lang.Exception {
-    ctor public PrivilegedActionException(Exception);
-    method public Exception getException();
-  }
-
-  public interface PrivilegedExceptionAction<T> {
-    method public T run() throws java.lang.Exception;
-  }
-
-  public class ProtectionDomain {
-    ctor public ProtectionDomain(java.security.CodeSource, java.security.PermissionCollection);
-    ctor public ProtectionDomain(java.security.CodeSource, java.security.PermissionCollection, ClassLoader, java.security.Principal[]);
-    method public final ClassLoader getClassLoader();
-    method public final java.security.CodeSource getCodeSource();
-    method public final java.security.PermissionCollection getPermissions();
-    method public final java.security.Principal[] getPrincipals();
-    method public boolean implies(java.security.Permission);
-  }
-
-  public abstract class Provider extends java.util.Properties {
-    ctor protected Provider(String, double, String);
-    method public Object compute(Object, java.util.function.BiFunction<? super java.lang.Object,? super java.lang.Object,?>);
-    method public Object computeIfAbsent(Object, java.util.function.Function<? super java.lang.Object,?>);
-    method public Object computeIfPresent(Object, java.util.function.BiFunction<? super java.lang.Object,? super java.lang.Object,?>);
-    method public java.util.Enumeration<java.lang.Object> elements();
-    method public java.util.Set<java.util.Map.Entry<java.lang.Object,java.lang.Object>> entrySet();
-    method public void forEach(java.util.function.BiConsumer<? super java.lang.Object,? super java.lang.Object>);
-    method public Object get(Object);
-    method public String getInfo();
-    method public String getName();
-    method public Object getOrDefault(Object, Object);
-    method public java.security.Provider.Service getService(String, String);
-    method public java.util.Set<java.security.Provider.Service> getServices();
-    method public double getVersion();
-    method public java.util.Set<java.lang.Object> keySet();
-    method public java.util.Enumeration<java.lang.Object> keys();
-    method public Object merge(Object, Object, java.util.function.BiFunction<? super java.lang.Object,? super java.lang.Object,?>);
-    method public Object put(Object, Object);
-    method public void putAll(java.util.Map<?,?>);
-    method public Object putIfAbsent(Object, Object);
-    method protected void putService(java.security.Provider.Service);
-    method public Object remove(Object);
-    method protected void removeService(java.security.Provider.Service);
-    method public boolean replace(Object, Object, Object);
-    method public Object replace(Object, Object);
-    method public void replaceAll(java.util.function.BiFunction<? super java.lang.Object,? super java.lang.Object,?>);
-    method public java.util.Collection<java.lang.Object> values();
-  }
-
-  public static class Provider.Service {
-    ctor public Provider.Service(java.security.Provider, String, String, String, java.util.List<java.lang.String>, java.util.Map<java.lang.String,java.lang.String>);
-    method public final String getAlgorithm();
-    method public final String getAttribute(String);
-    method public final String getClassName();
-    method public final java.security.Provider getProvider();
-    method public final String getType();
-    method public Object newInstance(Object) throws java.security.NoSuchAlgorithmException;
-    method public boolean supportsParameter(Object);
-  }
-
-  public class ProviderException extends java.lang.RuntimeException {
-    ctor public ProviderException();
-    ctor public ProviderException(String);
-    ctor public ProviderException(String, Throwable);
-    ctor public ProviderException(Throwable);
-  }
-
-  public interface PublicKey extends java.security.Key {
-    field public static final long serialVersionUID = 7187392471159151072L; // 0x63bebf5f40c219e0L
-  }
-
-  public class SecureClassLoader extends java.lang.ClassLoader {
-    ctor protected SecureClassLoader(ClassLoader);
-    ctor protected SecureClassLoader();
-    method protected final Class<?> defineClass(String, byte[], int, int, java.security.CodeSource);
-    method protected final Class<?> defineClass(String, java.nio.ByteBuffer, java.security.CodeSource);
-    method protected java.security.PermissionCollection getPermissions(java.security.CodeSource);
-  }
-
-  public class SecureRandom extends java.util.Random {
-    ctor public SecureRandom();
-    ctor public SecureRandom(byte[]);
-    ctor protected SecureRandom(java.security.SecureRandomSpi, java.security.Provider);
-    method public byte[] generateSeed(int);
-    method public String getAlgorithm();
-    method public static java.security.SecureRandom getInstance(String) throws java.security.NoSuchAlgorithmException;
-    method public static java.security.SecureRandom getInstance(String, String) throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException;
-    method public static java.security.SecureRandom getInstance(String, java.security.Provider) throws java.security.NoSuchAlgorithmException;
-    method public static java.security.SecureRandom getInstanceStrong() throws java.security.NoSuchAlgorithmException;
-    method public final java.security.Provider getProvider();
-    method public static byte[] getSeed(int);
-    method protected final int next(int);
-    method public void setSeed(byte[]);
-  }
-
-  public abstract class SecureRandomSpi implements java.io.Serializable {
-    ctor public SecureRandomSpi();
-    method protected abstract byte[] engineGenerateSeed(int);
-    method protected abstract void engineNextBytes(byte[]);
-    method protected abstract void engineSetSeed(byte[]);
-  }
-
-  public final class Security {
-    method public static int addProvider(java.security.Provider);
-    method @Deprecated public static String getAlgorithmProperty(String, String);
-    method public static java.util.Set<java.lang.String> getAlgorithms(String);
-    method public static String getProperty(String);
-    method public static java.security.Provider getProvider(String);
-    method public static java.security.Provider[] getProviders();
-    method public static java.security.Provider[] getProviders(String);
-    method public static java.security.Provider[] getProviders(java.util.Map<java.lang.String,java.lang.String>);
-    method public static int insertProviderAt(java.security.Provider, int);
-    method public static void removeProvider(String);
-    method public static void setProperty(String, String);
-  }
-
-  public final class SecurityPermission extends java.security.BasicPermission {
-    ctor public SecurityPermission(String);
-    ctor public SecurityPermission(String, String);
-  }
-
-  public abstract class Signature extends java.security.SignatureSpi {
-    ctor protected Signature(String);
-    method public final String getAlgorithm();
-    method public static java.security.Signature getInstance(String) throws java.security.NoSuchAlgorithmException;
-    method public static java.security.Signature getInstance(String, String) throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException;
-    method public static java.security.Signature getInstance(String, java.security.Provider) throws java.security.NoSuchAlgorithmException;
-    method @Deprecated public final Object getParameter(String) throws java.security.InvalidParameterException;
-    method public final java.security.AlgorithmParameters getParameters();
-    method public final java.security.Provider getProvider();
-    method public final void initSign(java.security.PrivateKey) throws java.security.InvalidKeyException;
-    method public final void initSign(java.security.PrivateKey, java.security.SecureRandom) throws java.security.InvalidKeyException;
-    method public final void initVerify(java.security.PublicKey) throws java.security.InvalidKeyException;
-    method public final void initVerify(java.security.cert.Certificate) throws java.security.InvalidKeyException;
-    method @Deprecated public final void setParameter(String, Object) throws java.security.InvalidParameterException;
-    method public final void setParameter(java.security.spec.AlgorithmParameterSpec) throws java.security.InvalidAlgorithmParameterException;
-    method public final byte[] sign() throws java.security.SignatureException;
-    method public final int sign(byte[], int, int) throws java.security.SignatureException;
-    method public final void update(byte) throws java.security.SignatureException;
-    method public final void update(byte[]) throws java.security.SignatureException;
-    method public final void update(byte[], int, int) throws java.security.SignatureException;
-    method public final void update(java.nio.ByteBuffer) throws java.security.SignatureException;
-    method public final boolean verify(byte[]) throws java.security.SignatureException;
-    method public final boolean verify(byte[], int, int) throws java.security.SignatureException;
-    field protected static final int SIGN = 2; // 0x2
-    field protected static final int UNINITIALIZED = 0; // 0x0
-    field protected static final int VERIFY = 3; // 0x3
-    field protected int state;
-  }
-
-  public class SignatureException extends java.security.GeneralSecurityException {
-    ctor public SignatureException();
-    ctor public SignatureException(String);
-    ctor public SignatureException(String, Throwable);
-    ctor public SignatureException(Throwable);
-  }
-
-  public abstract class SignatureSpi {
-    ctor public SignatureSpi();
-    method public Object clone() throws java.lang.CloneNotSupportedException;
-    method @Deprecated protected abstract Object engineGetParameter(String) throws java.security.InvalidParameterException;
-    method protected java.security.AlgorithmParameters engineGetParameters();
-    method protected abstract void engineInitSign(java.security.PrivateKey) throws java.security.InvalidKeyException;
-    method protected void engineInitSign(java.security.PrivateKey, java.security.SecureRandom) throws java.security.InvalidKeyException;
-    method protected abstract void engineInitVerify(java.security.PublicKey) throws java.security.InvalidKeyException;
-    method @Deprecated protected abstract void engineSetParameter(String, Object) throws java.security.InvalidParameterException;
-    method protected void engineSetParameter(java.security.spec.AlgorithmParameterSpec) throws java.security.InvalidAlgorithmParameterException;
-    method protected abstract byte[] engineSign() throws java.security.SignatureException;
-    method protected int engineSign(byte[], int, int) throws java.security.SignatureException;
-    method protected abstract void engineUpdate(byte) throws java.security.SignatureException;
-    method protected abstract void engineUpdate(byte[], int, int) throws java.security.SignatureException;
-    method protected void engineUpdate(java.nio.ByteBuffer);
-    method protected abstract boolean engineVerify(byte[]) throws java.security.SignatureException;
-    method protected boolean engineVerify(byte[], int, int) throws java.security.SignatureException;
-    field protected java.security.SecureRandom appRandom;
-  }
-
-  public final class SignedObject implements java.io.Serializable {
-    ctor public SignedObject(java.io.Serializable, java.security.PrivateKey, java.security.Signature) throws java.io.IOException, java.security.InvalidKeyException, java.security.SignatureException;
-    method public String getAlgorithm();
-    method public Object getObject() throws java.lang.ClassNotFoundException, java.io.IOException;
-    method public byte[] getSignature();
-    method public boolean verify(java.security.PublicKey, java.security.Signature) throws java.security.InvalidKeyException, java.security.SignatureException;
-  }
-
-  @Deprecated public abstract class Signer extends java.security.Identity {
-    ctor @Deprecated protected Signer();
-    ctor @Deprecated public Signer(String);
-    ctor @Deprecated public Signer(String, java.security.IdentityScope) throws java.security.KeyManagementException;
-    method @Deprecated public java.security.PrivateKey getPrivateKey();
-    method @Deprecated public final void setKeyPair(java.security.KeyPair) throws java.security.InvalidParameterException, java.security.KeyException;
-  }
-
-  public final class Timestamp implements java.io.Serializable {
-    ctor public Timestamp(java.util.Date, java.security.cert.CertPath);
-    method public java.security.cert.CertPath getSignerCertPath();
-    method public java.util.Date getTimestamp();
-  }
-
-  public class UnrecoverableEntryException extends java.security.GeneralSecurityException {
-    ctor public UnrecoverableEntryException();
-    ctor public UnrecoverableEntryException(String);
-  }
-
-  public class UnrecoverableKeyException extends java.security.UnrecoverableEntryException {
-    ctor public UnrecoverableKeyException();
-    ctor public UnrecoverableKeyException(String);
-  }
-
-  public final class UnresolvedPermission extends java.security.Permission implements java.io.Serializable {
-    ctor public UnresolvedPermission(String, String, String, java.security.cert.Certificate[]);
-    method public String getActions();
-    method public String getUnresolvedActions();
-    method public java.security.cert.Certificate[] getUnresolvedCerts();
-    method public String getUnresolvedName();
-    method public String getUnresolvedType();
-    method public boolean implies(java.security.Permission);
-  }
-
-}
-
-package java.security.acl {
-
-  public interface Acl extends java.security.acl.Owner {
-    method public boolean addEntry(java.security.Principal, java.security.acl.AclEntry) throws java.security.acl.NotOwnerException;
-    method public boolean checkPermission(java.security.Principal, java.security.acl.Permission);
-    method public java.util.Enumeration<java.security.acl.AclEntry> entries();
-    method public String getName();
-    method public java.util.Enumeration<java.security.acl.Permission> getPermissions(java.security.Principal);
-    method public boolean removeEntry(java.security.Principal, java.security.acl.AclEntry) throws java.security.acl.NotOwnerException;
-    method public void setName(java.security.Principal, String) throws java.security.acl.NotOwnerException;
-    method public String toString();
-  }
-
-  public interface AclEntry extends java.lang.Cloneable {
-    method public boolean addPermission(java.security.acl.Permission);
-    method public boolean checkPermission(java.security.acl.Permission);
-    method public Object clone();
-    method public java.security.Principal getPrincipal();
-    method public boolean isNegative();
-    method public java.util.Enumeration<java.security.acl.Permission> permissions();
-    method public boolean removePermission(java.security.acl.Permission);
-    method public void setNegativePermissions();
-    method public boolean setPrincipal(java.security.Principal);
-    method public String toString();
-  }
-
-  public class AclNotFoundException extends java.lang.Exception {
-    ctor public AclNotFoundException();
-  }
-
-  public interface Group extends java.security.Principal {
-    method public boolean addMember(java.security.Principal);
-    method public boolean isMember(java.security.Principal);
-    method public java.util.Enumeration<? extends java.security.Principal> members();
-    method public boolean removeMember(java.security.Principal);
-  }
-
-  public class LastOwnerException extends java.lang.Exception {
-    ctor public LastOwnerException();
-  }
-
-  public class NotOwnerException extends java.lang.Exception {
-    ctor public NotOwnerException();
-  }
-
-  public interface Owner {
-    method public boolean addOwner(java.security.Principal, java.security.Principal) throws java.security.acl.NotOwnerException;
-    method public boolean deleteOwner(java.security.Principal, java.security.Principal) throws java.security.acl.LastOwnerException, java.security.acl.NotOwnerException;
-    method public boolean isOwner(java.security.Principal);
-  }
-
-  public interface Permission {
-  }
-
-}
-
-package java.security.cert {
-
-  public abstract class CRL {
-    ctor protected CRL(String);
-    method public final String getType();
-    method public abstract boolean isRevoked(java.security.cert.Certificate);
-    method public abstract String toString();
-  }
-
-  public class CRLException extends java.security.GeneralSecurityException {
-    ctor public CRLException();
-    ctor public CRLException(String);
-    ctor public CRLException(String, Throwable);
-    ctor public CRLException(Throwable);
-  }
-
-  public enum CRLReason {
-    enum_constant public static final java.security.cert.CRLReason AA_COMPROMISE;
-    enum_constant public static final java.security.cert.CRLReason AFFILIATION_CHANGED;
-    enum_constant public static final java.security.cert.CRLReason CA_COMPROMISE;
-    enum_constant public static final java.security.cert.CRLReason CERTIFICATE_HOLD;
-    enum_constant public static final java.security.cert.CRLReason CESSATION_OF_OPERATION;
-    enum_constant public static final java.security.cert.CRLReason KEY_COMPROMISE;
-    enum_constant public static final java.security.cert.CRLReason PRIVILEGE_WITHDRAWN;
-    enum_constant public static final java.security.cert.CRLReason REMOVE_FROM_CRL;
-    enum_constant public static final java.security.cert.CRLReason SUPERSEDED;
-    enum_constant public static final java.security.cert.CRLReason UNSPECIFIED;
-    enum_constant public static final java.security.cert.CRLReason UNUSED;
-  }
-
-  public interface CRLSelector extends java.lang.Cloneable {
-    method public Object clone();
-    method public boolean match(java.security.cert.CRL);
-  }
-
-  public abstract class CertPath implements java.io.Serializable {
-    ctor protected CertPath(String);
-    method public abstract java.util.List<? extends java.security.cert.Certificate> getCertificates();
-    method public abstract byte[] getEncoded() throws java.security.cert.CertificateEncodingException;
-    method public abstract byte[] getEncoded(String) throws java.security.cert.CertificateEncodingException;
-    method public abstract java.util.Iterator<java.lang.String> getEncodings();
-    method public String getType();
-    method protected Object writeReplace() throws java.io.ObjectStreamException;
-  }
-
-  protected static class CertPath.CertPathRep implements java.io.Serializable {
-    ctor protected CertPath.CertPathRep(String, byte[]);
-    method protected Object readResolve() throws java.io.ObjectStreamException;
-  }
-
-  public class CertPathBuilder {
-    ctor protected CertPathBuilder(java.security.cert.CertPathBuilderSpi, java.security.Provider, String);
-    method public final java.security.cert.CertPathBuilderResult build(java.security.cert.CertPathParameters) throws java.security.cert.CertPathBuilderException, java.security.InvalidAlgorithmParameterException;
-    method public final String getAlgorithm();
-    method public static final String getDefaultType();
-    method public static java.security.cert.CertPathBuilder getInstance(String) throws java.security.NoSuchAlgorithmException;
-    method public static java.security.cert.CertPathBuilder getInstance(String, String) throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException;
-    method public static java.security.cert.CertPathBuilder getInstance(String, java.security.Provider) throws java.security.NoSuchAlgorithmException;
-    method public final java.security.Provider getProvider();
-    method public final java.security.cert.CertPathChecker getRevocationChecker();
-  }
-
-  public class CertPathBuilderException extends java.security.GeneralSecurityException {
-    ctor public CertPathBuilderException();
-    ctor public CertPathBuilderException(String);
-    ctor public CertPathBuilderException(Throwable);
-    ctor public CertPathBuilderException(String, Throwable);
-  }
-
-  public interface CertPathBuilderResult extends java.lang.Cloneable {
-    method public Object clone();
-    method public java.security.cert.CertPath getCertPath();
-  }
-
-  public abstract class CertPathBuilderSpi {
-    ctor public CertPathBuilderSpi();
-    method public abstract java.security.cert.CertPathBuilderResult engineBuild(java.security.cert.CertPathParameters) throws java.security.cert.CertPathBuilderException, java.security.InvalidAlgorithmParameterException;
-    method public java.security.cert.CertPathChecker engineGetRevocationChecker();
-  }
-
-  public interface CertPathChecker {
-    method public void check(java.security.cert.Certificate) throws java.security.cert.CertPathValidatorException;
-    method public void init(boolean) throws java.security.cert.CertPathValidatorException;
-    method public boolean isForwardCheckingSupported();
-  }
-
-  public interface CertPathParameters extends java.lang.Cloneable {
-    method public Object clone();
-  }
-
-  public class CertPathValidator {
-    ctor protected CertPathValidator(java.security.cert.CertPathValidatorSpi, java.security.Provider, String);
-    method public final String getAlgorithm();
-    method public static final String getDefaultType();
-    method public static java.security.cert.CertPathValidator getInstance(String) throws java.security.NoSuchAlgorithmException;
-    method public static java.security.cert.CertPathValidator getInstance(String, String) throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException;
-    method public static java.security.cert.CertPathValidator getInstance(String, java.security.Provider) throws java.security.NoSuchAlgorithmException;
-    method public final java.security.Provider getProvider();
-    method public final java.security.cert.CertPathChecker getRevocationChecker();
-    method public final java.security.cert.CertPathValidatorResult validate(java.security.cert.CertPath, java.security.cert.CertPathParameters) throws java.security.cert.CertPathValidatorException, java.security.InvalidAlgorithmParameterException;
-  }
-
-  public class CertPathValidatorException extends java.security.GeneralSecurityException {
-    ctor public CertPathValidatorException();
-    ctor public CertPathValidatorException(String);
-    ctor public CertPathValidatorException(Throwable);
-    ctor public CertPathValidatorException(String, Throwable);
-    ctor public CertPathValidatorException(String, Throwable, java.security.cert.CertPath, int);
-    ctor public CertPathValidatorException(String, Throwable, java.security.cert.CertPath, int, java.security.cert.CertPathValidatorException.Reason);
-    method public java.security.cert.CertPath getCertPath();
-    method public int getIndex();
-    method public java.security.cert.CertPathValidatorException.Reason getReason();
-  }
-
-  public enum CertPathValidatorException.BasicReason implements java.security.cert.CertPathValidatorException.Reason {
-    enum_constant public static final java.security.cert.CertPathValidatorException.BasicReason ALGORITHM_CONSTRAINED;
-    enum_constant public static final java.security.cert.CertPathValidatorException.BasicReason EXPIRED;
-    enum_constant public static final java.security.cert.CertPathValidatorException.BasicReason INVALID_SIGNATURE;
-    enum_constant public static final java.security.cert.CertPathValidatorException.BasicReason NOT_YET_VALID;
-    enum_constant public static final java.security.cert.CertPathValidatorException.BasicReason REVOKED;
-    enum_constant public static final java.security.cert.CertPathValidatorException.BasicReason UNDETERMINED_REVOCATION_STATUS;
-    enum_constant public static final java.security.cert.CertPathValidatorException.BasicReason UNSPECIFIED;
-  }
-
-  public static interface CertPathValidatorException.Reason extends java.io.Serializable {
-  }
-
-  public interface CertPathValidatorResult extends java.lang.Cloneable {
-    method public Object clone();
-  }
-
-  public abstract class CertPathValidatorSpi {
-    ctor public CertPathValidatorSpi();
-    method public java.security.cert.CertPathChecker engineGetRevocationChecker();
-    method public abstract java.security.cert.CertPathValidatorResult engineValidate(java.security.cert.CertPath, java.security.cert.CertPathParameters) throws java.security.cert.CertPathValidatorException, java.security.InvalidAlgorithmParameterException;
-  }
-
-  public interface CertSelector extends java.lang.Cloneable {
-    method public Object clone();
-    method public boolean match(java.security.cert.Certificate);
-  }
-
-  public class CertStore {
-    ctor protected CertStore(java.security.cert.CertStoreSpi, java.security.Provider, String, java.security.cert.CertStoreParameters);
-    method public final java.util.Collection<? extends java.security.cert.CRL> getCRLs(java.security.cert.CRLSelector) throws java.security.cert.CertStoreException;
-    method public final java.security.cert.CertStoreParameters getCertStoreParameters();
-    method public final java.util.Collection<? extends java.security.cert.Certificate> getCertificates(java.security.cert.CertSelector) throws java.security.cert.CertStoreException;
-    method public static final String getDefaultType();
-    method public static java.security.cert.CertStore getInstance(String, java.security.cert.CertStoreParameters) throws java.security.InvalidAlgorithmParameterException, java.security.NoSuchAlgorithmException;
-    method public static java.security.cert.CertStore getInstance(String, java.security.cert.CertStoreParameters, String) throws java.security.InvalidAlgorithmParameterException, java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException;
-    method public static java.security.cert.CertStore getInstance(String, java.security.cert.CertStoreParameters, java.security.Provider) throws java.security.InvalidAlgorithmParameterException, java.security.NoSuchAlgorithmException;
-    method public final java.security.Provider getProvider();
-    method public final String getType();
-  }
-
-  public class CertStoreException extends java.security.GeneralSecurityException {
-    ctor public CertStoreException();
-    ctor public CertStoreException(String);
-    ctor public CertStoreException(Throwable);
-    ctor public CertStoreException(String, Throwable);
-  }
-
-  public interface CertStoreParameters extends java.lang.Cloneable {
-    method public Object clone();
-  }
-
-  public abstract class CertStoreSpi {
-    ctor public CertStoreSpi(java.security.cert.CertStoreParameters) throws java.security.InvalidAlgorithmParameterException;
-    method public abstract java.util.Collection<? extends java.security.cert.CRL> engineGetCRLs(java.security.cert.CRLSelector) throws java.security.cert.CertStoreException;
-    method public abstract java.util.Collection<? extends java.security.cert.Certificate> engineGetCertificates(java.security.cert.CertSelector) throws java.security.cert.CertStoreException;
-  }
-
-  public abstract class Certificate implements java.io.Serializable {
-    ctor protected Certificate(String);
-    method public abstract byte[] getEncoded() throws java.security.cert.CertificateEncodingException;
-    method public abstract java.security.PublicKey getPublicKey();
-    method public final String getType();
-    method public abstract String toString();
-    method public abstract void verify(java.security.PublicKey) throws java.security.cert.CertificateException, java.security.InvalidKeyException, java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException, java.security.SignatureException;
-    method public abstract void verify(java.security.PublicKey, String) throws java.security.cert.CertificateException, java.security.InvalidKeyException, java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException, java.security.SignatureException;
-    method public void verify(java.security.PublicKey, java.security.Provider) throws java.security.cert.CertificateException, java.security.InvalidKeyException, java.security.NoSuchAlgorithmException, java.security.SignatureException;
-    method protected Object writeReplace() throws java.io.ObjectStreamException;
-  }
-
-  protected static class Certificate.CertificateRep implements java.io.Serializable {
-    ctor protected Certificate.CertificateRep(String, byte[]);
-    method protected Object readResolve() throws java.io.ObjectStreamException;
-  }
-
-  public class CertificateEncodingException extends java.security.cert.CertificateException {
-    ctor public CertificateEncodingException();
-    ctor public CertificateEncodingException(String);
-    ctor public CertificateEncodingException(String, Throwable);
-    ctor public CertificateEncodingException(Throwable);
-  }
-
-  public class CertificateException extends java.security.GeneralSecurityException {
-    ctor public CertificateException();
-    ctor public CertificateException(String);
-    ctor public CertificateException(String, Throwable);
-    ctor public CertificateException(Throwable);
-  }
-
-  public class CertificateExpiredException extends java.security.cert.CertificateException {
-    ctor public CertificateExpiredException();
-    ctor public CertificateExpiredException(String);
-  }
-
-  public class CertificateFactory {
-    ctor protected CertificateFactory(java.security.cert.CertificateFactorySpi, java.security.Provider, String);
-    method public final java.security.cert.CRL generateCRL(java.io.InputStream) throws java.security.cert.CRLException;
-    method public final java.util.Collection<? extends java.security.cert.CRL> generateCRLs(java.io.InputStream) throws java.security.cert.CRLException;
-    method public final java.security.cert.CertPath generateCertPath(java.io.InputStream) throws java.security.cert.CertificateException;
-    method public final java.security.cert.CertPath generateCertPath(java.io.InputStream, String) throws java.security.cert.CertificateException;
-    method public final java.security.cert.CertPath generateCertPath(java.util.List<? extends java.security.cert.Certificate>) throws java.security.cert.CertificateException;
-    method public final java.security.cert.Certificate generateCertificate(java.io.InputStream) throws java.security.cert.CertificateException;
-    method public final java.util.Collection<? extends java.security.cert.Certificate> generateCertificates(java.io.InputStream) throws java.security.cert.CertificateException;
-    method public final java.util.Iterator<java.lang.String> getCertPathEncodings();
-    method public static final java.security.cert.CertificateFactory getInstance(String) throws java.security.cert.CertificateException;
-    method public static final java.security.cert.CertificateFactory getInstance(String, String) throws java.security.cert.CertificateException, java.security.NoSuchProviderException;
-    method public static final java.security.cert.CertificateFactory getInstance(String, java.security.Provider) throws java.security.cert.CertificateException;
-    method public final java.security.Provider getProvider();
-    method public final String getType();
-  }
-
-  public abstract class CertificateFactorySpi {
-    ctor public CertificateFactorySpi();
-    method public abstract java.security.cert.CRL engineGenerateCRL(java.io.InputStream) throws java.security.cert.CRLException;
-    method public abstract java.util.Collection<? extends java.security.cert.CRL> engineGenerateCRLs(java.io.InputStream) throws java.security.cert.CRLException;
-    method public java.security.cert.CertPath engineGenerateCertPath(java.io.InputStream) throws java.security.cert.CertificateException;
-    method public java.security.cert.CertPath engineGenerateCertPath(java.io.InputStream, String) throws java.security.cert.CertificateException;
-    method public java.security.cert.CertPath engineGenerateCertPath(java.util.List<? extends java.security.cert.Certificate>) throws java.security.cert.CertificateException;
-    method public abstract java.security.cert.Certificate engineGenerateCertificate(java.io.InputStream) throws java.security.cert.CertificateException;
-    method public abstract java.util.Collection<? extends java.security.cert.Certificate> engineGenerateCertificates(java.io.InputStream) throws java.security.cert.CertificateException;
-    method public java.util.Iterator<java.lang.String> engineGetCertPathEncodings();
-  }
-
-  public class CertificateNotYetValidException extends java.security.cert.CertificateException {
-    ctor public CertificateNotYetValidException();
-    ctor public CertificateNotYetValidException(String);
-  }
-
-  public class CertificateParsingException extends java.security.cert.CertificateException {
-    ctor public CertificateParsingException();
-    ctor public CertificateParsingException(String);
-    ctor public CertificateParsingException(String, Throwable);
-    ctor public CertificateParsingException(Throwable);
-  }
-
-  public class CertificateRevokedException extends java.security.cert.CertificateException {
-    ctor public CertificateRevokedException(java.util.Date, java.security.cert.CRLReason, javax.security.auth.x500.X500Principal, java.util.Map<java.lang.String,java.security.cert.Extension>);
-    method public javax.security.auth.x500.X500Principal getAuthorityName();
-    method public java.util.Map<java.lang.String,java.security.cert.Extension> getExtensions();
-    method public java.util.Date getInvalidityDate();
-    method public java.util.Date getRevocationDate();
-    method public java.security.cert.CRLReason getRevocationReason();
-  }
-
-  public class CollectionCertStoreParameters implements java.security.cert.CertStoreParameters {
-    ctor public CollectionCertStoreParameters(java.util.Collection<?>);
-    ctor public CollectionCertStoreParameters();
-    method public Object clone();
-    method public java.util.Collection<?> getCollection();
-  }
-
-  public interface Extension {
-    method public void encode(java.io.OutputStream) throws java.io.IOException;
-    method public String getId();
-    method public byte[] getValue();
-    method public boolean isCritical();
-  }
-
-  public class LDAPCertStoreParameters implements java.security.cert.CertStoreParameters {
-    ctor public LDAPCertStoreParameters(String, int);
-    ctor public LDAPCertStoreParameters(String);
-    ctor public LDAPCertStoreParameters();
-    method public Object clone();
-    method public int getPort();
-    method public String getServerName();
-  }
-
-  public class PKIXBuilderParameters extends java.security.cert.PKIXParameters {
-    ctor public PKIXBuilderParameters(java.util.Set<java.security.cert.TrustAnchor>, java.security.cert.CertSelector) throws java.security.InvalidAlgorithmParameterException;
-    ctor public PKIXBuilderParameters(java.security.KeyStore, java.security.cert.CertSelector) throws java.security.InvalidAlgorithmParameterException, java.security.KeyStoreException;
-    method public int getMaxPathLength();
-    method public void setMaxPathLength(int);
-  }
-
-  public class PKIXCertPathBuilderResult extends java.security.cert.PKIXCertPathValidatorResult implements java.security.cert.CertPathBuilderResult {
-    ctor public PKIXCertPathBuilderResult(java.security.cert.CertPath, java.security.cert.TrustAnchor, java.security.cert.PolicyNode, java.security.PublicKey);
-    method public java.security.cert.CertPath getCertPath();
-  }
-
-  public abstract class PKIXCertPathChecker implements java.security.cert.CertPathChecker java.lang.Cloneable {
-    ctor protected PKIXCertPathChecker();
-    method public abstract void check(java.security.cert.Certificate, java.util.Collection<java.lang.String>) throws java.security.cert.CertPathValidatorException;
-    method public void check(java.security.cert.Certificate) throws java.security.cert.CertPathValidatorException;
-    method public Object clone();
-    method public abstract java.util.Set<java.lang.String> getSupportedExtensions();
-  }
-
-  public class PKIXCertPathValidatorResult implements java.security.cert.CertPathValidatorResult {
-    ctor public PKIXCertPathValidatorResult(java.security.cert.TrustAnchor, java.security.cert.PolicyNode, java.security.PublicKey);
-    method public Object clone();
-    method public java.security.cert.PolicyNode getPolicyTree();
-    method public java.security.PublicKey getPublicKey();
-    method public java.security.cert.TrustAnchor getTrustAnchor();
-  }
-
-  public class PKIXParameters implements java.security.cert.CertPathParameters {
-    ctor public PKIXParameters(java.util.Set<java.security.cert.TrustAnchor>) throws java.security.InvalidAlgorithmParameterException;
-    ctor public PKIXParameters(java.security.KeyStore) throws java.security.InvalidAlgorithmParameterException, java.security.KeyStoreException;
-    method public void addCertPathChecker(java.security.cert.PKIXCertPathChecker);
-    method public void addCertStore(java.security.cert.CertStore);
-    method public Object clone();
-    method public java.util.List<java.security.cert.PKIXCertPathChecker> getCertPathCheckers();
-    method public java.util.List<java.security.cert.CertStore> getCertStores();
-    method public java.util.Date getDate();
-    method public java.util.Set<java.lang.String> getInitialPolicies();
-    method public boolean getPolicyQualifiersRejected();
-    method public String getSigProvider();
-    method public java.security.cert.CertSelector getTargetCertConstraints();
-    method public java.util.Set<java.security.cert.TrustAnchor> getTrustAnchors();
-    method public boolean isAnyPolicyInhibited();
-    method public boolean isExplicitPolicyRequired();
-    method public boolean isPolicyMappingInhibited();
-    method public boolean isRevocationEnabled();
-    method public void setAnyPolicyInhibited(boolean);
-    method public void setCertPathCheckers(java.util.List<java.security.cert.PKIXCertPathChecker>);
-    method public void setCertStores(java.util.List<java.security.cert.CertStore>);
-    method public void setDate(java.util.Date);
-    method public void setExplicitPolicyRequired(boolean);
-    method public void setInitialPolicies(java.util.Set<java.lang.String>);
-    method public void setPolicyMappingInhibited(boolean);
-    method public void setPolicyQualifiersRejected(boolean);
-    method public void setRevocationEnabled(boolean);
-    method public void setSigProvider(String);
-    method public void setTargetCertConstraints(java.security.cert.CertSelector);
-    method public void setTrustAnchors(java.util.Set<java.security.cert.TrustAnchor>) throws java.security.InvalidAlgorithmParameterException;
-  }
-
-  public enum PKIXReason implements java.security.cert.CertPathValidatorException.Reason {
-    enum_constant public static final java.security.cert.PKIXReason INVALID_KEY_USAGE;
-    enum_constant public static final java.security.cert.PKIXReason INVALID_NAME;
-    enum_constant public static final java.security.cert.PKIXReason INVALID_POLICY;
-    enum_constant public static final java.security.cert.PKIXReason NAME_CHAINING;
-    enum_constant public static final java.security.cert.PKIXReason NOT_CA_CERT;
-    enum_constant public static final java.security.cert.PKIXReason NO_TRUST_ANCHOR;
-    enum_constant public static final java.security.cert.PKIXReason PATH_TOO_LONG;
-    enum_constant public static final java.security.cert.PKIXReason UNRECOGNIZED_CRIT_EXT;
-  }
-
-  public abstract class PKIXRevocationChecker extends java.security.cert.PKIXCertPathChecker {
-    ctor protected PKIXRevocationChecker();
-    method public java.security.cert.PKIXRevocationChecker clone();
-    method public java.util.List<java.security.cert.Extension> getOcspExtensions();
-    method public java.net.URI getOcspResponder();
-    method public java.security.cert.X509Certificate getOcspResponderCert();
-    method public java.util.Map<java.security.cert.X509Certificate,byte[]> getOcspResponses();
-    method public java.util.Set<java.security.cert.PKIXRevocationChecker.Option> getOptions();
-    method public abstract java.util.List<java.security.cert.CertPathValidatorException> getSoftFailExceptions();
-    method public void setOcspExtensions(java.util.List<java.security.cert.Extension>);
-    method public void setOcspResponder(java.net.URI);
-    method public void setOcspResponderCert(java.security.cert.X509Certificate);
-    method public void setOcspResponses(java.util.Map<java.security.cert.X509Certificate,byte[]>);
-    method public void setOptions(java.util.Set<java.security.cert.PKIXRevocationChecker.Option>);
-  }
-
-  public enum PKIXRevocationChecker.Option {
-    enum_constant public static final java.security.cert.PKIXRevocationChecker.Option NO_FALLBACK;
-    enum_constant public static final java.security.cert.PKIXRevocationChecker.Option ONLY_END_ENTITY;
-    enum_constant public static final java.security.cert.PKIXRevocationChecker.Option PREFER_CRLS;
-    enum_constant public static final java.security.cert.PKIXRevocationChecker.Option SOFT_FAIL;
-  }
-
-  public interface PolicyNode {
-    method public java.util.Iterator<? extends java.security.cert.PolicyNode> getChildren();
-    method public int getDepth();
-    method public java.util.Set<java.lang.String> getExpectedPolicies();
-    method public java.security.cert.PolicyNode getParent();
-    method public java.util.Set<? extends java.security.cert.PolicyQualifierInfo> getPolicyQualifiers();
-    method public String getValidPolicy();
-    method public boolean isCritical();
-  }
-
-  public class PolicyQualifierInfo {
-    ctor public PolicyQualifierInfo(byte[]) throws java.io.IOException;
-    method public final byte[] getEncoded();
-    method public final byte[] getPolicyQualifier();
-    method public final String getPolicyQualifierId();
-  }
-
-  public class TrustAnchor {
-    ctor public TrustAnchor(java.security.cert.X509Certificate, byte[]);
-    ctor public TrustAnchor(javax.security.auth.x500.X500Principal, java.security.PublicKey, byte[]);
-    ctor public TrustAnchor(String, java.security.PublicKey, byte[]);
-    method public final javax.security.auth.x500.X500Principal getCA();
-    method public final String getCAName();
-    method public final java.security.PublicKey getCAPublicKey();
-    method public final byte[] getNameConstraints();
-    method public final java.security.cert.X509Certificate getTrustedCert();
-  }
-
-  public abstract class X509CRL extends java.security.cert.CRL implements java.security.cert.X509Extension {
-    ctor protected X509CRL();
-    method public abstract byte[] getEncoded() throws java.security.cert.CRLException;
-    method public abstract java.security.Principal getIssuerDN();
-    method public javax.security.auth.x500.X500Principal getIssuerX500Principal();
-    method public abstract java.util.Date getNextUpdate();
-    method public abstract java.security.cert.X509CRLEntry getRevokedCertificate(java.math.BigInteger);
-    method public java.security.cert.X509CRLEntry getRevokedCertificate(java.security.cert.X509Certificate);
-    method public abstract java.util.Set<? extends java.security.cert.X509CRLEntry> getRevokedCertificates();
-    method public abstract String getSigAlgName();
-    method public abstract String getSigAlgOID();
-    method public abstract byte[] getSigAlgParams();
-    method public abstract byte[] getSignature();
-    method public abstract byte[] getTBSCertList() throws java.security.cert.CRLException;
-    method public abstract java.util.Date getThisUpdate();
-    method public abstract int getVersion();
-    method public abstract void verify(java.security.PublicKey) throws java.security.cert.CRLException, java.security.InvalidKeyException, java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException, java.security.SignatureException;
-    method public abstract void verify(java.security.PublicKey, String) throws java.security.cert.CRLException, java.security.InvalidKeyException, java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException, java.security.SignatureException;
-    method public void verify(java.security.PublicKey, java.security.Provider) throws java.security.cert.CRLException, java.security.InvalidKeyException, java.security.NoSuchAlgorithmException, java.security.SignatureException;
-  }
-
-  public abstract class X509CRLEntry implements java.security.cert.X509Extension {
-    ctor public X509CRLEntry();
-    method public javax.security.auth.x500.X500Principal getCertificateIssuer();
-    method public abstract byte[] getEncoded() throws java.security.cert.CRLException;
-    method public abstract java.util.Date getRevocationDate();
-    method public java.security.cert.CRLReason getRevocationReason();
-    method public abstract java.math.BigInteger getSerialNumber();
-    method public abstract boolean hasExtensions();
-    method public abstract String toString();
-  }
-
-  public class X509CRLSelector implements java.security.cert.CRLSelector {
-    ctor public X509CRLSelector();
-    method public void addIssuer(javax.security.auth.x500.X500Principal);
-    method public void addIssuerName(String) throws java.io.IOException;
-    method public void addIssuerName(byte[]) throws java.io.IOException;
-    method public Object clone();
-    method public java.security.cert.X509Certificate getCertificateChecking();
-    method public java.util.Date getDateAndTime();
-    method public java.util.Collection<java.lang.Object> getIssuerNames();
-    method public java.util.Collection<javax.security.auth.x500.X500Principal> getIssuers();
-    method public java.math.BigInteger getMaxCRL();
-    method public java.math.BigInteger getMinCRL();
-    method public boolean match(java.security.cert.CRL);
-    method public void setCertificateChecking(java.security.cert.X509Certificate);
-    method public void setDateAndTime(java.util.Date);
-    method public void setIssuerNames(java.util.Collection<?>) throws java.io.IOException;
-    method public void setIssuers(java.util.Collection<javax.security.auth.x500.X500Principal>);
-    method public void setMaxCRLNumber(java.math.BigInteger);
-    method public void setMinCRLNumber(java.math.BigInteger);
-  }
-
-  public class X509CertSelector implements java.security.cert.CertSelector {
-    ctor public X509CertSelector();
-    method public void addPathToName(int, String) throws java.io.IOException;
-    method public void addPathToName(int, byte[]) throws java.io.IOException;
-    method public void addSubjectAlternativeName(int, String) throws java.io.IOException;
-    method public void addSubjectAlternativeName(int, byte[]) throws java.io.IOException;
-    method public Object clone();
-    method public byte[] getAuthorityKeyIdentifier();
-    method public int getBasicConstraints();
-    method public java.security.cert.X509Certificate getCertificate();
-    method public java.util.Date getCertificateValid();
-    method public java.util.Set<java.lang.String> getExtendedKeyUsage();
-    method public javax.security.auth.x500.X500Principal getIssuer();
-    method public byte[] getIssuerAsBytes() throws java.io.IOException;
-    method public String getIssuerAsString();
-    method public boolean[] getKeyUsage();
-    method public boolean getMatchAllSubjectAltNames();
-    method public byte[] getNameConstraints();
-    method public java.util.Collection<java.util.List<?>> getPathToNames();
-    method public java.util.Set<java.lang.String> getPolicy();
-    method public java.util.Date getPrivateKeyValid();
-    method public java.math.BigInteger getSerialNumber();
-    method public javax.security.auth.x500.X500Principal getSubject();
-    method public java.util.Collection<java.util.List<?>> getSubjectAlternativeNames();
-    method public byte[] getSubjectAsBytes() throws java.io.IOException;
-    method public String getSubjectAsString();
-    method public byte[] getSubjectKeyIdentifier();
-    method public java.security.PublicKey getSubjectPublicKey();
-    method public String getSubjectPublicKeyAlgID();
-    method public boolean match(java.security.cert.Certificate);
-    method public void setAuthorityKeyIdentifier(byte[]);
-    method public void setBasicConstraints(int);
-    method public void setCertificate(java.security.cert.X509Certificate);
-    method public void setCertificateValid(java.util.Date);
-    method public void setExtendedKeyUsage(java.util.Set<java.lang.String>) throws java.io.IOException;
-    method public void setIssuer(javax.security.auth.x500.X500Principal);
-    method public void setIssuer(String) throws java.io.IOException;
-    method public void setIssuer(byte[]) throws java.io.IOException;
-    method public void setKeyUsage(boolean[]);
-    method public void setMatchAllSubjectAltNames(boolean);
-    method public void setNameConstraints(byte[]) throws java.io.IOException;
-    method public void setPathToNames(java.util.Collection<java.util.List<?>>) throws java.io.IOException;
-    method public void setPolicy(java.util.Set<java.lang.String>) throws java.io.IOException;
-    method public void setPrivateKeyValid(java.util.Date);
-    method public void setSerialNumber(java.math.BigInteger);
-    method public void setSubject(javax.security.auth.x500.X500Principal);
-    method public void setSubject(String) throws java.io.IOException;
-    method public void setSubject(byte[]) throws java.io.IOException;
-    method public void setSubjectAlternativeNames(java.util.Collection<java.util.List<?>>) throws java.io.IOException;
-    method public void setSubjectKeyIdentifier(byte[]);
-    method public void setSubjectPublicKey(java.security.PublicKey);
-    method public void setSubjectPublicKey(byte[]) throws java.io.IOException;
-    method public void setSubjectPublicKeyAlgID(String) throws java.io.IOException;
-  }
-
-  public abstract class X509Certificate extends java.security.cert.Certificate implements java.security.cert.X509Extension {
-    ctor protected X509Certificate();
-    method public abstract void checkValidity() throws java.security.cert.CertificateExpiredException, java.security.cert.CertificateNotYetValidException;
-    method public abstract void checkValidity(java.util.Date) throws java.security.cert.CertificateExpiredException, java.security.cert.CertificateNotYetValidException;
-    method public abstract int getBasicConstraints();
-    method public java.util.List<java.lang.String> getExtendedKeyUsage() throws java.security.cert.CertificateParsingException;
-    method public java.util.Collection<java.util.List<?>> getIssuerAlternativeNames() throws java.security.cert.CertificateParsingException;
-    method public abstract java.security.Principal getIssuerDN();
-    method public abstract boolean[] getIssuerUniqueID();
-    method public javax.security.auth.x500.X500Principal getIssuerX500Principal();
-    method public abstract boolean[] getKeyUsage();
-    method public abstract java.util.Date getNotAfter();
-    method public abstract java.util.Date getNotBefore();
-    method public abstract java.math.BigInteger getSerialNumber();
-    method public abstract String getSigAlgName();
-    method public abstract String getSigAlgOID();
-    method public abstract byte[] getSigAlgParams();
-    method public abstract byte[] getSignature();
-    method public java.util.Collection<java.util.List<?>> getSubjectAlternativeNames() throws java.security.cert.CertificateParsingException;
-    method public abstract java.security.Principal getSubjectDN();
-    method public abstract boolean[] getSubjectUniqueID();
-    method public javax.security.auth.x500.X500Principal getSubjectX500Principal();
-    method public abstract byte[] getTBSCertificate() throws java.security.cert.CertificateEncodingException;
-    method public abstract int getVersion();
-  }
-
-  public interface X509Extension {
-    method public java.util.Set<java.lang.String> getCriticalExtensionOIDs();
-    method public byte[] getExtensionValue(String);
-    method public java.util.Set<java.lang.String> getNonCriticalExtensionOIDs();
-    method public boolean hasUnsupportedCriticalExtension();
-  }
-
-}
-
-package java.security.interfaces {
-
-  public interface DSAKey {
-    method public java.security.interfaces.DSAParams getParams();
-  }
-
-  public interface DSAKeyPairGenerator {
-    method public void initialize(java.security.interfaces.DSAParams, java.security.SecureRandom) throws java.security.InvalidParameterException;
-    method public void initialize(int, boolean, java.security.SecureRandom) throws java.security.InvalidParameterException;
-  }
-
-  public interface DSAParams {
-    method public java.math.BigInteger getG();
-    method public java.math.BigInteger getP();
-    method public java.math.BigInteger getQ();
-  }
-
-  public interface DSAPrivateKey extends java.security.interfaces.DSAKey java.security.PrivateKey {
-    method public java.math.BigInteger getX();
-    field public static final long serialVersionUID = 7776497482533790279L; // 0x6bebab423b256247L
-  }
-
-  public interface DSAPublicKey extends java.security.interfaces.DSAKey java.security.PublicKey {
-    method public java.math.BigInteger getY();
-    field public static final long serialVersionUID = 1234526332779022332L; // 0x1121eb28ab28c7fcL
-  }
-
-  public interface ECKey {
-    method public java.security.spec.ECParameterSpec getParams();
-  }
-
-  public interface ECPrivateKey extends java.security.PrivateKey java.security.interfaces.ECKey {
-    method public java.math.BigInteger getS();
-    field public static final long serialVersionUID = -7896394956925609184L; // 0x926a5e9fa2435b20L
-  }
-
-  public interface ECPublicKey extends java.security.PublicKey java.security.interfaces.ECKey {
-    method public java.security.spec.ECPoint getW();
-    field public static final long serialVersionUID = -3314988629879632826L; // 0xd1fecb679990cc46L
-  }
-
-  public interface RSAKey {
-    method public java.math.BigInteger getModulus();
-  }
-
-  public interface RSAMultiPrimePrivateCrtKey extends java.security.interfaces.RSAPrivateKey {
-    method public java.math.BigInteger getCrtCoefficient();
-    method public java.security.spec.RSAOtherPrimeInfo[] getOtherPrimeInfo();
-    method public java.math.BigInteger getPrimeExponentP();
-    method public java.math.BigInteger getPrimeExponentQ();
-    method public java.math.BigInteger getPrimeP();
-    method public java.math.BigInteger getPrimeQ();
-    method public java.math.BigInteger getPublicExponent();
-    field public static final long serialVersionUID = 618058533534628008L; // 0x893c8f62dbaf8a8L
-  }
-
-  public interface RSAPrivateCrtKey extends java.security.interfaces.RSAPrivateKey {
-    method public java.math.BigInteger getCrtCoefficient();
-    method public java.math.BigInteger getPrimeExponentP();
-    method public java.math.BigInteger getPrimeExponentQ();
-    method public java.math.BigInteger getPrimeP();
-    method public java.math.BigInteger getPrimeQ();
-    method public java.math.BigInteger getPublicExponent();
-    field public static final long serialVersionUID = -5682214253527700368L; // 0xb124b83df8d1ec70L
-  }
-
-  public interface RSAPrivateKey extends java.security.PrivateKey java.security.interfaces.RSAKey {
-    method public java.math.BigInteger getPrivateExponent();
-    field public static final long serialVersionUID = 5187144804936595022L; // 0x47fc70b7a8c2364eL
-  }
-
-  public interface RSAPublicKey extends java.security.PublicKey java.security.interfaces.RSAKey {
-    method public java.math.BigInteger getPublicExponent();
-    field public static final long serialVersionUID = -8727434096241101194L; // 0x86e1ecedeceab676L
-  }
-
-}
-
-package java.security.spec {
-
-  public interface AlgorithmParameterSpec {
-  }
-
-  public class DSAParameterSpec implements java.security.spec.AlgorithmParameterSpec java.security.interfaces.DSAParams {
-    ctor public DSAParameterSpec(java.math.BigInteger, java.math.BigInteger, java.math.BigInteger);
-    method public java.math.BigInteger getG();
-    method public java.math.BigInteger getP();
-    method public java.math.BigInteger getQ();
-  }
-
-  public class DSAPrivateKeySpec implements java.security.spec.KeySpec {
-    ctor public DSAPrivateKeySpec(java.math.BigInteger, java.math.BigInteger, java.math.BigInteger, java.math.BigInteger);
-    method public java.math.BigInteger getG();
-    method public java.math.BigInteger getP();
-    method public java.math.BigInteger getQ();
-    method public java.math.BigInteger getX();
-  }
-
-  public class DSAPublicKeySpec implements java.security.spec.KeySpec {
-    ctor public DSAPublicKeySpec(java.math.BigInteger, java.math.BigInteger, java.math.BigInteger, java.math.BigInteger);
-    method public java.math.BigInteger getG();
-    method public java.math.BigInteger getP();
-    method public java.math.BigInteger getQ();
-    method public java.math.BigInteger getY();
-  }
-
-  public interface ECField {
-    method public int getFieldSize();
-  }
-
-  public class ECFieldF2m implements java.security.spec.ECField {
-    ctor public ECFieldF2m(int);
-    ctor public ECFieldF2m(int, java.math.BigInteger);
-    ctor public ECFieldF2m(int, int[]);
-    method public int getFieldSize();
-    method public int getM();
-    method public int[] getMidTermsOfReductionPolynomial();
-    method public java.math.BigInteger getReductionPolynomial();
-  }
-
-  public class ECFieldFp implements java.security.spec.ECField {
-    ctor public ECFieldFp(java.math.BigInteger);
-    method public int getFieldSize();
-    method public java.math.BigInteger getP();
-  }
-
-  public class ECGenParameterSpec implements java.security.spec.AlgorithmParameterSpec {
-    ctor public ECGenParameterSpec(String);
-    method public String getName();
-  }
-
-  public class ECParameterSpec implements java.security.spec.AlgorithmParameterSpec {
-    ctor public ECParameterSpec(java.security.spec.EllipticCurve, java.security.spec.ECPoint, java.math.BigInteger, int);
-    method public int getCofactor();
-    method public java.security.spec.EllipticCurve getCurve();
-    method public java.security.spec.ECPoint getGenerator();
-    method public java.math.BigInteger getOrder();
-  }
-
-  public class ECPoint {
-    ctor public ECPoint(java.math.BigInteger, java.math.BigInteger);
-    method public java.math.BigInteger getAffineX();
-    method public java.math.BigInteger getAffineY();
-    field public static final java.security.spec.ECPoint POINT_INFINITY;
-  }
-
-  public class ECPrivateKeySpec implements java.security.spec.KeySpec {
-    ctor public ECPrivateKeySpec(java.math.BigInteger, java.security.spec.ECParameterSpec);
-    method public java.security.spec.ECParameterSpec getParams();
-    method public java.math.BigInteger getS();
-  }
-
-  public class ECPublicKeySpec implements java.security.spec.KeySpec {
-    ctor public ECPublicKeySpec(java.security.spec.ECPoint, java.security.spec.ECParameterSpec);
-    method public java.security.spec.ECParameterSpec getParams();
-    method public java.security.spec.ECPoint getW();
-  }
-
-  public class EllipticCurve {
-    ctor public EllipticCurve(java.security.spec.ECField, java.math.BigInteger, java.math.BigInteger);
-    ctor public EllipticCurve(java.security.spec.ECField, java.math.BigInteger, java.math.BigInteger, byte[]);
-    method public java.math.BigInteger getA();
-    method public java.math.BigInteger getB();
-    method public java.security.spec.ECField getField();
-    method public byte[] getSeed();
-  }
-
-  public abstract class EncodedKeySpec implements java.security.spec.KeySpec {
-    ctor public EncodedKeySpec(byte[]);
-    method public byte[] getEncoded();
-    method public abstract String getFormat();
-  }
-
-  public class InvalidKeySpecException extends java.security.GeneralSecurityException {
-    ctor public InvalidKeySpecException();
-    ctor public InvalidKeySpecException(String);
-    ctor public InvalidKeySpecException(String, Throwable);
-    ctor public InvalidKeySpecException(Throwable);
-  }
-
-  public class InvalidParameterSpecException extends java.security.GeneralSecurityException {
-    ctor public InvalidParameterSpecException();
-    ctor public InvalidParameterSpecException(String);
-  }
-
-  public interface KeySpec {
-  }
-
-  public class MGF1ParameterSpec implements java.security.spec.AlgorithmParameterSpec {
-    ctor public MGF1ParameterSpec(String);
-    method public String getDigestAlgorithm();
-    field public static final java.security.spec.MGF1ParameterSpec SHA1;
-    field public static final java.security.spec.MGF1ParameterSpec SHA224;
-    field public static final java.security.spec.MGF1ParameterSpec SHA256;
-    field public static final java.security.spec.MGF1ParameterSpec SHA384;
-    field public static final java.security.spec.MGF1ParameterSpec SHA512;
-  }
-
-  public class PKCS8EncodedKeySpec extends java.security.spec.EncodedKeySpec {
-    ctor public PKCS8EncodedKeySpec(byte[]);
-    method public final String getFormat();
-  }
-
-  public class PSSParameterSpec implements java.security.spec.AlgorithmParameterSpec {
-    ctor public PSSParameterSpec(String, String, java.security.spec.AlgorithmParameterSpec, int, int);
-    ctor public PSSParameterSpec(int);
-    method public String getDigestAlgorithm();
-    method public String getMGFAlgorithm();
-    method public java.security.spec.AlgorithmParameterSpec getMGFParameters();
-    method public int getSaltLength();
-    method public int getTrailerField();
-    field public static final java.security.spec.PSSParameterSpec DEFAULT;
-  }
-
-  public class RSAKeyGenParameterSpec implements java.security.spec.AlgorithmParameterSpec {
-    ctor public RSAKeyGenParameterSpec(int, java.math.BigInteger);
-    method public int getKeysize();
-    method public java.math.BigInteger getPublicExponent();
-    field public static final java.math.BigInteger F0;
-    field public static final java.math.BigInteger F4;
-  }
-
-  public class RSAMultiPrimePrivateCrtKeySpec extends java.security.spec.RSAPrivateKeySpec {
-    ctor public RSAMultiPrimePrivateCrtKeySpec(java.math.BigInteger, java.math.BigInteger, java.math.BigInteger, java.math.BigInteger, java.math.BigInteger, java.math.BigInteger, java.math.BigInteger, java.math.BigInteger, java.security.spec.RSAOtherPrimeInfo[]);
-    method public java.math.BigInteger getCrtCoefficient();
-    method public java.security.spec.RSAOtherPrimeInfo[] getOtherPrimeInfo();
-    method public java.math.BigInteger getPrimeExponentP();
-    method public java.math.BigInteger getPrimeExponentQ();
-    method public java.math.BigInteger getPrimeP();
-    method public java.math.BigInteger getPrimeQ();
-    method public java.math.BigInteger getPublicExponent();
-  }
-
-  public class RSAOtherPrimeInfo {
-    ctor public RSAOtherPrimeInfo(java.math.BigInteger, java.math.BigInteger, java.math.BigInteger);
-    method public final java.math.BigInteger getCrtCoefficient();
-    method public final java.math.BigInteger getExponent();
-    method public final java.math.BigInteger getPrime();
-  }
-
-  public class RSAPrivateCrtKeySpec extends java.security.spec.RSAPrivateKeySpec {
-    ctor public RSAPrivateCrtKeySpec(java.math.BigInteger, java.math.BigInteger, java.math.BigInteger, java.math.BigInteger, java.math.BigInteger, java.math.BigInteger, java.math.BigInteger, java.math.BigInteger);
-    method public java.math.BigInteger getCrtCoefficient();
-    method public java.math.BigInteger getPrimeExponentP();
-    method public java.math.BigInteger getPrimeExponentQ();
-    method public java.math.BigInteger getPrimeP();
-    method public java.math.BigInteger getPrimeQ();
-    method public java.math.BigInteger getPublicExponent();
-  }
-
-  public class RSAPrivateKeySpec implements java.security.spec.KeySpec {
-    ctor public RSAPrivateKeySpec(java.math.BigInteger, java.math.BigInteger);
-    method public java.math.BigInteger getModulus();
-    method public java.math.BigInteger getPrivateExponent();
-  }
-
-  public class RSAPublicKeySpec implements java.security.spec.KeySpec {
-    ctor public RSAPublicKeySpec(java.math.BigInteger, java.math.BigInteger);
-    method public java.math.BigInteger getModulus();
-    method public java.math.BigInteger getPublicExponent();
-  }
-
-  public class X509EncodedKeySpec extends java.security.spec.EncodedKeySpec {
-    ctor public X509EncodedKeySpec(byte[]);
-    method public final String getFormat();
-  }
-
-}
-
-package java.sql {
-
-  public interface Array {
-    method public void free() throws java.sql.SQLException;
-    method public Object getArray() throws java.sql.SQLException;
-    method public Object getArray(java.util.Map<java.lang.String,java.lang.Class<?>>) throws java.sql.SQLException;
-    method public Object getArray(long, int) throws java.sql.SQLException;
-    method public Object getArray(long, int, java.util.Map<java.lang.String,java.lang.Class<?>>) throws java.sql.SQLException;
-    method public int getBaseType() throws java.sql.SQLException;
-    method public String getBaseTypeName() throws java.sql.SQLException;
-    method public java.sql.ResultSet getResultSet() throws java.sql.SQLException;
-    method public java.sql.ResultSet getResultSet(java.util.Map<java.lang.String,java.lang.Class<?>>) throws java.sql.SQLException;
-    method public java.sql.ResultSet getResultSet(long, int) throws java.sql.SQLException;
-    method public java.sql.ResultSet getResultSet(long, int, java.util.Map<java.lang.String,java.lang.Class<?>>) throws java.sql.SQLException;
-  }
-
-  public class BatchUpdateException extends java.sql.SQLException {
-    ctor public BatchUpdateException(String, String, int, int[]);
-    ctor public BatchUpdateException(String, String, int[]);
-    ctor public BatchUpdateException(String, int[]);
-    ctor public BatchUpdateException(int[]);
-    ctor public BatchUpdateException();
-    ctor public BatchUpdateException(Throwable);
-    ctor public BatchUpdateException(int[], Throwable);
-    ctor public BatchUpdateException(String, int[], Throwable);
-    ctor public BatchUpdateException(String, String, int[], Throwable);
-    ctor public BatchUpdateException(String, String, int, int[], Throwable);
-    method public int[] getUpdateCounts();
-  }
-
-  public interface Blob {
-    method public void free() throws java.sql.SQLException;
-    method public java.io.InputStream getBinaryStream() throws java.sql.SQLException;
-    method public java.io.InputStream getBinaryStream(long, long) throws java.sql.SQLException;
-    method public byte[] getBytes(long, int) throws java.sql.SQLException;
-    method public long length() throws java.sql.SQLException;
-    method public long position(byte[], long) throws java.sql.SQLException;
-    method public long position(java.sql.Blob, long) throws java.sql.SQLException;
-    method public java.io.OutputStream setBinaryStream(long) throws java.sql.SQLException;
-    method public int setBytes(long, byte[]) throws java.sql.SQLException;
-    method public int setBytes(long, byte[], int, int) throws java.sql.SQLException;
-    method public void truncate(long) throws java.sql.SQLException;
-  }
-
-  public interface CallableStatement extends java.sql.PreparedStatement {
-    method public java.sql.Array getArray(int) throws java.sql.SQLException;
-    method public java.sql.Array getArray(String) throws java.sql.SQLException;
-    method @Deprecated public java.math.BigDecimal getBigDecimal(int, int) throws java.sql.SQLException;
-    method public java.math.BigDecimal getBigDecimal(int) throws java.sql.SQLException;
-    method public java.math.BigDecimal getBigDecimal(String) throws java.sql.SQLException;
-    method public java.sql.Blob getBlob(int) throws java.sql.SQLException;
-    method public java.sql.Blob getBlob(String) throws java.sql.SQLException;
-    method public boolean getBoolean(int) throws java.sql.SQLException;
-    method public boolean getBoolean(String) throws java.sql.SQLException;
-    method public byte getByte(int) throws java.sql.SQLException;
-    method public byte getByte(String) throws java.sql.SQLException;
-    method public byte[] getBytes(int) throws java.sql.SQLException;
-    method public byte[] getBytes(String) throws java.sql.SQLException;
-    method public java.io.Reader getCharacterStream(int) throws java.sql.SQLException;
-    method public java.io.Reader getCharacterStream(String) throws java.sql.SQLException;
-    method public java.sql.Clob getClob(int) throws java.sql.SQLException;
-    method public java.sql.Clob getClob(String) throws java.sql.SQLException;
-    method public java.sql.Date getDate(int) throws java.sql.SQLException;
-    method public java.sql.Date getDate(int, java.util.Calendar) throws java.sql.SQLException;
-    method public java.sql.Date getDate(String) throws java.sql.SQLException;
-    method public java.sql.Date getDate(String, java.util.Calendar) throws java.sql.SQLException;
-    method public double getDouble(int) throws java.sql.SQLException;
-    method public double getDouble(String) throws java.sql.SQLException;
-    method public float getFloat(int) throws java.sql.SQLException;
-    method public float getFloat(String) throws java.sql.SQLException;
-    method public int getInt(int) throws java.sql.SQLException;
-    method public int getInt(String) throws java.sql.SQLException;
-    method public long getLong(int) throws java.sql.SQLException;
-    method public long getLong(String) throws java.sql.SQLException;
-    method public java.io.Reader getNCharacterStream(int) throws java.sql.SQLException;
-    method public java.io.Reader getNCharacterStream(String) throws java.sql.SQLException;
-    method public java.sql.NClob getNClob(int) throws java.sql.SQLException;
-    method public java.sql.NClob getNClob(String) throws java.sql.SQLException;
-    method public String getNString(int) throws java.sql.SQLException;
-    method public String getNString(String) throws java.sql.SQLException;
-    method public Object getObject(int) throws java.sql.SQLException;
-    method public Object getObject(int, java.util.Map<java.lang.String,java.lang.Class<?>>) throws java.sql.SQLException;
-    method public Object getObject(String) throws java.sql.SQLException;
-    method public Object getObject(String, java.util.Map<java.lang.String,java.lang.Class<?>>) throws java.sql.SQLException;
-    method public java.sql.Ref getRef(int) throws java.sql.SQLException;
-    method public java.sql.Ref getRef(String) throws java.sql.SQLException;
-    method public java.sql.RowId getRowId(int) throws java.sql.SQLException;
-    method public java.sql.RowId getRowId(String) throws java.sql.SQLException;
-    method public java.sql.SQLXML getSQLXML(int) throws java.sql.SQLException;
-    method public java.sql.SQLXML getSQLXML(String) throws java.sql.SQLException;
-    method public short getShort(int) throws java.sql.SQLException;
-    method public short getShort(String) throws java.sql.SQLException;
-    method public String getString(int) throws java.sql.SQLException;
-    method public String getString(String) throws java.sql.SQLException;
-    method public java.sql.Time getTime(int) throws java.sql.SQLException;
-    method public java.sql.Time getTime(int, java.util.Calendar) throws java.sql.SQLException;
-    method public java.sql.Time getTime(String) throws java.sql.SQLException;
-    method public java.sql.Time getTime(String, java.util.Calendar) throws java.sql.SQLException;
-    method public java.sql.Timestamp getTimestamp(int) throws java.sql.SQLException;
-    method public java.sql.Timestamp getTimestamp(int, java.util.Calendar) throws java.sql.SQLException;
-    method public java.sql.Timestamp getTimestamp(String) throws java.sql.SQLException;
-    method public java.sql.Timestamp getTimestamp(String, java.util.Calendar) throws java.sql.SQLException;
-    method public java.net.URL getURL(int) throws java.sql.SQLException;
-    method public java.net.URL getURL(String) throws java.sql.SQLException;
-    method public void registerOutParameter(int, int) throws java.sql.SQLException;
-    method public void registerOutParameter(int, int, int) throws java.sql.SQLException;
-    method public void registerOutParameter(int, int, String) throws java.sql.SQLException;
-    method public void registerOutParameter(String, int) throws java.sql.SQLException;
-    method public void registerOutParameter(String, int, int) throws java.sql.SQLException;
-    method public void registerOutParameter(String, int, String) throws java.sql.SQLException;
-    method public void setAsciiStream(String, java.io.InputStream, int) throws java.sql.SQLException;
-    method public void setAsciiStream(String, java.io.InputStream, long) throws java.sql.SQLException;
-    method public void setAsciiStream(String, java.io.InputStream) throws java.sql.SQLException;
-    method public void setBigDecimal(String, java.math.BigDecimal) throws java.sql.SQLException;
-    method public void setBinaryStream(String, java.io.InputStream, int) throws java.sql.SQLException;
-    method public void setBinaryStream(String, java.io.InputStream, long) throws java.sql.SQLException;
-    method public void setBinaryStream(String, java.io.InputStream) throws java.sql.SQLException;
-    method public void setBlob(String, java.io.InputStream, long) throws java.sql.SQLException;
-    method public void setBlob(String, java.sql.Blob) throws java.sql.SQLException;
-    method public void setBlob(String, java.io.InputStream) throws java.sql.SQLException;
-    method public void setBoolean(String, boolean) throws java.sql.SQLException;
-    method public void setByte(String, byte) throws java.sql.SQLException;
-    method public void setBytes(String, byte[]) throws java.sql.SQLException;
-    method public void setCharacterStream(String, java.io.Reader, int) throws java.sql.SQLException;
-    method public void setCharacterStream(String, java.io.Reader, long) throws java.sql.SQLException;
-    method public void setCharacterStream(String, java.io.Reader) throws java.sql.SQLException;
-    method public void setClob(String, java.io.Reader, long) throws java.sql.SQLException;
-    method public void setClob(String, java.sql.Clob) throws java.sql.SQLException;
-    method public void setClob(String, java.io.Reader) throws java.sql.SQLException;
-    method public void setDate(String, java.sql.Date) throws java.sql.SQLException;
-    method public void setDate(String, java.sql.Date, java.util.Calendar) throws java.sql.SQLException;
-    method public void setDouble(String, double) throws java.sql.SQLException;
-    method public void setFloat(String, float) throws java.sql.SQLException;
-    method public void setInt(String, int) throws java.sql.SQLException;
-    method public void setLong(String, long) throws java.sql.SQLException;
-    method public void setNCharacterStream(String, java.io.Reader, long) throws java.sql.SQLException;
-    method public void setNCharacterStream(String, java.io.Reader) throws java.sql.SQLException;
-    method public void setNClob(String, java.sql.NClob) throws java.sql.SQLException;
-    method public void setNClob(String, java.io.Reader, long) throws java.sql.SQLException;
-    method public void setNClob(String, java.io.Reader) throws java.sql.SQLException;
-    method public void setNString(String, String) throws java.sql.SQLException;
-    method public void setNull(String, int) throws java.sql.SQLException;
-    method public void setNull(String, int, String) throws java.sql.SQLException;
-    method public void setObject(String, Object, int, int) throws java.sql.SQLException;
-    method public void setObject(String, Object, int) throws java.sql.SQLException;
-    method public void setObject(String, Object) throws java.sql.SQLException;
-    method public void setRowId(String, java.sql.RowId) throws java.sql.SQLException;
-    method public void setSQLXML(String, java.sql.SQLXML) throws java.sql.SQLException;
-    method public void setShort(String, short) throws java.sql.SQLException;
-    method public void setString(String, String) throws java.sql.SQLException;
-    method public void setTime(String, java.sql.Time) throws java.sql.SQLException;
-    method public void setTime(String, java.sql.Time, java.util.Calendar) throws java.sql.SQLException;
-    method public void setTimestamp(String, java.sql.Timestamp) throws java.sql.SQLException;
-    method public void setTimestamp(String, java.sql.Timestamp, java.util.Calendar) throws java.sql.SQLException;
-    method public void setURL(String, java.net.URL) throws java.sql.SQLException;
-    method public boolean wasNull() throws java.sql.SQLException;
-  }
-
-  public enum ClientInfoStatus {
-    enum_constant public static final java.sql.ClientInfoStatus REASON_UNKNOWN;
-    enum_constant public static final java.sql.ClientInfoStatus REASON_UNKNOWN_PROPERTY;
-    enum_constant public static final java.sql.ClientInfoStatus REASON_VALUE_INVALID;
-    enum_constant public static final java.sql.ClientInfoStatus REASON_VALUE_TRUNCATED;
-  }
-
-  public interface Clob {
-    method public void free() throws java.sql.SQLException;
-    method public java.io.InputStream getAsciiStream() throws java.sql.SQLException;
-    method public java.io.Reader getCharacterStream() throws java.sql.SQLException;
-    method public java.io.Reader getCharacterStream(long, long) throws java.sql.SQLException;
-    method public String getSubString(long, int) throws java.sql.SQLException;
-    method public long length() throws java.sql.SQLException;
-    method public long position(String, long) throws java.sql.SQLException;
-    method public long position(java.sql.Clob, long) throws java.sql.SQLException;
-    method public java.io.OutputStream setAsciiStream(long) throws java.sql.SQLException;
-    method public java.io.Writer setCharacterStream(long) throws java.sql.SQLException;
-    method public int setString(long, String) throws java.sql.SQLException;
-    method public int setString(long, String, int, int) throws java.sql.SQLException;
-    method public void truncate(long) throws java.sql.SQLException;
-  }
-
-  public interface Connection extends java.sql.Wrapper java.lang.AutoCloseable {
-    method public void clearWarnings() throws java.sql.SQLException;
-    method public void close() throws java.sql.SQLException;
-    method public void commit() throws java.sql.SQLException;
-    method public java.sql.Array createArrayOf(String, Object[]) throws java.sql.SQLException;
-    method public java.sql.Blob createBlob() throws java.sql.SQLException;
-    method public java.sql.Clob createClob() throws java.sql.SQLException;
-    method public java.sql.NClob createNClob() throws java.sql.SQLException;
-    method public java.sql.SQLXML createSQLXML() throws java.sql.SQLException;
-    method public java.sql.Statement createStatement() throws java.sql.SQLException;
-    method public java.sql.Statement createStatement(int, int) throws java.sql.SQLException;
-    method public java.sql.Statement createStatement(int, int, int) throws java.sql.SQLException;
-    method public java.sql.Struct createStruct(String, Object[]) throws java.sql.SQLException;
-    method public boolean getAutoCommit() throws java.sql.SQLException;
-    method public String getCatalog() throws java.sql.SQLException;
-    method public String getClientInfo(String) throws java.sql.SQLException;
-    method public java.util.Properties getClientInfo() throws java.sql.SQLException;
-    method public int getHoldability() throws java.sql.SQLException;
-    method public java.sql.DatabaseMetaData getMetaData() throws java.sql.SQLException;
-    method public int getTransactionIsolation() throws java.sql.SQLException;
-    method public java.util.Map<java.lang.String,java.lang.Class<?>> getTypeMap() throws java.sql.SQLException;
-    method public java.sql.SQLWarning getWarnings() throws java.sql.SQLException;
-    method public boolean isClosed() throws java.sql.SQLException;
-    method public boolean isReadOnly() throws java.sql.SQLException;
-    method public boolean isValid(int) throws java.sql.SQLException;
-    method public String nativeSQL(String) throws java.sql.SQLException;
-    method public java.sql.CallableStatement prepareCall(String) throws java.sql.SQLException;
-    method public java.sql.CallableStatement prepareCall(String, int, int) throws java.sql.SQLException;
-    method public java.sql.CallableStatement prepareCall(String, int, int, int) throws java.sql.SQLException;
-    method public java.sql.PreparedStatement prepareStatement(String) throws java.sql.SQLException;
-    method public java.sql.PreparedStatement prepareStatement(String, int, int) throws java.sql.SQLException;
-    method public java.sql.PreparedStatement prepareStatement(String, int, int, int) throws java.sql.SQLException;
-    method public java.sql.PreparedStatement prepareStatement(String, int) throws java.sql.SQLException;
-    method public java.sql.PreparedStatement prepareStatement(String, int[]) throws java.sql.SQLException;
-    method public java.sql.PreparedStatement prepareStatement(String, String[]) throws java.sql.SQLException;
-    method public void releaseSavepoint(java.sql.Savepoint) throws java.sql.SQLException;
-    method public void rollback() throws java.sql.SQLException;
-    method public void rollback(java.sql.Savepoint) throws java.sql.SQLException;
-    method public void setAutoCommit(boolean) throws java.sql.SQLException;
-    method public void setCatalog(String) throws java.sql.SQLException;
-    method public void setClientInfo(String, String) throws java.sql.SQLClientInfoException;
-    method public void setClientInfo(java.util.Properties) throws java.sql.SQLClientInfoException;
-    method public void setHoldability(int) throws java.sql.SQLException;
-    method public void setReadOnly(boolean) throws java.sql.SQLException;
-    method public java.sql.Savepoint setSavepoint() throws java.sql.SQLException;
-    method public java.sql.Savepoint setSavepoint(String) throws java.sql.SQLException;
-    method public void setTransactionIsolation(int) throws java.sql.SQLException;
-    method public void setTypeMap(java.util.Map<java.lang.String,java.lang.Class<?>>) throws java.sql.SQLException;
-    field public static final int TRANSACTION_NONE = 0; // 0x0
-    field public static final int TRANSACTION_READ_COMMITTED = 2; // 0x2
-    field public static final int TRANSACTION_READ_UNCOMMITTED = 1; // 0x1
-    field public static final int TRANSACTION_REPEATABLE_READ = 4; // 0x4
-    field public static final int TRANSACTION_SERIALIZABLE = 8; // 0x8
-  }
-
-  public class DataTruncation extends java.sql.SQLWarning {
-    ctor public DataTruncation(int, boolean, boolean, int, int);
-    ctor public DataTruncation(int, boolean, boolean, int, int, Throwable);
-    method public int getDataSize();
-    method public int getIndex();
-    method public boolean getParameter();
-    method public boolean getRead();
-    method public int getTransferSize();
-  }
-
-  public interface DatabaseMetaData extends java.sql.Wrapper {
-    method public boolean allProceduresAreCallable() throws java.sql.SQLException;
-    method public boolean allTablesAreSelectable() throws java.sql.SQLException;
-    method public boolean autoCommitFailureClosesAllResultSets() throws java.sql.SQLException;
-    method public boolean dataDefinitionCausesTransactionCommit() throws java.sql.SQLException;
-    method public boolean dataDefinitionIgnoredInTransactions() throws java.sql.SQLException;
-    method public boolean deletesAreDetected(int) throws java.sql.SQLException;
-    method public boolean doesMaxRowSizeIncludeBlobs() throws java.sql.SQLException;
-    method public java.sql.ResultSet getAttributes(String, String, String, String) throws java.sql.SQLException;
-    method public java.sql.ResultSet getBestRowIdentifier(String, String, String, int, boolean) throws java.sql.SQLException;
-    method public String getCatalogSeparator() throws java.sql.SQLException;
-    method public String getCatalogTerm() throws java.sql.SQLException;
-    method public java.sql.ResultSet getCatalogs() throws java.sql.SQLException;
-    method public java.sql.ResultSet getClientInfoProperties() throws java.sql.SQLException;
-    method public java.sql.ResultSet getColumnPrivileges(String, String, String, String) throws java.sql.SQLException;
-    method public java.sql.ResultSet getColumns(String, String, String, String) throws java.sql.SQLException;
-    method public java.sql.Connection getConnection() throws java.sql.SQLException;
-    method public java.sql.ResultSet getCrossReference(String, String, String, String, String, String) throws java.sql.SQLException;
-    method public int getDatabaseMajorVersion() throws java.sql.SQLException;
-    method public int getDatabaseMinorVersion() throws java.sql.SQLException;
-    method public String getDatabaseProductName() throws java.sql.SQLException;
-    method public String getDatabaseProductVersion() throws java.sql.SQLException;
-    method public int getDefaultTransactionIsolation() throws java.sql.SQLException;
-    method public int getDriverMajorVersion();
-    method public int getDriverMinorVersion();
-    method public String getDriverName() throws java.sql.SQLException;
-    method public String getDriverVersion() throws java.sql.SQLException;
-    method public java.sql.ResultSet getExportedKeys(String, String, String) throws java.sql.SQLException;
-    method public String getExtraNameCharacters() throws java.sql.SQLException;
-    method public java.sql.ResultSet getFunctionColumns(String, String, String, String) throws java.sql.SQLException;
-    method public java.sql.ResultSet getFunctions(String, String, String) throws java.sql.SQLException;
-    method public String getIdentifierQuoteString() throws java.sql.SQLException;
-    method public java.sql.ResultSet getImportedKeys(String, String, String) throws java.sql.SQLException;
-    method public java.sql.ResultSet getIndexInfo(String, String, String, boolean, boolean) throws java.sql.SQLException;
-    method public int getJDBCMajorVersion() throws java.sql.SQLException;
-    method public int getJDBCMinorVersion() throws java.sql.SQLException;
-    method public int getMaxBinaryLiteralLength() throws java.sql.SQLException;
-    method public int getMaxCatalogNameLength() throws java.sql.SQLException;
-    method public int getMaxCharLiteralLength() throws java.sql.SQLException;
-    method public int getMaxColumnNameLength() throws java.sql.SQLException;
-    method public int getMaxColumnsInGroupBy() throws java.sql.SQLException;
-    method public int getMaxColumnsInIndex() throws java.sql.SQLException;
-    method public int getMaxColumnsInOrderBy() throws java.sql.SQLException;
-    method public int getMaxColumnsInSelect() throws java.sql.SQLException;
-    method public int getMaxColumnsInTable() throws java.sql.SQLException;
-    method public int getMaxConnections() throws java.sql.SQLException;
-    method public int getMaxCursorNameLength() throws java.sql.SQLException;
-    method public int getMaxIndexLength() throws java.sql.SQLException;
-    method public int getMaxProcedureNameLength() throws java.sql.SQLException;
-    method public int getMaxRowSize() throws java.sql.SQLException;
-    method public int getMaxSchemaNameLength() throws java.sql.SQLException;
-    method public int getMaxStatementLength() throws java.sql.SQLException;
-    method public int getMaxStatements() throws java.sql.SQLException;
-    method public int getMaxTableNameLength() throws java.sql.SQLException;
-    method public int getMaxTablesInSelect() throws java.sql.SQLException;
-    method public int getMaxUserNameLength() throws java.sql.SQLException;
-    method public String getNumericFunctions() throws java.sql.SQLException;
-    method public java.sql.ResultSet getPrimaryKeys(String, String, String) throws java.sql.SQLException;
-    method public java.sql.ResultSet getProcedureColumns(String, String, String, String) throws java.sql.SQLException;
-    method public String getProcedureTerm() throws java.sql.SQLException;
-    method public java.sql.ResultSet getProcedures(String, String, String) throws java.sql.SQLException;
-    method public int getResultSetHoldability() throws java.sql.SQLException;
-    method public java.sql.RowIdLifetime getRowIdLifetime() throws java.sql.SQLException;
-    method public String getSQLKeywords() throws java.sql.SQLException;
-    method public int getSQLStateType() throws java.sql.SQLException;
-    method public String getSchemaTerm() throws java.sql.SQLException;
-    method public java.sql.ResultSet getSchemas() throws java.sql.SQLException;
-    method public java.sql.ResultSet getSchemas(String, String) throws java.sql.SQLException;
-    method public String getSearchStringEscape() throws java.sql.SQLException;
-    method public String getStringFunctions() throws java.sql.SQLException;
-    method public java.sql.ResultSet getSuperTables(String, String, String) throws java.sql.SQLException;
-    method public java.sql.ResultSet getSuperTypes(String, String, String) throws java.sql.SQLException;
-    method public String getSystemFunctions() throws java.sql.SQLException;
-    method public java.sql.ResultSet getTablePrivileges(String, String, String) throws java.sql.SQLException;
-    method public java.sql.ResultSet getTableTypes() throws java.sql.SQLException;
-    method public java.sql.ResultSet getTables(String, String, String, String[]) throws java.sql.SQLException;
-    method public String getTimeDateFunctions() throws java.sql.SQLException;
-    method public java.sql.ResultSet getTypeInfo() throws java.sql.SQLException;
-    method public java.sql.ResultSet getUDTs(String, String, String, int[]) throws java.sql.SQLException;
-    method public String getURL() throws java.sql.SQLException;
-    method public String getUserName() throws java.sql.SQLException;
-    method public java.sql.ResultSet getVersionColumns(String, String, String) throws java.sql.SQLException;
-    method public boolean insertsAreDetected(int) throws java.sql.SQLException;
-    method public boolean isCatalogAtStart() throws java.sql.SQLException;
-    method public boolean isReadOnly() throws java.sql.SQLException;
-    method public boolean locatorsUpdateCopy() throws java.sql.SQLException;
-    method public boolean nullPlusNonNullIsNull() throws java.sql.SQLException;
-    method public boolean nullsAreSortedAtEnd() throws java.sql.SQLException;
-    method public boolean nullsAreSortedAtStart() throws java.sql.SQLException;
-    method public boolean nullsAreSortedHigh() throws java.sql.SQLException;
-    method public boolean nullsAreSortedLow() throws java.sql.SQLException;
-    method public boolean othersDeletesAreVisible(int) throws java.sql.SQLException;
-    method public boolean othersInsertsAreVisible(int) throws java.sql.SQLException;
-    method public boolean othersUpdatesAreVisible(int) throws java.sql.SQLException;
-    method public boolean ownDeletesAreVisible(int) throws java.sql.SQLException;
-    method public boolean ownInsertsAreVisible(int) throws java.sql.SQLException;
-    method public boolean ownUpdatesAreVisible(int) throws java.sql.SQLException;
-    method public boolean storesLowerCaseIdentifiers() throws java.sql.SQLException;
-    method public boolean storesLowerCaseQuotedIdentifiers() throws java.sql.SQLException;
-    method public boolean storesMixedCaseIdentifiers() throws java.sql.SQLException;
-    method public boolean storesMixedCaseQuotedIdentifiers() throws java.sql.SQLException;
-    method public boolean storesUpperCaseIdentifiers() throws java.sql.SQLException;
-    method public boolean storesUpperCaseQuotedIdentifiers() throws java.sql.SQLException;
-    method public boolean supportsANSI92EntryLevelSQL() throws java.sql.SQLException;
-    method public boolean supportsANSI92FullSQL() throws java.sql.SQLException;
-    method public boolean supportsANSI92IntermediateSQL() throws java.sql.SQLException;
-    method public boolean supportsAlterTableWithAddColumn() throws java.sql.SQLException;
-    method public boolean supportsAlterTableWithDropColumn() throws java.sql.SQLException;
-    method public boolean supportsBatchUpdates() throws java.sql.SQLException;
-    method public boolean supportsCatalogsInDataManipulation() throws java.sql.SQLException;
-    method public boolean supportsCatalogsInIndexDefinitions() throws java.sql.SQLException;
-    method public boolean supportsCatalogsInPrivilegeDefinitions() throws java.sql.SQLException;
-    method public boolean supportsCatalogsInProcedureCalls() throws java.sql.SQLException;
-    method public boolean supportsCatalogsInTableDefinitions() throws java.sql.SQLException;
-    method public boolean supportsColumnAliasing() throws java.sql.SQLException;
-    method public boolean supportsConvert() throws java.sql.SQLException;
-    method public boolean supportsConvert(int, int) throws java.sql.SQLException;
-    method public boolean supportsCoreSQLGrammar() throws java.sql.SQLException;
-    method public boolean supportsCorrelatedSubqueries() throws java.sql.SQLException;
-    method public boolean supportsDataDefinitionAndDataManipulationTransactions() throws java.sql.SQLException;
-    method public boolean supportsDataManipulationTransactionsOnly() throws java.sql.SQLException;
-    method public boolean supportsDifferentTableCorrelationNames() throws java.sql.SQLException;
-    method public boolean supportsExpressionsInOrderBy() throws java.sql.SQLException;
-    method public boolean supportsExtendedSQLGrammar() throws java.sql.SQLException;
-    method public boolean supportsFullOuterJoins() throws java.sql.SQLException;
-    method public boolean supportsGetGeneratedKeys() throws java.sql.SQLException;
-    method public boolean supportsGroupBy() throws java.sql.SQLException;
-    method public boolean supportsGroupByBeyondSelect() throws java.sql.SQLException;
-    method public boolean supportsGroupByUnrelated() throws java.sql.SQLException;
-    method public boolean supportsIntegrityEnhancementFacility() throws java.sql.SQLException;
-    method public boolean supportsLikeEscapeClause() throws java.sql.SQLException;
-    method public boolean supportsLimitedOuterJoins() throws java.sql.SQLException;
-    method public boolean supportsMinimumSQLGrammar() throws java.sql.SQLException;
-    method public boolean supportsMixedCaseIdentifiers() throws java.sql.SQLException;
-    method public boolean supportsMixedCaseQuotedIdentifiers() throws java.sql.SQLException;
-    method public boolean supportsMultipleOpenResults() throws java.sql.SQLException;
-    method public boolean supportsMultipleResultSets() throws java.sql.SQLException;
-    method public boolean supportsMultipleTransactions() throws java.sql.SQLException;
-    method public boolean supportsNamedParameters() throws java.sql.SQLException;
-    method public boolean supportsNonNullableColumns() throws java.sql.SQLException;
-    method public boolean supportsOpenCursorsAcrossCommit() throws java.sql.SQLException;
-    method public boolean supportsOpenCursorsAcrossRollback() throws java.sql.SQLException;
-    method public boolean supportsOpenStatementsAcrossCommit() throws java.sql.SQLException;
-    method public boolean supportsOpenStatementsAcrossRollback() throws java.sql.SQLException;
-    method public boolean supportsOrderByUnrelated() throws java.sql.SQLException;
-    method public boolean supportsOuterJoins() throws java.sql.SQLException;
-    method public boolean supportsPositionedDelete() throws java.sql.SQLException;
-    method public boolean supportsPositionedUpdate() throws java.sql.SQLException;
-    method public boolean supportsResultSetConcurrency(int, int) throws java.sql.SQLException;
-    method public boolean supportsResultSetHoldability(int) throws java.sql.SQLException;
-    method public boolean supportsResultSetType(int) throws java.sql.SQLException;
-    method public boolean supportsSavepoints() throws java.sql.SQLException;
-    method public boolean supportsSchemasInDataManipulation() throws java.sql.SQLException;
-    method public boolean supportsSchemasInIndexDefinitions() throws java.sql.SQLException;
-    method public boolean supportsSchemasInPrivilegeDefinitions() throws java.sql.SQLException;
-    method public boolean supportsSchemasInProcedureCalls() throws java.sql.SQLException;
-    method public boolean supportsSchemasInTableDefinitions() throws java.sql.SQLException;
-    method public boolean supportsSelectForUpdate() throws java.sql.SQLException;
-    method public boolean supportsStatementPooling() throws java.sql.SQLException;
-    method public boolean supportsStoredFunctionsUsingCallSyntax() throws java.sql.SQLException;
-    method public boolean supportsStoredProcedures() throws java.sql.SQLException;
-    method public boolean supportsSubqueriesInComparisons() throws java.sql.SQLException;
-    method public boolean supportsSubqueriesInExists() throws java.sql.SQLException;
-    method public boolean supportsSubqueriesInIns() throws java.sql.SQLException;
-    method public boolean supportsSubqueriesInQuantifieds() throws java.sql.SQLException;
-    method public boolean supportsTableCorrelationNames() throws java.sql.SQLException;
-    method public boolean supportsTransactionIsolationLevel(int) throws java.sql.SQLException;
-    method public boolean supportsTransactions() throws java.sql.SQLException;
-    method public boolean supportsUnion() throws java.sql.SQLException;
-    method public boolean supportsUnionAll() throws java.sql.SQLException;
-    method public boolean updatesAreDetected(int) throws java.sql.SQLException;
-    method public boolean usesLocalFilePerTable() throws java.sql.SQLException;
-    method public boolean usesLocalFiles() throws java.sql.SQLException;
-    field public static final short attributeNoNulls = 0; // 0x0
-    field public static final short attributeNullable = 1; // 0x1
-    field public static final short attributeNullableUnknown = 2; // 0x2
-    field public static final int bestRowNotPseudo = 1; // 0x1
-    field public static final int bestRowPseudo = 2; // 0x2
-    field public static final int bestRowSession = 2; // 0x2
-    field public static final int bestRowTemporary = 0; // 0x0
-    field public static final int bestRowTransaction = 1; // 0x1
-    field public static final int bestRowUnknown = 0; // 0x0
-    field public static final int columnNoNulls = 0; // 0x0
-    field public static final int columnNullable = 1; // 0x1
-    field public static final int columnNullableUnknown = 2; // 0x2
-    field public static final int functionColumnIn = 1; // 0x1
-    field public static final int functionColumnInOut = 2; // 0x2
-    field public static final int functionColumnOut = 3; // 0x3
-    field public static final int functionColumnResult = 5; // 0x5
-    field public static final int functionColumnUnknown = 0; // 0x0
-    field public static final int functionNoNulls = 0; // 0x0
-    field public static final int functionNoTable = 1; // 0x1
-    field public static final int functionNullable = 1; // 0x1
-    field public static final int functionNullableUnknown = 2; // 0x2
-    field public static final int functionResultUnknown = 0; // 0x0
-    field public static final int functionReturn = 4; // 0x4
-    field public static final int functionReturnsTable = 2; // 0x2
-    field public static final int importedKeyCascade = 0; // 0x0
-    field public static final int importedKeyInitiallyDeferred = 5; // 0x5
-    field public static final int importedKeyInitiallyImmediate = 6; // 0x6
-    field public static final int importedKeyNoAction = 3; // 0x3
-    field public static final int importedKeyNotDeferrable = 7; // 0x7
-    field public static final int importedKeyRestrict = 1; // 0x1
-    field public static final int importedKeySetDefault = 4; // 0x4
-    field public static final int importedKeySetNull = 2; // 0x2
-    field public static final int procedureColumnIn = 1; // 0x1
-    field public static final int procedureColumnInOut = 2; // 0x2
-    field public static final int procedureColumnOut = 4; // 0x4
-    field public static final int procedureColumnResult = 3; // 0x3
-    field public static final int procedureColumnReturn = 5; // 0x5
-    field public static final int procedureColumnUnknown = 0; // 0x0
-    field public static final int procedureNoNulls = 0; // 0x0
-    field public static final int procedureNoResult = 1; // 0x1
-    field public static final int procedureNullable = 1; // 0x1
-    field public static final int procedureNullableUnknown = 2; // 0x2
-    field public static final int procedureResultUnknown = 0; // 0x0
-    field public static final int procedureReturnsResult = 2; // 0x2
-    field public static final int sqlStateSQL = 2; // 0x2
-    field public static final int sqlStateSQL99 = 2; // 0x2
-    field public static final int sqlStateXOpen = 1; // 0x1
-    field public static final short tableIndexClustered = 1; // 0x1
-    field public static final short tableIndexHashed = 2; // 0x2
-    field public static final short tableIndexOther = 3; // 0x3
-    field public static final short tableIndexStatistic = 0; // 0x0
-    field public static final int typeNoNulls = 0; // 0x0
-    field public static final int typeNullable = 1; // 0x1
-    field public static final int typeNullableUnknown = 2; // 0x2
-    field public static final int typePredBasic = 2; // 0x2
-    field public static final int typePredChar = 1; // 0x1
-    field public static final int typePredNone = 0; // 0x0
-    field public static final int typeSearchable = 3; // 0x3
-    field public static final int versionColumnNotPseudo = 1; // 0x1
-    field public static final int versionColumnPseudo = 2; // 0x2
-    field public static final int versionColumnUnknown = 0; // 0x0
-  }
-
-  public class Date extends java.util.Date {
-    ctor @Deprecated public Date(int, int, int);
-    ctor public Date(long);
-    method public static java.sql.Date valueOf(String);
-  }
-
-  public interface Driver {
-    method public boolean acceptsURL(String) throws java.sql.SQLException;
-    method public java.sql.Connection connect(String, java.util.Properties) throws java.sql.SQLException;
-    method public int getMajorVersion();
-    method public int getMinorVersion();
-    method public java.sql.DriverPropertyInfo[] getPropertyInfo(String, java.util.Properties) throws java.sql.SQLException;
-    method public boolean jdbcCompliant();
-  }
-
-  public class DriverManager {
-    method public static void deregisterDriver(java.sql.Driver) throws java.sql.SQLException;
-    method public static java.sql.Connection getConnection(String, java.util.Properties) throws java.sql.SQLException;
-    method public static java.sql.Connection getConnection(String, String, String) throws java.sql.SQLException;
-    method public static java.sql.Connection getConnection(String) throws java.sql.SQLException;
-    method public static java.sql.Driver getDriver(String) throws java.sql.SQLException;
-    method public static java.util.Enumeration<java.sql.Driver> getDrivers();
-    method @Deprecated public static java.io.PrintStream getLogStream();
-    method public static java.io.PrintWriter getLogWriter();
-    method public static int getLoginTimeout();
-    method public static void println(String);
-    method public static void registerDriver(java.sql.Driver) throws java.sql.SQLException;
-    method @Deprecated public static void setLogStream(java.io.PrintStream);
-    method public static void setLogWriter(java.io.PrintWriter);
-    method public static void setLoginTimeout(int);
-  }
-
-  public class DriverPropertyInfo {
-    ctor public DriverPropertyInfo(String, String);
-    field public String[] choices;
-    field public String description;
-    field public String name;
-    field public boolean required;
-    field public String value;
-  }
-
-  public interface NClob extends java.sql.Clob {
-  }
-
-  public interface ParameterMetaData extends java.sql.Wrapper {
-    method public String getParameterClassName(int) throws java.sql.SQLException;
-    method public int getParameterCount() throws java.sql.SQLException;
-    method public int getParameterMode(int) throws java.sql.SQLException;
-    method public int getParameterType(int) throws java.sql.SQLException;
-    method public String getParameterTypeName(int) throws java.sql.SQLException;
-    method public int getPrecision(int) throws java.sql.SQLException;
-    method public int getScale(int) throws java.sql.SQLException;
-    method public int isNullable(int) throws java.sql.SQLException;
-    method public boolean isSigned(int) throws java.sql.SQLException;
-    field public static final int parameterModeIn = 1; // 0x1
-    field public static final int parameterModeInOut = 2; // 0x2
-    field public static final int parameterModeOut = 4; // 0x4
-    field public static final int parameterModeUnknown = 0; // 0x0
-    field public static final int parameterNoNulls = 0; // 0x0
-    field public static final int parameterNullable = 1; // 0x1
-    field public static final int parameterNullableUnknown = 2; // 0x2
-  }
-
-  public interface PreparedStatement extends java.sql.Statement {
-    method public void addBatch() throws java.sql.SQLException;
-    method public void clearParameters() throws java.sql.SQLException;
-    method public boolean execute() throws java.sql.SQLException;
-    method public java.sql.ResultSet executeQuery() throws java.sql.SQLException;
-    method public int executeUpdate() throws java.sql.SQLException;
-    method public java.sql.ResultSetMetaData getMetaData() throws java.sql.SQLException;
-    method public java.sql.ParameterMetaData getParameterMetaData() throws java.sql.SQLException;
-    method public void setArray(int, java.sql.Array) throws java.sql.SQLException;
-    method public void setAsciiStream(int, java.io.InputStream, int) throws java.sql.SQLException;
-    method public void setAsciiStream(int, java.io.InputStream, long) throws java.sql.SQLException;
-    method public void setAsciiStream(int, java.io.InputStream) throws java.sql.SQLException;
-    method public void setBigDecimal(int, java.math.BigDecimal) throws java.sql.SQLException;
-    method public void setBinaryStream(int, java.io.InputStream, int) throws java.sql.SQLException;
-    method public void setBinaryStream(int, java.io.InputStream, long) throws java.sql.SQLException;
-    method public void setBinaryStream(int, java.io.InputStream) throws java.sql.SQLException;
-    method public void setBlob(int, java.sql.Blob) throws java.sql.SQLException;
-    method public void setBlob(int, java.io.InputStream, long) throws java.sql.SQLException;
-    method public void setBlob(int, java.io.InputStream) throws java.sql.SQLException;
-    method public void setBoolean(int, boolean) throws java.sql.SQLException;
-    method public void setByte(int, byte) throws java.sql.SQLException;
-    method public void setBytes(int, byte[]) throws java.sql.SQLException;
-    method public void setCharacterStream(int, java.io.Reader, int) throws java.sql.SQLException;
-    method public void setCharacterStream(int, java.io.Reader, long) throws java.sql.SQLException;
-    method public void setCharacterStream(int, java.io.Reader) throws java.sql.SQLException;
-    method public void setClob(int, java.sql.Clob) throws java.sql.SQLException;
-    method public void setClob(int, java.io.Reader, long) throws java.sql.SQLException;
-    method public void setClob(int, java.io.Reader) throws java.sql.SQLException;
-    method public void setDate(int, java.sql.Date) throws java.sql.SQLException;
-    method public void setDate(int, java.sql.Date, java.util.Calendar) throws java.sql.SQLException;
-    method public void setDouble(int, double) throws java.sql.SQLException;
-    method public void setFloat(int, float) throws java.sql.SQLException;
-    method public void setInt(int, int) throws java.sql.SQLException;
-    method public void setLong(int, long) throws java.sql.SQLException;
-    method public void setNCharacterStream(int, java.io.Reader, long) throws java.sql.SQLException;
-    method public void setNCharacterStream(int, java.io.Reader) throws java.sql.SQLException;
-    method public void setNClob(int, java.sql.NClob) throws java.sql.SQLException;
-    method public void setNClob(int, java.io.Reader, long) throws java.sql.SQLException;
-    method public void setNClob(int, java.io.Reader) throws java.sql.SQLException;
-    method public void setNString(int, String) throws java.sql.SQLException;
-    method public void setNull(int, int) throws java.sql.SQLException;
-    method public void setNull(int, int, String) throws java.sql.SQLException;
-    method public void setObject(int, Object, int) throws java.sql.SQLException;
-    method public void setObject(int, Object) throws java.sql.SQLException;
-    method public void setObject(int, Object, int, int) throws java.sql.SQLException;
-    method public void setRef(int, java.sql.Ref) throws java.sql.SQLException;
-    method public void setRowId(int, java.sql.RowId) throws java.sql.SQLException;
-    method public void setSQLXML(int, java.sql.SQLXML) throws java.sql.SQLException;
-    method public void setShort(int, short) throws java.sql.SQLException;
-    method public void setString(int, String) throws java.sql.SQLException;
-    method public void setTime(int, java.sql.Time) throws java.sql.SQLException;
-    method public void setTime(int, java.sql.Time, java.util.Calendar) throws java.sql.SQLException;
-    method public void setTimestamp(int, java.sql.Timestamp) throws java.sql.SQLException;
-    method public void setTimestamp(int, java.sql.Timestamp, java.util.Calendar) throws java.sql.SQLException;
-    method public void setURL(int, java.net.URL) throws java.sql.SQLException;
-    method @Deprecated public void setUnicodeStream(int, java.io.InputStream, int) throws java.sql.SQLException;
-  }
-
-  public interface Ref {
-    method public String getBaseTypeName() throws java.sql.SQLException;
-    method public Object getObject(java.util.Map<java.lang.String,java.lang.Class<?>>) throws java.sql.SQLException;
-    method public Object getObject() throws java.sql.SQLException;
-    method public void setObject(Object) throws java.sql.SQLException;
-  }
-
-  public interface ResultSet extends java.sql.Wrapper java.lang.AutoCloseable {
-    method public boolean absolute(int) throws java.sql.SQLException;
-    method public void afterLast() throws java.sql.SQLException;
-    method public void beforeFirst() throws java.sql.SQLException;
-    method public void cancelRowUpdates() throws java.sql.SQLException;
-    method public void clearWarnings() throws java.sql.SQLException;
-    method public void close() throws java.sql.SQLException;
-    method public void deleteRow() throws java.sql.SQLException;
-    method public int findColumn(String) throws java.sql.SQLException;
-    method public boolean first() throws java.sql.SQLException;
-    method public java.sql.Array getArray(int) throws java.sql.SQLException;
-    method public java.sql.Array getArray(String) throws java.sql.SQLException;
-    method public java.io.InputStream getAsciiStream(int) throws java.sql.SQLException;
-    method public java.io.InputStream getAsciiStream(String) throws java.sql.SQLException;
-    method @Deprecated public java.math.BigDecimal getBigDecimal(int, int) throws java.sql.SQLException;
-    method @Deprecated public java.math.BigDecimal getBigDecimal(String, int) throws java.sql.SQLException;
-    method public java.math.BigDecimal getBigDecimal(int) throws java.sql.SQLException;
-    method public java.math.BigDecimal getBigDecimal(String) throws java.sql.SQLException;
-    method public java.io.InputStream getBinaryStream(int) throws java.sql.SQLException;
-    method public java.io.InputStream getBinaryStream(String) throws java.sql.SQLException;
-    method public java.sql.Blob getBlob(int) throws java.sql.SQLException;
-    method public java.sql.Blob getBlob(String) throws java.sql.SQLException;
-    method public boolean getBoolean(int) throws java.sql.SQLException;
-    method public boolean getBoolean(String) throws java.sql.SQLException;
-    method public byte getByte(int) throws java.sql.SQLException;
-    method public byte getByte(String) throws java.sql.SQLException;
-    method public byte[] getBytes(int) throws java.sql.SQLException;
-    method public byte[] getBytes(String) throws java.sql.SQLException;
-    method public java.io.Reader getCharacterStream(int) throws java.sql.SQLException;
-    method public java.io.Reader getCharacterStream(String) throws java.sql.SQLException;
-    method public java.sql.Clob getClob(int) throws java.sql.SQLException;
-    method public java.sql.Clob getClob(String) throws java.sql.SQLException;
-    method public int getConcurrency() throws java.sql.SQLException;
-    method public String getCursorName() throws java.sql.SQLException;
-    method public java.sql.Date getDate(int) throws java.sql.SQLException;
-    method public java.sql.Date getDate(String) throws java.sql.SQLException;
-    method public java.sql.Date getDate(int, java.util.Calendar) throws java.sql.SQLException;
-    method public java.sql.Date getDate(String, java.util.Calendar) throws java.sql.SQLException;
-    method public double getDouble(int) throws java.sql.SQLException;
-    method public double getDouble(String) throws java.sql.SQLException;
-    method public int getFetchDirection() throws java.sql.SQLException;
-    method public int getFetchSize() throws java.sql.SQLException;
-    method public float getFloat(int) throws java.sql.SQLException;
-    method public float getFloat(String) throws java.sql.SQLException;
-    method public int getHoldability() throws java.sql.SQLException;
-    method public int getInt(int) throws java.sql.SQLException;
-    method public int getInt(String) throws java.sql.SQLException;
-    method public long getLong(int) throws java.sql.SQLException;
-    method public long getLong(String) throws java.sql.SQLException;
-    method public java.sql.ResultSetMetaData getMetaData() throws java.sql.SQLException;
-    method public java.io.Reader getNCharacterStream(int) throws java.sql.SQLException;
-    method public java.io.Reader getNCharacterStream(String) throws java.sql.SQLException;
-    method public java.sql.NClob getNClob(int) throws java.sql.SQLException;
-    method public java.sql.NClob getNClob(String) throws java.sql.SQLException;
-    method public String getNString(int) throws java.sql.SQLException;
-    method public String getNString(String) throws java.sql.SQLException;
-    method public Object getObject(int) throws java.sql.SQLException;
-    method public Object getObject(String) throws java.sql.SQLException;
-    method public Object getObject(int, java.util.Map<java.lang.String,java.lang.Class<?>>) throws java.sql.SQLException;
-    method public Object getObject(String, java.util.Map<java.lang.String,java.lang.Class<?>>) throws java.sql.SQLException;
-    method public java.sql.Ref getRef(int) throws java.sql.SQLException;
-    method public java.sql.Ref getRef(String) throws java.sql.SQLException;
-    method public int getRow() throws java.sql.SQLException;
-    method public java.sql.RowId getRowId(int) throws java.sql.SQLException;
-    method public java.sql.RowId getRowId(String) throws java.sql.SQLException;
-    method public java.sql.SQLXML getSQLXML(int) throws java.sql.SQLException;
-    method public java.sql.SQLXML getSQLXML(String) throws java.sql.SQLException;
-    method public short getShort(int) throws java.sql.SQLException;
-    method public short getShort(String) throws java.sql.SQLException;
-    method public java.sql.Statement getStatement() throws java.sql.SQLException;
-    method public String getString(int) throws java.sql.SQLException;
-    method public String getString(String) throws java.sql.SQLException;
-    method public java.sql.Time getTime(int) throws java.sql.SQLException;
-    method public java.sql.Time getTime(String) throws java.sql.SQLException;
-    method public java.sql.Time getTime(int, java.util.Calendar) throws java.sql.SQLException;
-    method public java.sql.Time getTime(String, java.util.Calendar) throws java.sql.SQLException;
-    method public java.sql.Timestamp getTimestamp(int) throws java.sql.SQLException;
-    method public java.sql.Timestamp getTimestamp(String) throws java.sql.SQLException;
-    method public java.sql.Timestamp getTimestamp(int, java.util.Calendar) throws java.sql.SQLException;
-    method public java.sql.Timestamp getTimestamp(String, java.util.Calendar) throws java.sql.SQLException;
-    method public int getType() throws java.sql.SQLException;
-    method public java.net.URL getURL(int) throws java.sql.SQLException;
-    method public java.net.URL getURL(String) throws java.sql.SQLException;
-    method @Deprecated public java.io.InputStream getUnicodeStream(int) throws java.sql.SQLException;
-    method @Deprecated public java.io.InputStream getUnicodeStream(String) throws java.sql.SQLException;
-    method public java.sql.SQLWarning getWarnings() throws java.sql.SQLException;
-    method public void insertRow() throws java.sql.SQLException;
-    method public boolean isAfterLast() throws java.sql.SQLException;
-    method public boolean isBeforeFirst() throws java.sql.SQLException;
-    method public boolean isClosed() throws java.sql.SQLException;
-    method public boolean isFirst() throws java.sql.SQLException;
-    method public boolean isLast() throws java.sql.SQLException;
-    method public boolean last() throws java.sql.SQLException;
-    method public void moveToCurrentRow() throws java.sql.SQLException;
-    method public void moveToInsertRow() throws java.sql.SQLException;
-    method public boolean next() throws java.sql.SQLException;
-    method public boolean previous() throws java.sql.SQLException;
-    method public void refreshRow() throws java.sql.SQLException;
-    method public boolean relative(int) throws java.sql.SQLException;
-    method public boolean rowDeleted() throws java.sql.SQLException;
-    method public boolean rowInserted() throws java.sql.SQLException;
-    method public boolean rowUpdated() throws java.sql.SQLException;
-    method public void setFetchDirection(int) throws java.sql.SQLException;
-    method public void setFetchSize(int) throws java.sql.SQLException;
-    method public void updateArray(int, java.sql.Array) throws java.sql.SQLException;
-    method public void updateArray(String, java.sql.Array) throws java.sql.SQLException;
-    method public void updateAsciiStream(int, java.io.InputStream, int) throws java.sql.SQLException;
-    method public void updateAsciiStream(String, java.io.InputStream, int) throws java.sql.SQLException;
-    method public void updateAsciiStream(int, java.io.InputStream, long) throws java.sql.SQLException;
-    method public void updateAsciiStream(String, java.io.InputStream, long) throws java.sql.SQLException;
-    method public void updateAsciiStream(int, java.io.InputStream) throws java.sql.SQLException;
-    method public void updateAsciiStream(String, java.io.InputStream) throws java.sql.SQLException;
-    method public void updateBigDecimal(int, java.math.BigDecimal) throws java.sql.SQLException;
-    method public void updateBigDecimal(String, java.math.BigDecimal) throws java.sql.SQLException;
-    method public void updateBinaryStream(int, java.io.InputStream, int) throws java.sql.SQLException;
-    method public void updateBinaryStream(String, java.io.InputStream, int) throws java.sql.SQLException;
-    method public void updateBinaryStream(int, java.io.InputStream, long) throws java.sql.SQLException;
-    method public void updateBinaryStream(String, java.io.InputStream, long) throws java.sql.SQLException;
-    method public void updateBinaryStream(int, java.io.InputStream) throws java.sql.SQLException;
-    method public void updateBinaryStream(String, java.io.InputStream) throws java.sql.SQLException;
-    method public void updateBlob(int, java.sql.Blob) throws java.sql.SQLException;
-    method public void updateBlob(String, java.sql.Blob) throws java.sql.SQLException;
-    method public void updateBlob(int, java.io.InputStream, long) throws java.sql.SQLException;
-    method public void updateBlob(String, java.io.InputStream, long) throws java.sql.SQLException;
-    method public void updateBlob(int, java.io.InputStream) throws java.sql.SQLException;
-    method public void updateBlob(String, java.io.InputStream) throws java.sql.SQLException;
-    method public void updateBoolean(int, boolean) throws java.sql.SQLException;
-    method public void updateBoolean(String, boolean) throws java.sql.SQLException;
-    method public void updateByte(int, byte) throws java.sql.SQLException;
-    method public void updateByte(String, byte) throws java.sql.SQLException;
-    method public void updateBytes(int, byte[]) throws java.sql.SQLException;
-    method public void updateBytes(String, byte[]) throws java.sql.SQLException;
-    method public void updateCharacterStream(int, java.io.Reader, int) throws java.sql.SQLException;
-    method public void updateCharacterStream(String, java.io.Reader, int) throws java.sql.SQLException;
-    method public void updateCharacterStream(int, java.io.Reader, long) throws java.sql.SQLException;
-    method public void updateCharacterStream(String, java.io.Reader, long) throws java.sql.SQLException;
-    method public void updateCharacterStream(int, java.io.Reader) throws java.sql.SQLException;
-    method public void updateCharacterStream(String, java.io.Reader) throws java.sql.SQLException;
-    method public void updateClob(int, java.sql.Clob) throws java.sql.SQLException;
-    method public void updateClob(String, java.sql.Clob) throws java.sql.SQLException;
-    method public void updateClob(int, java.io.Reader, long) throws java.sql.SQLException;
-    method public void updateClob(String, java.io.Reader, long) throws java.sql.SQLException;
-    method public void updateClob(int, java.io.Reader) throws java.sql.SQLException;
-    method public void updateClob(String, java.io.Reader) throws java.sql.SQLException;
-    method public void updateDate(int, java.sql.Date) throws java.sql.SQLException;
-    method public void updateDate(String, java.sql.Date) throws java.sql.SQLException;
-    method public void updateDouble(int, double) throws java.sql.SQLException;
-    method public void updateDouble(String, double) throws java.sql.SQLException;
-    method public void updateFloat(int, float) throws java.sql.SQLException;
-    method public void updateFloat(String, float) throws java.sql.SQLException;
-    method public void updateInt(int, int) throws java.sql.SQLException;
-    method public void updateInt(String, int) throws java.sql.SQLException;
-    method public void updateLong(int, long) throws java.sql.SQLException;
-    method public void updateLong(String, long) throws java.sql.SQLException;
-    method public void updateNCharacterStream(int, java.io.Reader, long) throws java.sql.SQLException;
-    method public void updateNCharacterStream(String, java.io.Reader, long) throws java.sql.SQLException;
-    method public void updateNCharacterStream(int, java.io.Reader) throws java.sql.SQLException;
-    method public void updateNCharacterStream(String, java.io.Reader) throws java.sql.SQLException;
-    method public void updateNClob(int, java.sql.NClob) throws java.sql.SQLException;
-    method public void updateNClob(String, java.sql.NClob) throws java.sql.SQLException;
-    method public void updateNClob(int, java.io.Reader, long) throws java.sql.SQLException;
-    method public void updateNClob(String, java.io.Reader, long) throws java.sql.SQLException;
-    method public void updateNClob(int, java.io.Reader) throws java.sql.SQLException;
-    method public void updateNClob(String, java.io.Reader) throws java.sql.SQLException;
-    method public void updateNString(int, String) throws java.sql.SQLException;
-    method public void updateNString(String, String) throws java.sql.SQLException;
-    method public void updateNull(int) throws java.sql.SQLException;
-    method public void updateNull(String) throws java.sql.SQLException;
-    method public void updateObject(int, Object, int) throws java.sql.SQLException;
-    method public void updateObject(int, Object) throws java.sql.SQLException;
-    method public void updateObject(String, Object, int) throws java.sql.SQLException;
-    method public void updateObject(String, Object) throws java.sql.SQLException;
-    method public void updateRef(int, java.sql.Ref) throws java.sql.SQLException;
-    method public void updateRef(String, java.sql.Ref) throws java.sql.SQLException;
-    method public void updateRow() throws java.sql.SQLException;
-    method public void updateRowId(int, java.sql.RowId) throws java.sql.SQLException;
-    method public void updateRowId(String, java.sql.RowId) throws java.sql.SQLException;
-    method public void updateSQLXML(int, java.sql.SQLXML) throws java.sql.SQLException;
-    method public void updateSQLXML(String, java.sql.SQLXML) throws java.sql.SQLException;
-    method public void updateShort(int, short) throws java.sql.SQLException;
-    method public void updateShort(String, short) throws java.sql.SQLException;
-    method public void updateString(int, String) throws java.sql.SQLException;
-    method public void updateString(String, String) throws java.sql.SQLException;
-    method public void updateTime(int, java.sql.Time) throws java.sql.SQLException;
-    method public void updateTime(String, java.sql.Time) throws java.sql.SQLException;
-    method public void updateTimestamp(int, java.sql.Timestamp) throws java.sql.SQLException;
-    method public void updateTimestamp(String, java.sql.Timestamp) throws java.sql.SQLException;
-    method public boolean wasNull() throws java.sql.SQLException;
-    field public static final int CLOSE_CURSORS_AT_COMMIT = 2; // 0x2
-    field public static final int CONCUR_READ_ONLY = 1007; // 0x3ef
-    field public static final int CONCUR_UPDATABLE = 1008; // 0x3f0
-    field public static final int FETCH_FORWARD = 1000; // 0x3e8
-    field public static final int FETCH_REVERSE = 1001; // 0x3e9
-    field public static final int FETCH_UNKNOWN = 1002; // 0x3ea
-    field public static final int HOLD_CURSORS_OVER_COMMIT = 1; // 0x1
-    field public static final int TYPE_FORWARD_ONLY = 1003; // 0x3eb
-    field public static final int TYPE_SCROLL_INSENSITIVE = 1004; // 0x3ec
-    field public static final int TYPE_SCROLL_SENSITIVE = 1005; // 0x3ed
-  }
-
-  public interface ResultSetMetaData extends java.sql.Wrapper {
-    method public String getCatalogName(int) throws java.sql.SQLException;
-    method public String getColumnClassName(int) throws java.sql.SQLException;
-    method public int getColumnCount() throws java.sql.SQLException;
-    method public int getColumnDisplaySize(int) throws java.sql.SQLException;
-    method public String getColumnLabel(int) throws java.sql.SQLException;
-    method public String getColumnName(int) throws java.sql.SQLException;
-    method public int getColumnType(int) throws java.sql.SQLException;
-    method public String getColumnTypeName(int) throws java.sql.SQLException;
-    method public int getPrecision(int) throws java.sql.SQLException;
-    method public int getScale(int) throws java.sql.SQLException;
-    method public String getSchemaName(int) throws java.sql.SQLException;
-    method public String getTableName(int) throws java.sql.SQLException;
-    method public boolean isAutoIncrement(int) throws java.sql.SQLException;
-    method public boolean isCaseSensitive(int) throws java.sql.SQLException;
-    method public boolean isCurrency(int) throws java.sql.SQLException;
-    method public boolean isDefinitelyWritable(int) throws java.sql.SQLException;
-    method public int isNullable(int) throws java.sql.SQLException;
-    method public boolean isReadOnly(int) throws java.sql.SQLException;
-    method public boolean isSearchable(int) throws java.sql.SQLException;
-    method public boolean isSigned(int) throws java.sql.SQLException;
-    method public boolean isWritable(int) throws java.sql.SQLException;
-    field public static final int columnNoNulls = 0; // 0x0
-    field public static final int columnNullable = 1; // 0x1
-    field public static final int columnNullableUnknown = 2; // 0x2
-  }
-
-  public interface RowId {
-    method public boolean equals(Object);
-    method public byte[] getBytes();
-    method public int hashCode();
-    method public String toString();
-  }
-
-  public enum RowIdLifetime {
-    enum_constant public static final java.sql.RowIdLifetime ROWID_UNSUPPORTED;
-    enum_constant public static final java.sql.RowIdLifetime ROWID_VALID_FOREVER;
-    enum_constant public static final java.sql.RowIdLifetime ROWID_VALID_OTHER;
-    enum_constant public static final java.sql.RowIdLifetime ROWID_VALID_SESSION;
-    enum_constant public static final java.sql.RowIdLifetime ROWID_VALID_TRANSACTION;
-  }
-
-  public class SQLClientInfoException extends java.sql.SQLException {
-    ctor public SQLClientInfoException();
-    ctor public SQLClientInfoException(java.util.Map<java.lang.String,java.sql.ClientInfoStatus>);
-    ctor public SQLClientInfoException(java.util.Map<java.lang.String,java.sql.ClientInfoStatus>, Throwable);
-    ctor public SQLClientInfoException(String, java.util.Map<java.lang.String,java.sql.ClientInfoStatus>);
-    ctor public SQLClientInfoException(String, java.util.Map<java.lang.String,java.sql.ClientInfoStatus>, Throwable);
-    ctor public SQLClientInfoException(String, String, java.util.Map<java.lang.String,java.sql.ClientInfoStatus>);
-    ctor public SQLClientInfoException(String, String, java.util.Map<java.lang.String,java.sql.ClientInfoStatus>, Throwable);
-    ctor public SQLClientInfoException(String, String, int, java.util.Map<java.lang.String,java.sql.ClientInfoStatus>);
-    ctor public SQLClientInfoException(String, String, int, java.util.Map<java.lang.String,java.sql.ClientInfoStatus>, Throwable);
-    method public java.util.Map<java.lang.String,java.sql.ClientInfoStatus> getFailedProperties();
-  }
-
-  public interface SQLData {
-    method public String getSQLTypeName() throws java.sql.SQLException;
-    method public void readSQL(java.sql.SQLInput, String) throws java.sql.SQLException;
-    method public void writeSQL(java.sql.SQLOutput) throws java.sql.SQLException;
-  }
-
-  public class SQLDataException extends java.sql.SQLNonTransientException {
-    ctor public SQLDataException();
-    ctor public SQLDataException(String);
-    ctor public SQLDataException(String, String);
-    ctor public SQLDataException(String, String, int);
-    ctor public SQLDataException(Throwable);
-    ctor public SQLDataException(String, Throwable);
-    ctor public SQLDataException(String, String, Throwable);
-    ctor public SQLDataException(String, String, int, Throwable);
-  }
-
-  public class SQLException extends java.lang.Exception implements java.lang.Iterable<java.lang.Throwable> {
-    ctor public SQLException(String, String, int);
-    ctor public SQLException(String, String);
-    ctor public SQLException(String);
-    ctor public SQLException();
-    ctor public SQLException(Throwable);
-    ctor public SQLException(String, Throwable);
-    ctor public SQLException(String, String, Throwable);
-    ctor public SQLException(String, String, int, Throwable);
-    method public int getErrorCode();
-    method public java.sql.SQLException getNextException();
-    method public String getSQLState();
-    method public java.util.Iterator<java.lang.Throwable> iterator();
-    method public void setNextException(java.sql.SQLException);
-  }
-
-  public class SQLFeatureNotSupportedException extends java.sql.SQLNonTransientException {
-    ctor public SQLFeatureNotSupportedException();
-    ctor public SQLFeatureNotSupportedException(String);
-    ctor public SQLFeatureNotSupportedException(String, String);
-    ctor public SQLFeatureNotSupportedException(String, String, int);
-    ctor public SQLFeatureNotSupportedException(Throwable);
-    ctor public SQLFeatureNotSupportedException(String, Throwable);
-    ctor public SQLFeatureNotSupportedException(String, String, Throwable);
-    ctor public SQLFeatureNotSupportedException(String, String, int, Throwable);
-  }
-
-  public interface SQLInput {
-    method public java.sql.Array readArray() throws java.sql.SQLException;
-    method public java.io.InputStream readAsciiStream() throws java.sql.SQLException;
-    method public java.math.BigDecimal readBigDecimal() throws java.sql.SQLException;
-    method public java.io.InputStream readBinaryStream() throws java.sql.SQLException;
-    method public java.sql.Blob readBlob() throws java.sql.SQLException;
-    method public boolean readBoolean() throws java.sql.SQLException;
-    method public byte readByte() throws java.sql.SQLException;
-    method public byte[] readBytes() throws java.sql.SQLException;
-    method public java.io.Reader readCharacterStream() throws java.sql.SQLException;
-    method public java.sql.Clob readClob() throws java.sql.SQLException;
-    method public java.sql.Date readDate() throws java.sql.SQLException;
-    method public double readDouble() throws java.sql.SQLException;
-    method public float readFloat() throws java.sql.SQLException;
-    method public int readInt() throws java.sql.SQLException;
-    method public long readLong() throws java.sql.SQLException;
-    method public java.sql.NClob readNClob() throws java.sql.SQLException;
-    method public String readNString() throws java.sql.SQLException;
-    method public Object readObject() throws java.sql.SQLException;
-    method public java.sql.Ref readRef() throws java.sql.SQLException;
-    method public java.sql.RowId readRowId() throws java.sql.SQLException;
-    method public java.sql.SQLXML readSQLXML() throws java.sql.SQLException;
-    method public short readShort() throws java.sql.SQLException;
-    method public String readString() throws java.sql.SQLException;
-    method public java.sql.Time readTime() throws java.sql.SQLException;
-    method public java.sql.Timestamp readTimestamp() throws java.sql.SQLException;
-    method public java.net.URL readURL() throws java.sql.SQLException;
-    method public boolean wasNull() throws java.sql.SQLException;
-  }
-
-  public class SQLIntegrityConstraintViolationException extends java.sql.SQLNonTransientException {
-    ctor public SQLIntegrityConstraintViolationException();
-    ctor public SQLIntegrityConstraintViolationException(String);
-    ctor public SQLIntegrityConstraintViolationException(String, String);
-    ctor public SQLIntegrityConstraintViolationException(String, String, int);
-    ctor public SQLIntegrityConstraintViolationException(Throwable);
-    ctor public SQLIntegrityConstraintViolationException(String, Throwable);
-    ctor public SQLIntegrityConstraintViolationException(String, String, Throwable);
-    ctor public SQLIntegrityConstraintViolationException(String, String, int, Throwable);
-  }
-
-  public class SQLInvalidAuthorizationSpecException extends java.sql.SQLNonTransientException {
-    ctor public SQLInvalidAuthorizationSpecException();
-    ctor public SQLInvalidAuthorizationSpecException(String);
-    ctor public SQLInvalidAuthorizationSpecException(String, String);
-    ctor public SQLInvalidAuthorizationSpecException(String, String, int);
-    ctor public SQLInvalidAuthorizationSpecException(Throwable);
-    ctor public SQLInvalidAuthorizationSpecException(String, Throwable);
-    ctor public SQLInvalidAuthorizationSpecException(String, String, Throwable);
-    ctor public SQLInvalidAuthorizationSpecException(String, String, int, Throwable);
-  }
-
-  public class SQLNonTransientConnectionException extends java.sql.SQLNonTransientException {
-    ctor public SQLNonTransientConnectionException();
-    ctor public SQLNonTransientConnectionException(String);
-    ctor public SQLNonTransientConnectionException(String, String);
-    ctor public SQLNonTransientConnectionException(String, String, int);
-    ctor public SQLNonTransientConnectionException(Throwable);
-    ctor public SQLNonTransientConnectionException(String, Throwable);
-    ctor public SQLNonTransientConnectionException(String, String, Throwable);
-    ctor public SQLNonTransientConnectionException(String, String, int, Throwable);
-  }
-
-  public class SQLNonTransientException extends java.sql.SQLException {
-    ctor public SQLNonTransientException();
-    ctor public SQLNonTransientException(String);
-    ctor public SQLNonTransientException(String, String);
-    ctor public SQLNonTransientException(String, String, int);
-    ctor public SQLNonTransientException(Throwable);
-    ctor public SQLNonTransientException(String, Throwable);
-    ctor public SQLNonTransientException(String, String, Throwable);
-    ctor public SQLNonTransientException(String, String, int, Throwable);
-  }
-
-  public interface SQLOutput {
-    method public void writeArray(java.sql.Array) throws java.sql.SQLException;
-    method public void writeAsciiStream(java.io.InputStream) throws java.sql.SQLException;
-    method public void writeBigDecimal(java.math.BigDecimal) throws java.sql.SQLException;
-    method public void writeBinaryStream(java.io.InputStream) throws java.sql.SQLException;
-    method public void writeBlob(java.sql.Blob) throws java.sql.SQLException;
-    method public void writeBoolean(boolean) throws java.sql.SQLException;
-    method public void writeByte(byte) throws java.sql.SQLException;
-    method public void writeBytes(byte[]) throws java.sql.SQLException;
-    method public void writeCharacterStream(java.io.Reader) throws java.sql.SQLException;
-    method public void writeClob(java.sql.Clob) throws java.sql.SQLException;
-    method public void writeDate(java.sql.Date) throws java.sql.SQLException;
-    method public void writeDouble(double) throws java.sql.SQLException;
-    method public void writeFloat(float) throws java.sql.SQLException;
-    method public void writeInt(int) throws java.sql.SQLException;
-    method public void writeLong(long) throws java.sql.SQLException;
-    method public void writeNClob(java.sql.NClob) throws java.sql.SQLException;
-    method public void writeNString(String) throws java.sql.SQLException;
-    method public void writeObject(java.sql.SQLData) throws java.sql.SQLException;
-    method public void writeRef(java.sql.Ref) throws java.sql.SQLException;
-    method public void writeRowId(java.sql.RowId) throws java.sql.SQLException;
-    method public void writeSQLXML(java.sql.SQLXML) throws java.sql.SQLException;
-    method public void writeShort(short) throws java.sql.SQLException;
-    method public void writeString(String) throws java.sql.SQLException;
-    method public void writeStruct(java.sql.Struct) throws java.sql.SQLException;
-    method public void writeTime(java.sql.Time) throws java.sql.SQLException;
-    method public void writeTimestamp(java.sql.Timestamp) throws java.sql.SQLException;
-    method public void writeURL(java.net.URL) throws java.sql.SQLException;
-  }
-
-  public final class SQLPermission extends java.security.BasicPermission {
-    ctor public SQLPermission(String);
-    ctor public SQLPermission(String, String);
-  }
-
-  public class SQLRecoverableException extends java.sql.SQLException {
-    ctor public SQLRecoverableException();
-    ctor public SQLRecoverableException(String);
-    ctor public SQLRecoverableException(String, String);
-    ctor public SQLRecoverableException(String, String, int);
-    ctor public SQLRecoverableException(Throwable);
-    ctor public SQLRecoverableException(String, Throwable);
-    ctor public SQLRecoverableException(String, String, Throwable);
-    ctor public SQLRecoverableException(String, String, int, Throwable);
-  }
-
-  public class SQLSyntaxErrorException extends java.sql.SQLNonTransientException {
-    ctor public SQLSyntaxErrorException();
-    ctor public SQLSyntaxErrorException(String);
-    ctor public SQLSyntaxErrorException(String, String);
-    ctor public SQLSyntaxErrorException(String, String, int);
-    ctor public SQLSyntaxErrorException(Throwable);
-    ctor public SQLSyntaxErrorException(String, Throwable);
-    ctor public SQLSyntaxErrorException(String, String, Throwable);
-    ctor public SQLSyntaxErrorException(String, String, int, Throwable);
-  }
-
-  public class SQLTimeoutException extends java.sql.SQLTransientException {
-    ctor public SQLTimeoutException();
-    ctor public SQLTimeoutException(String);
-    ctor public SQLTimeoutException(String, String);
-    ctor public SQLTimeoutException(String, String, int);
-    ctor public SQLTimeoutException(Throwable);
-    ctor public SQLTimeoutException(String, Throwable);
-    ctor public SQLTimeoutException(String, String, Throwable);
-    ctor public SQLTimeoutException(String, String, int, Throwable);
-  }
-
-  public class SQLTransactionRollbackException extends java.sql.SQLTransientException {
-    ctor public SQLTransactionRollbackException();
-    ctor public SQLTransactionRollbackException(String);
-    ctor public SQLTransactionRollbackException(String, String);
-    ctor public SQLTransactionRollbackException(String, String, int);
-    ctor public SQLTransactionRollbackException(Throwable);
-    ctor public SQLTransactionRollbackException(String, Throwable);
-    ctor public SQLTransactionRollbackException(String, String, Throwable);
-    ctor public SQLTransactionRollbackException(String, String, int, Throwable);
-  }
-
-  public class SQLTransientConnectionException extends java.sql.SQLTransientException {
-    ctor public SQLTransientConnectionException();
-    ctor public SQLTransientConnectionException(String);
-    ctor public SQLTransientConnectionException(String, String);
-    ctor public SQLTransientConnectionException(String, String, int);
-    ctor public SQLTransientConnectionException(Throwable);
-    ctor public SQLTransientConnectionException(String, Throwable);
-    ctor public SQLTransientConnectionException(String, String, Throwable);
-    ctor public SQLTransientConnectionException(String, String, int, Throwable);
-  }
-
-  public class SQLTransientException extends java.sql.SQLException {
-    ctor public SQLTransientException();
-    ctor public SQLTransientException(String);
-    ctor public SQLTransientException(String, String);
-    ctor public SQLTransientException(String, String, int);
-    ctor public SQLTransientException(Throwable);
-    ctor public SQLTransientException(String, Throwable);
-    ctor public SQLTransientException(String, String, Throwable);
-    ctor public SQLTransientException(String, String, int, Throwable);
-  }
-
-  public class SQLWarning extends java.sql.SQLException {
-    ctor public SQLWarning(String, String, int);
-    ctor public SQLWarning(String, String);
-    ctor public SQLWarning(String);
-    ctor public SQLWarning();
-    ctor public SQLWarning(Throwable);
-    ctor public SQLWarning(String, Throwable);
-    ctor public SQLWarning(String, String, Throwable);
-    ctor public SQLWarning(String, String, int, Throwable);
-    method public java.sql.SQLWarning getNextWarning();
-    method public void setNextWarning(java.sql.SQLWarning);
-  }
-
-  public interface SQLXML {
-    method public void free() throws java.sql.SQLException;
-    method public java.io.InputStream getBinaryStream() throws java.sql.SQLException;
-    method public java.io.Reader getCharacterStream() throws java.sql.SQLException;
-    method public <T extends javax.xml.transform.Source> T getSource(Class<T>) throws java.sql.SQLException;
-    method public String getString() throws java.sql.SQLException;
-    method public java.io.OutputStream setBinaryStream() throws java.sql.SQLException;
-    method public java.io.Writer setCharacterStream() throws java.sql.SQLException;
-    method public <T extends javax.xml.transform.Result> T setResult(Class<T>) throws java.sql.SQLException;
-    method public void setString(String) throws java.sql.SQLException;
-  }
-
-  public interface Savepoint {
-    method public int getSavepointId() throws java.sql.SQLException;
-    method public String getSavepointName() throws java.sql.SQLException;
-  }
-
-  public interface Statement extends java.sql.Wrapper java.lang.AutoCloseable {
-    method public void addBatch(String) throws java.sql.SQLException;
-    method public void cancel() throws java.sql.SQLException;
-    method public void clearBatch() throws java.sql.SQLException;
-    method public void clearWarnings() throws java.sql.SQLException;
-    method public void close() throws java.sql.SQLException;
-    method public boolean execute(String) throws java.sql.SQLException;
-    method public boolean execute(String, int) throws java.sql.SQLException;
-    method public boolean execute(String, int[]) throws java.sql.SQLException;
-    method public boolean execute(String, String[]) throws java.sql.SQLException;
-    method public int[] executeBatch() throws java.sql.SQLException;
-    method public java.sql.ResultSet executeQuery(String) throws java.sql.SQLException;
-    method public int executeUpdate(String) throws java.sql.SQLException;
-    method public int executeUpdate(String, int) throws java.sql.SQLException;
-    method public int executeUpdate(String, int[]) throws java.sql.SQLException;
-    method public int executeUpdate(String, String[]) throws java.sql.SQLException;
-    method public java.sql.Connection getConnection() throws java.sql.SQLException;
-    method public int getFetchDirection() throws java.sql.SQLException;
-    method public int getFetchSize() throws java.sql.SQLException;
-    method public java.sql.ResultSet getGeneratedKeys() throws java.sql.SQLException;
-    method public int getMaxFieldSize() throws java.sql.SQLException;
-    method public int getMaxRows() throws java.sql.SQLException;
-    method public boolean getMoreResults() throws java.sql.SQLException;
-    method public boolean getMoreResults(int) throws java.sql.SQLException;
-    method public int getQueryTimeout() throws java.sql.SQLException;
-    method public java.sql.ResultSet getResultSet() throws java.sql.SQLException;
-    method public int getResultSetConcurrency() throws java.sql.SQLException;
-    method public int getResultSetHoldability() throws java.sql.SQLException;
-    method public int getResultSetType() throws java.sql.SQLException;
-    method public int getUpdateCount() throws java.sql.SQLException;
-    method public java.sql.SQLWarning getWarnings() throws java.sql.SQLException;
-    method public boolean isClosed() throws java.sql.SQLException;
-    method public boolean isPoolable() throws java.sql.SQLException;
-    method public void setCursorName(String) throws java.sql.SQLException;
-    method public void setEscapeProcessing(boolean) throws java.sql.SQLException;
-    method public void setFetchDirection(int) throws java.sql.SQLException;
-    method public void setFetchSize(int) throws java.sql.SQLException;
-    method public void setMaxFieldSize(int) throws java.sql.SQLException;
-    method public void setMaxRows(int) throws java.sql.SQLException;
-    method public void setPoolable(boolean) throws java.sql.SQLException;
-    method public void setQueryTimeout(int) throws java.sql.SQLException;
-    field public static final int CLOSE_ALL_RESULTS = 3; // 0x3
-    field public static final int CLOSE_CURRENT_RESULT = 1; // 0x1
-    field public static final int EXECUTE_FAILED = -3; // 0xfffffffd
-    field public static final int KEEP_CURRENT_RESULT = 2; // 0x2
-    field public static final int NO_GENERATED_KEYS = 2; // 0x2
-    field public static final int RETURN_GENERATED_KEYS = 1; // 0x1
-    field public static final int SUCCESS_NO_INFO = -2; // 0xfffffffe
-  }
-
-  public interface Struct {
-    method public Object[] getAttributes() throws java.sql.SQLException;
-    method public Object[] getAttributes(java.util.Map<java.lang.String,java.lang.Class<?>>) throws java.sql.SQLException;
-    method public String getSQLTypeName() throws java.sql.SQLException;
-  }
-
-  public class Time extends java.util.Date {
-    ctor @Deprecated public Time(int, int, int);
-    ctor public Time(long);
-    method public static java.sql.Time valueOf(String);
-  }
-
-  public class Timestamp extends java.util.Date {
-    ctor @Deprecated public Timestamp(int, int, int, int, int, int, int);
-    ctor public Timestamp(long);
-    method public boolean after(java.sql.Timestamp);
-    method public boolean before(java.sql.Timestamp);
-    method public int compareTo(java.sql.Timestamp);
-    method public boolean equals(java.sql.Timestamp);
-    method public int getNanos();
-    method public void setNanos(int);
-    method public static java.sql.Timestamp valueOf(String);
-  }
-
-  public class Types {
-    field public static final int ARRAY = 2003; // 0x7d3
-    field public static final int BIGINT = -5; // 0xfffffffb
-    field public static final int BINARY = -2; // 0xfffffffe
-    field public static final int BIT = -7; // 0xfffffff9
-    field public static final int BLOB = 2004; // 0x7d4
-    field public static final int BOOLEAN = 16; // 0x10
-    field public static final int CHAR = 1; // 0x1
-    field public static final int CLOB = 2005; // 0x7d5
-    field public static final int DATALINK = 70; // 0x46
-    field public static final int DATE = 91; // 0x5b
-    field public static final int DECIMAL = 3; // 0x3
-    field public static final int DISTINCT = 2001; // 0x7d1
-    field public static final int DOUBLE = 8; // 0x8
-    field public static final int FLOAT = 6; // 0x6
-    field public static final int INTEGER = 4; // 0x4
-    field public static final int JAVA_OBJECT = 2000; // 0x7d0
-    field public static final int LONGNVARCHAR = -16; // 0xfffffff0
-    field public static final int LONGVARBINARY = -4; // 0xfffffffc
-    field public static final int LONGVARCHAR = -1; // 0xffffffff
-    field public static final int NCHAR = -15; // 0xfffffff1
-    field public static final int NCLOB = 2011; // 0x7db
-    field public static final int NULL = 0; // 0x0
-    field public static final int NUMERIC = 2; // 0x2
-    field public static final int NVARCHAR = -9; // 0xfffffff7
-    field public static final int OTHER = 1111; // 0x457
-    field public static final int REAL = 7; // 0x7
-    field public static final int REF = 2006; // 0x7d6
-    field public static final int ROWID = -8; // 0xfffffff8
-    field public static final int SMALLINT = 5; // 0x5
-    field public static final int SQLXML = 2009; // 0x7d9
-    field public static final int STRUCT = 2002; // 0x7d2
-    field public static final int TIME = 92; // 0x5c
-    field public static final int TIMESTAMP = 93; // 0x5d
-    field public static final int TINYINT = -6; // 0xfffffffa
-    field public static final int VARBINARY = -3; // 0xfffffffd
-    field public static final int VARCHAR = 12; // 0xc
-  }
-
-  public interface Wrapper {
-    method public boolean isWrapperFor(Class<?>) throws java.sql.SQLException;
-    method public <T> T unwrap(Class<T>) throws java.sql.SQLException;
-  }
-
-}
-
-package java.text {
-
-  public class Annotation {
-    ctor public Annotation(Object);
-    method public Object getValue();
-  }
-
-  public interface AttributedCharacterIterator extends java.text.CharacterIterator {
-    method public java.util.Set<java.text.AttributedCharacterIterator.Attribute> getAllAttributeKeys();
-    method public Object getAttribute(java.text.AttributedCharacterIterator.Attribute);
-    method public java.util.Map<java.text.AttributedCharacterIterator.Attribute,java.lang.Object> getAttributes();
-    method public int getRunLimit();
-    method public int getRunLimit(java.text.AttributedCharacterIterator.Attribute);
-    method public int getRunLimit(java.util.Set<? extends java.text.AttributedCharacterIterator.Attribute>);
-    method public int getRunStart();
-    method public int getRunStart(java.text.AttributedCharacterIterator.Attribute);
-    method public int getRunStart(java.util.Set<? extends java.text.AttributedCharacterIterator.Attribute>);
-  }
-
-  public static class AttributedCharacterIterator.Attribute implements java.io.Serializable {
-    ctor protected AttributedCharacterIterator.Attribute(String);
-    method public final boolean equals(Object);
-    method protected String getName();
-    method public final int hashCode();
-    method protected Object readResolve() throws java.io.InvalidObjectException;
-    field public static final java.text.AttributedCharacterIterator.Attribute INPUT_METHOD_SEGMENT;
-    field public static final java.text.AttributedCharacterIterator.Attribute LANGUAGE;
-    field public static final java.text.AttributedCharacterIterator.Attribute READING;
-  }
-
-  public class AttributedString {
-    ctor public AttributedString(String);
-    ctor public AttributedString(String, java.util.Map<? extends java.text.AttributedCharacterIterator.Attribute,?>);
-    ctor public AttributedString(java.text.AttributedCharacterIterator);
-    ctor public AttributedString(java.text.AttributedCharacterIterator, int, int);
-    ctor public AttributedString(java.text.AttributedCharacterIterator, int, int, java.text.AttributedCharacterIterator.Attribute[]);
-    method public void addAttribute(java.text.AttributedCharacterIterator.Attribute, Object);
-    method public void addAttribute(java.text.AttributedCharacterIterator.Attribute, Object, int, int);
-    method public void addAttributes(java.util.Map<? extends java.text.AttributedCharacterIterator.Attribute,?>, int, int);
-    method public java.text.AttributedCharacterIterator getIterator();
-    method public java.text.AttributedCharacterIterator getIterator(java.text.AttributedCharacterIterator.Attribute[]);
-    method public java.text.AttributedCharacterIterator getIterator(java.text.AttributedCharacterIterator.Attribute[], int, int);
-  }
-
-  public final class Bidi {
-    ctor public Bidi(String, int);
-    ctor public Bidi(java.text.AttributedCharacterIterator);
-    ctor public Bidi(char[], int, byte[], int, int, int);
-    method public boolean baseIsLeftToRight();
-    method public java.text.Bidi createLineBidi(int, int);
-    method public int getBaseLevel();
-    method public int getLength();
-    method public int getLevelAt(int);
-    method public int getRunCount();
-    method public int getRunLevel(int);
-    method public int getRunLimit(int);
-    method public int getRunStart(int);
-    method public boolean isLeftToRight();
-    method public boolean isMixed();
-    method public boolean isRightToLeft();
-    method public static void reorderVisually(byte[], int, Object[], int, int);
-    method public static boolean requiresBidi(char[], int, int);
-    field public static final int DIRECTION_DEFAULT_LEFT_TO_RIGHT = -2; // 0xfffffffe
-    field public static final int DIRECTION_DEFAULT_RIGHT_TO_LEFT = -1; // 0xffffffff
-    field public static final int DIRECTION_LEFT_TO_RIGHT = 0; // 0x0
-    field public static final int DIRECTION_RIGHT_TO_LEFT = 1; // 0x1
-  }
-
-  public abstract class BreakIterator implements java.lang.Cloneable {
-    ctor protected BreakIterator();
-    method public Object clone();
-    method public abstract int current();
-    method public abstract int first();
-    method public abstract int following(int);
-    method public static java.util.Locale[] getAvailableLocales();
-    method public static java.text.BreakIterator getCharacterInstance();
-    method public static java.text.BreakIterator getCharacterInstance(java.util.Locale);
-    method public static java.text.BreakIterator getLineInstance();
-    method public static java.text.BreakIterator getLineInstance(java.util.Locale);
-    method public static java.text.BreakIterator getSentenceInstance();
-    method public static java.text.BreakIterator getSentenceInstance(java.util.Locale);
-    method public abstract java.text.CharacterIterator getText();
-    method public static java.text.BreakIterator getWordInstance();
-    method public static java.text.BreakIterator getWordInstance(java.util.Locale);
-    method public boolean isBoundary(int);
-    method public abstract int last();
-    method public abstract int next(int);
-    method public abstract int next();
-    method public int preceding(int);
-    method public abstract int previous();
-    method public void setText(String);
-    method public abstract void setText(java.text.CharacterIterator);
-    field public static final int DONE = -1; // 0xffffffff
-  }
-
-  public interface CharacterIterator extends java.lang.Cloneable {
-    method public Object clone();
-    method public char current();
-    method public char first();
-    method public int getBeginIndex();
-    method public int getEndIndex();
-    method public int getIndex();
-    method public char last();
-    method public char next();
-    method public char previous();
-    method public char setIndex(int);
-    field public static final char DONE = 65535; // 0xffff '\uffff'
-  }
-
-  public class ChoiceFormat extends java.text.NumberFormat {
-    ctor public ChoiceFormat(String);
-    ctor public ChoiceFormat(double[], String[]);
-    method public void applyPattern(String);
-    method public StringBuffer format(long, StringBuffer, java.text.FieldPosition);
-    method public StringBuffer format(double, StringBuffer, java.text.FieldPosition);
-    method public Object[] getFormats();
-    method public double[] getLimits();
-    method public static final double nextDouble(double);
-    method public static double nextDouble(double, boolean);
-    method public Number parse(String, java.text.ParsePosition);
-    method public static final double previousDouble(double);
-    method public void setChoices(double[], String[]);
-    method public String toPattern();
-  }
-
-  public final class CollationElementIterator {
-    method public int getMaxExpansion(int);
-    method public int getOffset();
-    method public int next();
-    method public int previous();
-    method public static int primaryOrder(int);
-    method public void reset();
-    method public static short secondaryOrder(int);
-    method public void setOffset(int);
-    method public void setText(String);
-    method public void setText(java.text.CharacterIterator);
-    method public static short tertiaryOrder(int);
-    field public static final int NULLORDER = -1; // 0xffffffff
-  }
-
-  public abstract class CollationKey implements java.lang.Comparable<java.text.CollationKey> {
-    ctor protected CollationKey(String);
-    method public abstract int compareTo(java.text.CollationKey);
-    method public String getSourceString();
-    method public abstract byte[] toByteArray();
-  }
-
-  public abstract class Collator implements java.lang.Cloneable java.util.Comparator<java.lang.Object> {
-    ctor protected Collator();
-    method public Object clone();
-    method public abstract int compare(String, String);
-    method public int compare(Object, Object);
-    method public boolean equals(String, String);
-    method public static java.util.Locale[] getAvailableLocales();
-    method public abstract java.text.CollationKey getCollationKey(String);
-    method public int getDecomposition();
-    method public static java.text.Collator getInstance();
-    method public static java.text.Collator getInstance(java.util.Locale);
-    method public int getStrength();
-    method public abstract int hashCode();
-    method public void setDecomposition(int);
-    method public void setStrength(int);
-    field public static final int CANONICAL_DECOMPOSITION = 1; // 0x1
-    field public static final int FULL_DECOMPOSITION = 2; // 0x2
-    field public static final int IDENTICAL = 3; // 0x3
-    field public static final int NO_DECOMPOSITION = 0; // 0x0
-    field public static final int PRIMARY = 0; // 0x0
-    field public static final int SECONDARY = 1; // 0x1
-    field public static final int TERTIARY = 2; // 0x2
-  }
-
-  public abstract class DateFormat extends java.text.Format {
-    ctor protected DateFormat();
-    method @NonNull public final StringBuffer format(@NonNull Object, @NonNull StringBuffer, @NonNull java.text.FieldPosition);
-    method @NonNull public abstract StringBuffer format(@NonNull java.util.Date, @NonNull StringBuffer, @NonNull java.text.FieldPosition);
-    method @NonNull public final String format(@NonNull java.util.Date);
-    method @NonNull public static java.util.Locale[] getAvailableLocales();
-    method @NonNull public java.util.Calendar getCalendar();
-    method @NonNull public static final java.text.DateFormat getDateInstance();
-    method @NonNull public static final java.text.DateFormat getDateInstance(int);
-    method @NonNull public static final java.text.DateFormat getDateInstance(int, @NonNull java.util.Locale);
-    method @NonNull public static final java.text.DateFormat getDateTimeInstance();
-    method @NonNull public static final java.text.DateFormat getDateTimeInstance(int, int);
-    method @NonNull public static final java.text.DateFormat getDateTimeInstance(int, int, @NonNull java.util.Locale);
-    method @NonNull public static final java.text.DateFormat getInstance();
-    method @NonNull public java.text.NumberFormat getNumberFormat();
-    method @NonNull public static final java.text.DateFormat getTimeInstance();
-    method @NonNull public static final java.text.DateFormat getTimeInstance(int);
-    method @NonNull public static final java.text.DateFormat getTimeInstance(int, @NonNull java.util.Locale);
-    method @NonNull public java.util.TimeZone getTimeZone();
-    method public boolean isLenient();
-    method @Nullable public java.util.Date parse(@NonNull String) throws java.text.ParseException;
-    method @Nullable public abstract java.util.Date parse(@NonNull String, @NonNull java.text.ParsePosition);
-    method @Nullable public Object parseObject(@NonNull String, @NonNull java.text.ParsePosition);
-    method public void setCalendar(@NonNull java.util.Calendar);
-    method public void setLenient(boolean);
-    method public void setNumberFormat(@NonNull java.text.NumberFormat);
-    method public void setTimeZone(@NonNull java.util.TimeZone);
-    field public static final int AM_PM_FIELD = 14; // 0xe
-    field public static final int DATE_FIELD = 3; // 0x3
-    field public static final int DAY_OF_WEEK_FIELD = 9; // 0x9
-    field public static final int DAY_OF_WEEK_IN_MONTH_FIELD = 11; // 0xb
-    field public static final int DAY_OF_YEAR_FIELD = 10; // 0xa
-    field public static final int DEFAULT = 2; // 0x2
-    field public static final int ERA_FIELD = 0; // 0x0
-    field public static final int FULL = 0; // 0x0
-    field public static final int HOUR0_FIELD = 16; // 0x10
-    field public static final int HOUR1_FIELD = 15; // 0xf
-    field public static final int HOUR_OF_DAY0_FIELD = 5; // 0x5
-    field public static final int HOUR_OF_DAY1_FIELD = 4; // 0x4
-    field public static final int LONG = 1; // 0x1
-    field public static final int MEDIUM = 2; // 0x2
-    field public static final int MILLISECOND_FIELD = 8; // 0x8
-    field public static final int MINUTE_FIELD = 6; // 0x6
-    field public static final int MONTH_FIELD = 2; // 0x2
-    field public static final int SECOND_FIELD = 7; // 0x7
-    field public static final int SHORT = 3; // 0x3
-    field public static final int TIMEZONE_FIELD = 17; // 0x11
-    field public static final int WEEK_OF_MONTH_FIELD = 13; // 0xd
-    field public static final int WEEK_OF_YEAR_FIELD = 12; // 0xc
-    field public static final int YEAR_FIELD = 1; // 0x1
-    field @NonNull protected java.util.Calendar calendar;
-    field @NonNull protected java.text.NumberFormat numberFormat;
-  }
-
-  public static class DateFormat.Field extends java.text.Format.Field {
-    ctor protected DateFormat.Field(@NonNull String, int);
-    method public int getCalendarField();
-    method @NonNull public static java.text.DateFormat.Field ofCalendarField(int);
-    field @NonNull public static final java.text.DateFormat.Field AM_PM;
-    field @NonNull public static final java.text.DateFormat.Field DAY_OF_MONTH;
-    field @NonNull public static final java.text.DateFormat.Field DAY_OF_WEEK;
-    field @NonNull public static final java.text.DateFormat.Field DAY_OF_WEEK_IN_MONTH;
-    field @NonNull public static final java.text.DateFormat.Field DAY_OF_YEAR;
-    field @NonNull public static final java.text.DateFormat.Field ERA;
-    field @NonNull public static final java.text.DateFormat.Field HOUR0;
-    field @NonNull public static final java.text.DateFormat.Field HOUR1;
-    field @NonNull public static final java.text.DateFormat.Field HOUR_OF_DAY0;
-    field @NonNull public static final java.text.DateFormat.Field HOUR_OF_DAY1;
-    field @NonNull public static final java.text.DateFormat.Field MILLISECOND;
-    field @NonNull public static final java.text.DateFormat.Field MINUTE;
-    field @NonNull public static final java.text.DateFormat.Field MONTH;
-    field @NonNull public static final java.text.DateFormat.Field SECOND;
-    field @NonNull public static final java.text.DateFormat.Field TIME_ZONE;
-    field @NonNull public static final java.text.DateFormat.Field WEEK_OF_MONTH;
-    field @NonNull public static final java.text.DateFormat.Field WEEK_OF_YEAR;
-    field @NonNull public static final java.text.DateFormat.Field YEAR;
-  }
-
-  public class DateFormatSymbols implements java.lang.Cloneable java.io.Serializable {
-    ctor public DateFormatSymbols();
-    ctor public DateFormatSymbols(java.util.Locale);
-    method public Object clone();
-    method public String[] getAmPmStrings();
-    method public static java.util.Locale[] getAvailableLocales();
-    method public String[] getEras();
-    method public static final java.text.DateFormatSymbols getInstance();
-    method public static final java.text.DateFormatSymbols getInstance(java.util.Locale);
-    method public String getLocalPatternChars();
-    method public String[] getMonths();
-    method public String[] getShortMonths();
-    method public String[] getShortWeekdays();
-    method public String[] getWeekdays();
-    method public String[][] getZoneStrings();
-    method public void setAmPmStrings(String[]);
-    method public void setEras(String[]);
-    method public void setLocalPatternChars(String);
-    method public void setMonths(String[]);
-    method public void setShortMonths(String[]);
-    method public void setShortWeekdays(String[]);
-    method public void setWeekdays(String[]);
-    method public void setZoneStrings(String[][]);
-  }
-
-  public class DecimalFormat extends java.text.NumberFormat {
-    ctor public DecimalFormat();
-    ctor public DecimalFormat(String);
-    ctor public DecimalFormat(String, java.text.DecimalFormatSymbols);
-    method public void applyLocalizedPattern(String);
-    method public void applyPattern(String);
-    method public final StringBuffer format(Object, StringBuffer, java.text.FieldPosition);
-    method public StringBuffer format(double, StringBuffer, java.text.FieldPosition);
-    method public StringBuffer format(long, StringBuffer, java.text.FieldPosition);
-    method public java.text.DecimalFormatSymbols getDecimalFormatSymbols();
-    method public int getGroupingSize();
-    method public int getMultiplier();
-    method public String getNegativePrefix();
-    method public String getNegativeSuffix();
-    method public String getPositivePrefix();
-    method public String getPositiveSuffix();
-    method public boolean isDecimalSeparatorAlwaysShown();
-    method public boolean isParseBigDecimal();
-    method public Number parse(String, java.text.ParsePosition);
-    method public void setDecimalFormatSymbols(java.text.DecimalFormatSymbols);
-    method public void setDecimalSeparatorAlwaysShown(boolean);
-    method public void setGroupingSize(int);
-    method public void setMultiplier(int);
-    method public void setNegativePrefix(String);
-    method public void setNegativeSuffix(String);
-    method public void setParseBigDecimal(boolean);
-    method public void setPositivePrefix(String);
-    method public void setPositiveSuffix(String);
-    method public String toLocalizedPattern();
-    method public String toPattern();
-  }
-
-  public class DecimalFormatSymbols implements java.lang.Cloneable java.io.Serializable {
-    ctor public DecimalFormatSymbols();
-    ctor public DecimalFormatSymbols(java.util.Locale);
-    method public Object clone();
-    method public static java.util.Locale[] getAvailableLocales();
-    method public java.util.Currency getCurrency();
-    method public String getCurrencySymbol();
-    method public char getDecimalSeparator();
-    method public char getDigit();
-    method public String getExponentSeparator();
-    method public char getGroupingSeparator();
-    method public String getInfinity();
-    method public static final java.text.DecimalFormatSymbols getInstance();
-    method public static final java.text.DecimalFormatSymbols getInstance(java.util.Locale);
-    method public String getInternationalCurrencySymbol();
-    method public char getMinusSign();
-    method public char getMonetaryDecimalSeparator();
-    method public String getNaN();
-    method public char getPatternSeparator();
-    method public char getPerMill();
-    method public char getPercent();
-    method public char getZeroDigit();
-    method public void setCurrency(java.util.Currency);
-    method public void setCurrencySymbol(String);
-    method public void setDecimalSeparator(char);
-    method public void setDigit(char);
-    method public void setExponentSeparator(String);
-    method public void setGroupingSeparator(char);
-    method public void setInfinity(String);
-    method public void setInternationalCurrencySymbol(String);
-    method public void setMinusSign(char);
-    method public void setMonetaryDecimalSeparator(char);
-    method public void setNaN(String);
-    method public void setPatternSeparator(char);
-    method public void setPerMill(char);
-    method public void setPercent(char);
-    method public void setZeroDigit(char);
-  }
-
-  public class FieldPosition {
-    ctor public FieldPosition(int);
-    ctor public FieldPosition(java.text.Format.Field);
-    ctor public FieldPosition(java.text.Format.Field, int);
-    method public int getBeginIndex();
-    method public int getEndIndex();
-    method public int getField();
-    method public java.text.Format.Field getFieldAttribute();
-    method public void setBeginIndex(int);
-    method public void setEndIndex(int);
-  }
-
-  public abstract class Format implements java.lang.Cloneable java.io.Serializable {
-    ctor protected Format();
-    method public Object clone();
-    method public final String format(Object);
-    method public abstract StringBuffer format(Object, StringBuffer, java.text.FieldPosition);
-    method public java.text.AttributedCharacterIterator formatToCharacterIterator(Object);
-    method public abstract Object parseObject(String, java.text.ParsePosition);
-    method public Object parseObject(String) throws java.text.ParseException;
-  }
-
-  public static class Format.Field extends java.text.AttributedCharacterIterator.Attribute {
-    ctor protected Format.Field(String);
-  }
-
-  public class MessageFormat extends java.text.Format {
-    ctor public MessageFormat(String);
-    ctor public MessageFormat(String, java.util.Locale);
-    method public void applyPattern(String);
-    method public final StringBuffer format(Object[], StringBuffer, java.text.FieldPosition);
-    method public static String format(String, java.lang.Object...);
-    method public final StringBuffer format(Object, StringBuffer, java.text.FieldPosition);
-    method public java.text.Format[] getFormats();
-    method public java.text.Format[] getFormatsByArgumentIndex();
-    method public java.util.Locale getLocale();
-    method public Object[] parse(String, java.text.ParsePosition);
-    method public Object[] parse(String) throws java.text.ParseException;
-    method public Object parseObject(String, java.text.ParsePosition);
-    method public void setFormat(int, java.text.Format);
-    method public void setFormatByArgumentIndex(int, java.text.Format);
-    method public void setFormats(java.text.Format[]);
-    method public void setFormatsByArgumentIndex(java.text.Format[]);
-    method public void setLocale(java.util.Locale);
-    method public String toPattern();
-  }
-
-  public static class MessageFormat.Field extends java.text.Format.Field {
-    ctor protected MessageFormat.Field(String);
-    field public static final java.text.MessageFormat.Field ARGUMENT;
-  }
-
-  public final class Normalizer {
-    method public static boolean isNormalized(CharSequence, java.text.Normalizer.Form);
-    method public static String normalize(CharSequence, java.text.Normalizer.Form);
-  }
-
-  public enum Normalizer.Form {
-    enum_constant public static final java.text.Normalizer.Form NFC;
-    enum_constant public static final java.text.Normalizer.Form NFD;
-    enum_constant public static final java.text.Normalizer.Form NFKC;
-    enum_constant public static final java.text.Normalizer.Form NFKD;
-  }
-
-  public abstract class NumberFormat extends java.text.Format {
-    ctor protected NumberFormat();
-    method @NonNull public StringBuffer format(@NonNull Object, @NonNull StringBuffer, @NonNull java.text.FieldPosition);
-    method @NonNull public final String format(double);
-    method @NonNull public final String format(long);
-    method @NonNull public abstract StringBuffer format(double, @NonNull StringBuffer, @NonNull java.text.FieldPosition);
-    method @NonNull public abstract StringBuffer format(long, @NonNull StringBuffer, @NonNull java.text.FieldPosition);
-    method @NonNull public static java.util.Locale[] getAvailableLocales();
-    method @Nullable public java.util.Currency getCurrency();
-    method @NonNull public static final java.text.NumberFormat getCurrencyInstance();
-    method @NonNull public static java.text.NumberFormat getCurrencyInstance(@NonNull java.util.Locale);
-    method @NonNull public static final java.text.NumberFormat getInstance();
-    method @NonNull public static java.text.NumberFormat getInstance(@NonNull java.util.Locale);
-    method @NonNull public static final java.text.NumberFormat getIntegerInstance();
-    method @NonNull public static java.text.NumberFormat getIntegerInstance(@NonNull java.util.Locale);
-    method public int getMaximumFractionDigits();
-    method public int getMaximumIntegerDigits();
-    method public int getMinimumFractionDigits();
-    method public int getMinimumIntegerDigits();
-    method @NonNull public static final java.text.NumberFormat getNumberInstance();
-    method @NonNull public static java.text.NumberFormat getNumberInstance(@NonNull java.util.Locale);
-    method @NonNull public static final java.text.NumberFormat getPercentInstance();
-    method @NonNull public static java.text.NumberFormat getPercentInstance(@NonNull java.util.Locale);
-    method @NonNull public java.math.RoundingMode getRoundingMode();
-    method public boolean isGroupingUsed();
-    method public boolean isParseIntegerOnly();
-    method @Nullable public abstract Number parse(@NonNull String, @NonNull java.text.ParsePosition);
-    method @Nullable public Number parse(@NonNull String) throws java.text.ParseException;
-    method @Nullable public final Object parseObject(@NonNull String, @NonNull java.text.ParsePosition);
-    method public void setCurrency(@NonNull java.util.Currency);
-    method public void setGroupingUsed(boolean);
-    method public void setMaximumFractionDigits(int);
-    method public void setMaximumIntegerDigits(int);
-    method public void setMinimumFractionDigits(int);
-    method public void setMinimumIntegerDigits(int);
-    method public void setParseIntegerOnly(boolean);
-    method public void setRoundingMode(@Nullable java.math.RoundingMode);
-    field public static final int FRACTION_FIELD = 1; // 0x1
-    field public static final int INTEGER_FIELD = 0; // 0x0
-  }
-
-  public static class NumberFormat.Field extends java.text.Format.Field {
-    ctor protected NumberFormat.Field(@NonNull String);
-    field @NonNull public static final java.text.NumberFormat.Field CURRENCY;
-    field @NonNull public static final java.text.NumberFormat.Field DECIMAL_SEPARATOR;
-    field @NonNull public static final java.text.NumberFormat.Field EXPONENT;
-    field @NonNull public static final java.text.NumberFormat.Field EXPONENT_SIGN;
-    field @NonNull public static final java.text.NumberFormat.Field EXPONENT_SYMBOL;
-    field @NonNull public static final java.text.NumberFormat.Field FRACTION;
-    field @NonNull public static final java.text.NumberFormat.Field GROUPING_SEPARATOR;
-    field @NonNull public static final java.text.NumberFormat.Field INTEGER;
-    field @NonNull public static final java.text.NumberFormat.Field PERCENT;
-    field @NonNull public static final java.text.NumberFormat.Field PERMILLE;
-    field @NonNull public static final java.text.NumberFormat.Field SIGN;
-  }
-
-  public class ParseException extends java.lang.Exception {
-    ctor public ParseException(String, int);
-    method public int getErrorOffset();
-  }
-
-  public class ParsePosition {
-    ctor public ParsePosition(int);
-    method public int getErrorIndex();
-    method public int getIndex();
-    method public void setErrorIndex(int);
-    method public void setIndex(int);
-  }
-
-  public class RuleBasedCollator extends java.text.Collator {
-    ctor public RuleBasedCollator(String) throws java.text.ParseException;
-    method public int compare(String, String);
-    method public java.text.CollationElementIterator getCollationElementIterator(String);
-    method public java.text.CollationElementIterator getCollationElementIterator(java.text.CharacterIterator);
-    method public java.text.CollationKey getCollationKey(String);
-    method public String getRules();
-  }
-
-  public class SimpleDateFormat extends java.text.DateFormat {
-    ctor public SimpleDateFormat();
-    ctor public SimpleDateFormat(String);
-    ctor public SimpleDateFormat(String, java.util.Locale);
-    ctor public SimpleDateFormat(String, java.text.DateFormatSymbols);
-    method public void applyLocalizedPattern(String);
-    method public void applyPattern(String);
-    method public StringBuffer format(java.util.Date, StringBuffer, java.text.FieldPosition);
-    method public java.util.Date get2DigitYearStart();
-    method public java.text.DateFormatSymbols getDateFormatSymbols();
-    method public java.util.Date parse(String, java.text.ParsePosition);
-    method public void set2DigitYearStart(java.util.Date);
-    method public void setDateFormatSymbols(java.text.DateFormatSymbols);
-    method public String toLocalizedPattern();
-    method public String toPattern();
-  }
-
-  public final class StringCharacterIterator implements java.text.CharacterIterator {
-    ctor public StringCharacterIterator(String);
-    ctor public StringCharacterIterator(String, int);
-    ctor public StringCharacterIterator(String, int, int, int);
-    method public Object clone();
-    method public char current();
-    method public char first();
-    method public int getBeginIndex();
-    method public int getEndIndex();
-    method public int getIndex();
-    method public char last();
-    method public char next();
-    method public char previous();
-    method public char setIndex(int);
-    method public void setText(String);
-  }
-
-}
-
-package java.time {
-
-  public abstract class Clock {
-    ctor protected Clock();
-    method public static java.time.Clock fixed(java.time.Instant, java.time.ZoneId);
-    method public abstract java.time.ZoneId getZone();
-    method public abstract java.time.Instant instant();
-    method public long millis();
-    method public static java.time.Clock offset(java.time.Clock, java.time.Duration);
-    method public static java.time.Clock system(java.time.ZoneId);
-    method public static java.time.Clock systemDefaultZone();
-    method public static java.time.Clock systemUTC();
-    method public static java.time.Clock tick(java.time.Clock, java.time.Duration);
-    method public static java.time.Clock tickMinutes(java.time.ZoneId);
-    method public static java.time.Clock tickSeconds(java.time.ZoneId);
-    method public abstract java.time.Clock withZone(java.time.ZoneId);
-  }
-
-  public class DateTimeException extends java.lang.RuntimeException {
-    ctor public DateTimeException(String);
-    ctor public DateTimeException(String, Throwable);
-  }
-
-  public enum DayOfWeek implements java.time.temporal.TemporalAccessor java.time.temporal.TemporalAdjuster {
-    method public java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal);
-    method public static java.time.DayOfWeek from(java.time.temporal.TemporalAccessor);
-    method public String getDisplayName(java.time.format.TextStyle, java.util.Locale);
-    method public long getLong(java.time.temporal.TemporalField);
-    method public int getValue();
-    method public boolean isSupported(java.time.temporal.TemporalField);
-    method public java.time.DayOfWeek minus(long);
-    method public static java.time.DayOfWeek of(int);
-    method public java.time.DayOfWeek plus(long);
-    enum_constant public static final java.time.DayOfWeek FRIDAY;
-    enum_constant public static final java.time.DayOfWeek MONDAY;
-    enum_constant public static final java.time.DayOfWeek SATURDAY;
-    enum_constant public static final java.time.DayOfWeek SUNDAY;
-    enum_constant public static final java.time.DayOfWeek THURSDAY;
-    enum_constant public static final java.time.DayOfWeek TUESDAY;
-    enum_constant public static final java.time.DayOfWeek WEDNESDAY;
-  }
-
-  public final class Duration implements java.lang.Comparable<java.time.Duration> java.io.Serializable java.time.temporal.TemporalAmount {
-    method public java.time.Duration abs();
-    method public java.time.temporal.Temporal addTo(java.time.temporal.Temporal);
-    method public static java.time.Duration between(java.time.temporal.Temporal, java.time.temporal.Temporal);
-    method public int compareTo(java.time.Duration);
-    method public java.time.Duration dividedBy(long);
-    method public static java.time.Duration from(java.time.temporal.TemporalAmount);
-    method public long get(java.time.temporal.TemporalUnit);
-    method public int getNano();
-    method public long getSeconds();
-    method public java.util.List<java.time.temporal.TemporalUnit> getUnits();
-    method public boolean isNegative();
-    method public boolean isZero();
-    method public java.time.Duration minus(java.time.Duration);
-    method public java.time.Duration minus(long, java.time.temporal.TemporalUnit);
-    method public java.time.Duration minusDays(long);
-    method public java.time.Duration minusHours(long);
-    method public java.time.Duration minusMillis(long);
-    method public java.time.Duration minusMinutes(long);
-    method public java.time.Duration minusNanos(long);
-    method public java.time.Duration minusSeconds(long);
-    method public java.time.Duration multipliedBy(long);
-    method public java.time.Duration negated();
-    method public static java.time.Duration of(long, java.time.temporal.TemporalUnit);
-    method public static java.time.Duration ofDays(long);
-    method public static java.time.Duration ofHours(long);
-    method public static java.time.Duration ofMillis(long);
-    method public static java.time.Duration ofMinutes(long);
-    method public static java.time.Duration ofNanos(long);
-    method public static java.time.Duration ofSeconds(long);
-    method public static java.time.Duration ofSeconds(long, long);
-    method public static java.time.Duration parse(CharSequence);
-    method public java.time.Duration plus(java.time.Duration);
-    method public java.time.Duration plus(long, java.time.temporal.TemporalUnit);
-    method public java.time.Duration plusDays(long);
-    method public java.time.Duration plusHours(long);
-    method public java.time.Duration plusMillis(long);
-    method public java.time.Duration plusMinutes(long);
-    method public java.time.Duration plusNanos(long);
-    method public java.time.Duration plusSeconds(long);
-    method public java.time.temporal.Temporal subtractFrom(java.time.temporal.Temporal);
-    method public long toDays();
-    method public long toHours();
-    method public long toMillis();
-    method public long toMinutes();
-    method public long toNanos();
-    method public java.time.Duration withNanos(int);
-    method public java.time.Duration withSeconds(long);
-    field public static final java.time.Duration ZERO;
-  }
-
-  public final class Instant implements java.lang.Comparable<java.time.Instant> java.io.Serializable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
-    method public java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal);
-    method public java.time.OffsetDateTime atOffset(java.time.ZoneOffset);
-    method public java.time.ZonedDateTime atZone(java.time.ZoneId);
-    method public int compareTo(java.time.Instant);
-    method public static java.time.Instant from(java.time.temporal.TemporalAccessor);
-    method public long getEpochSecond();
-    method public long getLong(java.time.temporal.TemporalField);
-    method public int getNano();
-    method public boolean isAfter(java.time.Instant);
-    method public boolean isBefore(java.time.Instant);
-    method public boolean isSupported(java.time.temporal.TemporalField);
-    method public boolean isSupported(java.time.temporal.TemporalUnit);
-    method public java.time.Instant minus(java.time.temporal.TemporalAmount);
-    method public java.time.Instant minus(long, java.time.temporal.TemporalUnit);
-    method public java.time.Instant minusMillis(long);
-    method public java.time.Instant minusNanos(long);
-    method public java.time.Instant minusSeconds(long);
-    method public static java.time.Instant now();
-    method public static java.time.Instant now(java.time.Clock);
-    method public static java.time.Instant ofEpochMilli(long);
-    method public static java.time.Instant ofEpochSecond(long);
-    method public static java.time.Instant ofEpochSecond(long, long);
-    method public static java.time.Instant parse(CharSequence);
-    method public java.time.Instant plus(java.time.temporal.TemporalAmount);
-    method public java.time.Instant plus(long, java.time.temporal.TemporalUnit);
-    method public java.time.Instant plusMillis(long);
-    method public java.time.Instant plusNanos(long);
-    method public java.time.Instant plusSeconds(long);
-    method public long toEpochMilli();
-    method public java.time.Instant truncatedTo(java.time.temporal.TemporalUnit);
-    method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.Instant with(java.time.temporal.TemporalAdjuster);
-    method public java.time.Instant with(java.time.temporal.TemporalField, long);
-    field public static final java.time.Instant EPOCH;
-    field public static final java.time.Instant MAX;
-    field public static final java.time.Instant MIN;
-  }
-
-  public final class LocalDate implements java.time.chrono.ChronoLocalDate java.io.Serializable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
-    method public java.time.LocalDateTime atStartOfDay();
-    method public java.time.ZonedDateTime atStartOfDay(java.time.ZoneId);
-    method public java.time.LocalDateTime atTime(java.time.LocalTime);
-    method public java.time.LocalDateTime atTime(int, int);
-    method public java.time.LocalDateTime atTime(int, int, int);
-    method public java.time.LocalDateTime atTime(int, int, int, int);
-    method public java.time.OffsetDateTime atTime(java.time.OffsetTime);
-    method public static java.time.LocalDate from(java.time.temporal.TemporalAccessor);
-    method public java.time.chrono.IsoChronology getChronology();
-    method public int getDayOfMonth();
-    method public java.time.DayOfWeek getDayOfWeek();
-    method public int getDayOfYear();
-    method public long getLong(java.time.temporal.TemporalField);
-    method public java.time.Month getMonth();
-    method public int getMonthValue();
-    method public int getYear();
-    method public int lengthOfMonth();
-    method public java.time.LocalDate minus(java.time.temporal.TemporalAmount);
-    method public java.time.LocalDate minus(long, java.time.temporal.TemporalUnit);
-    method public java.time.LocalDate minusDays(long);
-    method public java.time.LocalDate minusMonths(long);
-    method public java.time.LocalDate minusWeeks(long);
-    method public java.time.LocalDate minusYears(long);
-    method public static java.time.LocalDate now();
-    method public static java.time.LocalDate now(java.time.ZoneId);
-    method public static java.time.LocalDate now(java.time.Clock);
-    method public static java.time.LocalDate of(int, java.time.Month, int);
-    method public static java.time.LocalDate of(int, int, int);
-    method public static java.time.LocalDate ofEpochDay(long);
-    method public static java.time.LocalDate ofYearDay(int, int);
-    method public static java.time.LocalDate parse(CharSequence);
-    method public static java.time.LocalDate parse(CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.LocalDate plus(java.time.temporal.TemporalAmount);
-    method public java.time.LocalDate plus(long, java.time.temporal.TemporalUnit);
-    method public java.time.LocalDate plusDays(long);
-    method public java.time.LocalDate plusMonths(long);
-    method public java.time.LocalDate plusWeeks(long);
-    method public java.time.LocalDate plusYears(long);
-    method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.Period until(java.time.chrono.ChronoLocalDate);
-    method public java.time.LocalDate with(java.time.temporal.TemporalAdjuster);
-    method public java.time.LocalDate with(java.time.temporal.TemporalField, long);
-    method public java.time.LocalDate withDayOfMonth(int);
-    method public java.time.LocalDate withDayOfYear(int);
-    method public java.time.LocalDate withMonth(int);
-    method public java.time.LocalDate withYear(int);
-    field public static final java.time.LocalDate MAX;
-    field public static final java.time.LocalDate MIN;
-  }
-
-  public final class LocalDateTime implements java.time.chrono.ChronoLocalDateTime<java.time.LocalDate> java.io.Serializable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
-    method public java.time.OffsetDateTime atOffset(java.time.ZoneOffset);
-    method public java.time.ZonedDateTime atZone(java.time.ZoneId);
-    method public static java.time.LocalDateTime from(java.time.temporal.TemporalAccessor);
-    method public int getDayOfMonth();
-    method public java.time.DayOfWeek getDayOfWeek();
-    method public int getDayOfYear();
-    method public int getHour();
-    method public long getLong(java.time.temporal.TemporalField);
-    method public int getMinute();
-    method public java.time.Month getMonth();
-    method public int getMonthValue();
-    method public int getNano();
-    method public int getSecond();
-    method public int getYear();
-    method public boolean isSupported(java.time.temporal.TemporalField);
-    method public java.time.LocalDateTime minus(java.time.temporal.TemporalAmount);
-    method public java.time.LocalDateTime minus(long, java.time.temporal.TemporalUnit);
-    method public java.time.LocalDateTime minusDays(long);
-    method public java.time.LocalDateTime minusHours(long);
-    method public java.time.LocalDateTime minusMinutes(long);
-    method public java.time.LocalDateTime minusMonths(long);
-    method public java.time.LocalDateTime minusNanos(long);
-    method public java.time.LocalDateTime minusSeconds(long);
-    method public java.time.LocalDateTime minusWeeks(long);
-    method public java.time.LocalDateTime minusYears(long);
-    method public static java.time.LocalDateTime now();
-    method public static java.time.LocalDateTime now(java.time.ZoneId);
-    method public static java.time.LocalDateTime now(java.time.Clock);
-    method public static java.time.LocalDateTime of(int, java.time.Month, int, int, int);
-    method public static java.time.LocalDateTime of(int, java.time.Month, int, int, int, int);
-    method public static java.time.LocalDateTime of(int, java.time.Month, int, int, int, int, int);
-    method public static java.time.LocalDateTime of(int, int, int, int, int);
-    method public static java.time.LocalDateTime of(int, int, int, int, int, int);
-    method public static java.time.LocalDateTime of(int, int, int, int, int, int, int);
-    method public static java.time.LocalDateTime of(java.time.LocalDate, java.time.LocalTime);
-    method public static java.time.LocalDateTime ofEpochSecond(long, int, java.time.ZoneOffset);
-    method public static java.time.LocalDateTime ofInstant(java.time.Instant, java.time.ZoneId);
-    method public static java.time.LocalDateTime parse(CharSequence);
-    method public static java.time.LocalDateTime parse(CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.LocalDateTime plus(java.time.temporal.TemporalAmount);
-    method public java.time.LocalDateTime plus(long, java.time.temporal.TemporalUnit);
-    method public java.time.LocalDateTime plusDays(long);
-    method public java.time.LocalDateTime plusHours(long);
-    method public java.time.LocalDateTime plusMinutes(long);
-    method public java.time.LocalDateTime plusMonths(long);
-    method public java.time.LocalDateTime plusNanos(long);
-    method public java.time.LocalDateTime plusSeconds(long);
-    method public java.time.LocalDateTime plusWeeks(long);
-    method public java.time.LocalDateTime plusYears(long);
-    method public java.time.LocalDate toLocalDate();
-    method public java.time.LocalTime toLocalTime();
-    method public java.time.LocalDateTime truncatedTo(java.time.temporal.TemporalUnit);
-    method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.LocalDateTime with(java.time.temporal.TemporalAdjuster);
-    method public java.time.LocalDateTime with(java.time.temporal.TemporalField, long);
-    method public java.time.LocalDateTime withDayOfMonth(int);
-    method public java.time.LocalDateTime withDayOfYear(int);
-    method public java.time.LocalDateTime withHour(int);
-    method public java.time.LocalDateTime withMinute(int);
-    method public java.time.LocalDateTime withMonth(int);
-    method public java.time.LocalDateTime withNano(int);
-    method public java.time.LocalDateTime withSecond(int);
-    method public java.time.LocalDateTime withYear(int);
-    field public static final java.time.LocalDateTime MAX;
-    field public static final java.time.LocalDateTime MIN;
-  }
-
-  public final class LocalTime implements java.lang.Comparable<java.time.LocalTime> java.io.Serializable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
-    method public java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal);
-    method public java.time.LocalDateTime atDate(java.time.LocalDate);
-    method public java.time.OffsetTime atOffset(java.time.ZoneOffset);
-    method public int compareTo(java.time.LocalTime);
-    method public String format(java.time.format.DateTimeFormatter);
-    method public static java.time.LocalTime from(java.time.temporal.TemporalAccessor);
-    method public int getHour();
-    method public long getLong(java.time.temporal.TemporalField);
-    method public int getMinute();
-    method public int getNano();
-    method public int getSecond();
-    method public boolean isAfter(java.time.LocalTime);
-    method public boolean isBefore(java.time.LocalTime);
-    method public boolean isSupported(java.time.temporal.TemporalField);
-    method public boolean isSupported(java.time.temporal.TemporalUnit);
-    method public java.time.LocalTime minus(java.time.temporal.TemporalAmount);
-    method public java.time.LocalTime minus(long, java.time.temporal.TemporalUnit);
-    method public java.time.LocalTime minusHours(long);
-    method public java.time.LocalTime minusMinutes(long);
-    method public java.time.LocalTime minusNanos(long);
-    method public java.time.LocalTime minusSeconds(long);
-    method public static java.time.LocalTime now();
-    method public static java.time.LocalTime now(java.time.ZoneId);
-    method public static java.time.LocalTime now(java.time.Clock);
-    method public static java.time.LocalTime of(int, int);
-    method public static java.time.LocalTime of(int, int, int);
-    method public static java.time.LocalTime of(int, int, int, int);
-    method public static java.time.LocalTime ofNanoOfDay(long);
-    method public static java.time.LocalTime ofSecondOfDay(long);
-    method public static java.time.LocalTime parse(CharSequence);
-    method public static java.time.LocalTime parse(CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.LocalTime plus(java.time.temporal.TemporalAmount);
-    method public java.time.LocalTime plus(long, java.time.temporal.TemporalUnit);
-    method public java.time.LocalTime plusHours(long);
-    method public java.time.LocalTime plusMinutes(long);
-    method public java.time.LocalTime plusNanos(long);
-    method public java.time.LocalTime plusSeconds(long);
-    method public long toNanoOfDay();
-    method public int toSecondOfDay();
-    method public java.time.LocalTime truncatedTo(java.time.temporal.TemporalUnit);
-    method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.LocalTime with(java.time.temporal.TemporalAdjuster);
-    method public java.time.LocalTime with(java.time.temporal.TemporalField, long);
-    method public java.time.LocalTime withHour(int);
-    method public java.time.LocalTime withMinute(int);
-    method public java.time.LocalTime withNano(int);
-    method public java.time.LocalTime withSecond(int);
-    field public static final java.time.LocalTime MAX;
-    field public static final java.time.LocalTime MIDNIGHT;
-    field public static final java.time.LocalTime MIN;
-    field public static final java.time.LocalTime NOON;
-  }
-
-  public enum Month implements java.time.temporal.TemporalAccessor java.time.temporal.TemporalAdjuster {
-    method public java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal);
-    method public int firstDayOfYear(boolean);
-    method public java.time.Month firstMonthOfQuarter();
-    method public static java.time.Month from(java.time.temporal.TemporalAccessor);
-    method public String getDisplayName(java.time.format.TextStyle, java.util.Locale);
-    method public long getLong(java.time.temporal.TemporalField);
-    method public int getValue();
-    method public boolean isSupported(java.time.temporal.TemporalField);
-    method public int length(boolean);
-    method public int maxLength();
-    method public int minLength();
-    method public java.time.Month minus(long);
-    method public static java.time.Month of(int);
-    method public java.time.Month plus(long);
-    enum_constant public static final java.time.Month APRIL;
-    enum_constant public static final java.time.Month AUGUST;
-    enum_constant public static final java.time.Month DECEMBER;
-    enum_constant public static final java.time.Month FEBRUARY;
-    enum_constant public static final java.time.Month JANUARY;
-    enum_constant public static final java.time.Month JULY;
-    enum_constant public static final java.time.Month JUNE;
-    enum_constant public static final java.time.Month MARCH;
-    enum_constant public static final java.time.Month MAY;
-    enum_constant public static final java.time.Month NOVEMBER;
-    enum_constant public static final java.time.Month OCTOBER;
-    enum_constant public static final java.time.Month SEPTEMBER;
-  }
-
-  public final class MonthDay implements java.lang.Comparable<java.time.MonthDay> java.io.Serializable java.time.temporal.TemporalAccessor java.time.temporal.TemporalAdjuster {
-    method public java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal);
-    method public java.time.LocalDate atYear(int);
-    method public int compareTo(java.time.MonthDay);
-    method public String format(java.time.format.DateTimeFormatter);
-    method public static java.time.MonthDay from(java.time.temporal.TemporalAccessor);
-    method public int getDayOfMonth();
-    method public long getLong(java.time.temporal.TemporalField);
-    method public java.time.Month getMonth();
-    method public int getMonthValue();
-    method public boolean isAfter(java.time.MonthDay);
-    method public boolean isBefore(java.time.MonthDay);
-    method public boolean isSupported(java.time.temporal.TemporalField);
-    method public boolean isValidYear(int);
-    method public static java.time.MonthDay now();
-    method public static java.time.MonthDay now(java.time.ZoneId);
-    method public static java.time.MonthDay now(java.time.Clock);
-    method public static java.time.MonthDay of(java.time.Month, int);
-    method public static java.time.MonthDay of(int, int);
-    method public static java.time.MonthDay parse(CharSequence);
-    method public static java.time.MonthDay parse(CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.MonthDay with(java.time.Month);
-    method public java.time.MonthDay withDayOfMonth(int);
-    method public java.time.MonthDay withMonth(int);
-  }
-
-  public final class OffsetDateTime implements java.lang.Comparable<java.time.OffsetDateTime> java.io.Serializable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
-    method public java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal);
-    method public java.time.ZonedDateTime atZoneSameInstant(java.time.ZoneId);
-    method public java.time.ZonedDateTime atZoneSimilarLocal(java.time.ZoneId);
-    method public int compareTo(java.time.OffsetDateTime);
-    method public String format(java.time.format.DateTimeFormatter);
-    method public static java.time.OffsetDateTime from(java.time.temporal.TemporalAccessor);
-    method public int getDayOfMonth();
-    method public java.time.DayOfWeek getDayOfWeek();
-    method public int getDayOfYear();
-    method public int getHour();
-    method public long getLong(java.time.temporal.TemporalField);
-    method public int getMinute();
-    method public java.time.Month getMonth();
-    method public int getMonthValue();
-    method public int getNano();
-    method public java.time.ZoneOffset getOffset();
-    method public int getSecond();
-    method public int getYear();
-    method public boolean isAfter(java.time.OffsetDateTime);
-    method public boolean isBefore(java.time.OffsetDateTime);
-    method public boolean isEqual(java.time.OffsetDateTime);
-    method public boolean isSupported(java.time.temporal.TemporalField);
-    method public boolean isSupported(java.time.temporal.TemporalUnit);
-    method public java.time.OffsetDateTime minus(java.time.temporal.TemporalAmount);
-    method public java.time.OffsetDateTime minus(long, java.time.temporal.TemporalUnit);
-    method public java.time.OffsetDateTime minusDays(long);
-    method public java.time.OffsetDateTime minusHours(long);
-    method public java.time.OffsetDateTime minusMinutes(long);
-    method public java.time.OffsetDateTime minusMonths(long);
-    method public java.time.OffsetDateTime minusNanos(long);
-    method public java.time.OffsetDateTime minusSeconds(long);
-    method public java.time.OffsetDateTime minusWeeks(long);
-    method public java.time.OffsetDateTime minusYears(long);
-    method public static java.time.OffsetDateTime now();
-    method public static java.time.OffsetDateTime now(java.time.ZoneId);
-    method public static java.time.OffsetDateTime now(java.time.Clock);
-    method public static java.time.OffsetDateTime of(java.time.LocalDate, java.time.LocalTime, java.time.ZoneOffset);
-    method public static java.time.OffsetDateTime of(java.time.LocalDateTime, java.time.ZoneOffset);
-    method public static java.time.OffsetDateTime of(int, int, int, int, int, int, int, java.time.ZoneOffset);
-    method public static java.time.OffsetDateTime ofInstant(java.time.Instant, java.time.ZoneId);
-    method public static java.time.OffsetDateTime parse(CharSequence);
-    method public static java.time.OffsetDateTime parse(CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.OffsetDateTime plus(java.time.temporal.TemporalAmount);
-    method public java.time.OffsetDateTime plus(long, java.time.temporal.TemporalUnit);
-    method public java.time.OffsetDateTime plusDays(long);
-    method public java.time.OffsetDateTime plusHours(long);
-    method public java.time.OffsetDateTime plusMinutes(long);
-    method public java.time.OffsetDateTime plusMonths(long);
-    method public java.time.OffsetDateTime plusNanos(long);
-    method public java.time.OffsetDateTime plusSeconds(long);
-    method public java.time.OffsetDateTime plusWeeks(long);
-    method public java.time.OffsetDateTime plusYears(long);
-    method public static java.util.Comparator<java.time.OffsetDateTime> timeLineOrder();
-    method public long toEpochSecond();
-    method public java.time.Instant toInstant();
-    method public java.time.LocalDate toLocalDate();
-    method public java.time.LocalDateTime toLocalDateTime();
-    method public java.time.LocalTime toLocalTime();
-    method public java.time.OffsetTime toOffsetTime();
-    method public java.time.ZonedDateTime toZonedDateTime();
-    method public java.time.OffsetDateTime truncatedTo(java.time.temporal.TemporalUnit);
-    method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.OffsetDateTime with(java.time.temporal.TemporalAdjuster);
-    method public java.time.OffsetDateTime with(java.time.temporal.TemporalField, long);
-    method public java.time.OffsetDateTime withDayOfMonth(int);
-    method public java.time.OffsetDateTime withDayOfYear(int);
-    method public java.time.OffsetDateTime withHour(int);
-    method public java.time.OffsetDateTime withMinute(int);
-    method public java.time.OffsetDateTime withMonth(int);
-    method public java.time.OffsetDateTime withNano(int);
-    method public java.time.OffsetDateTime withOffsetSameInstant(java.time.ZoneOffset);
-    method public java.time.OffsetDateTime withOffsetSameLocal(java.time.ZoneOffset);
-    method public java.time.OffsetDateTime withSecond(int);
-    method public java.time.OffsetDateTime withYear(int);
-    field public static final java.time.OffsetDateTime MAX;
-    field public static final java.time.OffsetDateTime MIN;
-  }
-
-  public final class OffsetTime implements java.lang.Comparable<java.time.OffsetTime> java.io.Serializable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
-    method public java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal);
-    method public java.time.OffsetDateTime atDate(java.time.LocalDate);
-    method public int compareTo(java.time.OffsetTime);
-    method public String format(java.time.format.DateTimeFormatter);
-    method public static java.time.OffsetTime from(java.time.temporal.TemporalAccessor);
-    method public int getHour();
-    method public long getLong(java.time.temporal.TemporalField);
-    method public int getMinute();
-    method public int getNano();
-    method public java.time.ZoneOffset getOffset();
-    method public int getSecond();
-    method public boolean isAfter(java.time.OffsetTime);
-    method public boolean isBefore(java.time.OffsetTime);
-    method public boolean isEqual(java.time.OffsetTime);
-    method public boolean isSupported(java.time.temporal.TemporalField);
-    method public boolean isSupported(java.time.temporal.TemporalUnit);
-    method public java.time.OffsetTime minus(java.time.temporal.TemporalAmount);
-    method public java.time.OffsetTime minus(long, java.time.temporal.TemporalUnit);
-    method public java.time.OffsetTime minusHours(long);
-    method public java.time.OffsetTime minusMinutes(long);
-    method public java.time.OffsetTime minusNanos(long);
-    method public java.time.OffsetTime minusSeconds(long);
-    method public static java.time.OffsetTime now();
-    method public static java.time.OffsetTime now(java.time.ZoneId);
-    method public static java.time.OffsetTime now(java.time.Clock);
-    method public static java.time.OffsetTime of(java.time.LocalTime, java.time.ZoneOffset);
-    method public static java.time.OffsetTime of(int, int, int, int, java.time.ZoneOffset);
-    method public static java.time.OffsetTime ofInstant(java.time.Instant, java.time.ZoneId);
-    method public static java.time.OffsetTime parse(CharSequence);
-    method public static java.time.OffsetTime parse(CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.OffsetTime plus(java.time.temporal.TemporalAmount);
-    method public java.time.OffsetTime plus(long, java.time.temporal.TemporalUnit);
-    method public java.time.OffsetTime plusHours(long);
-    method public java.time.OffsetTime plusMinutes(long);
-    method public java.time.OffsetTime plusNanos(long);
-    method public java.time.OffsetTime plusSeconds(long);
-    method public java.time.LocalTime toLocalTime();
-    method public java.time.OffsetTime truncatedTo(java.time.temporal.TemporalUnit);
-    method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.OffsetTime with(java.time.temporal.TemporalAdjuster);
-    method public java.time.OffsetTime with(java.time.temporal.TemporalField, long);
-    method public java.time.OffsetTime withHour(int);
-    method public java.time.OffsetTime withMinute(int);
-    method public java.time.OffsetTime withNano(int);
-    method public java.time.OffsetTime withOffsetSameInstant(java.time.ZoneOffset);
-    method public java.time.OffsetTime withOffsetSameLocal(java.time.ZoneOffset);
-    method public java.time.OffsetTime withSecond(int);
-    field public static final java.time.OffsetTime MAX;
-    field public static final java.time.OffsetTime MIN;
-  }
-
-  public final class Period implements java.time.chrono.ChronoPeriod java.io.Serializable {
-    method public java.time.temporal.Temporal addTo(java.time.temporal.Temporal);
-    method public static java.time.Period between(java.time.LocalDate, java.time.LocalDate);
-    method public static java.time.Period from(java.time.temporal.TemporalAmount);
-    method public long get(java.time.temporal.TemporalUnit);
-    method public java.time.chrono.IsoChronology getChronology();
-    method public int getDays();
-    method public int getMonths();
-    method public java.util.List<java.time.temporal.TemporalUnit> getUnits();
-    method public int getYears();
-    method public java.time.Period minus(java.time.temporal.TemporalAmount);
-    method public java.time.Period minusDays(long);
-    method public java.time.Period minusMonths(long);
-    method public java.time.Period minusYears(long);
-    method public java.time.Period multipliedBy(int);
-    method public java.time.Period negated();
-    method public java.time.Period normalized();
-    method public static java.time.Period of(int, int, int);
-    method public static java.time.Period ofDays(int);
-    method public static java.time.Period ofMonths(int);
-    method public static java.time.Period ofWeeks(int);
-    method public static java.time.Period ofYears(int);
-    method public static java.time.Period parse(CharSequence);
-    method public java.time.Period plus(java.time.temporal.TemporalAmount);
-    method public java.time.Period plusDays(long);
-    method public java.time.Period plusMonths(long);
-    method public java.time.Period plusYears(long);
-    method public java.time.temporal.Temporal subtractFrom(java.time.temporal.Temporal);
-    method public long toTotalMonths();
-    method public java.time.Period withDays(int);
-    method public java.time.Period withMonths(int);
-    method public java.time.Period withYears(int);
-    field public static final java.time.Period ZERO;
-  }
-
-  public final class Year implements java.lang.Comparable<java.time.Year> java.io.Serializable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
-    method public java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal);
-    method public java.time.LocalDate atDay(int);
-    method public java.time.YearMonth atMonth(java.time.Month);
-    method public java.time.YearMonth atMonth(int);
-    method public java.time.LocalDate atMonthDay(java.time.MonthDay);
-    method public int compareTo(java.time.Year);
-    method public String format(java.time.format.DateTimeFormatter);
-    method public static java.time.Year from(java.time.temporal.TemporalAccessor);
-    method public long getLong(java.time.temporal.TemporalField);
-    method public int getValue();
-    method public boolean isAfter(java.time.Year);
-    method public boolean isBefore(java.time.Year);
-    method public static boolean isLeap(long);
-    method public boolean isLeap();
-    method public boolean isSupported(java.time.temporal.TemporalField);
-    method public boolean isSupported(java.time.temporal.TemporalUnit);
-    method public boolean isValidMonthDay(java.time.MonthDay);
-    method public int length();
-    method public java.time.Year minus(java.time.temporal.TemporalAmount);
-    method public java.time.Year minus(long, java.time.temporal.TemporalUnit);
-    method public java.time.Year minusYears(long);
-    method public static java.time.Year now();
-    method public static java.time.Year now(java.time.ZoneId);
-    method public static java.time.Year now(java.time.Clock);
-    method public static java.time.Year of(int);
-    method public static java.time.Year parse(CharSequence);
-    method public static java.time.Year parse(CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.Year plus(java.time.temporal.TemporalAmount);
-    method public java.time.Year plus(long, java.time.temporal.TemporalUnit);
-    method public java.time.Year plusYears(long);
-    method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.Year with(java.time.temporal.TemporalAdjuster);
-    method public java.time.Year with(java.time.temporal.TemporalField, long);
-    field public static final int MAX_VALUE = 999999999; // 0x3b9ac9ff
-    field public static final int MIN_VALUE = -999999999; // 0xc4653601
-  }
-
-  public final class YearMonth implements java.lang.Comparable<java.time.YearMonth> java.io.Serializable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
-    method public java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal);
-    method public java.time.LocalDate atDay(int);
-    method public java.time.LocalDate atEndOfMonth();
-    method public int compareTo(java.time.YearMonth);
-    method public String format(java.time.format.DateTimeFormatter);
-    method public static java.time.YearMonth from(java.time.temporal.TemporalAccessor);
-    method public long getLong(java.time.temporal.TemporalField);
-    method public java.time.Month getMonth();
-    method public int getMonthValue();
-    method public int getYear();
-    method public boolean isAfter(java.time.YearMonth);
-    method public boolean isBefore(java.time.YearMonth);
-    method public boolean isLeapYear();
-    method public boolean isSupported(java.time.temporal.TemporalField);
-    method public boolean isSupported(java.time.temporal.TemporalUnit);
-    method public boolean isValidDay(int);
-    method public int lengthOfMonth();
-    method public int lengthOfYear();
-    method public java.time.YearMonth minus(java.time.temporal.TemporalAmount);
-    method public java.time.YearMonth minus(long, java.time.temporal.TemporalUnit);
-    method public java.time.YearMonth minusMonths(long);
-    method public java.time.YearMonth minusYears(long);
-    method public static java.time.YearMonth now();
-    method public static java.time.YearMonth now(java.time.ZoneId);
-    method public static java.time.YearMonth now(java.time.Clock);
-    method public static java.time.YearMonth of(int, java.time.Month);
-    method public static java.time.YearMonth of(int, int);
-    method public static java.time.YearMonth parse(CharSequence);
-    method public static java.time.YearMonth parse(CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.YearMonth plus(java.time.temporal.TemporalAmount);
-    method public java.time.YearMonth plus(long, java.time.temporal.TemporalUnit);
-    method public java.time.YearMonth plusMonths(long);
-    method public java.time.YearMonth plusYears(long);
-    method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.YearMonth with(java.time.temporal.TemporalAdjuster);
-    method public java.time.YearMonth with(java.time.temporal.TemporalField, long);
-    method public java.time.YearMonth withMonth(int);
-    method public java.time.YearMonth withYear(int);
-  }
-
-  public abstract class ZoneId implements java.io.Serializable {
-    method public static java.time.ZoneId from(java.time.temporal.TemporalAccessor);
-    method public static java.util.Set<java.lang.String> getAvailableZoneIds();
-    method public String getDisplayName(java.time.format.TextStyle, java.util.Locale);
-    method public abstract String getId();
-    method public abstract java.time.zone.ZoneRules getRules();
-    method public java.time.ZoneId normalized();
-    method public static java.time.ZoneId of(String, java.util.Map<java.lang.String,java.lang.String>);
-    method public static java.time.ZoneId of(String);
-    method public static java.time.ZoneId ofOffset(String, java.time.ZoneOffset);
-    method public static java.time.ZoneId systemDefault();
-    field public static final java.util.Map<java.lang.String,java.lang.String> SHORT_IDS;
-  }
-
-  public final class ZoneOffset extends java.time.ZoneId implements java.lang.Comparable<java.time.ZoneOffset> java.io.Serializable java.time.temporal.TemporalAccessor java.time.temporal.TemporalAdjuster {
-    method public java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal);
-    method public int compareTo(java.time.ZoneOffset);
-    method public static java.time.ZoneOffset from(java.time.temporal.TemporalAccessor);
-    method public String getId();
-    method public long getLong(java.time.temporal.TemporalField);
-    method public java.time.zone.ZoneRules getRules();
-    method public int getTotalSeconds();
-    method public boolean isSupported(java.time.temporal.TemporalField);
-    method public static java.time.ZoneOffset of(String);
-    method public static java.time.ZoneOffset ofHours(int);
-    method public static java.time.ZoneOffset ofHoursMinutes(int, int);
-    method public static java.time.ZoneOffset ofHoursMinutesSeconds(int, int, int);
-    method public static java.time.ZoneOffset ofTotalSeconds(int);
-    field public static final java.time.ZoneOffset MAX;
-    field public static final java.time.ZoneOffset MIN;
-    field public static final java.time.ZoneOffset UTC;
-  }
-
-  public final class ZonedDateTime implements java.time.chrono.ChronoZonedDateTime<java.time.LocalDate> java.io.Serializable java.time.temporal.Temporal {
-    method public static java.time.ZonedDateTime from(java.time.temporal.TemporalAccessor);
-    method public int getDayOfMonth();
-    method public java.time.DayOfWeek getDayOfWeek();
-    method public int getDayOfYear();
-    method public int getHour();
-    method public int getMinute();
-    method public java.time.Month getMonth();
-    method public int getMonthValue();
-    method public int getNano();
-    method public java.time.ZoneOffset getOffset();
-    method public int getSecond();
-    method public int getYear();
-    method public java.time.ZoneId getZone();
-    method public boolean isSupported(java.time.temporal.TemporalField);
-    method public java.time.ZonedDateTime minus(java.time.temporal.TemporalAmount);
-    method public java.time.ZonedDateTime minus(long, java.time.temporal.TemporalUnit);
-    method public java.time.ZonedDateTime minusDays(long);
-    method public java.time.ZonedDateTime minusHours(long);
-    method public java.time.ZonedDateTime minusMinutes(long);
-    method public java.time.ZonedDateTime minusMonths(long);
-    method public java.time.ZonedDateTime minusNanos(long);
-    method public java.time.ZonedDateTime minusSeconds(long);
-    method public java.time.ZonedDateTime minusWeeks(long);
-    method public java.time.ZonedDateTime minusYears(long);
-    method public static java.time.ZonedDateTime now();
-    method public static java.time.ZonedDateTime now(java.time.ZoneId);
-    method public static java.time.ZonedDateTime now(java.time.Clock);
-    method public static java.time.ZonedDateTime of(java.time.LocalDate, java.time.LocalTime, java.time.ZoneId);
-    method public static java.time.ZonedDateTime of(java.time.LocalDateTime, java.time.ZoneId);
-    method public static java.time.ZonedDateTime of(int, int, int, int, int, int, int, java.time.ZoneId);
-    method public static java.time.ZonedDateTime ofInstant(java.time.Instant, java.time.ZoneId);
-    method public static java.time.ZonedDateTime ofInstant(java.time.LocalDateTime, java.time.ZoneOffset, java.time.ZoneId);
-    method public static java.time.ZonedDateTime ofLocal(java.time.LocalDateTime, java.time.ZoneId, java.time.ZoneOffset);
-    method public static java.time.ZonedDateTime ofStrict(java.time.LocalDateTime, java.time.ZoneOffset, java.time.ZoneId);
-    method public static java.time.ZonedDateTime parse(CharSequence);
-    method public static java.time.ZonedDateTime parse(CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.ZonedDateTime plus(java.time.temporal.TemporalAmount);
-    method public java.time.ZonedDateTime plus(long, java.time.temporal.TemporalUnit);
-    method public java.time.ZonedDateTime plusDays(long);
-    method public java.time.ZonedDateTime plusHours(long);
-    method public java.time.ZonedDateTime plusMinutes(long);
-    method public java.time.ZonedDateTime plusMonths(long);
-    method public java.time.ZonedDateTime plusNanos(long);
-    method public java.time.ZonedDateTime plusSeconds(long);
-    method public java.time.ZonedDateTime plusWeeks(long);
-    method public java.time.ZonedDateTime plusYears(long);
-    method public java.time.LocalDate toLocalDate();
-    method public java.time.LocalDateTime toLocalDateTime();
-    method public java.time.OffsetDateTime toOffsetDateTime();
-    method public java.time.ZonedDateTime truncatedTo(java.time.temporal.TemporalUnit);
-    method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.ZonedDateTime with(java.time.temporal.TemporalAdjuster);
-    method public java.time.ZonedDateTime with(java.time.temporal.TemporalField, long);
-    method public java.time.ZonedDateTime withDayOfMonth(int);
-    method public java.time.ZonedDateTime withDayOfYear(int);
-    method public java.time.ZonedDateTime withEarlierOffsetAtOverlap();
-    method public java.time.ZonedDateTime withFixedOffsetZone();
-    method public java.time.ZonedDateTime withHour(int);
-    method public java.time.ZonedDateTime withLaterOffsetAtOverlap();
-    method public java.time.ZonedDateTime withMinute(int);
-    method public java.time.ZonedDateTime withMonth(int);
-    method public java.time.ZonedDateTime withNano(int);
-    method public java.time.ZonedDateTime withSecond(int);
-    method public java.time.ZonedDateTime withYear(int);
-    method public java.time.ZonedDateTime withZoneSameInstant(java.time.ZoneId);
-    method public java.time.ZonedDateTime withZoneSameLocal(java.time.ZoneId);
-  }
-
-}
-
-package java.time.chrono {
-
-  public abstract class AbstractChronology implements java.time.chrono.Chronology {
-    ctor protected AbstractChronology();
-    method public int compareTo(java.time.chrono.Chronology);
-    method public java.time.chrono.ChronoLocalDate resolveDate(java.util.Map<java.time.temporal.TemporalField,java.lang.Long>, java.time.format.ResolverStyle);
-  }
-
-  public interface ChronoLocalDate extends java.time.temporal.Temporal java.lang.Comparable<java.time.chrono.ChronoLocalDate> java.time.temporal.TemporalAdjuster {
-    method public default java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal);
-    method public default java.time.chrono.ChronoLocalDateTime<?> atTime(java.time.LocalTime);
-    method public default int compareTo(java.time.chrono.ChronoLocalDate);
-    method public boolean equals(Object);
-    method public default String format(java.time.format.DateTimeFormatter);
-    method public static java.time.chrono.ChronoLocalDate from(java.time.temporal.TemporalAccessor);
-    method public java.time.chrono.Chronology getChronology();
-    method public default java.time.chrono.Era getEra();
-    method public int hashCode();
-    method public default boolean isAfter(java.time.chrono.ChronoLocalDate);
-    method public default boolean isBefore(java.time.chrono.ChronoLocalDate);
-    method public default boolean isEqual(java.time.chrono.ChronoLocalDate);
-    method public default boolean isLeapYear();
-    method public default boolean isSupported(java.time.temporal.TemporalField);
-    method public default boolean isSupported(java.time.temporal.TemporalUnit);
-    method public int lengthOfMonth();
-    method public default int lengthOfYear();
-    method public default java.time.chrono.ChronoLocalDate minus(java.time.temporal.TemporalAmount);
-    method public default java.time.chrono.ChronoLocalDate minus(long, java.time.temporal.TemporalUnit);
-    method public default java.time.chrono.ChronoLocalDate plus(java.time.temporal.TemporalAmount);
-    method public default java.time.chrono.ChronoLocalDate plus(long, java.time.temporal.TemporalUnit);
-    method public static java.util.Comparator<java.time.chrono.ChronoLocalDate> timeLineOrder();
-    method public default long toEpochDay();
-    method public String toString();
-    method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
-    method public default java.time.chrono.ChronoLocalDate with(java.time.temporal.TemporalAdjuster);
-    method public default java.time.chrono.ChronoLocalDate with(java.time.temporal.TemporalField, long);
-  }
-
-  public interface ChronoLocalDateTime<D extends java.time.chrono.ChronoLocalDate> extends java.time.temporal.Temporal java.lang.Comparable<java.time.chrono.ChronoLocalDateTime<?>> java.time.temporal.TemporalAdjuster {
-    method public default java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal);
-    method public java.time.chrono.ChronoZonedDateTime<D> atZone(java.time.ZoneId);
-    method public default int compareTo(java.time.chrono.ChronoLocalDateTime<?>);
-    method public boolean equals(Object);
-    method public default String format(java.time.format.DateTimeFormatter);
-    method public static java.time.chrono.ChronoLocalDateTime<?> from(java.time.temporal.TemporalAccessor);
-    method public default java.time.chrono.Chronology getChronology();
-    method public int hashCode();
-    method public default boolean isAfter(java.time.chrono.ChronoLocalDateTime<?>);
-    method public default boolean isBefore(java.time.chrono.ChronoLocalDateTime<?>);
-    method public default boolean isEqual(java.time.chrono.ChronoLocalDateTime<?>);
-    method public default boolean isSupported(java.time.temporal.TemporalUnit);
-    method public default java.time.chrono.ChronoLocalDateTime<D> minus(java.time.temporal.TemporalAmount);
-    method public default java.time.chrono.ChronoLocalDateTime<D> minus(long, java.time.temporal.TemporalUnit);
-    method public default java.time.chrono.ChronoLocalDateTime<D> plus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.ChronoLocalDateTime<D> plus(long, java.time.temporal.TemporalUnit);
-    method public static java.util.Comparator<java.time.chrono.ChronoLocalDateTime<?>> timeLineOrder();
-    method public default long toEpochSecond(java.time.ZoneOffset);
-    method public default java.time.Instant toInstant(java.time.ZoneOffset);
-    method public D toLocalDate();
-    method public java.time.LocalTime toLocalTime();
-    method public String toString();
-    method public default java.time.chrono.ChronoLocalDateTime<D> with(java.time.temporal.TemporalAdjuster);
-    method public java.time.chrono.ChronoLocalDateTime<D> with(java.time.temporal.TemporalField, long);
-  }
-
-  public interface ChronoPeriod extends java.time.temporal.TemporalAmount {
-    method public static java.time.chrono.ChronoPeriod between(java.time.chrono.ChronoLocalDate, java.time.chrono.ChronoLocalDate);
-    method public boolean equals(Object);
-    method public java.time.chrono.Chronology getChronology();
-    method public int hashCode();
-    method public default boolean isNegative();
-    method public default boolean isZero();
-    method public java.time.chrono.ChronoPeriod minus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.ChronoPeriod multipliedBy(int);
-    method public default java.time.chrono.ChronoPeriod negated();
-    method public java.time.chrono.ChronoPeriod normalized();
-    method public java.time.chrono.ChronoPeriod plus(java.time.temporal.TemporalAmount);
-    method public String toString();
-  }
-
-  public interface ChronoZonedDateTime<D extends java.time.chrono.ChronoLocalDate> extends java.time.temporal.Temporal java.lang.Comparable<java.time.chrono.ChronoZonedDateTime<?>> {
-    method public default int compareTo(java.time.chrono.ChronoZonedDateTime<?>);
-    method public boolean equals(Object);
-    method public default String format(java.time.format.DateTimeFormatter);
-    method public static java.time.chrono.ChronoZonedDateTime<?> from(java.time.temporal.TemporalAccessor);
-    method public default java.time.chrono.Chronology getChronology();
-    method public default long getLong(java.time.temporal.TemporalField);
-    method public java.time.ZoneOffset getOffset();
-    method public java.time.ZoneId getZone();
-    method public int hashCode();
-    method public default boolean isAfter(java.time.chrono.ChronoZonedDateTime<?>);
-    method public default boolean isBefore(java.time.chrono.ChronoZonedDateTime<?>);
-    method public default boolean isEqual(java.time.chrono.ChronoZonedDateTime<?>);
-    method public default boolean isSupported(java.time.temporal.TemporalUnit);
-    method public default java.time.chrono.ChronoZonedDateTime<D> minus(java.time.temporal.TemporalAmount);
-    method public default java.time.chrono.ChronoZonedDateTime<D> minus(long, java.time.temporal.TemporalUnit);
-    method public default java.time.chrono.ChronoZonedDateTime<D> plus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.ChronoZonedDateTime<D> plus(long, java.time.temporal.TemporalUnit);
-    method public static java.util.Comparator<java.time.chrono.ChronoZonedDateTime<?>> timeLineOrder();
-    method public default long toEpochSecond();
-    method public default java.time.Instant toInstant();
-    method public default D toLocalDate();
-    method public java.time.chrono.ChronoLocalDateTime<D> toLocalDateTime();
-    method public default java.time.LocalTime toLocalTime();
-    method public String toString();
-    method public default java.time.chrono.ChronoZonedDateTime<D> with(java.time.temporal.TemporalAdjuster);
-    method public java.time.chrono.ChronoZonedDateTime<D> with(java.time.temporal.TemporalField, long);
-    method public java.time.chrono.ChronoZonedDateTime<D> withEarlierOffsetAtOverlap();
-    method public java.time.chrono.ChronoZonedDateTime<D> withLaterOffsetAtOverlap();
-    method public java.time.chrono.ChronoZonedDateTime<D> withZoneSameInstant(java.time.ZoneId);
-    method public java.time.chrono.ChronoZonedDateTime<D> withZoneSameLocal(java.time.ZoneId);
-  }
-
-  public interface Chronology extends java.lang.Comparable<java.time.chrono.Chronology> {
-    method public int compareTo(java.time.chrono.Chronology);
-    method public default java.time.chrono.ChronoLocalDate date(java.time.chrono.Era, int, int, int);
-    method public java.time.chrono.ChronoLocalDate date(int, int, int);
-    method public java.time.chrono.ChronoLocalDate date(java.time.temporal.TemporalAccessor);
-    method public java.time.chrono.ChronoLocalDate dateEpochDay(long);
-    method public default java.time.chrono.ChronoLocalDate dateNow();
-    method public default java.time.chrono.ChronoLocalDate dateNow(java.time.ZoneId);
-    method public default java.time.chrono.ChronoLocalDate dateNow(java.time.Clock);
-    method public default java.time.chrono.ChronoLocalDate dateYearDay(java.time.chrono.Era, int, int);
-    method public java.time.chrono.ChronoLocalDate dateYearDay(int, int);
-    method public boolean equals(Object);
-    method public java.time.chrono.Era eraOf(int);
-    method public java.util.List<java.time.chrono.Era> eras();
-    method public static java.time.chrono.Chronology from(java.time.temporal.TemporalAccessor);
-    method public static java.util.Set<java.time.chrono.Chronology> getAvailableChronologies();
-    method public String getCalendarType();
-    method public default String getDisplayName(java.time.format.TextStyle, java.util.Locale);
-    method public String getId();
-    method public int hashCode();
-    method public boolean isLeapYear(long);
-    method public default java.time.chrono.ChronoLocalDateTime<? extends java.time.chrono.ChronoLocalDate> localDateTime(java.time.temporal.TemporalAccessor);
-    method public static java.time.chrono.Chronology of(String);
-    method public static java.time.chrono.Chronology ofLocale(java.util.Locale);
-    method public default java.time.chrono.ChronoPeriod period(int, int, int);
-    method public int prolepticYear(java.time.chrono.Era, int);
-    method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
-    method public java.time.chrono.ChronoLocalDate resolveDate(java.util.Map<java.time.temporal.TemporalField,java.lang.Long>, java.time.format.ResolverStyle);
-    method public String toString();
-    method public default java.time.chrono.ChronoZonedDateTime<? extends java.time.chrono.ChronoLocalDate> zonedDateTime(java.time.temporal.TemporalAccessor);
-    method public default java.time.chrono.ChronoZonedDateTime<? extends java.time.chrono.ChronoLocalDate> zonedDateTime(java.time.Instant, java.time.ZoneId);
-  }
-
-  public interface Era extends java.time.temporal.TemporalAccessor java.time.temporal.TemporalAdjuster {
-    method public default java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal);
-    method public default String getDisplayName(java.time.format.TextStyle, java.util.Locale);
-    method public default long getLong(java.time.temporal.TemporalField);
-    method public int getValue();
-    method public default boolean isSupported(java.time.temporal.TemporalField);
-  }
-
-  public final class HijrahChronology extends java.time.chrono.AbstractChronology implements java.io.Serializable {
-    method public java.time.chrono.HijrahDate date(java.time.chrono.Era, int, int, int);
-    method public java.time.chrono.HijrahDate date(int, int, int);
-    method public java.time.chrono.HijrahDate date(java.time.temporal.TemporalAccessor);
-    method public java.time.chrono.HijrahDate dateEpochDay(long);
-    method public java.time.chrono.HijrahDate dateNow();
-    method public java.time.chrono.HijrahDate dateNow(java.time.ZoneId);
-    method public java.time.chrono.HijrahDate dateNow(java.time.Clock);
-    method public java.time.chrono.HijrahDate dateYearDay(java.time.chrono.Era, int, int);
-    method public java.time.chrono.HijrahDate dateYearDay(int, int);
-    method public java.time.chrono.HijrahEra eraOf(int);
-    method public java.util.List<java.time.chrono.Era> eras();
-    method public String getCalendarType();
-    method public String getId();
-    method public boolean isLeapYear(long);
-    method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.HijrahDate> localDateTime(java.time.temporal.TemporalAccessor);
-    method public int prolepticYear(java.time.chrono.Era, int);
-    method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
-    method public java.time.chrono.HijrahDate resolveDate(java.util.Map<java.time.temporal.TemporalField,java.lang.Long>, java.time.format.ResolverStyle);
-    method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.HijrahDate> zonedDateTime(java.time.temporal.TemporalAccessor);
-    method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.HijrahDate> zonedDateTime(java.time.Instant, java.time.ZoneId);
-    field public static final java.time.chrono.HijrahChronology INSTANCE;
-  }
-
-  public final class HijrahDate implements java.time.chrono.ChronoLocalDate java.io.Serializable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
-    method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.HijrahDate> atTime(java.time.LocalTime);
-    method public static java.time.chrono.HijrahDate from(java.time.temporal.TemporalAccessor);
-    method public java.time.chrono.HijrahChronology getChronology();
-    method public java.time.chrono.HijrahEra getEra();
-    method public long getLong(java.time.temporal.TemporalField);
-    method public int lengthOfMonth();
-    method public java.time.chrono.HijrahDate minus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.HijrahDate minus(long, java.time.temporal.TemporalUnit);
-    method public static java.time.chrono.HijrahDate now();
-    method public static java.time.chrono.HijrahDate now(java.time.ZoneId);
-    method public static java.time.chrono.HijrahDate now(java.time.Clock);
-    method public static java.time.chrono.HijrahDate of(int, int, int);
-    method public java.time.chrono.HijrahDate plus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.HijrahDate plus(long, java.time.temporal.TemporalUnit);
-    method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
-    method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.chrono.HijrahDate with(java.time.temporal.TemporalField, long);
-    method public java.time.chrono.HijrahDate with(java.time.temporal.TemporalAdjuster);
-    method public java.time.chrono.HijrahDate withVariant(java.time.chrono.HijrahChronology);
-  }
-
-  public enum HijrahEra implements java.time.chrono.Era {
-    method public int getValue();
-    method public static java.time.chrono.HijrahEra of(int);
-    enum_constant public static final java.time.chrono.HijrahEra AH;
-  }
-
-  public final class IsoChronology extends java.time.chrono.AbstractChronology implements java.io.Serializable {
-    method public java.time.LocalDate date(java.time.chrono.Era, int, int, int);
-    method public java.time.LocalDate date(int, int, int);
-    method public java.time.LocalDate date(java.time.temporal.TemporalAccessor);
-    method public java.time.LocalDate dateEpochDay(long);
-    method public java.time.LocalDate dateNow();
-    method public java.time.LocalDate dateNow(java.time.ZoneId);
-    method public java.time.LocalDate dateNow(java.time.Clock);
-    method public java.time.LocalDate dateYearDay(java.time.chrono.Era, int, int);
-    method public java.time.LocalDate dateYearDay(int, int);
-    method public java.time.chrono.IsoEra eraOf(int);
-    method public java.util.List<java.time.chrono.Era> eras();
-    method public String getCalendarType();
-    method public String getId();
-    method public boolean isLeapYear(long);
-    method public java.time.LocalDateTime localDateTime(java.time.temporal.TemporalAccessor);
-    method public java.time.Period period(int, int, int);
-    method public int prolepticYear(java.time.chrono.Era, int);
-    method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
-    method public java.time.LocalDate resolveDate(java.util.Map<java.time.temporal.TemporalField,java.lang.Long>, java.time.format.ResolverStyle);
-    method public java.time.ZonedDateTime zonedDateTime(java.time.temporal.TemporalAccessor);
-    method public java.time.ZonedDateTime zonedDateTime(java.time.Instant, java.time.ZoneId);
-    field public static final java.time.chrono.IsoChronology INSTANCE;
-  }
-
-  public enum IsoEra implements java.time.chrono.Era {
-    method public int getValue();
-    method public static java.time.chrono.IsoEra of(int);
-    enum_constant public static final java.time.chrono.IsoEra BCE;
-    enum_constant public static final java.time.chrono.IsoEra CE;
-  }
-
-  public final class JapaneseChronology extends java.time.chrono.AbstractChronology implements java.io.Serializable {
-    method public java.time.chrono.JapaneseDate date(java.time.chrono.Era, int, int, int);
-    method public java.time.chrono.JapaneseDate date(int, int, int);
-    method public java.time.chrono.JapaneseDate date(java.time.temporal.TemporalAccessor);
-    method public java.time.chrono.JapaneseDate dateEpochDay(long);
-    method public java.time.chrono.JapaneseDate dateNow();
-    method public java.time.chrono.JapaneseDate dateNow(java.time.ZoneId);
-    method public java.time.chrono.JapaneseDate dateNow(java.time.Clock);
-    method public java.time.chrono.JapaneseDate dateYearDay(java.time.chrono.Era, int, int);
-    method public java.time.chrono.JapaneseDate dateYearDay(int, int);
-    method public java.time.chrono.JapaneseEra eraOf(int);
-    method public java.util.List<java.time.chrono.Era> eras();
-    method public String getCalendarType();
-    method public String getId();
-    method public boolean isLeapYear(long);
-    method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.JapaneseDate> localDateTime(java.time.temporal.TemporalAccessor);
-    method public int prolepticYear(java.time.chrono.Era, int);
-    method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
-    method public java.time.chrono.JapaneseDate resolveDate(java.util.Map<java.time.temporal.TemporalField,java.lang.Long>, java.time.format.ResolverStyle);
-    method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.JapaneseDate> zonedDateTime(java.time.temporal.TemporalAccessor);
-    method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.JapaneseDate> zonedDateTime(java.time.Instant, java.time.ZoneId);
-    field public static final java.time.chrono.JapaneseChronology INSTANCE;
-  }
-
-  public final class JapaneseDate implements java.time.chrono.ChronoLocalDate java.io.Serializable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
-    method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.JapaneseDate> atTime(java.time.LocalTime);
-    method public static java.time.chrono.JapaneseDate from(java.time.temporal.TemporalAccessor);
-    method public java.time.chrono.JapaneseChronology getChronology();
-    method public java.time.chrono.JapaneseEra getEra();
-    method public long getLong(java.time.temporal.TemporalField);
-    method public int lengthOfMonth();
-    method public java.time.chrono.JapaneseDate minus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.JapaneseDate minus(long, java.time.temporal.TemporalUnit);
-    method public static java.time.chrono.JapaneseDate now();
-    method public static java.time.chrono.JapaneseDate now(java.time.ZoneId);
-    method public static java.time.chrono.JapaneseDate now(java.time.Clock);
-    method public static java.time.chrono.JapaneseDate of(java.time.chrono.JapaneseEra, int, int, int);
-    method public static java.time.chrono.JapaneseDate of(int, int, int);
-    method public java.time.chrono.JapaneseDate plus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.JapaneseDate plus(long, java.time.temporal.TemporalUnit);
-    method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
-    method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.chrono.JapaneseDate with(java.time.temporal.TemporalField, long);
-    method public java.time.chrono.JapaneseDate with(java.time.temporal.TemporalAdjuster);
-  }
-
-  public final class JapaneseEra implements java.time.chrono.Era java.io.Serializable {
-    method public int getValue();
-    method public static java.time.chrono.JapaneseEra of(int);
-    method public static java.time.chrono.JapaneseEra valueOf(String);
-    method public static java.time.chrono.JapaneseEra[] values();
-    field public static final java.time.chrono.JapaneseEra HEISEI;
-    field public static final java.time.chrono.JapaneseEra MEIJI;
-    field public static final java.time.chrono.JapaneseEra REIWA;
-    field public static final java.time.chrono.JapaneseEra SHOWA;
-    field public static final java.time.chrono.JapaneseEra TAISHO;
-  }
-
-  public final class MinguoChronology extends java.time.chrono.AbstractChronology implements java.io.Serializable {
-    method public java.time.chrono.MinguoDate date(java.time.chrono.Era, int, int, int);
-    method public java.time.chrono.MinguoDate date(int, int, int);
-    method public java.time.chrono.MinguoDate date(java.time.temporal.TemporalAccessor);
-    method public java.time.chrono.MinguoDate dateEpochDay(long);
-    method public java.time.chrono.MinguoDate dateNow();
-    method public java.time.chrono.MinguoDate dateNow(java.time.ZoneId);
-    method public java.time.chrono.MinguoDate dateNow(java.time.Clock);
-    method public java.time.chrono.MinguoDate dateYearDay(java.time.chrono.Era, int, int);
-    method public java.time.chrono.MinguoDate dateYearDay(int, int);
-    method public java.time.chrono.MinguoEra eraOf(int);
-    method public java.util.List<java.time.chrono.Era> eras();
-    method public String getCalendarType();
-    method public String getId();
-    method public boolean isLeapYear(long);
-    method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.MinguoDate> localDateTime(java.time.temporal.TemporalAccessor);
-    method public int prolepticYear(java.time.chrono.Era, int);
-    method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
-    method public java.time.chrono.MinguoDate resolveDate(java.util.Map<java.time.temporal.TemporalField,java.lang.Long>, java.time.format.ResolverStyle);
-    method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.MinguoDate> zonedDateTime(java.time.temporal.TemporalAccessor);
-    method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.MinguoDate> zonedDateTime(java.time.Instant, java.time.ZoneId);
-    field public static final java.time.chrono.MinguoChronology INSTANCE;
-  }
-
-  public final class MinguoDate implements java.time.chrono.ChronoLocalDate java.io.Serializable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
-    method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.MinguoDate> atTime(java.time.LocalTime);
-    method public static java.time.chrono.MinguoDate from(java.time.temporal.TemporalAccessor);
-    method public java.time.chrono.MinguoChronology getChronology();
-    method public java.time.chrono.MinguoEra getEra();
-    method public long getLong(java.time.temporal.TemporalField);
-    method public int lengthOfMonth();
-    method public java.time.chrono.MinguoDate minus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.MinguoDate minus(long, java.time.temporal.TemporalUnit);
-    method public static java.time.chrono.MinguoDate now();
-    method public static java.time.chrono.MinguoDate now(java.time.ZoneId);
-    method public static java.time.chrono.MinguoDate now(java.time.Clock);
-    method public static java.time.chrono.MinguoDate of(int, int, int);
-    method public java.time.chrono.MinguoDate plus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.MinguoDate plus(long, java.time.temporal.TemporalUnit);
-    method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
-    method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.chrono.MinguoDate with(java.time.temporal.TemporalField, long);
-    method public java.time.chrono.MinguoDate with(java.time.temporal.TemporalAdjuster);
-  }
-
-  public enum MinguoEra implements java.time.chrono.Era {
-    method public int getValue();
-    method public static java.time.chrono.MinguoEra of(int);
-    enum_constant public static final java.time.chrono.MinguoEra BEFORE_ROC;
-    enum_constant public static final java.time.chrono.MinguoEra ROC;
-  }
-
-  public final class ThaiBuddhistChronology extends java.time.chrono.AbstractChronology implements java.io.Serializable {
-    method public java.time.chrono.ThaiBuddhistDate date(java.time.chrono.Era, int, int, int);
-    method public java.time.chrono.ThaiBuddhistDate date(int, int, int);
-    method public java.time.chrono.ThaiBuddhistDate date(java.time.temporal.TemporalAccessor);
-    method public java.time.chrono.ThaiBuddhistDate dateEpochDay(long);
-    method public java.time.chrono.ThaiBuddhistDate dateNow();
-    method public java.time.chrono.ThaiBuddhistDate dateNow(java.time.ZoneId);
-    method public java.time.chrono.ThaiBuddhistDate dateNow(java.time.Clock);
-    method public java.time.chrono.ThaiBuddhistDate dateYearDay(java.time.chrono.Era, int, int);
-    method public java.time.chrono.ThaiBuddhistDate dateYearDay(int, int);
-    method public java.time.chrono.ThaiBuddhistEra eraOf(int);
-    method public java.util.List<java.time.chrono.Era> eras();
-    method public String getCalendarType();
-    method public String getId();
-    method public boolean isLeapYear(long);
-    method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.ThaiBuddhistDate> localDateTime(java.time.temporal.TemporalAccessor);
-    method public int prolepticYear(java.time.chrono.Era, int);
-    method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
-    method public java.time.chrono.ThaiBuddhistDate resolveDate(java.util.Map<java.time.temporal.TemporalField,java.lang.Long>, java.time.format.ResolverStyle);
-    method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.ThaiBuddhistDate> zonedDateTime(java.time.temporal.TemporalAccessor);
-    method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.ThaiBuddhistDate> zonedDateTime(java.time.Instant, java.time.ZoneId);
-    field public static final java.time.chrono.ThaiBuddhistChronology INSTANCE;
-  }
-
-  public final class ThaiBuddhistDate implements java.time.chrono.ChronoLocalDate java.io.Serializable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
-    method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.ThaiBuddhistDate> atTime(java.time.LocalTime);
-    method public static java.time.chrono.ThaiBuddhistDate from(java.time.temporal.TemporalAccessor);
-    method public java.time.chrono.ThaiBuddhistChronology getChronology();
-    method public java.time.chrono.ThaiBuddhistEra getEra();
-    method public long getLong(java.time.temporal.TemporalField);
-    method public int lengthOfMonth();
-    method public java.time.chrono.ThaiBuddhistDate minus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.ThaiBuddhistDate minus(long, java.time.temporal.TemporalUnit);
-    method public static java.time.chrono.ThaiBuddhistDate now();
-    method public static java.time.chrono.ThaiBuddhistDate now(java.time.ZoneId);
-    method public static java.time.chrono.ThaiBuddhistDate now(java.time.Clock);
-    method public static java.time.chrono.ThaiBuddhistDate of(int, int, int);
-    method public java.time.chrono.ThaiBuddhistDate plus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.ThaiBuddhistDate plus(long, java.time.temporal.TemporalUnit);
-    method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
-    method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.chrono.ThaiBuddhistDate with(java.time.temporal.TemporalField, long);
-    method public java.time.chrono.ThaiBuddhistDate with(java.time.temporal.TemporalAdjuster);
-  }
-
-  public enum ThaiBuddhistEra implements java.time.chrono.Era {
-    method public int getValue();
-    method public static java.time.chrono.ThaiBuddhistEra of(int);
-    enum_constant public static final java.time.chrono.ThaiBuddhistEra BE;
-    enum_constant public static final java.time.chrono.ThaiBuddhistEra BEFORE_BE;
-  }
-
-}
-
-package java.time.format {
-
-  public final class DateTimeFormatter {
-    method public String format(java.time.temporal.TemporalAccessor);
-    method public void formatTo(java.time.temporal.TemporalAccessor, Appendable);
-    method public java.time.chrono.Chronology getChronology();
-    method public java.time.format.DecimalStyle getDecimalStyle();
-    method public java.util.Locale getLocale();
-    method public java.util.Set<java.time.temporal.TemporalField> getResolverFields();
-    method public java.time.format.ResolverStyle getResolverStyle();
-    method public java.time.ZoneId getZone();
-    method public static java.time.format.DateTimeFormatter ofLocalizedDate(java.time.format.FormatStyle);
-    method public static java.time.format.DateTimeFormatter ofLocalizedDateTime(java.time.format.FormatStyle);
-    method public static java.time.format.DateTimeFormatter ofLocalizedDateTime(java.time.format.FormatStyle, java.time.format.FormatStyle);
-    method public static java.time.format.DateTimeFormatter ofLocalizedTime(java.time.format.FormatStyle);
-    method public static java.time.format.DateTimeFormatter ofPattern(String);
-    method public static java.time.format.DateTimeFormatter ofPattern(String, java.util.Locale);
-    method public java.time.temporal.TemporalAccessor parse(CharSequence);
-    method public java.time.temporal.TemporalAccessor parse(CharSequence, java.text.ParsePosition);
-    method public <T> T parse(CharSequence, java.time.temporal.TemporalQuery<T>);
-    method public java.time.temporal.TemporalAccessor parseBest(CharSequence, java.time.temporal.TemporalQuery<?>...);
-    method public java.time.temporal.TemporalAccessor parseUnresolved(CharSequence, java.text.ParsePosition);
-    method public static java.time.temporal.TemporalQuery<java.time.Period> parsedExcessDays();
-    method public static java.time.temporal.TemporalQuery<java.lang.Boolean> parsedLeapSecond();
-    method public java.text.Format toFormat();
-    method public java.text.Format toFormat(java.time.temporal.TemporalQuery<?>);
-    method public java.time.format.DateTimeFormatter withChronology(java.time.chrono.Chronology);
-    method public java.time.format.DateTimeFormatter withDecimalStyle(java.time.format.DecimalStyle);
-    method public java.time.format.DateTimeFormatter withLocale(java.util.Locale);
-    method public java.time.format.DateTimeFormatter withResolverFields(java.time.temporal.TemporalField...);
-    method public java.time.format.DateTimeFormatter withResolverFields(java.util.Set<java.time.temporal.TemporalField>);
-    method public java.time.format.DateTimeFormatter withResolverStyle(java.time.format.ResolverStyle);
-    method public java.time.format.DateTimeFormatter withZone(java.time.ZoneId);
-    field public static final java.time.format.DateTimeFormatter BASIC_ISO_DATE;
-    field public static final java.time.format.DateTimeFormatter ISO_DATE;
-    field public static final java.time.format.DateTimeFormatter ISO_DATE_TIME;
-    field public static final java.time.format.DateTimeFormatter ISO_INSTANT;
-    field public static final java.time.format.DateTimeFormatter ISO_LOCAL_DATE;
-    field public static final java.time.format.DateTimeFormatter ISO_LOCAL_DATE_TIME;
-    field public static final java.time.format.DateTimeFormatter ISO_LOCAL_TIME;
-    field public static final java.time.format.DateTimeFormatter ISO_OFFSET_DATE;
-    field public static final java.time.format.DateTimeFormatter ISO_OFFSET_DATE_TIME;
-    field public static final java.time.format.DateTimeFormatter ISO_OFFSET_TIME;
-    field public static final java.time.format.DateTimeFormatter ISO_ORDINAL_DATE;
-    field public static final java.time.format.DateTimeFormatter ISO_TIME;
-    field public static final java.time.format.DateTimeFormatter ISO_WEEK_DATE;
-    field public static final java.time.format.DateTimeFormatter ISO_ZONED_DATE_TIME;
-    field public static final java.time.format.DateTimeFormatter RFC_1123_DATE_TIME;
-  }
-
-  public final class DateTimeFormatterBuilder {
-    ctor public DateTimeFormatterBuilder();
-    method public java.time.format.DateTimeFormatterBuilder append(java.time.format.DateTimeFormatter);
-    method public java.time.format.DateTimeFormatterBuilder appendChronologyId();
-    method public java.time.format.DateTimeFormatterBuilder appendChronologyText(java.time.format.TextStyle);
-    method public java.time.format.DateTimeFormatterBuilder appendFraction(java.time.temporal.TemporalField, int, int, boolean);
-    method public java.time.format.DateTimeFormatterBuilder appendInstant();
-    method public java.time.format.DateTimeFormatterBuilder appendInstant(int);
-    method public java.time.format.DateTimeFormatterBuilder appendLiteral(char);
-    method public java.time.format.DateTimeFormatterBuilder appendLiteral(String);
-    method public java.time.format.DateTimeFormatterBuilder appendLocalized(java.time.format.FormatStyle, java.time.format.FormatStyle);
-    method public java.time.format.DateTimeFormatterBuilder appendLocalizedOffset(java.time.format.TextStyle);
-    method public java.time.format.DateTimeFormatterBuilder appendOffset(String, String);
-    method public java.time.format.DateTimeFormatterBuilder appendOffsetId();
-    method public java.time.format.DateTimeFormatterBuilder appendOptional(java.time.format.DateTimeFormatter);
-    method public java.time.format.DateTimeFormatterBuilder appendPattern(String);
-    method public java.time.format.DateTimeFormatterBuilder appendText(java.time.temporal.TemporalField);
-    method public java.time.format.DateTimeFormatterBuilder appendText(java.time.temporal.TemporalField, java.time.format.TextStyle);
-    method public java.time.format.DateTimeFormatterBuilder appendText(java.time.temporal.TemporalField, java.util.Map<java.lang.Long,java.lang.String>);
-    method public java.time.format.DateTimeFormatterBuilder appendValue(java.time.temporal.TemporalField);
-    method public java.time.format.DateTimeFormatterBuilder appendValue(java.time.temporal.TemporalField, int);
-    method public java.time.format.DateTimeFormatterBuilder appendValue(java.time.temporal.TemporalField, int, int, java.time.format.SignStyle);
-    method public java.time.format.DateTimeFormatterBuilder appendValueReduced(java.time.temporal.TemporalField, int, int, int);
-    method public java.time.format.DateTimeFormatterBuilder appendValueReduced(java.time.temporal.TemporalField, int, int, java.time.chrono.ChronoLocalDate);
-    method public java.time.format.DateTimeFormatterBuilder appendZoneId();
-    method public java.time.format.DateTimeFormatterBuilder appendZoneOrOffsetId();
-    method public java.time.format.DateTimeFormatterBuilder appendZoneRegionId();
-    method public java.time.format.DateTimeFormatterBuilder appendZoneText(java.time.format.TextStyle);
-    method public java.time.format.DateTimeFormatterBuilder appendZoneText(java.time.format.TextStyle, java.util.Set<java.time.ZoneId>);
-    method public static String getLocalizedDateTimePattern(java.time.format.FormatStyle, java.time.format.FormatStyle, java.time.chrono.Chronology, java.util.Locale);
-    method public java.time.format.DateTimeFormatterBuilder optionalEnd();
-    method public java.time.format.DateTimeFormatterBuilder optionalStart();
-    method public java.time.format.DateTimeFormatterBuilder padNext(int);
-    method public java.time.format.DateTimeFormatterBuilder padNext(int, char);
-    method public java.time.format.DateTimeFormatterBuilder parseCaseInsensitive();
-    method public java.time.format.DateTimeFormatterBuilder parseCaseSensitive();
-    method public java.time.format.DateTimeFormatterBuilder parseDefaulting(java.time.temporal.TemporalField, long);
-    method public java.time.format.DateTimeFormatterBuilder parseLenient();
-    method public java.time.format.DateTimeFormatterBuilder parseStrict();
-    method public java.time.format.DateTimeFormatter toFormatter();
-    method public java.time.format.DateTimeFormatter toFormatter(java.util.Locale);
-  }
-
-  public class DateTimeParseException extends java.time.DateTimeException {
-    ctor public DateTimeParseException(String, CharSequence, int);
-    ctor public DateTimeParseException(String, CharSequence, int, Throwable);
-    method public int getErrorIndex();
-    method public String getParsedString();
-  }
-
-  public final class DecimalStyle {
-    method public static java.util.Set<java.util.Locale> getAvailableLocales();
-    method public char getDecimalSeparator();
-    method public char getNegativeSign();
-    method public char getPositiveSign();
-    method public char getZeroDigit();
-    method public static java.time.format.DecimalStyle of(java.util.Locale);
-    method public static java.time.format.DecimalStyle ofDefaultLocale();
-    method public java.time.format.DecimalStyle withDecimalSeparator(char);
-    method public java.time.format.DecimalStyle withNegativeSign(char);
-    method public java.time.format.DecimalStyle withPositiveSign(char);
-    method public java.time.format.DecimalStyle withZeroDigit(char);
-    field public static final java.time.format.DecimalStyle STANDARD;
-  }
-
-  public enum FormatStyle {
-    enum_constant public static final java.time.format.FormatStyle FULL;
-    enum_constant public static final java.time.format.FormatStyle LONG;
-    enum_constant public static final java.time.format.FormatStyle MEDIUM;
-    enum_constant public static final java.time.format.FormatStyle SHORT;
-  }
-
-  public enum ResolverStyle {
-    enum_constant public static final java.time.format.ResolverStyle LENIENT;
-    enum_constant public static final java.time.format.ResolverStyle SMART;
-    enum_constant public static final java.time.format.ResolverStyle STRICT;
-  }
-
-  public enum SignStyle {
-    enum_constant public static final java.time.format.SignStyle ALWAYS;
-    enum_constant public static final java.time.format.SignStyle EXCEEDS_PAD;
-    enum_constant public static final java.time.format.SignStyle NEVER;
-    enum_constant public static final java.time.format.SignStyle NORMAL;
-    enum_constant public static final java.time.format.SignStyle NOT_NEGATIVE;
-  }
-
-  public enum TextStyle {
-    method public java.time.format.TextStyle asNormal();
-    method public java.time.format.TextStyle asStandalone();
-    method public boolean isStandalone();
-    enum_constant public static final java.time.format.TextStyle FULL;
-    enum_constant public static final java.time.format.TextStyle FULL_STANDALONE;
-    enum_constant public static final java.time.format.TextStyle NARROW;
-    enum_constant public static final java.time.format.TextStyle NARROW_STANDALONE;
-    enum_constant public static final java.time.format.TextStyle SHORT;
-    enum_constant public static final java.time.format.TextStyle SHORT_STANDALONE;
-  }
-
-}
-
-package java.time.temporal {
-
-  public enum ChronoField implements java.time.temporal.TemporalField {
-    method public <R extends java.time.temporal.Temporal> R adjustInto(R, long);
-    method public int checkValidIntValue(long);
-    method public long checkValidValue(long);
-    method public java.time.temporal.TemporalUnit getBaseUnit();
-    method public long getFrom(java.time.temporal.TemporalAccessor);
-    method public java.time.temporal.TemporalUnit getRangeUnit();
-    method public boolean isDateBased();
-    method public boolean isSupportedBy(java.time.temporal.TemporalAccessor);
-    method public boolean isTimeBased();
-    method public java.time.temporal.ValueRange range();
-    method public java.time.temporal.ValueRange rangeRefinedBy(java.time.temporal.TemporalAccessor);
-    enum_constant public static final java.time.temporal.ChronoField ALIGNED_DAY_OF_WEEK_IN_MONTH;
-    enum_constant public static final java.time.temporal.ChronoField ALIGNED_DAY_OF_WEEK_IN_YEAR;
-    enum_constant public static final java.time.temporal.ChronoField ALIGNED_WEEK_OF_MONTH;
-    enum_constant public static final java.time.temporal.ChronoField ALIGNED_WEEK_OF_YEAR;
-    enum_constant public static final java.time.temporal.ChronoField AMPM_OF_DAY;
-    enum_constant public static final java.time.temporal.ChronoField CLOCK_HOUR_OF_AMPM;
-    enum_constant public static final java.time.temporal.ChronoField CLOCK_HOUR_OF_DAY;
-    enum_constant public static final java.time.temporal.ChronoField DAY_OF_MONTH;
-    enum_constant public static final java.time.temporal.ChronoField DAY_OF_WEEK;
-    enum_constant public static final java.time.temporal.ChronoField DAY_OF_YEAR;
-    enum_constant public static final java.time.temporal.ChronoField EPOCH_DAY;
-    enum_constant public static final java.time.temporal.ChronoField ERA;
-    enum_constant public static final java.time.temporal.ChronoField HOUR_OF_AMPM;
-    enum_constant public static final java.time.temporal.ChronoField HOUR_OF_DAY;
-    enum_constant public static final java.time.temporal.ChronoField INSTANT_SECONDS;
-    enum_constant public static final java.time.temporal.ChronoField MICRO_OF_DAY;
-    enum_constant public static final java.time.temporal.ChronoField MICRO_OF_SECOND;
-    enum_constant public static final java.time.temporal.ChronoField MILLI_OF_DAY;
-    enum_constant public static final java.time.temporal.ChronoField MILLI_OF_SECOND;
-    enum_constant public static final java.time.temporal.ChronoField MINUTE_OF_DAY;
-    enum_constant public static final java.time.temporal.ChronoField MINUTE_OF_HOUR;
-    enum_constant public static final java.time.temporal.ChronoField MONTH_OF_YEAR;
-    enum_constant public static final java.time.temporal.ChronoField NANO_OF_DAY;
-    enum_constant public static final java.time.temporal.ChronoField NANO_OF_SECOND;
-    enum_constant public static final java.time.temporal.ChronoField OFFSET_SECONDS;
-    enum_constant public static final java.time.temporal.ChronoField PROLEPTIC_MONTH;
-    enum_constant public static final java.time.temporal.ChronoField SECOND_OF_DAY;
-    enum_constant public static final java.time.temporal.ChronoField SECOND_OF_MINUTE;
-    enum_constant public static final java.time.temporal.ChronoField YEAR;
-    enum_constant public static final java.time.temporal.ChronoField YEAR_OF_ERA;
-  }
-
-  public enum ChronoUnit implements java.time.temporal.TemporalUnit {
-    method public <R extends java.time.temporal.Temporal> R addTo(R, long);
-    method public long between(java.time.temporal.Temporal, java.time.temporal.Temporal);
-    method public java.time.Duration getDuration();
-    method public boolean isDateBased();
-    method public boolean isDurationEstimated();
-    method public boolean isTimeBased();
-    enum_constant public static final java.time.temporal.ChronoUnit CENTURIES;
-    enum_constant public static final java.time.temporal.ChronoUnit DAYS;
-    enum_constant public static final java.time.temporal.ChronoUnit DECADES;
-    enum_constant public static final java.time.temporal.ChronoUnit ERAS;
-    enum_constant public static final java.time.temporal.ChronoUnit FOREVER;
-    enum_constant public static final java.time.temporal.ChronoUnit HALF_DAYS;
-    enum_constant public static final java.time.temporal.ChronoUnit HOURS;
-    enum_constant public static final java.time.temporal.ChronoUnit MICROS;
-    enum_constant public static final java.time.temporal.ChronoUnit MILLENNIA;
-    enum_constant public static final java.time.temporal.ChronoUnit MILLIS;
-    enum_constant public static final java.time.temporal.ChronoUnit MINUTES;
-    enum_constant public static final java.time.temporal.ChronoUnit MONTHS;
-    enum_constant public static final java.time.temporal.ChronoUnit NANOS;
-    enum_constant public static final java.time.temporal.ChronoUnit SECONDS;
-    enum_constant public static final java.time.temporal.ChronoUnit WEEKS;
-    enum_constant public static final java.time.temporal.ChronoUnit YEARS;
-  }
-
-  public final class IsoFields {
-    field public static final java.time.temporal.TemporalField DAY_OF_QUARTER;
-    field public static final java.time.temporal.TemporalField QUARTER_OF_YEAR;
-    field public static final java.time.temporal.TemporalUnit QUARTER_YEARS;
-    field public static final java.time.temporal.TemporalField WEEK_BASED_YEAR;
-    field public static final java.time.temporal.TemporalUnit WEEK_BASED_YEARS;
-    field public static final java.time.temporal.TemporalField WEEK_OF_WEEK_BASED_YEAR;
-  }
-
-  public final class JulianFields {
-    field public static final java.time.temporal.TemporalField JULIAN_DAY;
-    field public static final java.time.temporal.TemporalField MODIFIED_JULIAN_DAY;
-    field public static final java.time.temporal.TemporalField RATA_DIE;
-  }
-
-  public interface Temporal extends java.time.temporal.TemporalAccessor {
-    method public boolean isSupported(java.time.temporal.TemporalUnit);
-    method public default java.time.temporal.Temporal minus(java.time.temporal.TemporalAmount);
-    method public default java.time.temporal.Temporal minus(long, java.time.temporal.TemporalUnit);
-    method public default java.time.temporal.Temporal plus(java.time.temporal.TemporalAmount);
-    method public java.time.temporal.Temporal plus(long, java.time.temporal.TemporalUnit);
-    method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public default java.time.temporal.Temporal with(java.time.temporal.TemporalAdjuster);
-    method public java.time.temporal.Temporal with(java.time.temporal.TemporalField, long);
-  }
-
-  public interface TemporalAccessor {
-    method public default int get(java.time.temporal.TemporalField);
-    method public long getLong(java.time.temporal.TemporalField);
-    method public boolean isSupported(java.time.temporal.TemporalField);
-    method public default <R> R query(java.time.temporal.TemporalQuery<R>);
-    method public default java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
-  }
-
-  @java.lang.FunctionalInterface public interface TemporalAdjuster {
-    method public java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal);
-  }
-
-  public final class TemporalAdjusters {
-    method public static java.time.temporal.TemporalAdjuster dayOfWeekInMonth(int, java.time.DayOfWeek);
-    method public static java.time.temporal.TemporalAdjuster firstDayOfMonth();
-    method public static java.time.temporal.TemporalAdjuster firstDayOfNextMonth();
-    method public static java.time.temporal.TemporalAdjuster firstDayOfNextYear();
-    method public static java.time.temporal.TemporalAdjuster firstDayOfYear();
-    method public static java.time.temporal.TemporalAdjuster firstInMonth(java.time.DayOfWeek);
-    method public static java.time.temporal.TemporalAdjuster lastDayOfMonth();
-    method public static java.time.temporal.TemporalAdjuster lastDayOfYear();
-    method public static java.time.temporal.TemporalAdjuster lastInMonth(java.time.DayOfWeek);
-    method public static java.time.temporal.TemporalAdjuster next(java.time.DayOfWeek);
-    method public static java.time.temporal.TemporalAdjuster nextOrSame(java.time.DayOfWeek);
-    method public static java.time.temporal.TemporalAdjuster ofDateAdjuster(java.util.function.UnaryOperator<java.time.LocalDate>);
-    method public static java.time.temporal.TemporalAdjuster previous(java.time.DayOfWeek);
-    method public static java.time.temporal.TemporalAdjuster previousOrSame(java.time.DayOfWeek);
-  }
-
-  public interface TemporalAmount {
-    method public java.time.temporal.Temporal addTo(java.time.temporal.Temporal);
-    method public long get(java.time.temporal.TemporalUnit);
-    method public java.util.List<java.time.temporal.TemporalUnit> getUnits();
-    method public java.time.temporal.Temporal subtractFrom(java.time.temporal.Temporal);
-  }
-
-  public interface TemporalField {
-    method public <R extends java.time.temporal.Temporal> R adjustInto(R, long);
-    method public java.time.temporal.TemporalUnit getBaseUnit();
-    method public default String getDisplayName(java.util.Locale);
-    method public long getFrom(java.time.temporal.TemporalAccessor);
-    method public java.time.temporal.TemporalUnit getRangeUnit();
-    method public boolean isDateBased();
-    method public boolean isSupportedBy(java.time.temporal.TemporalAccessor);
-    method public boolean isTimeBased();
-    method public java.time.temporal.ValueRange range();
-    method public java.time.temporal.ValueRange rangeRefinedBy(java.time.temporal.TemporalAccessor);
-    method public default java.time.temporal.TemporalAccessor resolve(java.util.Map<java.time.temporal.TemporalField,java.lang.Long>, java.time.temporal.TemporalAccessor, java.time.format.ResolverStyle);
-    method public String toString();
-  }
-
-  public final class TemporalQueries {
-    method public static java.time.temporal.TemporalQuery<java.time.chrono.Chronology> chronology();
-    method public static java.time.temporal.TemporalQuery<java.time.LocalDate> localDate();
-    method public static java.time.temporal.TemporalQuery<java.time.LocalTime> localTime();
-    method public static java.time.temporal.TemporalQuery<java.time.ZoneOffset> offset();
-    method public static java.time.temporal.TemporalQuery<java.time.temporal.TemporalUnit> precision();
-    method public static java.time.temporal.TemporalQuery<java.time.ZoneId> zone();
-    method public static java.time.temporal.TemporalQuery<java.time.ZoneId> zoneId();
-  }
-
-  @java.lang.FunctionalInterface public interface TemporalQuery<R> {
-    method public R queryFrom(java.time.temporal.TemporalAccessor);
-  }
-
-  public interface TemporalUnit {
-    method public <R extends java.time.temporal.Temporal> R addTo(R, long);
-    method public long between(java.time.temporal.Temporal, java.time.temporal.Temporal);
-    method public java.time.Duration getDuration();
-    method public boolean isDateBased();
-    method public boolean isDurationEstimated();
-    method public default boolean isSupportedBy(java.time.temporal.Temporal);
-    method public boolean isTimeBased();
-    method public String toString();
-  }
-
-  public class UnsupportedTemporalTypeException extends java.time.DateTimeException {
-    ctor public UnsupportedTemporalTypeException(String);
-    ctor public UnsupportedTemporalTypeException(String, Throwable);
-  }
-
-  public final class ValueRange implements java.io.Serializable {
-    method public int checkValidIntValue(long, java.time.temporal.TemporalField);
-    method public long checkValidValue(long, java.time.temporal.TemporalField);
-    method public long getLargestMinimum();
-    method public long getMaximum();
-    method public long getMinimum();
-    method public long getSmallestMaximum();
-    method public boolean isFixed();
-    method public boolean isIntValue();
-    method public boolean isValidIntValue(long);
-    method public boolean isValidValue(long);
-    method public static java.time.temporal.ValueRange of(long, long);
-    method public static java.time.temporal.ValueRange of(long, long, long);
-    method public static java.time.temporal.ValueRange of(long, long, long, long);
-  }
-
-  public final class WeekFields implements java.io.Serializable {
-    method public java.time.temporal.TemporalField dayOfWeek();
-    method public java.time.DayOfWeek getFirstDayOfWeek();
-    method public int getMinimalDaysInFirstWeek();
-    method public static java.time.temporal.WeekFields of(java.util.Locale);
-    method public static java.time.temporal.WeekFields of(java.time.DayOfWeek, int);
-    method public java.time.temporal.TemporalField weekBasedYear();
-    method public java.time.temporal.TemporalField weekOfMonth();
-    method public java.time.temporal.TemporalField weekOfWeekBasedYear();
-    method public java.time.temporal.TemporalField weekOfYear();
-    field public static final java.time.temporal.WeekFields ISO;
-    field public static final java.time.temporal.WeekFields SUNDAY_START;
-    field public static final java.time.temporal.TemporalUnit WEEK_BASED_YEARS;
-  }
-
-}
-
-package java.time.zone {
-
-  public final class ZoneOffsetTransition implements java.lang.Comparable<java.time.zone.ZoneOffsetTransition> java.io.Serializable {
-    method public int compareTo(java.time.zone.ZoneOffsetTransition);
-    method public java.time.LocalDateTime getDateTimeAfter();
-    method public java.time.LocalDateTime getDateTimeBefore();
-    method public java.time.Duration getDuration();
-    method public java.time.Instant getInstant();
-    method public java.time.ZoneOffset getOffsetAfter();
-    method public java.time.ZoneOffset getOffsetBefore();
-    method public boolean isGap();
-    method public boolean isOverlap();
-    method public boolean isValidOffset(java.time.ZoneOffset);
-    method public static java.time.zone.ZoneOffsetTransition of(java.time.LocalDateTime, java.time.ZoneOffset, java.time.ZoneOffset);
-    method public long toEpochSecond();
-  }
-
-  public final class ZoneOffsetTransitionRule implements java.io.Serializable {
-    method public java.time.zone.ZoneOffsetTransition createTransition(int);
-    method public int getDayOfMonthIndicator();
-    method public java.time.DayOfWeek getDayOfWeek();
-    method public java.time.LocalTime getLocalTime();
-    method public java.time.Month getMonth();
-    method public java.time.ZoneOffset getOffsetAfter();
-    method public java.time.ZoneOffset getOffsetBefore();
-    method public java.time.ZoneOffset getStandardOffset();
-    method public java.time.zone.ZoneOffsetTransitionRule.TimeDefinition getTimeDefinition();
-    method public boolean isMidnightEndOfDay();
-    method public static java.time.zone.ZoneOffsetTransitionRule of(java.time.Month, int, java.time.DayOfWeek, java.time.LocalTime, boolean, java.time.zone.ZoneOffsetTransitionRule.TimeDefinition, java.time.ZoneOffset, java.time.ZoneOffset, java.time.ZoneOffset);
-  }
-
-  public enum ZoneOffsetTransitionRule.TimeDefinition {
-    method public java.time.LocalDateTime createDateTime(java.time.LocalDateTime, java.time.ZoneOffset, java.time.ZoneOffset);
-    enum_constant public static final java.time.zone.ZoneOffsetTransitionRule.TimeDefinition STANDARD;
-    enum_constant public static final java.time.zone.ZoneOffsetTransitionRule.TimeDefinition UTC;
-    enum_constant public static final java.time.zone.ZoneOffsetTransitionRule.TimeDefinition WALL;
-  }
-
-  public final class ZoneRules implements java.io.Serializable {
-    method public java.time.Duration getDaylightSavings(java.time.Instant);
-    method public java.time.ZoneOffset getOffset(java.time.Instant);
-    method public java.time.ZoneOffset getOffset(java.time.LocalDateTime);
-    method public java.time.ZoneOffset getStandardOffset(java.time.Instant);
-    method public java.time.zone.ZoneOffsetTransition getTransition(java.time.LocalDateTime);
-    method public java.util.List<java.time.zone.ZoneOffsetTransitionRule> getTransitionRules();
-    method public java.util.List<java.time.zone.ZoneOffsetTransition> getTransitions();
-    method public java.util.List<java.time.ZoneOffset> getValidOffsets(java.time.LocalDateTime);
-    method public boolean isDaylightSavings(java.time.Instant);
-    method public boolean isFixedOffset();
-    method public boolean isValidOffset(java.time.LocalDateTime, java.time.ZoneOffset);
-    method public java.time.zone.ZoneOffsetTransition nextTransition(java.time.Instant);
-    method public static java.time.zone.ZoneRules of(java.time.ZoneOffset, java.time.ZoneOffset, java.util.List<java.time.zone.ZoneOffsetTransition>, java.util.List<java.time.zone.ZoneOffsetTransition>, java.util.List<java.time.zone.ZoneOffsetTransitionRule>);
-    method public static java.time.zone.ZoneRules of(java.time.ZoneOffset);
-    method public java.time.zone.ZoneOffsetTransition previousTransition(java.time.Instant);
-  }
-
-  public class ZoneRulesException extends java.time.DateTimeException {
-    ctor public ZoneRulesException(String);
-    ctor public ZoneRulesException(String, Throwable);
-  }
-
-}
-
-package java.util {
-
-  public abstract class AbstractCollection<E> implements java.util.Collection<E> {
-    ctor protected AbstractCollection();
-    method public boolean add(E);
-    method public boolean addAll(@NonNull java.util.Collection<? extends E>);
-    method public void clear();
-    method public boolean contains(@Nullable Object);
-    method public boolean containsAll(@NonNull java.util.Collection<?>);
-    method public boolean isEmpty();
-    method public boolean remove(@Nullable Object);
-    method public boolean removeAll(@NonNull java.util.Collection<?>);
-    method public boolean retainAll(@NonNull java.util.Collection<?>);
-    method @NonNull public Object[] toArray();
-    method @NonNull public <T> T[] toArray(@NonNull T[]);
-  }
-
-  public abstract class AbstractList<E> extends java.util.AbstractCollection<E> implements java.util.List<E> {
-    ctor protected AbstractList();
-    method public void add(int, E);
-    method public boolean addAll(int, @NonNull java.util.Collection<? extends E>);
-    method public int indexOf(@Nullable Object);
-    method @NonNull public java.util.Iterator<E> iterator();
-    method public int lastIndexOf(@Nullable Object);
-    method @NonNull public java.util.ListIterator<E> listIterator();
-    method @NonNull public java.util.ListIterator<E> listIterator(int);
-    method public E remove(int);
-    method protected void removeRange(int, int);
-    method public E set(int, E);
-    method @NonNull public java.util.List<E> subList(int, int);
-    field protected transient int modCount;
-  }
-
-  public abstract class AbstractMap<K, V> implements java.util.Map<K,V> {
-    ctor protected AbstractMap();
-    method public void clear();
-    method public boolean containsKey(@Nullable Object);
-    method public boolean containsValue(@Nullable Object);
-    method @Nullable public V get(@Nullable Object);
-    method public boolean isEmpty();
-    method @NonNull public java.util.Set<K> keySet();
-    method @Nullable public V put(K, V);
-    method public void putAll(@NonNull java.util.Map<? extends K,? extends V>);
-    method @Nullable public V remove(@Nullable Object);
-    method public int size();
-    method @NonNull public java.util.Collection<V> values();
-  }
-
-  public static class AbstractMap.SimpleEntry<K, V> implements java.util.Map.Entry<K,V> java.io.Serializable {
-    ctor public AbstractMap.SimpleEntry(K, V);
-    ctor public AbstractMap.SimpleEntry(@NonNull java.util.Map.Entry<? extends K,? extends V>);
-    method public K getKey();
-    method public V getValue();
-    method public V setValue(V);
-  }
-
-  public static class AbstractMap.SimpleImmutableEntry<K, V> implements java.util.Map.Entry<K,V> java.io.Serializable {
-    ctor public AbstractMap.SimpleImmutableEntry(K, V);
-    ctor public AbstractMap.SimpleImmutableEntry(@NonNull java.util.Map.Entry<? extends K,? extends V>);
-    method public K getKey();
-    method public V getValue();
-    method public V setValue(V);
-  }
-
-  public abstract class AbstractQueue<E> extends java.util.AbstractCollection<E> implements java.util.Queue<E> {
-    ctor protected AbstractQueue();
-    method public E element();
-    method public E remove();
-  }
-
-  public abstract class AbstractSequentialList<E> extends java.util.AbstractList<E> {
-    ctor protected AbstractSequentialList();
-    method public E get(int);
-  }
-
-  public abstract class AbstractSet<E> extends java.util.AbstractCollection<E> implements java.util.Set<E> {
-    ctor protected AbstractSet();
-  }
-
-  public class ArrayDeque<E> extends java.util.AbstractCollection<E> implements java.lang.Cloneable java.util.Deque<E> java.io.Serializable {
-    ctor public ArrayDeque();
-    ctor public ArrayDeque(int);
-    ctor public ArrayDeque(@NonNull java.util.Collection<? extends E>);
-    method public void addFirst(E);
-    method public void addLast(E);
-    method @NonNull public java.util.ArrayDeque<E> clone();
-    method @NonNull public java.util.Iterator<E> descendingIterator();
-    method public E element();
-    method public E getFirst();
-    method public E getLast();
-    method @NonNull public java.util.Iterator<E> iterator();
-    method public boolean offer(E);
-    method public boolean offerFirst(E);
-    method public boolean offerLast(E);
-    method @Nullable public E peek();
-    method @Nullable public E peekFirst();
-    method @Nullable public E peekLast();
-    method @Nullable public E poll();
-    method @Nullable public E pollFirst();
-    method @Nullable public E pollLast();
-    method public E pop();
-    method public void push(E);
-    method public E remove();
-    method public E removeFirst();
-    method public boolean removeFirstOccurrence(@Nullable Object);
-    method public E removeLast();
-    method public boolean removeLastOccurrence(@Nullable Object);
-    method public int size();
-  }
-
-  public class ArrayList<E> extends java.util.AbstractList<E> implements java.lang.Cloneable java.util.List<E> java.util.RandomAccess java.io.Serializable {
-    ctor public ArrayList(int);
-    ctor public ArrayList();
-    ctor public ArrayList(@NonNull java.util.Collection<? extends E>);
-    method @NonNull public Object clone();
-    method public void ensureCapacity(int);
-    method public void forEach(@NonNull java.util.function.Consumer<? super E>);
-    method public E get(int);
-    method public int size();
-    method public void trimToSize();
-  }
-
-  public class Arrays {
-    method @NonNull @java.lang.SafeVarargs public static <T> java.util.List<T> asList(@NonNull T...);
-    method public static int binarySearch(@NonNull long[], long);
-    method public static int binarySearch(@NonNull long[], int, int, long);
-    method public static int binarySearch(@NonNull int[], int);
-    method public static int binarySearch(@NonNull int[], int, int, int);
-    method public static int binarySearch(@NonNull short[], short);
-    method public static int binarySearch(@NonNull short[], int, int, short);
-    method public static int binarySearch(@NonNull char[], char);
-    method public static int binarySearch(@NonNull char[], int, int, char);
-    method public static int binarySearch(@NonNull byte[], byte);
-    method public static int binarySearch(@NonNull byte[], int, int, byte);
-    method public static int binarySearch(@NonNull double[], double);
-    method public static int binarySearch(@NonNull double[], int, int, double);
-    method public static int binarySearch(@NonNull float[], float);
-    method public static int binarySearch(@NonNull float[], int, int, float);
-    method public static int binarySearch(@NonNull Object[], @NonNull Object);
-    method public static int binarySearch(@NonNull Object[], int, int, @NonNull Object);
-    method public static <T> int binarySearch(@NonNull T[], T, @Nullable java.util.Comparator<? super T>);
-    method public static <T> int binarySearch(@NonNull T[], int, int, T, @Nullable java.util.Comparator<? super T>);
-    method @NonNull public static <T> T[] copyOf(@NonNull T[], int);
-    method @NonNull public static <T, U> T[] copyOf(@NonNull U[], int, @NonNull Class<? extends T[]>);
-    method @NonNull public static byte[] copyOf(@NonNull byte[], int);
-    method @NonNull public static short[] copyOf(@NonNull short[], int);
-    method @NonNull public static int[] copyOf(@NonNull int[], int);
-    method @NonNull public static long[] copyOf(@NonNull long[], int);
-    method @NonNull public static char[] copyOf(@NonNull char[], int);
-    method @NonNull public static float[] copyOf(@NonNull float[], int);
-    method @NonNull public static double[] copyOf(@NonNull double[], int);
-    method @NonNull public static boolean[] copyOf(@NonNull boolean[], int);
-    method @NonNull public static <T> T[] copyOfRange(@NonNull T[], int, int);
-    method @NonNull public static <T, U> T[] copyOfRange(@NonNull U[], int, int, @NonNull Class<? extends T[]>);
-    method @NonNull public static byte[] copyOfRange(@NonNull byte[], int, int);
-    method @NonNull public static short[] copyOfRange(@NonNull short[], int, int);
-    method @NonNull public static int[] copyOfRange(@NonNull int[], int, int);
-    method @NonNull public static long[] copyOfRange(@NonNull long[], int, int);
-    method @NonNull public static char[] copyOfRange(@NonNull char[], int, int);
-    method @NonNull public static float[] copyOfRange(@NonNull float[], int, int);
-    method @NonNull public static double[] copyOfRange(@NonNull double[], int, int);
-    method @NonNull public static boolean[] copyOfRange(@NonNull boolean[], int, int);
-    method public static boolean deepEquals(@Nullable Object[], @Nullable Object[]);
-    method public static int deepHashCode(@Nullable Object[]);
-    method @NonNull public static String deepToString(@Nullable Object[]);
-    method public static boolean equals(@Nullable long[], @Nullable long[]);
-    method public static boolean equals(@Nullable int[], @Nullable int[]);
-    method public static boolean equals(@Nullable short[], @Nullable short[]);
-    method public static boolean equals(@Nullable char[], @Nullable char[]);
-    method public static boolean equals(@Nullable byte[], @Nullable byte[]);
-    method public static boolean equals(@Nullable boolean[], @Nullable boolean[]);
-    method public static boolean equals(@Nullable double[], @Nullable double[]);
-    method public static boolean equals(@Nullable float[], @Nullable float[]);
-    method public static boolean equals(@Nullable Object[], @Nullable Object[]);
-    method public static void fill(@NonNull long[], long);
-    method public static void fill(@NonNull long[], int, int, long);
-    method public static void fill(@NonNull int[], int);
-    method public static void fill(@NonNull int[], int, int, int);
-    method public static void fill(@NonNull short[], short);
-    method public static void fill(@NonNull short[], int, int, short);
-    method public static void fill(@NonNull char[], char);
-    method public static void fill(@NonNull char[], int, int, char);
-    method public static void fill(@NonNull byte[], byte);
-    method public static void fill(@NonNull byte[], int, int, byte);
-    method public static void fill(@NonNull boolean[], boolean);
-    method public static void fill(@NonNull boolean[], int, int, boolean);
-    method public static void fill(@NonNull double[], double);
-    method public static void fill(@NonNull double[], int, int, double);
-    method public static void fill(@NonNull float[], float);
-    method public static void fill(@NonNull float[], int, int, float);
-    method public static void fill(@NonNull Object[], @Nullable Object);
-    method public static void fill(@NonNull Object[], int, int, @Nullable Object);
-    method public static int hashCode(@Nullable long[]);
-    method public static int hashCode(@Nullable int[]);
-    method public static int hashCode(@Nullable short[]);
-    method public static int hashCode(@Nullable char[]);
-    method public static int hashCode(@Nullable byte[]);
-    method public static int hashCode(@Nullable boolean[]);
-    method public static int hashCode(@Nullable float[]);
-    method public static int hashCode(@Nullable double[]);
-    method public static int hashCode(@Nullable Object[]);
-    method public static <T> void parallelPrefix(@NonNull T[], @NonNull java.util.function.BinaryOperator<T>);
-    method public static <T> void parallelPrefix(@NonNull T[], int, int, @NonNull java.util.function.BinaryOperator<T>);
-    method public static void parallelPrefix(@NonNull long[], @NonNull java.util.function.LongBinaryOperator);
-    method public static void parallelPrefix(@NonNull long[], int, int, @NonNull java.util.function.LongBinaryOperator);
-    method public static void parallelPrefix(@NonNull double[], @NonNull java.util.function.DoubleBinaryOperator);
-    method public static void parallelPrefix(@NonNull double[], int, int, @NonNull java.util.function.DoubleBinaryOperator);
-    method public static void parallelPrefix(@NonNull int[], @NonNull java.util.function.IntBinaryOperator);
-    method public static void parallelPrefix(@NonNull int[], int, int, @NonNull java.util.function.IntBinaryOperator);
-    method public static <T> void parallelSetAll(@NonNull T[], @NonNull java.util.function.IntFunction<? extends T>);
-    method public static void parallelSetAll(@NonNull int[], @NonNull java.util.function.IntUnaryOperator);
-    method public static void parallelSetAll(@NonNull long[], @NonNull java.util.function.IntToLongFunction);
-    method public static void parallelSetAll(@NonNull double[], @NonNull java.util.function.IntToDoubleFunction);
-    method public static void parallelSort(@NonNull byte[]);
-    method public static void parallelSort(@NonNull byte[], int, int);
-    method public static void parallelSort(@NonNull char[]);
-    method public static void parallelSort(@NonNull char[], int, int);
-    method public static void parallelSort(@NonNull short[]);
-    method public static void parallelSort(@NonNull short[], int, int);
-    method public static void parallelSort(@NonNull int[]);
-    method public static void parallelSort(@NonNull int[], int, int);
-    method public static void parallelSort(@NonNull long[]);
-    method public static void parallelSort(@NonNull long[], int, int);
-    method public static void parallelSort(@NonNull float[]);
-    method public static void parallelSort(@NonNull float[], int, int);
-    method public static void parallelSort(@NonNull double[]);
-    method public static void parallelSort(@NonNull double[], int, int);
-    method public static <T extends java.lang.Comparable<? super T>> void parallelSort(@NonNull T[]);
-    method public static <T extends java.lang.Comparable<? super T>> void parallelSort(@NonNull T[], int, int);
-    method public static <T> void parallelSort(@NonNull T[], @Nullable java.util.Comparator<? super T>);
-    method public static <T> void parallelSort(@NonNull T[], int, int, @Nullable java.util.Comparator<? super T>);
-    method public static <T> void setAll(@NonNull T[], @NonNull java.util.function.IntFunction<? extends T>);
-    method public static void setAll(@NonNull int[], @NonNull java.util.function.IntUnaryOperator);
-    method public static void setAll(@NonNull long[], @NonNull java.util.function.IntToLongFunction);
-    method public static void setAll(@NonNull double[], @NonNull java.util.function.IntToDoubleFunction);
-    method public static void sort(@NonNull int[]);
-    method public static void sort(@NonNull int[], int, int);
-    method public static void sort(@NonNull long[]);
-    method public static void sort(@NonNull long[], int, int);
-    method public static void sort(@NonNull short[]);
-    method public static void sort(@NonNull short[], int, int);
-    method public static void sort(@NonNull char[]);
-    method public static void sort(@NonNull char[], int, int);
-    method public static void sort(@NonNull byte[]);
-    method public static void sort(@NonNull byte[], int, int);
-    method public static void sort(@NonNull float[]);
-    method public static void sort(@NonNull float[], int, int);
-    method public static void sort(@NonNull double[]);
-    method public static void sort(@NonNull double[], int, int);
-    method public static void sort(@NonNull Object[]);
-    method public static void sort(@NonNull Object[], int, int);
-    method public static <T> void sort(@NonNull T[], @Nullable java.util.Comparator<? super T>);
-    method public static <T> void sort(@NonNull T[], int, int, @Nullable java.util.Comparator<? super T>);
-    method @NonNull public static <T> java.util.Spliterator<T> spliterator(@NonNull T[]);
-    method @NonNull public static <T> java.util.Spliterator<T> spliterator(@NonNull T[], int, int);
-    method @NonNull public static java.util.Spliterator.OfInt spliterator(@NonNull int[]);
-    method @NonNull public static java.util.Spliterator.OfInt spliterator(@NonNull int[], int, int);
-    method @NonNull public static java.util.Spliterator.OfLong spliterator(@NonNull long[]);
-    method @NonNull public static java.util.Spliterator.OfLong spliterator(@NonNull long[], int, int);
-    method @NonNull public static java.util.Spliterator.OfDouble spliterator(@NonNull double[]);
-    method @NonNull public static java.util.Spliterator.OfDouble spliterator(@NonNull double[], int, int);
-    method @NonNull public static <T> java.util.stream.Stream<T> stream(@NonNull T[]);
-    method @NonNull public static <T> java.util.stream.Stream<T> stream(@NonNull T[], int, int);
-    method @NonNull public static java.util.stream.IntStream stream(@NonNull int[]);
-    method @NonNull public static java.util.stream.IntStream stream(@NonNull int[], int, int);
-    method @NonNull public static java.util.stream.LongStream stream(@NonNull long[]);
-    method @NonNull public static java.util.stream.LongStream stream(@NonNull long[], int, int);
-    method @NonNull public static java.util.stream.DoubleStream stream(@NonNull double[]);
-    method @NonNull public static java.util.stream.DoubleStream stream(@NonNull double[], int, int);
-    method @NonNull public static String toString(@Nullable long[]);
-    method @NonNull public static String toString(@Nullable int[]);
-    method @NonNull public static String toString(@Nullable short[]);
-    method @NonNull public static String toString(@Nullable char[]);
-    method @NonNull public static String toString(@Nullable byte[]);
-    method @NonNull public static String toString(@Nullable boolean[]);
-    method @NonNull public static String toString(@Nullable float[]);
-    method @NonNull public static String toString(@Nullable double[]);
-    method @NonNull public static String toString(@Nullable Object[]);
-  }
-
-  public class Base64 {
-    method public static java.util.Base64.Decoder getDecoder();
-    method public static java.util.Base64.Encoder getEncoder();
-    method public static java.util.Base64.Decoder getMimeDecoder();
-    method public static java.util.Base64.Encoder getMimeEncoder();
-    method public static java.util.Base64.Encoder getMimeEncoder(int, byte[]);
-    method public static java.util.Base64.Decoder getUrlDecoder();
-    method public static java.util.Base64.Encoder getUrlEncoder();
-  }
-
-  public static class Base64.Decoder {
-    method public byte[] decode(byte[]);
-    method public byte[] decode(String);
-    method public int decode(byte[], byte[]);
-    method public java.nio.ByteBuffer decode(java.nio.ByteBuffer);
-    method public java.io.InputStream wrap(java.io.InputStream);
-  }
-
-  public static class Base64.Encoder {
-    method public byte[] encode(byte[]);
-    method public int encode(byte[], byte[]);
-    method public java.nio.ByteBuffer encode(java.nio.ByteBuffer);
-    method public String encodeToString(byte[]);
-    method public java.util.Base64.Encoder withoutPadding();
-    method public java.io.OutputStream wrap(java.io.OutputStream);
-  }
-
-  public class BitSet implements java.lang.Cloneable java.io.Serializable {
-    ctor public BitSet();
-    ctor public BitSet(int);
-    method public void and(java.util.BitSet);
-    method public void andNot(java.util.BitSet);
-    method public int cardinality();
-    method public void clear(int);
-    method public void clear(int, int);
-    method public void clear();
-    method public Object clone();
-    method public void flip(int);
-    method public void flip(int, int);
-    method public boolean get(int);
-    method public java.util.BitSet get(int, int);
-    method public boolean intersects(java.util.BitSet);
-    method public boolean isEmpty();
-    method public int length();
-    method public int nextClearBit(int);
-    method public int nextSetBit(int);
-    method public void or(java.util.BitSet);
-    method public int previousClearBit(int);
-    method public int previousSetBit(int);
-    method public void set(int);
-    method public void set(int, boolean);
-    method public void set(int, int);
-    method public void set(int, int, boolean);
-    method public int size();
-    method public java.util.stream.IntStream stream();
-    method public byte[] toByteArray();
-    method public long[] toLongArray();
-    method public static java.util.BitSet valueOf(long[]);
-    method public static java.util.BitSet valueOf(java.nio.LongBuffer);
-    method public static java.util.BitSet valueOf(byte[]);
-    method public static java.util.BitSet valueOf(java.nio.ByteBuffer);
-    method public void xor(java.util.BitSet);
-  }
-
-  public abstract class Calendar implements java.lang.Cloneable java.lang.Comparable<java.util.Calendar> java.io.Serializable {
-    ctor protected Calendar();
-    ctor protected Calendar(@NonNull java.util.TimeZone, @NonNull java.util.Locale);
-    method public abstract void add(int, int);
-    method public boolean after(@Nullable Object);
-    method public boolean before(@Nullable Object);
-    method public final void clear();
-    method public final void clear(int);
-    method @NonNull public Object clone();
-    method public int compareTo(@NonNull java.util.Calendar);
-    method protected void complete();
-    method protected abstract void computeFields();
-    method protected abstract void computeTime();
-    method public int get(int);
-    method public int getActualMaximum(int);
-    method public int getActualMinimum(int);
-    method @NonNull public static java.util.Set<java.lang.String> getAvailableCalendarTypes();
-    method @NonNull public static java.util.Locale[] getAvailableLocales();
-    method @NonNull public String getCalendarType();
-    method @Nullable public String getDisplayName(int, int, @NonNull java.util.Locale);
-    method @Nullable public java.util.Map<java.lang.String,java.lang.Integer> getDisplayNames(int, int, @NonNull java.util.Locale);
-    method public int getFirstDayOfWeek();
-    method public abstract int getGreatestMinimum(int);
-    method @NonNull public static java.util.Calendar getInstance();
-    method @NonNull public static java.util.Calendar getInstance(@NonNull java.util.TimeZone);
-    method @NonNull public static java.util.Calendar getInstance(@NonNull java.util.Locale);
-    method @NonNull public static java.util.Calendar getInstance(@NonNull java.util.TimeZone, @NonNull java.util.Locale);
-    method public abstract int getLeastMaximum(int);
-    method public abstract int getMaximum(int);
-    method public int getMinimalDaysInFirstWeek();
-    method public abstract int getMinimum(int);
-    method @NonNull public final java.util.Date getTime();
-    method public long getTimeInMillis();
-    method @NonNull public java.util.TimeZone getTimeZone();
-    method public int getWeekYear();
-    method public int getWeeksInWeekYear();
-    method protected final int internalGet(int);
-    method public boolean isLenient();
-    method public final boolean isSet(int);
-    method public boolean isWeekDateSupported();
-    method public abstract void roll(int, boolean);
-    method public void roll(int, int);
-    method public void set(int, int);
-    method public final void set(int, int, int);
-    method public final void set(int, int, int, int, int);
-    method public final void set(int, int, int, int, int, int);
-    method public void setFirstDayOfWeek(int);
-    method public void setLenient(boolean);
-    method public void setMinimalDaysInFirstWeek(int);
-    method public final void setTime(@NonNull java.util.Date);
-    method public void setTimeInMillis(long);
-    method public void setTimeZone(@NonNull java.util.TimeZone);
-    method public void setWeekDate(int, int, int);
-    method @NonNull public final java.time.Instant toInstant();
-    field public static final int ALL_STYLES = 0; // 0x0
-    field public static final int AM = 0; // 0x0
-    field public static final int AM_PM = 9; // 0x9
-    field public static final int APRIL = 3; // 0x3
-    field public static final int AUGUST = 7; // 0x7
-    field public static final int DATE = 5; // 0x5
-    field public static final int DAY_OF_MONTH = 5; // 0x5
-    field public static final int DAY_OF_WEEK = 7; // 0x7
-    field public static final int DAY_OF_WEEK_IN_MONTH = 8; // 0x8
-    field public static final int DAY_OF_YEAR = 6; // 0x6
-    field public static final int DECEMBER = 11; // 0xb
-    field public static final int DST_OFFSET = 16; // 0x10
-    field public static final int ERA = 0; // 0x0
-    field public static final int FEBRUARY = 1; // 0x1
-    field public static final int FIELD_COUNT = 17; // 0x11
-    field public static final int FRIDAY = 6; // 0x6
-    field public static final int HOUR = 10; // 0xa
-    field public static final int HOUR_OF_DAY = 11; // 0xb
-    field public static final int JANUARY = 0; // 0x0
-    field public static final int JULY = 6; // 0x6
-    field public static final int JUNE = 5; // 0x5
-    field public static final int LONG = 2; // 0x2
-    field public static final int LONG_FORMAT = 2; // 0x2
-    field public static final int LONG_STANDALONE = 32770; // 0x8002
-    field public static final int MARCH = 2; // 0x2
-    field public static final int MAY = 4; // 0x4
-    field public static final int MILLISECOND = 14; // 0xe
-    field public static final int MINUTE = 12; // 0xc
-    field public static final int MONDAY = 2; // 0x2
-    field public static final int MONTH = 2; // 0x2
-    field public static final int NARROW_FORMAT = 4; // 0x4
-    field public static final int NARROW_STANDALONE = 32772; // 0x8004
-    field public static final int NOVEMBER = 10; // 0xa
-    field public static final int OCTOBER = 9; // 0x9
-    field public static final int PM = 1; // 0x1
-    field public static final int SATURDAY = 7; // 0x7
-    field public static final int SECOND = 13; // 0xd
-    field public static final int SEPTEMBER = 8; // 0x8
-    field public static final int SHORT = 1; // 0x1
-    field public static final int SHORT_FORMAT = 1; // 0x1
-    field public static final int SHORT_STANDALONE = 32769; // 0x8001
-    field public static final int SUNDAY = 1; // 0x1
-    field public static final int THURSDAY = 5; // 0x5
-    field public static final int TUESDAY = 3; // 0x3
-    field public static final int UNDECIMBER = 12; // 0xc
-    field public static final int WEDNESDAY = 4; // 0x4
-    field public static final int WEEK_OF_MONTH = 4; // 0x4
-    field public static final int WEEK_OF_YEAR = 3; // 0x3
-    field public static final int YEAR = 1; // 0x1
-    field public static final int ZONE_OFFSET = 15; // 0xf
-    field protected boolean areFieldsSet;
-    field @NonNull protected int[] fields;
-    field @NonNull protected boolean[] isSet;
-    field protected boolean isTimeSet;
-    field protected long time;
-  }
-
-  public static class Calendar.Builder {
-    ctor public Calendar.Builder();
-    method @NonNull public java.util.Calendar build();
-    method @NonNull public java.util.Calendar.Builder set(int, int);
-    method @NonNull public java.util.Calendar.Builder setCalendarType(@NonNull String);
-    method @NonNull public java.util.Calendar.Builder setDate(int, int, int);
-    method @NonNull public java.util.Calendar.Builder setFields(@NonNull int...);
-    method @NonNull public java.util.Calendar.Builder setInstant(long);
-    method @NonNull public java.util.Calendar.Builder setInstant(@NonNull java.util.Date);
-    method @NonNull public java.util.Calendar.Builder setLenient(boolean);
-    method @NonNull public java.util.Calendar.Builder setLocale(@NonNull java.util.Locale);
-    method @NonNull public java.util.Calendar.Builder setTimeOfDay(int, int, int);
-    method @NonNull public java.util.Calendar.Builder setTimeOfDay(int, int, int, int);
-    method @NonNull public java.util.Calendar.Builder setTimeZone(@NonNull java.util.TimeZone);
-    method @NonNull public java.util.Calendar.Builder setWeekDate(int, int, int);
-    method @NonNull public java.util.Calendar.Builder setWeekDefinition(int, int);
-  }
-
-  public interface Collection<E> extends java.lang.Iterable<E> {
-    method public boolean add(E);
-    method public boolean addAll(@NonNull java.util.Collection<? extends E>);
-    method public void clear();
-    method public boolean contains(@Nullable Object);
-    method public boolean containsAll(@NonNull java.util.Collection<?>);
-    method public boolean equals(@Nullable Object);
-    method public int hashCode();
-    method public boolean isEmpty();
-    method @NonNull public java.util.Iterator<E> iterator();
-    method @NonNull public default java.util.stream.Stream<E> parallelStream();
-    method public boolean remove(@Nullable Object);
-    method public boolean removeAll(@NonNull java.util.Collection<?>);
-    method public default boolean removeIf(@NonNull java.util.function.Predicate<? super E>);
-    method public boolean retainAll(@NonNull java.util.Collection<?>);
-    method public int size();
-    method @NonNull public default java.util.Spliterator<E> spliterator();
-    method @NonNull public default java.util.stream.Stream<E> stream();
-    method @NonNull public Object[] toArray();
-    method @NonNull public <T> T[] toArray(@NonNull T[]);
-  }
-
-  public class Collections {
-    method @java.lang.SafeVarargs public static <T> boolean addAll(@NonNull java.util.Collection<? super T>, @NonNull T...);
-    method @NonNull public static <T> java.util.Queue<T> asLifoQueue(@NonNull java.util.Deque<T>);
-    method public static <T> int binarySearch(@NonNull java.util.List<? extends java.lang.Comparable<? super T>>, @NonNull T);
-    method public static <T> int binarySearch(@NonNull java.util.List<? extends T>, T, @Nullable java.util.Comparator<? super T>);
-    method @NonNull public static <E> java.util.Collection<E> checkedCollection(@NonNull java.util.Collection<E>, @NonNull Class<E>);
-    method @NonNull public static <E> java.util.List<E> checkedList(@NonNull java.util.List<E>, @NonNull Class<E>);
-    method @NonNull public static <K, V> java.util.Map<K,V> checkedMap(@NonNull java.util.Map<K,V>, @NonNull Class<K>, @NonNull Class<V>);
-    method @NonNull public static <K, V> java.util.NavigableMap<K,V> checkedNavigableMap(@NonNull java.util.NavigableMap<K,V>, @NonNull Class<K>, @NonNull Class<V>);
-    method @NonNull public static <E> java.util.NavigableSet<E> checkedNavigableSet(@NonNull java.util.NavigableSet<E>, @NonNull Class<E>);
-    method @NonNull public static <E> java.util.Queue<E> checkedQueue(@NonNull java.util.Queue<E>, @NonNull Class<E>);
-    method @NonNull public static <E> java.util.Set<E> checkedSet(@NonNull java.util.Set<E>, @NonNull Class<E>);
-    method @NonNull public static <K, V> java.util.SortedMap<K,V> checkedSortedMap(@NonNull java.util.SortedMap<K,V>, @NonNull Class<K>, @NonNull Class<V>);
-    method @NonNull public static <E> java.util.SortedSet<E> checkedSortedSet(@NonNull java.util.SortedSet<E>, @NonNull Class<E>);
-    method public static <T> void copy(@NonNull java.util.List<? super T>, @NonNull java.util.List<? extends T>);
-    method public static boolean disjoint(@NonNull java.util.Collection<?>, @NonNull java.util.Collection<?>);
-    method @NonNull public static <T> java.util.Enumeration<T> emptyEnumeration();
-    method @NonNull public static <T> java.util.Iterator<T> emptyIterator();
-    method @NonNull public static final <T> java.util.List<T> emptyList();
-    method @NonNull public static <T> java.util.ListIterator<T> emptyListIterator();
-    method @NonNull public static final <K, V> java.util.Map<K,V> emptyMap();
-    method @NonNull public static final <K, V> java.util.NavigableMap<K,V> emptyNavigableMap();
-    method @NonNull public static <E> java.util.NavigableSet<E> emptyNavigableSet();
-    method @NonNull public static final <T> java.util.Set<T> emptySet();
-    method @NonNull public static final <K, V> java.util.SortedMap<K,V> emptySortedMap();
-    method @NonNull public static <E> java.util.SortedSet<E> emptySortedSet();
-    method @NonNull public static <T> java.util.Enumeration<T> enumeration(@NonNull java.util.Collection<T>);
-    method public static <T> void fill(@NonNull java.util.List<? super T>, T);
-    method public static int frequency(@NonNull java.util.Collection<?>, @Nullable Object);
-    method public static int indexOfSubList(@NonNull java.util.List<?>, @NonNull java.util.List<?>);
-    method public static int lastIndexOfSubList(@NonNull java.util.List<?>, @NonNull java.util.List<?>);
-    method @NonNull public static <T> java.util.ArrayList<T> list(@NonNull java.util.Enumeration<T>);
-    method @NonNull public static <T extends java.lang.Object & java.lang.Comparable<? super T>> T max(@NonNull java.util.Collection<? extends T>);
-    method public static <T> T max(@NonNull java.util.Collection<? extends T>, @Nullable java.util.Comparator<? super T>);
-    method @NonNull public static <T extends java.lang.Object & java.lang.Comparable<? super T>> T min(@NonNull java.util.Collection<? extends T>);
-    method public static <T> T min(@NonNull java.util.Collection<? extends T>, @Nullable java.util.Comparator<? super T>);
-    method @NonNull public static <T> java.util.List<T> nCopies(int, T);
-    method @NonNull public static <E> java.util.Set<E> newSetFromMap(@NonNull java.util.Map<E,java.lang.Boolean>);
-    method public static <T> boolean replaceAll(@NonNull java.util.List<T>, T, T);
-    method public static void reverse(@NonNull java.util.List<?>);
-    method @NonNull public static <T> java.util.Comparator<T> reverseOrder();
-    method @NonNull public static <T> java.util.Comparator<T> reverseOrder(@Nullable java.util.Comparator<T>);
-    method public static void rotate(@NonNull java.util.List<?>, int);
-    method public static void shuffle(@NonNull java.util.List<?>);
-    method public static void shuffle(@NonNull java.util.List<?>, @NonNull java.util.Random);
-    method @NonNull public static <T> java.util.Set<T> singleton(T);
-    method @NonNull public static <T> java.util.List<T> singletonList(T);
-    method @NonNull public static <K, V> java.util.Map<K,V> singletonMap(K, V);
-    method public static <T extends java.lang.Comparable<? super T>> void sort(@NonNull java.util.List<T>);
-    method public static <T> void sort(@NonNull java.util.List<T>, @Nullable java.util.Comparator<? super T>);
-    method public static void swap(@NonNull java.util.List<?>, int, int);
-    method @NonNull public static <T> java.util.Collection<T> synchronizedCollection(@NonNull java.util.Collection<T>);
-    method @NonNull public static <T> java.util.List<T> synchronizedList(@NonNull java.util.List<T>);
-    method @NonNull public static <K, V> java.util.Map<K,V> synchronizedMap(@NonNull java.util.Map<K,V>);
-    method @NonNull public static <K, V> java.util.NavigableMap<K,V> synchronizedNavigableMap(@NonNull java.util.NavigableMap<K,V>);
-    method @NonNull public static <T> java.util.NavigableSet<T> synchronizedNavigableSet(@NonNull java.util.NavigableSet<T>);
-    method @NonNull public static <T> java.util.Set<T> synchronizedSet(@NonNull java.util.Set<T>);
-    method @NonNull public static <K, V> java.util.SortedMap<K,V> synchronizedSortedMap(@NonNull java.util.SortedMap<K,V>);
-    method @NonNull public static <T> java.util.SortedSet<T> synchronizedSortedSet(@NonNull java.util.SortedSet<T>);
-    method @NonNull public static <T> java.util.Collection<T> unmodifiableCollection(@NonNull java.util.Collection<? extends T>);
-    method @NonNull public static <T> java.util.List<T> unmodifiableList(@NonNull java.util.List<? extends T>);
-    method @NonNull public static <K, V> java.util.Map<K,V> unmodifiableMap(@NonNull java.util.Map<? extends K,? extends V>);
-    method @NonNull public static <K, V> java.util.NavigableMap<K,V> unmodifiableNavigableMap(@NonNull java.util.NavigableMap<K,? extends V>);
-    method @NonNull public static <T> java.util.NavigableSet<T> unmodifiableNavigableSet(@NonNull java.util.NavigableSet<T>);
-    method @NonNull public static <T> java.util.Set<T> unmodifiableSet(@NonNull java.util.Set<? extends T>);
-    method @NonNull public static <K, V> java.util.SortedMap<K,V> unmodifiableSortedMap(@NonNull java.util.SortedMap<K,? extends V>);
-    method @NonNull public static <T> java.util.SortedSet<T> unmodifiableSortedSet(@NonNull java.util.SortedSet<T>);
-    field @NonNull public static final java.util.List EMPTY_LIST;
-    field @NonNull public static final java.util.Map EMPTY_MAP;
-    field @NonNull public static final java.util.Set EMPTY_SET;
-  }
-
-  @java.lang.FunctionalInterface public interface Comparator<T> {
-    method public int compare(T, T);
-    method public static <T, U> java.util.Comparator<T> comparing(java.util.function.Function<? super T,? extends U>, java.util.Comparator<? super U>);
-    method public static <T, U extends java.lang.Comparable<? super U>> java.util.Comparator<T> comparing(java.util.function.Function<? super T,? extends U>);
-    method public static <T> java.util.Comparator<T> comparingDouble(java.util.function.ToDoubleFunction<? super T>);
-    method public static <T> java.util.Comparator<T> comparingInt(java.util.function.ToIntFunction<? super T>);
-    method public static <T> java.util.Comparator<T> comparingLong(java.util.function.ToLongFunction<? super T>);
-    method public boolean equals(Object);
-    method public static <T extends java.lang.Comparable<? super T>> java.util.Comparator<T> naturalOrder();
-    method public static <T> java.util.Comparator<T> nullsFirst(java.util.Comparator<? super T>);
-    method public static <T> java.util.Comparator<T> nullsLast(java.util.Comparator<? super T>);
-    method public static <T extends java.lang.Comparable<? super T>> java.util.Comparator<T> reverseOrder();
-    method public default java.util.Comparator<T> reversed();
-    method public default java.util.Comparator<T> thenComparing(java.util.Comparator<? super T>);
-    method public default <U> java.util.Comparator<T> thenComparing(java.util.function.Function<? super T,? extends U>, java.util.Comparator<? super U>);
-    method public default <U extends java.lang.Comparable<? super U>> java.util.Comparator<T> thenComparing(java.util.function.Function<? super T,? extends U>);
-    method public default java.util.Comparator<T> thenComparingDouble(java.util.function.ToDoubleFunction<? super T>);
-    method public default java.util.Comparator<T> thenComparingInt(java.util.function.ToIntFunction<? super T>);
-    method public default java.util.Comparator<T> thenComparingLong(java.util.function.ToLongFunction<? super T>);
-  }
-
-  public class ConcurrentModificationException extends java.lang.RuntimeException {
-    ctor public ConcurrentModificationException();
-    ctor public ConcurrentModificationException(String);
-    ctor public ConcurrentModificationException(Throwable);
-    ctor public ConcurrentModificationException(String, Throwable);
-  }
-
-  public final class Currency implements java.io.Serializable {
-    method public static java.util.Set<java.util.Currency> getAvailableCurrencies();
-    method public String getCurrencyCode();
-    method public int getDefaultFractionDigits();
-    method public String getDisplayName();
-    method public String getDisplayName(java.util.Locale);
-    method public static java.util.Currency getInstance(String);
-    method public static java.util.Currency getInstance(java.util.Locale);
-    method public int getNumericCode();
-    method public String getSymbol();
-    method public String getSymbol(java.util.Locale);
-  }
-
-  public class Date implements java.lang.Cloneable java.lang.Comparable<java.util.Date> java.io.Serializable {
-    ctor public Date();
-    ctor public Date(long);
-    ctor @Deprecated public Date(int, int, int);
-    ctor @Deprecated public Date(int, int, int, int, int);
-    ctor @Deprecated public Date(int, int, int, int, int, int);
-    ctor @Deprecated public Date(String);
-    method @Deprecated public static long UTC(int, int, int, int, int, int);
-    method public boolean after(java.util.Date);
-    method public boolean before(java.util.Date);
-    method public Object clone();
-    method public int compareTo(java.util.Date);
-    method public static java.util.Date from(java.time.Instant);
-    method @Deprecated public int getDate();
-    method @Deprecated public int getDay();
-    method @Deprecated public int getHours();
-    method @Deprecated public int getMinutes();
-    method @Deprecated public int getMonth();
-    method @Deprecated public int getSeconds();
-    method public long getTime();
-    method @Deprecated public int getTimezoneOffset();
-    method @Deprecated public int getYear();
-    method @Deprecated public static long parse(String);
-    method @Deprecated public void setDate(int);
-    method @Deprecated public void setHours(int);
-    method @Deprecated public void setMinutes(int);
-    method @Deprecated public void setMonth(int);
-    method @Deprecated public void setSeconds(int);
-    method public void setTime(long);
-    method @Deprecated public void setYear(int);
-    method @Deprecated public String toGMTString();
-    method public java.time.Instant toInstant();
-    method @Deprecated public String toLocaleString();
-  }
-
-  public interface Deque<E> extends java.util.Queue<E> {
-    method public void addFirst(E);
-    method public void addLast(E);
-    method @NonNull public java.util.Iterator<E> descendingIterator();
-    method public E getFirst();
-    method public E getLast();
-    method public boolean offerFirst(E);
-    method public boolean offerLast(E);
-    method @Nullable public E peekFirst();
-    method @Nullable public E peekLast();
-    method @Nullable public E pollFirst();
-    method @Nullable public E pollLast();
-    method public E pop();
-    method public void push(E);
-    method public E removeFirst();
-    method public boolean removeFirstOccurrence(@Nullable Object);
-    method public E removeLast();
-    method public boolean removeLastOccurrence(@Nullable Object);
-  }
-
-  public abstract class Dictionary<K, V> {
-    ctor public Dictionary();
-    method public abstract java.util.Enumeration<V> elements();
-    method public abstract V get(Object);
-    method public abstract boolean isEmpty();
-    method public abstract java.util.Enumeration<K> keys();
-    method public abstract V put(K, V);
-    method public abstract V remove(Object);
-    method public abstract int size();
-  }
-
-  public class DoubleSummaryStatistics implements java.util.function.DoubleConsumer {
-    ctor public DoubleSummaryStatistics();
-    method public void accept(double);
-    method public void combine(java.util.DoubleSummaryStatistics);
-    method public final double getAverage();
-    method public final long getCount();
-    method public final double getMax();
-    method public final double getMin();
-    method public final double getSum();
-  }
-
-  public class DuplicateFormatFlagsException extends java.util.IllegalFormatException {
-    ctor public DuplicateFormatFlagsException(String);
-    method public String getFlags();
-  }
-
-  public class EmptyStackException extends java.lang.RuntimeException {
-    ctor public EmptyStackException();
-  }
-
-  public class EnumMap<K extends java.lang.Enum<K>, V> extends java.util.AbstractMap<K,V> implements java.lang.Cloneable java.io.Serializable {
-    ctor public EnumMap(Class<K>);
-    ctor public EnumMap(java.util.EnumMap<K,? extends V>);
-    ctor public EnumMap(java.util.Map<K,? extends V>);
-    method public java.util.EnumMap<K,V> clone();
-    method public java.util.Set<java.util.Map.Entry<K,V>> entrySet();
-  }
-
-  public abstract class EnumSet<E extends java.lang.Enum<E>> extends java.util.AbstractSet<E> implements java.lang.Cloneable java.io.Serializable {
-    method public static <E extends java.lang.Enum<E>> java.util.EnumSet<E> allOf(Class<E>);
-    method public java.util.EnumSet<E> clone();
-    method public static <E extends java.lang.Enum<E>> java.util.EnumSet<E> complementOf(java.util.EnumSet<E>);
-    method public static <E extends java.lang.Enum<E>> java.util.EnumSet<E> copyOf(java.util.EnumSet<E>);
-    method public static <E extends java.lang.Enum<E>> java.util.EnumSet<E> copyOf(java.util.Collection<E>);
-    method public static <E extends java.lang.Enum<E>> java.util.EnumSet<E> noneOf(Class<E>);
-    method public static <E extends java.lang.Enum<E>> java.util.EnumSet<E> of(E);
-    method public static <E extends java.lang.Enum<E>> java.util.EnumSet<E> of(E, E);
-    method public static <E extends java.lang.Enum<E>> java.util.EnumSet<E> of(E, E, E);
-    method public static <E extends java.lang.Enum<E>> java.util.EnumSet<E> of(E, E, E, E);
-    method public static <E extends java.lang.Enum<E>> java.util.EnumSet<E> of(E, E, E, E, E);
-    method @java.lang.SafeVarargs public static <E extends java.lang.Enum<E>> java.util.EnumSet<E> of(E, E...);
-    method public static <E extends java.lang.Enum<E>> java.util.EnumSet<E> range(E, E);
-  }
-
-  public interface Enumeration<E> {
-    method public boolean hasMoreElements();
-    method public E nextElement();
-  }
-
-  public interface EventListener {
-  }
-
-  public abstract class EventListenerProxy<T extends java.util.EventListener> implements java.util.EventListener {
-    ctor public EventListenerProxy(T);
-    method public T getListener();
-  }
-
-  public class EventObject implements java.io.Serializable {
-    ctor public EventObject(Object);
-    method public Object getSource();
-    field protected transient Object source;
-  }
-
-  public class FormatFlagsConversionMismatchException extends java.util.IllegalFormatException {
-    ctor public FormatFlagsConversionMismatchException(String, char);
-    method public char getConversion();
-    method public String getFlags();
-  }
-
-  public interface Formattable {
-    method public void formatTo(java.util.Formatter, int, int, int);
-  }
-
-  public class FormattableFlags {
-    field public static final int ALTERNATE = 4; // 0x4
-    field public static final int LEFT_JUSTIFY = 1; // 0x1
-    field public static final int UPPERCASE = 2; // 0x2
-  }
-
-  public final class Formatter implements java.io.Closeable java.io.Flushable {
-    ctor public Formatter();
-    ctor public Formatter(Appendable);
-    ctor public Formatter(java.util.Locale);
-    ctor public Formatter(Appendable, java.util.Locale);
-    ctor public Formatter(String) throws java.io.FileNotFoundException;
-    ctor public Formatter(String, String) throws java.io.FileNotFoundException, java.io.UnsupportedEncodingException;
-    ctor public Formatter(String, String, java.util.Locale) throws java.io.FileNotFoundException, java.io.UnsupportedEncodingException;
-    ctor public Formatter(java.io.File) throws java.io.FileNotFoundException;
-    ctor public Formatter(java.io.File, String) throws java.io.FileNotFoundException, java.io.UnsupportedEncodingException;
-    ctor public Formatter(java.io.File, String, java.util.Locale) throws java.io.FileNotFoundException, java.io.UnsupportedEncodingException;
-    ctor public Formatter(java.io.PrintStream);
-    ctor public Formatter(java.io.OutputStream);
-    ctor public Formatter(java.io.OutputStream, String) throws java.io.UnsupportedEncodingException;
-    ctor public Formatter(java.io.OutputStream, String, java.util.Locale) throws java.io.UnsupportedEncodingException;
-    method public void close();
-    method public void flush();
-    method public java.util.Formatter format(String, java.lang.Object...);
-    method public java.util.Formatter format(java.util.Locale, String, java.lang.Object...);
-    method public java.io.IOException ioException();
-    method public java.util.Locale locale();
-    method public Appendable out();
-  }
-
-  public enum Formatter.BigDecimalLayoutForm {
-    enum_constant public static final java.util.Formatter.BigDecimalLayoutForm DECIMAL_FLOAT;
-    enum_constant public static final java.util.Formatter.BigDecimalLayoutForm SCIENTIFIC;
-  }
-
-  public class FormatterClosedException extends java.lang.IllegalStateException {
-    ctor public FormatterClosedException();
-  }
-
-  public class GregorianCalendar extends java.util.Calendar {
-    ctor public GregorianCalendar();
-    ctor public GregorianCalendar(java.util.TimeZone);
-    ctor public GregorianCalendar(java.util.Locale);
-    ctor public GregorianCalendar(java.util.TimeZone, java.util.Locale);
-    ctor public GregorianCalendar(int, int, int);
-    ctor public GregorianCalendar(int, int, int, int, int);
-    ctor public GregorianCalendar(int, int, int, int, int, int);
-    method public void add(int, int);
-    method protected void computeFields();
-    method protected void computeTime();
-    method public static java.util.GregorianCalendar from(java.time.ZonedDateTime);
-    method public int getGreatestMinimum(int);
-    method public final java.util.Date getGregorianChange();
-    method public int getLeastMaximum(int);
-    method public int getMaximum(int);
-    method public int getMinimum(int);
-    method public boolean isLeapYear(int);
-    method public final boolean isWeekDateSupported();
-    method public void roll(int, boolean);
-    method public void setGregorianChange(java.util.Date);
-    method public java.time.ZonedDateTime toZonedDateTime();
-    field public static final int AD = 1; // 0x1
-    field public static final int BC = 0; // 0x0
-  }
-
-  public class HashMap<K, V> extends java.util.AbstractMap<K,V> implements java.lang.Cloneable java.util.Map<K,V> java.io.Serializable {
-    ctor public HashMap(int, float);
-    ctor public HashMap(int);
-    ctor public HashMap();
-    ctor public HashMap(@NonNull java.util.Map<? extends K,? extends V>);
-    method @NonNull public Object clone();
-    method @NonNull public java.util.Set<java.util.Map.Entry<K,V>> entrySet();
-  }
-
-  public class HashSet<E> extends java.util.AbstractSet<E> implements java.lang.Cloneable java.io.Serializable java.util.Set<E> {
-    ctor public HashSet();
-    ctor public HashSet(@NonNull java.util.Collection<? extends E>);
-    ctor public HashSet(int, float);
-    ctor public HashSet(int);
-    method @NonNull public Object clone();
-    method @NonNull public java.util.Iterator<E> iterator();
-    method public int size();
-  }
-
-  public class Hashtable<K, V> extends java.util.Dictionary<K,V> implements java.lang.Cloneable java.util.Map<K,V> java.io.Serializable {
-    ctor public Hashtable(int, float);
-    ctor public Hashtable(int);
-    ctor public Hashtable();
-    ctor public Hashtable(java.util.Map<? extends K,? extends V>);
-    method public void clear();
-    method public Object clone();
-    method public boolean contains(Object);
-    method public boolean containsKey(Object);
-    method public boolean containsValue(Object);
-    method public java.util.Enumeration<V> elements();
-    method public java.util.Set<java.util.Map.Entry<K,V>> entrySet();
-    method public V get(Object);
-    method public boolean isEmpty();
-    method public java.util.Set<K> keySet();
-    method public java.util.Enumeration<K> keys();
-    method public V put(K, V);
-    method public void putAll(java.util.Map<? extends K,? extends V>);
-    method protected void rehash();
-    method public V remove(Object);
-    method public int size();
-    method public java.util.Collection<V> values();
-  }
-
-  public class IdentityHashMap<K, V> extends java.util.AbstractMap<K,V> implements java.lang.Cloneable java.util.Map<K,V> java.io.Serializable {
-    ctor public IdentityHashMap();
-    ctor public IdentityHashMap(int);
-    ctor public IdentityHashMap(java.util.Map<? extends K,? extends V>);
-    method public Object clone();
-    method public java.util.Set<java.util.Map.Entry<K,V>> entrySet();
-  }
-
-  public class IllegalFormatCodePointException extends java.util.IllegalFormatException {
-    ctor public IllegalFormatCodePointException(int);
-    method public int getCodePoint();
-  }
-
-  public class IllegalFormatConversionException extends java.util.IllegalFormatException {
-    ctor public IllegalFormatConversionException(char, Class<?>);
-    method public Class<?> getArgumentClass();
-    method public char getConversion();
-  }
-
-  public class IllegalFormatException extends java.lang.IllegalArgumentException {
-  }
-
-  public class IllegalFormatFlagsException extends java.util.IllegalFormatException {
-    ctor public IllegalFormatFlagsException(String);
-    method public String getFlags();
-  }
-
-  public class IllegalFormatPrecisionException extends java.util.IllegalFormatException {
-    ctor public IllegalFormatPrecisionException(int);
-    method public int getPrecision();
-  }
-
-  public class IllegalFormatWidthException extends java.util.IllegalFormatException {
-    ctor public IllegalFormatWidthException(int);
-    method public int getWidth();
-  }
-
-  public class IllformedLocaleException extends java.lang.RuntimeException {
-    ctor public IllformedLocaleException();
-    ctor public IllformedLocaleException(String);
-    ctor public IllformedLocaleException(String, int);
-    method public int getErrorIndex();
-  }
-
-  public class InputMismatchException extends java.util.NoSuchElementException {
-    ctor public InputMismatchException();
-    ctor public InputMismatchException(String);
-  }
-
-  public class IntSummaryStatistics implements java.util.function.IntConsumer {
-    ctor public IntSummaryStatistics();
-    method public void accept(int);
-    method public void combine(java.util.IntSummaryStatistics);
-    method public final double getAverage();
-    method public final long getCount();
-    method public final int getMax();
-    method public final int getMin();
-    method public final long getSum();
-  }
-
-  public class InvalidPropertiesFormatException extends java.io.IOException {
-    ctor public InvalidPropertiesFormatException(Throwable);
-    ctor public InvalidPropertiesFormatException(String);
-  }
-
-  public interface Iterator<E> {
-    method public default void forEachRemaining(@NonNull java.util.function.Consumer<? super E>);
-    method public boolean hasNext();
-    method public E next();
-    method public default void remove();
-  }
-
-  public class LinkedHashMap<K, V> extends java.util.HashMap<K,V> implements java.util.Map<K,V> {
-    ctor public LinkedHashMap(int, float);
-    ctor public LinkedHashMap(int);
-    ctor public LinkedHashMap();
-    ctor public LinkedHashMap(java.util.Map<? extends K,? extends V>);
-    ctor public LinkedHashMap(int, float, boolean);
-    method protected boolean removeEldestEntry(java.util.Map.Entry<K,V>);
-  }
-
-  public class LinkedHashSet<E> extends java.util.HashSet<E> implements java.lang.Cloneable java.io.Serializable java.util.Set<E> {
-    ctor public LinkedHashSet(int, float);
-    ctor public LinkedHashSet(int);
-    ctor public LinkedHashSet();
-    ctor public LinkedHashSet(java.util.Collection<? extends E>);
-  }
-
-  public class LinkedList<E> extends java.util.AbstractSequentialList<E> implements java.lang.Cloneable java.util.Deque<E> java.util.List<E> java.io.Serializable {
-    ctor public LinkedList();
-    ctor public LinkedList(@NonNull java.util.Collection<? extends E>);
-    method public void addFirst(E);
-    method public void addLast(E);
-    method @NonNull public Object clone();
-    method @NonNull public java.util.Iterator<E> descendingIterator();
-    method public E element();
-    method public E getFirst();
-    method public E getLast();
-    method public boolean offer(E);
-    method public boolean offerFirst(E);
-    method public boolean offerLast(E);
-    method @Nullable public E peek();
-    method @Nullable public E peekFirst();
-    method @Nullable public E peekLast();
-    method @Nullable public E poll();
-    method @Nullable public E pollFirst();
-    method @Nullable public E pollLast();
-    method public E pop();
-    method public void push(E);
-    method public E remove();
-    method public E removeFirst();
-    method public boolean removeFirstOccurrence(@Nullable Object);
-    method public E removeLast();
-    method public boolean removeLastOccurrence(@Nullable Object);
-    method public int size();
-  }
-
-  public interface List<E> extends java.util.Collection<E> {
-    method public void add(int, E);
-    method public boolean addAll(int, @NonNull java.util.Collection<? extends E>);
-    method public E get(int);
-    method public int indexOf(@Nullable Object);
-    method public int lastIndexOf(@Nullable Object);
-    method @NonNull public java.util.ListIterator<E> listIterator();
-    method @NonNull public java.util.ListIterator<E> listIterator(int);
-    method @NonNull public static <E> java.util.List<E> of();
-    method @NonNull public static <E> java.util.List<E> of(@NonNull E);
-    method @NonNull public static <E> java.util.List<E> of(@NonNull E, @NonNull E);
-    method @NonNull public static <E> java.util.List<E> of(@NonNull E, @NonNull E, @NonNull E);
-    method @NonNull public static <E> java.util.List<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E);
-    method @NonNull public static <E> java.util.List<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
-    method @NonNull public static <E> java.util.List<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
-    method @NonNull public static <E> java.util.List<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
-    method @NonNull public static <E> java.util.List<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
-    method @NonNull public static <E> java.util.List<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
-    method @NonNull public static <E> java.util.List<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
-    method @NonNull @java.lang.SafeVarargs public static <E> java.util.List<E> of(@NonNull E...);
-    method public E remove(int);
-    method public default void replaceAll(@NonNull java.util.function.UnaryOperator<E>);
-    method public E set(int, E);
-    method public default void sort(@Nullable java.util.Comparator<? super E>);
-    method @NonNull public java.util.List<E> subList(int, int);
-  }
-
-  public interface ListIterator<E> extends java.util.Iterator<E> {
-    method public void add(E);
-    method public boolean hasPrevious();
-    method public int nextIndex();
-    method public E previous();
-    method public int previousIndex();
-    method public void remove();
-    method public void set(E);
-  }
-
-  public abstract class ListResourceBundle extends java.util.ResourceBundle {
-    ctor public ListResourceBundle();
-    method protected abstract Object[][] getContents();
-    method public java.util.Enumeration<java.lang.String> getKeys();
-    method public final Object handleGetObject(String);
-  }
-
-  public final class Locale implements java.lang.Cloneable java.io.Serializable {
-    ctor public Locale(@NonNull String, @NonNull String, @NonNull String);
-    ctor public Locale(@NonNull String, @NonNull String);
-    ctor public Locale(@NonNull String);
-    method @NonNull public Object clone();
-    method @NonNull public static java.util.List<java.util.Locale> filter(@NonNull java.util.List<java.util.Locale.LanguageRange>, @NonNull java.util.Collection<java.util.Locale>, @NonNull java.util.Locale.FilteringMode);
-    method @NonNull public static java.util.List<java.util.Locale> filter(@NonNull java.util.List<java.util.Locale.LanguageRange>, @NonNull java.util.Collection<java.util.Locale>);
-    method @NonNull public static java.util.List<java.lang.String> filterTags(@NonNull java.util.List<java.util.Locale.LanguageRange>, @NonNull java.util.Collection<java.lang.String>, @NonNull java.util.Locale.FilteringMode);
-    method @NonNull public static java.util.List<java.lang.String> filterTags(@NonNull java.util.List<java.util.Locale.LanguageRange>, @NonNull java.util.Collection<java.lang.String>);
-    method @NonNull public static java.util.Locale forLanguageTag(@NonNull String);
-    method @NonNull public static java.util.Locale[] getAvailableLocales();
-    method @NonNull public String getCountry();
-    method @NonNull public static java.util.Locale getDefault();
-    method @NonNull public static java.util.Locale getDefault(@NonNull java.util.Locale.Category);
-    method @NonNull public String getDisplayCountry();
-    method @NonNull public String getDisplayCountry(@NonNull java.util.Locale);
-    method @NonNull public String getDisplayLanguage();
-    method @NonNull public String getDisplayLanguage(@NonNull java.util.Locale);
-    method @NonNull public String getDisplayName();
-    method @NonNull public String getDisplayName(@NonNull java.util.Locale);
-    method @NonNull public String getDisplayScript();
-    method @NonNull public String getDisplayScript(@NonNull java.util.Locale);
-    method @NonNull public String getDisplayVariant();
-    method @NonNull public String getDisplayVariant(@NonNull java.util.Locale);
-    method @Nullable public String getExtension(char);
-    method @NonNull public java.util.Set<java.lang.Character> getExtensionKeys();
-    method @NonNull public String getISO3Country() throws java.util.MissingResourceException;
-    method @NonNull public String getISO3Language() throws java.util.MissingResourceException;
-    method @NonNull public static String[] getISOCountries();
-    method @NonNull public static String[] getISOLanguages();
-    method @NonNull public String getLanguage();
-    method @NonNull public String getScript();
-    method @NonNull public java.util.Set<java.lang.String> getUnicodeLocaleAttributes();
-    method @NonNull public java.util.Set<java.lang.String> getUnicodeLocaleKeys();
-    method @Nullable public String getUnicodeLocaleType(@NonNull String);
-    method @NonNull public String getVariant();
-    method public boolean hasExtensions();
-    method @Nullable public static java.util.Locale lookup(@NonNull java.util.List<java.util.Locale.LanguageRange>, @NonNull java.util.Collection<java.util.Locale>);
-    method @Nullable public static String lookupTag(@NonNull java.util.List<java.util.Locale.LanguageRange>, @NonNull java.util.Collection<java.lang.String>);
-    method public static void setDefault(@NonNull java.util.Locale);
-    method public static void setDefault(@NonNull java.util.Locale.Category, @NonNull java.util.Locale);
-    method @NonNull public java.util.Locale stripExtensions();
-    method @NonNull public String toLanguageTag();
-    field @NonNull public static final java.util.Locale CANADA;
-    field @NonNull public static final java.util.Locale CANADA_FRENCH;
-    field @NonNull public static final java.util.Locale CHINA;
-    field @NonNull public static final java.util.Locale CHINESE;
-    field @NonNull public static final java.util.Locale ENGLISH;
-    field @NonNull public static final java.util.Locale FRANCE;
-    field @NonNull public static final java.util.Locale FRENCH;
-    field @NonNull public static final java.util.Locale GERMAN;
-    field @NonNull public static final java.util.Locale GERMANY;
-    field @NonNull public static final java.util.Locale ITALIAN;
-    field @NonNull public static final java.util.Locale ITALY;
-    field @NonNull public static final java.util.Locale JAPAN;
-    field @NonNull public static final java.util.Locale JAPANESE;
-    field @NonNull public static final java.util.Locale KOREA;
-    field @NonNull public static final java.util.Locale KOREAN;
-    field @NonNull public static final java.util.Locale PRC;
-    field public static final char PRIVATE_USE_EXTENSION = 120; // 0x0078 'x'
-    field @NonNull public static final java.util.Locale ROOT;
-    field @NonNull public static final java.util.Locale SIMPLIFIED_CHINESE;
-    field @NonNull public static final java.util.Locale TAIWAN;
-    field @NonNull public static final java.util.Locale TRADITIONAL_CHINESE;
-    field @NonNull public static final java.util.Locale UK;
-    field public static final char UNICODE_LOCALE_EXTENSION = 117; // 0x0075 'u'
-    field @NonNull public static final java.util.Locale US;
-  }
-
-  public static final class Locale.Builder {
-    ctor public Locale.Builder();
-    method @NonNull public java.util.Locale.Builder addUnicodeLocaleAttribute(@NonNull String);
-    method @NonNull public java.util.Locale build();
-    method @NonNull public java.util.Locale.Builder clear();
-    method @NonNull public java.util.Locale.Builder clearExtensions();
-    method @NonNull public java.util.Locale.Builder removeUnicodeLocaleAttribute(@NonNull String);
-    method @NonNull public java.util.Locale.Builder setExtension(char, @Nullable String);
-    method @NonNull public java.util.Locale.Builder setLanguage(@Nullable String);
-    method @NonNull public java.util.Locale.Builder setLanguageTag(@NonNull String);
-    method @NonNull public java.util.Locale.Builder setLocale(@NonNull java.util.Locale);
-    method @NonNull public java.util.Locale.Builder setRegion(@Nullable String);
-    method @NonNull public java.util.Locale.Builder setScript(@Nullable String);
-    method @NonNull public java.util.Locale.Builder setUnicodeLocaleKeyword(@NonNull String, @Nullable String);
-    method @NonNull public java.util.Locale.Builder setVariant(@Nullable String);
-  }
-
-  public enum Locale.Category {
-    enum_constant public static final java.util.Locale.Category DISPLAY;
-    enum_constant public static final java.util.Locale.Category FORMAT;
-  }
-
-  public enum Locale.FilteringMode {
-    enum_constant public static final java.util.Locale.FilteringMode AUTOSELECT_FILTERING;
-    enum_constant public static final java.util.Locale.FilteringMode EXTENDED_FILTERING;
-    enum_constant public static final java.util.Locale.FilteringMode IGNORE_EXTENDED_RANGES;
-    enum_constant public static final java.util.Locale.FilteringMode MAP_EXTENDED_RANGES;
-    enum_constant public static final java.util.Locale.FilteringMode REJECT_EXTENDED_RANGES;
-  }
-
-  public static final class Locale.LanguageRange {
-    ctor public Locale.LanguageRange(@NonNull String);
-    ctor public Locale.LanguageRange(@NonNull String, double);
-    method @NonNull public String getRange();
-    method public double getWeight();
-    method @NonNull public static java.util.List<java.util.Locale.LanguageRange> mapEquivalents(@NonNull java.util.List<java.util.Locale.LanguageRange>, @NonNull java.util.Map<java.lang.String,java.util.List<java.lang.String>>);
-    method @NonNull public static java.util.List<java.util.Locale.LanguageRange> parse(@NonNull String);
-    method @NonNull public static java.util.List<java.util.Locale.LanguageRange> parse(@NonNull String, @NonNull java.util.Map<java.lang.String,java.util.List<java.lang.String>>);
-    field public static final double MAX_WEIGHT = 1.0;
-    field public static final double MIN_WEIGHT = 0.0;
-  }
-
-  public class LongSummaryStatistics implements java.util.function.IntConsumer java.util.function.LongConsumer {
-    ctor public LongSummaryStatistics();
-    method public void accept(int);
-    method public void accept(long);
-    method public void combine(java.util.LongSummaryStatistics);
-    method public final double getAverage();
-    method public final long getCount();
-    method public final long getMax();
-    method public final long getMin();
-    method public final long getSum();
-  }
-
-  public interface Map<K, V> {
-    method public void clear();
-    method @Nullable public default V compute(K, @NonNull java.util.function.BiFunction<? super K,? super V,? extends V>);
-    method @Nullable public default V computeIfAbsent(K, @NonNull java.util.function.Function<? super K,? extends V>);
-    method @Nullable public default V computeIfPresent(K, @NonNull java.util.function.BiFunction<? super K,? super V,? extends V>);
-    method public boolean containsKey(@Nullable Object);
-    method public boolean containsValue(@Nullable Object);
-    method @NonNull public static <K, V> java.util.Map.Entry<K,V> entry(@NonNull K, @NonNull V);
-    method @NonNull public java.util.Set<java.util.Map.Entry<K,V>> entrySet();
-    method public boolean equals(@Nullable Object);
-    method public default void forEach(@NonNull java.util.function.BiConsumer<? super K,? super V>);
-    method @Nullable public V get(@Nullable Object);
-    method @Nullable public default V getOrDefault(@Nullable Object, @Nullable V);
-    method public int hashCode();
-    method public boolean isEmpty();
-    method @NonNull public java.util.Set<K> keySet();
-    method @Nullable public default V merge(K, @NonNull V, @NonNull java.util.function.BiFunction<? super V,? super V,? extends V>);
-    method @NonNull public static <K, V> java.util.Map<K,V> of();
-    method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V);
-    method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V, @NonNull K, @NonNull V);
-    method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V);
-    method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V);
-    method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V);
-    method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V);
-    method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V);
-    method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V);
-    method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V);
-    method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V);
-    method @NonNull @java.lang.SafeVarargs public static <K, V> java.util.Map<K,V> ofEntries(@NonNull java.util.Map.Entry<? extends K,? extends V>...);
-    method @Nullable public V put(K, V);
-    method public void putAll(@NonNull java.util.Map<? extends K,? extends V>);
-    method @Nullable public default V putIfAbsent(K, V);
-    method @Nullable public V remove(@Nullable Object);
-    method public default boolean remove(@Nullable Object, @Nullable Object);
-    method public default boolean replace(K, @Nullable V, V);
-    method @Nullable public default V replace(K, V);
-    method public default void replaceAll(@NonNull java.util.function.BiFunction<? super K,? super V,? extends V>);
-    method public int size();
-    method @NonNull public java.util.Collection<V> values();
-  }
-
-  public static interface Map.Entry<K, V> {
-    method @NonNull public static <K extends java.lang.Comparable<? super K>, V> java.util.Comparator<java.util.Map.Entry<K,V>> comparingByKey();
-    method @NonNull public static <K, V> java.util.Comparator<java.util.Map.Entry<K,V>> comparingByKey(@NonNull java.util.Comparator<? super K>);
-    method @NonNull public static <K, V extends java.lang.Comparable<? super V>> java.util.Comparator<java.util.Map.Entry<K,V>> comparingByValue();
-    method @NonNull public static <K, V> java.util.Comparator<java.util.Map.Entry<K,V>> comparingByValue(@NonNull java.util.Comparator<? super V>);
-    method public boolean equals(@Nullable Object);
-    method public K getKey();
-    method public V getValue();
-    method public int hashCode();
-    method public V setValue(V);
-  }
-
-  public class MissingFormatArgumentException extends java.util.IllegalFormatException {
-    ctor public MissingFormatArgumentException(String);
-    method public String getFormatSpecifier();
-  }
-
-  public class MissingFormatWidthException extends java.util.IllegalFormatException {
-    ctor public MissingFormatWidthException(String);
-    method public String getFormatSpecifier();
-  }
-
-  public class MissingResourceException extends java.lang.RuntimeException {
-    ctor public MissingResourceException(String, String, String);
-    method public String getClassName();
-    method public String getKey();
-  }
-
-  public interface NavigableMap<K, V> extends java.util.SortedMap<K,V> {
-    method @Nullable public java.util.Map.Entry<K,V> ceilingEntry(K);
-    method @Nullable public K ceilingKey(K);
-    method @NonNull public java.util.NavigableSet<K> descendingKeySet();
-    method @NonNull public java.util.NavigableMap<K,V> descendingMap();
-    method @Nullable public java.util.Map.Entry<K,V> firstEntry();
-    method @Nullable public java.util.Map.Entry<K,V> floorEntry(K);
-    method @Nullable public K floorKey(K);
-    method @NonNull public java.util.NavigableMap<K,V> headMap(K, boolean);
-    method @Nullable public java.util.Map.Entry<K,V> higherEntry(K);
-    method @Nullable public K higherKey(K);
-    method @Nullable public java.util.Map.Entry<K,V> lastEntry();
-    method @Nullable public java.util.Map.Entry<K,V> lowerEntry(K);
-    method @Nullable public K lowerKey(K);
-    method @NonNull public java.util.NavigableSet<K> navigableKeySet();
-    method @Nullable public java.util.Map.Entry<K,V> pollFirstEntry();
-    method @Nullable public java.util.Map.Entry<K,V> pollLastEntry();
-    method @NonNull public java.util.NavigableMap<K,V> subMap(K, boolean, K, boolean);
-    method @NonNull public java.util.NavigableMap<K,V> tailMap(K, boolean);
-  }
-
-  public interface NavigableSet<E> extends java.util.SortedSet<E> {
-    method public E ceiling(E);
-    method public java.util.Iterator<E> descendingIterator();
-    method public java.util.NavigableSet<E> descendingSet();
-    method public E floor(E);
-    method public java.util.NavigableSet<E> headSet(E, boolean);
-    method public E higher(E);
-    method public E lower(E);
-    method public E pollFirst();
-    method public E pollLast();
-    method public java.util.NavigableSet<E> subSet(E, boolean, E, boolean);
-    method public java.util.NavigableSet<E> tailSet(E, boolean);
-  }
-
-  public class NoSuchElementException extends java.lang.RuntimeException {
-    ctor public NoSuchElementException();
-    ctor public NoSuchElementException(String);
-  }
-
-  public final class Objects {
-    method public static int checkFromIndexSize(int, int, int);
-    method public static int checkFromToIndex(int, int, int);
-    method public static int checkIndex(int, int);
-    method public static <T> int compare(T, T, @NonNull java.util.Comparator<? super T>);
-    method public static boolean deepEquals(@Nullable Object, @Nullable Object);
-    method public static boolean equals(@Nullable Object, @Nullable Object);
-    method public static int hash(@Nullable java.lang.Object...);
-    method public static int hashCode(@Nullable Object);
-    method public static boolean isNull(@Nullable Object);
-    method public static boolean nonNull(@Nullable Object);
-    method @NonNull public static <T> T requireNonNull(@Nullable T);
-    method @NonNull public static <T> T requireNonNull(@Nullable T, @NonNull String);
-    method @NonNull public static <T> T requireNonNull(@Nullable T, @NonNull java.util.function.Supplier<java.lang.String>);
-    method @NonNull public static <T> T requireNonNullElse(@Nullable T, @NonNull T);
-    method @NonNull public static <T> T requireNonNullElseGet(@Nullable T, @NonNull java.util.function.Supplier<? extends T>);
-    method @NonNull public static String toString(@Nullable Object);
-    method @NonNull public static String toString(@Nullable Object, @NonNull String);
-  }
-
-  public class Observable {
-    ctor public Observable();
-    method public void addObserver(java.util.Observer);
-    method protected void clearChanged();
-    method public int countObservers();
-    method public void deleteObserver(java.util.Observer);
-    method public void deleteObservers();
-    method public boolean hasChanged();
-    method public void notifyObservers();
-    method public void notifyObservers(Object);
-    method protected void setChanged();
-  }
-
-  public interface Observer {
-    method public void update(java.util.Observable, Object);
-  }
-
-  public final class Optional<T> {
-    method public static <T> java.util.Optional<T> empty();
-    method public java.util.Optional<T> filter(java.util.function.Predicate<? super T>);
-    method public <U> java.util.Optional<U> flatMap(java.util.function.Function<? super T,java.util.Optional<U>>);
-    method public T get();
-    method public void ifPresent(java.util.function.Consumer<? super T>);
-    method public boolean isPresent();
-    method public <U> java.util.Optional<U> map(java.util.function.Function<? super T,? extends U>);
-    method public static <T> java.util.Optional<T> of(T);
-    method public static <T> java.util.Optional<T> ofNullable(T);
-    method public T orElse(T);
-    method public T orElseGet(java.util.function.Supplier<? extends T>);
-    method public <X extends java.lang.Throwable> T orElseThrow(java.util.function.Supplier<? extends X>) throws X;
-  }
-
-  public final class OptionalDouble {
-    method public static java.util.OptionalDouble empty();
-    method public double getAsDouble();
-    method public void ifPresent(java.util.function.DoubleConsumer);
-    method public boolean isPresent();
-    method public static java.util.OptionalDouble of(double);
-    method public double orElse(double);
-    method public double orElseGet(java.util.function.DoubleSupplier);
-    method public <X extends java.lang.Throwable> double orElseThrow(java.util.function.Supplier<X>) throws X;
-  }
-
-  public final class OptionalInt {
-    method public static java.util.OptionalInt empty();
-    method public int getAsInt();
-    method public void ifPresent(java.util.function.IntConsumer);
-    method public boolean isPresent();
-    method public static java.util.OptionalInt of(int);
-    method public int orElse(int);
-    method public int orElseGet(java.util.function.IntSupplier);
-    method public <X extends java.lang.Throwable> int orElseThrow(java.util.function.Supplier<X>) throws X;
-  }
-
-  public final class OptionalLong {
-    method public static java.util.OptionalLong empty();
-    method public long getAsLong();
-    method public void ifPresent(java.util.function.LongConsumer);
-    method public boolean isPresent();
-    method public static java.util.OptionalLong of(long);
-    method public long orElse(long);
-    method public long orElseGet(java.util.function.LongSupplier);
-    method public <X extends java.lang.Throwable> long orElseThrow(java.util.function.Supplier<X>) throws X;
-  }
-
-  public interface PrimitiveIterator<T, T_CONS> extends java.util.Iterator<T> {
-    method public void forEachRemaining(T_CONS);
-  }
-
-  public static interface PrimitiveIterator.OfDouble extends java.util.PrimitiveIterator<java.lang.Double,java.util.function.DoubleConsumer> {
-    method public default void forEachRemaining(java.util.function.DoubleConsumer);
-    method public default void forEachRemaining(java.util.function.Consumer<? super java.lang.Double>);
-    method public default Double next();
-    method public double nextDouble();
-  }
-
-  public static interface PrimitiveIterator.OfInt extends java.util.PrimitiveIterator<java.lang.Integer,java.util.function.IntConsumer> {
-    method public default void forEachRemaining(java.util.function.IntConsumer);
-    method public default void forEachRemaining(java.util.function.Consumer<? super java.lang.Integer>);
-    method public default Integer next();
-    method public int nextInt();
-  }
-
-  public static interface PrimitiveIterator.OfLong extends java.util.PrimitiveIterator<java.lang.Long,java.util.function.LongConsumer> {
-    method public default void forEachRemaining(java.util.function.LongConsumer);
-    method public default void forEachRemaining(java.util.function.Consumer<? super java.lang.Long>);
-    method public default Long next();
-    method public long nextLong();
-  }
-
-  public class PriorityQueue<E> extends java.util.AbstractQueue<E> implements java.io.Serializable {
-    ctor public PriorityQueue();
-    ctor public PriorityQueue(int);
-    ctor public PriorityQueue(java.util.Comparator<? super E>);
-    ctor public PriorityQueue(int, java.util.Comparator<? super E>);
-    ctor public PriorityQueue(java.util.Collection<? extends E>);
-    ctor public PriorityQueue(java.util.PriorityQueue<? extends E>);
-    ctor public PriorityQueue(java.util.SortedSet<? extends E>);
-    method public java.util.Comparator<? super E> comparator();
-    method public java.util.Iterator<E> iterator();
-    method public boolean offer(E);
-    method public E peek();
-    method public E poll();
-    method public int size();
-    method public final java.util.Spliterator<E> spliterator();
-  }
-
-  public class Properties extends java.util.Hashtable<java.lang.Object,java.lang.Object> {
-    ctor public Properties();
-    ctor public Properties(java.util.Properties);
-    method public String getProperty(String);
-    method public String getProperty(String, String);
-    method public void list(java.io.PrintStream);
-    method public void list(java.io.PrintWriter);
-    method public void load(java.io.Reader) throws java.io.IOException;
-    method public void load(java.io.InputStream) throws java.io.IOException;
-    method public void loadFromXML(java.io.InputStream) throws java.io.IOException, java.util.InvalidPropertiesFormatException;
-    method public java.util.Enumeration<?> propertyNames();
-    method @Deprecated public void save(java.io.OutputStream, String);
-    method public Object setProperty(String, String);
-    method public void store(java.io.Writer, String) throws java.io.IOException;
-    method public void store(java.io.OutputStream, String) throws java.io.IOException;
-    method public void storeToXML(java.io.OutputStream, String) throws java.io.IOException;
-    method public void storeToXML(java.io.OutputStream, String, String) throws java.io.IOException;
-    method public java.util.Set<java.lang.String> stringPropertyNames();
-    field protected java.util.Properties defaults;
-  }
-
-  public final class PropertyPermission extends java.security.BasicPermission {
-    ctor public PropertyPermission(String, String);
-  }
-
-  public class PropertyResourceBundle extends java.util.ResourceBundle {
-    ctor public PropertyResourceBundle(java.io.InputStream) throws java.io.IOException;
-    ctor public PropertyResourceBundle(java.io.Reader) throws java.io.IOException;
-    method public java.util.Enumeration<java.lang.String> getKeys();
-    method public Object handleGetObject(String);
-  }
-
-  public interface Queue<E> extends java.util.Collection<E> {
-    method public E element();
-    method public boolean offer(E);
-    method @Nullable public E peek();
-    method @Nullable public E poll();
-    method public E remove();
-  }
-
-  public class Random implements java.io.Serializable {
-    ctor public Random();
-    ctor public Random(long);
-    method public java.util.stream.DoubleStream doubles(long);
-    method public java.util.stream.DoubleStream doubles();
-    method public java.util.stream.DoubleStream doubles(long, double, double);
-    method public java.util.stream.DoubleStream doubles(double, double);
-    method public java.util.stream.IntStream ints(long);
-    method public java.util.stream.IntStream ints();
-    method public java.util.stream.IntStream ints(long, int, int);
-    method public java.util.stream.IntStream ints(int, int);
-    method public java.util.stream.LongStream longs(long);
-    method public java.util.stream.LongStream longs();
-    method public java.util.stream.LongStream longs(long, long, long);
-    method public java.util.stream.LongStream longs(long, long);
-    method protected int next(int);
-    method public boolean nextBoolean();
-    method public void nextBytes(byte[]);
-    method public double nextDouble();
-    method public float nextFloat();
-    method public double nextGaussian();
-    method public int nextInt();
-    method public int nextInt(int);
-    method public long nextLong();
-    method public void setSeed(long);
-  }
-
-  public interface RandomAccess {
-  }
-
-  public abstract class ResourceBundle {
-    ctor public ResourceBundle();
-    method public static final void clearCache();
-    method public static final void clearCache(ClassLoader);
-    method public boolean containsKey(String);
-    method public String getBaseBundleName();
-    method public static final java.util.ResourceBundle getBundle(String);
-    method public static final java.util.ResourceBundle getBundle(String, java.util.ResourceBundle.Control);
-    method public static final java.util.ResourceBundle getBundle(String, java.util.Locale);
-    method public static final java.util.ResourceBundle getBundle(String, java.util.Locale, java.util.ResourceBundle.Control);
-    method public static java.util.ResourceBundle getBundle(String, java.util.Locale, ClassLoader);
-    method public static java.util.ResourceBundle getBundle(String, java.util.Locale, ClassLoader, java.util.ResourceBundle.Control);
-    method public abstract java.util.Enumeration<java.lang.String> getKeys();
-    method public java.util.Locale getLocale();
-    method public final Object getObject(String);
-    method public final String getString(String);
-    method public final String[] getStringArray(String);
-    method protected abstract Object handleGetObject(String);
-    method protected java.util.Set<java.lang.String> handleKeySet();
-    method public java.util.Set<java.lang.String> keySet();
-    method protected void setParent(java.util.ResourceBundle);
-    field protected java.util.ResourceBundle parent;
-  }
-
-  public static class ResourceBundle.Control {
-    ctor protected ResourceBundle.Control();
-    method public java.util.List<java.util.Locale> getCandidateLocales(String, java.util.Locale);
-    method public static final java.util.ResourceBundle.Control getControl(java.util.List<java.lang.String>);
-    method public java.util.Locale getFallbackLocale(String, java.util.Locale);
-    method public java.util.List<java.lang.String> getFormats(String);
-    method public static final java.util.ResourceBundle.Control getNoFallbackControl(java.util.List<java.lang.String>);
-    method public long getTimeToLive(String, java.util.Locale);
-    method public boolean needsReload(String, java.util.Locale, String, ClassLoader, java.util.ResourceBundle, long);
-    method public java.util.ResourceBundle newBundle(String, java.util.Locale, String, ClassLoader, boolean) throws java.io.IOException, java.lang.IllegalAccessException, java.lang.InstantiationException;
-    method public String toBundleName(String, java.util.Locale);
-    method public final String toResourceName(String, String);
-    field public static final java.util.List<java.lang.String> FORMAT_CLASS;
-    field public static final java.util.List<java.lang.String> FORMAT_DEFAULT;
-    field public static final java.util.List<java.lang.String> FORMAT_PROPERTIES;
-    field public static final long TTL_DONT_CACHE = -1L; // 0xffffffffffffffffL
-    field public static final long TTL_NO_EXPIRATION_CONTROL = -2L; // 0xfffffffffffffffeL
-  }
-
-  public final class Scanner implements java.io.Closeable java.util.Iterator<java.lang.String> {
-    ctor public Scanner(Readable);
-    ctor public Scanner(java.io.InputStream);
-    ctor public Scanner(java.io.InputStream, String);
-    ctor public Scanner(java.io.File) throws java.io.FileNotFoundException;
-    ctor public Scanner(java.io.File, String) throws java.io.FileNotFoundException;
-    ctor public Scanner(java.nio.file.Path) throws java.io.IOException;
-    ctor public Scanner(java.nio.file.Path, String) throws java.io.IOException;
-    ctor public Scanner(String);
-    ctor public Scanner(java.nio.channels.ReadableByteChannel);
-    ctor public Scanner(java.nio.channels.ReadableByteChannel, String);
-    method public void close();
-    method public java.util.regex.Pattern delimiter();
-    method public String findInLine(String);
-    method public String findInLine(java.util.regex.Pattern);
-    method public String findWithinHorizon(String, int);
-    method public String findWithinHorizon(java.util.regex.Pattern, int);
-    method public boolean hasNext();
-    method public boolean hasNext(String);
-    method public boolean hasNext(java.util.regex.Pattern);
-    method public boolean hasNextBigDecimal();
-    method public boolean hasNextBigInteger();
-    method public boolean hasNextBigInteger(int);
-    method public boolean hasNextBoolean();
-    method public boolean hasNextByte();
-    method public boolean hasNextByte(int);
-    method public boolean hasNextDouble();
-    method public boolean hasNextFloat();
-    method public boolean hasNextInt();
-    method public boolean hasNextInt(int);
-    method public boolean hasNextLine();
-    method public boolean hasNextLong();
-    method public boolean hasNextLong(int);
-    method public boolean hasNextShort();
-    method public boolean hasNextShort(int);
-    method public java.io.IOException ioException();
-    method public java.util.Locale locale();
-    method public java.util.regex.MatchResult match();
-    method public String next();
-    method public String next(String);
-    method public String next(java.util.regex.Pattern);
-    method public java.math.BigDecimal nextBigDecimal();
-    method public java.math.BigInteger nextBigInteger();
-    method public java.math.BigInteger nextBigInteger(int);
-    method public boolean nextBoolean();
-    method public byte nextByte();
-    method public byte nextByte(int);
-    method public double nextDouble();
-    method public float nextFloat();
-    method public int nextInt();
-    method public int nextInt(int);
-    method public String nextLine();
-    method public long nextLong();
-    method public long nextLong(int);
-    method public short nextShort();
-    method public short nextShort(int);
-    method public int radix();
-    method public java.util.Scanner reset();
-    method public java.util.Scanner skip(java.util.regex.Pattern);
-    method public java.util.Scanner skip(String);
-    method public java.util.Scanner useDelimiter(java.util.regex.Pattern);
-    method public java.util.Scanner useDelimiter(String);
-    method public java.util.Scanner useLocale(java.util.Locale);
-    method public java.util.Scanner useRadix(int);
-  }
-
-  public class ServiceConfigurationError extends java.lang.Error {
-    ctor public ServiceConfigurationError(String);
-    ctor public ServiceConfigurationError(String, Throwable);
-  }
-
-  public final class ServiceLoader<S> implements java.lang.Iterable<S> {
-    method public java.util.Iterator<S> iterator();
-    method public static <S> java.util.ServiceLoader<S> load(Class<S>, ClassLoader);
-    method public static <S> java.util.ServiceLoader<S> load(Class<S>);
-    method public static <S> java.util.ServiceLoader<S> loadInstalled(Class<S>);
-    method public void reload();
-  }
-
-  public interface Set<E> extends java.util.Collection<E> {
-    method @NonNull public static <E> java.util.Set<E> of();
-    method @NonNull public static <E> java.util.Set<E> of(@NonNull E);
-    method @NonNull public static <E> java.util.Set<E> of(@NonNull E, @NonNull E);
-    method @NonNull public static <E> java.util.Set<E> of(@NonNull E, @NonNull E, @NonNull E);
-    method @NonNull public static <E> java.util.Set<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E);
-    method @NonNull public static <E> java.util.Set<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
-    method @NonNull public static <E> java.util.Set<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
-    method @NonNull public static <E> java.util.Set<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
-    method @NonNull public static <E> java.util.Set<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
-    method @NonNull public static <E> java.util.Set<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
-    method @NonNull public static <E> java.util.Set<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
-    method @NonNull @java.lang.SafeVarargs public static <E> java.util.Set<E> of(@NonNull E...);
-  }
-
-  public class SimpleTimeZone extends java.util.TimeZone {
-    ctor public SimpleTimeZone(int, String);
-    ctor public SimpleTimeZone(int, String, int, int, int, int, int, int, int, int);
-    ctor public SimpleTimeZone(int, String, int, int, int, int, int, int, int, int, int);
-    ctor public SimpleTimeZone(int, String, int, int, int, int, int, int, int, int, int, int, int);
-    method public int getOffset(int, int, int, int, int, int);
-    method public int getRawOffset();
-    method public boolean inDaylightTime(java.util.Date);
-    method public void setDSTSavings(int);
-    method public void setEndRule(int, int, int, int);
-    method public void setEndRule(int, int, int);
-    method public void setEndRule(int, int, int, int, boolean);
-    method public void setRawOffset(int);
-    method public void setStartRule(int, int, int, int);
-    method public void setStartRule(int, int, int);
-    method public void setStartRule(int, int, int, int, boolean);
-    method public void setStartYear(int);
-    method public boolean useDaylightTime();
-    field public static final int STANDARD_TIME = 1; // 0x1
-    field public static final int UTC_TIME = 2; // 0x2
-    field public static final int WALL_TIME = 0; // 0x0
-  }
-
-  public interface SortedMap<K, V> extends java.util.Map<K,V> {
-    method @Nullable public java.util.Comparator<? super K> comparator();
-    method public K firstKey();
-    method @NonNull public java.util.SortedMap<K,V> headMap(K);
-    method public K lastKey();
-    method @NonNull public java.util.SortedMap<K,V> subMap(K, K);
-    method @NonNull public java.util.SortedMap<K,V> tailMap(K);
-  }
-
-  public interface SortedSet<E> extends java.util.Set<E> {
-    method public java.util.Comparator<? super E> comparator();
-    method public E first();
-    method public java.util.SortedSet<E> headSet(E);
-    method public E last();
-    method public java.util.SortedSet<E> subSet(E, E);
-    method public java.util.SortedSet<E> tailSet(E);
-  }
-
-  public interface Spliterator<T> {
-    method public int characteristics();
-    method public long estimateSize();
-    method public default void forEachRemaining(java.util.function.Consumer<? super T>);
-    method public default java.util.Comparator<? super T> getComparator();
-    method public default long getExactSizeIfKnown();
-    method public default boolean hasCharacteristics(int);
-    method public boolean tryAdvance(java.util.function.Consumer<? super T>);
-    method public java.util.Spliterator<T> trySplit();
-    field public static final int CONCURRENT = 4096; // 0x1000
-    field public static final int DISTINCT = 1; // 0x1
-    field public static final int IMMUTABLE = 1024; // 0x400
-    field public static final int NONNULL = 256; // 0x100
-    field public static final int ORDERED = 16; // 0x10
-    field public static final int SIZED = 64; // 0x40
-    field public static final int SORTED = 4; // 0x4
-    field public static final int SUBSIZED = 16384; // 0x4000
-  }
-
-  public static interface Spliterator.OfDouble extends java.util.Spliterator.OfPrimitive<java.lang.Double,java.util.function.DoubleConsumer,java.util.Spliterator.OfDouble> {
-    method public default void forEachRemaining(java.util.function.DoubleConsumer);
-    method public default void forEachRemaining(java.util.function.Consumer<? super java.lang.Double>);
-    method public boolean tryAdvance(java.util.function.DoubleConsumer);
-    method public default boolean tryAdvance(java.util.function.Consumer<? super java.lang.Double>);
-    method public java.util.Spliterator.OfDouble trySplit();
-  }
-
-  public static interface Spliterator.OfInt extends java.util.Spliterator.OfPrimitive<java.lang.Integer,java.util.function.IntConsumer,java.util.Spliterator.OfInt> {
-    method public default void forEachRemaining(java.util.function.IntConsumer);
-    method public default void forEachRemaining(java.util.function.Consumer<? super java.lang.Integer>);
-    method public boolean tryAdvance(java.util.function.IntConsumer);
-    method public default boolean tryAdvance(java.util.function.Consumer<? super java.lang.Integer>);
-    method public java.util.Spliterator.OfInt trySplit();
-  }
-
-  public static interface Spliterator.OfLong extends java.util.Spliterator.OfPrimitive<java.lang.Long,java.util.function.LongConsumer,java.util.Spliterator.OfLong> {
-    method public default void forEachRemaining(java.util.function.LongConsumer);
-    method public default void forEachRemaining(java.util.function.Consumer<? super java.lang.Long>);
-    method public boolean tryAdvance(java.util.function.LongConsumer);
-    method public default boolean tryAdvance(java.util.function.Consumer<? super java.lang.Long>);
-    method public java.util.Spliterator.OfLong trySplit();
-  }
-
-  public static interface Spliterator.OfPrimitive<T, T_CONS, T_SPLITR extends java.util.Spliterator.OfPrimitive<T, T_CONS, T_SPLITR>> extends java.util.Spliterator<T> {
-    method public default void forEachRemaining(T_CONS);
-    method public boolean tryAdvance(T_CONS);
-    method public T_SPLITR trySplit();
-  }
-
-  public final class Spliterators {
-    method public static java.util.Spliterator.OfDouble emptyDoubleSpliterator();
-    method public static java.util.Spliterator.OfInt emptyIntSpliterator();
-    method public static java.util.Spliterator.OfLong emptyLongSpliterator();
-    method public static <T> java.util.Spliterator<T> emptySpliterator();
-    method public static <T> java.util.Iterator<T> iterator(java.util.Spliterator<? extends T>);
-    method public static java.util.PrimitiveIterator.OfInt iterator(java.util.Spliterator.OfInt);
-    method public static java.util.PrimitiveIterator.OfLong iterator(java.util.Spliterator.OfLong);
-    method public static java.util.PrimitiveIterator.OfDouble iterator(java.util.Spliterator.OfDouble);
-    method public static <T> java.util.Spliterator<T> spliterator(Object[], int);
-    method public static <T> java.util.Spliterator<T> spliterator(Object[], int, int, int);
-    method public static java.util.Spliterator.OfInt spliterator(int[], int);
-    method public static java.util.Spliterator.OfInt spliterator(int[], int, int, int);
-    method public static java.util.Spliterator.OfLong spliterator(long[], int);
-    method public static java.util.Spliterator.OfLong spliterator(long[], int, int, int);
-    method public static java.util.Spliterator.OfDouble spliterator(double[], int);
-    method public static java.util.Spliterator.OfDouble spliterator(double[], int, int, int);
-    method public static <T> java.util.Spliterator<T> spliterator(java.util.Collection<? extends T>, int);
-    method public static <T> java.util.Spliterator<T> spliterator(java.util.Iterator<? extends T>, long, int);
-    method public static java.util.Spliterator.OfInt spliterator(java.util.PrimitiveIterator.OfInt, long, int);
-    method public static java.util.Spliterator.OfLong spliterator(java.util.PrimitiveIterator.OfLong, long, int);
-    method public static java.util.Spliterator.OfDouble spliterator(java.util.PrimitiveIterator.OfDouble, long, int);
-    method public static <T> java.util.Spliterator<T> spliteratorUnknownSize(java.util.Iterator<? extends T>, int);
-    method public static java.util.Spliterator.OfInt spliteratorUnknownSize(java.util.PrimitiveIterator.OfInt, int);
-    method public static java.util.Spliterator.OfLong spliteratorUnknownSize(java.util.PrimitiveIterator.OfLong, int);
-    method public static java.util.Spliterator.OfDouble spliteratorUnknownSize(java.util.PrimitiveIterator.OfDouble, int);
-  }
-
-  public abstract static class Spliterators.AbstractDoubleSpliterator implements java.util.Spliterator.OfDouble {
-    ctor protected Spliterators.AbstractDoubleSpliterator(long, int);
-    method public int characteristics();
-    method public long estimateSize();
-    method public java.util.Spliterator.OfDouble trySplit();
-  }
-
-  public abstract static class Spliterators.AbstractIntSpliterator implements java.util.Spliterator.OfInt {
-    ctor protected Spliterators.AbstractIntSpliterator(long, int);
-    method public int characteristics();
-    method public long estimateSize();
-    method public java.util.Spliterator.OfInt trySplit();
-  }
-
-  public abstract static class Spliterators.AbstractLongSpliterator implements java.util.Spliterator.OfLong {
-    ctor protected Spliterators.AbstractLongSpliterator(long, int);
-    method public int characteristics();
-    method public long estimateSize();
-    method public java.util.Spliterator.OfLong trySplit();
-  }
-
-  public abstract static class Spliterators.AbstractSpliterator<T> implements java.util.Spliterator<T> {
-    ctor protected Spliterators.AbstractSpliterator(long, int);
-    method public int characteristics();
-    method public long estimateSize();
-    method public java.util.Spliterator<T> trySplit();
-  }
-
-  public final class SplittableRandom {
-    ctor public SplittableRandom(long);
-    ctor public SplittableRandom();
-    method public java.util.stream.DoubleStream doubles(long);
-    method public java.util.stream.DoubleStream doubles();
-    method public java.util.stream.DoubleStream doubles(long, double, double);
-    method public java.util.stream.DoubleStream doubles(double, double);
-    method public java.util.stream.IntStream ints(long);
-    method public java.util.stream.IntStream ints();
-    method public java.util.stream.IntStream ints(long, int, int);
-    method public java.util.stream.IntStream ints(int, int);
-    method public java.util.stream.LongStream longs(long);
-    method public java.util.stream.LongStream longs();
-    method public java.util.stream.LongStream longs(long, long, long);
-    method public java.util.stream.LongStream longs(long, long);
-    method public boolean nextBoolean();
-    method public double nextDouble();
-    method public double nextDouble(double);
-    method public double nextDouble(double, double);
-    method public int nextInt();
-    method public int nextInt(int);
-    method public int nextInt(int, int);
-    method public long nextLong();
-    method public long nextLong(long);
-    method public long nextLong(long, long);
-    method public java.util.SplittableRandom split();
-  }
-
-  public class Stack<E> extends java.util.Vector<E> {
-    ctor public Stack();
-    method public boolean empty();
-    method public E peek();
-    method public E pop();
-    method public E push(E);
-    method public int search(Object);
-  }
-
-  public final class StringJoiner {
-    ctor public StringJoiner(CharSequence);
-    ctor public StringJoiner(CharSequence, CharSequence, CharSequence);
-    method public java.util.StringJoiner add(CharSequence);
-    method public int length();
-    method public java.util.StringJoiner merge(java.util.StringJoiner);
-    method public java.util.StringJoiner setEmptyValue(CharSequence);
-  }
-
-  public class StringTokenizer implements java.util.Enumeration<java.lang.Object> {
-    ctor public StringTokenizer(String, String, boolean);
-    ctor public StringTokenizer(String, String);
-    ctor public StringTokenizer(String);
-    method public int countTokens();
-    method public boolean hasMoreElements();
-    method public boolean hasMoreTokens();
-    method public Object nextElement();
-    method public String nextToken();
-    method public String nextToken(String);
-  }
-
-  public abstract class TimeZone implements java.lang.Cloneable java.io.Serializable {
-    ctor public TimeZone();
-    method public Object clone();
-    method public static String[] getAvailableIDs(int);
-    method public static String[] getAvailableIDs();
-    method public int getDSTSavings();
-    method public static java.util.TimeZone getDefault();
-    method public final String getDisplayName();
-    method public final String getDisplayName(java.util.Locale);
-    method public final String getDisplayName(boolean, int);
-    method public String getDisplayName(boolean, int, java.util.Locale);
-    method public String getID();
-    method public abstract int getOffset(int, int, int, int, int, int);
-    method public int getOffset(long);
-    method public abstract int getRawOffset();
-    method public static java.util.TimeZone getTimeZone(String);
-    method public static java.util.TimeZone getTimeZone(java.time.ZoneId);
-    method public boolean hasSameRules(java.util.TimeZone);
-    method public abstract boolean inDaylightTime(java.util.Date);
-    method public boolean observesDaylightTime();
-    method public static void setDefault(java.util.TimeZone);
-    method public void setID(String);
-    method public abstract void setRawOffset(int);
-    method public java.time.ZoneId toZoneId();
-    method public abstract boolean useDaylightTime();
-    field public static final int LONG = 1; // 0x1
-    field public static final int SHORT = 0; // 0x0
-  }
-
-  public class Timer {
-    ctor public Timer();
-    ctor public Timer(boolean);
-    ctor public Timer(String);
-    ctor public Timer(String, boolean);
-    method public void cancel();
-    method public int purge();
-    method public void schedule(java.util.TimerTask, long);
-    method public void schedule(java.util.TimerTask, java.util.Date);
-    method public void schedule(java.util.TimerTask, long, long);
-    method public void schedule(java.util.TimerTask, java.util.Date, long);
-    method public void scheduleAtFixedRate(java.util.TimerTask, long, long);
-    method public void scheduleAtFixedRate(java.util.TimerTask, java.util.Date, long);
-  }
-
-  public abstract class TimerTask implements java.lang.Runnable {
-    ctor protected TimerTask();
-    method public boolean cancel();
-    method public long scheduledExecutionTime();
-  }
-
-  public class TooManyListenersException extends java.lang.Exception {
-    ctor public TooManyListenersException();
-    ctor public TooManyListenersException(String);
-  }
-
-  public class TreeMap<K, V> extends java.util.AbstractMap<K,V> implements java.lang.Cloneable java.util.NavigableMap<K,V> java.io.Serializable {
-    ctor public TreeMap();
-    ctor public TreeMap(@Nullable java.util.Comparator<? super K>);
-    ctor public TreeMap(@NonNull java.util.Map<? extends K,? extends V>);
-    ctor public TreeMap(@NonNull java.util.SortedMap<K,? extends V>);
-    method @Nullable public java.util.Map.Entry<K,V> ceilingEntry(K);
-    method @Nullable public K ceilingKey(K);
-    method @NonNull public Object clone();
-    method @Nullable public java.util.Comparator<? super K> comparator();
-    method @NonNull public java.util.NavigableSet<K> descendingKeySet();
-    method @NonNull public java.util.NavigableMap<K,V> descendingMap();
-    method @NonNull public java.util.Set<java.util.Map.Entry<K,V>> entrySet();
-    method @Nullable public java.util.Map.Entry<K,V> firstEntry();
-    method public K firstKey();
-    method @Nullable public java.util.Map.Entry<K,V> floorEntry(K);
-    method @Nullable public K floorKey(K);
-    method @NonNull public java.util.NavigableMap<K,V> headMap(K, boolean);
-    method @NonNull public java.util.SortedMap<K,V> headMap(K);
-    method @Nullable public java.util.Map.Entry<K,V> higherEntry(K);
-    method @Nullable public K higherKey(K);
-    method @Nullable public java.util.Map.Entry<K,V> lastEntry();
-    method public K lastKey();
-    method @Nullable public java.util.Map.Entry<K,V> lowerEntry(K);
-    method @Nullable public K lowerKey(K);
-    method @NonNull public java.util.NavigableSet<K> navigableKeySet();
-    method @Nullable public java.util.Map.Entry<K,V> pollFirstEntry();
-    method @Nullable public java.util.Map.Entry<K,V> pollLastEntry();
-    method @NonNull public java.util.NavigableMap<K,V> subMap(K, boolean, K, boolean);
-    method @NonNull public java.util.SortedMap<K,V> subMap(K, K);
-    method @NonNull public java.util.NavigableMap<K,V> tailMap(K, boolean);
-    method @NonNull public java.util.SortedMap<K,V> tailMap(K);
-  }
-
-  public class TreeSet<E> extends java.util.AbstractSet<E> implements java.lang.Cloneable java.util.NavigableSet<E> java.io.Serializable {
-    ctor public TreeSet();
-    ctor public TreeSet(java.util.Comparator<? super E>);
-    ctor public TreeSet(java.util.Collection<? extends E>);
-    ctor public TreeSet(java.util.SortedSet<E>);
-    method public E ceiling(E);
-    method public Object clone();
-    method public java.util.Comparator<? super E> comparator();
-    method public java.util.Iterator<E> descendingIterator();
-    method public java.util.NavigableSet<E> descendingSet();
-    method public E first();
-    method public E floor(E);
-    method public java.util.NavigableSet<E> headSet(E, boolean);
-    method public java.util.SortedSet<E> headSet(E);
-    method public E higher(E);
-    method public java.util.Iterator<E> iterator();
-    method public E last();
-    method public E lower(E);
-    method public E pollFirst();
-    method public E pollLast();
-    method public int size();
-    method public java.util.NavigableSet<E> subSet(E, boolean, E, boolean);
-    method public java.util.SortedSet<E> subSet(E, E);
-    method public java.util.NavigableSet<E> tailSet(E, boolean);
-    method public java.util.SortedSet<E> tailSet(E);
-  }
-
-  public final class UUID implements java.lang.Comparable<java.util.UUID> java.io.Serializable {
-    ctor public UUID(long, long);
-    method public int clockSequence();
-    method public int compareTo(java.util.UUID);
-    method public static java.util.UUID fromString(String);
-    method public long getLeastSignificantBits();
-    method public long getMostSignificantBits();
-    method public static java.util.UUID nameUUIDFromBytes(byte[]);
-    method public long node();
-    method public static java.util.UUID randomUUID();
-    method public long timestamp();
-    method public int variant();
-    method public int version();
-  }
-
-  public class UnknownFormatConversionException extends java.util.IllegalFormatException {
-    ctor public UnknownFormatConversionException(String);
-    method public String getConversion();
-  }
-
-  public class UnknownFormatFlagsException extends java.util.IllegalFormatException {
-    ctor public UnknownFormatFlagsException(String);
-    method public String getFlags();
-  }
-
-  public class Vector<E> extends java.util.AbstractList<E> implements java.lang.Cloneable java.util.List<E> java.util.RandomAccess java.io.Serializable {
-    ctor public Vector(int, int);
-    ctor public Vector(int);
-    ctor public Vector();
-    ctor public Vector(@NonNull java.util.Collection<? extends E>);
-    method public void addElement(E);
-    method public int capacity();
-    method @NonNull public Object clone();
-    method public void copyInto(@NonNull Object[]);
-    method public E elementAt(int);
-    method @NonNull public java.util.Enumeration<E> elements();
-    method public void ensureCapacity(int);
-    method public E firstElement();
-    method public void forEach(@NonNull java.util.function.Consumer<? super E>);
-    method public E get(int);
-    method public int indexOf(@Nullable Object, int);
-    method public void insertElementAt(E, int);
-    method public E lastElement();
-    method public int lastIndexOf(@Nullable Object, int);
-    method public void removeAllElements();
-    method public boolean removeElement(@Nullable Object);
-    method public void removeElementAt(int);
-    method public void setElementAt(E, int);
-    method public void setSize(int);
-    method public int size();
-    method public void trimToSize();
-    field protected int capacityIncrement;
-    field protected int elementCount;
-    field @NonNull protected Object[] elementData;
-  }
-
-  public class WeakHashMap<K, V> extends java.util.AbstractMap<K,V> implements java.util.Map<K,V> {
-    ctor public WeakHashMap(int, float);
-    ctor public WeakHashMap(int);
-    ctor public WeakHashMap();
-    ctor public WeakHashMap(@NonNull java.util.Map<? extends K,? extends V>);
-    method @NonNull public java.util.Set<java.util.Map.Entry<K,V>> entrySet();
-  }
-
-}
-
-package java.util.concurrent {
-
-  public abstract class AbstractExecutorService implements java.util.concurrent.ExecutorService {
-    ctor public AbstractExecutorService();
-    method public <T> java.util.List<java.util.concurrent.Future<T>> invokeAll(java.util.Collection<? extends java.util.concurrent.Callable<T>>) throws java.lang.InterruptedException;
-    method public <T> java.util.List<java.util.concurrent.Future<T>> invokeAll(java.util.Collection<? extends java.util.concurrent.Callable<T>>, long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-    method public <T> T invokeAny(java.util.Collection<? extends java.util.concurrent.Callable<T>>) throws java.util.concurrent.ExecutionException, java.lang.InterruptedException;
-    method public <T> T invokeAny(java.util.Collection<? extends java.util.concurrent.Callable<T>>, long, java.util.concurrent.TimeUnit) throws java.util.concurrent.ExecutionException, java.lang.InterruptedException, java.util.concurrent.TimeoutException;
-    method protected <T> java.util.concurrent.RunnableFuture<T> newTaskFor(Runnable, T);
-    method protected <T> java.util.concurrent.RunnableFuture<T> newTaskFor(java.util.concurrent.Callable<T>);
-    method public java.util.concurrent.Future<?> submit(Runnable);
-    method public <T> java.util.concurrent.Future<T> submit(Runnable, T);
-    method public <T> java.util.concurrent.Future<T> submit(java.util.concurrent.Callable<T>);
-  }
-
-  public class ArrayBlockingQueue<E> extends java.util.AbstractQueue<E> implements java.util.concurrent.BlockingQueue<E> java.io.Serializable {
-    ctor public ArrayBlockingQueue(int);
-    ctor public ArrayBlockingQueue(int, boolean);
-    ctor public ArrayBlockingQueue(int, boolean, java.util.Collection<? extends E>);
-    method public int drainTo(java.util.Collection<? super E>);
-    method public int drainTo(java.util.Collection<? super E>, int);
-    method public java.util.Iterator<E> iterator();
-    method public boolean offer(E);
-    method public boolean offer(E, long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-    method public E peek();
-    method public E poll();
-    method public E poll(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-    method public void put(E) throws java.lang.InterruptedException;
-    method public int remainingCapacity();
-    method public int size();
-    method public E take() throws java.lang.InterruptedException;
-  }
-
-  public interface BlockingDeque<E> extends java.util.concurrent.BlockingQueue<E> java.util.Deque<E> {
-    method public boolean offerFirst(E, long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-    method public boolean offerLast(E, long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-    method public E pollFirst(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-    method public E pollLast(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-    method public void putFirst(E) throws java.lang.InterruptedException;
-    method public void putLast(E) throws java.lang.InterruptedException;
-    method public E takeFirst() throws java.lang.InterruptedException;
-    method public E takeLast() throws java.lang.InterruptedException;
-  }
-
-  public interface BlockingQueue<E> extends java.util.Queue<E> {
-    method public int drainTo(java.util.Collection<? super E>);
-    method public int drainTo(java.util.Collection<? super E>, int);
-    method public boolean offer(E, long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-    method public E poll(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-    method public void put(E) throws java.lang.InterruptedException;
-    method public int remainingCapacity();
-    method public E take() throws java.lang.InterruptedException;
-  }
-
-  public class BrokenBarrierException extends java.lang.Exception {
-    ctor public BrokenBarrierException();
-    ctor public BrokenBarrierException(String);
-  }
-
-  @java.lang.FunctionalInterface public interface Callable<V> {
-    method public V call() throws java.lang.Exception;
-  }
-
-  public class CancellationException extends java.lang.IllegalStateException {
-    ctor public CancellationException();
-    ctor public CancellationException(String);
-  }
-
-  public class CompletableFuture<T> implements java.util.concurrent.CompletionStage<T> java.util.concurrent.Future<T> {
-    ctor public CompletableFuture();
-    method public java.util.concurrent.CompletableFuture<java.lang.Void> acceptEither(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Consumer<? super T>);
-    method public java.util.concurrent.CompletableFuture<java.lang.Void> acceptEitherAsync(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Consumer<? super T>);
-    method public java.util.concurrent.CompletableFuture<java.lang.Void> acceptEitherAsync(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Consumer<? super T>, java.util.concurrent.Executor);
-    method public static java.util.concurrent.CompletableFuture<java.lang.Void> allOf(java.util.concurrent.CompletableFuture<?>...);
-    method public static java.util.concurrent.CompletableFuture<java.lang.Object> anyOf(java.util.concurrent.CompletableFuture<?>...);
-    method public <U> java.util.concurrent.CompletableFuture<U> applyToEither(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Function<? super T,U>);
-    method public <U> java.util.concurrent.CompletableFuture<U> applyToEitherAsync(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Function<? super T,U>);
-    method public <U> java.util.concurrent.CompletableFuture<U> applyToEitherAsync(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Function<? super T,U>, java.util.concurrent.Executor);
-    method public boolean cancel(boolean);
-    method public boolean complete(T);
-    method public boolean completeExceptionally(Throwable);
-    method public static <U> java.util.concurrent.CompletableFuture<U> completedFuture(U);
-    method public java.util.concurrent.CompletableFuture<T> exceptionally(java.util.function.Function<java.lang.Throwable,? extends T>);
-    method public T get() throws java.util.concurrent.ExecutionException, java.lang.InterruptedException;
-    method public T get(long, java.util.concurrent.TimeUnit) throws java.util.concurrent.ExecutionException, java.lang.InterruptedException, java.util.concurrent.TimeoutException;
-    method public T getNow(T);
-    method public int getNumberOfDependents();
-    method public <U> java.util.concurrent.CompletableFuture<U> handle(java.util.function.BiFunction<? super T,java.lang.Throwable,? extends U>);
-    method public <U> java.util.concurrent.CompletableFuture<U> handleAsync(java.util.function.BiFunction<? super T,java.lang.Throwable,? extends U>);
-    method public <U> java.util.concurrent.CompletableFuture<U> handleAsync(java.util.function.BiFunction<? super T,java.lang.Throwable,? extends U>, java.util.concurrent.Executor);
-    method public boolean isCancelled();
-    method public boolean isCompletedExceptionally();
-    method public boolean isDone();
-    method public T join();
-    method public void obtrudeException(Throwable);
-    method public void obtrudeValue(T);
-    method public java.util.concurrent.CompletableFuture<java.lang.Void> runAfterBoth(java.util.concurrent.CompletionStage<?>, Runnable);
-    method public java.util.concurrent.CompletableFuture<java.lang.Void> runAfterBothAsync(java.util.concurrent.CompletionStage<?>, Runnable);
-    method public java.util.concurrent.CompletableFuture<java.lang.Void> runAfterBothAsync(java.util.concurrent.CompletionStage<?>, Runnable, java.util.concurrent.Executor);
-    method public java.util.concurrent.CompletableFuture<java.lang.Void> runAfterEither(java.util.concurrent.CompletionStage<?>, Runnable);
-    method public java.util.concurrent.CompletableFuture<java.lang.Void> runAfterEitherAsync(java.util.concurrent.CompletionStage<?>, Runnable);
-    method public java.util.concurrent.CompletableFuture<java.lang.Void> runAfterEitherAsync(java.util.concurrent.CompletionStage<?>, Runnable, java.util.concurrent.Executor);
-    method public static java.util.concurrent.CompletableFuture<java.lang.Void> runAsync(Runnable);
-    method public static java.util.concurrent.CompletableFuture<java.lang.Void> runAsync(Runnable, java.util.concurrent.Executor);
-    method public static <U> java.util.concurrent.CompletableFuture<U> supplyAsync(java.util.function.Supplier<U>);
-    method public static <U> java.util.concurrent.CompletableFuture<U> supplyAsync(java.util.function.Supplier<U>, java.util.concurrent.Executor);
-    method public java.util.concurrent.CompletableFuture<java.lang.Void> thenAccept(java.util.function.Consumer<? super T>);
-    method public java.util.concurrent.CompletableFuture<java.lang.Void> thenAcceptAsync(java.util.function.Consumer<? super T>);
-    method public java.util.concurrent.CompletableFuture<java.lang.Void> thenAcceptAsync(java.util.function.Consumer<? super T>, java.util.concurrent.Executor);
-    method public <U> java.util.concurrent.CompletableFuture<java.lang.Void> thenAcceptBoth(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiConsumer<? super T,? super U>);
-    method public <U> java.util.concurrent.CompletableFuture<java.lang.Void> thenAcceptBothAsync(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiConsumer<? super T,? super U>);
-    method public <U> java.util.concurrent.CompletableFuture<java.lang.Void> thenAcceptBothAsync(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiConsumer<? super T,? super U>, java.util.concurrent.Executor);
-    method public <U> java.util.concurrent.CompletableFuture<U> thenApply(java.util.function.Function<? super T,? extends U>);
-    method public <U> java.util.concurrent.CompletableFuture<U> thenApplyAsync(java.util.function.Function<? super T,? extends U>);
-    method public <U> java.util.concurrent.CompletableFuture<U> thenApplyAsync(java.util.function.Function<? super T,? extends U>, java.util.concurrent.Executor);
-    method public <U, V> java.util.concurrent.CompletableFuture<V> thenCombine(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiFunction<? super T,? super U,? extends V>);
-    method public <U, V> java.util.concurrent.CompletableFuture<V> thenCombineAsync(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiFunction<? super T,? super U,? extends V>);
-    method public <U, V> java.util.concurrent.CompletableFuture<V> thenCombineAsync(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiFunction<? super T,? super U,? extends V>, java.util.concurrent.Executor);
-    method public <U> java.util.concurrent.CompletableFuture<U> thenCompose(java.util.function.Function<? super T,? extends java.util.concurrent.CompletionStage<U>>);
-    method public <U> java.util.concurrent.CompletableFuture<U> thenComposeAsync(java.util.function.Function<? super T,? extends java.util.concurrent.CompletionStage<U>>);
-    method public <U> java.util.concurrent.CompletableFuture<U> thenComposeAsync(java.util.function.Function<? super T,? extends java.util.concurrent.CompletionStage<U>>, java.util.concurrent.Executor);
-    method public java.util.concurrent.CompletableFuture<java.lang.Void> thenRun(Runnable);
-    method public java.util.concurrent.CompletableFuture<java.lang.Void> thenRunAsync(Runnable);
-    method public java.util.concurrent.CompletableFuture<java.lang.Void> thenRunAsync(Runnable, java.util.concurrent.Executor);
-    method public java.util.concurrent.CompletableFuture<T> toCompletableFuture();
-    method public java.util.concurrent.CompletableFuture<T> whenComplete(java.util.function.BiConsumer<? super T,? super java.lang.Throwable>);
-    method public java.util.concurrent.CompletableFuture<T> whenCompleteAsync(java.util.function.BiConsumer<? super T,? super java.lang.Throwable>);
-    method public java.util.concurrent.CompletableFuture<T> whenCompleteAsync(java.util.function.BiConsumer<? super T,? super java.lang.Throwable>, java.util.concurrent.Executor);
-  }
-
-  public static interface CompletableFuture.AsynchronousCompletionTask {
-  }
-
-  public class CompletionException extends java.lang.RuntimeException {
-    ctor protected CompletionException();
-    ctor protected CompletionException(String);
-    ctor public CompletionException(String, Throwable);
-    ctor public CompletionException(Throwable);
-  }
-
-  public interface CompletionService<V> {
-    method public java.util.concurrent.Future<V> poll();
-    method public java.util.concurrent.Future<V> poll(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-    method public java.util.concurrent.Future<V> submit(java.util.concurrent.Callable<V>);
-    method public java.util.concurrent.Future<V> submit(Runnable, V);
-    method public java.util.concurrent.Future<V> take() throws java.lang.InterruptedException;
-  }
-
-  public interface CompletionStage<T> {
-    method public java.util.concurrent.CompletionStage<java.lang.Void> acceptEither(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Consumer<? super T>);
-    method public java.util.concurrent.CompletionStage<java.lang.Void> acceptEitherAsync(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Consumer<? super T>);
-    method public java.util.concurrent.CompletionStage<java.lang.Void> acceptEitherAsync(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Consumer<? super T>, java.util.concurrent.Executor);
-    method public <U> java.util.concurrent.CompletionStage<U> applyToEither(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Function<? super T,U>);
-    method public <U> java.util.concurrent.CompletionStage<U> applyToEitherAsync(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Function<? super T,U>);
-    method public <U> java.util.concurrent.CompletionStage<U> applyToEitherAsync(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Function<? super T,U>, java.util.concurrent.Executor);
-    method public java.util.concurrent.CompletionStage<T> exceptionally(java.util.function.Function<java.lang.Throwable,? extends T>);
-    method public <U> java.util.concurrent.CompletionStage<U> handle(java.util.function.BiFunction<? super T,java.lang.Throwable,? extends U>);
-    method public <U> java.util.concurrent.CompletionStage<U> handleAsync(java.util.function.BiFunction<? super T,java.lang.Throwable,? extends U>);
-    method public <U> java.util.concurrent.CompletionStage<U> handleAsync(java.util.function.BiFunction<? super T,java.lang.Throwable,? extends U>, java.util.concurrent.Executor);
-    method public java.util.concurrent.CompletionStage<java.lang.Void> runAfterBoth(java.util.concurrent.CompletionStage<?>, Runnable);
-    method public java.util.concurrent.CompletionStage<java.lang.Void> runAfterBothAsync(java.util.concurrent.CompletionStage<?>, Runnable);
-    method public java.util.concurrent.CompletionStage<java.lang.Void> runAfterBothAsync(java.util.concurrent.CompletionStage<?>, Runnable, java.util.concurrent.Executor);
-    method public java.util.concurrent.CompletionStage<java.lang.Void> runAfterEither(java.util.concurrent.CompletionStage<?>, Runnable);
-    method public java.util.concurrent.CompletionStage<java.lang.Void> runAfterEitherAsync(java.util.concurrent.CompletionStage<?>, Runnable);
-    method public java.util.concurrent.CompletionStage<java.lang.Void> runAfterEitherAsync(java.util.concurrent.CompletionStage<?>, Runnable, java.util.concurrent.Executor);
-    method public java.util.concurrent.CompletionStage<java.lang.Void> thenAccept(java.util.function.Consumer<? super T>);
-    method public java.util.concurrent.CompletionStage<java.lang.Void> thenAcceptAsync(java.util.function.Consumer<? super T>);
-    method public java.util.concurrent.CompletionStage<java.lang.Void> thenAcceptAsync(java.util.function.Consumer<? super T>, java.util.concurrent.Executor);
-    method public <U> java.util.concurrent.CompletionStage<java.lang.Void> thenAcceptBoth(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiConsumer<? super T,? super U>);
-    method public <U> java.util.concurrent.CompletionStage<java.lang.Void> thenAcceptBothAsync(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiConsumer<? super T,? super U>);
-    method public <U> java.util.concurrent.CompletionStage<java.lang.Void> thenAcceptBothAsync(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiConsumer<? super T,? super U>, java.util.concurrent.Executor);
-    method public <U> java.util.concurrent.CompletionStage<U> thenApply(java.util.function.Function<? super T,? extends U>);
-    method public <U> java.util.concurrent.CompletionStage<U> thenApplyAsync(java.util.function.Function<? super T,? extends U>);
-    method public <U> java.util.concurrent.CompletionStage<U> thenApplyAsync(java.util.function.Function<? super T,? extends U>, java.util.concurrent.Executor);
-    method public <U, V> java.util.concurrent.CompletionStage<V> thenCombine(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiFunction<? super T,? super U,? extends V>);
-    method public <U, V> java.util.concurrent.CompletionStage<V> thenCombineAsync(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiFunction<? super T,? super U,? extends V>);
-    method public <U, V> java.util.concurrent.CompletionStage<V> thenCombineAsync(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiFunction<? super T,? super U,? extends V>, java.util.concurrent.Executor);
-    method public <U> java.util.concurrent.CompletionStage<U> thenCompose(java.util.function.Function<? super T,? extends java.util.concurrent.CompletionStage<U>>);
-    method public <U> java.util.concurrent.CompletionStage<U> thenComposeAsync(java.util.function.Function<? super T,? extends java.util.concurrent.CompletionStage<U>>);
-    method public <U> java.util.concurrent.CompletionStage<U> thenComposeAsync(java.util.function.Function<? super T,? extends java.util.concurrent.CompletionStage<U>>, java.util.concurrent.Executor);
-    method public java.util.concurrent.CompletionStage<java.lang.Void> thenRun(Runnable);
-    method public java.util.concurrent.CompletionStage<java.lang.Void> thenRunAsync(Runnable);
-    method public java.util.concurrent.CompletionStage<java.lang.Void> thenRunAsync(Runnable, java.util.concurrent.Executor);
-    method public java.util.concurrent.CompletableFuture<T> toCompletableFuture();
-    method public java.util.concurrent.CompletionStage<T> whenComplete(java.util.function.BiConsumer<? super T,? super java.lang.Throwable>);
-    method public java.util.concurrent.CompletionStage<T> whenCompleteAsync(java.util.function.BiConsumer<? super T,? super java.lang.Throwable>);
-    method public java.util.concurrent.CompletionStage<T> whenCompleteAsync(java.util.function.BiConsumer<? super T,? super java.lang.Throwable>, java.util.concurrent.Executor);
-  }
-
-  public class ConcurrentHashMap<K, V> extends java.util.AbstractMap<K,V> implements java.util.concurrent.ConcurrentMap<K,V> java.io.Serializable {
-    ctor public ConcurrentHashMap();
-    ctor public ConcurrentHashMap(int);
-    ctor public ConcurrentHashMap(@NonNull java.util.Map<? extends K,? extends V>);
-    ctor public ConcurrentHashMap(int, float);
-    ctor public ConcurrentHashMap(int, float, int);
-    method public boolean contains(@NonNull Object);
-    method @NonNull public java.util.Enumeration<V> elements();
-    method @NonNull public java.util.Set<java.util.Map.Entry<K,V>> entrySet();
-    method public void forEach(long, @NonNull java.util.function.BiConsumer<? super K,? super V>);
-    method public <U> void forEach(long, @NonNull java.util.function.BiFunction<? super K,? super V,? extends U>, @NonNull java.util.function.Consumer<? super U>);
-    method public void forEachEntry(long, @NonNull java.util.function.Consumer<? super java.util.Map.Entry<K,V>>);
-    method public <U> void forEachEntry(long, @NonNull java.util.function.Function<java.util.Map.Entry<K,V>,? extends U>, @NonNull java.util.function.Consumer<? super U>);
-    method public void forEachKey(long, @NonNull java.util.function.Consumer<? super K>);
-    method public <U> void forEachKey(long, @NonNull java.util.function.Function<? super K,? extends U>, @NonNull java.util.function.Consumer<? super U>);
-    method public void forEachValue(long, @NonNull java.util.function.Consumer<? super V>);
-    method public <U> void forEachValue(long, @NonNull java.util.function.Function<? super V,? extends U>, @NonNull java.util.function.Consumer<? super U>);
-    method @NonNull public java.util.concurrent.ConcurrentHashMap.KeySetView<K,V> keySet(@NonNull V);
-    method @NonNull public java.util.Enumeration<K> keys();
-    method public long mappingCount();
-    method @NonNull public static <K> java.util.concurrent.ConcurrentHashMap.KeySetView<K,java.lang.Boolean> newKeySet();
-    method @NonNull public static <K> java.util.concurrent.ConcurrentHashMap.KeySetView<K,java.lang.Boolean> newKeySet(int);
-    method @Nullable public <U> U reduce(long, @NonNull java.util.function.BiFunction<? super K,? super V,? extends U>, @NonNull java.util.function.BiFunction<? super U,? super U,? extends U>);
-    method @Nullable public java.util.Map.Entry<K,V> reduceEntries(long, @NonNull java.util.function.BiFunction<java.util.Map.Entry<K,V>,java.util.Map.Entry<K,V>,? extends java.util.Map.Entry<K,V>>);
-    method @Nullable public <U> U reduceEntries(long, @NonNull java.util.function.Function<java.util.Map.Entry<K,V>,? extends U>, @NonNull java.util.function.BiFunction<? super U,? super U,? extends U>);
-    method public double reduceEntriesToDouble(long, @NonNull java.util.function.ToDoubleFunction<java.util.Map.Entry<K,V>>, double, @NonNull java.util.function.DoubleBinaryOperator);
-    method public int reduceEntriesToInt(long, @NonNull java.util.function.ToIntFunction<java.util.Map.Entry<K,V>>, int, @NonNull java.util.function.IntBinaryOperator);
-    method public long reduceEntriesToLong(long, @NonNull java.util.function.ToLongFunction<java.util.Map.Entry<K,V>>, long, @NonNull java.util.function.LongBinaryOperator);
-    method @Nullable public K reduceKeys(long, @NonNull java.util.function.BiFunction<? super K,? super K,? extends K>);
-    method @Nullable public <U> U reduceKeys(long, @NonNull java.util.function.Function<? super K,? extends U>, @NonNull java.util.function.BiFunction<? super U,? super U,? extends U>);
-    method public double reduceKeysToDouble(long, @NonNull java.util.function.ToDoubleFunction<? super K>, double, @NonNull java.util.function.DoubleBinaryOperator);
-    method public int reduceKeysToInt(long, @NonNull java.util.function.ToIntFunction<? super K>, int, @NonNull java.util.function.IntBinaryOperator);
-    method public long reduceKeysToLong(long, @NonNull java.util.function.ToLongFunction<? super K>, long, @NonNull java.util.function.LongBinaryOperator);
-    method public double reduceToDouble(long, @NonNull java.util.function.ToDoubleBiFunction<? super K,? super V>, double, @NonNull java.util.function.DoubleBinaryOperator);
-    method public int reduceToInt(long, @NonNull java.util.function.ToIntBiFunction<? super K,? super V>, int, @NonNull java.util.function.IntBinaryOperator);
-    method public long reduceToLong(long, @NonNull java.util.function.ToLongBiFunction<? super K,? super V>, long, @NonNull java.util.function.LongBinaryOperator);
-    method @Nullable public V reduceValues(long, @NonNull java.util.function.BiFunction<? super V,? super V,? extends V>);
-    method @Nullable public <U> U reduceValues(long, @NonNull java.util.function.Function<? super V,? extends U>, @NonNull java.util.function.BiFunction<? super U,? super U,? extends U>);
-    method public double reduceValuesToDouble(long, @NonNull java.util.function.ToDoubleFunction<? super V>, double, @NonNull java.util.function.DoubleBinaryOperator);
-    method public int reduceValuesToInt(long, @NonNull java.util.function.ToIntFunction<? super V>, int, @NonNull java.util.function.IntBinaryOperator);
-    method public long reduceValuesToLong(long, @NonNull java.util.function.ToLongFunction<? super V>, long, @NonNull java.util.function.LongBinaryOperator);
-    method @Nullable public <U> U search(long, @NonNull java.util.function.BiFunction<? super K,? super V,? extends U>);
-    method @Nullable public <U> U searchEntries(long, @NonNull java.util.function.Function<java.util.Map.Entry<K,V>,? extends U>);
-    method @Nullable public <U> U searchKeys(long, @NonNull java.util.function.Function<? super K,? extends U>);
-    method @Nullable public <U> U searchValues(long, @NonNull java.util.function.Function<? super V,? extends U>);
-  }
-
-  public static class ConcurrentHashMap.KeySetView<K, V> implements java.util.Collection<K> java.io.Serializable java.util.Set<K> {
-    method public boolean add(@NonNull K);
-    method public boolean addAll(@NonNull java.util.Collection<? extends K>);
-    method public final void clear();
-    method public boolean contains(@NonNull Object);
-    method public final boolean containsAll(@NonNull java.util.Collection<?>);
-    method public void forEach(@NonNull java.util.function.Consumer<? super K>);
-    method @NonNull public java.util.concurrent.ConcurrentHashMap<K,V> getMap();
-    method @Nullable public V getMappedValue();
-    method public final boolean isEmpty();
-    method @NonNull public java.util.Iterator<K> iterator();
-    method public boolean remove(@NonNull Object);
-    method public final boolean removeAll(@NonNull java.util.Collection<?>);
-    method public final boolean retainAll(@NonNull java.util.Collection<?>);
-    method public final int size();
-    method @NonNull public java.util.Spliterator<K> spliterator();
-    method @NonNull public final Object[] toArray();
-    method @NonNull public final <T> T[] toArray(@NonNull T[]);
-    method @NonNull public final String toString();
-  }
-
-  public class ConcurrentLinkedDeque<E> extends java.util.AbstractCollection<E> implements java.util.Deque<E> java.io.Serializable {
-    ctor public ConcurrentLinkedDeque();
-    ctor public ConcurrentLinkedDeque(java.util.Collection<? extends E>);
-    method public void addFirst(E);
-    method public void addLast(E);
-    method public java.util.Iterator<E> descendingIterator();
-    method public E element();
-    method public E getFirst();
-    method public E getLast();
-    method public java.util.Iterator<E> iterator();
-    method public boolean offer(E);
-    method public boolean offerFirst(E);
-    method public boolean offerLast(E);
-    method public E peek();
-    method public E peekFirst();
-    method public E peekLast();
-    method public E poll();
-    method public E pollFirst();
-    method public E pollLast();
-    method public E pop();
-    method public void push(E);
-    method public E remove();
-    method public E removeFirst();
-    method public boolean removeFirstOccurrence(Object);
-    method public E removeLast();
-    method public boolean removeLastOccurrence(Object);
-    method public int size();
-  }
-
-  public class ConcurrentLinkedQueue<E> extends java.util.AbstractQueue<E> implements java.util.Queue<E> java.io.Serializable {
-    ctor public ConcurrentLinkedQueue();
-    ctor public ConcurrentLinkedQueue(java.util.Collection<? extends E>);
-    method public java.util.Iterator<E> iterator();
-    method public boolean offer(E);
-    method public E peek();
-    method public E poll();
-    method public int size();
-  }
-
-  public interface ConcurrentMap<K, V> extends java.util.Map<K,V> {
-    method public V putIfAbsent(K, V);
-    method public boolean remove(Object, Object);
-    method public boolean replace(K, V, V);
-    method public V replace(K, V);
-  }
-
-  public interface ConcurrentNavigableMap<K, V> extends java.util.concurrent.ConcurrentMap<K,V> java.util.NavigableMap<K,V> {
-    method public java.util.concurrent.ConcurrentNavigableMap<K,V> descendingMap();
-    method public java.util.concurrent.ConcurrentNavigableMap<K,V> headMap(K, boolean);
-    method public java.util.concurrent.ConcurrentNavigableMap<K,V> headMap(K);
-    method public java.util.NavigableSet<K> keySet();
-    method public java.util.concurrent.ConcurrentNavigableMap<K,V> subMap(K, boolean, K, boolean);
-    method public java.util.concurrent.ConcurrentNavigableMap<K,V> subMap(K, K);
-    method public java.util.concurrent.ConcurrentNavigableMap<K,V> tailMap(K, boolean);
-    method public java.util.concurrent.ConcurrentNavigableMap<K,V> tailMap(K);
-  }
-
-  public class ConcurrentSkipListMap<K, V> extends java.util.AbstractMap<K,V> implements java.lang.Cloneable java.util.concurrent.ConcurrentNavigableMap<K,V> java.io.Serializable {
-    ctor public ConcurrentSkipListMap();
-    ctor public ConcurrentSkipListMap(java.util.Comparator<? super K>);
-    ctor public ConcurrentSkipListMap(java.util.Map<? extends K,? extends V>);
-    ctor public ConcurrentSkipListMap(java.util.SortedMap<K,? extends V>);
-    method public java.util.Map.Entry<K,V> ceilingEntry(K);
-    method public K ceilingKey(K);
-    method public java.util.concurrent.ConcurrentSkipListMap<K,V> clone();
-    method public java.util.Comparator<? super K> comparator();
-    method public java.util.NavigableSet<K> descendingKeySet();
-    method public java.util.concurrent.ConcurrentNavigableMap<K,V> descendingMap();
-    method public java.util.Set<java.util.Map.Entry<K,V>> entrySet();
-    method public java.util.Map.Entry<K,V> firstEntry();
-    method public K firstKey();
-    method public java.util.Map.Entry<K,V> floorEntry(K);
-    method public K floorKey(K);
-    method public java.util.concurrent.ConcurrentNavigableMap<K,V> headMap(K, boolean);
-    method public java.util.concurrent.ConcurrentNavigableMap<K,V> headMap(K);
-    method public java.util.Map.Entry<K,V> higherEntry(K);
-    method public K higherKey(K);
-    method public java.util.NavigableSet<K> keySet();
-    method public java.util.Map.Entry<K,V> lastEntry();
-    method public K lastKey();
-    method public java.util.Map.Entry<K,V> lowerEntry(K);
-    method public K lowerKey(K);
-    method public java.util.NavigableSet<K> navigableKeySet();
-    method public java.util.Map.Entry<K,V> pollFirstEntry();
-    method public java.util.Map.Entry<K,V> pollLastEntry();
-    method public java.util.concurrent.ConcurrentNavigableMap<K,V> subMap(K, boolean, K, boolean);
-    method public java.util.concurrent.ConcurrentNavigableMap<K,V> subMap(K, K);
-    method public java.util.concurrent.ConcurrentNavigableMap<K,V> tailMap(K, boolean);
-    method public java.util.concurrent.ConcurrentNavigableMap<K,V> tailMap(K);
-  }
-
-  public class ConcurrentSkipListSet<E> extends java.util.AbstractSet<E> implements java.lang.Cloneable java.util.NavigableSet<E> java.io.Serializable {
-    ctor public ConcurrentSkipListSet();
-    ctor public ConcurrentSkipListSet(java.util.Comparator<? super E>);
-    ctor public ConcurrentSkipListSet(java.util.Collection<? extends E>);
-    ctor public ConcurrentSkipListSet(java.util.SortedSet<E>);
-    method public E ceiling(E);
-    method public java.util.concurrent.ConcurrentSkipListSet<E> clone();
-    method public java.util.Comparator<? super E> comparator();
-    method public java.util.Iterator<E> descendingIterator();
-    method public java.util.NavigableSet<E> descendingSet();
-    method public E first();
-    method public E floor(E);
-    method public java.util.NavigableSet<E> headSet(E, boolean);
-    method public java.util.NavigableSet<E> headSet(E);
-    method public E higher(E);
-    method public java.util.Iterator<E> iterator();
-    method public E last();
-    method public E lower(E);
-    method public E pollFirst();
-    method public E pollLast();
-    method public int size();
-    method public java.util.NavigableSet<E> subSet(E, boolean, E, boolean);
-    method public java.util.NavigableSet<E> subSet(E, E);
-    method public java.util.NavigableSet<E> tailSet(E, boolean);
-    method public java.util.NavigableSet<E> tailSet(E);
-  }
-
-  public class CopyOnWriteArrayList<E> implements java.lang.Cloneable java.util.List<E> java.util.RandomAccess java.io.Serializable {
-    ctor public CopyOnWriteArrayList();
-    ctor public CopyOnWriteArrayList(@NonNull java.util.Collection<? extends E>);
-    ctor public CopyOnWriteArrayList(@NonNull E[]);
-    method public boolean add(E);
-    method public void add(int, E);
-    method public boolean addAll(@NonNull java.util.Collection<? extends E>);
-    method public boolean addAll(int, @NonNull java.util.Collection<? extends E>);
-    method public int addAllAbsent(@NonNull java.util.Collection<? extends E>);
-    method public boolean addIfAbsent(E);
-    method public void clear();
-    method @NonNull public Object clone();
-    method public boolean contains(@Nullable Object);
-    method public boolean containsAll(@NonNull java.util.Collection<?>);
-    method public void forEach(@NonNull java.util.function.Consumer<? super E>);
-    method public E get(int);
-    method public int indexOf(@Nullable Object);
-    method public int indexOf(@Nullable E, int);
-    method public boolean isEmpty();
-    method @NonNull public java.util.Iterator<E> iterator();
-    method public int lastIndexOf(@Nullable Object);
-    method public int lastIndexOf(@Nullable E, int);
-    method @NonNull public java.util.ListIterator<E> listIterator();
-    method @NonNull public java.util.ListIterator<E> listIterator(int);
-    method public E remove(int);
-    method public boolean remove(@Nullable Object);
-    method public boolean removeAll(@NonNull java.util.Collection<?>);
-    method public boolean retainAll(@NonNull java.util.Collection<?>);
-    method public E set(int, E);
-    method public int size();
-    method @NonNull public java.util.List<E> subList(int, int);
-    method @NonNull public Object[] toArray();
-    method @NonNull public <T> T[] toArray(@NonNull T[]);
-  }
-
-  public class CopyOnWriteArraySet<E> extends java.util.AbstractSet<E> implements java.io.Serializable {
-    ctor public CopyOnWriteArraySet();
-    ctor public CopyOnWriteArraySet(java.util.Collection<? extends E>);
-    method public void forEach(java.util.function.Consumer<? super E>);
-    method public java.util.Iterator<E> iterator();
-    method public int size();
-  }
-
-  public class CountDownLatch {
-    ctor public CountDownLatch(int);
-    method public void await() throws java.lang.InterruptedException;
-    method public boolean await(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-    method public void countDown();
-    method public long getCount();
-  }
-
-  public abstract class CountedCompleter<T> extends java.util.concurrent.ForkJoinTask<T> {
-    ctor protected CountedCompleter(java.util.concurrent.CountedCompleter<?>, int);
-    ctor protected CountedCompleter(java.util.concurrent.CountedCompleter<?>);
-    ctor protected CountedCompleter();
-    method public final void addToPendingCount(int);
-    method public final boolean compareAndSetPendingCount(int, int);
-    method public void complete(T);
-    method public abstract void compute();
-    method public final int decrementPendingCountUnlessZero();
-    method protected final boolean exec();
-    method public final java.util.concurrent.CountedCompleter<?> firstComplete();
-    method public final java.util.concurrent.CountedCompleter<?> getCompleter();
-    method public final int getPendingCount();
-    method public T getRawResult();
-    method public final java.util.concurrent.CountedCompleter<?> getRoot();
-    method public final void helpComplete(int);
-    method public final java.util.concurrent.CountedCompleter<?> nextComplete();
-    method public void onCompletion(java.util.concurrent.CountedCompleter<?>);
-    method public boolean onExceptionalCompletion(Throwable, java.util.concurrent.CountedCompleter<?>);
-    method public final void propagateCompletion();
-    method public final void quietlyCompleteRoot();
-    method public final void setPendingCount(int);
-    method protected void setRawResult(T);
-    method public final void tryComplete();
-  }
-
-  public class CyclicBarrier {
-    ctor public CyclicBarrier(int, Runnable);
-    ctor public CyclicBarrier(int);
-    method public int await() throws java.util.concurrent.BrokenBarrierException, java.lang.InterruptedException;
-    method public int await(long, java.util.concurrent.TimeUnit) throws java.util.concurrent.BrokenBarrierException, java.lang.InterruptedException, java.util.concurrent.TimeoutException;
-    method public int getNumberWaiting();
-    method public int getParties();
-    method public boolean isBroken();
-    method public void reset();
-  }
-
-  public class DelayQueue<E extends java.util.concurrent.Delayed> extends java.util.AbstractQueue<E> implements java.util.concurrent.BlockingQueue<E> {
-    ctor public DelayQueue();
-    ctor public DelayQueue(java.util.Collection<? extends E>);
-    method public int drainTo(java.util.Collection<? super E>);
-    method public int drainTo(java.util.Collection<? super E>, int);
-    method public java.util.Iterator<E> iterator();
-    method public boolean offer(E);
-    method public boolean offer(E, long, java.util.concurrent.TimeUnit);
-    method public E peek();
-    method public E poll();
-    method public E poll(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-    method public void put(E);
-    method public int remainingCapacity();
-    method public int size();
-    method public E take() throws java.lang.InterruptedException;
-  }
-
-  public interface Delayed extends java.lang.Comparable<java.util.concurrent.Delayed> {
-    method public long getDelay(java.util.concurrent.TimeUnit);
-  }
-
-  public class Exchanger<V> {
-    ctor public Exchanger();
-    method public V exchange(V) throws java.lang.InterruptedException;
-    method public V exchange(V, long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException, java.util.concurrent.TimeoutException;
-  }
-
-  public class ExecutionException extends java.lang.Exception {
-    ctor protected ExecutionException();
-    ctor protected ExecutionException(String);
-    ctor public ExecutionException(String, Throwable);
-    ctor public ExecutionException(Throwable);
-  }
-
-  public interface Executor {
-    method public void execute(Runnable);
-  }
-
-  public class ExecutorCompletionService<V> implements java.util.concurrent.CompletionService<V> {
-    ctor public ExecutorCompletionService(java.util.concurrent.Executor);
-    ctor public ExecutorCompletionService(java.util.concurrent.Executor, java.util.concurrent.BlockingQueue<java.util.concurrent.Future<V>>);
-    method public java.util.concurrent.Future<V> poll();
-    method public java.util.concurrent.Future<V> poll(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-    method public java.util.concurrent.Future<V> submit(java.util.concurrent.Callable<V>);
-    method public java.util.concurrent.Future<V> submit(Runnable, V);
-    method public java.util.concurrent.Future<V> take() throws java.lang.InterruptedException;
-  }
-
-  public interface ExecutorService extends java.util.concurrent.Executor {
-    method public boolean awaitTermination(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-    method public <T> java.util.List<java.util.concurrent.Future<T>> invokeAll(java.util.Collection<? extends java.util.concurrent.Callable<T>>) throws java.lang.InterruptedException;
-    method public <T> java.util.List<java.util.concurrent.Future<T>> invokeAll(java.util.Collection<? extends java.util.concurrent.Callable<T>>, long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-    method public <T> T invokeAny(java.util.Collection<? extends java.util.concurrent.Callable<T>>) throws java.util.concurrent.ExecutionException, java.lang.InterruptedException;
-    method public <T> T invokeAny(java.util.Collection<? extends java.util.concurrent.Callable<T>>, long, java.util.concurrent.TimeUnit) throws java.util.concurrent.ExecutionException, java.lang.InterruptedException, java.util.concurrent.TimeoutException;
-    method public boolean isShutdown();
-    method public boolean isTerminated();
-    method public void shutdown();
-    method public java.util.List<java.lang.Runnable> shutdownNow();
-    method public <T> java.util.concurrent.Future<T> submit(java.util.concurrent.Callable<T>);
-    method public <T> java.util.concurrent.Future<T> submit(Runnable, T);
-    method public java.util.concurrent.Future<?> submit(Runnable);
-  }
-
-  public class Executors {
-    method public static <T> java.util.concurrent.Callable<T> callable(Runnable, T);
-    method public static java.util.concurrent.Callable<java.lang.Object> callable(Runnable);
-    method public static java.util.concurrent.Callable<java.lang.Object> callable(java.security.PrivilegedAction<?>);
-    method public static java.util.concurrent.Callable<java.lang.Object> callable(java.security.PrivilegedExceptionAction<?>);
-    method public static java.util.concurrent.ThreadFactory defaultThreadFactory();
-    method public static java.util.concurrent.ExecutorService newCachedThreadPool();
-    method public static java.util.concurrent.ExecutorService newCachedThreadPool(java.util.concurrent.ThreadFactory);
-    method public static java.util.concurrent.ExecutorService newFixedThreadPool(int);
-    method public static java.util.concurrent.ExecutorService newFixedThreadPool(int, java.util.concurrent.ThreadFactory);
-    method public static java.util.concurrent.ScheduledExecutorService newScheduledThreadPool(int);
-    method public static java.util.concurrent.ScheduledExecutorService newScheduledThreadPool(int, java.util.concurrent.ThreadFactory);
-    method public static java.util.concurrent.ExecutorService newSingleThreadExecutor();
-    method public static java.util.concurrent.ExecutorService newSingleThreadExecutor(java.util.concurrent.ThreadFactory);
-    method public static java.util.concurrent.ScheduledExecutorService newSingleThreadScheduledExecutor();
-    method public static java.util.concurrent.ScheduledExecutorService newSingleThreadScheduledExecutor(java.util.concurrent.ThreadFactory);
-    method public static java.util.concurrent.ExecutorService newWorkStealingPool(int);
-    method public static java.util.concurrent.ExecutorService newWorkStealingPool();
-    method public static <T> java.util.concurrent.Callable<T> privilegedCallable(java.util.concurrent.Callable<T>);
-    method public static <T> java.util.concurrent.Callable<T> privilegedCallableUsingCurrentClassLoader(java.util.concurrent.Callable<T>);
-    method public static java.util.concurrent.ThreadFactory privilegedThreadFactory();
-    method public static java.util.concurrent.ExecutorService unconfigurableExecutorService(java.util.concurrent.ExecutorService);
-    method public static java.util.concurrent.ScheduledExecutorService unconfigurableScheduledExecutorService(java.util.concurrent.ScheduledExecutorService);
-  }
-
-  public final class Flow {
-    method public static int defaultBufferSize();
-  }
-
-  public static interface Flow.Processor<T, R> extends java.util.concurrent.Flow.Subscriber<T> java.util.concurrent.Flow.Publisher<R> {
-  }
-
-  @java.lang.FunctionalInterface public static interface Flow.Publisher<T> {
-    method public void subscribe(java.util.concurrent.Flow.Subscriber<? super T>);
-  }
-
-  public static interface Flow.Subscriber<T> {
-    method public void onComplete();
-    method public void onError(Throwable);
-    method public void onNext(T);
-    method public void onSubscribe(java.util.concurrent.Flow.Subscription);
-  }
-
-  public static interface Flow.Subscription {
-    method public void cancel();
-    method public void request(long);
-  }
-
-  public class ForkJoinPool extends java.util.concurrent.AbstractExecutorService {
-    ctor public ForkJoinPool();
-    ctor public ForkJoinPool(int);
-    ctor public ForkJoinPool(int, java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory, java.lang.Thread.UncaughtExceptionHandler, boolean);
-    method public boolean awaitQuiescence(long, java.util.concurrent.TimeUnit);
-    method public boolean awaitTermination(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-    method public static java.util.concurrent.ForkJoinPool commonPool();
-    method protected int drainTasksTo(java.util.Collection<? super java.util.concurrent.ForkJoinTask<?>>);
-    method public void execute(java.util.concurrent.ForkJoinTask<?>);
-    method public void execute(Runnable);
-    method public int getActiveThreadCount();
-    method public boolean getAsyncMode();
-    method public static int getCommonPoolParallelism();
-    method public java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory getFactory();
-    method public int getParallelism();
-    method public int getPoolSize();
-    method public int getQueuedSubmissionCount();
-    method public long getQueuedTaskCount();
-    method public int getRunningThreadCount();
-    method public long getStealCount();
-    method public java.lang.Thread.UncaughtExceptionHandler getUncaughtExceptionHandler();
-    method public boolean hasQueuedSubmissions();
-    method public <T> T invoke(java.util.concurrent.ForkJoinTask<T>);
-    method public <T> java.util.List<java.util.concurrent.Future<T>> invokeAll(java.util.Collection<? extends java.util.concurrent.Callable<T>>);
-    method public boolean isQuiescent();
-    method public boolean isShutdown();
-    method public boolean isTerminated();
-    method public boolean isTerminating();
-    method public static void managedBlock(java.util.concurrent.ForkJoinPool.ManagedBlocker) throws java.lang.InterruptedException;
-    method protected java.util.concurrent.ForkJoinTask<?> pollSubmission();
-    method public void shutdown();
-    method public java.util.List<java.lang.Runnable> shutdownNow();
-    method public <T> java.util.concurrent.ForkJoinTask<T> submit(java.util.concurrent.ForkJoinTask<T>);
-    method public <T> java.util.concurrent.ForkJoinTask<T> submit(java.util.concurrent.Callable<T>);
-    method public <T> java.util.concurrent.ForkJoinTask<T> submit(Runnable, T);
-    method public java.util.concurrent.ForkJoinTask<?> submit(Runnable);
-    field public static final java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory defaultForkJoinWorkerThreadFactory;
-  }
-
-  public static interface ForkJoinPool.ForkJoinWorkerThreadFactory {
-    method public java.util.concurrent.ForkJoinWorkerThread newThread(java.util.concurrent.ForkJoinPool);
-  }
-
-  public static interface ForkJoinPool.ManagedBlocker {
-    method public boolean block() throws java.lang.InterruptedException;
-    method public boolean isReleasable();
-  }
-
-  public abstract class ForkJoinTask<V> implements java.util.concurrent.Future<V> java.io.Serializable {
-    ctor public ForkJoinTask();
-    method public static java.util.concurrent.ForkJoinTask<?> adapt(Runnable);
-    method public static <T> java.util.concurrent.ForkJoinTask<T> adapt(Runnable, T);
-    method public static <T> java.util.concurrent.ForkJoinTask<T> adapt(java.util.concurrent.Callable<? extends T>);
-    method public boolean cancel(boolean);
-    method public final boolean compareAndSetForkJoinTaskTag(short, short);
-    method public void complete(V);
-    method public void completeExceptionally(Throwable);
-    method protected abstract boolean exec();
-    method public final java.util.concurrent.ForkJoinTask<V> fork();
-    method public final V get() throws java.util.concurrent.ExecutionException, java.lang.InterruptedException;
-    method public final V get(long, java.util.concurrent.TimeUnit) throws java.util.concurrent.ExecutionException, java.lang.InterruptedException, java.util.concurrent.TimeoutException;
-    method public final Throwable getException();
-    method public final short getForkJoinTaskTag();
-    method public static java.util.concurrent.ForkJoinPool getPool();
-    method public static int getQueuedTaskCount();
-    method public abstract V getRawResult();
-    method public static int getSurplusQueuedTaskCount();
-    method public static void helpQuiesce();
-    method public static boolean inForkJoinPool();
-    method public final V invoke();
-    method public static void invokeAll(java.util.concurrent.ForkJoinTask<?>, java.util.concurrent.ForkJoinTask<?>);
-    method public static void invokeAll(java.util.concurrent.ForkJoinTask<?>...);
-    method public static <T extends java.util.concurrent.ForkJoinTask<?>> java.util.Collection<T> invokeAll(java.util.Collection<T>);
-    method public final boolean isCancelled();
-    method public final boolean isCompletedAbnormally();
-    method public final boolean isCompletedNormally();
-    method public final boolean isDone();
-    method public final V join();
-    method protected static java.util.concurrent.ForkJoinTask<?> peekNextLocalTask();
-    method protected static java.util.concurrent.ForkJoinTask<?> pollNextLocalTask();
-    method protected static java.util.concurrent.ForkJoinTask<?> pollTask();
-    method public final void quietlyComplete();
-    method public final void quietlyInvoke();
-    method public final void quietlyJoin();
-    method public void reinitialize();
-    method public final short setForkJoinTaskTag(short);
-    method protected abstract void setRawResult(V);
-    method public boolean tryUnfork();
-  }
-
-  public class ForkJoinWorkerThread extends java.lang.Thread {
-    ctor protected ForkJoinWorkerThread(java.util.concurrent.ForkJoinPool);
-    method public java.util.concurrent.ForkJoinPool getPool();
-    method public int getPoolIndex();
-    method protected void onStart();
-    method protected void onTermination(Throwable);
-  }
-
-  public interface Future<V> {
-    method public boolean cancel(boolean);
-    method public V get() throws java.util.concurrent.ExecutionException, java.lang.InterruptedException;
-    method public V get(long, java.util.concurrent.TimeUnit) throws java.util.concurrent.ExecutionException, java.lang.InterruptedException, java.util.concurrent.TimeoutException;
-    method public boolean isCancelled();
-    method public boolean isDone();
-  }
-
-  public class FutureTask<V> implements java.util.concurrent.RunnableFuture<V> {
-    ctor public FutureTask(java.util.concurrent.Callable<V>);
-    ctor public FutureTask(Runnable, V);
-    method public boolean cancel(boolean);
-    method protected void done();
-    method public V get() throws java.util.concurrent.ExecutionException, java.lang.InterruptedException;
-    method public V get(long, java.util.concurrent.TimeUnit) throws java.util.concurrent.ExecutionException, java.lang.InterruptedException, java.util.concurrent.TimeoutException;
-    method public boolean isCancelled();
-    method public boolean isDone();
-    method public void run();
-    method protected boolean runAndReset();
-    method protected void set(V);
-    method protected void setException(Throwable);
-  }
-
-  public class LinkedBlockingDeque<E> extends java.util.AbstractQueue<E> implements java.util.concurrent.BlockingDeque<E> java.io.Serializable {
-    ctor public LinkedBlockingDeque();
-    ctor public LinkedBlockingDeque(int);
-    ctor public LinkedBlockingDeque(java.util.Collection<? extends E>);
-    method public void addFirst(E);
-    method public void addLast(E);
-    method public java.util.Iterator<E> descendingIterator();
-    method public int drainTo(java.util.Collection<? super E>);
-    method public int drainTo(java.util.Collection<? super E>, int);
-    method public E getFirst();
-    method public E getLast();
-    method public java.util.Iterator<E> iterator();
-    method public boolean offer(E);
-    method public boolean offer(E, long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-    method public boolean offerFirst(E);
-    method public boolean offerFirst(E, long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-    method public boolean offerLast(E);
-    method public boolean offerLast(E, long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-    method public E peek();
-    method public E peekFirst();
-    method public E peekLast();
-    method public E poll();
-    method public E poll(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-    method public E pollFirst();
-    method public E pollFirst(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-    method public E pollLast();
-    method public E pollLast(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-    method public E pop();
-    method public void push(E);
-    method public void put(E) throws java.lang.InterruptedException;
-    method public void putFirst(E) throws java.lang.InterruptedException;
-    method public void putLast(E) throws java.lang.InterruptedException;
-    method public int remainingCapacity();
-    method public E removeFirst();
-    method public boolean removeFirstOccurrence(Object);
-    method public E removeLast();
-    method public boolean removeLastOccurrence(Object);
-    method public int size();
-    method public E take() throws java.lang.InterruptedException;
-    method public E takeFirst() throws java.lang.InterruptedException;
-    method public E takeLast() throws java.lang.InterruptedException;
-  }
-
-  public class LinkedBlockingQueue<E> extends java.util.AbstractQueue<E> implements java.util.concurrent.BlockingQueue<E> java.io.Serializable {
-    ctor public LinkedBlockingQueue();
-    ctor public LinkedBlockingQueue(int);
-    ctor public LinkedBlockingQueue(java.util.Collection<? extends E>);
-    method public int drainTo(java.util.Collection<? super E>);
-    method public int drainTo(java.util.Collection<? super E>, int);
-    method public java.util.Iterator<E> iterator();
-    method public boolean offer(E, long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-    method public boolean offer(E);
-    method public E peek();
-    method public E poll(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-    method public E poll();
-    method public void put(E) throws java.lang.InterruptedException;
-    method public int remainingCapacity();
-    method public int size();
-    method public E take() throws java.lang.InterruptedException;
-  }
-
-  public class LinkedTransferQueue<E> extends java.util.AbstractQueue<E> implements java.io.Serializable java.util.concurrent.TransferQueue<E> {
-    ctor public LinkedTransferQueue();
-    ctor public LinkedTransferQueue(java.util.Collection<? extends E>);
-    method public int drainTo(java.util.Collection<? super E>);
-    method public int drainTo(java.util.Collection<? super E>, int);
-    method public int getWaitingConsumerCount();
-    method public boolean hasWaitingConsumer();
-    method public java.util.Iterator<E> iterator();
-    method public boolean offer(E, long, java.util.concurrent.TimeUnit);
-    method public boolean offer(E);
-    method public E peek();
-    method public E poll(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-    method public E poll();
-    method public void put(E);
-    method public int remainingCapacity();
-    method public int size();
-    method public E take() throws java.lang.InterruptedException;
-    method public void transfer(E) throws java.lang.InterruptedException;
-    method public boolean tryTransfer(E);
-    method public boolean tryTransfer(E, long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-  }
-
-  public class Phaser {
-    ctor public Phaser();
-    ctor public Phaser(int);
-    ctor public Phaser(java.util.concurrent.Phaser);
-    ctor public Phaser(java.util.concurrent.Phaser, int);
-    method public int arrive();
-    method public int arriveAndAwaitAdvance();
-    method public int arriveAndDeregister();
-    method public int awaitAdvance(int);
-    method public int awaitAdvanceInterruptibly(int) throws java.lang.InterruptedException;
-    method public int awaitAdvanceInterruptibly(int, long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException, java.util.concurrent.TimeoutException;
-    method public int bulkRegister(int);
-    method public void forceTermination();
-    method public int getArrivedParties();
-    method public java.util.concurrent.Phaser getParent();
-    method public final int getPhase();
-    method public int getRegisteredParties();
-    method public java.util.concurrent.Phaser getRoot();
-    method public int getUnarrivedParties();
-    method public boolean isTerminated();
-    method protected boolean onAdvance(int, int);
-    method public int register();
-  }
-
-  public class PriorityBlockingQueue<E> extends java.util.AbstractQueue<E> implements java.util.concurrent.BlockingQueue<E> java.io.Serializable {
-    ctor public PriorityBlockingQueue();
-    ctor public PriorityBlockingQueue(int);
-    ctor public PriorityBlockingQueue(int, java.util.Comparator<? super E>);
-    ctor public PriorityBlockingQueue(java.util.Collection<? extends E>);
-    method public java.util.Comparator<? super E> comparator();
-    method public int drainTo(java.util.Collection<? super E>);
-    method public int drainTo(java.util.Collection<? super E>, int);
-    method public java.util.Iterator<E> iterator();
-    method public boolean offer(E);
-    method public boolean offer(E, long, java.util.concurrent.TimeUnit);
-    method public E peek();
-    method public E poll();
-    method public E poll(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-    method public void put(E);
-    method public int remainingCapacity();
-    method public int size();
-    method public E take() throws java.lang.InterruptedException;
-  }
-
-  public abstract class RecursiveAction extends java.util.concurrent.ForkJoinTask<java.lang.Void> {
-    ctor public RecursiveAction();
-    method protected abstract void compute();
-    method protected final boolean exec();
-    method public final Void getRawResult();
-    method protected final void setRawResult(Void);
-  }
-
-  public abstract class RecursiveTask<V> extends java.util.concurrent.ForkJoinTask<V> {
-    ctor public RecursiveTask();
-    method protected abstract V compute();
-    method protected final boolean exec();
-    method public final V getRawResult();
-    method protected final void setRawResult(V);
-  }
-
-  public class RejectedExecutionException extends java.lang.RuntimeException {
-    ctor public RejectedExecutionException();
-    ctor public RejectedExecutionException(String);
-    ctor public RejectedExecutionException(String, Throwable);
-    ctor public RejectedExecutionException(Throwable);
-  }
-
-  public interface RejectedExecutionHandler {
-    method public void rejectedExecution(Runnable, java.util.concurrent.ThreadPoolExecutor);
-  }
-
-  public interface RunnableFuture<V> extends java.lang.Runnable java.util.concurrent.Future<V> {
-  }
-
-  public interface RunnableScheduledFuture<V> extends java.util.concurrent.RunnableFuture<V> java.util.concurrent.ScheduledFuture<V> {
-    method public boolean isPeriodic();
-  }
-
-  public interface ScheduledExecutorService extends java.util.concurrent.ExecutorService {
-    method public java.util.concurrent.ScheduledFuture<?> schedule(Runnable, long, java.util.concurrent.TimeUnit);
-    method public <V> java.util.concurrent.ScheduledFuture<V> schedule(java.util.concurrent.Callable<V>, long, java.util.concurrent.TimeUnit);
-    method public java.util.concurrent.ScheduledFuture<?> scheduleAtFixedRate(Runnable, long, long, java.util.concurrent.TimeUnit);
-    method public java.util.concurrent.ScheduledFuture<?> scheduleWithFixedDelay(Runnable, long, long, java.util.concurrent.TimeUnit);
-  }
-
-  public interface ScheduledFuture<V> extends java.util.concurrent.Delayed java.util.concurrent.Future<V> {
-  }
-
-  public class ScheduledThreadPoolExecutor extends java.util.concurrent.ThreadPoolExecutor implements java.util.concurrent.ScheduledExecutorService {
-    ctor public ScheduledThreadPoolExecutor(int);
-    ctor public ScheduledThreadPoolExecutor(int, java.util.concurrent.ThreadFactory);
-    ctor public ScheduledThreadPoolExecutor(int, java.util.concurrent.RejectedExecutionHandler);
-    ctor public ScheduledThreadPoolExecutor(int, java.util.concurrent.ThreadFactory, java.util.concurrent.RejectedExecutionHandler);
-    method protected <V> java.util.concurrent.RunnableScheduledFuture<V> decorateTask(Runnable, java.util.concurrent.RunnableScheduledFuture<V>);
-    method protected <V> java.util.concurrent.RunnableScheduledFuture<V> decorateTask(java.util.concurrent.Callable<V>, java.util.concurrent.RunnableScheduledFuture<V>);
-    method public boolean getContinueExistingPeriodicTasksAfterShutdownPolicy();
-    method public boolean getExecuteExistingDelayedTasksAfterShutdownPolicy();
-    method public boolean getRemoveOnCancelPolicy();
-    method public java.util.concurrent.ScheduledFuture<?> schedule(Runnable, long, java.util.concurrent.TimeUnit);
-    method public <V> java.util.concurrent.ScheduledFuture<V> schedule(java.util.concurrent.Callable<V>, long, java.util.concurrent.TimeUnit);
-    method public java.util.concurrent.ScheduledFuture<?> scheduleAtFixedRate(Runnable, long, long, java.util.concurrent.TimeUnit);
-    method public java.util.concurrent.ScheduledFuture<?> scheduleWithFixedDelay(Runnable, long, long, java.util.concurrent.TimeUnit);
-    method public void setContinueExistingPeriodicTasksAfterShutdownPolicy(boolean);
-    method public void setExecuteExistingDelayedTasksAfterShutdownPolicy(boolean);
-    method public void setRemoveOnCancelPolicy(boolean);
-  }
-
-  public class Semaphore implements java.io.Serializable {
-    ctor public Semaphore(int);
-    ctor public Semaphore(int, boolean);
-    method public void acquire() throws java.lang.InterruptedException;
-    method public void acquire(int) throws java.lang.InterruptedException;
-    method public void acquireUninterruptibly();
-    method public void acquireUninterruptibly(int);
-    method public int availablePermits();
-    method public int drainPermits();
-    method public final int getQueueLength();
-    method protected java.util.Collection<java.lang.Thread> getQueuedThreads();
-    method public final boolean hasQueuedThreads();
-    method public boolean isFair();
-    method protected void reducePermits(int);
-    method public void release();
-    method public void release(int);
-    method public boolean tryAcquire();
-    method public boolean tryAcquire(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-    method public boolean tryAcquire(int);
-    method public boolean tryAcquire(int, long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-  }
-
-  public class SynchronousQueue<E> extends java.util.AbstractQueue<E> implements java.util.concurrent.BlockingQueue<E> java.io.Serializable {
-    ctor public SynchronousQueue();
-    ctor public SynchronousQueue(boolean);
-    method public int drainTo(java.util.Collection<? super E>);
-    method public int drainTo(java.util.Collection<? super E>, int);
-    method public java.util.Iterator<E> iterator();
-    method public boolean offer(E, long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-    method public boolean offer(E);
-    method public E peek();
-    method public E poll(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-    method public E poll();
-    method public void put(E) throws java.lang.InterruptedException;
-    method public int remainingCapacity();
-    method public int size();
-    method public E take() throws java.lang.InterruptedException;
-  }
-
-  public interface ThreadFactory {
-    method public Thread newThread(Runnable);
-  }
-
-  public class ThreadLocalRandom extends java.util.Random {
-    method public static java.util.concurrent.ThreadLocalRandom current();
-    method public double nextDouble(double);
-    method public double nextDouble(double, double);
-    method public int nextInt(int, int);
-    method public long nextLong(long);
-    method public long nextLong(long, long);
-  }
-
-  public class ThreadPoolExecutor extends java.util.concurrent.AbstractExecutorService {
-    ctor public ThreadPoolExecutor(int, int, long, java.util.concurrent.TimeUnit, java.util.concurrent.BlockingQueue<java.lang.Runnable>);
-    ctor public ThreadPoolExecutor(int, int, long, java.util.concurrent.TimeUnit, java.util.concurrent.BlockingQueue<java.lang.Runnable>, java.util.concurrent.ThreadFactory);
-    ctor public ThreadPoolExecutor(int, int, long, java.util.concurrent.TimeUnit, java.util.concurrent.BlockingQueue<java.lang.Runnable>, java.util.concurrent.RejectedExecutionHandler);
-    ctor public ThreadPoolExecutor(int, int, long, java.util.concurrent.TimeUnit, java.util.concurrent.BlockingQueue<java.lang.Runnable>, java.util.concurrent.ThreadFactory, java.util.concurrent.RejectedExecutionHandler);
-    method protected void afterExecute(Runnable, Throwable);
-    method public void allowCoreThreadTimeOut(boolean);
-    method public boolean allowsCoreThreadTimeOut();
-    method public boolean awaitTermination(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-    method protected void beforeExecute(Thread, Runnable);
-    method public void execute(Runnable);
-    method protected void finalize();
-    method public int getActiveCount();
-    method public long getCompletedTaskCount();
-    method public int getCorePoolSize();
-    method public long getKeepAliveTime(java.util.concurrent.TimeUnit);
-    method public int getLargestPoolSize();
-    method public int getMaximumPoolSize();
-    method public int getPoolSize();
-    method public java.util.concurrent.BlockingQueue<java.lang.Runnable> getQueue();
-    method public java.util.concurrent.RejectedExecutionHandler getRejectedExecutionHandler();
-    method public long getTaskCount();
-    method public java.util.concurrent.ThreadFactory getThreadFactory();
-    method public boolean isShutdown();
-    method public boolean isTerminated();
-    method public boolean isTerminating();
-    method public int prestartAllCoreThreads();
-    method public boolean prestartCoreThread();
-    method public void purge();
-    method public boolean remove(Runnable);
-    method public void setCorePoolSize(int);
-    method public void setKeepAliveTime(long, java.util.concurrent.TimeUnit);
-    method public void setMaximumPoolSize(int);
-    method public void setRejectedExecutionHandler(java.util.concurrent.RejectedExecutionHandler);
-    method public void setThreadFactory(java.util.concurrent.ThreadFactory);
-    method public void shutdown();
-    method public java.util.List<java.lang.Runnable> shutdownNow();
-    method protected void terminated();
-  }
-
-  public static class ThreadPoolExecutor.AbortPolicy implements java.util.concurrent.RejectedExecutionHandler {
-    ctor public ThreadPoolExecutor.AbortPolicy();
-    method public void rejectedExecution(Runnable, java.util.concurrent.ThreadPoolExecutor);
-  }
-
-  public static class ThreadPoolExecutor.CallerRunsPolicy implements java.util.concurrent.RejectedExecutionHandler {
-    ctor public ThreadPoolExecutor.CallerRunsPolicy();
-    method public void rejectedExecution(Runnable, java.util.concurrent.ThreadPoolExecutor);
-  }
-
-  public static class ThreadPoolExecutor.DiscardOldestPolicy implements java.util.concurrent.RejectedExecutionHandler {
-    ctor public ThreadPoolExecutor.DiscardOldestPolicy();
-    method public void rejectedExecution(Runnable, java.util.concurrent.ThreadPoolExecutor);
-  }
-
-  public static class ThreadPoolExecutor.DiscardPolicy implements java.util.concurrent.RejectedExecutionHandler {
-    ctor public ThreadPoolExecutor.DiscardPolicy();
-    method public void rejectedExecution(Runnable, java.util.concurrent.ThreadPoolExecutor);
-  }
-
-  public enum TimeUnit {
-    method public long convert(long, java.util.concurrent.TimeUnit);
-    method public void sleep(long) throws java.lang.InterruptedException;
-    method public void timedJoin(Thread, long) throws java.lang.InterruptedException;
-    method public void timedWait(Object, long) throws java.lang.InterruptedException;
-    method public long toDays(long);
-    method public long toHours(long);
-    method public long toMicros(long);
-    method public long toMillis(long);
-    method public long toMinutes(long);
-    method public long toNanos(long);
-    method public long toSeconds(long);
-    enum_constant public static final java.util.concurrent.TimeUnit DAYS;
-    enum_constant public static final java.util.concurrent.TimeUnit HOURS;
-    enum_constant public static final java.util.concurrent.TimeUnit MICROSECONDS;
-    enum_constant public static final java.util.concurrent.TimeUnit MILLISECONDS;
-    enum_constant public static final java.util.concurrent.TimeUnit MINUTES;
-    enum_constant public static final java.util.concurrent.TimeUnit NANOSECONDS;
-    enum_constant public static final java.util.concurrent.TimeUnit SECONDS;
-  }
-
-  public class TimeoutException extends java.lang.Exception {
-    ctor public TimeoutException();
-    ctor public TimeoutException(String);
-  }
-
-  public interface TransferQueue<E> extends java.util.concurrent.BlockingQueue<E> {
-    method public int getWaitingConsumerCount();
-    method public boolean hasWaitingConsumer();
-    method public void transfer(E) throws java.lang.InterruptedException;
-    method public boolean tryTransfer(E);
-    method public boolean tryTransfer(E, long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-  }
-
-}
-
-package java.util.concurrent.atomic {
-
-  public class AtomicBoolean implements java.io.Serializable {
-    ctor public AtomicBoolean(boolean);
-    ctor public AtomicBoolean();
-    method public final boolean compareAndSet(boolean, boolean);
-    method public final boolean get();
-    method public final boolean getAndSet(boolean);
-    method public final void lazySet(boolean);
-    method public final void set(boolean);
-    method public boolean weakCompareAndSet(boolean, boolean);
-  }
-
-  public class AtomicInteger extends java.lang.Number implements java.io.Serializable {
-    ctor public AtomicInteger(int);
-    ctor public AtomicInteger();
-    method public final int accumulateAndGet(int, java.util.function.IntBinaryOperator);
-    method public final int addAndGet(int);
-    method public final boolean compareAndSet(int, int);
-    method public final int decrementAndGet();
-    method public double doubleValue();
-    method public float floatValue();
-    method public final int get();
-    method public final int getAndAccumulate(int, java.util.function.IntBinaryOperator);
-    method public final int getAndAdd(int);
-    method public final int getAndDecrement();
-    method public final int getAndIncrement();
-    method public final int getAndSet(int);
-    method public final int getAndUpdate(java.util.function.IntUnaryOperator);
-    method public final int incrementAndGet();
-    method public int intValue();
-    method public final void lazySet(int);
-    method public long longValue();
-    method public final void set(int);
-    method public final int updateAndGet(java.util.function.IntUnaryOperator);
-    method public final boolean weakCompareAndSet(int, int);
-  }
-
-  public class AtomicIntegerArray implements java.io.Serializable {
-    ctor public AtomicIntegerArray(int);
-    ctor public AtomicIntegerArray(int[]);
-    method public final int accumulateAndGet(int, int, java.util.function.IntBinaryOperator);
-    method public final int addAndGet(int, int);
-    method public final boolean compareAndSet(int, int, int);
-    method public final int decrementAndGet(int);
-    method public final int get(int);
-    method public final int getAndAccumulate(int, int, java.util.function.IntBinaryOperator);
-    method public final int getAndAdd(int, int);
-    method public final int getAndDecrement(int);
-    method public final int getAndIncrement(int);
-    method public final int getAndSet(int, int);
-    method public final int getAndUpdate(int, java.util.function.IntUnaryOperator);
-    method public final int incrementAndGet(int);
-    method public final void lazySet(int, int);
-    method public final int length();
-    method public final void set(int, int);
-    method public final int updateAndGet(int, java.util.function.IntUnaryOperator);
-    method public final boolean weakCompareAndSet(int, int, int);
-  }
-
-  public abstract class AtomicIntegerFieldUpdater<T> {
-    ctor protected AtomicIntegerFieldUpdater();
-    method public final int accumulateAndGet(T, int, java.util.function.IntBinaryOperator);
-    method public int addAndGet(T, int);
-    method public abstract boolean compareAndSet(T, int, int);
-    method public int decrementAndGet(T);
-    method public abstract int get(T);
-    method public final int getAndAccumulate(T, int, java.util.function.IntBinaryOperator);
-    method public int getAndAdd(T, int);
-    method public int getAndDecrement(T);
-    method public int getAndIncrement(T);
-    method public int getAndSet(T, int);
-    method public final int getAndUpdate(T, java.util.function.IntUnaryOperator);
-    method public int incrementAndGet(T);
-    method public abstract void lazySet(T, int);
-    method public static <U> java.util.concurrent.atomic.AtomicIntegerFieldUpdater<U> newUpdater(Class<U>, String);
-    method public abstract void set(T, int);
-    method public final int updateAndGet(T, java.util.function.IntUnaryOperator);
-    method public abstract boolean weakCompareAndSet(T, int, int);
-  }
-
-  public class AtomicLong extends java.lang.Number implements java.io.Serializable {
-    ctor public AtomicLong(long);
-    ctor public AtomicLong();
-    method public final long accumulateAndGet(long, java.util.function.LongBinaryOperator);
-    method public final long addAndGet(long);
-    method public final boolean compareAndSet(long, long);
-    method public final long decrementAndGet();
-    method public double doubleValue();
-    method public float floatValue();
-    method public final long get();
-    method public final long getAndAccumulate(long, java.util.function.LongBinaryOperator);
-    method public final long getAndAdd(long);
-    method public final long getAndDecrement();
-    method public final long getAndIncrement();
-    method public final long getAndSet(long);
-    method public final long getAndUpdate(java.util.function.LongUnaryOperator);
-    method public final long incrementAndGet();
-    method public int intValue();
-    method public final void lazySet(long);
-    method public long longValue();
-    method public final void set(long);
-    method public final long updateAndGet(java.util.function.LongUnaryOperator);
-    method public final boolean weakCompareAndSet(long, long);
-  }
-
-  public class AtomicLongArray implements java.io.Serializable {
-    ctor public AtomicLongArray(int);
-    ctor public AtomicLongArray(long[]);
-    method public final long accumulateAndGet(int, long, java.util.function.LongBinaryOperator);
-    method public long addAndGet(int, long);
-    method public final boolean compareAndSet(int, long, long);
-    method public final long decrementAndGet(int);
-    method public final long get(int);
-    method public final long getAndAccumulate(int, long, java.util.function.LongBinaryOperator);
-    method public final long getAndAdd(int, long);
-    method public final long getAndDecrement(int);
-    method public final long getAndIncrement(int);
-    method public final long getAndSet(int, long);
-    method public final long getAndUpdate(int, java.util.function.LongUnaryOperator);
-    method public final long incrementAndGet(int);
-    method public final void lazySet(int, long);
-    method public final int length();
-    method public final void set(int, long);
-    method public final long updateAndGet(int, java.util.function.LongUnaryOperator);
-    method public final boolean weakCompareAndSet(int, long, long);
-  }
-
-  public abstract class AtomicLongFieldUpdater<T> {
-    ctor protected AtomicLongFieldUpdater();
-    method public final long accumulateAndGet(T, long, java.util.function.LongBinaryOperator);
-    method public long addAndGet(T, long);
-    method public abstract boolean compareAndSet(T, long, long);
-    method public long decrementAndGet(T);
-    method public abstract long get(T);
-    method public final long getAndAccumulate(T, long, java.util.function.LongBinaryOperator);
-    method public long getAndAdd(T, long);
-    method public long getAndDecrement(T);
-    method public long getAndIncrement(T);
-    method public long getAndSet(T, long);
-    method public final long getAndUpdate(T, java.util.function.LongUnaryOperator);
-    method public long incrementAndGet(T);
-    method public abstract void lazySet(T, long);
-    method public static <U> java.util.concurrent.atomic.AtomicLongFieldUpdater<U> newUpdater(Class<U>, String);
-    method public abstract void set(T, long);
-    method public final long updateAndGet(T, java.util.function.LongUnaryOperator);
-    method public abstract boolean weakCompareAndSet(T, long, long);
-  }
-
-  public class AtomicMarkableReference<V> {
-    ctor public AtomicMarkableReference(V, boolean);
-    method public boolean attemptMark(V, boolean);
-    method public boolean compareAndSet(V, V, boolean, boolean);
-    method public V get(boolean[]);
-    method public V getReference();
-    method public boolean isMarked();
-    method public void set(V, boolean);
-    method public boolean weakCompareAndSet(V, V, boolean, boolean);
-  }
-
-  public class AtomicReference<V> implements java.io.Serializable {
-    ctor public AtomicReference(V);
-    ctor public AtomicReference();
-    method public final V accumulateAndGet(V, java.util.function.BinaryOperator<V>);
-    method public final boolean compareAndSet(V, V);
-    method public final V get();
-    method public final V getAndAccumulate(V, java.util.function.BinaryOperator<V>);
-    method public final V getAndSet(V);
-    method public final V getAndUpdate(java.util.function.UnaryOperator<V>);
-    method public final void lazySet(V);
-    method public final void set(V);
-    method public final V updateAndGet(java.util.function.UnaryOperator<V>);
-    method public final boolean weakCompareAndSet(V, V);
-  }
-
-  public class AtomicReferenceArray<E> implements java.io.Serializable {
-    ctor public AtomicReferenceArray(int);
-    ctor public AtomicReferenceArray(E[]);
-    method public final E accumulateAndGet(int, E, java.util.function.BinaryOperator<E>);
-    method public final boolean compareAndSet(int, E, E);
-    method public final E get(int);
-    method public final E getAndAccumulate(int, E, java.util.function.BinaryOperator<E>);
-    method public final E getAndSet(int, E);
-    method public final E getAndUpdate(int, java.util.function.UnaryOperator<E>);
-    method public final void lazySet(int, E);
-    method public final int length();
-    method public final void set(int, E);
-    method public final E updateAndGet(int, java.util.function.UnaryOperator<E>);
-    method public final boolean weakCompareAndSet(int, E, E);
-  }
-
-  public abstract class AtomicReferenceFieldUpdater<T, V> {
-    ctor protected AtomicReferenceFieldUpdater();
-    method public final V accumulateAndGet(T, V, java.util.function.BinaryOperator<V>);
-    method public abstract boolean compareAndSet(T, V, V);
-    method public abstract V get(T);
-    method public final V getAndAccumulate(T, V, java.util.function.BinaryOperator<V>);
-    method public V getAndSet(T, V);
-    method public final V getAndUpdate(T, java.util.function.UnaryOperator<V>);
-    method public abstract void lazySet(T, V);
-    method public static <U, W> java.util.concurrent.atomic.AtomicReferenceFieldUpdater<U,W> newUpdater(Class<U>, Class<W>, String);
-    method public abstract void set(T, V);
-    method public final V updateAndGet(T, java.util.function.UnaryOperator<V>);
-    method public abstract boolean weakCompareAndSet(T, V, V);
-  }
-
-  public class AtomicStampedReference<V> {
-    ctor public AtomicStampedReference(V, int);
-    method public boolean attemptStamp(V, int);
-    method public boolean compareAndSet(V, V, int, int);
-    method public V get(int[]);
-    method public V getReference();
-    method public int getStamp();
-    method public void set(V, int);
-    method public boolean weakCompareAndSet(V, V, int, int);
-  }
-
-  public class DoubleAccumulator extends java.lang.Number implements java.io.Serializable {
-    ctor public DoubleAccumulator(java.util.function.DoubleBinaryOperator, double);
-    method public void accumulate(double);
-    method public double doubleValue();
-    method public float floatValue();
-    method public double get();
-    method public double getThenReset();
-    method public int intValue();
-    method public long longValue();
-    method public void reset();
-  }
-
-  public class DoubleAdder extends java.lang.Number implements java.io.Serializable {
-    ctor public DoubleAdder();
-    method public void add(double);
-    method public double doubleValue();
-    method public float floatValue();
-    method public int intValue();
-    method public long longValue();
-    method public void reset();
-    method public double sum();
-    method public double sumThenReset();
-  }
-
-  public class LongAccumulator extends java.lang.Number implements java.io.Serializable {
-    ctor public LongAccumulator(java.util.function.LongBinaryOperator, long);
-    method public void accumulate(long);
-    method public double doubleValue();
-    method public float floatValue();
-    method public long get();
-    method public long getThenReset();
-    method public int intValue();
-    method public long longValue();
-    method public void reset();
-  }
-
-  public class LongAdder extends java.lang.Number implements java.io.Serializable {
-    ctor public LongAdder();
-    method public void add(long);
-    method public void decrement();
-    method public double doubleValue();
-    method public float floatValue();
-    method public void increment();
-    method public int intValue();
-    method public long longValue();
-    method public void reset();
-    method public long sum();
-    method public long sumThenReset();
-  }
-
-}
-
-package java.util.concurrent.locks {
-
-  public abstract class AbstractOwnableSynchronizer implements java.io.Serializable {
-    ctor protected AbstractOwnableSynchronizer();
-    method protected final Thread getExclusiveOwnerThread();
-    method protected final void setExclusiveOwnerThread(Thread);
-  }
-
-  public abstract class AbstractQueuedLongSynchronizer extends java.util.concurrent.locks.AbstractOwnableSynchronizer implements java.io.Serializable {
-    ctor protected AbstractQueuedLongSynchronizer();
-    method public final void acquire(long);
-    method public final void acquireInterruptibly(long) throws java.lang.InterruptedException;
-    method public final void acquireShared(long);
-    method public final void acquireSharedInterruptibly(long) throws java.lang.InterruptedException;
-    method protected final boolean compareAndSetState(long, long);
-    method public final java.util.Collection<java.lang.Thread> getExclusiveQueuedThreads();
-    method public final Thread getFirstQueuedThread();
-    method public final int getQueueLength();
-    method public final java.util.Collection<java.lang.Thread> getQueuedThreads();
-    method public final java.util.Collection<java.lang.Thread> getSharedQueuedThreads();
-    method protected final long getState();
-    method public final int getWaitQueueLength(java.util.concurrent.locks.AbstractQueuedLongSynchronizer.ConditionObject);
-    method public final java.util.Collection<java.lang.Thread> getWaitingThreads(java.util.concurrent.locks.AbstractQueuedLongSynchronizer.ConditionObject);
-    method public final boolean hasContended();
-    method public final boolean hasQueuedPredecessors();
-    method public final boolean hasQueuedThreads();
-    method public final boolean hasWaiters(java.util.concurrent.locks.AbstractQueuedLongSynchronizer.ConditionObject);
-    method protected boolean isHeldExclusively();
-    method public final boolean isQueued(Thread);
-    method public final boolean owns(java.util.concurrent.locks.AbstractQueuedLongSynchronizer.ConditionObject);
-    method public final boolean release(long);
-    method public final boolean releaseShared(long);
-    method protected final void setState(long);
-    method protected boolean tryAcquire(long);
-    method public final boolean tryAcquireNanos(long, long) throws java.lang.InterruptedException;
-    method protected long tryAcquireShared(long);
-    method public final boolean tryAcquireSharedNanos(long, long) throws java.lang.InterruptedException;
-    method protected boolean tryRelease(long);
-    method protected boolean tryReleaseShared(long);
-  }
-
-  public class AbstractQueuedLongSynchronizer.ConditionObject implements java.util.concurrent.locks.Condition java.io.Serializable {
-    ctor public AbstractQueuedLongSynchronizer.ConditionObject();
-    method public final void await() throws java.lang.InterruptedException;
-    method public final boolean await(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-    method public final long awaitNanos(long) throws java.lang.InterruptedException;
-    method public final void awaitUninterruptibly();
-    method public final boolean awaitUntil(java.util.Date) throws java.lang.InterruptedException;
-    method protected final int getWaitQueueLength();
-    method protected final java.util.Collection<java.lang.Thread> getWaitingThreads();
-    method protected final boolean hasWaiters();
-    method public final void signal();
-    method public final void signalAll();
-  }
-
-  public abstract class AbstractQueuedSynchronizer extends java.util.concurrent.locks.AbstractOwnableSynchronizer implements java.io.Serializable {
-    ctor protected AbstractQueuedSynchronizer();
-    method public final void acquire(int);
-    method public final void acquireInterruptibly(int) throws java.lang.InterruptedException;
-    method public final void acquireShared(int);
-    method public final void acquireSharedInterruptibly(int) throws java.lang.InterruptedException;
-    method protected final boolean compareAndSetState(int, int);
-    method public final java.util.Collection<java.lang.Thread> getExclusiveQueuedThreads();
-    method public final Thread getFirstQueuedThread();
-    method public final int getQueueLength();
-    method public final java.util.Collection<java.lang.Thread> getQueuedThreads();
-    method public final java.util.Collection<java.lang.Thread> getSharedQueuedThreads();
-    method protected final int getState();
-    method public final int getWaitQueueLength(java.util.concurrent.locks.AbstractQueuedSynchronizer.ConditionObject);
-    method public final java.util.Collection<java.lang.Thread> getWaitingThreads(java.util.concurrent.locks.AbstractQueuedSynchronizer.ConditionObject);
-    method public final boolean hasContended();
-    method public final boolean hasQueuedPredecessors();
-    method public final boolean hasQueuedThreads();
-    method public final boolean hasWaiters(java.util.concurrent.locks.AbstractQueuedSynchronizer.ConditionObject);
-    method protected boolean isHeldExclusively();
-    method public final boolean isQueued(Thread);
-    method public final boolean owns(java.util.concurrent.locks.AbstractQueuedSynchronizer.ConditionObject);
-    method public final boolean release(int);
-    method public final boolean releaseShared(int);
-    method protected final void setState(int);
-    method protected boolean tryAcquire(int);
-    method public final boolean tryAcquireNanos(int, long) throws java.lang.InterruptedException;
-    method protected int tryAcquireShared(int);
-    method public final boolean tryAcquireSharedNanos(int, long) throws java.lang.InterruptedException;
-    method protected boolean tryRelease(int);
-    method protected boolean tryReleaseShared(int);
-  }
-
-  public class AbstractQueuedSynchronizer.ConditionObject implements java.util.concurrent.locks.Condition java.io.Serializable {
-    ctor public AbstractQueuedSynchronizer.ConditionObject();
-    method public final void await() throws java.lang.InterruptedException;
-    method public final boolean await(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-    method public final long awaitNanos(long) throws java.lang.InterruptedException;
-    method public final void awaitUninterruptibly();
-    method public final boolean awaitUntil(java.util.Date) throws java.lang.InterruptedException;
-    method protected final int getWaitQueueLength();
-    method protected final java.util.Collection<java.lang.Thread> getWaitingThreads();
-    method protected final boolean hasWaiters();
-    method public final void signal();
-    method public final void signalAll();
-  }
-
-  public interface Condition {
-    method public void await() throws java.lang.InterruptedException;
-    method public boolean await(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-    method public long awaitNanos(long) throws java.lang.InterruptedException;
-    method public void awaitUninterruptibly();
-    method public boolean awaitUntil(java.util.Date) throws java.lang.InterruptedException;
-    method public void signal();
-    method public void signalAll();
-  }
-
-  public interface Lock {
-    method public void lock();
-    method public void lockInterruptibly() throws java.lang.InterruptedException;
-    method public java.util.concurrent.locks.Condition newCondition();
-    method public boolean tryLock();
-    method public boolean tryLock(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-    method public void unlock();
-  }
-
-  public class LockSupport {
-    method public static Object getBlocker(Thread);
-    method public static void park(Object);
-    method public static void park();
-    method public static void parkNanos(Object, long);
-    method public static void parkNanos(long);
-    method public static void parkUntil(Object, long);
-    method public static void parkUntil(long);
-    method public static void unpark(Thread);
-  }
-
-  public interface ReadWriteLock {
-    method public java.util.concurrent.locks.Lock readLock();
-    method public java.util.concurrent.locks.Lock writeLock();
-  }
-
-  public class ReentrantLock implements java.util.concurrent.locks.Lock java.io.Serializable {
-    ctor public ReentrantLock();
-    ctor public ReentrantLock(boolean);
-    method public int getHoldCount();
-    method protected Thread getOwner();
-    method public final int getQueueLength();
-    method protected java.util.Collection<java.lang.Thread> getQueuedThreads();
-    method public int getWaitQueueLength(java.util.concurrent.locks.Condition);
-    method protected java.util.Collection<java.lang.Thread> getWaitingThreads(java.util.concurrent.locks.Condition);
-    method public final boolean hasQueuedThread(Thread);
-    method public final boolean hasQueuedThreads();
-    method public boolean hasWaiters(java.util.concurrent.locks.Condition);
-    method public final boolean isFair();
-    method public boolean isHeldByCurrentThread();
-    method public boolean isLocked();
-    method public void lock();
-    method public void lockInterruptibly() throws java.lang.InterruptedException;
-    method public java.util.concurrent.locks.Condition newCondition();
-    method public boolean tryLock();
-    method public boolean tryLock(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-    method public void unlock();
-  }
-
-  public class ReentrantReadWriteLock implements java.util.concurrent.locks.ReadWriteLock java.io.Serializable {
-    ctor public ReentrantReadWriteLock();
-    ctor public ReentrantReadWriteLock(boolean);
-    method protected Thread getOwner();
-    method public final int getQueueLength();
-    method protected java.util.Collection<java.lang.Thread> getQueuedReaderThreads();
-    method protected java.util.Collection<java.lang.Thread> getQueuedThreads();
-    method protected java.util.Collection<java.lang.Thread> getQueuedWriterThreads();
-    method public int getReadHoldCount();
-    method public int getReadLockCount();
-    method public int getWaitQueueLength(java.util.concurrent.locks.Condition);
-    method protected java.util.Collection<java.lang.Thread> getWaitingThreads(java.util.concurrent.locks.Condition);
-    method public int getWriteHoldCount();
-    method public final boolean hasQueuedThread(Thread);
-    method public final boolean hasQueuedThreads();
-    method public boolean hasWaiters(java.util.concurrent.locks.Condition);
-    method public final boolean isFair();
-    method public boolean isWriteLocked();
-    method public boolean isWriteLockedByCurrentThread();
-    method public java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock readLock();
-    method public java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock writeLock();
-  }
-
-  public static class ReentrantReadWriteLock.ReadLock implements java.util.concurrent.locks.Lock java.io.Serializable {
-    ctor protected ReentrantReadWriteLock.ReadLock(java.util.concurrent.locks.ReentrantReadWriteLock);
-    method public void lock();
-    method public void lockInterruptibly() throws java.lang.InterruptedException;
-    method public java.util.concurrent.locks.Condition newCondition();
-    method public boolean tryLock();
-    method public boolean tryLock(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-    method public void unlock();
-  }
-
-  public static class ReentrantReadWriteLock.WriteLock implements java.util.concurrent.locks.Lock java.io.Serializable {
-    ctor protected ReentrantReadWriteLock.WriteLock(java.util.concurrent.locks.ReentrantReadWriteLock);
-    method public int getHoldCount();
-    method public boolean isHeldByCurrentThread();
-    method public void lock();
-    method public void lockInterruptibly() throws java.lang.InterruptedException;
-    method public java.util.concurrent.locks.Condition newCondition();
-    method public boolean tryLock();
-    method public boolean tryLock(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-    method public void unlock();
-  }
-
-  public class StampedLock implements java.io.Serializable {
-    ctor public StampedLock();
-    method public java.util.concurrent.locks.Lock asReadLock();
-    method public java.util.concurrent.locks.ReadWriteLock asReadWriteLock();
-    method public java.util.concurrent.locks.Lock asWriteLock();
-    method public int getReadLockCount();
-    method public boolean isReadLocked();
-    method public boolean isWriteLocked();
-    method public long readLock();
-    method public long readLockInterruptibly() throws java.lang.InterruptedException;
-    method public long tryConvertToOptimisticRead(long);
-    method public long tryConvertToReadLock(long);
-    method public long tryConvertToWriteLock(long);
-    method public long tryOptimisticRead();
-    method public long tryReadLock();
-    method public long tryReadLock(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-    method public boolean tryUnlockRead();
-    method public boolean tryUnlockWrite();
-    method public long tryWriteLock();
-    method public long tryWriteLock(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-    method public void unlock(long);
-    method public void unlockRead(long);
-    method public void unlockWrite(long);
-    method public boolean validate(long);
-    method public long writeLock();
-    method public long writeLockInterruptibly() throws java.lang.InterruptedException;
-  }
-
-}
-
-package java.util.function {
-
-  @java.lang.FunctionalInterface public interface BiConsumer<T, U> {
-    method public void accept(T, U);
-    method public default java.util.function.BiConsumer<T,U> andThen(java.util.function.BiConsumer<? super T,? super U>);
-  }
-
-  @java.lang.FunctionalInterface public interface BiFunction<T, U, R> {
-    method public default <V> java.util.function.BiFunction<T,U,V> andThen(java.util.function.Function<? super R,? extends V>);
-    method public R apply(T, U);
-  }
-
-  @java.lang.FunctionalInterface public interface BiPredicate<T, U> {
-    method public default java.util.function.BiPredicate<T,U> and(java.util.function.BiPredicate<? super T,? super U>);
-    method public default java.util.function.BiPredicate<T,U> negate();
-    method public default java.util.function.BiPredicate<T,U> or(java.util.function.BiPredicate<? super T,? super U>);
-    method public boolean test(T, U);
-  }
-
-  @java.lang.FunctionalInterface public interface BinaryOperator<T> extends java.util.function.BiFunction<T,T,T> {
-    method public static <T> java.util.function.BinaryOperator<T> maxBy(java.util.Comparator<? super T>);
-    method public static <T> java.util.function.BinaryOperator<T> minBy(java.util.Comparator<? super T>);
-  }
-
-  @java.lang.FunctionalInterface public interface BooleanSupplier {
-    method public boolean getAsBoolean();
-  }
-
-  @java.lang.FunctionalInterface public interface Consumer<T> {
-    method public void accept(T);
-    method public default java.util.function.Consumer<T> andThen(java.util.function.Consumer<? super T>);
-  }
-
-  @java.lang.FunctionalInterface public interface DoubleBinaryOperator {
-    method public double applyAsDouble(double, double);
-  }
-
-  @java.lang.FunctionalInterface public interface DoubleConsumer {
-    method public void accept(double);
-    method public default java.util.function.DoubleConsumer andThen(java.util.function.DoubleConsumer);
-  }
-
-  @java.lang.FunctionalInterface public interface DoubleFunction<R> {
-    method public R apply(double);
-  }
-
-  @java.lang.FunctionalInterface public interface DoublePredicate {
-    method public default java.util.function.DoublePredicate and(java.util.function.DoublePredicate);
-    method public default java.util.function.DoublePredicate negate();
-    method public default java.util.function.DoublePredicate or(java.util.function.DoublePredicate);
-    method public boolean test(double);
-  }
-
-  @java.lang.FunctionalInterface public interface DoubleSupplier {
-    method public double getAsDouble();
-  }
-
-  @java.lang.FunctionalInterface public interface DoubleToIntFunction {
-    method public int applyAsInt(double);
-  }
-
-  @java.lang.FunctionalInterface public interface DoubleToLongFunction {
-    method public long applyAsLong(double);
-  }
-
-  @java.lang.FunctionalInterface public interface DoubleUnaryOperator {
-    method public default java.util.function.DoubleUnaryOperator andThen(java.util.function.DoubleUnaryOperator);
-    method public double applyAsDouble(double);
-    method public default java.util.function.DoubleUnaryOperator compose(java.util.function.DoubleUnaryOperator);
-    method public static java.util.function.DoubleUnaryOperator identity();
-  }
-
-  @java.lang.FunctionalInterface public interface Function<T, R> {
-    method public default <V> java.util.function.Function<T,V> andThen(java.util.function.Function<? super R,? extends V>);
-    method public R apply(T);
-    method public default <V> java.util.function.Function<V,R> compose(java.util.function.Function<? super V,? extends T>);
-    method public static <T> java.util.function.Function<T,T> identity();
-  }
-
-  @java.lang.FunctionalInterface public interface IntBinaryOperator {
-    method public int applyAsInt(int, int);
-  }
-
-  @java.lang.FunctionalInterface public interface IntConsumer {
-    method public void accept(int);
-    method public default java.util.function.IntConsumer andThen(java.util.function.IntConsumer);
-  }
-
-  @java.lang.FunctionalInterface public interface IntFunction<R> {
-    method public R apply(int);
-  }
-
-  @java.lang.FunctionalInterface public interface IntPredicate {
-    method public default java.util.function.IntPredicate and(java.util.function.IntPredicate);
-    method public default java.util.function.IntPredicate negate();
-    method public default java.util.function.IntPredicate or(java.util.function.IntPredicate);
-    method public boolean test(int);
-  }
-
-  @java.lang.FunctionalInterface public interface IntSupplier {
-    method public int getAsInt();
-  }
-
-  @java.lang.FunctionalInterface public interface IntToDoubleFunction {
-    method public double applyAsDouble(int);
-  }
-
-  @java.lang.FunctionalInterface public interface IntToLongFunction {
-    method public long applyAsLong(int);
-  }
-
-  @java.lang.FunctionalInterface public interface IntUnaryOperator {
-    method public default java.util.function.IntUnaryOperator andThen(java.util.function.IntUnaryOperator);
-    method public int applyAsInt(int);
-    method public default java.util.function.IntUnaryOperator compose(java.util.function.IntUnaryOperator);
-    method public static java.util.function.IntUnaryOperator identity();
-  }
-
-  @java.lang.FunctionalInterface public interface LongBinaryOperator {
-    method public long applyAsLong(long, long);
-  }
-
-  @java.lang.FunctionalInterface public interface LongConsumer {
-    method public void accept(long);
-    method public default java.util.function.LongConsumer andThen(java.util.function.LongConsumer);
-  }
-
-  @java.lang.FunctionalInterface public interface LongFunction<R> {
-    method public R apply(long);
-  }
-
-  @java.lang.FunctionalInterface public interface LongPredicate {
-    method public default java.util.function.LongPredicate and(java.util.function.LongPredicate);
-    method public default java.util.function.LongPredicate negate();
-    method public default java.util.function.LongPredicate or(java.util.function.LongPredicate);
-    method public boolean test(long);
-  }
-
-  @java.lang.FunctionalInterface public interface LongSupplier {
-    method public long getAsLong();
-  }
-
-  @java.lang.FunctionalInterface public interface LongToDoubleFunction {
-    method public double applyAsDouble(long);
-  }
-
-  @java.lang.FunctionalInterface public interface LongToIntFunction {
-    method public int applyAsInt(long);
-  }
-
-  @java.lang.FunctionalInterface public interface LongUnaryOperator {
-    method public default java.util.function.LongUnaryOperator andThen(java.util.function.LongUnaryOperator);
-    method public long applyAsLong(long);
-    method public default java.util.function.LongUnaryOperator compose(java.util.function.LongUnaryOperator);
-    method public static java.util.function.LongUnaryOperator identity();
-  }
-
-  @java.lang.FunctionalInterface public interface ObjDoubleConsumer<T> {
-    method public void accept(T, double);
-  }
-
-  @java.lang.FunctionalInterface public interface ObjIntConsumer<T> {
-    method public void accept(T, int);
-  }
-
-  @java.lang.FunctionalInterface public interface ObjLongConsumer<T> {
-    method public void accept(T, long);
-  }
-
-  @java.lang.FunctionalInterface public interface Predicate<T> {
-    method public default java.util.function.Predicate<T> and(java.util.function.Predicate<? super T>);
-    method public static <T> java.util.function.Predicate<T> isEqual(Object);
-    method public default java.util.function.Predicate<T> negate();
-    method public default java.util.function.Predicate<T> or(java.util.function.Predicate<? super T>);
-    method public boolean test(T);
-  }
-
-  @java.lang.FunctionalInterface public interface Supplier<T> {
-    method public T get();
-  }
-
-  @java.lang.FunctionalInterface public interface ToDoubleBiFunction<T, U> {
-    method public double applyAsDouble(T, U);
-  }
-
-  @java.lang.FunctionalInterface public interface ToDoubleFunction<T> {
-    method public double applyAsDouble(T);
-  }
-
-  @java.lang.FunctionalInterface public interface ToIntBiFunction<T, U> {
-    method public int applyAsInt(T, U);
-  }
-
-  @java.lang.FunctionalInterface public interface ToIntFunction<T> {
-    method public int applyAsInt(T);
-  }
-
-  @java.lang.FunctionalInterface public interface ToLongBiFunction<T, U> {
-    method public long applyAsLong(T, U);
-  }
-
-  @java.lang.FunctionalInterface public interface ToLongFunction<T> {
-    method public long applyAsLong(T);
-  }
-
-  @java.lang.FunctionalInterface public interface UnaryOperator<T> extends java.util.function.Function<T,T> {
-    method public static <T> java.util.function.UnaryOperator<T> identity();
-  }
-
-}
-
-package java.util.jar {
-
-  public class Attributes implements java.lang.Cloneable java.util.Map<java.lang.Object,java.lang.Object> {
-    ctor public Attributes();
-    ctor public Attributes(int);
-    ctor public Attributes(java.util.jar.Attributes);
-    method public void clear();
-    method public Object clone();
-    method public boolean containsKey(Object);
-    method public boolean containsValue(Object);
-    method public java.util.Set<java.util.Map.Entry<java.lang.Object,java.lang.Object>> entrySet();
-    method public Object get(Object);
-    method public String getValue(String);
-    method public String getValue(java.util.jar.Attributes.Name);
-    method public boolean isEmpty();
-    method public java.util.Set<java.lang.Object> keySet();
-    method public Object put(Object, Object);
-    method public void putAll(java.util.Map<?,?>);
-    method public String putValue(String, String);
-    method public Object remove(Object);
-    method public int size();
-    method public java.util.Collection<java.lang.Object> values();
-    field protected java.util.Map<java.lang.Object,java.lang.Object> map;
-  }
-
-  public static class Attributes.Name {
-    ctor public Attributes.Name(String);
-    field public static final java.util.jar.Attributes.Name CLASS_PATH;
-    field public static final java.util.jar.Attributes.Name CONTENT_TYPE;
-    field @Deprecated public static final java.util.jar.Attributes.Name EXTENSION_INSTALLATION;
-    field public static final java.util.jar.Attributes.Name EXTENSION_LIST;
-    field public static final java.util.jar.Attributes.Name EXTENSION_NAME;
-    field public static final java.util.jar.Attributes.Name IMPLEMENTATION_TITLE;
-    field @Deprecated public static final java.util.jar.Attributes.Name IMPLEMENTATION_URL;
-    field public static final java.util.jar.Attributes.Name IMPLEMENTATION_VENDOR;
-    field @Deprecated public static final java.util.jar.Attributes.Name IMPLEMENTATION_VENDOR_ID;
-    field public static final java.util.jar.Attributes.Name IMPLEMENTATION_VERSION;
-    field public static final java.util.jar.Attributes.Name MAIN_CLASS;
-    field public static final java.util.jar.Attributes.Name MANIFEST_VERSION;
-    field public static final java.util.jar.Attributes.Name SEALED;
-    field public static final java.util.jar.Attributes.Name SIGNATURE_VERSION;
-    field public static final java.util.jar.Attributes.Name SPECIFICATION_TITLE;
-    field public static final java.util.jar.Attributes.Name SPECIFICATION_VENDOR;
-    field public static final java.util.jar.Attributes.Name SPECIFICATION_VERSION;
-  }
-
-  public class JarEntry extends java.util.zip.ZipEntry {
-    ctor public JarEntry(String);
-    ctor public JarEntry(java.util.zip.ZipEntry);
-    ctor public JarEntry(java.util.jar.JarEntry);
-    method public java.util.jar.Attributes getAttributes() throws java.io.IOException;
-    method public java.security.cert.Certificate[] getCertificates();
-    method public java.security.CodeSigner[] getCodeSigners();
-    field public static final int CENATT = 36; // 0x24
-    field public static final int CENATX = 38; // 0x26
-    field public static final int CENCOM = 32; // 0x20
-    field public static final int CENCRC = 16; // 0x10
-    field public static final int CENDSK = 34; // 0x22
-    field public static final int CENEXT = 30; // 0x1e
-    field public static final int CENFLG = 8; // 0x8
-    field public static final int CENHDR = 46; // 0x2e
-    field public static final int CENHOW = 10; // 0xa
-    field public static final int CENLEN = 24; // 0x18
-    field public static final int CENNAM = 28; // 0x1c
-    field public static final int CENOFF = 42; // 0x2a
-    field public static final long CENSIG = 33639248L; // 0x2014b50L
-    field public static final int CENSIZ = 20; // 0x14
-    field public static final int CENTIM = 12; // 0xc
-    field public static final int CENVEM = 4; // 0x4
-    field public static final int CENVER = 6; // 0x6
-    field public static final int ENDCOM = 20; // 0x14
-    field public static final int ENDHDR = 22; // 0x16
-    field public static final int ENDOFF = 16; // 0x10
-    field public static final long ENDSIG = 101010256L; // 0x6054b50L
-    field public static final int ENDSIZ = 12; // 0xc
-    field public static final int ENDSUB = 8; // 0x8
-    field public static final int ENDTOT = 10; // 0xa
-    field public static final int EXTCRC = 4; // 0x4
-    field public static final int EXTHDR = 16; // 0x10
-    field public static final int EXTLEN = 12; // 0xc
-    field public static final long EXTSIG = 134695760L; // 0x8074b50L
-    field public static final int EXTSIZ = 8; // 0x8
-    field public static final int LOCCRC = 14; // 0xe
-    field public static final int LOCEXT = 28; // 0x1c
-    field public static final int LOCFLG = 6; // 0x6
-    field public static final int LOCHDR = 30; // 0x1e
-    field public static final int LOCHOW = 8; // 0x8
-    field public static final int LOCLEN = 22; // 0x16
-    field public static final int LOCNAM = 26; // 0x1a
-    field public static final long LOCSIG = 67324752L; // 0x4034b50L
-    field public static final int LOCSIZ = 18; // 0x12
-    field public static final int LOCTIM = 10; // 0xa
-    field public static final int LOCVER = 4; // 0x4
-  }
-
-  public class JarException extends java.util.zip.ZipException {
-    ctor public JarException();
-    ctor public JarException(String);
-  }
-
-  public class JarFile extends java.util.zip.ZipFile {
-    ctor public JarFile(String) throws java.io.IOException;
-    ctor public JarFile(String, boolean) throws java.io.IOException;
-    ctor public JarFile(java.io.File) throws java.io.IOException;
-    ctor public JarFile(java.io.File, boolean) throws java.io.IOException;
-    ctor public JarFile(java.io.File, boolean, int) throws java.io.IOException;
-    method public java.util.Enumeration<java.util.jar.JarEntry> entries();
-    method public java.util.jar.JarEntry getJarEntry(String);
-    method public java.util.jar.Manifest getManifest() throws java.io.IOException;
-    method public java.util.stream.Stream<java.util.jar.JarEntry> stream();
-    field public static final int CENATT = 36; // 0x24
-    field public static final int CENATX = 38; // 0x26
-    field public static final int CENCOM = 32; // 0x20
-    field public static final int CENCRC = 16; // 0x10
-    field public static final int CENDSK = 34; // 0x22
-    field public static final int CENEXT = 30; // 0x1e
-    field public static final int CENFLG = 8; // 0x8
-    field public static final int CENHDR = 46; // 0x2e
-    field public static final int CENHOW = 10; // 0xa
-    field public static final int CENLEN = 24; // 0x18
-    field public static final int CENNAM = 28; // 0x1c
-    field public static final int CENOFF = 42; // 0x2a
-    field public static final long CENSIG = 33639248L; // 0x2014b50L
-    field public static final int CENSIZ = 20; // 0x14
-    field public static final int CENTIM = 12; // 0xc
-    field public static final int CENVEM = 4; // 0x4
-    field public static final int CENVER = 6; // 0x6
-    field public static final int ENDCOM = 20; // 0x14
-    field public static final int ENDHDR = 22; // 0x16
-    field public static final int ENDOFF = 16; // 0x10
-    field public static final long ENDSIG = 101010256L; // 0x6054b50L
-    field public static final int ENDSIZ = 12; // 0xc
-    field public static final int ENDSUB = 8; // 0x8
-    field public static final int ENDTOT = 10; // 0xa
-    field public static final int EXTCRC = 4; // 0x4
-    field public static final int EXTHDR = 16; // 0x10
-    field public static final int EXTLEN = 12; // 0xc
-    field public static final long EXTSIG = 134695760L; // 0x8074b50L
-    field public static final int EXTSIZ = 8; // 0x8
-    field public static final int LOCCRC = 14; // 0xe
-    field public static final int LOCEXT = 28; // 0x1c
-    field public static final int LOCFLG = 6; // 0x6
-    field public static final int LOCHDR = 30; // 0x1e
-    field public static final int LOCHOW = 8; // 0x8
-    field public static final int LOCLEN = 22; // 0x16
-    field public static final int LOCNAM = 26; // 0x1a
-    field public static final long LOCSIG = 67324752L; // 0x4034b50L
-    field public static final int LOCSIZ = 18; // 0x12
-    field public static final int LOCTIM = 10; // 0xa
-    field public static final int LOCVER = 4; // 0x4
-    field public static final String MANIFEST_NAME = "META-INF/MANIFEST.MF";
-  }
-
-  public class JarInputStream extends java.util.zip.ZipInputStream {
-    ctor public JarInputStream(java.io.InputStream) throws java.io.IOException;
-    ctor public JarInputStream(java.io.InputStream, boolean) throws java.io.IOException;
-    method public java.util.jar.Manifest getManifest();
-    method public java.util.jar.JarEntry getNextJarEntry() throws java.io.IOException;
-    field public static final int CENATT = 36; // 0x24
-    field public static final int CENATX = 38; // 0x26
-    field public static final int CENCOM = 32; // 0x20
-    field public static final int CENCRC = 16; // 0x10
-    field public static final int CENDSK = 34; // 0x22
-    field public static final int CENEXT = 30; // 0x1e
-    field public static final int CENFLG = 8; // 0x8
-    field public static final int CENHDR = 46; // 0x2e
-    field public static final int CENHOW = 10; // 0xa
-    field public static final int CENLEN = 24; // 0x18
-    field public static final int CENNAM = 28; // 0x1c
-    field public static final int CENOFF = 42; // 0x2a
-    field public static final long CENSIG = 33639248L; // 0x2014b50L
-    field public static final int CENSIZ = 20; // 0x14
-    field public static final int CENTIM = 12; // 0xc
-    field public static final int CENVEM = 4; // 0x4
-    field public static final int CENVER = 6; // 0x6
-    field public static final int ENDCOM = 20; // 0x14
-    field public static final int ENDHDR = 22; // 0x16
-    field public static final int ENDOFF = 16; // 0x10
-    field public static final long ENDSIG = 101010256L; // 0x6054b50L
-    field public static final int ENDSIZ = 12; // 0xc
-    field public static final int ENDSUB = 8; // 0x8
-    field public static final int ENDTOT = 10; // 0xa
-    field public static final int EXTCRC = 4; // 0x4
-    field public static final int EXTHDR = 16; // 0x10
-    field public static final int EXTLEN = 12; // 0xc
-    field public static final long EXTSIG = 134695760L; // 0x8074b50L
-    field public static final int EXTSIZ = 8; // 0x8
-    field public static final int LOCCRC = 14; // 0xe
-    field public static final int LOCEXT = 28; // 0x1c
-    field public static final int LOCFLG = 6; // 0x6
-    field public static final int LOCHDR = 30; // 0x1e
-    field public static final int LOCHOW = 8; // 0x8
-    field public static final int LOCLEN = 22; // 0x16
-    field public static final int LOCNAM = 26; // 0x1a
-    field public static final long LOCSIG = 67324752L; // 0x4034b50L
-    field public static final int LOCSIZ = 18; // 0x12
-    field public static final int LOCTIM = 10; // 0xa
-    field public static final int LOCVER = 4; // 0x4
-  }
-
-  public class JarOutputStream extends java.util.zip.ZipOutputStream {
-    ctor public JarOutputStream(java.io.OutputStream, java.util.jar.Manifest) throws java.io.IOException;
-    ctor public JarOutputStream(java.io.OutputStream) throws java.io.IOException;
-    field public static final int CENATT = 36; // 0x24
-    field public static final int CENATX = 38; // 0x26
-    field public static final int CENCOM = 32; // 0x20
-    field public static final int CENCRC = 16; // 0x10
-    field public static final int CENDSK = 34; // 0x22
-    field public static final int CENEXT = 30; // 0x1e
-    field public static final int CENFLG = 8; // 0x8
-    field public static final int CENHDR = 46; // 0x2e
-    field public static final int CENHOW = 10; // 0xa
-    field public static final int CENLEN = 24; // 0x18
-    field public static final int CENNAM = 28; // 0x1c
-    field public static final int CENOFF = 42; // 0x2a
-    field public static final long CENSIG = 33639248L; // 0x2014b50L
-    field public static final int CENSIZ = 20; // 0x14
-    field public static final int CENTIM = 12; // 0xc
-    field public static final int CENVEM = 4; // 0x4
-    field public static final int CENVER = 6; // 0x6
-    field public static final int ENDCOM = 20; // 0x14
-    field public static final int ENDHDR = 22; // 0x16
-    field public static final int ENDOFF = 16; // 0x10
-    field public static final long ENDSIG = 101010256L; // 0x6054b50L
-    field public static final int ENDSIZ = 12; // 0xc
-    field public static final int ENDSUB = 8; // 0x8
-    field public static final int ENDTOT = 10; // 0xa
-    field public static final int EXTCRC = 4; // 0x4
-    field public static final int EXTHDR = 16; // 0x10
-    field public static final int EXTLEN = 12; // 0xc
-    field public static final long EXTSIG = 134695760L; // 0x8074b50L
-    field public static final int EXTSIZ = 8; // 0x8
-    field public static final int LOCCRC = 14; // 0xe
-    field public static final int LOCEXT = 28; // 0x1c
-    field public static final int LOCFLG = 6; // 0x6
-    field public static final int LOCHDR = 30; // 0x1e
-    field public static final int LOCHOW = 8; // 0x8
-    field public static final int LOCLEN = 22; // 0x16
-    field public static final int LOCNAM = 26; // 0x1a
-    field public static final long LOCSIG = 67324752L; // 0x4034b50L
-    field public static final int LOCSIZ = 18; // 0x12
-    field public static final int LOCTIM = 10; // 0xa
-    field public static final int LOCVER = 4; // 0x4
-  }
-
-  public class Manifest implements java.lang.Cloneable {
-    ctor public Manifest();
-    ctor public Manifest(java.io.InputStream) throws java.io.IOException;
-    ctor public Manifest(java.util.jar.Manifest);
-    method public void clear();
-    method public Object clone();
-    method public java.util.jar.Attributes getAttributes(String);
-    method public java.util.Map<java.lang.String,java.util.jar.Attributes> getEntries();
-    method public java.util.jar.Attributes getMainAttributes();
-    method public void read(java.io.InputStream) throws java.io.IOException;
-    method public void write(java.io.OutputStream) throws java.io.IOException;
-  }
-
-  public abstract class Pack200 {
-    method public static java.util.jar.Pack200.Packer newPacker();
-    method public static java.util.jar.Pack200.Unpacker newUnpacker();
-  }
-
-  public static interface Pack200.Packer {
-    method @Deprecated public default void addPropertyChangeListener(java.beans.PropertyChangeListener);
-    method public void pack(java.util.jar.JarFile, java.io.OutputStream) throws java.io.IOException;
-    method public void pack(java.util.jar.JarInputStream, java.io.OutputStream) throws java.io.IOException;
-    method public java.util.SortedMap<java.lang.String,java.lang.String> properties();
-    method @Deprecated public default void removePropertyChangeListener(java.beans.PropertyChangeListener);
-    field public static final String CLASS_ATTRIBUTE_PFX = "pack.class.attribute.";
-    field public static final String CODE_ATTRIBUTE_PFX = "pack.code.attribute.";
-    field public static final String DEFLATE_HINT = "pack.deflate.hint";
-    field public static final String EFFORT = "pack.effort";
-    field public static final String ERROR = "error";
-    field public static final String FALSE = "false";
-    field public static final String FIELD_ATTRIBUTE_PFX = "pack.field.attribute.";
-    field public static final String KEEP = "keep";
-    field public static final String KEEP_FILE_ORDER = "pack.keep.file.order";
-    field public static final String LATEST = "latest";
-    field public static final String METHOD_ATTRIBUTE_PFX = "pack.method.attribute.";
-    field public static final String MODIFICATION_TIME = "pack.modification.time";
-    field public static final String PASS = "pass";
-    field public static final String PASS_FILE_PFX = "pack.pass.file.";
-    field public static final String PROGRESS = "pack.progress";
-    field public static final String SEGMENT_LIMIT = "pack.segment.limit";
-    field public static final String STRIP = "strip";
-    field public static final String TRUE = "true";
-    field public static final String UNKNOWN_ATTRIBUTE = "pack.unknown.attribute";
-  }
-
-  public static interface Pack200.Unpacker {
-    method @Deprecated public default void addPropertyChangeListener(java.beans.PropertyChangeListener);
-    method public java.util.SortedMap<java.lang.String,java.lang.String> properties();
-    method @Deprecated public default void removePropertyChangeListener(java.beans.PropertyChangeListener);
-    method public void unpack(java.io.InputStream, java.util.jar.JarOutputStream) throws java.io.IOException;
-    method public void unpack(java.io.File, java.util.jar.JarOutputStream) throws java.io.IOException;
-    field public static final String DEFLATE_HINT = "unpack.deflate.hint";
-    field public static final String FALSE = "false";
-    field public static final String KEEP = "keep";
-    field public static final String PROGRESS = "unpack.progress";
-    field public static final String TRUE = "true";
-  }
-
-}
-
-package java.util.logging {
-
-  public class ConsoleHandler extends java.util.logging.StreamHandler {
-    ctor public ConsoleHandler();
-    method public void close();
-  }
-
-  public class ErrorManager {
-    ctor public ErrorManager();
-    method public void error(String, Exception, int);
-    field public static final int CLOSE_FAILURE = 3; // 0x3
-    field public static final int FLUSH_FAILURE = 2; // 0x2
-    field public static final int FORMAT_FAILURE = 5; // 0x5
-    field public static final int GENERIC_FAILURE = 0; // 0x0
-    field public static final int OPEN_FAILURE = 4; // 0x4
-    field public static final int WRITE_FAILURE = 1; // 0x1
-  }
-
-  public class FileHandler extends java.util.logging.StreamHandler {
-    ctor public FileHandler() throws java.io.IOException, java.lang.SecurityException;
-    ctor public FileHandler(String) throws java.io.IOException, java.lang.SecurityException;
-    ctor public FileHandler(String, boolean) throws java.io.IOException, java.lang.SecurityException;
-    ctor public FileHandler(String, int, int) throws java.io.IOException, java.lang.SecurityException;
-    ctor public FileHandler(String, int, int, boolean) throws java.io.IOException, java.lang.SecurityException;
-  }
-
-  @java.lang.FunctionalInterface public interface Filter {
-    method public boolean isLoggable(java.util.logging.LogRecord);
-  }
-
-  public abstract class Formatter {
-    ctor protected Formatter();
-    method public abstract String format(java.util.logging.LogRecord);
-    method public String formatMessage(java.util.logging.LogRecord);
-    method public String getHead(java.util.logging.Handler);
-    method public String getTail(java.util.logging.Handler);
-  }
-
-  public abstract class Handler {
-    ctor protected Handler();
-    method public abstract void close() throws java.lang.SecurityException;
-    method public abstract void flush();
-    method public String getEncoding();
-    method public java.util.logging.ErrorManager getErrorManager();
-    method public java.util.logging.Filter getFilter();
-    method public java.util.logging.Formatter getFormatter();
-    method public java.util.logging.Level getLevel();
-    method public boolean isLoggable(java.util.logging.LogRecord);
-    method public abstract void publish(java.util.logging.LogRecord);
-    method protected void reportError(String, Exception, int);
-    method public void setEncoding(String) throws java.lang.SecurityException, java.io.UnsupportedEncodingException;
-    method public void setErrorManager(java.util.logging.ErrorManager);
-    method public void setFilter(java.util.logging.Filter) throws java.lang.SecurityException;
-    method public void setFormatter(java.util.logging.Formatter) throws java.lang.SecurityException;
-    method public void setLevel(java.util.logging.Level) throws java.lang.SecurityException;
-  }
-
-  public class Level implements java.io.Serializable {
-    ctor protected Level(@NonNull String, int);
-    ctor protected Level(@NonNull String, int, @Nullable String);
-    method @NonNull public String getLocalizedName();
-    method @NonNull public String getName();
-    method @Nullable public String getResourceBundleName();
-    method public final int intValue();
-    method @NonNull public static java.util.logging.Level parse(@NonNull String) throws java.lang.IllegalArgumentException;
-    method @NonNull public final String toString();
-    field @NonNull public static final java.util.logging.Level ALL;
-    field @NonNull public static final java.util.logging.Level CONFIG;
-    field @NonNull public static final java.util.logging.Level FINE;
-    field @NonNull public static final java.util.logging.Level FINER;
-    field @NonNull public static final java.util.logging.Level FINEST;
-    field @NonNull public static final java.util.logging.Level INFO;
-    field @NonNull public static final java.util.logging.Level OFF;
-    field @NonNull public static final java.util.logging.Level SEVERE;
-    field @NonNull public static final java.util.logging.Level WARNING;
-  }
-
-  public class LogManager {
-    ctor protected LogManager();
-    method public boolean addLogger(java.util.logging.Logger);
-    method @Deprecated public void addPropertyChangeListener(java.beans.PropertyChangeListener) throws java.lang.SecurityException;
-    method public void checkAccess() throws java.lang.SecurityException;
-    method public static java.util.logging.LogManager getLogManager();
-    method public java.util.logging.Logger getLogger(String);
-    method public java.util.Enumeration<java.lang.String> getLoggerNames();
-    method public static java.util.logging.LoggingMXBean getLoggingMXBean();
-    method public String getProperty(String);
-    method public void readConfiguration() throws java.io.IOException, java.lang.SecurityException;
-    method public void readConfiguration(java.io.InputStream) throws java.io.IOException, java.lang.SecurityException;
-    method @Deprecated public void removePropertyChangeListener(java.beans.PropertyChangeListener) throws java.lang.SecurityException;
-    method public void reset() throws java.lang.SecurityException;
-    field public static final String LOGGING_MXBEAN_NAME = "java.util.logging:type=Logging";
-  }
-
-  public class LogRecord implements java.io.Serializable {
-    ctor public LogRecord(java.util.logging.Level, String);
-    method public java.util.logging.Level getLevel();
-    method public String getLoggerName();
-    method public String getMessage();
-    method public long getMillis();
-    method public Object[] getParameters();
-    method public java.util.ResourceBundle getResourceBundle();
-    method public String getResourceBundleName();
-    method public long getSequenceNumber();
-    method public String getSourceClassName();
-    method public String getSourceMethodName();
-    method public int getThreadID();
-    method public Throwable getThrown();
-    method public void setLevel(java.util.logging.Level);
-    method public void setLoggerName(String);
-    method public void setMessage(String);
-    method public void setMillis(long);
-    method public void setParameters(Object[]);
-    method public void setResourceBundle(java.util.ResourceBundle);
-    method public void setResourceBundleName(String);
-    method public void setSequenceNumber(long);
-    method public void setSourceClassName(String);
-    method public void setSourceMethodName(String);
-    method public void setThreadID(int);
-    method public void setThrown(Throwable);
-  }
-
-  public class Logger {
-    ctor protected Logger(@Nullable String, @Nullable String);
-    method public void addHandler(@NonNull java.util.logging.Handler) throws java.lang.SecurityException;
-    method public void config(@Nullable String);
-    method public void config(@NonNull java.util.function.Supplier<java.lang.String>);
-    method public void entering(@Nullable String, @Nullable String);
-    method public void entering(@Nullable String, @Nullable String, @Nullable Object);
-    method public void entering(@Nullable String, @Nullable String, @Nullable Object[]);
-    method public void exiting(@Nullable String, @Nullable String);
-    method public void exiting(@Nullable String, @Nullable String, @Nullable Object);
-    method public void fine(@Nullable String);
-    method public void fine(@NonNull java.util.function.Supplier<java.lang.String>);
-    method public void finer(@Nullable String);
-    method public void finer(@NonNull java.util.function.Supplier<java.lang.String>);
-    method public void finest(@Nullable String);
-    method public void finest(@NonNull java.util.function.Supplier<java.lang.String>);
-    method @NonNull public static java.util.logging.Logger getAnonymousLogger();
-    method @NonNull public static java.util.logging.Logger getAnonymousLogger(@Nullable String);
-    method @Nullable public java.util.logging.Filter getFilter();
-    method @NonNull public static final java.util.logging.Logger getGlobal();
-    method @NonNull public java.util.logging.Handler[] getHandlers();
-    method @Nullable public java.util.logging.Level getLevel();
-    method @NonNull public static java.util.logging.Logger getLogger(@NonNull String);
-    method @NonNull public static java.util.logging.Logger getLogger(@NonNull String, @Nullable String);
-    method @Nullable public String getName();
-    method @Nullable public java.util.logging.Logger getParent();
-    method @Nullable public java.util.ResourceBundle getResourceBundle();
-    method @Nullable public String getResourceBundleName();
-    method public boolean getUseParentHandlers();
-    method public void info(@Nullable String);
-    method public void info(@NonNull java.util.function.Supplier<java.lang.String>);
-    method public boolean isLoggable(@NonNull java.util.logging.Level);
-    method public void log(@NonNull java.util.logging.LogRecord);
-    method public void log(@NonNull java.util.logging.Level, @Nullable String);
-    method public void log(@NonNull java.util.logging.Level, @NonNull java.util.function.Supplier<java.lang.String>);
-    method public void log(@NonNull java.util.logging.Level, @Nullable String, @Nullable Object);
-    method public void log(@NonNull java.util.logging.Level, @Nullable String, @Nullable Object[]);
-    method public void log(@NonNull java.util.logging.Level, @Nullable String, @Nullable Throwable);
-    method public void log(@NonNull java.util.logging.Level, @Nullable Throwable, @NonNull java.util.function.Supplier<java.lang.String>);
-    method public void logp(@NonNull java.util.logging.Level, @Nullable String, @Nullable String, @Nullable String);
-    method public void logp(@NonNull java.util.logging.Level, @Nullable String, @Nullable String, @NonNull java.util.function.Supplier<java.lang.String>);
-    method public void logp(@NonNull java.util.logging.Level, @Nullable String, @Nullable String, @Nullable String, @Nullable Object);
-    method public void logp(@NonNull java.util.logging.Level, @Nullable String, @Nullable String, @Nullable String, @Nullable Object[]);
-    method public void logp(@NonNull java.util.logging.Level, @Nullable String, @Nullable String, @Nullable String, @Nullable Throwable);
-    method public void logp(@NonNull java.util.logging.Level, @Nullable String, @Nullable String, @Nullable Throwable, @NonNull java.util.function.Supplier<java.lang.String>);
-    method @Deprecated public void logrb(@NonNull java.util.logging.Level, @Nullable String, @Nullable String, @Nullable String, @Nullable String);
-    method @Deprecated public void logrb(@NonNull java.util.logging.Level, @Nullable String, @Nullable String, @Nullable String, @Nullable String, @Nullable Object);
-    method @Deprecated public void logrb(@NonNull java.util.logging.Level, @Nullable String, @Nullable String, @Nullable String, @Nullable String, @Nullable Object[]);
-    method public void logrb(@NonNull java.util.logging.Level, @Nullable String, @Nullable String, @Nullable java.util.ResourceBundle, @Nullable String, @Nullable java.lang.Object...);
-    method @Deprecated public void logrb(@NonNull java.util.logging.Level, @Nullable String, @Nullable String, @Nullable String, @Nullable String, @Nullable Throwable);
-    method public void logrb(@NonNull java.util.logging.Level, @Nullable String, @Nullable String, @Nullable java.util.ResourceBundle, @Nullable String, @Nullable Throwable);
-    method public void removeHandler(@Nullable java.util.logging.Handler) throws java.lang.SecurityException;
-    method public void setFilter(@Nullable java.util.logging.Filter) throws java.lang.SecurityException;
-    method public void setLevel(@Nullable java.util.logging.Level) throws java.lang.SecurityException;
-    method public void setParent(@NonNull java.util.logging.Logger);
-    method public void setResourceBundle(@NonNull java.util.ResourceBundle);
-    method public void setUseParentHandlers(boolean);
-    method public void severe(@Nullable String);
-    method public void severe(@NonNull java.util.function.Supplier<java.lang.String>);
-    method public void throwing(@Nullable String, @Nullable String, @Nullable Throwable);
-    method public void warning(@Nullable String);
-    method public void warning(@NonNull java.util.function.Supplier<java.lang.String>);
-    field @NonNull public static final String GLOBAL_LOGGER_NAME = "global";
-    field @Deprecated @NonNull public static final java.util.logging.Logger global;
-  }
-
-  public interface LoggingMXBean {
-    method public String getLoggerLevel(String);
-    method public java.util.List<java.lang.String> getLoggerNames();
-    method public String getParentLoggerName(String);
-    method public void setLoggerLevel(String, String);
-  }
-
-  public final class LoggingPermission extends java.security.BasicPermission {
-    ctor public LoggingPermission(String, String) throws java.lang.IllegalArgumentException;
-  }
-
-  public class MemoryHandler extends java.util.logging.Handler {
-    ctor public MemoryHandler();
-    ctor public MemoryHandler(java.util.logging.Handler, int, java.util.logging.Level);
-    method public void close() throws java.lang.SecurityException;
-    method public void flush();
-    method public java.util.logging.Level getPushLevel();
-    method public void publish(java.util.logging.LogRecord);
-    method public void push();
-    method public void setPushLevel(java.util.logging.Level) throws java.lang.SecurityException;
-  }
-
-  public class SimpleFormatter extends java.util.logging.Formatter {
-    ctor public SimpleFormatter();
-    method public String format(java.util.logging.LogRecord);
-  }
-
-  public class SocketHandler extends java.util.logging.StreamHandler {
-    ctor public SocketHandler() throws java.io.IOException;
-    ctor public SocketHandler(String, int) throws java.io.IOException;
-  }
-
-  public class StreamHandler extends java.util.logging.Handler {
-    ctor public StreamHandler();
-    ctor public StreamHandler(java.io.OutputStream, java.util.logging.Formatter);
-    method public void close() throws java.lang.SecurityException;
-    method public void flush();
-    method public void publish(java.util.logging.LogRecord);
-    method protected void setOutputStream(java.io.OutputStream) throws java.lang.SecurityException;
-  }
-
-  public class XMLFormatter extends java.util.logging.Formatter {
-    ctor public XMLFormatter();
-    method public String format(java.util.logging.LogRecord);
-  }
-
-}
-
-package java.util.prefs {
-
-  public abstract class AbstractPreferences extends java.util.prefs.Preferences {
-    ctor protected AbstractPreferences(java.util.prefs.AbstractPreferences, String);
-    method public String absolutePath();
-    method public void addNodeChangeListener(java.util.prefs.NodeChangeListener);
-    method public void addPreferenceChangeListener(java.util.prefs.PreferenceChangeListener);
-    method protected final java.util.prefs.AbstractPreferences[] cachedChildren();
-    method protected abstract java.util.prefs.AbstractPreferences childSpi(String);
-    method public String[] childrenNames() throws java.util.prefs.BackingStoreException;
-    method protected abstract String[] childrenNamesSpi() throws java.util.prefs.BackingStoreException;
-    method public void clear() throws java.util.prefs.BackingStoreException;
-    method public void exportNode(java.io.OutputStream) throws java.util.prefs.BackingStoreException, java.io.IOException;
-    method public void exportSubtree(java.io.OutputStream) throws java.util.prefs.BackingStoreException, java.io.IOException;
-    method public void flush() throws java.util.prefs.BackingStoreException;
-    method protected abstract void flushSpi() throws java.util.prefs.BackingStoreException;
-    method public String get(String, String);
-    method public boolean getBoolean(String, boolean);
-    method public byte[] getByteArray(String, byte[]);
-    method protected java.util.prefs.AbstractPreferences getChild(String) throws java.util.prefs.BackingStoreException;
-    method public double getDouble(String, double);
-    method public float getFloat(String, float);
-    method public int getInt(String, int);
-    method public long getLong(String, long);
-    method protected abstract String getSpi(String);
-    method protected boolean isRemoved();
-    method public boolean isUserNode();
-    method public String[] keys() throws java.util.prefs.BackingStoreException;
-    method protected abstract String[] keysSpi() throws java.util.prefs.BackingStoreException;
-    method public String name();
-    method public java.util.prefs.Preferences node(String);
-    method public boolean nodeExists(String) throws java.util.prefs.BackingStoreException;
-    method public java.util.prefs.Preferences parent();
-    method public void put(String, String);
-    method public void putBoolean(String, boolean);
-    method public void putByteArray(String, byte[]);
-    method public void putDouble(String, double);
-    method public void putFloat(String, float);
-    method public void putInt(String, int);
-    method public void putLong(String, long);
-    method protected abstract void putSpi(String, String);
-    method public void remove(String);
-    method public void removeNode() throws java.util.prefs.BackingStoreException;
-    method public void removeNodeChangeListener(java.util.prefs.NodeChangeListener);
-    method protected abstract void removeNodeSpi() throws java.util.prefs.BackingStoreException;
-    method public void removePreferenceChangeListener(java.util.prefs.PreferenceChangeListener);
-    method protected abstract void removeSpi(String);
-    method public void sync() throws java.util.prefs.BackingStoreException;
-    method protected abstract void syncSpi() throws java.util.prefs.BackingStoreException;
-    field protected final Object lock;
-    field protected boolean newNode;
-  }
-
-  public class BackingStoreException extends java.lang.Exception {
-    ctor public BackingStoreException(String);
-    ctor public BackingStoreException(Throwable);
-  }
-
-  public class InvalidPreferencesFormatException extends java.lang.Exception {
-    ctor public InvalidPreferencesFormatException(Throwable);
-    ctor public InvalidPreferencesFormatException(String);
-    ctor public InvalidPreferencesFormatException(String, Throwable);
-  }
-
-  public class NodeChangeEvent extends java.util.EventObject {
-    ctor public NodeChangeEvent(java.util.prefs.Preferences, java.util.prefs.Preferences);
-    method public java.util.prefs.Preferences getChild();
-    method public java.util.prefs.Preferences getParent();
-  }
-
-  public interface NodeChangeListener extends java.util.EventListener {
-    method public void childAdded(java.util.prefs.NodeChangeEvent);
-    method public void childRemoved(java.util.prefs.NodeChangeEvent);
-  }
-
-  public class PreferenceChangeEvent extends java.util.EventObject {
-    ctor public PreferenceChangeEvent(java.util.prefs.Preferences, String, String);
-    method public String getKey();
-    method public String getNewValue();
-    method public java.util.prefs.Preferences getNode();
-  }
-
-  @java.lang.FunctionalInterface public interface PreferenceChangeListener extends java.util.EventListener {
-    method public void preferenceChange(java.util.prefs.PreferenceChangeEvent);
-  }
-
-  public abstract class Preferences {
-    ctor protected Preferences();
-    method public abstract String absolutePath();
-    method public abstract void addNodeChangeListener(java.util.prefs.NodeChangeListener);
-    method public abstract void addPreferenceChangeListener(java.util.prefs.PreferenceChangeListener);
-    method public abstract String[] childrenNames() throws java.util.prefs.BackingStoreException;
-    method public abstract void clear() throws java.util.prefs.BackingStoreException;
-    method public abstract void exportNode(java.io.OutputStream) throws java.util.prefs.BackingStoreException, java.io.IOException;
-    method public abstract void exportSubtree(java.io.OutputStream) throws java.util.prefs.BackingStoreException, java.io.IOException;
-    method public abstract void flush() throws java.util.prefs.BackingStoreException;
-    method public abstract String get(String, String);
-    method public abstract boolean getBoolean(String, boolean);
-    method public abstract byte[] getByteArray(String, byte[]);
-    method public abstract double getDouble(String, double);
-    method public abstract float getFloat(String, float);
-    method public abstract int getInt(String, int);
-    method public abstract long getLong(String, long);
-    method public static void importPreferences(java.io.InputStream) throws java.io.IOException, java.util.prefs.InvalidPreferencesFormatException;
-    method public abstract boolean isUserNode();
-    method public abstract String[] keys() throws java.util.prefs.BackingStoreException;
-    method public abstract String name();
-    method public abstract java.util.prefs.Preferences node(String);
-    method public abstract boolean nodeExists(String) throws java.util.prefs.BackingStoreException;
-    method public abstract java.util.prefs.Preferences parent();
-    method public abstract void put(String, String);
-    method public abstract void putBoolean(String, boolean);
-    method public abstract void putByteArray(String, byte[]);
-    method public abstract void putDouble(String, double);
-    method public abstract void putFloat(String, float);
-    method public abstract void putInt(String, int);
-    method public abstract void putLong(String, long);
-    method public abstract void remove(String);
-    method public abstract void removeNode() throws java.util.prefs.BackingStoreException;
-    method public abstract void removeNodeChangeListener(java.util.prefs.NodeChangeListener);
-    method public abstract void removePreferenceChangeListener(java.util.prefs.PreferenceChangeListener);
-    method public abstract void sync() throws java.util.prefs.BackingStoreException;
-    method public static java.util.prefs.Preferences systemNodeForPackage(Class<?>);
-    method public static java.util.prefs.Preferences systemRoot();
-    method public abstract String toString();
-    method public static java.util.prefs.Preferences userNodeForPackage(Class<?>);
-    method public static java.util.prefs.Preferences userRoot();
-    field public static final int MAX_KEY_LENGTH = 80; // 0x50
-    field public static final int MAX_NAME_LENGTH = 80; // 0x50
-    field public static final int MAX_VALUE_LENGTH = 8192; // 0x2000
-  }
-
-  public interface PreferencesFactory {
-    method public java.util.prefs.Preferences systemRoot();
-    method public java.util.prefs.Preferences userRoot();
-  }
-
-}
-
-package java.util.regex {
-
-  public interface MatchResult {
-    method public int end();
-    method public int end(int);
-    method public String group();
-    method public String group(int);
-    method public int groupCount();
-    method public int start();
-    method public int start(int);
-  }
-
-  public final class Matcher implements java.util.regex.MatchResult {
-    method @NonNull public java.util.regex.Matcher appendReplacement(@NonNull StringBuffer, @NonNull String);
-    method @NonNull public StringBuffer appendTail(@NonNull StringBuffer);
-    method public int end();
-    method public int end(int);
-    method public int end(@NonNull String);
-    method public boolean find();
-    method public boolean find(int);
-    method @NonNull public String group();
-    method @Nullable public String group(int);
-    method @Nullable public String group(@NonNull String);
-    method public int groupCount();
-    method public boolean hasAnchoringBounds();
-    method public boolean hasTransparentBounds();
-    method public boolean hitEnd();
-    method public boolean lookingAt();
-    method public boolean matches();
-    method @NonNull public java.util.regex.Pattern pattern();
-    method @NonNull public static String quoteReplacement(@NonNull String);
-    method @NonNull public java.util.regex.Matcher region(int, int);
-    method public int regionEnd();
-    method public int regionStart();
-    method @NonNull public String replaceAll(@NonNull String);
-    method @NonNull public String replaceFirst(@NonNull String);
-    method public boolean requireEnd();
-    method @NonNull public java.util.regex.Matcher reset();
-    method @NonNull public java.util.regex.Matcher reset(@NonNull CharSequence);
-    method public int start();
-    method public int start(int);
-    method public int start(@NonNull String);
-    method @NonNull public java.util.regex.MatchResult toMatchResult();
-    method @NonNull public java.util.regex.Matcher useAnchoringBounds(boolean);
-    method @NonNull public java.util.regex.Matcher usePattern(@NonNull java.util.regex.Pattern);
-    method @NonNull public java.util.regex.Matcher useTransparentBounds(boolean);
-  }
-
-  public final class Pattern implements java.io.Serializable {
-    method @NonNull public java.util.function.Predicate<java.lang.String> asPredicate();
-    method @NonNull public static java.util.regex.Pattern compile(@NonNull String);
-    method @NonNull public static java.util.regex.Pattern compile(@NonNull String, int);
-    method public int flags();
-    method @NonNull public java.util.regex.Matcher matcher(@NonNull CharSequence);
-    method public static boolean matches(@NonNull String, @NonNull CharSequence);
-    method @NonNull public String pattern();
-    method @NonNull public static String quote(@NonNull String);
-    method @NonNull public String[] split(@NonNull CharSequence, int);
-    method @NonNull public String[] split(@NonNull CharSequence);
-    method @NonNull public java.util.stream.Stream<java.lang.String> splitAsStream(@NonNull CharSequence);
-    field public static final int CANON_EQ = 128; // 0x80
-    field public static final int CASE_INSENSITIVE = 2; // 0x2
-    field public static final int COMMENTS = 4; // 0x4
-    field public static final int DOTALL = 32; // 0x20
-    field public static final int LITERAL = 16; // 0x10
-    field public static final int MULTILINE = 8; // 0x8
-    field public static final int UNICODE_CASE = 64; // 0x40
-    field public static final int UNICODE_CHARACTER_CLASS = 256; // 0x100
-    field public static final int UNIX_LINES = 1; // 0x1
-  }
-
-  public class PatternSyntaxException extends java.lang.IllegalArgumentException {
-    ctor public PatternSyntaxException(String, String, int);
-    method public String getDescription();
-    method public int getIndex();
-    method public String getPattern();
-  }
-
-}
-
-package java.util.stream {
-
-  public interface BaseStream<T, S extends java.util.stream.BaseStream<T, S>> extends java.lang.AutoCloseable {
-    method public void close();
-    method public boolean isParallel();
-    method public java.util.Iterator<T> iterator();
-    method public S onClose(Runnable);
-    method public S parallel();
-    method public S sequential();
-    method public java.util.Spliterator<T> spliterator();
-    method public S unordered();
-  }
-
-  public interface Collector<T, A, R> {
-    method public java.util.function.BiConsumer<A,T> accumulator();
-    method public java.util.Set<java.util.stream.Collector.Characteristics> characteristics();
-    method public java.util.function.BinaryOperator<A> combiner();
-    method public java.util.function.Function<A,R> finisher();
-    method public static <T, R> java.util.stream.Collector<T,R,R> of(java.util.function.Supplier<R>, java.util.function.BiConsumer<R,T>, java.util.function.BinaryOperator<R>, java.util.stream.Collector.Characteristics...);
-    method public static <T, A, R> java.util.stream.Collector<T,A,R> of(java.util.function.Supplier<A>, java.util.function.BiConsumer<A,T>, java.util.function.BinaryOperator<A>, java.util.function.Function<A,R>, java.util.stream.Collector.Characteristics...);
-    method public java.util.function.Supplier<A> supplier();
-  }
-
-  public enum Collector.Characteristics {
-    enum_constant public static final java.util.stream.Collector.Characteristics CONCURRENT;
-    enum_constant public static final java.util.stream.Collector.Characteristics IDENTITY_FINISH;
-    enum_constant public static final java.util.stream.Collector.Characteristics UNORDERED;
-  }
-
-  public final class Collectors {
-    method public static <T> java.util.stream.Collector<T,?,java.lang.Double> averagingDouble(java.util.function.ToDoubleFunction<? super T>);
-    method public static <T> java.util.stream.Collector<T,?,java.lang.Double> averagingInt(java.util.function.ToIntFunction<? super T>);
-    method public static <T> java.util.stream.Collector<T,?,java.lang.Double> averagingLong(java.util.function.ToLongFunction<? super T>);
-    method public static <T, A, R, RR> java.util.stream.Collector<T,A,RR> collectingAndThen(java.util.stream.Collector<T,A,R>, java.util.function.Function<R,RR>);
-    method public static <T> java.util.stream.Collector<T,?,java.lang.Long> counting();
-    method public static <T, K> java.util.stream.Collector<T,?,java.util.Map<K,java.util.List<T>>> groupingBy(java.util.function.Function<? super T,? extends K>);
-    method public static <T, K, A, D> java.util.stream.Collector<T,?,java.util.Map<K,D>> groupingBy(java.util.function.Function<? super T,? extends K>, java.util.stream.Collector<? super T,A,D>);
-    method public static <T, K, D, A, M extends java.util.Map<K, D>> java.util.stream.Collector<T,?,M> groupingBy(java.util.function.Function<? super T,? extends K>, java.util.function.Supplier<M>, java.util.stream.Collector<? super T,A,D>);
-    method public static <T, K> java.util.stream.Collector<T,?,java.util.concurrent.ConcurrentMap<K,java.util.List<T>>> groupingByConcurrent(java.util.function.Function<? super T,? extends K>);
-    method public static <T, K, A, D> java.util.stream.Collector<T,?,java.util.concurrent.ConcurrentMap<K,D>> groupingByConcurrent(java.util.function.Function<? super T,? extends K>, java.util.stream.Collector<? super T,A,D>);
-    method public static <T, K, A, D, M extends java.util.concurrent.ConcurrentMap<K, D>> java.util.stream.Collector<T,?,M> groupingByConcurrent(java.util.function.Function<? super T,? extends K>, java.util.function.Supplier<M>, java.util.stream.Collector<? super T,A,D>);
-    method public static java.util.stream.Collector<java.lang.CharSequence,?,java.lang.String> joining();
-    method public static java.util.stream.Collector<java.lang.CharSequence,?,java.lang.String> joining(CharSequence);
-    method public static java.util.stream.Collector<java.lang.CharSequence,?,java.lang.String> joining(CharSequence, CharSequence, CharSequence);
-    method public static <T, U, A, R> java.util.stream.Collector<T,?,R> mapping(java.util.function.Function<? super T,? extends U>, java.util.stream.Collector<? super U,A,R>);
-    method public static <T> java.util.stream.Collector<T,?,java.util.Optional<T>> maxBy(java.util.Comparator<? super T>);
-    method public static <T> java.util.stream.Collector<T,?,java.util.Optional<T>> minBy(java.util.Comparator<? super T>);
-    method public static <T> java.util.stream.Collector<T,?,java.util.Map<java.lang.Boolean,java.util.List<T>>> partitioningBy(java.util.function.Predicate<? super T>);
-    method public static <T, D, A> java.util.stream.Collector<T,?,java.util.Map<java.lang.Boolean,D>> partitioningBy(java.util.function.Predicate<? super T>, java.util.stream.Collector<? super T,A,D>);
-    method public static <T> java.util.stream.Collector<T,?,T> reducing(T, java.util.function.BinaryOperator<T>);
-    method public static <T> java.util.stream.Collector<T,?,java.util.Optional<T>> reducing(java.util.function.BinaryOperator<T>);
-    method public static <T, U> java.util.stream.Collector<T,?,U> reducing(U, java.util.function.Function<? super T,? extends U>, java.util.function.BinaryOperator<U>);
-    method public static <T> java.util.stream.Collector<T,?,java.util.DoubleSummaryStatistics> summarizingDouble(java.util.function.ToDoubleFunction<? super T>);
-    method public static <T> java.util.stream.Collector<T,?,java.util.IntSummaryStatistics> summarizingInt(java.util.function.ToIntFunction<? super T>);
-    method public static <T> java.util.stream.Collector<T,?,java.util.LongSummaryStatistics> summarizingLong(java.util.function.ToLongFunction<? super T>);
-    method public static <T> java.util.stream.Collector<T,?,java.lang.Double> summingDouble(java.util.function.ToDoubleFunction<? super T>);
-    method public static <T> java.util.stream.Collector<T,?,java.lang.Integer> summingInt(java.util.function.ToIntFunction<? super T>);
-    method public static <T> java.util.stream.Collector<T,?,java.lang.Long> summingLong(java.util.function.ToLongFunction<? super T>);
-    method public static <T, C extends java.util.Collection<T>> java.util.stream.Collector<T,?,C> toCollection(java.util.function.Supplier<C>);
-    method public static <T, K, U> java.util.stream.Collector<T,?,java.util.concurrent.ConcurrentMap<K,U>> toConcurrentMap(java.util.function.Function<? super T,? extends K>, java.util.function.Function<? super T,? extends U>);
-    method public static <T, K, U> java.util.stream.Collector<T,?,java.util.concurrent.ConcurrentMap<K,U>> toConcurrentMap(java.util.function.Function<? super T,? extends K>, java.util.function.Function<? super T,? extends U>, java.util.function.BinaryOperator<U>);
-    method public static <T, K, U, M extends java.util.concurrent.ConcurrentMap<K, U>> java.util.stream.Collector<T,?,M> toConcurrentMap(java.util.function.Function<? super T,? extends K>, java.util.function.Function<? super T,? extends U>, java.util.function.BinaryOperator<U>, java.util.function.Supplier<M>);
-    method public static <T> java.util.stream.Collector<T,?,java.util.List<T>> toList();
-    method public static <T, K, U> java.util.stream.Collector<T,?,java.util.Map<K,U>> toMap(java.util.function.Function<? super T,? extends K>, java.util.function.Function<? super T,? extends U>);
-    method public static <T, K, U> java.util.stream.Collector<T,?,java.util.Map<K,U>> toMap(java.util.function.Function<? super T,? extends K>, java.util.function.Function<? super T,? extends U>, java.util.function.BinaryOperator<U>);
-    method public static <T, K, U, M extends java.util.Map<K, U>> java.util.stream.Collector<T,?,M> toMap(java.util.function.Function<? super T,? extends K>, java.util.function.Function<? super T,? extends U>, java.util.function.BinaryOperator<U>, java.util.function.Supplier<M>);
-    method public static <T> java.util.stream.Collector<T,?,java.util.Set<T>> toSet();
-  }
-
-  public interface DoubleStream extends java.util.stream.BaseStream<java.lang.Double,java.util.stream.DoubleStream> {
-    method public boolean allMatch(java.util.function.DoublePredicate);
-    method public boolean anyMatch(java.util.function.DoublePredicate);
-    method public java.util.OptionalDouble average();
-    method public java.util.stream.Stream<java.lang.Double> boxed();
-    method public static java.util.stream.DoubleStream.Builder builder();
-    method public <R> R collect(java.util.function.Supplier<R>, java.util.function.ObjDoubleConsumer<R>, java.util.function.BiConsumer<R,R>);
-    method public static java.util.stream.DoubleStream concat(java.util.stream.DoubleStream, java.util.stream.DoubleStream);
-    method public long count();
-    method public java.util.stream.DoubleStream distinct();
-    method public static java.util.stream.DoubleStream empty();
-    method public java.util.stream.DoubleStream filter(java.util.function.DoublePredicate);
-    method public java.util.OptionalDouble findAny();
-    method public java.util.OptionalDouble findFirst();
-    method public java.util.stream.DoubleStream flatMap(java.util.function.DoubleFunction<? extends java.util.stream.DoubleStream>);
-    method public void forEach(java.util.function.DoubleConsumer);
-    method public void forEachOrdered(java.util.function.DoubleConsumer);
-    method public static java.util.stream.DoubleStream generate(java.util.function.DoubleSupplier);
-    method public static java.util.stream.DoubleStream iterate(double, java.util.function.DoubleUnaryOperator);
-    method public java.util.PrimitiveIterator.OfDouble iterator();
-    method public java.util.stream.DoubleStream limit(long);
-    method public java.util.stream.DoubleStream map(java.util.function.DoubleUnaryOperator);
-    method public java.util.stream.IntStream mapToInt(java.util.function.DoubleToIntFunction);
-    method public java.util.stream.LongStream mapToLong(java.util.function.DoubleToLongFunction);
-    method public <U> java.util.stream.Stream<U> mapToObj(java.util.function.DoubleFunction<? extends U>);
-    method public java.util.OptionalDouble max();
-    method public java.util.OptionalDouble min();
-    method public boolean noneMatch(java.util.function.DoublePredicate);
-    method public static java.util.stream.DoubleStream of(double);
-    method public static java.util.stream.DoubleStream of(double...);
-    method public java.util.stream.DoubleStream parallel();
-    method public java.util.stream.DoubleStream peek(java.util.function.DoubleConsumer);
-    method public double reduce(double, java.util.function.DoubleBinaryOperator);
-    method public java.util.OptionalDouble reduce(java.util.function.DoubleBinaryOperator);
-    method public java.util.stream.DoubleStream sequential();
-    method public java.util.stream.DoubleStream skip(long);
-    method public java.util.stream.DoubleStream sorted();
-    method public java.util.Spliterator.OfDouble spliterator();
-    method public double sum();
-    method public java.util.DoubleSummaryStatistics summaryStatistics();
-    method public double[] toArray();
-  }
-
-  public static interface DoubleStream.Builder extends java.util.function.DoubleConsumer {
-    method public default java.util.stream.DoubleStream.Builder add(double);
-    method public java.util.stream.DoubleStream build();
-  }
-
-  public interface IntStream extends java.util.stream.BaseStream<java.lang.Integer,java.util.stream.IntStream> {
-    method public boolean allMatch(java.util.function.IntPredicate);
-    method public boolean anyMatch(java.util.function.IntPredicate);
-    method public java.util.stream.DoubleStream asDoubleStream();
-    method public java.util.stream.LongStream asLongStream();
-    method public java.util.OptionalDouble average();
-    method public java.util.stream.Stream<java.lang.Integer> boxed();
-    method public static java.util.stream.IntStream.Builder builder();
-    method public <R> R collect(java.util.function.Supplier<R>, java.util.function.ObjIntConsumer<R>, java.util.function.BiConsumer<R,R>);
-    method public static java.util.stream.IntStream concat(java.util.stream.IntStream, java.util.stream.IntStream);
-    method public long count();
-    method public java.util.stream.IntStream distinct();
-    method public static java.util.stream.IntStream empty();
-    method public java.util.stream.IntStream filter(java.util.function.IntPredicate);
-    method public java.util.OptionalInt findAny();
-    method public java.util.OptionalInt findFirst();
-    method public java.util.stream.IntStream flatMap(java.util.function.IntFunction<? extends java.util.stream.IntStream>);
-    method public void forEach(java.util.function.IntConsumer);
-    method public void forEachOrdered(java.util.function.IntConsumer);
-    method public static java.util.stream.IntStream generate(java.util.function.IntSupplier);
-    method public static java.util.stream.IntStream iterate(int, java.util.function.IntUnaryOperator);
-    method public java.util.PrimitiveIterator.OfInt iterator();
-    method public java.util.stream.IntStream limit(long);
-    method public java.util.stream.IntStream map(java.util.function.IntUnaryOperator);
-    method public java.util.stream.DoubleStream mapToDouble(java.util.function.IntToDoubleFunction);
-    method public java.util.stream.LongStream mapToLong(java.util.function.IntToLongFunction);
-    method public <U> java.util.stream.Stream<U> mapToObj(java.util.function.IntFunction<? extends U>);
-    method public java.util.OptionalInt max();
-    method public java.util.OptionalInt min();
-    method public boolean noneMatch(java.util.function.IntPredicate);
-    method public static java.util.stream.IntStream of(int);
-    method public static java.util.stream.IntStream of(int...);
-    method public java.util.stream.IntStream parallel();
-    method public java.util.stream.IntStream peek(java.util.function.IntConsumer);
-    method public static java.util.stream.IntStream range(int, int);
-    method public static java.util.stream.IntStream rangeClosed(int, int);
-    method public int reduce(int, java.util.function.IntBinaryOperator);
-    method public java.util.OptionalInt reduce(java.util.function.IntBinaryOperator);
-    method public java.util.stream.IntStream sequential();
-    method public java.util.stream.IntStream skip(long);
-    method public java.util.stream.IntStream sorted();
-    method public java.util.Spliterator.OfInt spliterator();
-    method public int sum();
-    method public java.util.IntSummaryStatistics summaryStatistics();
-    method public int[] toArray();
-  }
-
-  public static interface IntStream.Builder extends java.util.function.IntConsumer {
-    method public default java.util.stream.IntStream.Builder add(int);
-    method public java.util.stream.IntStream build();
-  }
-
-  public interface LongStream extends java.util.stream.BaseStream<java.lang.Long,java.util.stream.LongStream> {
-    method public boolean allMatch(java.util.function.LongPredicate);
-    method public boolean anyMatch(java.util.function.LongPredicate);
-    method public java.util.stream.DoubleStream asDoubleStream();
-    method public java.util.OptionalDouble average();
-    method public java.util.stream.Stream<java.lang.Long> boxed();
-    method public static java.util.stream.LongStream.Builder builder();
-    method public <R> R collect(java.util.function.Supplier<R>, java.util.function.ObjLongConsumer<R>, java.util.function.BiConsumer<R,R>);
-    method public static java.util.stream.LongStream concat(java.util.stream.LongStream, java.util.stream.LongStream);
-    method public long count();
-    method public java.util.stream.LongStream distinct();
-    method public static java.util.stream.LongStream empty();
-    method public java.util.stream.LongStream filter(java.util.function.LongPredicate);
-    method public java.util.OptionalLong findAny();
-    method public java.util.OptionalLong findFirst();
-    method public java.util.stream.LongStream flatMap(java.util.function.LongFunction<? extends java.util.stream.LongStream>);
-    method public void forEach(java.util.function.LongConsumer);
-    method public void forEachOrdered(java.util.function.LongConsumer);
-    method public static java.util.stream.LongStream generate(java.util.function.LongSupplier);
-    method public static java.util.stream.LongStream iterate(long, java.util.function.LongUnaryOperator);
-    method public java.util.PrimitiveIterator.OfLong iterator();
-    method public java.util.stream.LongStream limit(long);
-    method public java.util.stream.LongStream map(java.util.function.LongUnaryOperator);
-    method public java.util.stream.DoubleStream mapToDouble(java.util.function.LongToDoubleFunction);
-    method public java.util.stream.IntStream mapToInt(java.util.function.LongToIntFunction);
-    method public <U> java.util.stream.Stream<U> mapToObj(java.util.function.LongFunction<? extends U>);
-    method public java.util.OptionalLong max();
-    method public java.util.OptionalLong min();
-    method public boolean noneMatch(java.util.function.LongPredicate);
-    method public static java.util.stream.LongStream of(long);
-    method public static java.util.stream.LongStream of(long...);
-    method public java.util.stream.LongStream parallel();
-    method public java.util.stream.LongStream peek(java.util.function.LongConsumer);
-    method public static java.util.stream.LongStream range(long, long);
-    method public static java.util.stream.LongStream rangeClosed(long, long);
-    method public long reduce(long, java.util.function.LongBinaryOperator);
-    method public java.util.OptionalLong reduce(java.util.function.LongBinaryOperator);
-    method public java.util.stream.LongStream sequential();
-    method public java.util.stream.LongStream skip(long);
-    method public java.util.stream.LongStream sorted();
-    method public java.util.Spliterator.OfLong spliterator();
-    method public long sum();
-    method public java.util.LongSummaryStatistics summaryStatistics();
-    method public long[] toArray();
-  }
-
-  public static interface LongStream.Builder extends java.util.function.LongConsumer {
-    method public default java.util.stream.LongStream.Builder add(long);
-    method public java.util.stream.LongStream build();
-  }
-
-  public interface Stream<T> extends java.util.stream.BaseStream<T,java.util.stream.Stream<T>> {
-    method public boolean allMatch(java.util.function.Predicate<? super T>);
-    method public boolean anyMatch(java.util.function.Predicate<? super T>);
-    method public static <T> java.util.stream.Stream.Builder<T> builder();
-    method public <R> R collect(java.util.function.Supplier<R>, java.util.function.BiConsumer<R,? super T>, java.util.function.BiConsumer<R,R>);
-    method public <R, A> R collect(java.util.stream.Collector<? super T,A,R>);
-    method public static <T> java.util.stream.Stream<T> concat(java.util.stream.Stream<? extends T>, java.util.stream.Stream<? extends T>);
-    method public long count();
-    method public java.util.stream.Stream<T> distinct();
-    method public static <T> java.util.stream.Stream<T> empty();
-    method public java.util.stream.Stream<T> filter(java.util.function.Predicate<? super T>);
-    method public java.util.Optional<T> findAny();
-    method public java.util.Optional<T> findFirst();
-    method public <R> java.util.stream.Stream<R> flatMap(java.util.function.Function<? super T,? extends java.util.stream.Stream<? extends R>>);
-    method public java.util.stream.DoubleStream flatMapToDouble(java.util.function.Function<? super T,? extends java.util.stream.DoubleStream>);
-    method public java.util.stream.IntStream flatMapToInt(java.util.function.Function<? super T,? extends java.util.stream.IntStream>);
-    method public java.util.stream.LongStream flatMapToLong(java.util.function.Function<? super T,? extends java.util.stream.LongStream>);
-    method public void forEach(java.util.function.Consumer<? super T>);
-    method public void forEachOrdered(java.util.function.Consumer<? super T>);
-    method public static <T> java.util.stream.Stream<T> generate(java.util.function.Supplier<T>);
-    method public static <T> java.util.stream.Stream<T> iterate(T, java.util.function.UnaryOperator<T>);
-    method public java.util.stream.Stream<T> limit(long);
-    method public <R> java.util.stream.Stream<R> map(java.util.function.Function<? super T,? extends R>);
-    method public java.util.stream.DoubleStream mapToDouble(java.util.function.ToDoubleFunction<? super T>);
-    method public java.util.stream.IntStream mapToInt(java.util.function.ToIntFunction<? super T>);
-    method public java.util.stream.LongStream mapToLong(java.util.function.ToLongFunction<? super T>);
-    method public java.util.Optional<T> max(java.util.Comparator<? super T>);
-    method public java.util.Optional<T> min(java.util.Comparator<? super T>);
-    method public boolean noneMatch(java.util.function.Predicate<? super T>);
-    method public static <T> java.util.stream.Stream<T> of(T);
-    method @java.lang.SafeVarargs public static <T> java.util.stream.Stream<T> of(T...);
-    method public java.util.stream.Stream<T> peek(java.util.function.Consumer<? super T>);
-    method public T reduce(T, java.util.function.BinaryOperator<T>);
-    method public java.util.Optional<T> reduce(java.util.function.BinaryOperator<T>);
-    method public <U> U reduce(U, java.util.function.BiFunction<U,? super T,U>, java.util.function.BinaryOperator<U>);
-    method public java.util.stream.Stream<T> skip(long);
-    method public java.util.stream.Stream<T> sorted();
-    method public java.util.stream.Stream<T> sorted(java.util.Comparator<? super T>);
-    method public Object[] toArray();
-    method public <A> A[] toArray(java.util.function.IntFunction<A[]>);
-  }
-
-  public static interface Stream.Builder<T> extends java.util.function.Consumer<T> {
-    method public default java.util.stream.Stream.Builder<T> add(T);
-    method public java.util.stream.Stream<T> build();
-  }
-
-  public final class StreamSupport {
-    method public static java.util.stream.DoubleStream doubleStream(java.util.Spliterator.OfDouble, boolean);
-    method public static java.util.stream.DoubleStream doubleStream(java.util.function.Supplier<? extends java.util.Spliterator.OfDouble>, int, boolean);
-    method public static java.util.stream.IntStream intStream(java.util.Spliterator.OfInt, boolean);
-    method public static java.util.stream.IntStream intStream(java.util.function.Supplier<? extends java.util.Spliterator.OfInt>, int, boolean);
-    method public static java.util.stream.LongStream longStream(java.util.Spliterator.OfLong, boolean);
-    method public static java.util.stream.LongStream longStream(java.util.function.Supplier<? extends java.util.Spliterator.OfLong>, int, boolean);
-    method public static <T> java.util.stream.Stream<T> stream(java.util.Spliterator<T>, boolean);
-    method public static <T> java.util.stream.Stream<T> stream(java.util.function.Supplier<? extends java.util.Spliterator<T>>, int, boolean);
-  }
-
-}
-
-package java.util.zip {
-
-  public class Adler32 implements java.util.zip.Checksum {
-    ctor public Adler32();
-    method public long getValue();
-    method public void reset();
-    method public void update(int);
-    method public void update(byte[], int, int);
-    method public void update(byte[]);
-    method public void update(java.nio.ByteBuffer);
-  }
-
-  public class CRC32 implements java.util.zip.Checksum {
-    ctor public CRC32();
-    method public long getValue();
-    method public void reset();
-    method public void update(int);
-    method public void update(byte[], int, int);
-    method public void update(byte[]);
-    method public void update(java.nio.ByteBuffer);
-  }
-
-  public class CheckedInputStream extends java.io.FilterInputStream {
-    ctor public CheckedInputStream(java.io.InputStream, java.util.zip.Checksum);
-    method public java.util.zip.Checksum getChecksum();
-  }
-
-  public class CheckedOutputStream extends java.io.FilterOutputStream {
-    ctor public CheckedOutputStream(java.io.OutputStream, java.util.zip.Checksum);
-    method public java.util.zip.Checksum getChecksum();
-  }
-
-  public interface Checksum {
-    method public long getValue();
-    method public void reset();
-    method public void update(int);
-    method public void update(byte[], int, int);
-  }
-
-  public class DataFormatException extends java.lang.Exception {
-    ctor public DataFormatException();
-    ctor public DataFormatException(String);
-  }
-
-  public class Deflater {
-    ctor public Deflater(int, boolean);
-    ctor public Deflater(int);
-    ctor public Deflater();
-    method public int deflate(byte[], int, int);
-    method public int deflate(byte[]);
-    method public int deflate(byte[], int, int, int);
-    method public void end();
-    method protected void finalize();
-    method public void finish();
-    method public boolean finished();
-    method public int getAdler();
-    method public long getBytesRead();
-    method public long getBytesWritten();
-    method public int getTotalIn();
-    method public int getTotalOut();
-    method public boolean needsInput();
-    method public void reset();
-    method public void setDictionary(byte[], int, int);
-    method public void setDictionary(byte[]);
-    method public void setInput(byte[], int, int);
-    method public void setInput(byte[]);
-    method public void setLevel(int);
-    method public void setStrategy(int);
-    field public static final int BEST_COMPRESSION = 9; // 0x9
-    field public static final int BEST_SPEED = 1; // 0x1
-    field public static final int DEFAULT_COMPRESSION = -1; // 0xffffffff
-    field public static final int DEFAULT_STRATEGY = 0; // 0x0
-    field public static final int DEFLATED = 8; // 0x8
-    field public static final int FILTERED = 1; // 0x1
-    field public static final int FULL_FLUSH = 3; // 0x3
-    field public static final int HUFFMAN_ONLY = 2; // 0x2
-    field public static final int NO_COMPRESSION = 0; // 0x0
-    field public static final int NO_FLUSH = 0; // 0x0
-    field public static final int SYNC_FLUSH = 2; // 0x2
-  }
-
-  public class DeflaterInputStream extends java.io.FilterInputStream {
-    ctor public DeflaterInputStream(java.io.InputStream);
-    ctor public DeflaterInputStream(java.io.InputStream, java.util.zip.Deflater);
-    ctor public DeflaterInputStream(java.io.InputStream, java.util.zip.Deflater, int);
-    field protected final byte[] buf;
-    field protected final java.util.zip.Deflater def;
-  }
-
-  public class DeflaterOutputStream extends java.io.FilterOutputStream {
-    ctor public DeflaterOutputStream(java.io.OutputStream, java.util.zip.Deflater, int, boolean);
-    ctor public DeflaterOutputStream(java.io.OutputStream, java.util.zip.Deflater, int);
-    ctor public DeflaterOutputStream(java.io.OutputStream, java.util.zip.Deflater, boolean);
-    ctor public DeflaterOutputStream(java.io.OutputStream, java.util.zip.Deflater);
-    ctor public DeflaterOutputStream(java.io.OutputStream, boolean);
-    ctor public DeflaterOutputStream(java.io.OutputStream);
-    method protected void deflate() throws java.io.IOException;
-    method public void finish() throws java.io.IOException;
-    field protected byte[] buf;
-    field protected java.util.zip.Deflater def;
-  }
-
-  public class GZIPInputStream extends java.util.zip.InflaterInputStream {
-    ctor public GZIPInputStream(java.io.InputStream, int) throws java.io.IOException;
-    ctor public GZIPInputStream(java.io.InputStream) throws java.io.IOException;
-    field public static final int GZIP_MAGIC = 35615; // 0x8b1f
-    field protected java.util.zip.CRC32 crc;
-    field protected boolean eos;
-  }
-
-  public class GZIPOutputStream extends java.util.zip.DeflaterOutputStream {
-    ctor public GZIPOutputStream(java.io.OutputStream, int) throws java.io.IOException;
-    ctor public GZIPOutputStream(java.io.OutputStream, int, boolean) throws java.io.IOException;
-    ctor public GZIPOutputStream(java.io.OutputStream) throws java.io.IOException;
-    ctor public GZIPOutputStream(java.io.OutputStream, boolean) throws java.io.IOException;
-    field protected java.util.zip.CRC32 crc;
-  }
-
-  public class Inflater {
-    ctor public Inflater(boolean);
-    ctor public Inflater();
-    method public void end();
-    method protected void finalize();
-    method public boolean finished();
-    method public int getAdler();
-    method public long getBytesRead();
-    method public long getBytesWritten();
-    method public int getRemaining();
-    method public int getTotalIn();
-    method public int getTotalOut();
-    method public int inflate(byte[], int, int) throws java.util.zip.DataFormatException;
-    method public int inflate(byte[]) throws java.util.zip.DataFormatException;
-    method public boolean needsDictionary();
-    method public boolean needsInput();
-    method public void reset();
-    method public void setDictionary(byte[], int, int);
-    method public void setDictionary(byte[]);
-    method public void setInput(byte[], int, int);
-    method public void setInput(byte[]);
-  }
-
-  public class InflaterInputStream extends java.io.FilterInputStream {
-    ctor public InflaterInputStream(java.io.InputStream, java.util.zip.Inflater, int);
-    ctor public InflaterInputStream(java.io.InputStream, java.util.zip.Inflater);
-    ctor public InflaterInputStream(java.io.InputStream);
-    method protected void fill() throws java.io.IOException;
-    field protected byte[] buf;
-    field @Deprecated protected boolean closed;
-    field protected java.util.zip.Inflater inf;
-    field protected int len;
-  }
-
-  public class InflaterOutputStream extends java.io.FilterOutputStream {
-    ctor public InflaterOutputStream(java.io.OutputStream);
-    ctor public InflaterOutputStream(java.io.OutputStream, java.util.zip.Inflater);
-    ctor public InflaterOutputStream(java.io.OutputStream, java.util.zip.Inflater, int);
-    method public void finish() throws java.io.IOException;
-    field protected final byte[] buf;
-    field protected final java.util.zip.Inflater inf;
-  }
-
-  public class ZipEntry implements java.lang.Cloneable {
-    ctor public ZipEntry(String);
-    ctor public ZipEntry(java.util.zip.ZipEntry);
-    method public Object clone();
-    method public String getComment();
-    method public long getCompressedSize();
-    method public long getCrc();
-    method public java.nio.file.attribute.FileTime getCreationTime();
-    method public byte[] getExtra();
-    method public java.nio.file.attribute.FileTime getLastAccessTime();
-    method public java.nio.file.attribute.FileTime getLastModifiedTime();
-    method public int getMethod();
-    method public String getName();
-    method public long getSize();
-    method public long getTime();
-    method public boolean isDirectory();
-    method public void setComment(String);
-    method public void setCompressedSize(long);
-    method public void setCrc(long);
-    method public java.util.zip.ZipEntry setCreationTime(java.nio.file.attribute.FileTime);
-    method public void setExtra(byte[]);
-    method public java.util.zip.ZipEntry setLastAccessTime(java.nio.file.attribute.FileTime);
-    method public java.util.zip.ZipEntry setLastModifiedTime(java.nio.file.attribute.FileTime);
-    method public void setMethod(int);
-    method public void setSize(long);
-    method public void setTime(long);
-    field public static final int CENATT = 36; // 0x24
-    field public static final int CENATX = 38; // 0x26
-    field public static final int CENCOM = 32; // 0x20
-    field public static final int CENCRC = 16; // 0x10
-    field public static final int CENDSK = 34; // 0x22
-    field public static final int CENEXT = 30; // 0x1e
-    field public static final int CENFLG = 8; // 0x8
-    field public static final int CENHDR = 46; // 0x2e
-    field public static final int CENHOW = 10; // 0xa
-    field public static final int CENLEN = 24; // 0x18
-    field public static final int CENNAM = 28; // 0x1c
-    field public static final int CENOFF = 42; // 0x2a
-    field public static final long CENSIG = 33639248L; // 0x2014b50L
-    field public static final int CENSIZ = 20; // 0x14
-    field public static final int CENTIM = 12; // 0xc
-    field public static final int CENVEM = 4; // 0x4
-    field public static final int CENVER = 6; // 0x6
-    field public static final int DEFLATED = 8; // 0x8
-    field public static final int ENDCOM = 20; // 0x14
-    field public static final int ENDHDR = 22; // 0x16
-    field public static final int ENDOFF = 16; // 0x10
-    field public static final long ENDSIG = 101010256L; // 0x6054b50L
-    field public static final int ENDSIZ = 12; // 0xc
-    field public static final int ENDSUB = 8; // 0x8
-    field public static final int ENDTOT = 10; // 0xa
-    field public static final int EXTCRC = 4; // 0x4
-    field public static final int EXTHDR = 16; // 0x10
-    field public static final int EXTLEN = 12; // 0xc
-    field public static final long EXTSIG = 134695760L; // 0x8074b50L
-    field public static final int EXTSIZ = 8; // 0x8
-    field public static final int LOCCRC = 14; // 0xe
-    field public static final int LOCEXT = 28; // 0x1c
-    field public static final int LOCFLG = 6; // 0x6
-    field public static final int LOCHDR = 30; // 0x1e
-    field public static final int LOCHOW = 8; // 0x8
-    field public static final int LOCLEN = 22; // 0x16
-    field public static final int LOCNAM = 26; // 0x1a
-    field public static final long LOCSIG = 67324752L; // 0x4034b50L
-    field public static final int LOCSIZ = 18; // 0x12
-    field public static final int LOCTIM = 10; // 0xa
-    field public static final int LOCVER = 4; // 0x4
-    field public static final int STORED = 0; // 0x0
-  }
-
-  public class ZipError extends java.lang.InternalError {
-    ctor public ZipError(String);
-  }
-
-  public class ZipException extends java.io.IOException {
-    ctor public ZipException();
-    ctor public ZipException(String);
-  }
-
-  public class ZipFile implements java.io.Closeable {
-    ctor public ZipFile(String) throws java.io.IOException;
-    ctor public ZipFile(java.io.File, int) throws java.io.IOException;
-    ctor public ZipFile(java.io.File) throws java.io.IOException, java.util.zip.ZipException;
-    ctor public ZipFile(java.io.File, int, java.nio.charset.Charset) throws java.io.IOException;
-    ctor public ZipFile(String, java.nio.charset.Charset) throws java.io.IOException;
-    ctor public ZipFile(java.io.File, java.nio.charset.Charset) throws java.io.IOException;
-    method public void close() throws java.io.IOException;
-    method public java.util.Enumeration<? extends java.util.zip.ZipEntry> entries();
-    method protected void finalize() throws java.io.IOException;
-    method public String getComment();
-    method public java.util.zip.ZipEntry getEntry(String);
-    method public java.io.InputStream getInputStream(java.util.zip.ZipEntry) throws java.io.IOException;
-    method public String getName();
-    method public int size();
-    method public java.util.stream.Stream<? extends java.util.zip.ZipEntry> stream();
-    field public static final int CENATT = 36; // 0x24
-    field public static final int CENATX = 38; // 0x26
-    field public static final int CENCOM = 32; // 0x20
-    field public static final int CENCRC = 16; // 0x10
-    field public static final int CENDSK = 34; // 0x22
-    field public static final int CENEXT = 30; // 0x1e
-    field public static final int CENFLG = 8; // 0x8
-    field public static final int CENHDR = 46; // 0x2e
-    field public static final int CENHOW = 10; // 0xa
-    field public static final int CENLEN = 24; // 0x18
-    field public static final int CENNAM = 28; // 0x1c
-    field public static final int CENOFF = 42; // 0x2a
-    field public static final long CENSIG = 33639248L; // 0x2014b50L
-    field public static final int CENSIZ = 20; // 0x14
-    field public static final int CENTIM = 12; // 0xc
-    field public static final int CENVEM = 4; // 0x4
-    field public static final int CENVER = 6; // 0x6
-    field public static final int ENDCOM = 20; // 0x14
-    field public static final int ENDHDR = 22; // 0x16
-    field public static final int ENDOFF = 16; // 0x10
-    field public static final long ENDSIG = 101010256L; // 0x6054b50L
-    field public static final int ENDSIZ = 12; // 0xc
-    field public static final int ENDSUB = 8; // 0x8
-    field public static final int ENDTOT = 10; // 0xa
-    field public static final int EXTCRC = 4; // 0x4
-    field public static final int EXTHDR = 16; // 0x10
-    field public static final int EXTLEN = 12; // 0xc
-    field public static final long EXTSIG = 134695760L; // 0x8074b50L
-    field public static final int EXTSIZ = 8; // 0x8
-    field public static final int LOCCRC = 14; // 0xe
-    field public static final int LOCEXT = 28; // 0x1c
-    field public static final int LOCFLG = 6; // 0x6
-    field public static final int LOCHDR = 30; // 0x1e
-    field public static final int LOCHOW = 8; // 0x8
-    field public static final int LOCLEN = 22; // 0x16
-    field public static final int LOCNAM = 26; // 0x1a
-    field public static final long LOCSIG = 67324752L; // 0x4034b50L
-    field public static final int LOCSIZ = 18; // 0x12
-    field public static final int LOCTIM = 10; // 0xa
-    field public static final int LOCVER = 4; // 0x4
-    field public static final int OPEN_DELETE = 4; // 0x4
-    field public static final int OPEN_READ = 1; // 0x1
-  }
-
-  public class ZipInputStream extends java.util.zip.InflaterInputStream {
-    ctor public ZipInputStream(java.io.InputStream);
-    ctor public ZipInputStream(java.io.InputStream, java.nio.charset.Charset);
-    method public void closeEntry() throws java.io.IOException;
-    method protected java.util.zip.ZipEntry createZipEntry(String);
-    method public java.util.zip.ZipEntry getNextEntry() throws java.io.IOException;
-    field public static final int CENATT = 36; // 0x24
-    field public static final int CENATX = 38; // 0x26
-    field public static final int CENCOM = 32; // 0x20
-    field public static final int CENCRC = 16; // 0x10
-    field public static final int CENDSK = 34; // 0x22
-    field public static final int CENEXT = 30; // 0x1e
-    field public static final int CENFLG = 8; // 0x8
-    field public static final int CENHDR = 46; // 0x2e
-    field public static final int CENHOW = 10; // 0xa
-    field public static final int CENLEN = 24; // 0x18
-    field public static final int CENNAM = 28; // 0x1c
-    field public static final int CENOFF = 42; // 0x2a
-    field public static final long CENSIG = 33639248L; // 0x2014b50L
-    field public static final int CENSIZ = 20; // 0x14
-    field public static final int CENTIM = 12; // 0xc
-    field public static final int CENVEM = 4; // 0x4
-    field public static final int CENVER = 6; // 0x6
-    field public static final int ENDCOM = 20; // 0x14
-    field public static final int ENDHDR = 22; // 0x16
-    field public static final int ENDOFF = 16; // 0x10
-    field public static final long ENDSIG = 101010256L; // 0x6054b50L
-    field public static final int ENDSIZ = 12; // 0xc
-    field public static final int ENDSUB = 8; // 0x8
-    field public static final int ENDTOT = 10; // 0xa
-    field public static final int EXTCRC = 4; // 0x4
-    field public static final int EXTHDR = 16; // 0x10
-    field public static final int EXTLEN = 12; // 0xc
-    field public static final long EXTSIG = 134695760L; // 0x8074b50L
-    field public static final int EXTSIZ = 8; // 0x8
-    field public static final int LOCCRC = 14; // 0xe
-    field public static final int LOCEXT = 28; // 0x1c
-    field public static final int LOCFLG = 6; // 0x6
-    field public static final int LOCHDR = 30; // 0x1e
-    field public static final int LOCHOW = 8; // 0x8
-    field public static final int LOCLEN = 22; // 0x16
-    field public static final int LOCNAM = 26; // 0x1a
-    field public static final long LOCSIG = 67324752L; // 0x4034b50L
-    field public static final int LOCSIZ = 18; // 0x12
-    field public static final int LOCTIM = 10; // 0xa
-    field public static final int LOCVER = 4; // 0x4
-  }
-
-  public class ZipOutputStream extends java.util.zip.DeflaterOutputStream {
-    ctor public ZipOutputStream(java.io.OutputStream);
-    ctor public ZipOutputStream(java.io.OutputStream, java.nio.charset.Charset);
-    method public void closeEntry() throws java.io.IOException;
-    method public void putNextEntry(java.util.zip.ZipEntry) throws java.io.IOException;
-    method public void setComment(String);
-    method public void setLevel(int);
-    method public void setMethod(int);
-    field public static final int CENATT = 36; // 0x24
-    field public static final int CENATX = 38; // 0x26
-    field public static final int CENCOM = 32; // 0x20
-    field public static final int CENCRC = 16; // 0x10
-    field public static final int CENDSK = 34; // 0x22
-    field public static final int CENEXT = 30; // 0x1e
-    field public static final int CENFLG = 8; // 0x8
-    field public static final int CENHDR = 46; // 0x2e
-    field public static final int CENHOW = 10; // 0xa
-    field public static final int CENLEN = 24; // 0x18
-    field public static final int CENNAM = 28; // 0x1c
-    field public static final int CENOFF = 42; // 0x2a
-    field public static final long CENSIG = 33639248L; // 0x2014b50L
-    field public static final int CENSIZ = 20; // 0x14
-    field public static final int CENTIM = 12; // 0xc
-    field public static final int CENVEM = 4; // 0x4
-    field public static final int CENVER = 6; // 0x6
-    field public static final int DEFLATED = 8; // 0x8
-    field public static final int ENDCOM = 20; // 0x14
-    field public static final int ENDHDR = 22; // 0x16
-    field public static final int ENDOFF = 16; // 0x10
-    field public static final long ENDSIG = 101010256L; // 0x6054b50L
-    field public static final int ENDSIZ = 12; // 0xc
-    field public static final int ENDSUB = 8; // 0x8
-    field public static final int ENDTOT = 10; // 0xa
-    field public static final int EXTCRC = 4; // 0x4
-    field public static final int EXTHDR = 16; // 0x10
-    field public static final int EXTLEN = 12; // 0xc
-    field public static final long EXTSIG = 134695760L; // 0x8074b50L
-    field public static final int EXTSIZ = 8; // 0x8
-    field public static final int LOCCRC = 14; // 0xe
-    field public static final int LOCEXT = 28; // 0x1c
-    field public static final int LOCFLG = 6; // 0x6
-    field public static final int LOCHDR = 30; // 0x1e
-    field public static final int LOCHOW = 8; // 0x8
-    field public static final int LOCLEN = 22; // 0x16
-    field public static final int LOCNAM = 26; // 0x1a
-    field public static final long LOCSIG = 67324752L; // 0x4034b50L
-    field public static final int LOCSIZ = 18; // 0x12
-    field public static final int LOCTIM = 10; // 0xa
-    field public static final int LOCVER = 4; // 0x4
-    field public static final int STORED = 0; // 0x0
-  }
-
-}
-
-package javax.crypto {
-
-  public class AEADBadTagException extends javax.crypto.BadPaddingException {
-    ctor public AEADBadTagException();
-    ctor public AEADBadTagException(String);
-  }
-
-  public class BadPaddingException extends java.security.GeneralSecurityException {
-    ctor public BadPaddingException();
-    ctor public BadPaddingException(String);
-  }
-
-  public class Cipher {
-    ctor protected Cipher(javax.crypto.CipherSpi, java.security.Provider, String);
-    method public final byte[] doFinal() throws javax.crypto.BadPaddingException, javax.crypto.IllegalBlockSizeException;
-    method public final int doFinal(byte[], int) throws javax.crypto.BadPaddingException, javax.crypto.IllegalBlockSizeException, javax.crypto.ShortBufferException;
-    method public final byte[] doFinal(byte[]) throws javax.crypto.BadPaddingException, javax.crypto.IllegalBlockSizeException;
-    method public final byte[] doFinal(byte[], int, int) throws javax.crypto.BadPaddingException, javax.crypto.IllegalBlockSizeException;
-    method public final int doFinal(byte[], int, int, byte[]) throws javax.crypto.BadPaddingException, javax.crypto.IllegalBlockSizeException, javax.crypto.ShortBufferException;
-    method public final int doFinal(byte[], int, int, byte[], int) throws javax.crypto.BadPaddingException, javax.crypto.IllegalBlockSizeException, javax.crypto.ShortBufferException;
-    method public final int doFinal(java.nio.ByteBuffer, java.nio.ByteBuffer) throws javax.crypto.BadPaddingException, javax.crypto.IllegalBlockSizeException, javax.crypto.ShortBufferException;
-    method public final String getAlgorithm();
-    method public final int getBlockSize();
-    method public final javax.crypto.ExemptionMechanism getExemptionMechanism();
-    method public final byte[] getIV();
-    method public static final javax.crypto.Cipher getInstance(String) throws java.security.NoSuchAlgorithmException, javax.crypto.NoSuchPaddingException;
-    method public static final javax.crypto.Cipher getInstance(String, String) throws java.security.NoSuchAlgorithmException, javax.crypto.NoSuchPaddingException, java.security.NoSuchProviderException;
-    method public static final javax.crypto.Cipher getInstance(String, java.security.Provider) throws java.security.NoSuchAlgorithmException, javax.crypto.NoSuchPaddingException;
-    method public static final int getMaxAllowedKeyLength(String) throws java.security.NoSuchAlgorithmException;
-    method public static final java.security.spec.AlgorithmParameterSpec getMaxAllowedParameterSpec(String) throws java.security.NoSuchAlgorithmException;
-    method public final int getOutputSize(int);
-    method public final java.security.AlgorithmParameters getParameters();
-    method public final java.security.Provider getProvider();
-    method public final void init(int, java.security.Key) throws java.security.InvalidKeyException;
-    method public final void init(int, java.security.Key, java.security.SecureRandom) throws java.security.InvalidKeyException;
-    method public final void init(int, java.security.Key, java.security.spec.AlgorithmParameterSpec) throws java.security.InvalidAlgorithmParameterException, java.security.InvalidKeyException;
-    method public final void init(int, java.security.Key, java.security.spec.AlgorithmParameterSpec, java.security.SecureRandom) throws java.security.InvalidAlgorithmParameterException, java.security.InvalidKeyException;
-    method public final void init(int, java.security.Key, java.security.AlgorithmParameters) throws java.security.InvalidAlgorithmParameterException, java.security.InvalidKeyException;
-    method public final void init(int, java.security.Key, java.security.AlgorithmParameters, java.security.SecureRandom) throws java.security.InvalidAlgorithmParameterException, java.security.InvalidKeyException;
-    method public final void init(int, java.security.cert.Certificate) throws java.security.InvalidKeyException;
-    method public final void init(int, java.security.cert.Certificate, java.security.SecureRandom) throws java.security.InvalidKeyException;
-    method public final java.security.Key unwrap(byte[], String, int) throws java.security.InvalidKeyException, java.security.NoSuchAlgorithmException;
-    method public final byte[] update(byte[]);
-    method public final byte[] update(byte[], int, int);
-    method public final int update(byte[], int, int, byte[]) throws javax.crypto.ShortBufferException;
-    method public final int update(byte[], int, int, byte[], int) throws javax.crypto.ShortBufferException;
-    method public final int update(java.nio.ByteBuffer, java.nio.ByteBuffer) throws javax.crypto.ShortBufferException;
-    method public final void updateAAD(byte[]);
-    method public final void updateAAD(byte[], int, int);
-    method public final void updateAAD(java.nio.ByteBuffer);
-    method public final byte[] wrap(java.security.Key) throws javax.crypto.IllegalBlockSizeException, java.security.InvalidKeyException;
-    field public static final int DECRYPT_MODE = 2; // 0x2
-    field public static final int ENCRYPT_MODE = 1; // 0x1
-    field public static final int PRIVATE_KEY = 2; // 0x2
-    field public static final int PUBLIC_KEY = 1; // 0x1
-    field public static final int SECRET_KEY = 3; // 0x3
-    field public static final int UNWRAP_MODE = 4; // 0x4
-    field public static final int WRAP_MODE = 3; // 0x3
-  }
-
-  public class CipherInputStream extends java.io.FilterInputStream {
-    ctor public CipherInputStream(java.io.InputStream, javax.crypto.Cipher);
-    ctor protected CipherInputStream(java.io.InputStream);
-  }
-
-  public class CipherOutputStream extends java.io.FilterOutputStream {
-    ctor public CipherOutputStream(java.io.OutputStream, javax.crypto.Cipher);
-    ctor protected CipherOutputStream(java.io.OutputStream);
-  }
-
-  public abstract class CipherSpi {
-    ctor public CipherSpi();
-    method protected abstract byte[] engineDoFinal(byte[], int, int) throws javax.crypto.BadPaddingException, javax.crypto.IllegalBlockSizeException;
-    method protected abstract int engineDoFinal(byte[], int, int, byte[], int) throws javax.crypto.BadPaddingException, javax.crypto.IllegalBlockSizeException, javax.crypto.ShortBufferException;
-    method protected int engineDoFinal(java.nio.ByteBuffer, java.nio.ByteBuffer) throws javax.crypto.BadPaddingException, javax.crypto.IllegalBlockSizeException, javax.crypto.ShortBufferException;
-    method protected abstract int engineGetBlockSize();
-    method protected abstract byte[] engineGetIV();
-    method protected int engineGetKeySize(java.security.Key) throws java.security.InvalidKeyException;
-    method protected abstract int engineGetOutputSize(int);
-    method protected abstract java.security.AlgorithmParameters engineGetParameters();
-    method protected abstract void engineInit(int, java.security.Key, java.security.SecureRandom) throws java.security.InvalidKeyException;
-    method protected abstract void engineInit(int, java.security.Key, java.security.spec.AlgorithmParameterSpec, java.security.SecureRandom) throws java.security.InvalidAlgorithmParameterException, java.security.InvalidKeyException;
-    method protected abstract void engineInit(int, java.security.Key, java.security.AlgorithmParameters, java.security.SecureRandom) throws java.security.InvalidAlgorithmParameterException, java.security.InvalidKeyException;
-    method protected abstract void engineSetMode(String) throws java.security.NoSuchAlgorithmException;
-    method protected abstract void engineSetPadding(String) throws javax.crypto.NoSuchPaddingException;
-    method protected java.security.Key engineUnwrap(byte[], String, int) throws java.security.InvalidKeyException, java.security.NoSuchAlgorithmException;
-    method protected abstract byte[] engineUpdate(byte[], int, int);
-    method protected abstract int engineUpdate(byte[], int, int, byte[], int) throws javax.crypto.ShortBufferException;
-    method protected int engineUpdate(java.nio.ByteBuffer, java.nio.ByteBuffer) throws javax.crypto.ShortBufferException;
-    method protected void engineUpdateAAD(byte[], int, int);
-    method protected void engineUpdateAAD(java.nio.ByteBuffer);
-    method protected byte[] engineWrap(java.security.Key) throws javax.crypto.IllegalBlockSizeException, java.security.InvalidKeyException;
-  }
-
-  public class EncryptedPrivateKeyInfo {
-    ctor public EncryptedPrivateKeyInfo(byte[]) throws java.io.IOException;
-    ctor public EncryptedPrivateKeyInfo(String, byte[]) throws java.security.NoSuchAlgorithmException;
-    ctor public EncryptedPrivateKeyInfo(java.security.AlgorithmParameters, byte[]) throws java.security.NoSuchAlgorithmException;
-    method public String getAlgName();
-    method public java.security.AlgorithmParameters getAlgParameters();
-    method public byte[] getEncoded() throws java.io.IOException;
-    method public byte[] getEncryptedData();
-    method public java.security.spec.PKCS8EncodedKeySpec getKeySpec(javax.crypto.Cipher) throws java.security.spec.InvalidKeySpecException;
-    method public java.security.spec.PKCS8EncodedKeySpec getKeySpec(java.security.Key) throws java.security.InvalidKeyException, java.security.NoSuchAlgorithmException;
-    method public java.security.spec.PKCS8EncodedKeySpec getKeySpec(java.security.Key, String) throws java.security.InvalidKeyException, java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException;
-    method public java.security.spec.PKCS8EncodedKeySpec getKeySpec(java.security.Key, java.security.Provider) throws java.security.InvalidKeyException, java.security.NoSuchAlgorithmException;
-  }
-
-  public class ExemptionMechanism {
-    ctor protected ExemptionMechanism(javax.crypto.ExemptionMechanismSpi, java.security.Provider, String);
-    method public final byte[] genExemptionBlob() throws javax.crypto.ExemptionMechanismException, java.lang.IllegalStateException;
-    method public final int genExemptionBlob(byte[]) throws javax.crypto.ExemptionMechanismException, java.lang.IllegalStateException, javax.crypto.ShortBufferException;
-    method public final int genExemptionBlob(byte[], int) throws javax.crypto.ExemptionMechanismException, java.lang.IllegalStateException, javax.crypto.ShortBufferException;
-    method public static final javax.crypto.ExemptionMechanism getInstance(String) throws java.security.NoSuchAlgorithmException;
-    method public static final javax.crypto.ExemptionMechanism getInstance(String, String) throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException;
-    method public static final javax.crypto.ExemptionMechanism getInstance(String, java.security.Provider) throws java.security.NoSuchAlgorithmException;
-    method public final String getName();
-    method public final int getOutputSize(int) throws java.lang.IllegalStateException;
-    method public final java.security.Provider getProvider();
-    method public final void init(java.security.Key) throws javax.crypto.ExemptionMechanismException, java.security.InvalidKeyException;
-    method public final void init(java.security.Key, java.security.spec.AlgorithmParameterSpec) throws javax.crypto.ExemptionMechanismException, java.security.InvalidAlgorithmParameterException, java.security.InvalidKeyException;
-    method public final void init(java.security.Key, java.security.AlgorithmParameters) throws javax.crypto.ExemptionMechanismException, java.security.InvalidAlgorithmParameterException, java.security.InvalidKeyException;
-    method public final boolean isCryptoAllowed(java.security.Key) throws javax.crypto.ExemptionMechanismException;
-  }
-
-  public class ExemptionMechanismException extends java.security.GeneralSecurityException {
-    ctor public ExemptionMechanismException();
-    ctor public ExemptionMechanismException(String);
-  }
-
-  public abstract class ExemptionMechanismSpi {
-    ctor public ExemptionMechanismSpi();
-    method protected abstract byte[] engineGenExemptionBlob() throws javax.crypto.ExemptionMechanismException;
-    method protected abstract int engineGenExemptionBlob(byte[], int) throws javax.crypto.ExemptionMechanismException, javax.crypto.ShortBufferException;
-    method protected abstract int engineGetOutputSize(int);
-    method protected abstract void engineInit(java.security.Key) throws javax.crypto.ExemptionMechanismException, java.security.InvalidKeyException;
-    method protected abstract void engineInit(java.security.Key, java.security.spec.AlgorithmParameterSpec) throws javax.crypto.ExemptionMechanismException, java.security.InvalidAlgorithmParameterException, java.security.InvalidKeyException;
-    method protected abstract void engineInit(java.security.Key, java.security.AlgorithmParameters) throws javax.crypto.ExemptionMechanismException, java.security.InvalidAlgorithmParameterException, java.security.InvalidKeyException;
-  }
-
-  public class IllegalBlockSizeException extends java.security.GeneralSecurityException {
-    ctor public IllegalBlockSizeException();
-    ctor public IllegalBlockSizeException(String);
-  }
-
-  public class KeyAgreement {
-    ctor protected KeyAgreement(javax.crypto.KeyAgreementSpi, java.security.Provider, String);
-    method public final java.security.Key doPhase(java.security.Key, boolean) throws java.lang.IllegalStateException, java.security.InvalidKeyException;
-    method public final byte[] generateSecret() throws java.lang.IllegalStateException;
-    method public final int generateSecret(byte[], int) throws java.lang.IllegalStateException, javax.crypto.ShortBufferException;
-    method public final javax.crypto.SecretKey generateSecret(String) throws java.lang.IllegalStateException, java.security.InvalidKeyException, java.security.NoSuchAlgorithmException;
-    method public final String getAlgorithm();
-    method public static final javax.crypto.KeyAgreement getInstance(String) throws java.security.NoSuchAlgorithmException;
-    method public static final javax.crypto.KeyAgreement getInstance(String, String) throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException;
-    method public static final javax.crypto.KeyAgreement getInstance(String, java.security.Provider) throws java.security.NoSuchAlgorithmException;
-    method public final java.security.Provider getProvider();
-    method public final void init(java.security.Key) throws java.security.InvalidKeyException;
-    method public final void init(java.security.Key, java.security.SecureRandom) throws java.security.InvalidKeyException;
-    method public final void init(java.security.Key, java.security.spec.AlgorithmParameterSpec) throws java.security.InvalidAlgorithmParameterException, java.security.InvalidKeyException;
-    method public final void init(java.security.Key, java.security.spec.AlgorithmParameterSpec, java.security.SecureRandom) throws java.security.InvalidAlgorithmParameterException, java.security.InvalidKeyException;
-  }
-
-  public abstract class KeyAgreementSpi {
-    ctor public KeyAgreementSpi();
-    method protected abstract java.security.Key engineDoPhase(java.security.Key, boolean) throws java.lang.IllegalStateException, java.security.InvalidKeyException;
-    method protected abstract byte[] engineGenerateSecret() throws java.lang.IllegalStateException;
-    method protected abstract int engineGenerateSecret(byte[], int) throws java.lang.IllegalStateException, javax.crypto.ShortBufferException;
-    method protected abstract javax.crypto.SecretKey engineGenerateSecret(String) throws java.lang.IllegalStateException, java.security.InvalidKeyException, java.security.NoSuchAlgorithmException;
-    method protected abstract void engineInit(java.security.Key, java.security.SecureRandom) throws java.security.InvalidKeyException;
-    method protected abstract void engineInit(java.security.Key, java.security.spec.AlgorithmParameterSpec, java.security.SecureRandom) throws java.security.InvalidAlgorithmParameterException, java.security.InvalidKeyException;
-  }
-
-  public class KeyGenerator {
-    ctor protected KeyGenerator(javax.crypto.KeyGeneratorSpi, java.security.Provider, String);
-    method public final javax.crypto.SecretKey generateKey();
-    method public final String getAlgorithm();
-    method public static final javax.crypto.KeyGenerator getInstance(String) throws java.security.NoSuchAlgorithmException;
-    method public static final javax.crypto.KeyGenerator getInstance(String, String) throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException;
-    method public static final javax.crypto.KeyGenerator getInstance(String, java.security.Provider) throws java.security.NoSuchAlgorithmException;
-    method public final java.security.Provider getProvider();
-    method public final void init(java.security.SecureRandom);
-    method public final void init(java.security.spec.AlgorithmParameterSpec) throws java.security.InvalidAlgorithmParameterException;
-    method public final void init(java.security.spec.AlgorithmParameterSpec, java.security.SecureRandom) throws java.security.InvalidAlgorithmParameterException;
-    method public final void init(int);
-    method public final void init(int, java.security.SecureRandom);
-  }
-
-  public abstract class KeyGeneratorSpi {
-    ctor public KeyGeneratorSpi();
-    method protected abstract javax.crypto.SecretKey engineGenerateKey();
-    method protected abstract void engineInit(java.security.SecureRandom);
-    method protected abstract void engineInit(java.security.spec.AlgorithmParameterSpec, java.security.SecureRandom) throws java.security.InvalidAlgorithmParameterException;
-    method protected abstract void engineInit(int, java.security.SecureRandom);
-  }
-
-  public class Mac implements java.lang.Cloneable {
-    ctor protected Mac(javax.crypto.MacSpi, java.security.Provider, String);
-    method public final Object clone() throws java.lang.CloneNotSupportedException;
-    method public final byte[] doFinal() throws java.lang.IllegalStateException;
-    method public final void doFinal(byte[], int) throws java.lang.IllegalStateException, javax.crypto.ShortBufferException;
-    method public final byte[] doFinal(byte[]) throws java.lang.IllegalStateException;
-    method public final String getAlgorithm();
-    method public static final javax.crypto.Mac getInstance(String) throws java.security.NoSuchAlgorithmException;
-    method public static final javax.crypto.Mac getInstance(String, String) throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException;
-    method public static final javax.crypto.Mac getInstance(String, java.security.Provider) throws java.security.NoSuchAlgorithmException;
-    method public final int getMacLength();
-    method public final java.security.Provider getProvider();
-    method public final void init(java.security.Key) throws java.security.InvalidKeyException;
-    method public final void init(java.security.Key, java.security.spec.AlgorithmParameterSpec) throws java.security.InvalidAlgorithmParameterException, java.security.InvalidKeyException;
-    method public final void reset();
-    method public final void update(byte) throws java.lang.IllegalStateException;
-    method public final void update(byte[]) throws java.lang.IllegalStateException;
-    method public final void update(byte[], int, int) throws java.lang.IllegalStateException;
-    method public final void update(java.nio.ByteBuffer);
-  }
-
-  public abstract class MacSpi {
-    ctor public MacSpi();
-    method public Object clone() throws java.lang.CloneNotSupportedException;
-    method protected abstract byte[] engineDoFinal();
-    method protected abstract int engineGetMacLength();
-    method protected abstract void engineInit(java.security.Key, java.security.spec.AlgorithmParameterSpec) throws java.security.InvalidAlgorithmParameterException, java.security.InvalidKeyException;
-    method protected abstract void engineReset();
-    method protected abstract void engineUpdate(byte);
-    method protected abstract void engineUpdate(byte[], int, int);
-    method protected void engineUpdate(java.nio.ByteBuffer);
-  }
-
-  public class NoSuchPaddingException extends java.security.GeneralSecurityException {
-    ctor public NoSuchPaddingException();
-    ctor public NoSuchPaddingException(String);
-  }
-
-  public class NullCipher extends javax.crypto.Cipher {
-    ctor public NullCipher();
-  }
-
-  public class SealedObject implements java.io.Serializable {
-    ctor public SealedObject(java.io.Serializable, javax.crypto.Cipher) throws java.io.IOException, javax.crypto.IllegalBlockSizeException;
-    ctor protected SealedObject(javax.crypto.SealedObject);
-    method public final String getAlgorithm();
-    method public final Object getObject(java.security.Key) throws java.lang.ClassNotFoundException, java.io.IOException, java.security.InvalidKeyException, java.security.NoSuchAlgorithmException;
-    method public final Object getObject(javax.crypto.Cipher) throws javax.crypto.BadPaddingException, java.lang.ClassNotFoundException, java.io.IOException, javax.crypto.IllegalBlockSizeException;
-    method public final Object getObject(java.security.Key, String) throws java.lang.ClassNotFoundException, java.io.IOException, java.security.InvalidKeyException, java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException;
-    field protected byte[] encodedParams;
-  }
-
-  public interface SecretKey extends java.security.Key javax.security.auth.Destroyable {
-    field public static final long serialVersionUID = -4795878709595146952L; // 0xbd719db928b8f538L
-  }
-
-  public class SecretKeyFactory {
-    ctor protected SecretKeyFactory(javax.crypto.SecretKeyFactorySpi, java.security.Provider, String);
-    method public final javax.crypto.SecretKey generateSecret(java.security.spec.KeySpec) throws java.security.spec.InvalidKeySpecException;
-    method public final String getAlgorithm();
-    method public static final javax.crypto.SecretKeyFactory getInstance(String) throws java.security.NoSuchAlgorithmException;
-    method public static final javax.crypto.SecretKeyFactory getInstance(String, String) throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException;
-    method public static final javax.crypto.SecretKeyFactory getInstance(String, java.security.Provider) throws java.security.NoSuchAlgorithmException;
-    method public final java.security.spec.KeySpec getKeySpec(javax.crypto.SecretKey, Class<?>) throws java.security.spec.InvalidKeySpecException;
-    method public final java.security.Provider getProvider();
-    method public final javax.crypto.SecretKey translateKey(javax.crypto.SecretKey) throws java.security.InvalidKeyException;
-  }
-
-  public abstract class SecretKeyFactorySpi {
-    ctor public SecretKeyFactorySpi();
-    method protected abstract javax.crypto.SecretKey engineGenerateSecret(java.security.spec.KeySpec) throws java.security.spec.InvalidKeySpecException;
-    method protected abstract java.security.spec.KeySpec engineGetKeySpec(javax.crypto.SecretKey, Class<?>) throws java.security.spec.InvalidKeySpecException;
-    method protected abstract javax.crypto.SecretKey engineTranslateKey(javax.crypto.SecretKey) throws java.security.InvalidKeyException;
-  }
-
-  public class ShortBufferException extends java.security.GeneralSecurityException {
-    ctor public ShortBufferException();
-    ctor public ShortBufferException(String);
-  }
-
-}
-
-package javax.crypto.interfaces {
-
-  public interface DHKey {
-    method public javax.crypto.spec.DHParameterSpec getParams();
-  }
-
-  public interface DHPrivateKey extends javax.crypto.interfaces.DHKey java.security.PrivateKey {
-    method public java.math.BigInteger getX();
-    field public static final long serialVersionUID = 2211791113380396553L; // 0x1eb1dc4c8e677e09L
-  }
-
-  public interface DHPublicKey extends javax.crypto.interfaces.DHKey java.security.PublicKey {
-    method public java.math.BigInteger getY();
-    field public static final long serialVersionUID = -6628103563352519193L; // 0xa4043eed23df4de7L
-  }
-
-  public interface PBEKey extends javax.crypto.SecretKey {
-    method public int getIterationCount();
-    method public char[] getPassword();
-    method public byte[] getSalt();
-    field public static final long serialVersionUID = -1430015993304333921L; // 0xec279007d7f7c19fL
-  }
-
-}
-
-package javax.crypto.spec {
-
-  public class DESKeySpec implements java.security.spec.KeySpec {
-    ctor public DESKeySpec(byte[]) throws java.security.InvalidKeyException;
-    ctor public DESKeySpec(byte[], int) throws java.security.InvalidKeyException;
-    method public byte[] getKey();
-    method public static boolean isParityAdjusted(byte[], int) throws java.security.InvalidKeyException;
-    method public static boolean isWeak(byte[], int) throws java.security.InvalidKeyException;
-    field public static final int DES_KEY_LEN = 8; // 0x8
-  }
-
-  public class DESedeKeySpec implements java.security.spec.KeySpec {
-    ctor public DESedeKeySpec(byte[]) throws java.security.InvalidKeyException;
-    ctor public DESedeKeySpec(byte[], int) throws java.security.InvalidKeyException;
-    method public byte[] getKey();
-    method public static boolean isParityAdjusted(byte[], int) throws java.security.InvalidKeyException;
-    field public static final int DES_EDE_KEY_LEN = 24; // 0x18
-  }
-
-  public class DHGenParameterSpec implements java.security.spec.AlgorithmParameterSpec {
-    ctor public DHGenParameterSpec(int, int);
-    method public int getExponentSize();
-    method public int getPrimeSize();
-  }
-
-  public class DHParameterSpec implements java.security.spec.AlgorithmParameterSpec {
-    ctor public DHParameterSpec(java.math.BigInteger, java.math.BigInteger);
-    ctor public DHParameterSpec(java.math.BigInteger, java.math.BigInteger, int);
-    method public java.math.BigInteger getG();
-    method public int getL();
-    method public java.math.BigInteger getP();
-  }
-
-  public class DHPrivateKeySpec implements java.security.spec.KeySpec {
-    ctor public DHPrivateKeySpec(java.math.BigInteger, java.math.BigInteger, java.math.BigInteger);
-    method public java.math.BigInteger getG();
-    method public java.math.BigInteger getP();
-    method public java.math.BigInteger getX();
-  }
-
-  public class DHPublicKeySpec implements java.security.spec.KeySpec {
-    ctor public DHPublicKeySpec(java.math.BigInteger, java.math.BigInteger, java.math.BigInteger);
-    method public java.math.BigInteger getG();
-    method public java.math.BigInteger getP();
-    method public java.math.BigInteger getY();
-  }
-
-  public class GCMParameterSpec implements java.security.spec.AlgorithmParameterSpec {
-    ctor public GCMParameterSpec(int, byte[]);
-    ctor public GCMParameterSpec(int, byte[], int, int);
-    method public byte[] getIV();
-    method public int getTLen();
-  }
-
-  public class IvParameterSpec implements java.security.spec.AlgorithmParameterSpec {
-    ctor public IvParameterSpec(byte[]);
-    ctor public IvParameterSpec(byte[], int, int);
-    method public byte[] getIV();
-  }
-
-  public class OAEPParameterSpec implements java.security.spec.AlgorithmParameterSpec {
-    ctor public OAEPParameterSpec(String, String, java.security.spec.AlgorithmParameterSpec, javax.crypto.spec.PSource);
-    method public String getDigestAlgorithm();
-    method public String getMGFAlgorithm();
-    method public java.security.spec.AlgorithmParameterSpec getMGFParameters();
-    method public javax.crypto.spec.PSource getPSource();
-    field public static final javax.crypto.spec.OAEPParameterSpec DEFAULT;
-  }
-
-  public class PBEKeySpec implements java.security.spec.KeySpec {
-    ctor public PBEKeySpec(char[]);
-    ctor public PBEKeySpec(char[], byte[], int, int);
-    ctor public PBEKeySpec(char[], byte[], int);
-    method public final void clearPassword();
-    method public final int getIterationCount();
-    method public final int getKeyLength();
-    method public final char[] getPassword();
-    method public final byte[] getSalt();
-  }
-
-  public class PBEParameterSpec implements java.security.spec.AlgorithmParameterSpec {
-    ctor public PBEParameterSpec(byte[], int);
-    ctor public PBEParameterSpec(byte[], int, java.security.spec.AlgorithmParameterSpec);
-    method public int getIterationCount();
-    method public java.security.spec.AlgorithmParameterSpec getParameterSpec();
-    method public byte[] getSalt();
-  }
-
-  public class PSource {
-    ctor protected PSource(String);
-    method public String getAlgorithm();
-  }
-
-  public static final class PSource.PSpecified extends javax.crypto.spec.PSource {
-    ctor public PSource.PSpecified(byte[]);
-    method public byte[] getValue();
-    field public static final javax.crypto.spec.PSource.PSpecified DEFAULT;
-  }
-
-  public class RC2ParameterSpec implements java.security.spec.AlgorithmParameterSpec {
-    ctor public RC2ParameterSpec(int);
-    ctor public RC2ParameterSpec(int, byte[]);
-    ctor public RC2ParameterSpec(int, byte[], int);
-    method public int getEffectiveKeyBits();
-    method public byte[] getIV();
-  }
-
-  public class RC5ParameterSpec implements java.security.spec.AlgorithmParameterSpec {
-    ctor public RC5ParameterSpec(int, int, int);
-    ctor public RC5ParameterSpec(int, int, int, byte[]);
-    ctor public RC5ParameterSpec(int, int, int, byte[], int);
-    method public byte[] getIV();
-    method public int getRounds();
-    method public int getVersion();
-    method public int getWordSize();
-  }
-
-  public class SecretKeySpec implements java.security.spec.KeySpec javax.crypto.SecretKey {
-    ctor public SecretKeySpec(byte[], String);
-    ctor public SecretKeySpec(byte[], int, int, String);
-    method public String getAlgorithm();
-    method public byte[] getEncoded();
-    method public String getFormat();
-  }
-
-}
-
 package javax.microedition.khronos.egl {
 
   public interface EGL {
@@ -73015,1527 +55376,6 @@
 
 }
 
-package javax.net {
-
-  public abstract class ServerSocketFactory {
-    ctor protected ServerSocketFactory();
-    method public java.net.ServerSocket createServerSocket() throws java.io.IOException;
-    method public abstract java.net.ServerSocket createServerSocket(int) throws java.io.IOException;
-    method public abstract java.net.ServerSocket createServerSocket(int, int) throws java.io.IOException;
-    method public abstract java.net.ServerSocket createServerSocket(int, int, java.net.InetAddress) throws java.io.IOException;
-    method public static javax.net.ServerSocketFactory getDefault();
-  }
-
-  public abstract class SocketFactory {
-    ctor protected SocketFactory();
-    method public java.net.Socket createSocket() throws java.io.IOException;
-    method public abstract java.net.Socket createSocket(String, int) throws java.io.IOException, java.net.UnknownHostException;
-    method public abstract java.net.Socket createSocket(String, int, java.net.InetAddress, int) throws java.io.IOException, java.net.UnknownHostException;
-    method public abstract java.net.Socket createSocket(java.net.InetAddress, int) throws java.io.IOException;
-    method public abstract java.net.Socket createSocket(java.net.InetAddress, int, java.net.InetAddress, int) throws java.io.IOException;
-    method public static javax.net.SocketFactory getDefault();
-  }
-
-}
-
-package javax.net.ssl {
-
-  public class CertPathTrustManagerParameters implements javax.net.ssl.ManagerFactoryParameters {
-    ctor public CertPathTrustManagerParameters(java.security.cert.CertPathParameters);
-    method public java.security.cert.CertPathParameters getParameters();
-  }
-
-  public abstract class ExtendedSSLSession implements javax.net.ssl.SSLSession {
-    ctor public ExtendedSSLSession();
-    method public abstract String[] getLocalSupportedSignatureAlgorithms();
-    method public abstract String[] getPeerSupportedSignatureAlgorithms();
-    method public java.util.List<javax.net.ssl.SNIServerName> getRequestedServerNames();
-  }
-
-  public class HandshakeCompletedEvent extends java.util.EventObject {
-    ctor public HandshakeCompletedEvent(javax.net.ssl.SSLSocket, javax.net.ssl.SSLSession);
-    method public String getCipherSuite();
-    method public java.security.cert.Certificate[] getLocalCertificates();
-    method public java.security.Principal getLocalPrincipal();
-    method public javax.security.cert.X509Certificate[] getPeerCertificateChain() throws javax.net.ssl.SSLPeerUnverifiedException;
-    method public java.security.cert.Certificate[] getPeerCertificates() throws javax.net.ssl.SSLPeerUnverifiedException;
-    method public java.security.Principal getPeerPrincipal() throws javax.net.ssl.SSLPeerUnverifiedException;
-    method public javax.net.ssl.SSLSession getSession();
-    method public javax.net.ssl.SSLSocket getSocket();
-  }
-
-  public interface HandshakeCompletedListener extends java.util.EventListener {
-    method public void handshakeCompleted(javax.net.ssl.HandshakeCompletedEvent);
-  }
-
-  public interface HostnameVerifier {
-    method public boolean verify(String, javax.net.ssl.SSLSession);
-  }
-
-  public abstract class HttpsURLConnection extends java.net.HttpURLConnection {
-    ctor protected HttpsURLConnection(java.net.URL);
-    method public abstract String getCipherSuite();
-    method public static javax.net.ssl.HostnameVerifier getDefaultHostnameVerifier();
-    method public static javax.net.ssl.SSLSocketFactory getDefaultSSLSocketFactory();
-    method public javax.net.ssl.HostnameVerifier getHostnameVerifier();
-    method public abstract java.security.cert.Certificate[] getLocalCertificates();
-    method public java.security.Principal getLocalPrincipal();
-    method public java.security.Principal getPeerPrincipal() throws javax.net.ssl.SSLPeerUnverifiedException;
-    method public javax.net.ssl.SSLSocketFactory getSSLSocketFactory();
-    method public abstract java.security.cert.Certificate[] getServerCertificates() throws javax.net.ssl.SSLPeerUnverifiedException;
-    method public static void setDefaultHostnameVerifier(javax.net.ssl.HostnameVerifier);
-    method public static void setDefaultSSLSocketFactory(javax.net.ssl.SSLSocketFactory);
-    method public void setHostnameVerifier(javax.net.ssl.HostnameVerifier);
-    method public void setSSLSocketFactory(javax.net.ssl.SSLSocketFactory);
-    field protected javax.net.ssl.HostnameVerifier hostnameVerifier;
-  }
-
-  public interface KeyManager {
-  }
-
-  public class KeyManagerFactory {
-    ctor protected KeyManagerFactory(javax.net.ssl.KeyManagerFactorySpi, java.security.Provider, String);
-    method public final String getAlgorithm();
-    method public static final String getDefaultAlgorithm();
-    method public static final javax.net.ssl.KeyManagerFactory getInstance(String) throws java.security.NoSuchAlgorithmException;
-    method public static final javax.net.ssl.KeyManagerFactory getInstance(String, String) throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException;
-    method public static final javax.net.ssl.KeyManagerFactory getInstance(String, java.security.Provider) throws java.security.NoSuchAlgorithmException;
-    method public final javax.net.ssl.KeyManager[] getKeyManagers();
-    method public final java.security.Provider getProvider();
-    method public final void init(java.security.KeyStore, char[]) throws java.security.KeyStoreException, java.security.NoSuchAlgorithmException, java.security.UnrecoverableKeyException;
-    method public final void init(javax.net.ssl.ManagerFactoryParameters) throws java.security.InvalidAlgorithmParameterException;
-  }
-
-  public abstract class KeyManagerFactorySpi {
-    ctor public KeyManagerFactorySpi();
-    method protected abstract javax.net.ssl.KeyManager[] engineGetKeyManagers();
-    method protected abstract void engineInit(java.security.KeyStore, char[]) throws java.security.KeyStoreException, java.security.NoSuchAlgorithmException, java.security.UnrecoverableKeyException;
-    method protected abstract void engineInit(javax.net.ssl.ManagerFactoryParameters) throws java.security.InvalidAlgorithmParameterException;
-  }
-
-  public class KeyStoreBuilderParameters implements javax.net.ssl.ManagerFactoryParameters {
-    ctor public KeyStoreBuilderParameters(java.security.KeyStore.Builder);
-    ctor public KeyStoreBuilderParameters(java.util.List<java.security.KeyStore.Builder>);
-    method public java.util.List<java.security.KeyStore.Builder> getParameters();
-  }
-
-  public interface ManagerFactoryParameters {
-  }
-
-  public final class SNIHostName extends javax.net.ssl.SNIServerName {
-    ctor public SNIHostName(String);
-    ctor public SNIHostName(byte[]);
-    method public static javax.net.ssl.SNIMatcher createSNIMatcher(String);
-    method public String getAsciiName();
-  }
-
-  public abstract class SNIMatcher {
-    ctor protected SNIMatcher(int);
-    method public final int getType();
-    method public abstract boolean matches(javax.net.ssl.SNIServerName);
-  }
-
-  public abstract class SNIServerName {
-    ctor protected SNIServerName(int, byte[]);
-    method public final byte[] getEncoded();
-    method public final int getType();
-  }
-
-  public class SSLContext {
-    ctor protected SSLContext(javax.net.ssl.SSLContextSpi, java.security.Provider, String);
-    method public final javax.net.ssl.SSLEngine createSSLEngine();
-    method public final javax.net.ssl.SSLEngine createSSLEngine(String, int);
-    method public final javax.net.ssl.SSLSessionContext getClientSessionContext();
-    method public static javax.net.ssl.SSLContext getDefault() throws java.security.NoSuchAlgorithmException;
-    method public final javax.net.ssl.SSLParameters getDefaultSSLParameters();
-    method public static javax.net.ssl.SSLContext getInstance(String) throws java.security.NoSuchAlgorithmException;
-    method public static javax.net.ssl.SSLContext getInstance(String, String) throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException;
-    method public static javax.net.ssl.SSLContext getInstance(String, java.security.Provider) throws java.security.NoSuchAlgorithmException;
-    method public final String getProtocol();
-    method public final java.security.Provider getProvider();
-    method public final javax.net.ssl.SSLSessionContext getServerSessionContext();
-    method public final javax.net.ssl.SSLServerSocketFactory getServerSocketFactory();
-    method public final javax.net.ssl.SSLSocketFactory getSocketFactory();
-    method public final javax.net.ssl.SSLParameters getSupportedSSLParameters();
-    method public final void init(javax.net.ssl.KeyManager[], javax.net.ssl.TrustManager[], java.security.SecureRandom) throws java.security.KeyManagementException;
-    method public static void setDefault(javax.net.ssl.SSLContext);
-  }
-
-  public abstract class SSLContextSpi {
-    ctor public SSLContextSpi();
-    method protected abstract javax.net.ssl.SSLEngine engineCreateSSLEngine();
-    method protected abstract javax.net.ssl.SSLEngine engineCreateSSLEngine(String, int);
-    method protected abstract javax.net.ssl.SSLSessionContext engineGetClientSessionContext();
-    method protected javax.net.ssl.SSLParameters engineGetDefaultSSLParameters();
-    method protected abstract javax.net.ssl.SSLSessionContext engineGetServerSessionContext();
-    method protected abstract javax.net.ssl.SSLServerSocketFactory engineGetServerSocketFactory();
-    method protected abstract javax.net.ssl.SSLSocketFactory engineGetSocketFactory();
-    method protected javax.net.ssl.SSLParameters engineGetSupportedSSLParameters();
-    method protected abstract void engineInit(javax.net.ssl.KeyManager[], javax.net.ssl.TrustManager[], java.security.SecureRandom) throws java.security.KeyManagementException;
-  }
-
-  public abstract class SSLEngine {
-    ctor protected SSLEngine();
-    ctor protected SSLEngine(String, int);
-    method public abstract void beginHandshake() throws javax.net.ssl.SSLException;
-    method public abstract void closeInbound() throws javax.net.ssl.SSLException;
-    method public abstract void closeOutbound();
-    method public String getApplicationProtocol();
-    method public abstract Runnable getDelegatedTask();
-    method public abstract boolean getEnableSessionCreation();
-    method public abstract String[] getEnabledCipherSuites();
-    method public abstract String[] getEnabledProtocols();
-    method public String getHandshakeApplicationProtocol();
-    method public java.util.function.BiFunction<javax.net.ssl.SSLEngine,java.util.List<java.lang.String>,java.lang.String> getHandshakeApplicationProtocolSelector();
-    method public javax.net.ssl.SSLSession getHandshakeSession();
-    method public abstract javax.net.ssl.SSLEngineResult.HandshakeStatus getHandshakeStatus();
-    method public abstract boolean getNeedClientAuth();
-    method public String getPeerHost();
-    method public int getPeerPort();
-    method public javax.net.ssl.SSLParameters getSSLParameters();
-    method public abstract javax.net.ssl.SSLSession getSession();
-    method public abstract String[] getSupportedCipherSuites();
-    method public abstract String[] getSupportedProtocols();
-    method public abstract boolean getUseClientMode();
-    method public abstract boolean getWantClientAuth();
-    method public abstract boolean isInboundDone();
-    method public abstract boolean isOutboundDone();
-    method public abstract void setEnableSessionCreation(boolean);
-    method public abstract void setEnabledCipherSuites(String[]);
-    method public abstract void setEnabledProtocols(String[]);
-    method public void setHandshakeApplicationProtocolSelector(java.util.function.BiFunction<javax.net.ssl.SSLEngine,java.util.List<java.lang.String>,java.lang.String>);
-    method public abstract void setNeedClientAuth(boolean);
-    method public void setSSLParameters(javax.net.ssl.SSLParameters);
-    method public abstract void setUseClientMode(boolean);
-    method public abstract void setWantClientAuth(boolean);
-    method public javax.net.ssl.SSLEngineResult unwrap(java.nio.ByteBuffer, java.nio.ByteBuffer) throws javax.net.ssl.SSLException;
-    method public javax.net.ssl.SSLEngineResult unwrap(java.nio.ByteBuffer, java.nio.ByteBuffer[]) throws javax.net.ssl.SSLException;
-    method public abstract javax.net.ssl.SSLEngineResult unwrap(java.nio.ByteBuffer, java.nio.ByteBuffer[], int, int) throws javax.net.ssl.SSLException;
-    method public javax.net.ssl.SSLEngineResult wrap(java.nio.ByteBuffer, java.nio.ByteBuffer) throws javax.net.ssl.SSLException;
-    method public javax.net.ssl.SSLEngineResult wrap(java.nio.ByteBuffer[], java.nio.ByteBuffer) throws javax.net.ssl.SSLException;
-    method public abstract javax.net.ssl.SSLEngineResult wrap(java.nio.ByteBuffer[], int, int, java.nio.ByteBuffer) throws javax.net.ssl.SSLException;
-  }
-
-  public class SSLEngineResult {
-    ctor public SSLEngineResult(javax.net.ssl.SSLEngineResult.Status, javax.net.ssl.SSLEngineResult.HandshakeStatus, int, int);
-    method public final int bytesConsumed();
-    method public final int bytesProduced();
-    method public final javax.net.ssl.SSLEngineResult.HandshakeStatus getHandshakeStatus();
-    method public final javax.net.ssl.SSLEngineResult.Status getStatus();
-  }
-
-  public enum SSLEngineResult.HandshakeStatus {
-    enum_constant public static final javax.net.ssl.SSLEngineResult.HandshakeStatus FINISHED;
-    enum_constant public static final javax.net.ssl.SSLEngineResult.HandshakeStatus NEED_TASK;
-    enum_constant public static final javax.net.ssl.SSLEngineResult.HandshakeStatus NEED_UNWRAP;
-    enum_constant public static final javax.net.ssl.SSLEngineResult.HandshakeStatus NEED_WRAP;
-    enum_constant public static final javax.net.ssl.SSLEngineResult.HandshakeStatus NOT_HANDSHAKING;
-  }
-
-  public enum SSLEngineResult.Status {
-    enum_constant public static final javax.net.ssl.SSLEngineResult.Status BUFFER_OVERFLOW;
-    enum_constant public static final javax.net.ssl.SSLEngineResult.Status BUFFER_UNDERFLOW;
-    enum_constant public static final javax.net.ssl.SSLEngineResult.Status CLOSED;
-    enum_constant public static final javax.net.ssl.SSLEngineResult.Status OK;
-  }
-
-  public class SSLException extends java.io.IOException {
-    ctor public SSLException(String);
-    ctor public SSLException(String, Throwable);
-    ctor public SSLException(Throwable);
-  }
-
-  public class SSLHandshakeException extends javax.net.ssl.SSLException {
-    ctor public SSLHandshakeException(String);
-  }
-
-  public class SSLKeyException extends javax.net.ssl.SSLException {
-    ctor public SSLKeyException(String);
-  }
-
-  public class SSLParameters {
-    ctor public SSLParameters();
-    ctor public SSLParameters(String[]);
-    ctor public SSLParameters(String[], String[]);
-    method public java.security.AlgorithmConstraints getAlgorithmConstraints();
-    method public String[] getApplicationProtocols();
-    method public String[] getCipherSuites();
-    method public String getEndpointIdentificationAlgorithm();
-    method public boolean getNeedClientAuth();
-    method public String[] getProtocols();
-    method public final java.util.Collection<javax.net.ssl.SNIMatcher> getSNIMatchers();
-    method public final java.util.List<javax.net.ssl.SNIServerName> getServerNames();
-    method public final boolean getUseCipherSuitesOrder();
-    method public boolean getWantClientAuth();
-    method public void setAlgorithmConstraints(java.security.AlgorithmConstraints);
-    method public void setApplicationProtocols(String[]);
-    method public void setCipherSuites(String[]);
-    method public void setEndpointIdentificationAlgorithm(String);
-    method public void setNeedClientAuth(boolean);
-    method public void setProtocols(String[]);
-    method public final void setSNIMatchers(java.util.Collection<javax.net.ssl.SNIMatcher>);
-    method public final void setServerNames(java.util.List<javax.net.ssl.SNIServerName>);
-    method public final void setUseCipherSuitesOrder(boolean);
-    method public void setWantClientAuth(boolean);
-  }
-
-  public class SSLPeerUnverifiedException extends javax.net.ssl.SSLException {
-    ctor public SSLPeerUnverifiedException(String);
-  }
-
-  public final class SSLPermission extends java.security.BasicPermission {
-    ctor public SSLPermission(String);
-    ctor public SSLPermission(String, String);
-  }
-
-  public class SSLProtocolException extends javax.net.ssl.SSLException {
-    ctor public SSLProtocolException(String);
-  }
-
-  public abstract class SSLServerSocket extends java.net.ServerSocket {
-    ctor protected SSLServerSocket() throws java.io.IOException;
-    ctor protected SSLServerSocket(int) throws java.io.IOException;
-    ctor protected SSLServerSocket(int, int) throws java.io.IOException;
-    ctor protected SSLServerSocket(int, int, java.net.InetAddress) throws java.io.IOException;
-    method public abstract boolean getEnableSessionCreation();
-    method public abstract String[] getEnabledCipherSuites();
-    method public abstract String[] getEnabledProtocols();
-    method public abstract boolean getNeedClientAuth();
-    method public javax.net.ssl.SSLParameters getSSLParameters();
-    method public abstract String[] getSupportedCipherSuites();
-    method public abstract String[] getSupportedProtocols();
-    method public abstract boolean getUseClientMode();
-    method public abstract boolean getWantClientAuth();
-    method public abstract void setEnableSessionCreation(boolean);
-    method public abstract void setEnabledCipherSuites(String[]);
-    method public abstract void setEnabledProtocols(String[]);
-    method public abstract void setNeedClientAuth(boolean);
-    method public void setSSLParameters(javax.net.ssl.SSLParameters);
-    method public abstract void setUseClientMode(boolean);
-    method public abstract void setWantClientAuth(boolean);
-  }
-
-  public abstract class SSLServerSocketFactory extends javax.net.ServerSocketFactory {
-    ctor protected SSLServerSocketFactory();
-    method public static javax.net.ServerSocketFactory getDefault();
-    method public abstract String[] getDefaultCipherSuites();
-    method public abstract String[] getSupportedCipherSuites();
-  }
-
-  public interface SSLSession {
-    method public int getApplicationBufferSize();
-    method public String getCipherSuite();
-    method public long getCreationTime();
-    method public byte[] getId();
-    method public long getLastAccessedTime();
-    method public java.security.cert.Certificate[] getLocalCertificates();
-    method public java.security.Principal getLocalPrincipal();
-    method public int getPacketBufferSize();
-    method public javax.security.cert.X509Certificate[] getPeerCertificateChain() throws javax.net.ssl.SSLPeerUnverifiedException;
-    method public java.security.cert.Certificate[] getPeerCertificates() throws javax.net.ssl.SSLPeerUnverifiedException;
-    method public String getPeerHost();
-    method public int getPeerPort();
-    method public java.security.Principal getPeerPrincipal() throws javax.net.ssl.SSLPeerUnverifiedException;
-    method public String getProtocol();
-    method public javax.net.ssl.SSLSessionContext getSessionContext();
-    method public Object getValue(String);
-    method public String[] getValueNames();
-    method public void invalidate();
-    method public boolean isValid();
-    method public void putValue(String, Object);
-    method public void removeValue(String);
-  }
-
-  public class SSLSessionBindingEvent extends java.util.EventObject {
-    ctor public SSLSessionBindingEvent(javax.net.ssl.SSLSession, String);
-    method public String getName();
-    method public javax.net.ssl.SSLSession getSession();
-  }
-
-  public interface SSLSessionBindingListener extends java.util.EventListener {
-    method public void valueBound(javax.net.ssl.SSLSessionBindingEvent);
-    method public void valueUnbound(javax.net.ssl.SSLSessionBindingEvent);
-  }
-
-  public interface SSLSessionContext {
-    method public java.util.Enumeration<byte[]> getIds();
-    method public javax.net.ssl.SSLSession getSession(byte[]);
-    method public int getSessionCacheSize();
-    method public int getSessionTimeout();
-    method public void setSessionCacheSize(int) throws java.lang.IllegalArgumentException;
-    method public void setSessionTimeout(int) throws java.lang.IllegalArgumentException;
-  }
-
-  public abstract class SSLSocket extends java.net.Socket {
-    ctor protected SSLSocket();
-    ctor protected SSLSocket(String, int) throws java.io.IOException, java.net.UnknownHostException;
-    ctor protected SSLSocket(java.net.InetAddress, int) throws java.io.IOException;
-    ctor protected SSLSocket(String, int, java.net.InetAddress, int) throws java.io.IOException, java.net.UnknownHostException;
-    ctor protected SSLSocket(java.net.InetAddress, int, java.net.InetAddress, int) throws java.io.IOException;
-    method public abstract void addHandshakeCompletedListener(javax.net.ssl.HandshakeCompletedListener);
-    method public String getApplicationProtocol();
-    method public abstract boolean getEnableSessionCreation();
-    method public abstract String[] getEnabledCipherSuites();
-    method public abstract String[] getEnabledProtocols();
-    method public String getHandshakeApplicationProtocol();
-    method public java.util.function.BiFunction<javax.net.ssl.SSLSocket,java.util.List<java.lang.String>,java.lang.String> getHandshakeApplicationProtocolSelector();
-    method public javax.net.ssl.SSLSession getHandshakeSession();
-    method public abstract boolean getNeedClientAuth();
-    method public javax.net.ssl.SSLParameters getSSLParameters();
-    method public abstract javax.net.ssl.SSLSession getSession();
-    method public abstract String[] getSupportedCipherSuites();
-    method public abstract String[] getSupportedProtocols();
-    method public abstract boolean getUseClientMode();
-    method public abstract boolean getWantClientAuth();
-    method public abstract void removeHandshakeCompletedListener(javax.net.ssl.HandshakeCompletedListener);
-    method public abstract void setEnableSessionCreation(boolean);
-    method public abstract void setEnabledCipherSuites(String[]);
-    method public abstract void setEnabledProtocols(String[]);
-    method public void setHandshakeApplicationProtocolSelector(java.util.function.BiFunction<javax.net.ssl.SSLSocket,java.util.List<java.lang.String>,java.lang.String>);
-    method public abstract void setNeedClientAuth(boolean);
-    method public void setSSLParameters(javax.net.ssl.SSLParameters);
-    method public abstract void setUseClientMode(boolean);
-    method public abstract void setWantClientAuth(boolean);
-    method public abstract void startHandshake() throws java.io.IOException;
-  }
-
-  public abstract class SSLSocketFactory extends javax.net.SocketFactory {
-    ctor public SSLSocketFactory();
-    method public abstract java.net.Socket createSocket(java.net.Socket, String, int, boolean) throws java.io.IOException;
-    method public static javax.net.SocketFactory getDefault();
-    method public abstract String[] getDefaultCipherSuites();
-    method public abstract String[] getSupportedCipherSuites();
-  }
-
-  public final class StandardConstants {
-    field public static final int SNI_HOST_NAME = 0; // 0x0
-  }
-
-  public interface TrustManager {
-  }
-
-  public class TrustManagerFactory {
-    ctor protected TrustManagerFactory(javax.net.ssl.TrustManagerFactorySpi, java.security.Provider, String);
-    method public final String getAlgorithm();
-    method public static final String getDefaultAlgorithm();
-    method public static final javax.net.ssl.TrustManagerFactory getInstance(String) throws java.security.NoSuchAlgorithmException;
-    method public static final javax.net.ssl.TrustManagerFactory getInstance(String, String) throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException;
-    method public static final javax.net.ssl.TrustManagerFactory getInstance(String, java.security.Provider) throws java.security.NoSuchAlgorithmException;
-    method public final java.security.Provider getProvider();
-    method public final javax.net.ssl.TrustManager[] getTrustManagers();
-    method public final void init(java.security.KeyStore) throws java.security.KeyStoreException;
-    method public final void init(javax.net.ssl.ManagerFactoryParameters) throws java.security.InvalidAlgorithmParameterException;
-  }
-
-  public abstract class TrustManagerFactorySpi {
-    ctor public TrustManagerFactorySpi();
-    method protected abstract javax.net.ssl.TrustManager[] engineGetTrustManagers();
-    method protected abstract void engineInit(java.security.KeyStore) throws java.security.KeyStoreException;
-    method protected abstract void engineInit(javax.net.ssl.ManagerFactoryParameters) throws java.security.InvalidAlgorithmParameterException;
-  }
-
-  public abstract class X509ExtendedKeyManager implements javax.net.ssl.X509KeyManager {
-    ctor protected X509ExtendedKeyManager();
-    method public String chooseEngineClientAlias(String[], java.security.Principal[], javax.net.ssl.SSLEngine);
-    method public String chooseEngineServerAlias(String, java.security.Principal[], javax.net.ssl.SSLEngine);
-  }
-
-  public abstract class X509ExtendedTrustManager implements javax.net.ssl.X509TrustManager {
-    ctor public X509ExtendedTrustManager();
-    method public abstract void checkClientTrusted(java.security.cert.X509Certificate[], String, java.net.Socket) throws java.security.cert.CertificateException;
-    method public abstract void checkClientTrusted(java.security.cert.X509Certificate[], String, javax.net.ssl.SSLEngine) throws java.security.cert.CertificateException;
-    method public abstract void checkServerTrusted(java.security.cert.X509Certificate[], String, java.net.Socket) throws java.security.cert.CertificateException;
-    method public abstract void checkServerTrusted(java.security.cert.X509Certificate[], String, javax.net.ssl.SSLEngine) throws java.security.cert.CertificateException;
-  }
-
-  public interface X509KeyManager extends javax.net.ssl.KeyManager {
-    method public String chooseClientAlias(String[], java.security.Principal[], java.net.Socket);
-    method public String chooseServerAlias(String, java.security.Principal[], java.net.Socket);
-    method public java.security.cert.X509Certificate[] getCertificateChain(String);
-    method public String[] getClientAliases(String, java.security.Principal[]);
-    method public java.security.PrivateKey getPrivateKey(String);
-    method public String[] getServerAliases(String, java.security.Principal[]);
-  }
-
-  public interface X509TrustManager extends javax.net.ssl.TrustManager {
-    method public void checkClientTrusted(java.security.cert.X509Certificate[], String) throws java.security.cert.CertificateException;
-    method public void checkServerTrusted(java.security.cert.X509Certificate[], String) throws java.security.cert.CertificateException;
-    method public java.security.cert.X509Certificate[] getAcceptedIssuers();
-  }
-
-}
-
-package javax.security.auth {
-
-  public final class AuthPermission extends java.security.BasicPermission {
-    ctor public AuthPermission(String);
-    ctor public AuthPermission(String, String);
-  }
-
-  public class DestroyFailedException extends java.lang.Exception {
-    ctor public DestroyFailedException();
-    ctor public DestroyFailedException(String);
-  }
-
-  public interface Destroyable {
-    method public default void destroy() throws javax.security.auth.DestroyFailedException;
-    method public default boolean isDestroyed();
-  }
-
-  public final class PrivateCredentialPermission extends java.security.Permission {
-    ctor public PrivateCredentialPermission(String, String);
-    method public String getActions();
-    method public String getCredentialClass();
-    method public String[][] getPrincipals();
-    method public boolean implies(java.security.Permission);
-  }
-
-  public final class Subject implements java.io.Serializable {
-    ctor public Subject();
-    ctor public Subject(boolean, java.util.Set<? extends java.security.Principal>, java.util.Set<?>, java.util.Set<?>);
-    method public static <T> T doAs(javax.security.auth.Subject, java.security.PrivilegedAction<T>);
-    method public static <T> T doAs(javax.security.auth.Subject, java.security.PrivilegedExceptionAction<T>) throws java.security.PrivilegedActionException;
-    method public static <T> T doAsPrivileged(javax.security.auth.Subject, java.security.PrivilegedAction<T>, java.security.AccessControlContext);
-    method public static <T> T doAsPrivileged(javax.security.auth.Subject, java.security.PrivilegedExceptionAction<T>, java.security.AccessControlContext) throws java.security.PrivilegedActionException;
-    method public java.util.Set<java.security.Principal> getPrincipals();
-    method public <T extends java.security.Principal> java.util.Set<T> getPrincipals(Class<T>);
-    method public java.util.Set<java.lang.Object> getPrivateCredentials();
-    method public <T> java.util.Set<T> getPrivateCredentials(Class<T>);
-    method public java.util.Set<java.lang.Object> getPublicCredentials();
-    method public <T> java.util.Set<T> getPublicCredentials(Class<T>);
-    method public static javax.security.auth.Subject getSubject(java.security.AccessControlContext);
-    method public boolean isReadOnly();
-    method public void setReadOnly();
-  }
-
-  public class SubjectDomainCombiner implements java.security.DomainCombiner {
-    ctor public SubjectDomainCombiner(javax.security.auth.Subject);
-    method public java.security.ProtectionDomain[] combine(java.security.ProtectionDomain[], java.security.ProtectionDomain[]);
-    method public javax.security.auth.Subject getSubject();
-  }
-
-}
-
-package javax.security.auth.callback {
-
-  public interface Callback {
-  }
-
-  public interface CallbackHandler {
-    method public void handle(javax.security.auth.callback.Callback[]) throws java.io.IOException, javax.security.auth.callback.UnsupportedCallbackException;
-  }
-
-  public class PasswordCallback implements javax.security.auth.callback.Callback java.io.Serializable {
-    ctor public PasswordCallback(String, boolean);
-    method public void clearPassword();
-    method public char[] getPassword();
-    method public String getPrompt();
-    method public boolean isEchoOn();
-    method public void setPassword(char[]);
-  }
-
-  public class UnsupportedCallbackException extends java.lang.Exception {
-    ctor public UnsupportedCallbackException(javax.security.auth.callback.Callback);
-    ctor public UnsupportedCallbackException(javax.security.auth.callback.Callback, String);
-    method public javax.security.auth.callback.Callback getCallback();
-  }
-
-}
-
-package javax.security.auth.login {
-
-  public class LoginException extends java.security.GeneralSecurityException {
-    ctor public LoginException();
-    ctor public LoginException(String);
-  }
-
-}
-
-package javax.security.auth.x500 {
-
-  public final class X500Principal implements java.security.Principal java.io.Serializable {
-    ctor public X500Principal(String);
-    ctor public X500Principal(String, java.util.Map<java.lang.String,java.lang.String>);
-    ctor public X500Principal(byte[]);
-    ctor public X500Principal(java.io.InputStream);
-    method public byte[] getEncoded();
-    method public String getName();
-    method public String getName(String);
-    method public String getName(String, java.util.Map<java.lang.String,java.lang.String>);
-    field public static final String CANONICAL = "CANONICAL";
-    field public static final String RFC1779 = "RFC1779";
-    field public static final String RFC2253 = "RFC2253";
-  }
-
-}
-
-package javax.security.cert {
-
-  public abstract class Certificate {
-    ctor public Certificate();
-    method public abstract byte[] getEncoded() throws javax.security.cert.CertificateEncodingException;
-    method public abstract java.security.PublicKey getPublicKey();
-    method public abstract String toString();
-    method public abstract void verify(java.security.PublicKey) throws javax.security.cert.CertificateException, java.security.InvalidKeyException, java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException, java.security.SignatureException;
-    method public abstract void verify(java.security.PublicKey, String) throws javax.security.cert.CertificateException, java.security.InvalidKeyException, java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException, java.security.SignatureException;
-  }
-
-  public class CertificateEncodingException extends javax.security.cert.CertificateException {
-    ctor public CertificateEncodingException();
-    ctor public CertificateEncodingException(String);
-  }
-
-  public class CertificateException extends java.lang.Exception {
-    ctor public CertificateException();
-    ctor public CertificateException(String);
-  }
-
-  public class CertificateExpiredException extends javax.security.cert.CertificateException {
-    ctor public CertificateExpiredException();
-    ctor public CertificateExpiredException(String);
-  }
-
-  public class CertificateNotYetValidException extends javax.security.cert.CertificateException {
-    ctor public CertificateNotYetValidException();
-    ctor public CertificateNotYetValidException(String);
-  }
-
-  public class CertificateParsingException extends javax.security.cert.CertificateException {
-    ctor public CertificateParsingException();
-    ctor public CertificateParsingException(String);
-  }
-
-  public abstract class X509Certificate extends javax.security.cert.Certificate {
-    ctor public X509Certificate();
-    method public abstract void checkValidity() throws javax.security.cert.CertificateExpiredException, javax.security.cert.CertificateNotYetValidException;
-    method public abstract void checkValidity(java.util.Date) throws javax.security.cert.CertificateExpiredException, javax.security.cert.CertificateNotYetValidException;
-    method public static final javax.security.cert.X509Certificate getInstance(java.io.InputStream) throws javax.security.cert.CertificateException;
-    method public static final javax.security.cert.X509Certificate getInstance(byte[]) throws javax.security.cert.CertificateException;
-    method public abstract java.security.Principal getIssuerDN();
-    method public abstract java.util.Date getNotAfter();
-    method public abstract java.util.Date getNotBefore();
-    method public abstract java.math.BigInteger getSerialNumber();
-    method public abstract String getSigAlgName();
-    method public abstract String getSigAlgOID();
-    method public abstract byte[] getSigAlgParams();
-    method public abstract java.security.Principal getSubjectDN();
-    method public abstract int getVersion();
-  }
-
-}
-
-package javax.sql {
-
-  public interface CommonDataSource {
-    method public java.io.PrintWriter getLogWriter() throws java.sql.SQLException;
-    method public int getLoginTimeout() throws java.sql.SQLException;
-    method public java.util.logging.Logger getParentLogger() throws java.sql.SQLFeatureNotSupportedException;
-    method public void setLogWriter(java.io.PrintWriter) throws java.sql.SQLException;
-    method public void setLoginTimeout(int) throws java.sql.SQLException;
-  }
-
-  public class ConnectionEvent extends java.util.EventObject {
-    ctor public ConnectionEvent(javax.sql.PooledConnection);
-    ctor public ConnectionEvent(javax.sql.PooledConnection, java.sql.SQLException);
-    method public java.sql.SQLException getSQLException();
-  }
-
-  public interface ConnectionEventListener extends java.util.EventListener {
-    method public void connectionClosed(javax.sql.ConnectionEvent);
-    method public void connectionErrorOccurred(javax.sql.ConnectionEvent);
-  }
-
-  public interface ConnectionPoolDataSource extends javax.sql.CommonDataSource {
-    method public javax.sql.PooledConnection getPooledConnection() throws java.sql.SQLException;
-    method public javax.sql.PooledConnection getPooledConnection(String, String) throws java.sql.SQLException;
-  }
-
-  public interface DataSource extends javax.sql.CommonDataSource java.sql.Wrapper {
-    method public java.sql.Connection getConnection() throws java.sql.SQLException;
-    method public java.sql.Connection getConnection(String, String) throws java.sql.SQLException;
-  }
-
-  public interface PooledConnection {
-    method public void addConnectionEventListener(javax.sql.ConnectionEventListener);
-    method public void addStatementEventListener(javax.sql.StatementEventListener);
-    method public void close() throws java.sql.SQLException;
-    method public java.sql.Connection getConnection() throws java.sql.SQLException;
-    method public void removeConnectionEventListener(javax.sql.ConnectionEventListener);
-    method public void removeStatementEventListener(javax.sql.StatementEventListener);
-  }
-
-  public interface RowSet extends java.sql.ResultSet {
-    method public void addRowSetListener(javax.sql.RowSetListener);
-    method public void clearParameters() throws java.sql.SQLException;
-    method public void execute() throws java.sql.SQLException;
-    method public String getCommand();
-    method public String getDataSourceName();
-    method public boolean getEscapeProcessing() throws java.sql.SQLException;
-    method public int getMaxFieldSize() throws java.sql.SQLException;
-    method public int getMaxRows() throws java.sql.SQLException;
-    method public String getPassword();
-    method public int getQueryTimeout() throws java.sql.SQLException;
-    method public int getTransactionIsolation();
-    method public java.util.Map<java.lang.String,java.lang.Class<?>> getTypeMap() throws java.sql.SQLException;
-    method public String getUrl() throws java.sql.SQLException;
-    method public String getUsername();
-    method public boolean isReadOnly();
-    method public void removeRowSetListener(javax.sql.RowSetListener);
-    method public void setArray(int, java.sql.Array) throws java.sql.SQLException;
-    method public void setAsciiStream(int, java.io.InputStream, int) throws java.sql.SQLException;
-    method public void setAsciiStream(String, java.io.InputStream, int) throws java.sql.SQLException;
-    method public void setAsciiStream(int, java.io.InputStream) throws java.sql.SQLException;
-    method public void setAsciiStream(String, java.io.InputStream) throws java.sql.SQLException;
-    method public void setBigDecimal(int, java.math.BigDecimal) throws java.sql.SQLException;
-    method public void setBigDecimal(String, java.math.BigDecimal) throws java.sql.SQLException;
-    method public void setBinaryStream(int, java.io.InputStream, int) throws java.sql.SQLException;
-    method public void setBinaryStream(String, java.io.InputStream, int) throws java.sql.SQLException;
-    method public void setBinaryStream(int, java.io.InputStream) throws java.sql.SQLException;
-    method public void setBinaryStream(String, java.io.InputStream) throws java.sql.SQLException;
-    method public void setBlob(int, java.sql.Blob) throws java.sql.SQLException;
-    method public void setBlob(int, java.io.InputStream, long) throws java.sql.SQLException;
-    method public void setBlob(int, java.io.InputStream) throws java.sql.SQLException;
-    method public void setBlob(String, java.io.InputStream, long) throws java.sql.SQLException;
-    method public void setBlob(String, java.sql.Blob) throws java.sql.SQLException;
-    method public void setBlob(String, java.io.InputStream) throws java.sql.SQLException;
-    method public void setBoolean(int, boolean) throws java.sql.SQLException;
-    method public void setBoolean(String, boolean) throws java.sql.SQLException;
-    method public void setByte(int, byte) throws java.sql.SQLException;
-    method public void setByte(String, byte) throws java.sql.SQLException;
-    method public void setBytes(int, byte[]) throws java.sql.SQLException;
-    method public void setBytes(String, byte[]) throws java.sql.SQLException;
-    method public void setCharacterStream(int, java.io.Reader, int) throws java.sql.SQLException;
-    method public void setCharacterStream(String, java.io.Reader, int) throws java.sql.SQLException;
-    method public void setCharacterStream(int, java.io.Reader) throws java.sql.SQLException;
-    method public void setCharacterStream(String, java.io.Reader) throws java.sql.SQLException;
-    method public void setClob(int, java.sql.Clob) throws java.sql.SQLException;
-    method public void setClob(int, java.io.Reader, long) throws java.sql.SQLException;
-    method public void setClob(int, java.io.Reader) throws java.sql.SQLException;
-    method public void setClob(String, java.io.Reader, long) throws java.sql.SQLException;
-    method public void setClob(String, java.sql.Clob) throws java.sql.SQLException;
-    method public void setClob(String, java.io.Reader) throws java.sql.SQLException;
-    method public void setCommand(String) throws java.sql.SQLException;
-    method public void setConcurrency(int) throws java.sql.SQLException;
-    method public void setDataSourceName(String) throws java.sql.SQLException;
-    method public void setDate(int, java.sql.Date) throws java.sql.SQLException;
-    method public void setDate(int, java.sql.Date, java.util.Calendar) throws java.sql.SQLException;
-    method public void setDate(String, java.sql.Date) throws java.sql.SQLException;
-    method public void setDate(String, java.sql.Date, java.util.Calendar) throws java.sql.SQLException;
-    method public void setDouble(int, double) throws java.sql.SQLException;
-    method public void setDouble(String, double) throws java.sql.SQLException;
-    method public void setEscapeProcessing(boolean) throws java.sql.SQLException;
-    method public void setFloat(int, float) throws java.sql.SQLException;
-    method public void setFloat(String, float) throws java.sql.SQLException;
-    method public void setInt(int, int) throws java.sql.SQLException;
-    method public void setInt(String, int) throws java.sql.SQLException;
-    method public void setLong(int, long) throws java.sql.SQLException;
-    method public void setLong(String, long) throws java.sql.SQLException;
-    method public void setMaxFieldSize(int) throws java.sql.SQLException;
-    method public void setMaxRows(int) throws java.sql.SQLException;
-    method public void setNCharacterStream(int, java.io.Reader) throws java.sql.SQLException;
-    method public void setNCharacterStream(int, java.io.Reader, long) throws java.sql.SQLException;
-    method public void setNCharacterStream(String, java.io.Reader, long) throws java.sql.SQLException;
-    method public void setNCharacterStream(String, java.io.Reader) throws java.sql.SQLException;
-    method public void setNClob(String, java.sql.NClob) throws java.sql.SQLException;
-    method public void setNClob(String, java.io.Reader, long) throws java.sql.SQLException;
-    method public void setNClob(String, java.io.Reader) throws java.sql.SQLException;
-    method public void setNClob(int, java.io.Reader, long) throws java.sql.SQLException;
-    method public void setNClob(int, java.sql.NClob) throws java.sql.SQLException;
-    method public void setNClob(int, java.io.Reader) throws java.sql.SQLException;
-    method public void setNString(int, String) throws java.sql.SQLException;
-    method public void setNString(String, String) throws java.sql.SQLException;
-    method public void setNull(int, int) throws java.sql.SQLException;
-    method public void setNull(String, int) throws java.sql.SQLException;
-    method public void setNull(int, int, String) throws java.sql.SQLException;
-    method public void setNull(String, int, String) throws java.sql.SQLException;
-    method public void setObject(int, Object, int, int) throws java.sql.SQLException;
-    method public void setObject(String, Object, int, int) throws java.sql.SQLException;
-    method public void setObject(int, Object, int) throws java.sql.SQLException;
-    method public void setObject(String, Object, int) throws java.sql.SQLException;
-    method public void setObject(String, Object) throws java.sql.SQLException;
-    method public void setObject(int, Object) throws java.sql.SQLException;
-    method public void setPassword(String) throws java.sql.SQLException;
-    method public void setQueryTimeout(int) throws java.sql.SQLException;
-    method public void setReadOnly(boolean) throws java.sql.SQLException;
-    method public void setRef(int, java.sql.Ref) throws java.sql.SQLException;
-    method public void setRowId(int, java.sql.RowId) throws java.sql.SQLException;
-    method public void setRowId(String, java.sql.RowId) throws java.sql.SQLException;
-    method public void setSQLXML(int, java.sql.SQLXML) throws java.sql.SQLException;
-    method public void setSQLXML(String, java.sql.SQLXML) throws java.sql.SQLException;
-    method public void setShort(int, short) throws java.sql.SQLException;
-    method public void setShort(String, short) throws java.sql.SQLException;
-    method public void setString(int, String) throws java.sql.SQLException;
-    method public void setString(String, String) throws java.sql.SQLException;
-    method public void setTime(int, java.sql.Time) throws java.sql.SQLException;
-    method public void setTime(int, java.sql.Time, java.util.Calendar) throws java.sql.SQLException;
-    method public void setTime(String, java.sql.Time) throws java.sql.SQLException;
-    method public void setTime(String, java.sql.Time, java.util.Calendar) throws java.sql.SQLException;
-    method public void setTimestamp(int, java.sql.Timestamp) throws java.sql.SQLException;
-    method public void setTimestamp(String, java.sql.Timestamp) throws java.sql.SQLException;
-    method public void setTimestamp(int, java.sql.Timestamp, java.util.Calendar) throws java.sql.SQLException;
-    method public void setTimestamp(String, java.sql.Timestamp, java.util.Calendar) throws java.sql.SQLException;
-    method public void setTransactionIsolation(int) throws java.sql.SQLException;
-    method public void setType(int) throws java.sql.SQLException;
-    method public void setTypeMap(java.util.Map<java.lang.String,java.lang.Class<?>>) throws java.sql.SQLException;
-    method public void setURL(int, java.net.URL) throws java.sql.SQLException;
-    method public void setUrl(String) throws java.sql.SQLException;
-    method public void setUsername(String) throws java.sql.SQLException;
-  }
-
-  public class RowSetEvent extends java.util.EventObject {
-    ctor public RowSetEvent(javax.sql.RowSet);
-  }
-
-  public interface RowSetInternal {
-    method public java.sql.Connection getConnection() throws java.sql.SQLException;
-    method public java.sql.ResultSet getOriginal() throws java.sql.SQLException;
-    method public java.sql.ResultSet getOriginalRow() throws java.sql.SQLException;
-    method public Object[] getParams() throws java.sql.SQLException;
-    method public void setMetaData(javax.sql.RowSetMetaData) throws java.sql.SQLException;
-  }
-
-  public interface RowSetListener extends java.util.EventListener {
-    method public void cursorMoved(javax.sql.RowSetEvent);
-    method public void rowChanged(javax.sql.RowSetEvent);
-    method public void rowSetChanged(javax.sql.RowSetEvent);
-  }
-
-  public interface RowSetMetaData extends java.sql.ResultSetMetaData {
-    method public void setAutoIncrement(int, boolean) throws java.sql.SQLException;
-    method public void setCaseSensitive(int, boolean) throws java.sql.SQLException;
-    method public void setCatalogName(int, String) throws java.sql.SQLException;
-    method public void setColumnCount(int) throws java.sql.SQLException;
-    method public void setColumnDisplaySize(int, int) throws java.sql.SQLException;
-    method public void setColumnLabel(int, String) throws java.sql.SQLException;
-    method public void setColumnName(int, String) throws java.sql.SQLException;
-    method public void setColumnType(int, int) throws java.sql.SQLException;
-    method public void setColumnTypeName(int, String) throws java.sql.SQLException;
-    method public void setCurrency(int, boolean) throws java.sql.SQLException;
-    method public void setNullable(int, int) throws java.sql.SQLException;
-    method public void setPrecision(int, int) throws java.sql.SQLException;
-    method public void setScale(int, int) throws java.sql.SQLException;
-    method public void setSchemaName(int, String) throws java.sql.SQLException;
-    method public void setSearchable(int, boolean) throws java.sql.SQLException;
-    method public void setSigned(int, boolean) throws java.sql.SQLException;
-    method public void setTableName(int, String) throws java.sql.SQLException;
-  }
-
-  public interface RowSetReader {
-    method public void readData(javax.sql.RowSetInternal) throws java.sql.SQLException;
-  }
-
-  public interface RowSetWriter {
-    method public boolean writeData(javax.sql.RowSetInternal) throws java.sql.SQLException;
-  }
-
-  public class StatementEvent extends java.util.EventObject {
-    ctor public StatementEvent(javax.sql.PooledConnection, java.sql.PreparedStatement);
-    ctor public StatementEvent(javax.sql.PooledConnection, java.sql.PreparedStatement, java.sql.SQLException);
-    method public java.sql.SQLException getSQLException();
-    method public java.sql.PreparedStatement getStatement();
-  }
-
-  public interface StatementEventListener extends java.util.EventListener {
-    method public void statementClosed(javax.sql.StatementEvent);
-    method public void statementErrorOccurred(javax.sql.StatementEvent);
-  }
-
-}
-
-package javax.xml {
-
-  public final class XMLConstants {
-    field public static final String DEFAULT_NS_PREFIX = "";
-    field public static final String FEATURE_SECURE_PROCESSING = "http://javax.xml.XMLConstants/feature/secure-processing";
-    field public static final String NULL_NS_URI = "";
-    field public static final String RELAXNG_NS_URI = "http://relaxng.org/ns/structure/1.0";
-    field public static final String W3C_XML_SCHEMA_INSTANCE_NS_URI = "http://www.w3.org/2001/XMLSchema-instance";
-    field public static final String W3C_XML_SCHEMA_NS_URI = "http://www.w3.org/2001/XMLSchema";
-    field public static final String W3C_XPATH_DATATYPE_NS_URI = "http://www.w3.org/2003/11/xpath-datatypes";
-    field public static final String XMLNS_ATTRIBUTE = "xmlns";
-    field public static final String XMLNS_ATTRIBUTE_NS_URI = "http://www.w3.org/2000/xmlns/";
-    field public static final String XML_DTD_NS_URI = "http://www.w3.org/TR/REC-xml";
-    field public static final String XML_NS_PREFIX = "xml";
-    field public static final String XML_NS_URI = "http://www.w3.org/XML/1998/namespace";
-  }
-
-}
-
-package javax.xml.datatype {
-
-  public class DatatypeConfigurationException extends java.lang.Exception {
-    ctor public DatatypeConfigurationException();
-    ctor public DatatypeConfigurationException(String);
-    ctor public DatatypeConfigurationException(String, Throwable);
-    ctor public DatatypeConfigurationException(Throwable);
-  }
-
-  public final class DatatypeConstants {
-    field public static final int APRIL = 4; // 0x4
-    field public static final int AUGUST = 8; // 0x8
-    field public static final javax.xml.namespace.QName DATE;
-    field public static final javax.xml.namespace.QName DATETIME;
-    field public static final javax.xml.datatype.DatatypeConstants.Field DAYS;
-    field public static final int DECEMBER = 12; // 0xc
-    field public static final javax.xml.namespace.QName DURATION;
-    field public static final javax.xml.namespace.QName DURATION_DAYTIME;
-    field public static final javax.xml.namespace.QName DURATION_YEARMONTH;
-    field public static final int EQUAL = 0; // 0x0
-    field public static final int FEBRUARY = 2; // 0x2
-    field public static final int FIELD_UNDEFINED = -2147483648; // 0x80000000
-    field public static final javax.xml.namespace.QName GDAY;
-    field public static final javax.xml.namespace.QName GMONTH;
-    field public static final javax.xml.namespace.QName GMONTHDAY;
-    field public static final int GREATER = 1; // 0x1
-    field public static final javax.xml.namespace.QName GYEAR;
-    field public static final javax.xml.namespace.QName GYEARMONTH;
-    field public static final javax.xml.datatype.DatatypeConstants.Field HOURS;
-    field public static final int INDETERMINATE = 2; // 0x2
-    field public static final int JANUARY = 1; // 0x1
-    field public static final int JULY = 7; // 0x7
-    field public static final int JUNE = 6; // 0x6
-    field public static final int LESSER = -1; // 0xffffffff
-    field public static final int MARCH = 3; // 0x3
-    field public static final int MAX_TIMEZONE_OFFSET = -840; // 0xfffffcb8
-    field public static final int MAY = 5; // 0x5
-    field public static final javax.xml.datatype.DatatypeConstants.Field MINUTES;
-    field public static final int MIN_TIMEZONE_OFFSET = 840; // 0x348
-    field public static final javax.xml.datatype.DatatypeConstants.Field MONTHS;
-    field public static final int NOVEMBER = 11; // 0xb
-    field public static final int OCTOBER = 10; // 0xa
-    field public static final javax.xml.datatype.DatatypeConstants.Field SECONDS;
-    field public static final int SEPTEMBER = 9; // 0x9
-    field public static final javax.xml.namespace.QName TIME;
-    field public static final javax.xml.datatype.DatatypeConstants.Field YEARS;
-  }
-
-  public static final class DatatypeConstants.Field {
-    method public int getId();
-  }
-
-  public abstract class DatatypeFactory {
-    ctor protected DatatypeFactory();
-    method public abstract javax.xml.datatype.Duration newDuration(String);
-    method public abstract javax.xml.datatype.Duration newDuration(long);
-    method public abstract javax.xml.datatype.Duration newDuration(boolean, java.math.BigInteger, java.math.BigInteger, java.math.BigInteger, java.math.BigInteger, java.math.BigInteger, java.math.BigDecimal);
-    method public javax.xml.datatype.Duration newDuration(boolean, int, int, int, int, int, int);
-    method public javax.xml.datatype.Duration newDurationDayTime(String);
-    method public javax.xml.datatype.Duration newDurationDayTime(long);
-    method public javax.xml.datatype.Duration newDurationDayTime(boolean, java.math.BigInteger, java.math.BigInteger, java.math.BigInteger, java.math.BigInteger);
-    method public javax.xml.datatype.Duration newDurationDayTime(boolean, int, int, int, int);
-    method public javax.xml.datatype.Duration newDurationYearMonth(String);
-    method public javax.xml.datatype.Duration newDurationYearMonth(long);
-    method public javax.xml.datatype.Duration newDurationYearMonth(boolean, java.math.BigInteger, java.math.BigInteger);
-    method public javax.xml.datatype.Duration newDurationYearMonth(boolean, int, int);
-    method public static javax.xml.datatype.DatatypeFactory newInstance() throws javax.xml.datatype.DatatypeConfigurationException;
-    method public static javax.xml.datatype.DatatypeFactory newInstance(String, ClassLoader) throws javax.xml.datatype.DatatypeConfigurationException;
-    method public abstract javax.xml.datatype.XMLGregorianCalendar newXMLGregorianCalendar();
-    method public abstract javax.xml.datatype.XMLGregorianCalendar newXMLGregorianCalendar(String);
-    method public abstract javax.xml.datatype.XMLGregorianCalendar newXMLGregorianCalendar(java.util.GregorianCalendar);
-    method public abstract javax.xml.datatype.XMLGregorianCalendar newXMLGregorianCalendar(java.math.BigInteger, int, int, int, int, int, java.math.BigDecimal, int);
-    method public javax.xml.datatype.XMLGregorianCalendar newXMLGregorianCalendar(int, int, int, int, int, int, int, int);
-    method public javax.xml.datatype.XMLGregorianCalendar newXMLGregorianCalendarDate(int, int, int, int);
-    method public javax.xml.datatype.XMLGregorianCalendar newXMLGregorianCalendarTime(int, int, int, int);
-    method public javax.xml.datatype.XMLGregorianCalendar newXMLGregorianCalendarTime(int, int, int, java.math.BigDecimal, int);
-    method public javax.xml.datatype.XMLGregorianCalendar newXMLGregorianCalendarTime(int, int, int, int, int);
-    field public static final String DATATYPEFACTORY_IMPLEMENTATION_CLASS;
-    field public static final String DATATYPEFACTORY_PROPERTY = "javax.xml.datatype.DatatypeFactory";
-  }
-
-  public abstract class Duration {
-    ctor public Duration();
-    method public abstract javax.xml.datatype.Duration add(javax.xml.datatype.Duration);
-    method public abstract void addTo(java.util.Calendar);
-    method public void addTo(java.util.Date);
-    method public abstract int compare(javax.xml.datatype.Duration);
-    method public int getDays();
-    method public abstract Number getField(javax.xml.datatype.DatatypeConstants.Field);
-    method public int getHours();
-    method public int getMinutes();
-    method public int getMonths();
-    method public int getSeconds();
-    method public abstract int getSign();
-    method public long getTimeInMillis(java.util.Calendar);
-    method public long getTimeInMillis(java.util.Date);
-    method public javax.xml.namespace.QName getXMLSchemaType();
-    method public int getYears();
-    method public abstract int hashCode();
-    method public boolean isLongerThan(javax.xml.datatype.Duration);
-    method public abstract boolean isSet(javax.xml.datatype.DatatypeConstants.Field);
-    method public boolean isShorterThan(javax.xml.datatype.Duration);
-    method public javax.xml.datatype.Duration multiply(int);
-    method public abstract javax.xml.datatype.Duration multiply(java.math.BigDecimal);
-    method public abstract javax.xml.datatype.Duration negate();
-    method public abstract javax.xml.datatype.Duration normalizeWith(java.util.Calendar);
-    method public javax.xml.datatype.Duration subtract(javax.xml.datatype.Duration);
-  }
-
-  public abstract class XMLGregorianCalendar implements java.lang.Cloneable {
-    ctor public XMLGregorianCalendar();
-    method public abstract void add(javax.xml.datatype.Duration);
-    method public abstract void clear();
-    method public abstract Object clone();
-    method public abstract int compare(javax.xml.datatype.XMLGregorianCalendar);
-    method public abstract int getDay();
-    method public abstract java.math.BigInteger getEon();
-    method public abstract java.math.BigInteger getEonAndYear();
-    method public abstract java.math.BigDecimal getFractionalSecond();
-    method public abstract int getHour();
-    method public int getMillisecond();
-    method public abstract int getMinute();
-    method public abstract int getMonth();
-    method public abstract int getSecond();
-    method public abstract java.util.TimeZone getTimeZone(int);
-    method public abstract int getTimezone();
-    method public abstract javax.xml.namespace.QName getXMLSchemaType();
-    method public abstract int getYear();
-    method public abstract boolean isValid();
-    method public abstract javax.xml.datatype.XMLGregorianCalendar normalize();
-    method public abstract void reset();
-    method public abstract void setDay(int);
-    method public abstract void setFractionalSecond(java.math.BigDecimal);
-    method public abstract void setHour(int);
-    method public abstract void setMillisecond(int);
-    method public abstract void setMinute(int);
-    method public abstract void setMonth(int);
-    method public abstract void setSecond(int);
-    method public void setTime(int, int, int);
-    method public void setTime(int, int, int, java.math.BigDecimal);
-    method public void setTime(int, int, int, int);
-    method public abstract void setTimezone(int);
-    method public abstract void setYear(java.math.BigInteger);
-    method public abstract void setYear(int);
-    method public abstract java.util.GregorianCalendar toGregorianCalendar();
-    method public abstract java.util.GregorianCalendar toGregorianCalendar(java.util.TimeZone, java.util.Locale, javax.xml.datatype.XMLGregorianCalendar);
-    method public abstract String toXMLFormat();
-  }
-
-}
-
-package javax.xml.namespace {
-
-  public interface NamespaceContext {
-    method public String getNamespaceURI(String);
-    method public String getPrefix(String);
-    method public java.util.Iterator getPrefixes(String);
-  }
-
-  public class QName implements java.io.Serializable {
-    ctor public QName(String, String);
-    ctor public QName(String, String, String);
-    ctor public QName(String);
-    method public final boolean equals(Object);
-    method public String getLocalPart();
-    method public String getNamespaceURI();
-    method public String getPrefix();
-    method public final int hashCode();
-    method public static javax.xml.namespace.QName valueOf(String);
-  }
-
-}
-
-package javax.xml.parsers {
-
-  public abstract class DocumentBuilder {
-    ctor protected DocumentBuilder();
-    method public abstract org.w3c.dom.DOMImplementation getDOMImplementation();
-    method public javax.xml.validation.Schema getSchema();
-    method public abstract boolean isNamespaceAware();
-    method public abstract boolean isValidating();
-    method public boolean isXIncludeAware();
-    method public abstract org.w3c.dom.Document newDocument();
-    method public org.w3c.dom.Document parse(java.io.InputStream) throws java.io.IOException, org.xml.sax.SAXException;
-    method public org.w3c.dom.Document parse(java.io.InputStream, String) throws java.io.IOException, org.xml.sax.SAXException;
-    method public org.w3c.dom.Document parse(String) throws java.io.IOException, org.xml.sax.SAXException;
-    method public org.w3c.dom.Document parse(java.io.File) throws java.io.IOException, org.xml.sax.SAXException;
-    method public abstract org.w3c.dom.Document parse(org.xml.sax.InputSource) throws java.io.IOException, org.xml.sax.SAXException;
-    method public void reset();
-    method public abstract void setEntityResolver(org.xml.sax.EntityResolver);
-    method public abstract void setErrorHandler(org.xml.sax.ErrorHandler);
-  }
-
-  public abstract class DocumentBuilderFactory {
-    ctor protected DocumentBuilderFactory();
-    method public abstract Object getAttribute(String) throws java.lang.IllegalArgumentException;
-    method public abstract boolean getFeature(String) throws javax.xml.parsers.ParserConfigurationException;
-    method public javax.xml.validation.Schema getSchema();
-    method public boolean isCoalescing();
-    method public boolean isExpandEntityReferences();
-    method public boolean isIgnoringComments();
-    method public boolean isIgnoringElementContentWhitespace();
-    method public boolean isNamespaceAware();
-    method public boolean isValidating();
-    method public boolean isXIncludeAware();
-    method public abstract javax.xml.parsers.DocumentBuilder newDocumentBuilder() throws javax.xml.parsers.ParserConfigurationException;
-    method public static javax.xml.parsers.DocumentBuilderFactory newInstance();
-    method public static javax.xml.parsers.DocumentBuilderFactory newInstance(String, ClassLoader);
-    method public abstract void setAttribute(String, Object) throws java.lang.IllegalArgumentException;
-    method public void setCoalescing(boolean);
-    method public void setExpandEntityReferences(boolean);
-    method public abstract void setFeature(String, boolean) throws javax.xml.parsers.ParserConfigurationException;
-    method public void setIgnoringComments(boolean);
-    method public void setIgnoringElementContentWhitespace(boolean);
-    method public void setNamespaceAware(boolean);
-    method public void setSchema(javax.xml.validation.Schema);
-    method public void setValidating(boolean);
-    method public void setXIncludeAware(boolean);
-  }
-
-  public class FactoryConfigurationError extends java.lang.Error {
-    ctor public FactoryConfigurationError();
-    ctor public FactoryConfigurationError(String);
-    ctor public FactoryConfigurationError(Exception);
-    ctor public FactoryConfigurationError(Exception, String);
-    method public Exception getException();
-  }
-
-  public class ParserConfigurationException extends java.lang.Exception {
-    ctor public ParserConfigurationException();
-    ctor public ParserConfigurationException(String);
-  }
-
-  public abstract class SAXParser {
-    ctor protected SAXParser();
-    method public abstract org.xml.sax.Parser getParser() throws org.xml.sax.SAXException;
-    method public abstract Object getProperty(String) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
-    method public javax.xml.validation.Schema getSchema();
-    method public abstract org.xml.sax.XMLReader getXMLReader() throws org.xml.sax.SAXException;
-    method public abstract boolean isNamespaceAware();
-    method public abstract boolean isValidating();
-    method public boolean isXIncludeAware();
-    method public void parse(java.io.InputStream, org.xml.sax.HandlerBase) throws java.io.IOException, org.xml.sax.SAXException;
-    method public void parse(java.io.InputStream, org.xml.sax.HandlerBase, String) throws java.io.IOException, org.xml.sax.SAXException;
-    method public void parse(java.io.InputStream, org.xml.sax.helpers.DefaultHandler) throws java.io.IOException, org.xml.sax.SAXException;
-    method public void parse(java.io.InputStream, org.xml.sax.helpers.DefaultHandler, String) throws java.io.IOException, org.xml.sax.SAXException;
-    method public void parse(String, org.xml.sax.HandlerBase) throws java.io.IOException, org.xml.sax.SAXException;
-    method public void parse(String, org.xml.sax.helpers.DefaultHandler) throws java.io.IOException, org.xml.sax.SAXException;
-    method public void parse(java.io.File, org.xml.sax.HandlerBase) throws java.io.IOException, org.xml.sax.SAXException;
-    method public void parse(java.io.File, org.xml.sax.helpers.DefaultHandler) throws java.io.IOException, org.xml.sax.SAXException;
-    method public void parse(org.xml.sax.InputSource, org.xml.sax.HandlerBase) throws java.io.IOException, org.xml.sax.SAXException;
-    method public void parse(org.xml.sax.InputSource, org.xml.sax.helpers.DefaultHandler) throws java.io.IOException, org.xml.sax.SAXException;
-    method public void reset();
-    method public abstract void setProperty(String, Object) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
-  }
-
-  public abstract class SAXParserFactory {
-    ctor protected SAXParserFactory();
-    method public abstract boolean getFeature(String) throws javax.xml.parsers.ParserConfigurationException, org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
-    method public javax.xml.validation.Schema getSchema();
-    method public boolean isNamespaceAware();
-    method public boolean isValidating();
-    method public boolean isXIncludeAware();
-    method public static javax.xml.parsers.SAXParserFactory newInstance();
-    method public static javax.xml.parsers.SAXParserFactory newInstance(String, ClassLoader);
-    method public abstract javax.xml.parsers.SAXParser newSAXParser() throws javax.xml.parsers.ParserConfigurationException, org.xml.sax.SAXException;
-    method public abstract void setFeature(String, boolean) throws javax.xml.parsers.ParserConfigurationException, org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
-    method public void setNamespaceAware(boolean);
-    method public void setSchema(javax.xml.validation.Schema);
-    method public void setValidating(boolean);
-    method public void setXIncludeAware(boolean);
-  }
-
-}
-
-package javax.xml.transform {
-
-  public interface ErrorListener {
-    method public void error(javax.xml.transform.TransformerException) throws javax.xml.transform.TransformerException;
-    method public void fatalError(javax.xml.transform.TransformerException) throws javax.xml.transform.TransformerException;
-    method public void warning(javax.xml.transform.TransformerException) throws javax.xml.transform.TransformerException;
-  }
-
-  public class OutputKeys {
-    field public static final String CDATA_SECTION_ELEMENTS = "cdata-section-elements";
-    field public static final String DOCTYPE_PUBLIC = "doctype-public";
-    field public static final String DOCTYPE_SYSTEM = "doctype-system";
-    field public static final String ENCODING = "encoding";
-    field public static final String INDENT = "indent";
-    field public static final String MEDIA_TYPE = "media-type";
-    field public static final String METHOD = "method";
-    field public static final String OMIT_XML_DECLARATION = "omit-xml-declaration";
-    field public static final String STANDALONE = "standalone";
-    field public static final String VERSION = "version";
-  }
-
-  public interface Result {
-    method public String getSystemId();
-    method public void setSystemId(String);
-    field public static final String PI_DISABLE_OUTPUT_ESCAPING = "javax.xml.transform.disable-output-escaping";
-    field public static final String PI_ENABLE_OUTPUT_ESCAPING = "javax.xml.transform.enable-output-escaping";
-  }
-
-  public interface Source {
-    method public String getSystemId();
-    method public void setSystemId(String);
-  }
-
-  public interface SourceLocator {
-    method public int getColumnNumber();
-    method public int getLineNumber();
-    method public String getPublicId();
-    method public String getSystemId();
-  }
-
-  public interface Templates {
-    method public java.util.Properties getOutputProperties();
-    method public javax.xml.transform.Transformer newTransformer() throws javax.xml.transform.TransformerConfigurationException;
-  }
-
-  public abstract class Transformer {
-    ctor protected Transformer();
-    method public abstract void clearParameters();
-    method public abstract javax.xml.transform.ErrorListener getErrorListener();
-    method public abstract java.util.Properties getOutputProperties();
-    method public abstract String getOutputProperty(String) throws java.lang.IllegalArgumentException;
-    method public abstract Object getParameter(String);
-    method public abstract javax.xml.transform.URIResolver getURIResolver();
-    method public void reset();
-    method public abstract void setErrorListener(javax.xml.transform.ErrorListener) throws java.lang.IllegalArgumentException;
-    method public abstract void setOutputProperties(java.util.Properties);
-    method public abstract void setOutputProperty(String, String) throws java.lang.IllegalArgumentException;
-    method public abstract void setParameter(String, Object);
-    method public abstract void setURIResolver(javax.xml.transform.URIResolver);
-    method public abstract void transform(javax.xml.transform.Source, javax.xml.transform.Result) throws javax.xml.transform.TransformerException;
-  }
-
-  public class TransformerConfigurationException extends javax.xml.transform.TransformerException {
-    ctor public TransformerConfigurationException();
-    ctor public TransformerConfigurationException(String);
-    ctor public TransformerConfigurationException(Throwable);
-    ctor public TransformerConfigurationException(String, Throwable);
-    ctor public TransformerConfigurationException(String, javax.xml.transform.SourceLocator);
-    ctor public TransformerConfigurationException(String, javax.xml.transform.SourceLocator, Throwable);
-  }
-
-  public class TransformerException extends java.lang.Exception {
-    ctor public TransformerException(String);
-    ctor public TransformerException(Throwable);
-    ctor public TransformerException(String, Throwable);
-    ctor public TransformerException(String, javax.xml.transform.SourceLocator);
-    ctor public TransformerException(String, javax.xml.transform.SourceLocator, Throwable);
-    method public Throwable getException();
-    method public String getLocationAsString();
-    method public javax.xml.transform.SourceLocator getLocator();
-    method public String getMessageAndLocation();
-    method public void setLocator(javax.xml.transform.SourceLocator);
-  }
-
-  public abstract class TransformerFactory {
-    ctor protected TransformerFactory();
-    method public abstract javax.xml.transform.Source getAssociatedStylesheet(javax.xml.transform.Source, String, String, String) throws javax.xml.transform.TransformerConfigurationException;
-    method public abstract Object getAttribute(String);
-    method public abstract javax.xml.transform.ErrorListener getErrorListener();
-    method public abstract boolean getFeature(String);
-    method public abstract javax.xml.transform.URIResolver getURIResolver();
-    method public static javax.xml.transform.TransformerFactory newInstance() throws javax.xml.transform.TransformerFactoryConfigurationError;
-    method public static javax.xml.transform.TransformerFactory newInstance(String, ClassLoader) throws javax.xml.transform.TransformerFactoryConfigurationError;
-    method public abstract javax.xml.transform.Templates newTemplates(javax.xml.transform.Source) throws javax.xml.transform.TransformerConfigurationException;
-    method public abstract javax.xml.transform.Transformer newTransformer(javax.xml.transform.Source) throws javax.xml.transform.TransformerConfigurationException;
-    method public abstract javax.xml.transform.Transformer newTransformer() throws javax.xml.transform.TransformerConfigurationException;
-    method public abstract void setAttribute(String, Object);
-    method public abstract void setErrorListener(javax.xml.transform.ErrorListener);
-    method public abstract void setFeature(String, boolean) throws javax.xml.transform.TransformerConfigurationException;
-    method public abstract void setURIResolver(javax.xml.transform.URIResolver);
-  }
-
-  public class TransformerFactoryConfigurationError extends java.lang.Error {
-    ctor public TransformerFactoryConfigurationError();
-    ctor public TransformerFactoryConfigurationError(String);
-    ctor public TransformerFactoryConfigurationError(Exception);
-    ctor public TransformerFactoryConfigurationError(Exception, String);
-    method public Exception getException();
-  }
-
-  public interface URIResolver {
-    method public javax.xml.transform.Source resolve(String, String) throws javax.xml.transform.TransformerException;
-  }
-
-}
-
-package javax.xml.transform.dom {
-
-  public interface DOMLocator extends javax.xml.transform.SourceLocator {
-    method public org.w3c.dom.Node getOriginatingNode();
-  }
-
-  public class DOMResult implements javax.xml.transform.Result {
-    ctor public DOMResult();
-    ctor public DOMResult(org.w3c.dom.Node);
-    ctor public DOMResult(org.w3c.dom.Node, String);
-    ctor public DOMResult(org.w3c.dom.Node, org.w3c.dom.Node);
-    ctor public DOMResult(org.w3c.dom.Node, org.w3c.dom.Node, String);
-    method public org.w3c.dom.Node getNextSibling();
-    method public org.w3c.dom.Node getNode();
-    method public String getSystemId();
-    method public void setNextSibling(org.w3c.dom.Node);
-    method public void setNode(org.w3c.dom.Node);
-    method public void setSystemId(String);
-    field public static final String FEATURE = "http://javax.xml.transform.dom.DOMResult/feature";
-  }
-
-  public class DOMSource implements javax.xml.transform.Source {
-    ctor public DOMSource();
-    ctor public DOMSource(org.w3c.dom.Node);
-    ctor public DOMSource(org.w3c.dom.Node, String);
-    method public org.w3c.dom.Node getNode();
-    method public String getSystemId();
-    method public void setNode(org.w3c.dom.Node);
-    method public void setSystemId(String);
-    field public static final String FEATURE = "http://javax.xml.transform.dom.DOMSource/feature";
-  }
-
-}
-
-package javax.xml.transform.sax {
-
-  public class SAXResult implements javax.xml.transform.Result {
-    ctor public SAXResult();
-    ctor public SAXResult(org.xml.sax.ContentHandler);
-    method public org.xml.sax.ContentHandler getHandler();
-    method public org.xml.sax.ext.LexicalHandler getLexicalHandler();
-    method public String getSystemId();
-    method public void setHandler(org.xml.sax.ContentHandler);
-    method public void setLexicalHandler(org.xml.sax.ext.LexicalHandler);
-    method public void setSystemId(String);
-    field public static final String FEATURE = "http://javax.xml.transform.sax.SAXResult/feature";
-  }
-
-  public class SAXSource implements javax.xml.transform.Source {
-    ctor public SAXSource();
-    ctor public SAXSource(org.xml.sax.XMLReader, org.xml.sax.InputSource);
-    ctor public SAXSource(org.xml.sax.InputSource);
-    method public org.xml.sax.InputSource getInputSource();
-    method public String getSystemId();
-    method public org.xml.sax.XMLReader getXMLReader();
-    method public void setInputSource(org.xml.sax.InputSource);
-    method public void setSystemId(String);
-    method public void setXMLReader(org.xml.sax.XMLReader);
-    method public static org.xml.sax.InputSource sourceToInputSource(javax.xml.transform.Source);
-    field public static final String FEATURE = "http://javax.xml.transform.sax.SAXSource/feature";
-  }
-
-  public abstract class SAXTransformerFactory extends javax.xml.transform.TransformerFactory {
-    ctor protected SAXTransformerFactory();
-    method public abstract javax.xml.transform.sax.TemplatesHandler newTemplatesHandler() throws javax.xml.transform.TransformerConfigurationException;
-    method public abstract javax.xml.transform.sax.TransformerHandler newTransformerHandler(javax.xml.transform.Source) throws javax.xml.transform.TransformerConfigurationException;
-    method public abstract javax.xml.transform.sax.TransformerHandler newTransformerHandler(javax.xml.transform.Templates) throws javax.xml.transform.TransformerConfigurationException;
-    method public abstract javax.xml.transform.sax.TransformerHandler newTransformerHandler() throws javax.xml.transform.TransformerConfigurationException;
-    method public abstract org.xml.sax.XMLFilter newXMLFilter(javax.xml.transform.Source) throws javax.xml.transform.TransformerConfigurationException;
-    method public abstract org.xml.sax.XMLFilter newXMLFilter(javax.xml.transform.Templates) throws javax.xml.transform.TransformerConfigurationException;
-    field public static final String FEATURE = "http://javax.xml.transform.sax.SAXTransformerFactory/feature";
-    field public static final String FEATURE_XMLFILTER = "http://javax.xml.transform.sax.SAXTransformerFactory/feature/xmlfilter";
-  }
-
-  public interface TemplatesHandler extends org.xml.sax.ContentHandler {
-    method public String getSystemId();
-    method public javax.xml.transform.Templates getTemplates();
-    method public void setSystemId(String);
-  }
-
-  public interface TransformerHandler extends org.xml.sax.ContentHandler org.xml.sax.DTDHandler org.xml.sax.ext.LexicalHandler {
-    method public String getSystemId();
-    method public javax.xml.transform.Transformer getTransformer();
-    method public void setResult(javax.xml.transform.Result) throws java.lang.IllegalArgumentException;
-    method public void setSystemId(String);
-  }
-
-}
-
-package javax.xml.transform.stream {
-
-  public class StreamResult implements javax.xml.transform.Result {
-    ctor public StreamResult();
-    ctor public StreamResult(java.io.OutputStream);
-    ctor public StreamResult(java.io.Writer);
-    ctor public StreamResult(String);
-    ctor public StreamResult(java.io.File);
-    method public java.io.OutputStream getOutputStream();
-    method public String getSystemId();
-    method public java.io.Writer getWriter();
-    method public void setOutputStream(java.io.OutputStream);
-    method public void setSystemId(String);
-    method public void setSystemId(java.io.File);
-    method public void setWriter(java.io.Writer);
-    field public static final String FEATURE = "http://javax.xml.transform.stream.StreamResult/feature";
-  }
-
-  public class StreamSource implements javax.xml.transform.Source {
-    ctor public StreamSource();
-    ctor public StreamSource(java.io.InputStream);
-    ctor public StreamSource(java.io.InputStream, String);
-    ctor public StreamSource(java.io.Reader);
-    ctor public StreamSource(java.io.Reader, String);
-    ctor public StreamSource(String);
-    ctor public StreamSource(java.io.File);
-    method public java.io.InputStream getInputStream();
-    method public String getPublicId();
-    method public java.io.Reader getReader();
-    method public String getSystemId();
-    method public void setInputStream(java.io.InputStream);
-    method public void setPublicId(String);
-    method public void setReader(java.io.Reader);
-    method public void setSystemId(String);
-    method public void setSystemId(java.io.File);
-    field public static final String FEATURE = "http://javax.xml.transform.stream.StreamSource/feature";
-  }
-
-}
-
-package javax.xml.validation {
-
-  public abstract class Schema {
-    ctor protected Schema();
-    method public abstract javax.xml.validation.Validator newValidator();
-    method public abstract javax.xml.validation.ValidatorHandler newValidatorHandler();
-  }
-
-  public abstract class SchemaFactory {
-    ctor protected SchemaFactory();
-    method public abstract org.xml.sax.ErrorHandler getErrorHandler();
-    method public boolean getFeature(String) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
-    method public Object getProperty(String) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
-    method public abstract org.w3c.dom.ls.LSResourceResolver getResourceResolver();
-    method public abstract boolean isSchemaLanguageSupported(String);
-    method public static javax.xml.validation.SchemaFactory newInstance(String);
-    method public static javax.xml.validation.SchemaFactory newInstance(String, String, ClassLoader);
-    method public javax.xml.validation.Schema newSchema(javax.xml.transform.Source) throws org.xml.sax.SAXException;
-    method public javax.xml.validation.Schema newSchema(java.io.File) throws org.xml.sax.SAXException;
-    method public javax.xml.validation.Schema newSchema(java.net.URL) throws org.xml.sax.SAXException;
-    method public abstract javax.xml.validation.Schema newSchema(javax.xml.transform.Source[]) throws org.xml.sax.SAXException;
-    method public abstract javax.xml.validation.Schema newSchema() throws org.xml.sax.SAXException;
-    method public abstract void setErrorHandler(org.xml.sax.ErrorHandler);
-    method public void setFeature(String, boolean) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
-    method public void setProperty(String, Object) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
-    method public abstract void setResourceResolver(org.w3c.dom.ls.LSResourceResolver);
-  }
-
-  public abstract class SchemaFactoryLoader {
-    ctor protected SchemaFactoryLoader();
-    method public abstract javax.xml.validation.SchemaFactory newFactory(String);
-  }
-
-  public abstract class TypeInfoProvider {
-    ctor protected TypeInfoProvider();
-    method public abstract org.w3c.dom.TypeInfo getAttributeTypeInfo(int);
-    method public abstract org.w3c.dom.TypeInfo getElementTypeInfo();
-    method public abstract boolean isIdAttribute(int);
-    method public abstract boolean isSpecified(int);
-  }
-
-  public abstract class Validator {
-    ctor protected Validator();
-    method public abstract org.xml.sax.ErrorHandler getErrorHandler();
-    method public boolean getFeature(String) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
-    method public Object getProperty(String) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
-    method public abstract org.w3c.dom.ls.LSResourceResolver getResourceResolver();
-    method public abstract void reset();
-    method public abstract void setErrorHandler(org.xml.sax.ErrorHandler);
-    method public void setFeature(String, boolean) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
-    method public void setProperty(String, Object) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
-    method public abstract void setResourceResolver(org.w3c.dom.ls.LSResourceResolver);
-    method public void validate(javax.xml.transform.Source) throws java.io.IOException, org.xml.sax.SAXException;
-    method public abstract void validate(javax.xml.transform.Source, javax.xml.transform.Result) throws java.io.IOException, org.xml.sax.SAXException;
-  }
-
-  public abstract class ValidatorHandler implements org.xml.sax.ContentHandler {
-    ctor protected ValidatorHandler();
-    method public abstract org.xml.sax.ContentHandler getContentHandler();
-    method public abstract org.xml.sax.ErrorHandler getErrorHandler();
-    method public boolean getFeature(String) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
-    method public Object getProperty(String) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
-    method public abstract org.w3c.dom.ls.LSResourceResolver getResourceResolver();
-    method public abstract javax.xml.validation.TypeInfoProvider getTypeInfoProvider();
-    method public abstract void setContentHandler(org.xml.sax.ContentHandler);
-    method public abstract void setErrorHandler(org.xml.sax.ErrorHandler);
-    method public void setFeature(String, boolean) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
-    method public void setProperty(String, Object) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
-    method public abstract void setResourceResolver(org.w3c.dom.ls.LSResourceResolver);
-  }
-
-}
-
-package javax.xml.xpath {
-
-  public interface XPath {
-    method public javax.xml.xpath.XPathExpression compile(String) throws javax.xml.xpath.XPathExpressionException;
-    method public Object evaluate(String, Object, javax.xml.namespace.QName) throws javax.xml.xpath.XPathExpressionException;
-    method public String evaluate(String, Object) throws javax.xml.xpath.XPathExpressionException;
-    method public Object evaluate(String, org.xml.sax.InputSource, javax.xml.namespace.QName) throws javax.xml.xpath.XPathExpressionException;
-    method public String evaluate(String, org.xml.sax.InputSource) throws javax.xml.xpath.XPathExpressionException;
-    method public javax.xml.namespace.NamespaceContext getNamespaceContext();
-    method public javax.xml.xpath.XPathFunctionResolver getXPathFunctionResolver();
-    method public javax.xml.xpath.XPathVariableResolver getXPathVariableResolver();
-    method public void reset();
-    method public void setNamespaceContext(javax.xml.namespace.NamespaceContext);
-    method public void setXPathFunctionResolver(javax.xml.xpath.XPathFunctionResolver);
-    method public void setXPathVariableResolver(javax.xml.xpath.XPathVariableResolver);
-  }
-
-  public class XPathConstants {
-    field public static final javax.xml.namespace.QName BOOLEAN;
-    field public static final String DOM_OBJECT_MODEL = "http://java.sun.com/jaxp/xpath/dom";
-    field public static final javax.xml.namespace.QName NODE;
-    field public static final javax.xml.namespace.QName NODESET;
-    field public static final javax.xml.namespace.QName NUMBER;
-    field public static final javax.xml.namespace.QName STRING;
-  }
-
-  public class XPathException extends java.lang.Exception {
-    ctor public XPathException(String);
-    ctor public XPathException(Throwable);
-  }
-
-  public interface XPathExpression {
-    method public Object evaluate(Object, javax.xml.namespace.QName) throws javax.xml.xpath.XPathExpressionException;
-    method public String evaluate(Object) throws javax.xml.xpath.XPathExpressionException;
-    method public Object evaluate(org.xml.sax.InputSource, javax.xml.namespace.QName) throws javax.xml.xpath.XPathExpressionException;
-    method public String evaluate(org.xml.sax.InputSource) throws javax.xml.xpath.XPathExpressionException;
-  }
-
-  public class XPathExpressionException extends javax.xml.xpath.XPathException {
-    ctor public XPathExpressionException(String);
-    ctor public XPathExpressionException(Throwable);
-  }
-
-  public abstract class XPathFactory {
-    ctor protected XPathFactory();
-    method public abstract boolean getFeature(String) throws javax.xml.xpath.XPathFactoryConfigurationException;
-    method public abstract boolean isObjectModelSupported(String);
-    method public static final javax.xml.xpath.XPathFactory newInstance();
-    method public static final javax.xml.xpath.XPathFactory newInstance(String) throws javax.xml.xpath.XPathFactoryConfigurationException;
-    method public static javax.xml.xpath.XPathFactory newInstance(String, String, ClassLoader) throws javax.xml.xpath.XPathFactoryConfigurationException;
-    method public abstract javax.xml.xpath.XPath newXPath();
-    method public abstract void setFeature(String, boolean) throws javax.xml.xpath.XPathFactoryConfigurationException;
-    method public abstract void setXPathFunctionResolver(javax.xml.xpath.XPathFunctionResolver);
-    method public abstract void setXPathVariableResolver(javax.xml.xpath.XPathVariableResolver);
-    field public static final String DEFAULT_OBJECT_MODEL_URI = "http://java.sun.com/jaxp/xpath/dom";
-    field public static final String DEFAULT_PROPERTY_NAME = "javax.xml.xpath.XPathFactory";
-  }
-
-  public class XPathFactoryConfigurationException extends javax.xml.xpath.XPathException {
-    ctor public XPathFactoryConfigurationException(String);
-    ctor public XPathFactoryConfigurationException(Throwable);
-  }
-
-  public interface XPathFunction {
-    method public Object evaluate(java.util.List) throws javax.xml.xpath.XPathFunctionException;
-  }
-
-  public class XPathFunctionException extends javax.xml.xpath.XPathExpressionException {
-    ctor public XPathFunctionException(String);
-    ctor public XPathFunctionException(Throwable);
-  }
-
-  public interface XPathFunctionResolver {
-    method public javax.xml.xpath.XPathFunction resolveFunction(javax.xml.namespace.QName, int);
-  }
-
-  public interface XPathVariableResolver {
-    method public Object resolveVariable(javax.xml.namespace.QName);
-  }
-
-}
-
 package org.apache.http.conn {
 
   @Deprecated public class ConnectTimeoutException extends java.io.InterruptedIOException {
@@ -74670,1152 +55510,3 @@
 
 }
 
-package org.json {
-
-  public class JSONArray {
-    ctor public JSONArray();
-    ctor public JSONArray(java.util.Collection);
-    ctor public JSONArray(org.json.JSONTokener) throws org.json.JSONException;
-    ctor public JSONArray(String) throws org.json.JSONException;
-    ctor public JSONArray(Object) throws org.json.JSONException;
-    method public Object get(int) throws org.json.JSONException;
-    method public boolean getBoolean(int) throws org.json.JSONException;
-    method public double getDouble(int) throws org.json.JSONException;
-    method public int getInt(int) throws org.json.JSONException;
-    method public org.json.JSONArray getJSONArray(int) throws org.json.JSONException;
-    method public org.json.JSONObject getJSONObject(int) throws org.json.JSONException;
-    method public long getLong(int) throws org.json.JSONException;
-    method public String getString(int) throws org.json.JSONException;
-    method public boolean isNull(int);
-    method public String join(String) throws org.json.JSONException;
-    method public int length();
-    method public Object opt(int);
-    method public boolean optBoolean(int);
-    method public boolean optBoolean(int, boolean);
-    method public double optDouble(int);
-    method public double optDouble(int, double);
-    method public int optInt(int);
-    method public int optInt(int, int);
-    method public org.json.JSONArray optJSONArray(int);
-    method public org.json.JSONObject optJSONObject(int);
-    method public long optLong(int);
-    method public long optLong(int, long);
-    method public String optString(int);
-    method public String optString(int, String);
-    method public org.json.JSONArray put(boolean);
-    method public org.json.JSONArray put(double) throws org.json.JSONException;
-    method public org.json.JSONArray put(int);
-    method public org.json.JSONArray put(long);
-    method public org.json.JSONArray put(Object);
-    method public org.json.JSONArray put(int, boolean) throws org.json.JSONException;
-    method public org.json.JSONArray put(int, double) throws org.json.JSONException;
-    method public org.json.JSONArray put(int, int) throws org.json.JSONException;
-    method public org.json.JSONArray put(int, long) throws org.json.JSONException;
-    method public org.json.JSONArray put(int, Object) throws org.json.JSONException;
-    method public Object remove(int);
-    method public org.json.JSONObject toJSONObject(org.json.JSONArray) throws org.json.JSONException;
-    method public String toString(int) throws org.json.JSONException;
-  }
-
-  public class JSONException extends java.lang.Exception {
-    ctor public JSONException(String);
-    ctor public JSONException(String, Throwable);
-    ctor public JSONException(Throwable);
-  }
-
-  public class JSONObject {
-    ctor public JSONObject();
-    ctor public JSONObject(@NonNull java.util.Map);
-    ctor public JSONObject(@NonNull org.json.JSONTokener) throws org.json.JSONException;
-    ctor public JSONObject(@NonNull String) throws org.json.JSONException;
-    ctor public JSONObject(@NonNull org.json.JSONObject, @NonNull String[]) throws org.json.JSONException;
-    method @NonNull public org.json.JSONObject accumulate(@NonNull String, @Nullable Object) throws org.json.JSONException;
-    method @NonNull public Object get(@NonNull String) throws org.json.JSONException;
-    method public boolean getBoolean(@NonNull String) throws org.json.JSONException;
-    method public double getDouble(@NonNull String) throws org.json.JSONException;
-    method public int getInt(@NonNull String) throws org.json.JSONException;
-    method @NonNull public org.json.JSONArray getJSONArray(@NonNull String) throws org.json.JSONException;
-    method @NonNull public org.json.JSONObject getJSONObject(@NonNull String) throws org.json.JSONException;
-    method public long getLong(@NonNull String) throws org.json.JSONException;
-    method @NonNull public String getString(@NonNull String) throws org.json.JSONException;
-    method public boolean has(@Nullable String);
-    method public boolean isNull(@Nullable String);
-    method @NonNull public java.util.Iterator<java.lang.String> keys();
-    method public int length();
-    method @Nullable public org.json.JSONArray names();
-    method @NonNull public static String numberToString(@NonNull Number) throws org.json.JSONException;
-    method @Nullable public Object opt(@Nullable String);
-    method public boolean optBoolean(@Nullable String);
-    method public boolean optBoolean(@Nullable String, boolean);
-    method public double optDouble(@Nullable String);
-    method public double optDouble(@Nullable String, double);
-    method public int optInt(@Nullable String);
-    method public int optInt(@Nullable String, int);
-    method @Nullable public org.json.JSONArray optJSONArray(@Nullable String);
-    method @Nullable public org.json.JSONObject optJSONObject(@Nullable String);
-    method public long optLong(@Nullable String);
-    method public long optLong(@Nullable String, long);
-    method @NonNull public String optString(@Nullable String);
-    method @NonNull public String optString(@Nullable String, @NonNull String);
-    method @NonNull public org.json.JSONObject put(@NonNull String, boolean) throws org.json.JSONException;
-    method @NonNull public org.json.JSONObject put(@NonNull String, double) throws org.json.JSONException;
-    method @NonNull public org.json.JSONObject put(@NonNull String, int) throws org.json.JSONException;
-    method @NonNull public org.json.JSONObject put(@NonNull String, long) throws org.json.JSONException;
-    method @NonNull public org.json.JSONObject put(@NonNull String, @Nullable Object) throws org.json.JSONException;
-    method @NonNull public org.json.JSONObject putOpt(@Nullable String, @Nullable Object) throws org.json.JSONException;
-    method @NonNull public static String quote(@Nullable String);
-    method @Nullable public Object remove(@Nullable String);
-    method @Nullable public org.json.JSONArray toJSONArray(@Nullable org.json.JSONArray) throws org.json.JSONException;
-    method @NonNull public String toString(int) throws org.json.JSONException;
-    method @Nullable public static Object wrap(@Nullable Object);
-    field @NonNull public static final Object NULL;
-  }
-
-  public class JSONStringer {
-    ctor public JSONStringer();
-    method public org.json.JSONStringer array() throws org.json.JSONException;
-    method public org.json.JSONStringer endArray() throws org.json.JSONException;
-    method public org.json.JSONStringer endObject() throws org.json.JSONException;
-    method public org.json.JSONStringer key(String) throws org.json.JSONException;
-    method public org.json.JSONStringer object() throws org.json.JSONException;
-    method public org.json.JSONStringer value(Object) throws org.json.JSONException;
-    method public org.json.JSONStringer value(boolean) throws org.json.JSONException;
-    method public org.json.JSONStringer value(double) throws org.json.JSONException;
-    method public org.json.JSONStringer value(long) throws org.json.JSONException;
-  }
-
-  public class JSONTokener {
-    ctor public JSONTokener(String);
-    method public void back();
-    method public static int dehexchar(char);
-    method public boolean more();
-    method public char next();
-    method public char next(char) throws org.json.JSONException;
-    method public String next(int) throws org.json.JSONException;
-    method public char nextClean() throws org.json.JSONException;
-    method public String nextString(char) throws org.json.JSONException;
-    method public String nextTo(String);
-    method public String nextTo(char);
-    method public Object nextValue() throws org.json.JSONException;
-    method public void skipPast(String);
-    method public char skipTo(char);
-    method public org.json.JSONException syntaxError(String);
-  }
-
-}
-
-package org.w3c.dom {
-
-  public interface Attr extends org.w3c.dom.Node {
-    method public String getName();
-    method public org.w3c.dom.Element getOwnerElement();
-    method public org.w3c.dom.TypeInfo getSchemaTypeInfo();
-    method public boolean getSpecified();
-    method public String getValue();
-    method public boolean isId();
-    method public void setValue(String) throws org.w3c.dom.DOMException;
-  }
-
-  public interface CDATASection extends org.w3c.dom.Text {
-  }
-
-  public interface CharacterData extends org.w3c.dom.Node {
-    method public void appendData(String) throws org.w3c.dom.DOMException;
-    method public void deleteData(int, int) throws org.w3c.dom.DOMException;
-    method public String getData() throws org.w3c.dom.DOMException;
-    method public int getLength();
-    method public void insertData(int, String) throws org.w3c.dom.DOMException;
-    method public void replaceData(int, int, String) throws org.w3c.dom.DOMException;
-    method public void setData(String) throws org.w3c.dom.DOMException;
-    method public String substringData(int, int) throws org.w3c.dom.DOMException;
-  }
-
-  public interface Comment extends org.w3c.dom.CharacterData {
-  }
-
-  public interface DOMConfiguration {
-    method public boolean canSetParameter(String, Object);
-    method public Object getParameter(String) throws org.w3c.dom.DOMException;
-    method public org.w3c.dom.DOMStringList getParameterNames();
-    method public void setParameter(String, Object) throws org.w3c.dom.DOMException;
-  }
-
-  public interface DOMError {
-    method public org.w3c.dom.DOMLocator getLocation();
-    method public String getMessage();
-    method public Object getRelatedData();
-    method public Object getRelatedException();
-    method public short getSeverity();
-    method public String getType();
-    field public static final short SEVERITY_ERROR = 2; // 0x2
-    field public static final short SEVERITY_FATAL_ERROR = 3; // 0x3
-    field public static final short SEVERITY_WARNING = 1; // 0x1
-  }
-
-  public interface DOMErrorHandler {
-    method public boolean handleError(org.w3c.dom.DOMError);
-  }
-
-  public class DOMException extends java.lang.RuntimeException {
-    ctor public DOMException(short, String);
-    field public static final short DOMSTRING_SIZE_ERR = 2; // 0x2
-    field public static final short HIERARCHY_REQUEST_ERR = 3; // 0x3
-    field public static final short INDEX_SIZE_ERR = 1; // 0x1
-    field public static final short INUSE_ATTRIBUTE_ERR = 10; // 0xa
-    field public static final short INVALID_ACCESS_ERR = 15; // 0xf
-    field public static final short INVALID_CHARACTER_ERR = 5; // 0x5
-    field public static final short INVALID_MODIFICATION_ERR = 13; // 0xd
-    field public static final short INVALID_STATE_ERR = 11; // 0xb
-    field public static final short NAMESPACE_ERR = 14; // 0xe
-    field public static final short NOT_FOUND_ERR = 8; // 0x8
-    field public static final short NOT_SUPPORTED_ERR = 9; // 0x9
-    field public static final short NO_DATA_ALLOWED_ERR = 6; // 0x6
-    field public static final short NO_MODIFICATION_ALLOWED_ERR = 7; // 0x7
-    field public static final short SYNTAX_ERR = 12; // 0xc
-    field public static final short TYPE_MISMATCH_ERR = 17; // 0x11
-    field public static final short VALIDATION_ERR = 16; // 0x10
-    field public static final short WRONG_DOCUMENT_ERR = 4; // 0x4
-    field public short code;
-  }
-
-  public interface DOMImplementation {
-    method public org.w3c.dom.Document createDocument(String, String, org.w3c.dom.DocumentType) throws org.w3c.dom.DOMException;
-    method public org.w3c.dom.DocumentType createDocumentType(String, String, String) throws org.w3c.dom.DOMException;
-    method public Object getFeature(String, String);
-    method public boolean hasFeature(String, String);
-  }
-
-  public interface DOMImplementationList {
-    method public int getLength();
-    method public org.w3c.dom.DOMImplementation item(int);
-  }
-
-  public interface DOMImplementationSource {
-    method public org.w3c.dom.DOMImplementation getDOMImplementation(String);
-    method public org.w3c.dom.DOMImplementationList getDOMImplementationList(String);
-  }
-
-  public interface DOMLocator {
-    method public int getByteOffset();
-    method public int getColumnNumber();
-    method public int getLineNumber();
-    method public org.w3c.dom.Node getRelatedNode();
-    method public String getUri();
-    method public int getUtf16Offset();
-  }
-
-  public interface DOMStringList {
-    method public boolean contains(String);
-    method public int getLength();
-    method public String item(int);
-  }
-
-  public interface Document extends org.w3c.dom.Node {
-    method public org.w3c.dom.Node adoptNode(org.w3c.dom.Node) throws org.w3c.dom.DOMException;
-    method public org.w3c.dom.Attr createAttribute(String) throws org.w3c.dom.DOMException;
-    method public org.w3c.dom.Attr createAttributeNS(String, String) throws org.w3c.dom.DOMException;
-    method public org.w3c.dom.CDATASection createCDATASection(String) throws org.w3c.dom.DOMException;
-    method public org.w3c.dom.Comment createComment(String);
-    method public org.w3c.dom.DocumentFragment createDocumentFragment();
-    method public org.w3c.dom.Element createElement(String) throws org.w3c.dom.DOMException;
-    method public org.w3c.dom.Element createElementNS(String, String) throws org.w3c.dom.DOMException;
-    method public org.w3c.dom.EntityReference createEntityReference(String) throws org.w3c.dom.DOMException;
-    method public org.w3c.dom.ProcessingInstruction createProcessingInstruction(String, String) throws org.w3c.dom.DOMException;
-    method public org.w3c.dom.Text createTextNode(String);
-    method public org.w3c.dom.DocumentType getDoctype();
-    method public org.w3c.dom.Element getDocumentElement();
-    method public String getDocumentURI();
-    method public org.w3c.dom.DOMConfiguration getDomConfig();
-    method public org.w3c.dom.Element getElementById(String);
-    method public org.w3c.dom.NodeList getElementsByTagName(String);
-    method public org.w3c.dom.NodeList getElementsByTagNameNS(String, String);
-    method public org.w3c.dom.DOMImplementation getImplementation();
-    method public String getInputEncoding();
-    method public boolean getStrictErrorChecking();
-    method public String getXmlEncoding();
-    method public boolean getXmlStandalone();
-    method public String getXmlVersion();
-    method public org.w3c.dom.Node importNode(org.w3c.dom.Node, boolean) throws org.w3c.dom.DOMException;
-    method public void normalizeDocument();
-    method public org.w3c.dom.Node renameNode(org.w3c.dom.Node, String, String) throws org.w3c.dom.DOMException;
-    method public void setDocumentURI(String);
-    method public void setStrictErrorChecking(boolean);
-    method public void setXmlStandalone(boolean) throws org.w3c.dom.DOMException;
-    method public void setXmlVersion(String) throws org.w3c.dom.DOMException;
-  }
-
-  public interface DocumentFragment extends org.w3c.dom.Node {
-  }
-
-  public interface DocumentType extends org.w3c.dom.Node {
-    method public org.w3c.dom.NamedNodeMap getEntities();
-    method public String getInternalSubset();
-    method public String getName();
-    method public org.w3c.dom.NamedNodeMap getNotations();
-    method public String getPublicId();
-    method public String getSystemId();
-  }
-
-  public interface Element extends org.w3c.dom.Node {
-    method public String getAttribute(String);
-    method public String getAttributeNS(String, String) throws org.w3c.dom.DOMException;
-    method public org.w3c.dom.Attr getAttributeNode(String);
-    method public org.w3c.dom.Attr getAttributeNodeNS(String, String) throws org.w3c.dom.DOMException;
-    method public org.w3c.dom.NodeList getElementsByTagName(String);
-    method public org.w3c.dom.NodeList getElementsByTagNameNS(String, String) throws org.w3c.dom.DOMException;
-    method public org.w3c.dom.TypeInfo getSchemaTypeInfo();
-    method public String getTagName();
-    method public boolean hasAttribute(String);
-    method public boolean hasAttributeNS(String, String) throws org.w3c.dom.DOMException;
-    method public void removeAttribute(String) throws org.w3c.dom.DOMException;
-    method public void removeAttributeNS(String, String) throws org.w3c.dom.DOMException;
-    method public org.w3c.dom.Attr removeAttributeNode(org.w3c.dom.Attr) throws org.w3c.dom.DOMException;
-    method public void setAttribute(String, String) throws org.w3c.dom.DOMException;
-    method public void setAttributeNS(String, String, String) throws org.w3c.dom.DOMException;
-    method public org.w3c.dom.Attr setAttributeNode(org.w3c.dom.Attr) throws org.w3c.dom.DOMException;
-    method public org.w3c.dom.Attr setAttributeNodeNS(org.w3c.dom.Attr) throws org.w3c.dom.DOMException;
-    method public void setIdAttribute(String, boolean) throws org.w3c.dom.DOMException;
-    method public void setIdAttributeNS(String, String, boolean) throws org.w3c.dom.DOMException;
-    method public void setIdAttributeNode(org.w3c.dom.Attr, boolean) throws org.w3c.dom.DOMException;
-  }
-
-  public interface Entity extends org.w3c.dom.Node {
-    method public String getInputEncoding();
-    method public String getNotationName();
-    method public String getPublicId();
-    method public String getSystemId();
-    method public String getXmlEncoding();
-    method public String getXmlVersion();
-  }
-
-  public interface EntityReference extends org.w3c.dom.Node {
-  }
-
-  public interface NameList {
-    method public boolean contains(String);
-    method public boolean containsNS(String, String);
-    method public int getLength();
-    method public String getName(int);
-    method public String getNamespaceURI(int);
-  }
-
-  public interface NamedNodeMap {
-    method public int getLength();
-    method public org.w3c.dom.Node getNamedItem(String);
-    method public org.w3c.dom.Node getNamedItemNS(String, String) throws org.w3c.dom.DOMException;
-    method public org.w3c.dom.Node item(int);
-    method public org.w3c.dom.Node removeNamedItem(String) throws org.w3c.dom.DOMException;
-    method public org.w3c.dom.Node removeNamedItemNS(String, String) throws org.w3c.dom.DOMException;
-    method public org.w3c.dom.Node setNamedItem(org.w3c.dom.Node) throws org.w3c.dom.DOMException;
-    method public org.w3c.dom.Node setNamedItemNS(org.w3c.dom.Node) throws org.w3c.dom.DOMException;
-  }
-
-  public interface Node {
-    method public org.w3c.dom.Node appendChild(org.w3c.dom.Node) throws org.w3c.dom.DOMException;
-    method public org.w3c.dom.Node cloneNode(boolean);
-    method public short compareDocumentPosition(org.w3c.dom.Node) throws org.w3c.dom.DOMException;
-    method public org.w3c.dom.NamedNodeMap getAttributes();
-    method public String getBaseURI();
-    method public org.w3c.dom.NodeList getChildNodes();
-    method public Object getFeature(String, String);
-    method public org.w3c.dom.Node getFirstChild();
-    method public org.w3c.dom.Node getLastChild();
-    method public String getLocalName();
-    method public String getNamespaceURI();
-    method public org.w3c.dom.Node getNextSibling();
-    method public String getNodeName();
-    method public short getNodeType();
-    method public String getNodeValue() throws org.w3c.dom.DOMException;
-    method public org.w3c.dom.Document getOwnerDocument();
-    method public org.w3c.dom.Node getParentNode();
-    method public String getPrefix();
-    method public org.w3c.dom.Node getPreviousSibling();
-    method public String getTextContent() throws org.w3c.dom.DOMException;
-    method public Object getUserData(String);
-    method public boolean hasAttributes();
-    method public boolean hasChildNodes();
-    method public org.w3c.dom.Node insertBefore(org.w3c.dom.Node, org.w3c.dom.Node) throws org.w3c.dom.DOMException;
-    method public boolean isDefaultNamespace(String);
-    method public boolean isEqualNode(org.w3c.dom.Node);
-    method public boolean isSameNode(org.w3c.dom.Node);
-    method public boolean isSupported(String, String);
-    method public String lookupNamespaceURI(String);
-    method public String lookupPrefix(String);
-    method public void normalize();
-    method public org.w3c.dom.Node removeChild(org.w3c.dom.Node) throws org.w3c.dom.DOMException;
-    method public org.w3c.dom.Node replaceChild(org.w3c.dom.Node, org.w3c.dom.Node) throws org.w3c.dom.DOMException;
-    method public void setNodeValue(String) throws org.w3c.dom.DOMException;
-    method public void setPrefix(String) throws org.w3c.dom.DOMException;
-    method public void setTextContent(String) throws org.w3c.dom.DOMException;
-    method public Object setUserData(String, Object, org.w3c.dom.UserDataHandler);
-    field public static final short ATTRIBUTE_NODE = 2; // 0x2
-    field public static final short CDATA_SECTION_NODE = 4; // 0x4
-    field public static final short COMMENT_NODE = 8; // 0x8
-    field public static final short DOCUMENT_FRAGMENT_NODE = 11; // 0xb
-    field public static final short DOCUMENT_NODE = 9; // 0x9
-    field public static final short DOCUMENT_POSITION_CONTAINED_BY = 16; // 0x10
-    field public static final short DOCUMENT_POSITION_CONTAINS = 8; // 0x8
-    field public static final short DOCUMENT_POSITION_DISCONNECTED = 1; // 0x1
-    field public static final short DOCUMENT_POSITION_FOLLOWING = 4; // 0x4
-    field public static final short DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 32; // 0x20
-    field public static final short DOCUMENT_POSITION_PRECEDING = 2; // 0x2
-    field public static final short DOCUMENT_TYPE_NODE = 10; // 0xa
-    field public static final short ELEMENT_NODE = 1; // 0x1
-    field public static final short ENTITY_NODE = 6; // 0x6
-    field public static final short ENTITY_REFERENCE_NODE = 5; // 0x5
-    field public static final short NOTATION_NODE = 12; // 0xc
-    field public static final short PROCESSING_INSTRUCTION_NODE = 7; // 0x7
-    field public static final short TEXT_NODE = 3; // 0x3
-  }
-
-  public interface NodeList {
-    method public int getLength();
-    method public org.w3c.dom.Node item(int);
-  }
-
-  public interface Notation extends org.w3c.dom.Node {
-    method public String getPublicId();
-    method public String getSystemId();
-  }
-
-  public interface ProcessingInstruction extends org.w3c.dom.Node {
-    method public String getData();
-    method public String getTarget();
-    method public void setData(String) throws org.w3c.dom.DOMException;
-  }
-
-  public interface Text extends org.w3c.dom.CharacterData {
-    method public String getWholeText();
-    method public boolean isElementContentWhitespace();
-    method public org.w3c.dom.Text replaceWholeText(String) throws org.w3c.dom.DOMException;
-    method public org.w3c.dom.Text splitText(int) throws org.w3c.dom.DOMException;
-  }
-
-  public interface TypeInfo {
-    method public String getTypeName();
-    method public String getTypeNamespace();
-    method public boolean isDerivedFrom(String, String, int);
-    field public static final int DERIVATION_EXTENSION = 2; // 0x2
-    field public static final int DERIVATION_LIST = 8; // 0x8
-    field public static final int DERIVATION_RESTRICTION = 1; // 0x1
-    field public static final int DERIVATION_UNION = 4; // 0x4
-  }
-
-  public interface UserDataHandler {
-    method public void handle(short, String, Object, org.w3c.dom.Node, org.w3c.dom.Node);
-    field public static final short NODE_ADOPTED = 5; // 0x5
-    field public static final short NODE_CLONED = 1; // 0x1
-    field public static final short NODE_DELETED = 3; // 0x3
-    field public static final short NODE_IMPORTED = 2; // 0x2
-    field public static final short NODE_RENAMED = 4; // 0x4
-  }
-
-}
-
-package org.w3c.dom.ls {
-
-  public interface DOMImplementationLS {
-    method public org.w3c.dom.ls.LSInput createLSInput();
-    method public org.w3c.dom.ls.LSOutput createLSOutput();
-    method public org.w3c.dom.ls.LSParser createLSParser(short, String) throws org.w3c.dom.DOMException;
-    method public org.w3c.dom.ls.LSSerializer createLSSerializer();
-    field public static final short MODE_ASYNCHRONOUS = 2; // 0x2
-    field public static final short MODE_SYNCHRONOUS = 1; // 0x1
-  }
-
-  public class LSException extends java.lang.RuntimeException {
-    ctor public LSException(short, String);
-    field public static final short PARSE_ERR = 81; // 0x51
-    field public static final short SERIALIZE_ERR = 82; // 0x52
-    field public short code;
-  }
-
-  public interface LSInput {
-    method public String getBaseURI();
-    method public java.io.InputStream getByteStream();
-    method public boolean getCertifiedText();
-    method public java.io.Reader getCharacterStream();
-    method public String getEncoding();
-    method public String getPublicId();
-    method public String getStringData();
-    method public String getSystemId();
-    method public void setBaseURI(String);
-    method public void setByteStream(java.io.InputStream);
-    method public void setCertifiedText(boolean);
-    method public void setCharacterStream(java.io.Reader);
-    method public void setEncoding(String);
-    method public void setPublicId(String);
-    method public void setStringData(String);
-    method public void setSystemId(String);
-  }
-
-  public interface LSOutput {
-    method public java.io.OutputStream getByteStream();
-    method public java.io.Writer getCharacterStream();
-    method public String getEncoding();
-    method public String getSystemId();
-    method public void setByteStream(java.io.OutputStream);
-    method public void setCharacterStream(java.io.Writer);
-    method public void setEncoding(String);
-    method public void setSystemId(String);
-  }
-
-  public interface LSParser {
-    method public void abort();
-    method public boolean getAsync();
-    method public boolean getBusy();
-    method public org.w3c.dom.DOMConfiguration getDomConfig();
-    method public org.w3c.dom.ls.LSParserFilter getFilter();
-    method public org.w3c.dom.Document parse(org.w3c.dom.ls.LSInput) throws org.w3c.dom.DOMException, org.w3c.dom.ls.LSException;
-    method public org.w3c.dom.Document parseURI(String) throws org.w3c.dom.DOMException, org.w3c.dom.ls.LSException;
-    method public org.w3c.dom.Node parseWithContext(org.w3c.dom.ls.LSInput, org.w3c.dom.Node, short) throws org.w3c.dom.DOMException, org.w3c.dom.ls.LSException;
-    method public void setFilter(org.w3c.dom.ls.LSParserFilter);
-    field public static final short ACTION_APPEND_AS_CHILDREN = 1; // 0x1
-    field public static final short ACTION_INSERT_AFTER = 4; // 0x4
-    field public static final short ACTION_INSERT_BEFORE = 3; // 0x3
-    field public static final short ACTION_REPLACE = 5; // 0x5
-    field public static final short ACTION_REPLACE_CHILDREN = 2; // 0x2
-  }
-
-  public interface LSParserFilter {
-    method public short acceptNode(org.w3c.dom.Node);
-    method public int getWhatToShow();
-    method public short startElement(org.w3c.dom.Element);
-    field public static final short FILTER_ACCEPT = 1; // 0x1
-    field public static final short FILTER_INTERRUPT = 4; // 0x4
-    field public static final short FILTER_REJECT = 2; // 0x2
-    field public static final short FILTER_SKIP = 3; // 0x3
-  }
-
-  public interface LSResourceResolver {
-    method public org.w3c.dom.ls.LSInput resolveResource(String, String, String, String, String);
-  }
-
-  public interface LSSerializer {
-    method public org.w3c.dom.DOMConfiguration getDomConfig();
-    method public String getNewLine();
-    method public void setNewLine(String);
-    method public boolean write(org.w3c.dom.Node, org.w3c.dom.ls.LSOutput) throws org.w3c.dom.ls.LSException;
-    method public String writeToString(org.w3c.dom.Node) throws org.w3c.dom.DOMException, org.w3c.dom.ls.LSException;
-    method public boolean writeToURI(org.w3c.dom.Node, String) throws org.w3c.dom.ls.LSException;
-  }
-
-}
-
-package org.xml.sax {
-
-  @Deprecated public interface AttributeList {
-    method @Deprecated public int getLength();
-    method @Deprecated public String getName(int);
-    method @Deprecated public String getType(int);
-    method @Deprecated public String getType(String);
-    method @Deprecated public String getValue(int);
-    method @Deprecated public String getValue(String);
-  }
-
-  public interface Attributes {
-    method public int getIndex(String, String);
-    method public int getIndex(String);
-    method public int getLength();
-    method public String getLocalName(int);
-    method public String getQName(int);
-    method public String getType(int);
-    method public String getType(String, String);
-    method public String getType(String);
-    method public String getURI(int);
-    method public String getValue(int);
-    method public String getValue(String, String);
-    method public String getValue(String);
-  }
-
-  public interface ContentHandler {
-    method public void characters(char[], int, int) throws org.xml.sax.SAXException;
-    method public void endDocument() throws org.xml.sax.SAXException;
-    method public void endElement(String, String, String) throws org.xml.sax.SAXException;
-    method public void endPrefixMapping(String) throws org.xml.sax.SAXException;
-    method public void ignorableWhitespace(char[], int, int) throws org.xml.sax.SAXException;
-    method public void processingInstruction(String, String) throws org.xml.sax.SAXException;
-    method public void setDocumentLocator(org.xml.sax.Locator);
-    method public void skippedEntity(String) throws org.xml.sax.SAXException;
-    method public void startDocument() throws org.xml.sax.SAXException;
-    method public void startElement(String, String, String, org.xml.sax.Attributes) throws org.xml.sax.SAXException;
-    method public void startPrefixMapping(String, String) throws org.xml.sax.SAXException;
-  }
-
-  public interface DTDHandler {
-    method public void notationDecl(String, String, String) throws org.xml.sax.SAXException;
-    method public void unparsedEntityDecl(String, String, String, String) throws org.xml.sax.SAXException;
-  }
-
-  @Deprecated public interface DocumentHandler {
-    method @Deprecated public void characters(char[], int, int) throws org.xml.sax.SAXException;
-    method @Deprecated public void endDocument() throws org.xml.sax.SAXException;
-    method @Deprecated public void endElement(String) throws org.xml.sax.SAXException;
-    method @Deprecated public void ignorableWhitespace(char[], int, int) throws org.xml.sax.SAXException;
-    method @Deprecated public void processingInstruction(String, String) throws org.xml.sax.SAXException;
-    method @Deprecated public void setDocumentLocator(org.xml.sax.Locator);
-    method @Deprecated public void startDocument() throws org.xml.sax.SAXException;
-    method @Deprecated public void startElement(String, org.xml.sax.AttributeList) throws org.xml.sax.SAXException;
-  }
-
-  public interface EntityResolver {
-    method public org.xml.sax.InputSource resolveEntity(String, String) throws java.io.IOException, org.xml.sax.SAXException;
-  }
-
-  public interface ErrorHandler {
-    method public void error(org.xml.sax.SAXParseException) throws org.xml.sax.SAXException;
-    method public void fatalError(org.xml.sax.SAXParseException) throws org.xml.sax.SAXException;
-    method public void warning(org.xml.sax.SAXParseException) throws org.xml.sax.SAXException;
-  }
-
-  @Deprecated public class HandlerBase implements org.xml.sax.DTDHandler org.xml.sax.DocumentHandler org.xml.sax.EntityResolver org.xml.sax.ErrorHandler {
-    ctor @Deprecated public HandlerBase();
-    method @Deprecated public void characters(char[], int, int) throws org.xml.sax.SAXException;
-    method @Deprecated public void endDocument() throws org.xml.sax.SAXException;
-    method @Deprecated public void endElement(String) throws org.xml.sax.SAXException;
-    method @Deprecated public void error(org.xml.sax.SAXParseException) throws org.xml.sax.SAXException;
-    method @Deprecated public void fatalError(org.xml.sax.SAXParseException) throws org.xml.sax.SAXException;
-    method @Deprecated public void ignorableWhitespace(char[], int, int) throws org.xml.sax.SAXException;
-    method @Deprecated public void notationDecl(String, String, String);
-    method @Deprecated public void processingInstruction(String, String) throws org.xml.sax.SAXException;
-    method @Deprecated public org.xml.sax.InputSource resolveEntity(String, String) throws org.xml.sax.SAXException;
-    method @Deprecated public void setDocumentLocator(org.xml.sax.Locator);
-    method @Deprecated public void startDocument() throws org.xml.sax.SAXException;
-    method @Deprecated public void startElement(String, org.xml.sax.AttributeList) throws org.xml.sax.SAXException;
-    method @Deprecated public void unparsedEntityDecl(String, String, String, String);
-    method @Deprecated public void warning(org.xml.sax.SAXParseException) throws org.xml.sax.SAXException;
-  }
-
-  public class InputSource {
-    ctor public InputSource();
-    ctor public InputSource(String);
-    ctor public InputSource(java.io.InputStream);
-    ctor public InputSource(java.io.Reader);
-    method public java.io.InputStream getByteStream();
-    method public java.io.Reader getCharacterStream();
-    method public String getEncoding();
-    method public String getPublicId();
-    method public String getSystemId();
-    method public void setByteStream(java.io.InputStream);
-    method public void setCharacterStream(java.io.Reader);
-    method public void setEncoding(String);
-    method public void setPublicId(String);
-    method public void setSystemId(String);
-  }
-
-  public interface Locator {
-    method public int getColumnNumber();
-    method public int getLineNumber();
-    method public String getPublicId();
-    method public String getSystemId();
-  }
-
-  @Deprecated public interface Parser {
-    method @Deprecated public void parse(org.xml.sax.InputSource) throws java.io.IOException, org.xml.sax.SAXException;
-    method @Deprecated public void parse(String) throws java.io.IOException, org.xml.sax.SAXException;
-    method @Deprecated public void setDTDHandler(org.xml.sax.DTDHandler);
-    method @Deprecated public void setDocumentHandler(org.xml.sax.DocumentHandler);
-    method @Deprecated public void setEntityResolver(org.xml.sax.EntityResolver);
-    method @Deprecated public void setErrorHandler(org.xml.sax.ErrorHandler);
-    method @Deprecated public void setLocale(java.util.Locale) throws org.xml.sax.SAXException;
-  }
-
-  public class SAXException extends java.lang.Exception {
-    ctor public SAXException();
-    ctor public SAXException(String);
-    ctor public SAXException(Exception);
-    ctor public SAXException(String, Exception);
-    method public Exception getException();
-  }
-
-  public class SAXNotRecognizedException extends org.xml.sax.SAXException {
-    ctor public SAXNotRecognizedException();
-    ctor public SAXNotRecognizedException(String);
-  }
-
-  public class SAXNotSupportedException extends org.xml.sax.SAXException {
-    ctor public SAXNotSupportedException();
-    ctor public SAXNotSupportedException(String);
-  }
-
-  public class SAXParseException extends org.xml.sax.SAXException {
-    ctor public SAXParseException(String, org.xml.sax.Locator);
-    ctor public SAXParseException(String, org.xml.sax.Locator, Exception);
-    ctor public SAXParseException(String, String, String, int, int);
-    ctor public SAXParseException(String, String, String, int, int, Exception);
-    method public int getColumnNumber();
-    method public int getLineNumber();
-    method public String getPublicId();
-    method public String getSystemId();
-  }
-
-  public interface XMLFilter extends org.xml.sax.XMLReader {
-    method public org.xml.sax.XMLReader getParent();
-    method public void setParent(org.xml.sax.XMLReader);
-  }
-
-  public interface XMLReader {
-    method public org.xml.sax.ContentHandler getContentHandler();
-    method public org.xml.sax.DTDHandler getDTDHandler();
-    method public org.xml.sax.EntityResolver getEntityResolver();
-    method public org.xml.sax.ErrorHandler getErrorHandler();
-    method public boolean getFeature(String) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
-    method public Object getProperty(String) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
-    method public void parse(org.xml.sax.InputSource) throws java.io.IOException, org.xml.sax.SAXException;
-    method public void parse(String) throws java.io.IOException, org.xml.sax.SAXException;
-    method public void setContentHandler(org.xml.sax.ContentHandler);
-    method public void setDTDHandler(org.xml.sax.DTDHandler);
-    method public void setEntityResolver(org.xml.sax.EntityResolver);
-    method public void setErrorHandler(org.xml.sax.ErrorHandler);
-    method public void setFeature(String, boolean) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
-    method public void setProperty(String, Object) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
-  }
-
-}
-
-package org.xml.sax.ext {
-
-  public interface Attributes2 extends org.xml.sax.Attributes {
-    method public boolean isDeclared(int);
-    method public boolean isDeclared(String);
-    method public boolean isDeclared(String, String);
-    method public boolean isSpecified(int);
-    method public boolean isSpecified(String, String);
-    method public boolean isSpecified(String);
-  }
-
-  public class Attributes2Impl extends org.xml.sax.helpers.AttributesImpl implements org.xml.sax.ext.Attributes2 {
-    ctor public Attributes2Impl();
-    ctor public Attributes2Impl(org.xml.sax.Attributes);
-    method public boolean isDeclared(int);
-    method public boolean isDeclared(String, String);
-    method public boolean isDeclared(String);
-    method public boolean isSpecified(int);
-    method public boolean isSpecified(String, String);
-    method public boolean isSpecified(String);
-    method public void setDeclared(int, boolean);
-    method public void setSpecified(int, boolean);
-  }
-
-  public interface DeclHandler {
-    method public void attributeDecl(String, String, String, String, String) throws org.xml.sax.SAXException;
-    method public void elementDecl(String, String) throws org.xml.sax.SAXException;
-    method public void externalEntityDecl(String, String, String) throws org.xml.sax.SAXException;
-    method public void internalEntityDecl(String, String) throws org.xml.sax.SAXException;
-  }
-
-  public class DefaultHandler2 extends org.xml.sax.helpers.DefaultHandler implements org.xml.sax.ext.DeclHandler org.xml.sax.ext.EntityResolver2 org.xml.sax.ext.LexicalHandler {
-    ctor public DefaultHandler2();
-    method public void attributeDecl(String, String, String, String, String) throws org.xml.sax.SAXException;
-    method public void comment(char[], int, int) throws org.xml.sax.SAXException;
-    method public void elementDecl(String, String) throws org.xml.sax.SAXException;
-    method public void endCDATA() throws org.xml.sax.SAXException;
-    method public void endDTD() throws org.xml.sax.SAXException;
-    method public void endEntity(String) throws org.xml.sax.SAXException;
-    method public void externalEntityDecl(String, String, String) throws org.xml.sax.SAXException;
-    method public org.xml.sax.InputSource getExternalSubset(String, String) throws java.io.IOException, org.xml.sax.SAXException;
-    method public void internalEntityDecl(String, String) throws org.xml.sax.SAXException;
-    method public org.xml.sax.InputSource resolveEntity(String, String, String, String) throws java.io.IOException, org.xml.sax.SAXException;
-    method public void startCDATA() throws org.xml.sax.SAXException;
-    method public void startDTD(String, String, String) throws org.xml.sax.SAXException;
-    method public void startEntity(String) throws org.xml.sax.SAXException;
-  }
-
-  public interface EntityResolver2 extends org.xml.sax.EntityResolver {
-    method public org.xml.sax.InputSource getExternalSubset(String, String) throws java.io.IOException, org.xml.sax.SAXException;
-    method public org.xml.sax.InputSource resolveEntity(String, String, String, String) throws java.io.IOException, org.xml.sax.SAXException;
-  }
-
-  public interface LexicalHandler {
-    method public void comment(char[], int, int) throws org.xml.sax.SAXException;
-    method public void endCDATA() throws org.xml.sax.SAXException;
-    method public void endDTD() throws org.xml.sax.SAXException;
-    method public void endEntity(String) throws org.xml.sax.SAXException;
-    method public void startCDATA() throws org.xml.sax.SAXException;
-    method public void startDTD(String, String, String) throws org.xml.sax.SAXException;
-    method public void startEntity(String) throws org.xml.sax.SAXException;
-  }
-
-  public interface Locator2 extends org.xml.sax.Locator {
-    method public String getEncoding();
-    method public String getXMLVersion();
-  }
-
-  public class Locator2Impl extends org.xml.sax.helpers.LocatorImpl implements org.xml.sax.ext.Locator2 {
-    ctor public Locator2Impl();
-    ctor public Locator2Impl(org.xml.sax.Locator);
-    method public String getEncoding();
-    method public String getXMLVersion();
-    method public void setEncoding(String);
-    method public void setXMLVersion(String);
-  }
-
-}
-
-package org.xml.sax.helpers {
-
-  @Deprecated public class AttributeListImpl implements org.xml.sax.AttributeList {
-    ctor @Deprecated public AttributeListImpl();
-    ctor @Deprecated public AttributeListImpl(org.xml.sax.AttributeList);
-    method @Deprecated public void addAttribute(String, String, String);
-    method @Deprecated public void clear();
-    method @Deprecated public int getLength();
-    method @Deprecated public String getName(int);
-    method @Deprecated public String getType(int);
-    method @Deprecated public String getType(String);
-    method @Deprecated public String getValue(int);
-    method @Deprecated public String getValue(String);
-    method @Deprecated public void removeAttribute(String);
-    method @Deprecated public void setAttributeList(org.xml.sax.AttributeList);
-  }
-
-  public class AttributesImpl implements org.xml.sax.Attributes {
-    ctor public AttributesImpl();
-    ctor public AttributesImpl(org.xml.sax.Attributes);
-    method public void addAttribute(String, String, String, String, String);
-    method public void clear();
-    method public int getIndex(String, String);
-    method public int getIndex(String);
-    method public int getLength();
-    method public String getLocalName(int);
-    method public String getQName(int);
-    method public String getType(int);
-    method public String getType(String, String);
-    method public String getType(String);
-    method public String getURI(int);
-    method public String getValue(int);
-    method public String getValue(String, String);
-    method public String getValue(String);
-    method public void removeAttribute(int);
-    method public void setAttribute(int, String, String, String, String, String);
-    method public void setAttributes(org.xml.sax.Attributes);
-    method public void setLocalName(int, String);
-    method public void setQName(int, String);
-    method public void setType(int, String);
-    method public void setURI(int, String);
-    method public void setValue(int, String);
-  }
-
-  public class DefaultHandler implements org.xml.sax.ContentHandler org.xml.sax.DTDHandler org.xml.sax.EntityResolver org.xml.sax.ErrorHandler {
-    ctor public DefaultHandler();
-    method public void characters(char[], int, int) throws org.xml.sax.SAXException;
-    method public void endDocument() throws org.xml.sax.SAXException;
-    method public void endElement(String, String, String) throws org.xml.sax.SAXException;
-    method public void endPrefixMapping(String) throws org.xml.sax.SAXException;
-    method public void error(org.xml.sax.SAXParseException) throws org.xml.sax.SAXException;
-    method public void fatalError(org.xml.sax.SAXParseException) throws org.xml.sax.SAXException;
-    method public void ignorableWhitespace(char[], int, int) throws org.xml.sax.SAXException;
-    method public void notationDecl(String, String, String) throws org.xml.sax.SAXException;
-    method public void processingInstruction(String, String) throws org.xml.sax.SAXException;
-    method public org.xml.sax.InputSource resolveEntity(String, String) throws java.io.IOException, org.xml.sax.SAXException;
-    method public void setDocumentLocator(org.xml.sax.Locator);
-    method public void skippedEntity(String) throws org.xml.sax.SAXException;
-    method public void startDocument() throws org.xml.sax.SAXException;
-    method public void startElement(String, String, String, org.xml.sax.Attributes) throws org.xml.sax.SAXException;
-    method public void startPrefixMapping(String, String) throws org.xml.sax.SAXException;
-    method public void unparsedEntityDecl(String, String, String, String) throws org.xml.sax.SAXException;
-    method public void warning(org.xml.sax.SAXParseException) throws org.xml.sax.SAXException;
-  }
-
-  public class LocatorImpl implements org.xml.sax.Locator {
-    ctor public LocatorImpl();
-    ctor public LocatorImpl(org.xml.sax.Locator);
-    method public int getColumnNumber();
-    method public int getLineNumber();
-    method public String getPublicId();
-    method public String getSystemId();
-    method public void setColumnNumber(int);
-    method public void setLineNumber(int);
-    method public void setPublicId(String);
-    method public void setSystemId(String);
-  }
-
-  public class NamespaceSupport {
-    ctor public NamespaceSupport();
-    method public boolean declarePrefix(String, String);
-    method public java.util.Enumeration getDeclaredPrefixes();
-    method public String getPrefix(String);
-    method public java.util.Enumeration getPrefixes();
-    method public java.util.Enumeration getPrefixes(String);
-    method public String getURI(String);
-    method public boolean isNamespaceDeclUris();
-    method public void popContext();
-    method public String[] processName(String, String[], boolean);
-    method public void pushContext();
-    method public void reset();
-    method public void setNamespaceDeclUris(boolean);
-    field public static final String NSDECL = "http://www.w3.org/xmlns/2000/";
-    field public static final String XMLNS = "http://www.w3.org/XML/1998/namespace";
-  }
-
-  public class ParserAdapter implements org.xml.sax.DocumentHandler org.xml.sax.XMLReader {
-    ctor public ParserAdapter() throws org.xml.sax.SAXException;
-    ctor public ParserAdapter(org.xml.sax.Parser);
-    method public void characters(char[], int, int) throws org.xml.sax.SAXException;
-    method public void endDocument() throws org.xml.sax.SAXException;
-    method public void endElement(String) throws org.xml.sax.SAXException;
-    method public org.xml.sax.ContentHandler getContentHandler();
-    method public org.xml.sax.DTDHandler getDTDHandler();
-    method public org.xml.sax.EntityResolver getEntityResolver();
-    method public org.xml.sax.ErrorHandler getErrorHandler();
-    method public boolean getFeature(String) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
-    method public Object getProperty(String) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
-    method public void ignorableWhitespace(char[], int, int) throws org.xml.sax.SAXException;
-    method public void parse(String) throws java.io.IOException, org.xml.sax.SAXException;
-    method public void parse(org.xml.sax.InputSource) throws java.io.IOException, org.xml.sax.SAXException;
-    method public void processingInstruction(String, String) throws org.xml.sax.SAXException;
-    method public void setContentHandler(org.xml.sax.ContentHandler);
-    method public void setDTDHandler(org.xml.sax.DTDHandler);
-    method public void setDocumentLocator(org.xml.sax.Locator);
-    method public void setEntityResolver(org.xml.sax.EntityResolver);
-    method public void setErrorHandler(org.xml.sax.ErrorHandler);
-    method public void setFeature(String, boolean) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
-    method public void setProperty(String, Object) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
-    method public void startDocument() throws org.xml.sax.SAXException;
-    method public void startElement(String, org.xml.sax.AttributeList) throws org.xml.sax.SAXException;
-  }
-
-  @Deprecated public class ParserFactory {
-    method @Deprecated public static org.xml.sax.Parser makeParser() throws java.lang.ClassCastException, java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException, java.lang.NullPointerException;
-    method @Deprecated public static org.xml.sax.Parser makeParser(String) throws java.lang.ClassCastException, java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
-  }
-
-  public class XMLFilterImpl implements org.xml.sax.ContentHandler org.xml.sax.DTDHandler org.xml.sax.EntityResolver org.xml.sax.ErrorHandler org.xml.sax.XMLFilter {
-    ctor public XMLFilterImpl();
-    ctor public XMLFilterImpl(org.xml.sax.XMLReader);
-    method public void characters(char[], int, int) throws org.xml.sax.SAXException;
-    method public void endDocument() throws org.xml.sax.SAXException;
-    method public void endElement(String, String, String) throws org.xml.sax.SAXException;
-    method public void endPrefixMapping(String) throws org.xml.sax.SAXException;
-    method public void error(org.xml.sax.SAXParseException) throws org.xml.sax.SAXException;
-    method public void fatalError(org.xml.sax.SAXParseException) throws org.xml.sax.SAXException;
-    method public org.xml.sax.ContentHandler getContentHandler();
-    method public org.xml.sax.DTDHandler getDTDHandler();
-    method public org.xml.sax.EntityResolver getEntityResolver();
-    method public org.xml.sax.ErrorHandler getErrorHandler();
-    method public boolean getFeature(String) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
-    method public org.xml.sax.XMLReader getParent();
-    method public Object getProperty(String) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
-    method public void ignorableWhitespace(char[], int, int) throws org.xml.sax.SAXException;
-    method public void notationDecl(String, String, String) throws org.xml.sax.SAXException;
-    method public void parse(org.xml.sax.InputSource) throws java.io.IOException, org.xml.sax.SAXException;
-    method public void parse(String) throws java.io.IOException, org.xml.sax.SAXException;
-    method public void processingInstruction(String, String) throws org.xml.sax.SAXException;
-    method public org.xml.sax.InputSource resolveEntity(String, String) throws java.io.IOException, org.xml.sax.SAXException;
-    method public void setContentHandler(org.xml.sax.ContentHandler);
-    method public void setDTDHandler(org.xml.sax.DTDHandler);
-    method public void setDocumentLocator(org.xml.sax.Locator);
-    method public void setEntityResolver(org.xml.sax.EntityResolver);
-    method public void setErrorHandler(org.xml.sax.ErrorHandler);
-    method public void setFeature(String, boolean) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
-    method public void setParent(org.xml.sax.XMLReader);
-    method public void setProperty(String, Object) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
-    method public void skippedEntity(String) throws org.xml.sax.SAXException;
-    method public void startDocument() throws org.xml.sax.SAXException;
-    method public void startElement(String, String, String, org.xml.sax.Attributes) throws org.xml.sax.SAXException;
-    method public void startPrefixMapping(String, String) throws org.xml.sax.SAXException;
-    method public void unparsedEntityDecl(String, String, String, String) throws org.xml.sax.SAXException;
-    method public void warning(org.xml.sax.SAXParseException) throws org.xml.sax.SAXException;
-  }
-
-  public class XMLReaderAdapter implements org.xml.sax.ContentHandler org.xml.sax.Parser {
-    ctor public XMLReaderAdapter() throws org.xml.sax.SAXException;
-    ctor public XMLReaderAdapter(org.xml.sax.XMLReader);
-    method public void characters(char[], int, int) throws org.xml.sax.SAXException;
-    method public void endDocument() throws org.xml.sax.SAXException;
-    method public void endElement(String, String, String) throws org.xml.sax.SAXException;
-    method public void endPrefixMapping(String);
-    method public void ignorableWhitespace(char[], int, int) throws org.xml.sax.SAXException;
-    method public void parse(String) throws java.io.IOException, org.xml.sax.SAXException;
-    method public void parse(org.xml.sax.InputSource) throws java.io.IOException, org.xml.sax.SAXException;
-    method public void processingInstruction(String, String) throws org.xml.sax.SAXException;
-    method public void setDTDHandler(org.xml.sax.DTDHandler);
-    method public void setDocumentHandler(org.xml.sax.DocumentHandler);
-    method public void setDocumentLocator(org.xml.sax.Locator);
-    method public void setEntityResolver(org.xml.sax.EntityResolver);
-    method public void setErrorHandler(org.xml.sax.ErrorHandler);
-    method public void setLocale(java.util.Locale) throws org.xml.sax.SAXException;
-    method public void skippedEntity(String) throws org.xml.sax.SAXException;
-    method public void startDocument() throws org.xml.sax.SAXException;
-    method public void startElement(String, String, String, org.xml.sax.Attributes) throws org.xml.sax.SAXException;
-    method public void startPrefixMapping(String, String);
-  }
-
-  public final class XMLReaderFactory {
-    method public static org.xml.sax.XMLReader createXMLReader() throws org.xml.sax.SAXException;
-    method public static org.xml.sax.XMLReader createXMLReader(String) throws org.xml.sax.SAXException;
-  }
-
-}
-
-package org.xmlpull.v1 {
-
-  public interface XmlPullParser {
-    method public void defineEntityReplacementText(String, String) throws org.xmlpull.v1.XmlPullParserException;
-    method public int getAttributeCount();
-    method public String getAttributeName(int);
-    method public String getAttributeNamespace(int);
-    method public String getAttributePrefix(int);
-    method public String getAttributeType(int);
-    method public String getAttributeValue(int);
-    method public String getAttributeValue(String, String);
-    method public int getColumnNumber();
-    method public int getDepth();
-    method public int getEventType() throws org.xmlpull.v1.XmlPullParserException;
-    method public boolean getFeature(String);
-    method public String getInputEncoding();
-    method public int getLineNumber();
-    method public String getName();
-    method public String getNamespace(String);
-    method public String getNamespace();
-    method public int getNamespaceCount(int) throws org.xmlpull.v1.XmlPullParserException;
-    method public String getNamespacePrefix(int) throws org.xmlpull.v1.XmlPullParserException;
-    method public String getNamespaceUri(int) throws org.xmlpull.v1.XmlPullParserException;
-    method public String getPositionDescription();
-    method public String getPrefix();
-    method public Object getProperty(String);
-    method public String getText();
-    method public char[] getTextCharacters(int[]);
-    method public boolean isAttributeDefault(int);
-    method public boolean isEmptyElementTag() throws org.xmlpull.v1.XmlPullParserException;
-    method public boolean isWhitespace() throws org.xmlpull.v1.XmlPullParserException;
-    method public int next() throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
-    method public int nextTag() throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
-    method public String nextText() throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
-    method public int nextToken() throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
-    method public void require(int, String, String) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
-    method public void setFeature(String, boolean) throws org.xmlpull.v1.XmlPullParserException;
-    method public void setInput(java.io.Reader) throws org.xmlpull.v1.XmlPullParserException;
-    method public void setInput(java.io.InputStream, String) throws org.xmlpull.v1.XmlPullParserException;
-    method public void setProperty(String, Object) throws org.xmlpull.v1.XmlPullParserException;
-    field public static final int CDSECT = 5; // 0x5
-    field public static final int COMMENT = 9; // 0x9
-    field public static final int DOCDECL = 10; // 0xa
-    field public static final int END_DOCUMENT = 1; // 0x1
-    field public static final int END_TAG = 3; // 0x3
-    field public static final int ENTITY_REF = 6; // 0x6
-    field public static final String FEATURE_PROCESS_DOCDECL = "http://xmlpull.org/v1/doc/features.html#process-docdecl";
-    field public static final String FEATURE_PROCESS_NAMESPACES = "http://xmlpull.org/v1/doc/features.html#process-namespaces";
-    field public static final String FEATURE_REPORT_NAMESPACE_ATTRIBUTES = "http://xmlpull.org/v1/doc/features.html#report-namespace-prefixes";
-    field public static final String FEATURE_VALIDATION = "http://xmlpull.org/v1/doc/features.html#validation";
-    field public static final int IGNORABLE_WHITESPACE = 7; // 0x7
-    field public static final String NO_NAMESPACE = "";
-    field public static final int PROCESSING_INSTRUCTION = 8; // 0x8
-    field public static final int START_DOCUMENT = 0; // 0x0
-    field public static final int START_TAG = 2; // 0x2
-    field public static final int TEXT = 4; // 0x4
-    field public static final String[] TYPES;
-  }
-
-  public class XmlPullParserException extends java.lang.Exception {
-    ctor public XmlPullParserException(String);
-    ctor public XmlPullParserException(String, org.xmlpull.v1.XmlPullParser, Throwable);
-    method public int getColumnNumber();
-    method public Throwable getDetail();
-    method public int getLineNumber();
-    field protected int column;
-    field protected Throwable detail;
-    field protected int row;
-  }
-
-  public class XmlPullParserFactory {
-    ctor protected XmlPullParserFactory();
-    method public boolean getFeature(String);
-    method public boolean isNamespaceAware();
-    method public boolean isValidating();
-    method public static org.xmlpull.v1.XmlPullParserFactory newInstance() throws org.xmlpull.v1.XmlPullParserException;
-    method public static org.xmlpull.v1.XmlPullParserFactory newInstance(String, Class) throws org.xmlpull.v1.XmlPullParserException;
-    method public org.xmlpull.v1.XmlPullParser newPullParser() throws org.xmlpull.v1.XmlPullParserException;
-    method public org.xmlpull.v1.XmlSerializer newSerializer() throws org.xmlpull.v1.XmlPullParserException;
-    method public void setFeature(String, boolean) throws org.xmlpull.v1.XmlPullParserException;
-    method public void setNamespaceAware(boolean);
-    method public void setValidating(boolean);
-    field public static final String PROPERTY_NAME = "org.xmlpull.v1.XmlPullParserFactory";
-    field protected String classNamesLocation;
-    field protected java.util.HashMap<java.lang.String,java.lang.Boolean> features;
-    field protected java.util.ArrayList parserClasses;
-    field protected java.util.ArrayList serializerClasses;
-  }
-
-  public interface XmlSerializer {
-    method public org.xmlpull.v1.XmlSerializer attribute(String, String, String) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;
-    method public void cdsect(String) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;
-    method public void comment(String) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;
-    method public void docdecl(String) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;
-    method public void endDocument() throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;
-    method public org.xmlpull.v1.XmlSerializer endTag(String, String) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;
-    method public void entityRef(String) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;
-    method public void flush() throws java.io.IOException;
-    method public int getDepth();
-    method public boolean getFeature(String);
-    method public String getName();
-    method public String getNamespace();
-    method public String getPrefix(String, boolean) throws java.lang.IllegalArgumentException;
-    method public Object getProperty(String);
-    method public void ignorableWhitespace(String) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;
-    method public void processingInstruction(String) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;
-    method public void setFeature(String, boolean) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException;
-    method public void setOutput(java.io.OutputStream, String) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;
-    method public void setOutput(java.io.Writer) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;
-    method public void setPrefix(String, String) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;
-    method public void setProperty(String, Object) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException;
-    method public void startDocument(String, Boolean) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;
-    method public org.xmlpull.v1.XmlSerializer startTag(String, String) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;
-    method public org.xmlpull.v1.XmlSerializer text(String) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;
-    method public org.xmlpull.v1.XmlSerializer text(char[], int, int) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;
-  }
-
-}
-
-package org.xmlpull.v1.sax2 {
-
-  public class Driver implements org.xml.sax.Attributes org.xml.sax.Locator org.xml.sax.XMLReader {
-    ctor public Driver() throws org.xmlpull.v1.XmlPullParserException;
-    ctor public Driver(org.xmlpull.v1.XmlPullParser) throws org.xmlpull.v1.XmlPullParserException;
-    method public int getColumnNumber();
-    method public org.xml.sax.ContentHandler getContentHandler();
-    method public org.xml.sax.DTDHandler getDTDHandler();
-    method public org.xml.sax.EntityResolver getEntityResolver();
-    method public org.xml.sax.ErrorHandler getErrorHandler();
-    method public boolean getFeature(String) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
-    method public int getIndex(String, String);
-    method public int getIndex(String);
-    method public int getLength();
-    method public int getLineNumber();
-    method public String getLocalName(int);
-    method public Object getProperty(String) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
-    method public String getPublicId();
-    method public String getQName(int);
-    method public String getSystemId();
-    method public String getType(int);
-    method public String getType(String, String);
-    method public String getType(String);
-    method public String getURI(int);
-    method public String getValue(int);
-    method public String getValue(String, String);
-    method public String getValue(String);
-    method public void parse(org.xml.sax.InputSource) throws java.io.IOException, org.xml.sax.SAXException;
-    method public void parse(String) throws java.io.IOException, org.xml.sax.SAXException;
-    method public void parseSubTree(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xml.sax.SAXException;
-    method public void setContentHandler(org.xml.sax.ContentHandler);
-    method public void setDTDHandler(org.xml.sax.DTDHandler);
-    method public void setEntityResolver(org.xml.sax.EntityResolver);
-    method public void setErrorHandler(org.xml.sax.ErrorHandler);
-    method public void setFeature(String, boolean) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
-    method public void setProperty(String, Object) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
-    method protected void startElement(String, String, String) throws org.xml.sax.SAXException;
-    field protected static final String APACHE_DYNAMIC_VALIDATION_FEATURE = "http://apache.org/xml/features/validation/dynamic";
-    field protected static final String APACHE_SCHEMA_VALIDATION_FEATURE = "http://apache.org/xml/features/validation/schema";
-    field protected static final String DECLARATION_HANDLER_PROPERTY = "http://xml.org/sax/properties/declaration-handler";
-    field protected static final String LEXICAL_HANDLER_PROPERTY = "http://xml.org/sax/properties/lexical-handler";
-    field protected static final String NAMESPACES_FEATURE = "http://xml.org/sax/features/namespaces";
-    field protected static final String NAMESPACE_PREFIXES_FEATURE = "http://xml.org/sax/features/namespace-prefixes";
-    field protected static final String VALIDATION_FEATURE = "http://xml.org/sax/features/validation";
-    field protected org.xml.sax.ContentHandler contentHandler;
-    field protected org.xml.sax.ErrorHandler errorHandler;
-    field protected org.xmlpull.v1.XmlPullParser pp;
-    field protected String systemId;
-  }
-
-}
-
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 05d7bb6..cc819fa 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -4146,8 +4146,10 @@
   public class AudioManager {
     method @Deprecated public int abandonAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, android.media.AudioAttributes);
     method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void addOnPreferredDeviceForStrategyChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.OnPreferredDeviceForStrategyChangedListener) throws java.lang.SecurityException;
+    method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void addOnPreferredDevicesForCapturePresetChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.OnPreferredDevicesForCapturePresetChangedListener) throws java.lang.SecurityException;
     method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void addOnPreferredDevicesForStrategyChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.OnPreferredDevicesForStrategyChangedListener) throws java.lang.SecurityException;
     method public void clearAudioServerStateCallback();
+    method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean clearPreferredDevicesForCapturePreset(int);
     method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int dispatchAudioFocusChange(@NonNull android.media.AudioFocusInfo, int, @NonNull android.media.audiopolicy.AudioPolicy);
     method @IntRange(from=0) public long getAdditionalOutputDeviceDelay(@NonNull android.media.AudioDeviceInfo);
     method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static java.util.List<android.media.audiopolicy.AudioProductStrategy> getAudioProductStrategies();
@@ -4157,6 +4159,7 @@
     method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getMaxVolumeIndexForAttributes(@NonNull android.media.AudioAttributes);
     method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getMinVolumeIndexForAttributes(@NonNull android.media.AudioAttributes);
     method @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public android.media.AudioDeviceAttributes getPreferredDeviceForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy);
+    method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public java.util.List<android.media.AudioDeviceAttributes> getPreferredDevicesForCapturePreset(int);
     method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public java.util.List<android.media.AudioDeviceAttributes> getPreferredDevicesForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy);
     method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int[] getSupportedSystemUsages();
     method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getVolumeIndexForAttributes(@NonNull android.media.AudioAttributes);
@@ -4165,6 +4168,7 @@
     method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int registerAudioPolicy(@NonNull android.media.audiopolicy.AudioPolicy);
     method public void registerVolumeGroupCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.VolumeGroupCallback);
     method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void removeOnPreferredDeviceForStrategyChangedListener(@NonNull android.media.AudioManager.OnPreferredDeviceForStrategyChangedListener);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void removeOnPreferredDevicesForCapturePresetChangedListener(@NonNull android.media.AudioManager.OnPreferredDevicesForCapturePresetChangedListener);
     method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void removeOnPreferredDevicesForStrategyChangedListener(@NonNull android.media.AudioManager.OnPreferredDevicesForStrategyChangedListener);
     method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean removePreferredDeviceForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, @NonNull android.media.AudioAttributes, int, int) throws java.lang.IllegalArgumentException;
@@ -4173,6 +4177,7 @@
     method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean setAdditionalOutputDeviceDelay(@NonNull android.media.AudioDeviceInfo, @IntRange(from=0) long);
     method public void setAudioServerStateCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.AudioServerStateCallback);
     method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setFocusRequestResult(@NonNull android.media.AudioFocusInfo, int, @NonNull android.media.audiopolicy.AudioPolicy);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean setPreferredDeviceForCapturePreset(int, @NonNull android.media.AudioDeviceAttributes);
     method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean setPreferredDeviceForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy, @NonNull android.media.AudioDeviceAttributes);
     method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean setPreferredDevicesForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy, @NonNull java.util.List<android.media.AudioDeviceAttributes>);
     method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setSupportedSystemUsages(@NonNull int[]);
@@ -4197,6 +4202,10 @@
     method @Deprecated public void onPreferredDeviceForStrategyChanged(@NonNull android.media.audiopolicy.AudioProductStrategy, @Nullable android.media.AudioDeviceAttributes);
   }
 
+  public static interface AudioManager.OnPreferredDevicesForCapturePresetChangedListener {
+    method public void onPreferredDevicesForCapturePresetChanged(int, @NonNull java.util.List<android.media.AudioDeviceAttributes>);
+  }
+
   public static interface AudioManager.OnPreferredDevicesForStrategyChangedListener {
     method public void onPreferredDevicesForStrategyChanged(@NonNull android.media.audiopolicy.AudioProductStrategy, @NonNull java.util.List<android.media.AudioDeviceAttributes>);
   }
@@ -6020,6 +6029,10 @@
     method @Deprecated public void onUpstreamChanged(@Nullable android.net.Network);
   }
 
+  public class DnsResolverServiceManager {
+    method @NonNull @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public static android.os.IBinder getService(@NonNull android.content.Context);
+  }
+
   public class EthernetManager {
     method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public android.net.EthernetManager.TetheredInterfaceRequest requestTetheredInterface(@NonNull java.util.concurrent.Executor, @NonNull android.net.EthernetManager.TetheredInterfaceCallback);
   }
@@ -6976,12 +6989,14 @@
     method @NonNull @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public android.os.connectivity.WifiBatteryStats getWifiBatteryStats();
     method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportFullWifiLockAcquiredFromSource(@NonNull android.os.WorkSource);
     method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportFullWifiLockReleasedFromSource(@NonNull android.os.WorkSource);
+    method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportMobileRadioPowerState(boolean, int) throws java.lang.RuntimeException;
     method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportWifiBatchedScanStartedFromSource(@NonNull android.os.WorkSource, @IntRange(from=0) int);
     method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportWifiBatchedScanStoppedFromSource(@NonNull android.os.WorkSource);
     method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportWifiMulticastDisabled(@NonNull android.os.WorkSource);
     method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportWifiMulticastEnabled(@NonNull android.os.WorkSource);
     method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportWifiOff();
     method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportWifiOn();
+    method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportWifiRadioPowerState(boolean, int) throws java.lang.RuntimeException;
     method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportWifiRssiChanged(@IntRange(from=0xffffff81, to=0) int);
     method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportWifiScanStartedFromSource(@NonNull android.os.WorkSource);
     method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportWifiScanStoppedFromSource(@NonNull android.os.WorkSource);
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index b6bd687..9cf9ce4 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -850,6 +850,7 @@
   }
 
   public class AudioManager {
+    method @Nullable public static android.media.AudioDeviceInfo getDeviceInfoFromType(int);
     method public boolean hasRegisteredDynamicPolicy();
   }
 
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 6edc8ea..9acf6756 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -53,7 +53,6 @@
 import android.content.pm.ParceledListSlice;
 import android.content.pm.UserInfo;
 import android.graphics.Bitmap;
-import android.net.NetworkUtils;
 import android.net.PrivateDnsConnectivityChecker;
 import android.net.ProxyInfo;
 import android.net.Uri;
@@ -90,6 +89,7 @@
 import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.net.NetworkUtilsInternal;
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.util.Preconditions;
 import com.android.org.conscrypt.TrustedCertificateStore;
@@ -11466,7 +11466,7 @@
             return PRIVATE_DNS_SET_ERROR_FAILURE_SETTING;
         }
 
-        if (NetworkUtils.isWeaklyValidatedHostname(privateDnsHost)) {
+        if (NetworkUtilsInternal.isWeaklyValidatedHostname(privateDnsHost)) {
             if (!PrivateDnsConnectivityChecker.canConnectToPrivateDnsServer(privateDnsHost)) {
                 return PRIVATE_DNS_SET_ERROR_HOST_NOT_SERVING;
             }
diff --git a/core/java/android/app/people/OWNERS b/core/java/android/app/people/OWNERS
new file mode 100644
index 0000000..7371a88
--- /dev/null
+++ b/core/java/android/app/people/OWNERS
@@ -0,0 +1,4 @@
+# Bug component: 978868
+
+danningc@google.com
+juliacr@google.com
\ No newline at end of file
diff --git a/core/java/android/net/DnsResolverServiceManager.java b/core/java/android/net/DnsResolverServiceManager.java
new file mode 100644
index 0000000..1597322
--- /dev/null
+++ b/core/java/android/net/DnsResolverServiceManager.java
@@ -0,0 +1,63 @@
+/*
+ * 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;
+
+import android.annotation.NonNull;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.content.Context;
+import android.os.IBinder;
+import android.os.ServiceManager;
+
+import java.util.Objects;
+
+/**
+ * Provides a way to obtain the DnsResolver binder objects.
+ *
+ * @hide
+ */
+@SystemApi
+public class DnsResolverServiceManager {
+    /**
+     * Name to retrieve a {@link android.net.IDnsResolver} IBinder.
+     */
+    private static final String DNS_RESOLVER_SERVICE = "dnsresolver";
+
+    private DnsResolverServiceManager() {}
+
+    /**
+     * Get an {@link IBinder} representing the DnsResolver stable AIDL interface
+     *
+     * @param context the context for permission check.
+     * @return {@link android.net.IDnsResolver} IBinder.
+     */
+    @NonNull
+    @RequiresPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK)
+    public static IBinder getService(@NonNull final Context context) {
+        Objects.requireNonNull(context);
+        context.enforceCallingOrSelfPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+                "DnsResolverServiceManager");
+        try {
+            return ServiceManager.getServiceOrThrow(DNS_RESOLVER_SERVICE);
+        } catch (ServiceManager.ServiceNotFoundException e) {
+            // Catch ServiceManager#ServiceNotFoundException and rethrow IllegalStateException
+            // because ServiceManager#ServiceNotFoundException is @hide so that it can't be listed
+            // on the system api. Thus, rethrow IllegalStateException if dns resolver service cannot
+            // be found.
+            throw new IllegalStateException("Cannot find dns resolver service.");
+        }
+    }
+}
diff --git a/core/java/android/net/EthernetManager.java b/core/java/android/net/EthernetManager.java
index 84a8e1c..7cd63ef 100644
--- a/core/java/android/net/EthernetManager.java
+++ b/core/java/android/net/EthernetManager.java
@@ -24,10 +24,11 @@
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.os.Build;
-import android.os.Handler;
-import android.os.Message;
 import android.os.RemoteException;
 
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.os.BackgroundThread;
+
 import java.util.ArrayList;
 import java.util.Objects;
 import java.util.concurrent.Executor;
@@ -41,31 +42,35 @@
 @SystemService(Context.ETHERNET_SERVICE)
 public class EthernetManager {
     private static final String TAG = "EthernetManager";
-    private static final int MSG_AVAILABILITY_CHANGED = 1000;
 
-    private final Context mContext;
     private final IEthernetManager mService;
-    private final Handler mHandler = new Handler(ConnectivityThread.getInstanceLooper()) {
-        @Override
-        public void handleMessage(Message msg) {
-            if (msg.what == MSG_AVAILABILITY_CHANGED) {
-                boolean isAvailable = (msg.arg1 == 1);
-                for (Listener listener : mListeners) {
-                    listener.onAvailabilityChanged((String) msg.obj, isAvailable);
-                }
-            }
-        }
-    };
-    private final ArrayList<Listener> mListeners = new ArrayList<>();
+    @GuardedBy("mListeners")
+    private final ArrayList<ListenerInfo> mListeners = new ArrayList<>();
     private final IEthernetServiceListener.Stub mServiceListener =
             new IEthernetServiceListener.Stub() {
                 @Override
                 public void onAvailabilityChanged(String iface, boolean isAvailable) {
-                    mHandler.obtainMessage(
-                            MSG_AVAILABILITY_CHANGED, isAvailable ? 1 : 0, 0, iface).sendToTarget();
+                    synchronized (mListeners) {
+                        for (ListenerInfo li : mListeners) {
+                            li.executor.execute(() ->
+                                    li.listener.onAvailabilityChanged(iface, isAvailable));
+                        }
+                    }
                 }
             };
 
+    private static class ListenerInfo {
+        @NonNull
+        public final Executor executor;
+        @NonNull
+        public final Listener listener;
+
+        private ListenerInfo(@NonNull Executor executor, @NonNull Listener listener) {
+            this.executor = executor;
+            this.listener = listener;
+        }
+    }
+
     /**
      * A listener interface to receive notification on changes in Ethernet.
      * @hide
@@ -89,7 +94,6 @@
      * @hide
      */
     public EthernetManager(Context context, IEthernetManager service) {
-        mContext = context;
         mService = service;
     }
 
@@ -146,21 +150,38 @@
 
     /**
      * Adds a listener.
+     *
+     * Consider using {@link #addListener(Listener, Executor)} instead: this method uses a default
+     * executor that may have higher latency than a provided executor.
      * @param listener A {@link Listener} to add.
      * @throws IllegalArgumentException If the listener is null.
      * @hide
      */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    public void addListener(Listener listener) {
-        if (listener == null) {
-            throw new IllegalArgumentException("listener must not be null");
+    public void addListener(@NonNull Listener listener) {
+        addListener(listener, BackgroundThread.getExecutor());
+    }
+
+    /**
+     * Adds a listener.
+     * @param listener A {@link Listener} to add.
+     * @param executor Executor to run callbacks on.
+     * @throws IllegalArgumentException If the listener or executor is null.
+     * @hide
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public void addListener(@NonNull Listener listener, @NonNull Executor executor) {
+        if (listener == null || executor == null) {
+            throw new NullPointerException("listener and executor must not be null");
         }
-        mListeners.add(listener);
-        if (mListeners.size() == 1) {
-            try {
-                mService.addListener(mServiceListener);
-            } catch (RemoteException e) {
-                throw e.rethrowFromSystemServer();
+        synchronized (mListeners) {
+            mListeners.add(new ListenerInfo(executor, listener));
+            if (mListeners.size() == 1) {
+                try {
+                    mService.addListener(mServiceListener);
+                } catch (RemoteException e) {
+                    throw e.rethrowFromSystemServer();
+                }
             }
         }
     }
@@ -185,16 +206,18 @@
      * @hide
      */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    public void removeListener(Listener listener) {
+    public void removeListener(@NonNull Listener listener) {
         if (listener == null) {
             throw new IllegalArgumentException("listener must not be null");
         }
-        mListeners.remove(listener);
-        if (mListeners.isEmpty()) {
-            try {
-                mService.removeListener(mServiceListener);
-            } catch (RemoteException e) {
-                throw e.rethrowFromSystemServer();
+        synchronized (mListeners) {
+            mListeners.removeIf(l -> l.listener == listener);
+            if (mListeners.isEmpty()) {
+                try {
+                    mService.removeListener(mServiceListener);
+                } catch (RemoteException e) {
+                    throw e.rethrowFromSystemServer();
+                }
             }
         }
     }
diff --git a/core/java/android/net/INetworkManagementEventObserver.aidl b/core/java/android/net/INetworkManagementEventObserver.aidl
index f0fe92e..37813ce 100644
--- a/core/java/android/net/INetworkManagementEventObserver.aidl
+++ b/core/java/android/net/INetworkManagementEventObserver.aidl
@@ -85,11 +85,14 @@
     /**
      * Interface data activity status is changed.
      *
-     * @param iface The interface.
+     * @param networkType The legacy network type of the data activity change.
      * @param active  True if the interface is actively transmitting data, false if it is idle.
      * @param tsNanos Elapsed realtime in nanos when the state of the network interface changed.
+     * @param uid Uid of this event. It represents the uid that was responsible for waking the
+     *            radio. For those events that are reported by system itself, not from specific uid,
+     *            use -1 for the events which means no uid.
      */
-    void interfaceClassDataActivityChanged(String label, boolean active, long tsNanos);
+    void interfaceClassDataActivityChanged(int networkType, boolean active, long tsNanos, int uid);
 
     /**
      * Information about available DNS servers has been received.
diff --git a/core/java/android/net/INetworkPolicyManager.aidl b/core/java/android/net/INetworkPolicyManager.aidl
index e486052..792e5b4 100644
--- a/core/java/android/net/INetworkPolicyManager.aidl
+++ b/core/java/android/net/INetworkPolicyManager.aidl
@@ -17,6 +17,7 @@
 package android.net;
 
 import android.net.INetworkPolicyListener;
+import android.net.Network;
 import android.net.NetworkPolicy;
 import android.net.NetworkQuotaInfo;
 import android.net.NetworkState;
@@ -67,6 +68,8 @@
     void setDeviceIdleMode(boolean enabled);
     void setWifiMeteredOverride(String networkId, int meteredOverride);
 
+    int getMultipathPreference(in Network network);
+
     @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     NetworkQuotaInfo getNetworkQuotaInfo(in NetworkState state);
 
diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java
index f05f033..ce16a78 100644
--- a/core/java/android/net/NetworkPolicyManager.java
+++ b/core/java/android/net/NetworkPolicyManager.java
@@ -432,6 +432,17 @@
         }
     }
 
+    /**
+     * Get multipath preference for the given network.
+     */
+    public int getMultipathPreference(Network network) {
+        try {
+            return mService.getMultipathPreference(network);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
     /** {@hide} */
     @Deprecated
     public static Iterator<Pair<ZonedDateTime, ZonedDateTime>> cycleIterator(NetworkPolicy policy) {
diff --git a/core/java/android/net/NetworkStatsHistory.java b/core/java/android/net/NetworkStatsHistory.java
index fba7561..bf25602 100644
--- a/core/java/android/net/NetworkStatsHistory.java
+++ b/core/java/android/net/NetworkStatsHistory.java
@@ -26,9 +26,9 @@
 import static android.net.NetworkStatsHistory.Entry.UNKNOWN;
 import static android.net.NetworkStatsHistory.ParcelUtils.readLongArray;
 import static android.net.NetworkStatsHistory.ParcelUtils.writeLongArray;
-import static android.net.NetworkUtils.multiplySafeByRational;
 import static android.text.format.DateUtils.SECOND_IN_MILLIS;
 
+import static com.android.internal.net.NetworkUtilsInternal.multiplySafeByRational;
 import static com.android.internal.util.ArrayUtils.total;
 
 import android.compat.annotation.UnsupportedAppUsage;
diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java
index d84ee2a..b5962c5 100644
--- a/core/java/android/net/NetworkUtils.java
+++ b/core/java/android/net/NetworkUtils.java
@@ -16,14 +16,9 @@
 
 package android.net;
 
-import static android.system.OsConstants.AF_INET;
-import static android.system.OsConstants.AF_INET6;
-
-import android.annotation.NonNull;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Build;
 import android.system.ErrnoException;
-import android.system.Os;
 import android.util.Log;
 import android.util.Pair;
 
@@ -155,14 +150,6 @@
     public static native Network getDnsNetwork() throws ErrnoException;
 
     /**
-     * Allow/Disallow creating AF_INET/AF_INET6 sockets and DNS lookups for current process.
-     *
-     * @param allowNetworking whether to allow or disallow creating AF_INET/AF_INET6 sockets
-     *                        and DNS lookups.
-     */
-    public static native void setAllowNetworkingForProcess(boolean allowNetworking);
-
-    /**
      * Get the tcp repair window associated with the {@code fd}.
      *
      * @param fd the tcp socket's {@link FileDescriptor}.
@@ -437,60 +424,4 @@
         return routedIPCount;
     }
 
-    private static final int[] ADDRESS_FAMILIES = new int[] {AF_INET, AF_INET6};
-
-    /**
-     * Returns true if the hostname is weakly validated.
-     * @param hostname Name of host to validate.
-     * @return True if it's a valid-ish hostname.
-     *
-     * @hide
-     */
-    public static boolean isWeaklyValidatedHostname(@NonNull String hostname) {
-        // TODO(b/34953048): Use a validation method that permits more accurate,
-        // but still inexpensive, checking of likely valid DNS hostnames.
-        final String weakHostnameRegex = "^[a-zA-Z0-9_.-]+$";
-        if (!hostname.matches(weakHostnameRegex)) {
-            return false;
-        }
-
-        for (int address_family : ADDRESS_FAMILIES) {
-            if (Os.inet_pton(address_family, hostname) != null) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Safely multiple a value by a rational.
-     * <p>
-     * Internally it uses integer-based math whenever possible, but switches
-     * over to double-based math if values would overflow.
-     * @hide
-     */
-    public static long multiplySafeByRational(long value, long num, long den) {
-        if (den == 0) {
-            throw new ArithmeticException("Invalid Denominator");
-        }
-        long x = value;
-        long y = num;
-
-        // Logic shamelessly borrowed from Math.multiplyExact()
-        long r = x * y;
-        long ax = Math.abs(x);
-        long ay = Math.abs(y);
-        if (((ax | ay) >>> 31 != 0)) {
-            // Some bits greater than 2^31 that might cause overflow
-            // Check the result using the divide operator
-            // and check for the special case of Long.MIN_VALUE * -1
-            if (((y != 0) && (r / y != x)) ||
-                    (x == Long.MIN_VALUE && y == -1)) {
-                // Use double math to avoid overflowing
-                return (long) (((double) num / den) * value);
-            }
-        }
-        return r / den;
-    }
 }
diff --git a/core/java/android/net/Proxy.java b/core/java/android/net/Proxy.java
index 20ccc07..03b07e0 100644
--- a/core/java/android/net/Proxy.java
+++ b/core/java/android/net/Proxy.java
@@ -24,6 +24,8 @@
 import android.text.TextUtils;
 import android.util.Log;
 
+import com.android.net.module.util.ProxyUtils;
+
 import java.net.InetSocketAddress;
 import java.net.ProxySelector;
 import java.net.URI;
@@ -251,7 +253,7 @@
         if (p != null) {
             host = p.getHost();
             port = Integer.toString(p.getPort());
-            exclList = p.getExclusionListAsString();
+            exclList = ProxyUtils.exclusionListAsString(p.getExclusionList());
             pacFileUrl = p.getPacFileUrl();
         }
         setHttpProxySystemProperty(host, port, exclList, pacFileUrl);
diff --git a/core/java/android/os/BatteryStatsManager.java b/core/java/android/os/BatteryStatsManager.java
index a9585c6..258e58d 100644
--- a/core/java/android/os/BatteryStatsManager.java
+++ b/core/java/android/os/BatteryStatsManager.java
@@ -26,6 +26,7 @@
 import android.content.Context;
 import android.os.connectivity.CellularBatteryStats;
 import android.os.connectivity.WifiBatteryStats;
+import android.telephony.DataConnectionRealTimeInfo;
 
 import com.android.internal.app.IBatteryStats;
 
@@ -376,4 +377,50 @@
             e.rethrowFromSystemServer();
         }
     }
+
+    /**
+     * Indicates that the radio power state has changed.
+     *
+     * @param isActive indicates if the mobile radio is powered.
+     * @param uid Uid of this event. For the active state it represents the uid that was responsible
+     *            for waking the radio, or -1 if the system was responsible for waking the radio.
+     *            For inactive state, the UID should always be -1.
+     * @throws RuntimeException if there are binder remote-invocation errors.
+     */
+    @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS)
+    public void reportMobileRadioPowerState(boolean isActive, int uid) throws RuntimeException {
+        try {
+            mBatteryStats.noteMobileRadioPowerState(getDataConnectionPowerState(isActive),
+                    SystemClock.elapsedRealtimeNanos(), uid);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Indicates that the wifi power state has changed.
+     *
+     * @param isActive indicates if the wifi radio is powered.
+     * @param uid Uid of this event. For the active state it represents the uid that was responsible
+     *            for waking the radio, or -1 if the system was responsible for waking the radio.
+     *            For inactive state, the UID should always be -1.
+     * @throws RuntimeException if there are binder remote-invocation errors.
+     */
+    @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS)
+    public void reportWifiRadioPowerState(boolean isActive, int uid) throws RuntimeException {
+        try {
+            mBatteryStats.noteWifiRadioPowerState(getDataConnectionPowerState(isActive),
+                    SystemClock.elapsedRealtimeNanos(), uid);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    private static int getDataConnectionPowerState(boolean isActive) {
+        // TODO: DataConnectionRealTimeInfo is under telephony package but the constants are used
+        // for both Wifi and mobile. It would make more sense to separate the constants to a generic
+        // class or move it to generic package.
+        return isActive ? DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH
+                : DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
+    }
 }
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index 8ab734d..27dc6e0 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -2576,6 +2576,13 @@
     public static native long getIonMappedSizeKb();
 
     /**
+     * Return memory size in kilobytes used by GPU.
+     *
+     * @hide
+     */
+    public static native long getGpuTotalUsageKb();
+
+    /**
      * Return whether virtually-mapped kernel stacks are enabled (CONFIG_VMAP_STACK).
      * Note: caller needs config_gz read sepolicy permission
      *
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index 25d84ba..33dedda 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -282,8 +282,8 @@
     /**
      * Control network activity of a UID over interfaces with a quota limit.
      */
-    void setUidMeteredNetworkDenylist(int uid, boolean enable);
-    void setUidMeteredNetworkAllowlist(int uid, boolean enable);
+    void setUidOnMeteredNetworkDenylist(int uid, boolean enable);
+    void setUidOnMeteredNetworkAllowlist(int uid, boolean enable);
     boolean setDataSaverModeEnabled(boolean enable);
 
     void setUidCleartextNetworkPolicy(int uid, int policy);
diff --git a/core/java/android/os/OWNERS b/core/java/android/os/OWNERS
index 563ff62..8c77a20 100644
--- a/core/java/android/os/OWNERS
+++ b/core/java/android/os/OWNERS
@@ -22,6 +22,34 @@
 per-file BatteryUsageStats* = file:/BATTERY_STATS_OWNERS
 per-file PowerComponents.java = file:/BATTERY_STATS_OWNERS
 
+# Binder
+per-file BadParcelableException.java = file:platform/frameworks/native:/libs/binder/OWNERS
+per-file Binder.java = file:platform/frameworks/native:/libs/binder/OWNERS
+per-file BinderProxy.java = file:platform/frameworks/native:/libs/binder/OWNERS
+per-file DeadObjectException.java = file:platform/frameworks/native:/libs/binder/OWNERS
+per-file IBinder.java = file:platform/frameworks/native:/libs/binder/OWNERS
+per-file Parcel.java = file:platform/frameworks/native:/libs/binder/OWNERS
+per-file ParcelFileDescriptor.java = file:platform/frameworks/native:/libs/binder/OWNERS
+per-file ParcelFormatException.java = file:platform/frameworks/native:/libs/binder/OWNERS
+per-file Parcelable.java = file:platform/frameworks/native:/libs/binder/OWNERS
+per-file ParcelableException.java = file:platform/frameworks/native:/libs/binder/OWNERS
+per-file ParcelableHolder.java = file:platform/frameworks/native:/libs/binder/OWNERS
+per-file ParcelableParcel.java = file:platform/frameworks/native:/libs/binder/OWNERS
+per-file RemoteException.java = file:platform/frameworks/native:/libs/binder/OWNERS
+per-file ServiceManager.java = file:platform/frameworks/native:/libs/binder/OWNERS
+per-file ServiceManagerNative.java = file:platform/frameworks/native:/libs/binder/OWNERS
+per-file ServiceSpecificException.java = file:platform/frameworks/native:/libs/binder/OWNERS
+per-file TransactionTooLargeException.java = file:platform/frameworks/native:/libs/binder/OWNERS
+
+# HwBinder
+per-file HwBinder.java = file:platform/system/libhwbinder:/OWNERS
+per-file HwBlob.java = file:platform/system/libhwbinder:/OWNERS
+per-file HwParcel.java = file:platform/system/libhwbinder:/OWNERS
+per-file HwParcel.java = file:platform/system/libhwbinder:/OWNERS
+per-file HwRemoteBinder.java = file:platform/system/libhwbinder:/OWNERS
+per-file IHwBinder.java = file:platform/system/libhwbinder:/OWNERS
+per-file IHwInterface.java = file:platform/system/libhwbinder:/OWNERS
+
 per-file GraphicsEnvironment.java = chrisforbes@google.com, cnorthrop@google.com, lpy@google.com, timvp@google.com, zzyiwei@google.com
 
 per-file *Network* = file:/services/core/java/com/android/server/net/OWNERS
diff --git a/core/java/android/os/ParcelableHolder.java b/core/java/android/os/ParcelableHolder.java
index 1be367c..368ee2d 100644
--- a/core/java/android/os/ParcelableHolder.java
+++ b/core/java/android/os/ParcelableHolder.java
@@ -63,6 +63,8 @@
  * op.y = ...;
  * ap.extension.setParcelable(op);}</pre>
  *
+ * <p class="note">ParcelableHolder is <strong>not</strong> thread-safe.</p>
+ *
  * @hide
  */
 @SystemApi
@@ -120,6 +122,7 @@
 
     /**
      * Write a parcelable into ParcelableHolder, the previous parcelable will be removed.
+     * (@link #setParcelable} and (@link #getParcelable} are not thread-safe.
      * @throws BadParcelableException if the parcelable's stability is more unstable
      *         ParcelableHolder.
      */
@@ -139,6 +142,8 @@
     }
 
     /**
+     * Read a parcelable from ParcelableHolder.
+     * (@link #setParcelable} and (@link #getParcelable} are not thread-safe.
      * @return the parcelable that was written by {@link #setParcelable} or {@link #readFromParcel},
      *         or {@code null} if the parcelable has not been written.
      * @throws BadParcelableException if T is different from the type written by
diff --git a/core/java/android/os/image/OWNERS b/core/java/android/os/image/OWNERS
index 389b55b..08a51ff 100644
--- a/core/java/android/os/image/OWNERS
+++ b/core/java/android/os/image/OWNERS
@@ -1 +1,3 @@
+include /packages/DynamicSystemInstallationService/OWNERS
+
 andrewhsieh@google.com
diff --git a/core/java/android/provider/OWNERS b/core/java/android/provider/OWNERS
index b02102b..cb1509a 100644
--- a/core/java/android/provider/OWNERS
+++ b/core/java/android/provider/OWNERS
@@ -10,6 +10,7 @@
 per-file *Downloads* = file:platform/packages/providers/DownloadProvider:/OWNERS
 
 per-file *DeviceConfig* = file:/packages/SettingsProvider/OWNERS
+per-file *Settings* = file:/packages/SettingsProvider/OWNERS
 
 per-file *Documents* = file:/core/java/android/os/storage/OWNERS
 per-file *Documents* = file:platform/packages/apps/DocumentsUI:/OWNERS
diff --git a/core/java/com/android/internal/app/OWNERS b/core/java/com/android/internal/app/OWNERS
index 382b49e..c5a956a 100644
--- a/core/java/com/android/internal/app/OWNERS
+++ b/core/java/com/android/internal/app/OWNERS
@@ -2,3 +2,4 @@
 per-file *Resolver* = file:/packages/SystemUI/OWNERS
 per-file *Chooser* = file:/packages/SystemUI/OWNERS
 per-file SimpleIconFactory.java = file:/packages/SystemUI/OWNERS
+per-file NetInitiatedActivity.java = file:/location/java/android/location/OWNERS
diff --git a/core/java/com/android/internal/net/NetworkUtilsInternal.java b/core/java/com/android/internal/net/NetworkUtilsInternal.java
new file mode 100644
index 0000000..571d7e7
--- /dev/null
+++ b/core/java/com/android/internal/net/NetworkUtilsInternal.java
@@ -0,0 +1,92 @@
+/*
+ * 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 com.android.internal.net;
+
+import static android.system.OsConstants.AF_INET;
+import static android.system.OsConstants.AF_INET6;
+
+import android.annotation.NonNull;
+import android.system.Os;
+
+/** @hide */
+public class NetworkUtilsInternal {
+
+    private static final int[] ADDRESS_FAMILIES = new int[] {AF_INET, AF_INET6};
+
+    /**
+     * Allow/Disallow creating AF_INET/AF_INET6 sockets and DNS lookups for current process.
+     *
+     * @param allowNetworking whether to allow or disallow creating AF_INET/AF_INET6 sockets
+     *                        and DNS lookups.
+     */
+    public static native void setAllowNetworkingForProcess(boolean allowNetworking);
+
+    /**
+     * Returns true if the hostname is weakly validated.
+     * @param hostname Name of host to validate.
+     * @return True if it's a valid-ish hostname.
+     *
+     * @hide
+     */
+    public static boolean isWeaklyValidatedHostname(@NonNull String hostname) {
+        // TODO(b/34953048): Use a validation method that permits more accurate,
+        // but still inexpensive, checking of likely valid DNS hostnames.
+        final String weakHostnameRegex = "^[a-zA-Z0-9_.-]+$";
+        if (!hostname.matches(weakHostnameRegex)) {
+            return false;
+        }
+
+        for (int address_family : ADDRESS_FAMILIES) {
+            if (Os.inet_pton(address_family, hostname) != null) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Safely multiple a value by a rational.
+     * <p>
+     * Internally it uses integer-based math whenever possible, but switches
+     * over to double-based math if values would overflow.
+     * @hide
+     */
+    public static long multiplySafeByRational(long value, long num, long den) {
+        if (den == 0) {
+            throw new ArithmeticException("Invalid Denominator");
+        }
+        long x = value;
+        long y = num;
+
+        // Logic shamelessly borrowed from Math.multiplyExact()
+        long r = x * y;
+        long ax = Math.abs(x);
+        long ay = Math.abs(y);
+        if (((ax | ay) >>> 31 != 0)) {
+            // Some bits greater than 2^31 that might cause overflow
+            // Check the result using the divide operator
+            // and check for the special case of Long.MIN_VALUE * -1
+            if (((y != 0) && (r / y != x))
+                    || (x == Long.MIN_VALUE && y == -1)) {
+                // Use double math to avoid overflowing
+                return (long) (((double) num / den) * value);
+            }
+        }
+        return r / den;
+    }
+}
diff --git a/core/java/com/android/internal/net/VpnProfile.java b/core/java/com/android/internal/net/VpnProfile.java
index a17f5f5..b7170d8 100644
--- a/core/java/com/android/internal/net/VpnProfile.java
+++ b/core/java/com/android/internal/net/VpnProfile.java
@@ -28,6 +28,7 @@
 import android.text.TextUtils;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.net.module.util.ProxyUtils;
 
 import java.net.InetAddress;
 import java.nio.charset.StandardCharsets;
@@ -285,10 +286,12 @@
                 String exclList = (values.length > 17) ? values[17] : "";
                 String pacFileUrl = (values.length > 18) ? values[18] : "";
                 if (!host.isEmpty() || !port.isEmpty() || !exclList.isEmpty()) {
-                    profile.proxy = new ProxyInfo(host, port.isEmpty() ?
-                            0 : Integer.parseInt(port), exclList);
+                    profile.proxy =
+                            ProxyInfo.buildDirectProxy(host, port.isEmpty() ?
+                                    0 : Integer.parseInt(port),
+                                    ProxyUtils.exclusionStringAsList(exclList));
                 } else if (!pacFileUrl.isEmpty()) {
-                    profile.proxy = new ProxyInfo(Uri.parse(pacFileUrl));
+                    profile.proxy = ProxyInfo.buildPacProxy(Uri.parse(pacFileUrl));
                 }
             } // else profile.proxy = null
 
@@ -337,8 +340,8 @@
             builder.append(VALUE_DELIMITER).append(proxy.getPort());
             builder.append(VALUE_DELIMITER)
                     .append(
-                            proxy.getExclusionListAsString() != null
-                                    ? proxy.getExclusionListAsString()
+                            ProxyUtils.exclusionListAsString(proxy.getExclusionList()) != null
+                                    ? ProxyUtils.exclusionListAsString(proxy.getExclusionList())
                                     : "");
             builder.append(VALUE_DELIMITER).append(proxy.getPacFileUrl().toString());
         } else {
diff --git a/core/java/com/android/internal/os/KernelWakelockReader.java b/core/java/com/android/internal/os/KernelWakelockReader.java
index c416814..e644274 100644
--- a/core/java/com/android/internal/os/KernelWakelockReader.java
+++ b/core/java/com/android/internal/os/KernelWakelockReader.java
@@ -190,7 +190,6 @@
 
         try {
             wlStats = mSuspendControlService.getWakeLockStats();
-            Slog.i(TAG, "Number of wakelock obtained from SystemSuspend: " + wlStats.length);
             updateWakelockStats(wlStats, staleStats);
         } catch (RemoteException e) {
             Slog.wtf(TAG, "Failed to obtain wakelock stats from ISuspendControlService", e);
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index 15d4525..0381a75 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -24,7 +24,6 @@
 import android.net.Credentials;
 import android.net.LocalServerSocket;
 import android.net.LocalSocket;
-import android.net.NetworkUtils;
 import android.os.FactoryTest;
 import android.os.IVold;
 import android.os.Process;
@@ -35,6 +34,8 @@
 import android.system.Os;
 import android.util.Log;
 
+import com.android.internal.net.NetworkUtilsInternal;
+
 import dalvik.annotation.optimization.FastNative;
 import dalvik.system.ZygoteHooks;
 
@@ -352,7 +353,7 @@
 
             // If no GIDs were specified, don't make any permissions changes based on groups.
             if (gids != null && gids.length > 0) {
-                NetworkUtils.setAllowNetworkingForProcess(containsInetGid(gids));
+                NetworkUtilsInternal.setAllowNetworkingForProcess(containsInetGid(gids));
             }
         }
 
diff --git a/core/java/com/android/internal/util/OWNERS b/core/java/com/android/internal/util/OWNERS
index 8b9acd3..a045451 100644
--- a/core/java/com/android/internal/util/OWNERS
+++ b/core/java/com/android/internal/util/OWNERS
@@ -2,3 +2,4 @@
 per-file MessageUtils*, Protocol*, RingBuffer*, TokenBucket* = jchalard@google.com, lorenzo@google.com, satk@google.com
 per-file Protocol* = etancohen@google.com, lorenzo@google.com
 per-file State* = jchalard@google.com, lorenzo@google.com, satk@google.com
+per-file DataClass* = eugenesusla@google.com
\ No newline at end of file
diff --git a/core/java/com/android/server/net/BaseNetworkObserver.java b/core/java/com/android/server/net/BaseNetworkObserver.java
index 2a9c0b4..93f89b5 100644
--- a/core/java/com/android/server/net/BaseNetworkObserver.java
+++ b/core/java/com/android/server/net/BaseNetworkObserver.java
@@ -64,7 +64,8 @@
     }
 
     @Override
-    public void interfaceClassDataActivityChanged(String label, boolean active, long tsNanos) {
+    public void interfaceClassDataActivityChanged(int networkType, boolean active, long tsNanos,
+            int uid) {
         // default no-op
     }
 
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 1968146..b4572fd 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -182,6 +182,7 @@
                 "android_content_res_Configuration.cpp",
                 "android_security_Scrypt.cpp",
                 "com_android_internal_content_om_OverlayConfig.cpp",
+                "com_android_internal_net_NetworkUtilsInternal.cpp",
                 "com_android_internal_os_ClassLoaderFactory.cpp",
                 "com_android_internal_os_FuseAppLoop.cpp",
                 "com_android_internal_os_KernelCpuUidBpfMapReader.cpp",
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 7b708ef..3198cb1 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -187,6 +187,7 @@
 extern int register_android_security_Scrypt(JNIEnv *env);
 extern int register_com_android_internal_content_NativeLibraryHelper(JNIEnv *env);
 extern int register_com_android_internal_content_om_OverlayConfig(JNIEnv *env);
+extern int register_com_android_internal_net_NetworkUtilsInternal(JNIEnv* env);
 extern int register_com_android_internal_os_ClassLoaderFactory(JNIEnv* env);
 extern int register_com_android_internal_os_FuseAppLoop(JNIEnv* env);
 extern int register_com_android_internal_os_KernelCpuUidBpfMapReader(JNIEnv *env);
@@ -1520,6 +1521,7 @@
         REG_JNI(register_android_os_SharedMemory),
         REG_JNI(register_android_os_incremental_IncrementalManager),
         REG_JNI(register_com_android_internal_content_om_OverlayConfig),
+        REG_JNI(register_com_android_internal_net_NetworkUtilsInternal),
         REG_JNI(register_com_android_internal_os_ClassLoaderFactory),
         REG_JNI(register_com_android_internal_os_Zygote),
         REG_JNI(register_com_android_internal_os_ZygoteInit),
diff --git a/core/jni/OWNERS b/core/jni/OWNERS
index 54b0340..2279d57 100644
--- a/core/jni/OWNERS
+++ b/core/jni/OWNERS
@@ -27,6 +27,18 @@
 per-file android_util_XmlBlock* = file:/core/java/android/content/res/OWNERS
 per-file com_android_internal_content_om_OverlayConfig* = file:/core/java/android/content/res/OWNERS
 
+# Binder related things
+per-file android_os_Parcel* = file:platform/frameworks/native:/libs/binder/OWNERS
+per-file android_os_ServiceManager* = file:platform/frameworks/native:/libs/binder/OWNERS
+per-file android_util_Binder* = file:platform/frameworks/native:/libs/binder/OWNERS
+
+# HwBinder related things
+per-file android_os_HwBinder* = file:platform/system/libhwbinder:/OWNERS
+per-file android_os_HwBlob* = file:platform/system/libhwbinder:/OWNERS
+per-file android_os_HwParcel* = file:platform/system/libhwbinder:/OWNERS
+per-file android_os_HwRemoteBinder* = file:platform/system/libhwbinder:/OWNERS
+per-file EphemeralStorage* = file:platform/system/libhwbinder:/OWNERS
+
 per-file *Zygote* = file:/ZYGOTE_OWNERS
 per-file Android.bp = file:platform/build/soong:/OWNERS
 per-file android_animation_* = file:/core/java/android/animation/OWNERS
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index ae72525..20e64ff 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -294,20 +294,25 @@
     return old;
 }
 
-#define check_AudioSystem_Command(status) _check_AudioSystem_Command(__func__, (status))
+#define check_AudioSystem_Command(...) _check_AudioSystem_Command(__func__, __VA_ARGS__)
 
-static int _check_AudioSystem_Command(const char* caller, status_t status)
-{
-    ALOGE_IF(status, "Command failed for %s: %d", caller, status);
+static int _check_AudioSystem_Command(const char *caller, status_t status,
+                                      std::vector<status_t> ignoredErrors = {}) {
+    int jniStatus = kAudioStatusOk;
     switch (status) {
     case DEAD_OBJECT:
-        return kAudioStatusMediaServerDied;
+        jniStatus = kAudioStatusMediaServerDied;
+        break;
     case NO_ERROR:
-        return kAudioStatusOk;
+        break;
     default:
+        if (std::find(begin(ignoredErrors), end(ignoredErrors), status) == end(ignoredErrors)) {
+            jniStatus = kAudioStatusError;
+        }
         break;
     }
-    return kAudioStatusError;
+    ALOGE_IF(jniStatus != kAudioStatusOk, "Command failed for %s: %d", caller, status);
+    return jniStatus;
 }
 
 static jint getVectorOfAudioDeviceTypeAddr(JNIEnv *env, jintArray deviceTypes,
@@ -2381,9 +2386,12 @@
 
 static jint android_media_AudioSystem_removeDevicesRoleForStrategy(JNIEnv *env, jobject thiz,
                                                                    jint strategy, jint role) {
-    return (jint)check_AudioSystem_Command(
-            AudioSystem::removeDevicesRoleForStrategy((product_strategy_t)strategy,
-                                                      (device_role_t)role));
+    return (jint)
+            check_AudioSystem_Command(AudioSystem::removeDevicesRoleForStrategy((product_strategy_t)
+                                                                                        strategy,
+                                                                                (device_role_t)
+                                                                                        role),
+                                      {NAME_NOT_FOUND});
 }
 
 static jint android_media_AudioSystem_getDevicesForRoleAndStrategy(JNIEnv *env, jobject thiz,
@@ -2408,6 +2416,79 @@
     return AUDIO_JAVA_SUCCESS;
 }
 
+static jint android_media_AudioSystem_setDevicesRoleForCapturePreset(
+        JNIEnv *env, jobject thiz, jint capturePreset, jint role, jintArray jDeviceTypes,
+        jobjectArray jDeviceAddresses) {
+    AudioDeviceTypeAddrVector nDevices;
+    jint results = getVectorOfAudioDeviceTypeAddr(env, jDeviceTypes, jDeviceAddresses, nDevices);
+    if (results != NO_ERROR) {
+        return results;
+    }
+    int status = check_AudioSystem_Command(
+            AudioSystem::setDevicesRoleForCapturePreset((audio_source_t)capturePreset,
+                                                        (device_role_t)role, nDevices));
+    return (jint)status;
+}
+
+static jint android_media_AudioSystem_addDevicesRoleForCapturePreset(
+        JNIEnv *env, jobject thiz, jint capturePreset, jint role, jintArray jDeviceTypes,
+        jobjectArray jDeviceAddresses) {
+    AudioDeviceTypeAddrVector nDevices;
+    jint results = getVectorOfAudioDeviceTypeAddr(env, jDeviceTypes, jDeviceAddresses, nDevices);
+    if (results != NO_ERROR) {
+        return results;
+    }
+    int status = check_AudioSystem_Command(
+            AudioSystem::addDevicesRoleForCapturePreset((audio_source_t)capturePreset,
+                                                        (device_role_t)role, nDevices));
+    return (jint)status;
+}
+
+static jint android_media_AudioSystem_removeDevicesRoleForCapturePreset(
+        JNIEnv *env, jobject thiz, jint capturePreset, jint role, jintArray jDeviceTypes,
+        jobjectArray jDeviceAddresses) {
+    AudioDeviceTypeAddrVector nDevices;
+    jint results = getVectorOfAudioDeviceTypeAddr(env, jDeviceTypes, jDeviceAddresses, nDevices);
+    if (results != NO_ERROR) {
+        return results;
+    }
+    int status = check_AudioSystem_Command(
+            AudioSystem::removeDevicesRoleForCapturePreset((audio_source_t)capturePreset,
+                                                           (device_role_t)role, nDevices));
+    return (jint)status;
+}
+
+static jint android_media_AudioSystem_clearDevicesRoleForCapturePreset(JNIEnv *env, jobject thiz,
+                                                                       jint capturePreset,
+                                                                       jint role) {
+    return (jint)check_AudioSystem_Command(
+            AudioSystem::clearDevicesRoleForCapturePreset((audio_source_t)capturePreset,
+                                                          (device_role_t)role));
+}
+
+static jint android_media_AudioSystem_getDevicesForRoleAndCapturePreset(JNIEnv *env, jobject thiz,
+                                                                        jint capturePreset,
+                                                                        jint role,
+                                                                        jobject jDevices) {
+    AudioDeviceTypeAddrVector nDevices;
+    status_t status = check_AudioSystem_Command(
+            AudioSystem::getDevicesForRoleAndCapturePreset((audio_source_t)capturePreset,
+                                                           (device_role_t)role, nDevices));
+    if (status != NO_ERROR) {
+        return (jint)status;
+    }
+    for (const auto &device : nDevices) {
+        jobject jAudioDeviceAttributes = NULL;
+        jint jStatus = createAudioDeviceAttributesFromNative(env, &jAudioDeviceAttributes, &device);
+        if (jStatus != AUDIO_JAVA_SUCCESS) {
+            return jStatus;
+        }
+        env->CallBooleanMethod(jDevices, gListMethods.add, jAudioDeviceAttributes);
+        env->DeleteLocalRef(jAudioDeviceAttributes);
+    }
+    return AUDIO_JAVA_SUCCESS;
+}
+
 static jint
 android_media_AudioSystem_getDevicesForAttributes(JNIEnv *env, jobject thiz,
         jobject jaa, jobjectArray jDeviceArray)
@@ -2559,6 +2640,16 @@
           (void *)android_media_AudioSystem_removeDevicesRoleForStrategy},
          {"getDevicesForRoleAndStrategy", "(IILjava/util/List;)I",
           (void *)android_media_AudioSystem_getDevicesForRoleAndStrategy},
+         {"setDevicesRoleForCapturePreset", "(II[I[Ljava/lang/String;)I",
+          (void *)android_media_AudioSystem_setDevicesRoleForCapturePreset},
+         {"addDevicesRoleForCapturePreset", "(II[I[Ljava/lang/String;)I",
+          (void *)android_media_AudioSystem_addDevicesRoleForCapturePreset},
+         {"removeDevicesRoleForCapturePreset", "(II[I[Ljava/lang/String;)I",
+          (void *)android_media_AudioSystem_removeDevicesRoleForCapturePreset},
+         {"clearDevicesRoleForCapturePreset", "(II)I",
+          (void *)android_media_AudioSystem_clearDevicesRoleForCapturePreset},
+         {"getDevicesForRoleAndCapturePreset", "(IILjava/util/List;)I",
+          (void *)android_media_AudioSystem_getDevicesForRoleAndCapturePreset},
          {"getDevicesForAttributes",
           "(Landroid/media/AudioAttributes;[Landroid/media/AudioDeviceAttributes;)I",
           (void *)android_media_AudioSystem_getDevicesForAttributes},
diff --git a/core/jni/android_net_NetUtils.cpp b/core/jni/android_net_NetUtils.cpp
index 8d4c4e5..2155246 100644
--- a/core/jni/android_net_NetUtils.cpp
+++ b/core/jni/android_net_NetUtils.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008, The Android Open Source Project
+ * Copyright 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.
@@ -28,7 +28,6 @@
 #include <netinet/udp.h>
 
 #include <DnsProxydProtocol.h> // NETID_USE_LOCAL_NAMESERVERS
-#include <android_runtime/AndroidRuntime.h>
 #include <cutils/properties.h>
 #include <nativehelper/JNIPlatformHelp.h>
 #include <nativehelper/ScopedLocalRef.h>
@@ -226,11 +225,6 @@
             class_Network, ctor, dnsNetId & ~NETID_USE_LOCAL_NAMESERVERS, privateDnsBypass);
 }
 
-static void android_net_utils_setAllowNetworkingForProcess(JNIEnv *env, jobject thiz,
-                                                           jboolean hasConnectivity) {
-    setAllowNetworkingForProcess(hasConnectivity == JNI_TRUE);
-}
-
 static jobject android_net_utils_getTcpRepairWindow(JNIEnv *env, jobject thiz, jobject javaFd) {
     if (javaFd == NULL) {
         jniThrowNullPointerException(env, NULL);
@@ -288,7 +282,6 @@
     { "resNetworkResult", "(Ljava/io/FileDescriptor;)Landroid/net/DnsResolver$DnsResponse;", (void*) android_net_utils_resNetworkResult },
     { "resNetworkCancel", "(Ljava/io/FileDescriptor;)V", (void*) android_net_utils_resNetworkCancel },
     { "getDnsNetwork", "()Landroid/net/Network;", (void*) android_net_utils_getDnsNetwork },
-    { "setAllowNetworkingForProcess", "(Z)V", (void *)android_net_utils_setAllowNetworkingForProcess },
 };
 // clang-format on
 
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index 5a859aa..28fc8ed 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -844,6 +844,17 @@
     return ionPss;
 }
 
+static jlong android_os_Debug_getGpuTotalUsageKb(JNIEnv* env, jobject clazz) {
+    jlong sizeKb = -1;
+    uint64_t size;
+
+    if (meminfo::ReadGpuTotalUsageKb(&size)) {
+        sizeKb = size;
+    }
+
+    return sizeKb;
+}
+
 static jboolean android_os_Debug_isVmapStack(JNIEnv *env, jobject clazz)
 {
     static enum {
@@ -912,6 +923,8 @@
             (void*)android_os_Debug_getIonPoolsSizeKb },
     { "getIonMappedSizeKb", "()J",
             (void*)android_os_Debug_getIonMappedSizeKb },
+    { "getGpuTotalUsageKb", "()J",
+            (void*)android_os_Debug_getGpuTotalUsageKb },
     { "isVmapStack", "()Z",
             (void*)android_os_Debug_isVmapStack },
 };
diff --git a/core/jni/com_android_internal_net_NetworkUtilsInternal.cpp b/core/jni/com_android_internal_net_NetworkUtilsInternal.cpp
new file mode 100644
index 0000000..10fc18d
--- /dev/null
+++ b/core/jni/com_android_internal_net_NetworkUtilsInternal.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright 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.
+ */
+
+#include "NetdClient.h"
+#include "core_jni_helpers.h"
+#include "jni.h"
+
+namespace android {
+static void android_net_utils_setAllowNetworkingForProcess(JNIEnv *env, jobject thiz,
+                                                           jboolean hasConnectivity) {
+    setAllowNetworkingForProcess(hasConnectivity == JNI_TRUE);
+}
+
+static const JNINativeMethod gNetworkUtilMethods[] = {
+        {"setAllowNetworkingForProcess", "(Z)V",
+         (void *)android_net_utils_setAllowNetworkingForProcess},
+};
+
+int register_com_android_internal_net_NetworkUtilsInternal(JNIEnv *env) {
+    return RegisterMethodsOrDie(env, "com/android/internal/net/NetworkUtilsInternal",
+                                gNetworkUtilMethods, NELEM(gNetworkUtilMethods));
+}
+
+} // namespace android
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 1389753..00e3d60 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -853,7 +853,7 @@
     <string name="lockscreen_transport_prev_description" msgid="2879469521751181478">"הרצועה הקודמת"</string>
     <string name="lockscreen_transport_next_description" msgid="2931509904881099919">"הרצועה הבאה"</string>
     <string name="lockscreen_transport_pause_description" msgid="6705284702135372494">"השהה"</string>
-    <string name="lockscreen_transport_play_description" msgid="106868788691652733">"הפעל"</string>
+    <string name="lockscreen_transport_play_description" msgid="106868788691652733">"הפעלה"</string>
     <string name="lockscreen_transport_stop_description" msgid="1449552232598355348">"הפסק"</string>
     <string name="lockscreen_transport_rew_description" msgid="7680106856221622779">"הרץ אחורה"</string>
     <string name="lockscreen_transport_ffw_description" msgid="4763794746640196772">"הרץ קדימה"</string>
@@ -1842,7 +1842,7 @@
     <string name="battery_saver_description" msgid="6794188153647295212">"‏כדי להאריך את חיי הסוללה, התכונה \'חיסכון בסוללה\':\n\n• מפעילה עיצוב כהה\n• מכבה או מגבילה פעילות ברקע, חלק מהאפקטים החזותיים ותכונות אחרות כמו Ok Google"</string>
     <string name="data_saver_description" msgid="4995164271550590517">"‏כדי לסייע בהפחתת השימוש בנתונים, חוסך הנתונים (Data Saver) מונע מאפליקציות מסוימות שליחה או קבלה של נתונים ברקע. אפליקציה שבה נעשה שימוש כרגע יכולה לגשת לנתונים, אבל בתדירות נמוכה יותר. המשמעות היא, למשל, שתמונות יוצגו רק לאחר שמקישים עליהן."</string>
     <string name="data_saver_enable_title" msgid="7080620065745260137">"להפעיל את חוסך הנתונים?"</string>
-    <string name="data_saver_enable_button" msgid="4399405762586419726">"הפעל"</string>
+    <string name="data_saver_enable_button" msgid="4399405762586419726">"הפעלה"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="2877101784123058273">
       <item quantity="two">‏למשך %d דקות (עד <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="many">‏למשך %1$d דקות (עד <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
@@ -1952,7 +1952,7 @@
     <string name="app_suspended_unsuspend_message" msgid="1665438589450555459">"ביטול ההשהיה של האפליקציה"</string>
     <string name="work_mode_off_title" msgid="5503291976647976560">"להפעיל את פרופיל העבודה?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"אפליקציות העבודה, התראות, נתונים ותכונות נוספות של פרופיל העבודה יופעלו"</string>
-    <string name="work_mode_turn_on" msgid="3662561662475962285">"הפעל"</string>
+    <string name="work_mode_turn_on" msgid="3662561662475962285">"הפעלה"</string>
     <string name="app_blocked_title" msgid="7353262160455028160">"האפליקציה לא זמינה"</string>
     <string name="app_blocked_message" msgid="542972921087873023">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> לא זמינה בשלב זה."</string>
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"‏האפליקציה הזו עוצבה לגרסה ישנה יותר של Android וייתכן שלא תפעל כראוי. ניתן לבדוק אם יש עדכונים או ליצור קשר עם המפתח."</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index ef599a1..c206b12 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -1838,8 +1838,8 @@
     <string name="package_updated_device_owner" msgid="7560272363805506941">"Zaktualizowany przez administratora"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Usunięty przez administratora"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
-    <string name="battery_saver_description_with_learn_more" msgid="4424488535318105801">"Aby wydłużyć czas pracy na baterii, funkcja Oszczędzanie baterii:\n\n• włącza tryb ciemny,\n• wyłącza lub ogranicza aktywność w tle, niektóre efekty wizualne oraz inne funkcje, np. „OK Google”.\n\n"<annotation id="url">"Więcej informacji"</annotation></string>
-    <string name="battery_saver_description" msgid="6794188153647295212">"Aby wydłużyć czas pracy na baterii, Oszczędzanie baterii:\n\n• włącza tryb ciemny,\n• wyłącza lub ogranicza aktywność w tle, niektóre efekty wizualne oraz inne funkcje, np. „OK Google”."</string>
+    <string name="battery_saver_description_with_learn_more" msgid="4424488535318105801">"Aby wydłużyć czas pracy na baterii, funkcja Oszczędzanie baterii:\n\n• włącza ciemny motyw,\n• wyłącza lub ogranicza aktywność w tle, niektóre efekty wizualne oraz inne funkcje, np. „OK Google”.\n\n"<annotation id="url">"Więcej informacji"</annotation></string>
+    <string name="battery_saver_description" msgid="6794188153647295212">"Aby wydłużyć czas pracy na baterii, Oszczędzanie baterii:\n\n• włącza ciemny motyw,\n• wyłącza lub ogranicza aktywność w tle, niektóre efekty wizualne oraz inne funkcje, np. „OK Google”."</string>
     <string name="data_saver_description" msgid="4995164271550590517">"Oszczędzanie danych uniemożliwia niektórym aplikacjom wysyłanie i odbieranie danych w tle, zmniejszając w ten sposób ich użycie. Aplikacja, z której w tej chwili korzystasz, może uzyskiwać dostęp do danych, ale rzadziej. Może to powodować, że obrazy będą się wyświetlać dopiero po kliknięciu."</string>
     <string name="data_saver_enable_title" msgid="7080620065745260137">"Włączyć Oszczędzanie danych?"</string>
     <string name="data_saver_enable_button" msgid="4399405762586419726">"Włącz"</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index d84b019..8742a67 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -1306,8 +1306,8 @@
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Pajisja e lidhur po karikohet. Trokit për opsione të tjera."</string>
     <string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"U zbulua aksesor i audios analoge"</string>
     <string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"Pajisja e bashkuar nuk është e pajtueshme me këtë telefon. Trokit për të mësuar më shumë."</string>
-    <string name="adb_active_notification_title" msgid="408390247354560331">"Korrigjuesi i USB-së është i lidhur"</string>
-    <string name="adb_active_notification_message" msgid="5617264033476778211">"Trokit për të çaktivizuar korrigjimin e USB-së"</string>
+    <string name="adb_active_notification_title" msgid="408390247354560331">"Korrigjimi përmes USB-së është i lidhur"</string>
+    <string name="adb_active_notification_message" msgid="5617264033476778211">"Trokit për të çaktivizuar korrigjimin përmes USB-së"</string>
     <string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"Përzgjidhe për të çaktivizuar korrigjimin e gabimeve të USB-së"</string>
     <string name="adbwifi_active_notification_title" msgid="6147343659168302473">"Korrigjimi përmes Wi-Fi është lidhur"</string>
     <string name="adbwifi_active_notification_message" msgid="930987922852867972">"Trokit për të çaktivizuar korrigjimin përmes Wi-Fi"</string>
@@ -1920,7 +1920,7 @@
     <string name="app_category_maps" msgid="6395725487922533156">"Harta dhe navigim"</string>
     <string name="app_category_productivity" msgid="1844422703029557883">"Produktivitet"</string>
     <string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Hapësira ruajtëse e pajisjes"</string>
-    <string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Korrigjimi i USB-së"</string>
+    <string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Korrigjimi përmes USB-së"</string>
     <string name="time_picker_hour_label" msgid="4208590187662336864">"orë"</string>
     <string name="time_picker_minute_label" msgid="8307452311269824553">"minutë"</string>
     <string name="time_picker_header_text" msgid="9073802285051516688">"Vendos orën"</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index c39e1aa..0c5f964 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -267,7 +267,7 @@
     <string name="global_action_lockdown" msgid="2475471405907902963">"பூட்டு"</string>
     <string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
     <string name="notification_hidden_text" msgid="2835519769868187223">"புதிய அறிவிப்பு"</string>
-    <string name="notification_channel_virtual_keyboard" msgid="6465975799223304567">"விர்ச்சுவல் கீபோர்ட்"</string>
+    <string name="notification_channel_virtual_keyboard" msgid="6465975799223304567">"விர்ச்சுவல் கீபோர்டு"</string>
     <string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"கைமுறை விசைப்பலகை"</string>
     <string name="notification_channel_security" msgid="8516754650348238057">"பாதுகாப்பு"</string>
     <string name="notification_channel_car_mode" msgid="2123919247040988436">"கார் பயன்முறை"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 92dd924..4c6be82 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -310,7 +310,7 @@
     <string name="permgrouplab_camera" msgid="9090413408963547706">"กล้องถ่ายรูป"</string>
     <string name="permgroupdesc_camera" msgid="7585150538459320326">"ถ่ายภาพและบันทึกวิดีโอ"</string>
     <string name="permgrouplab_calllog" msgid="7926834372073550288">"ประวัติการโทร"</string>
-    <string name="permgroupdesc_calllog" msgid="2026996642917801803">"อ่านและเขียนประวัติการโทรของโทรศัพท์"</string>
+    <string name="permgroupdesc_calllog" msgid="2026996642917801803">"อ่านและเขียนบันทึกการโทรของโทรศัพท์"</string>
     <string name="permgrouplab_phone" msgid="570318944091926620">"โทรศัพท์"</string>
     <string name="permgroupdesc_phone" msgid="270048070781478204">"โทรและจัดการการโทร"</string>
     <string name="permgrouplab_sensors" msgid="9134046949784064495">"เซ็นเซอร์ร่างกาย"</string>
@@ -403,12 +403,12 @@
     <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"อนุญาตให้แอปแก้ไขข้อมูลเกี่ยวกับรายชื่อติดต่อที่จัดเก็บไว้ในแท็บเล็ต สิทธิ์นี้ทำให้แอปลบข้อมูลรายชื่อติดต่อได้"</string>
     <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"อนุญาตให้แอปแก้ไขข้อมูลเกี่ยวกับรายชื่อติดต่อที่จัดเก็บไว้ในอุปกรณ์ Android TV สิทธิ์นี้ทำให้แอปลบข้อมูลรายชื่อติดต่อได้"</string>
     <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"อนุญาตให้แอปแก้ไขข้อมูลเกี่ยวกับรายชื่อติดต่อที่จัดเก็บไว้ในโทรศัพท์ สิทธิ์นี้ทำให้แอปลบข้อมูลรายชื่อติดต่อได้"</string>
-    <string name="permlab_readCallLog" msgid="1739990210293505948">"อ่านประวัติการโทร"</string>
+    <string name="permlab_readCallLog" msgid="1739990210293505948">"อ่านบันทึกการโทร"</string>
     <string name="permdesc_readCallLog" msgid="8964770895425873433">"แอปนี้สามารถอ่านประวัติการโทรของคุณได้"</string>
-    <string name="permlab_writeCallLog" msgid="670292975137658895">"เขียนประวัติการโทร"</string>
-    <string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"อนุญาตให้แอปแก้ไขประวัติการโทรจากแท็บเล็ตของคุณ รวมถึงข้อมูลเกี่ยวกับสายเรียกเข้าและการโทรออก แอปที่เป็นอันตรายอาจใช้สิ่งนี้เพื่อลบหรือแก้ไขประวัติการโทรของคุณ"</string>
-    <string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"อนุญาตให้แอปแก้ไขประวัติการโทรจากอุปกรณ์ Android TV รวมถึงข้อมูลเกี่ยวกับสายเรียกเข้าและสายโทรออก แอปที่เป็นอันตรายอาจใช้สิทธิ์นี้เพื่อลบหรือแก้ไขประวัติการโทรได้"</string>
-    <string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"อนุญาตให้แอปแก้ไขประวัติการโทรจากโทรศัพท์ของคุณ รวมถึงข้อมูลเกี่ยวกับสายเรียกเข้าและการโทรออก แอปที่เป็นอันตรายอาจใช้สิ่งนี้เพื่อลบหรือแก้ไขประวัติการโทรของคุณ"</string>
+    <string name="permlab_writeCallLog" msgid="670292975137658895">"เขียนบันทึกการโทร"</string>
+    <string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"อนุญาตให้แอปแก้ไขบันทึกการโทรจากแท็บเล็ตของคุณ รวมถึงข้อมูลเกี่ยวกับสายเรียกเข้าและการโทรออก แอปที่เป็นอันตรายอาจใช้สิ่งนี้เพื่อลบหรือแก้ไขบันทึกการโทรของคุณ"</string>
+    <string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"อนุญาตให้แอปแก้ไขบันทึกการโทรจากอุปกรณ์ Android TV รวมถึงข้อมูลเกี่ยวกับสายเรียกเข้าและสายโทรออก แอปที่เป็นอันตรายอาจใช้สิทธิ์นี้เพื่อลบหรือแก้ไขบันทึกการโทรได้"</string>
+    <string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"อนุญาตให้แอปแก้ไขบันทึกการโทรจากโทรศัพท์ของคุณ รวมถึงข้อมูลเกี่ยวกับสายเรียกเข้าและการโทรออก แอปที่เป็นอันตรายอาจใช้สิ่งนี้เพื่อลบหรือแก้ไขบันทึกการโทรของคุณ"</string>
     <string name="permlab_bodySensors" msgid="3411035315357380862">"เข้าถึงเซ็นเซอร์ร่างกาย (เช่น ตัววัดอัตราการเต้นของหัวใจ)"</string>
     <string name="permdesc_bodySensors" product="default" msgid="2365357960407973997">"อนุญาตให้แอปเข้าถึงข้อมูลจากเซ็นเซอร์ที่ตรวจสอบสภาพทางกายภาพ เช่น อัตราการเต้นของหัวใจ"</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"อ่านกิจกรรมในปฏิทินและรายละเอียด"</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index cdc132e..0480053 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -818,7 +818,7 @@
     <string name="keyguard_password_enter_puk_code" msgid="3112256684547584093">"‏PUK اور نیا PIN کوڈ ٹائپ کریں"</string>
     <string name="keyguard_password_enter_puk_prompt" msgid="2825313071899938305">"‏PUK کوڈ"</string>
     <string name="keyguard_password_enter_pin_prompt" msgid="5505434724229581207">"‏نیا PIN کوڈ"</string>
-    <string name="keyguard_password_entry_touch_hint" msgid="4032288032993261520"><font size="17">"پاسورڈ ٹائپ کرنے کیلئے تھپتھپائیں"</font></string>
+    <string name="keyguard_password_entry_touch_hint" msgid="4032288032993261520"><font size="17">"پاس ورڈ ٹائپ کرنے کیلئے تھپتھپائیں"</font></string>
     <string name="keyguard_password_enter_password_code" msgid="2751130557661643482">"غیر مقفل کرنے کیلئے پاس ورڈ ٹائپ کریں"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7792964196473964340">"‏غیر مقفل کرنے کیلئے PIN ٹائپ کریں"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="8583732939138432793">"‏غلط PIN کوڈ۔"</string>
diff --git a/core/tests/coretests/src/android/service/notification/OWNERS b/core/tests/coretests/src/android/service/notification/OWNERS
new file mode 100644
index 0000000..1502b60
--- /dev/null
+++ b/core/tests/coretests/src/android/service/notification/OWNERS
@@ -0,0 +1,2 @@
+include platform/frameworks/base:/services/core/java/com/android/server/notification/OWNERS
+
diff --git a/media/java/android/media/AudioDeviceAttributes.java b/media/java/android/media/AudioDeviceAttributes.java
index 0ab62c1..7caac89 100644
--- a/media/java/android/media/AudioDeviceAttributes.java
+++ b/media/java/android/media/AudioDeviceAttributes.java
@@ -72,6 +72,11 @@
     private final @Role int mRole;
 
     /**
+     * The internal audio device type
+     */
+    private final int mNativeType;
+
+    /**
      * @hide
      * Constructor from a valid {@link AudioDeviceInfo}
      * @param deviceInfo the connected audio device from which to obtain the device-identifying
@@ -83,6 +88,7 @@
         mRole = deviceInfo.isSink() ? ROLE_OUTPUT : ROLE_INPUT;
         mType = deviceInfo.getType();
         mAddress = deviceInfo.getAddress();
+        mNativeType = deviceInfo.getInternalType();
     }
 
     /**
@@ -101,9 +107,12 @@
         }
         if (role == ROLE_OUTPUT) {
             AudioDeviceInfo.enforceValidAudioDeviceTypeOut(type);
-        }
-        if (role == ROLE_INPUT) {
+            mNativeType = AudioDeviceInfo.convertDeviceTypeToInternalDevice(type);
+        } else if (role == ROLE_INPUT) {
             AudioDeviceInfo.enforceValidAudioDeviceTypeIn(type);
+            mNativeType = AudioDeviceInfo.convertDeviceTypeToInternalInputDevice(type);
+        } else {
+            mNativeType = AudioSystem.DEVICE_NONE;
         }
 
         mRole = role;
@@ -111,10 +120,17 @@
         mAddress = address;
     }
 
-    /*package*/ AudioDeviceAttributes(int nativeType, @NonNull String address) {
+    /**
+     * @hide
+     * Constructor from internal device type and address
+     * @param type the internal device type, as defined in {@link AudioSystem}
+     * @param address the address of the device, or an empty string for devices without one
+     */
+    public AudioDeviceAttributes(int nativeType, @NonNull String address) {
         mRole = (nativeType & AudioSystem.DEVICE_BIT_IN) != 0 ? ROLE_INPUT : ROLE_OUTPUT;
         mType = AudioDeviceInfo.convertInternalDeviceToDeviceType(nativeType);
         mAddress = address;
+        mNativeType = nativeType;
     }
 
     /**
@@ -147,6 +163,15 @@
         return mAddress;
     }
 
+    /**
+     * @hide
+     * Returns the internal device type of a device
+     * @return the internal device type
+     */
+    public int getInternalType() {
+        return mNativeType;
+    }
+
     @Override
     public int hashCode() {
         return Objects.hash(mRole, mType, mAddress);
@@ -172,10 +197,8 @@
     public String toString() {
         return new String("AudioDeviceAttributes:"
                 + " role:" + roleToString(mRole)
-                + " type:" + (mRole == ROLE_OUTPUT ? AudioSystem.getOutputDeviceName(
-                        AudioDeviceInfo.convertDeviceTypeToInternalDevice(mType))
-                        : AudioSystem.getInputDeviceName(
-                                AudioDeviceInfo.convertDeviceTypeToInternalDevice(mType)))
+                + " type:" + (mRole == ROLE_OUTPUT ? AudioSystem.getOutputDeviceName(mNativeType)
+                        : AudioSystem.getInputDeviceName(mNativeType))
                 + " addr:" + mAddress);
     }
 
@@ -189,12 +212,14 @@
         dest.writeInt(mRole);
         dest.writeInt(mType);
         dest.writeString(mAddress);
+        dest.writeInt(mNativeType);
     }
 
     private AudioDeviceAttributes(@NonNull Parcel in) {
         mRole = in.readInt();
         mType = in.readInt();
         mAddress = in.readString();
+        mNativeType = in.readInt();
     }
 
     public static final @NonNull Parcelable.Creator<AudioDeviceAttributes> CREATOR =
diff --git a/media/java/android/media/AudioDeviceInfo.java b/media/java/android/media/AudioDeviceInfo.java
index ff4a256..f79fc92 100644
--- a/media/java/android/media/AudioDeviceInfo.java
+++ b/media/java/android/media/AudioDeviceInfo.java
@@ -350,6 +350,14 @@
     }
 
     /**
+     * @hide
+     * @return the internal device tyoe
+     */
+    public int getInternalType() {
+        return mPort.type();
+    }
+
+    /**
      * @return The internal device ID.
      */
     public int getId() {
@@ -512,10 +520,21 @@
         return INT_TO_EXT_DEVICE_MAPPING.get(intDevice, TYPE_UNKNOWN);
     }
 
+    /** @hide */
+    public static int convertDeviceTypeToInternalInputDevice(int deviceType) {
+        return EXT_TO_INT_INPUT_DEVICE_MAPPING.get(deviceType, AudioSystem.DEVICE_NONE);
+    }
+
     private static final SparseIntArray INT_TO_EXT_DEVICE_MAPPING;
 
     private static final SparseIntArray EXT_TO_INT_DEVICE_MAPPING;
 
+    /**
+     * EXT_TO_INT_INPUT_DEVICE_MAPPING aims at mapping external device type to internal input device
+     * type.
+     */
+    private static final SparseIntArray EXT_TO_INT_INPUT_DEVICE_MAPPING;
+
     static {
         INT_TO_EXT_DEVICE_MAPPING = new SparseIntArray();
         INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_EARPIECE, TYPE_BUILTIN_EARPIECE);
@@ -600,6 +619,32 @@
         EXT_TO_INT_DEVICE_MAPPING.put(TYPE_REMOTE_SUBMIX, AudioSystem.DEVICE_OUT_REMOTE_SUBMIX);
         EXT_TO_INT_DEVICE_MAPPING.put(TYPE_BLE_HEADSET, AudioSystem.DEVICE_OUT_BLE_HEADSET);
         EXT_TO_INT_DEVICE_MAPPING.put(TYPE_BLE_SPEAKER, AudioSystem.DEVICE_OUT_BLE_SPEAKER);
+
+        // privileges mapping to input device
+        EXT_TO_INT_INPUT_DEVICE_MAPPING = new SparseIntArray();
+        EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_BUILTIN_MIC, AudioSystem.DEVICE_IN_BUILTIN_MIC);
+        EXT_TO_INT_INPUT_DEVICE_MAPPING.put(
+                TYPE_BLUETOOTH_SCO, AudioSystem.DEVICE_IN_BLUETOOTH_SCO_HEADSET);
+        EXT_TO_INT_INPUT_DEVICE_MAPPING.put(
+                TYPE_WIRED_HEADSET, AudioSystem.DEVICE_IN_WIRED_HEADSET);
+        EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_HDMI, AudioSystem.DEVICE_IN_HDMI);
+        EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_TELEPHONY, AudioSystem.DEVICE_IN_TELEPHONY_RX);
+        EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_DOCK, AudioSystem.DEVICE_IN_ANLG_DOCK_HEADSET);
+        EXT_TO_INT_INPUT_DEVICE_MAPPING.put(
+                TYPE_USB_ACCESSORY, AudioSystem.DEVICE_IN_USB_ACCESSORY);
+        EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_USB_DEVICE, AudioSystem.DEVICE_IN_USB_DEVICE);
+        EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_USB_HEADSET, AudioSystem.DEVICE_IN_USB_HEADSET);
+        EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_FM_TUNER, AudioSystem.DEVICE_IN_FM_TUNER);
+        EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_TV_TUNER, AudioSystem.DEVICE_IN_TV_TUNER);
+        EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_LINE_ANALOG, AudioSystem.DEVICE_IN_LINE);
+        EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_LINE_DIGITAL, AudioSystem.DEVICE_IN_SPDIF);
+        EXT_TO_INT_INPUT_DEVICE_MAPPING.put(
+                TYPE_BLUETOOTH_A2DP, AudioSystem.DEVICE_IN_BLUETOOTH_A2DP);
+        EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_IP, AudioSystem.DEVICE_IN_IP);
+        EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_BUS, AudioSystem.DEVICE_IN_BUS);
+        EXT_TO_INT_INPUT_DEVICE_MAPPING.put(
+                TYPE_REMOTE_SUBMIX, AudioSystem.DEVICE_IN_REMOTE_SUBMIX);
+        EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_BLE_HEADSET, AudioSystem.DEVICE_IN_BLE_HEADSET);
     }
 }
 
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index b330037..7dff0c2 100755
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -1948,6 +1948,349 @@
     }
 
     //====================================================================
+    // Audio Capture Preset routing
+
+    /**
+     * @hide
+     * Set the preferred device for a given capture preset, i.e. the audio routing to be used by
+     * this capture preset. Note that the device may not be available at the time the preferred
+     * device is set, but it will be used once made available.
+     * <p>Use {@link #clearPreferredDevicesForCapturePreset(int)} to cancel setting this preference
+     * for this capture preset.</p>
+     * @param capturePreset the audio capture preset whose routing will be affected
+     * @param device the audio device to route to when available
+     * @return true if the operation was successful, false otherwise
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+    public boolean setPreferredDeviceForCapturePreset(int capturePreset,
+                                                      @NonNull AudioDeviceAttributes device) {
+        return setPreferredDevicesForCapturePreset(capturePreset, Arrays.asList(device));
+    }
+
+    /**
+     * @hide
+     * Remove all the preferred audio devices previously set
+     * @param capturePreset the audio capture preset whose routing will be affected
+     * @return true if the operation was successful, false otherwise (invalid capture preset, or no
+     *     device set for example)
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+    public boolean clearPreferredDevicesForCapturePreset(int capturePreset) {
+        if (!MediaRecorder.isValidAudioSource(capturePreset)) {
+            return false;
+        }
+        try {
+            final int status = getService().clearPreferredDevicesForCapturePreset(capturePreset);
+            return status == AudioSystem.SUCCESS;
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     * Return the preferred devices for an audio capture preset, previously set with
+     * {@link #setPreferredDeviceForCapturePreset(int, AudioDeviceAttributes)}
+     * @param capturePreset the capture preset to query
+     * @return a list that contains preferred devices for that capture preset.
+     */
+    @NonNull
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+    public List<AudioDeviceAttributes> getPreferredDevicesForCapturePreset(int capturePreset) {
+        if (!MediaRecorder.isValidAudioSource(capturePreset)) {
+            return new ArrayList<AudioDeviceAttributes>();
+        }
+        try {
+            return getService().getPreferredDevicesForCapturePreset(capturePreset);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    private boolean setPreferredDevicesForCapturePreset(
+            int capturePreset, @NonNull List<AudioDeviceAttributes> devices) {
+        Objects.requireNonNull(devices);
+        if (!MediaRecorder.isValidAudioSource(capturePreset)) {
+            return false;
+        }
+        if (devices.size() != 1) {
+            throw new IllegalArgumentException(
+                    "Only support setting one preferred devices for capture preset");
+        }
+        for (AudioDeviceAttributes device : devices) {
+            Objects.requireNonNull(device);
+        }
+        try {
+            final int status =
+                    getService().setPreferredDevicesForCapturePreset(capturePreset, devices);
+            return status == AudioSystem.SUCCESS;
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     * Interface to be notified of changes in the preferred audio devices set for a given capture
+     * preset.
+     * <p>Note that this listener will only be invoked whenever
+     * {@link #setPreferredDeviceForCapturePreset(int, AudioDeviceAttributes)} or
+     * {@link #clearPreferredDevicesForCapturePreset(int)} causes a change in
+     * preferred device. It will not be invoked directly after registration with
+     * {@link #addOnPreferredDevicesForCapturePresetChangedListener(
+     * Executor, OnPreferredDevicesForCapturePresetChangedListener)}
+     * to indicate which strategies had preferred devices at the time of registration.</p>
+     * @see #setPreferredDeviceForCapturePreset(int, AudioDeviceAttributes)
+     * @see #clearPreferredDevicesForCapturePreset(int)
+     * @see #getPreferredDevicesForCapturePreset(int)
+     */
+    @SystemApi
+    public interface OnPreferredDevicesForCapturePresetChangedListener {
+        /**
+         * Called on the listener to indicate that the preferred audio devices for the given
+         * capture preset has changed.
+         * @param capturePreset the capture preset whose preferred device changed
+         * @param devices a list of newly set preferred audio devices
+         */
+        void onPreferredDevicesForCapturePresetChanged(
+                int capturePreset, @NonNull List<AudioDeviceAttributes> devices);
+    }
+
+    /**
+     * @hide
+     * Adds a listener for being notified of changes to the capture-preset-preferred audio device.
+     * @param executor
+     * @param listener
+     * @throws SecurityException if the caller doesn't hold the required permission
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+    public void addOnPreferredDevicesForCapturePresetChangedListener(
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull OnPreferredDevicesForCapturePresetChangedListener listener)
+            throws SecurityException {
+        Objects.requireNonNull(executor);
+        Objects.requireNonNull(listener);
+        int status = addOnDevRoleForCapturePresetChangedListener(
+                executor, listener, AudioSystem.DEVICE_ROLE_PREFERRED);
+        if (status == AudioSystem.ERROR) {
+            // This must not happen
+            throw new RuntimeException("Unknown error happened");
+        }
+        if (status == AudioSystem.BAD_VALUE) {
+            throw new IllegalArgumentException(
+                    "attempt to call addOnPreferredDevicesForCapturePresetChangedListener() "
+                            + "on a previously registered listener");
+        }
+    }
+
+    /**
+     * @hide
+     * Removes a previously added listener of changes to the capture-preset-preferred audio device.
+     * @param listener
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+    public void removeOnPreferredDevicesForCapturePresetChangedListener(
+            @NonNull OnPreferredDevicesForCapturePresetChangedListener listener) {
+        Objects.requireNonNull(listener);
+        int status = removeOnDevRoleForCapturePresetChangedListener(
+                listener, AudioSystem.DEVICE_ROLE_PREFERRED);
+        if (status == AudioSystem.ERROR) {
+            // This must not happen
+            throw new RuntimeException("Unknown error happened");
+        }
+        if (status == AudioSystem.BAD_VALUE) {
+            throw new IllegalArgumentException(
+                    "attempt to call removeOnPreferredDevicesForCapturePresetChangedListener() "
+                            + "on an unregistered listener");
+        }
+    }
+
+    private <T> int addOnDevRoleForCapturePresetChangedListener(
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull T listener, int deviceRole) {
+        Objects.requireNonNull(executor);
+        Objects.requireNonNull(listener);
+        DevRoleListeners<T> devRoleListeners =
+                (DevRoleListeners<T>) mDevRoleForCapturePresetListeners.get(deviceRole);
+        if (devRoleListeners == null) {
+            return AudioSystem.ERROR;
+        }
+        synchronized (devRoleListeners.mDevRoleListenersLock) {
+            if (devRoleListeners.hasDevRoleListener(listener)) {
+                return AudioSystem.BAD_VALUE;
+            }
+            // lazy initialization of the list of device role listener
+            if (devRoleListeners.mListenerInfos == null) {
+                devRoleListeners.mListenerInfos = new ArrayList<>();
+            }
+            final int oldCbCount = devRoleListeners.mListenerInfos.size();
+            devRoleListeners.mListenerInfos.add(new DevRoleListenerInfo<T>(executor, listener));
+            if (oldCbCount == 0 && devRoleListeners.mListenerInfos.size() > 0) {
+                // register binder for callbacks
+                synchronized (mDevRoleForCapturePresetListenersLock) {
+                    int deviceRoleListenerStatus = mDeviceRoleListenersStatus;
+                    mDeviceRoleListenersStatus |= (1 << deviceRole);
+                    if (deviceRoleListenerStatus != 0) {
+                        // There are already device role changed listeners active.
+                        return AudioSystem.SUCCESS;
+                    }
+                    if (mDevicesRoleForCapturePresetDispatcherStub == null) {
+                        mDevicesRoleForCapturePresetDispatcherStub =
+                                new CapturePresetDevicesRoleDispatcherStub();
+                    }
+                    try {
+                        getService().registerCapturePresetDevicesRoleDispatcher(
+                                mDevicesRoleForCapturePresetDispatcherStub);
+                    } catch (RemoteException e) {
+                        throw e.rethrowFromSystemServer();
+                    }
+                }
+            }
+        }
+        return AudioSystem.SUCCESS;
+    }
+
+    private <T> int removeOnDevRoleForCapturePresetChangedListener(
+            @NonNull T listener, int deviceRole) {
+        Objects.requireNonNull(listener);
+        DevRoleListeners<T> devRoleListeners =
+                (DevRoleListeners<T>) mDevRoleForCapturePresetListeners.get(deviceRole);
+        if (devRoleListeners == null) {
+            return AudioSystem.ERROR;
+        }
+        synchronized (devRoleListeners.mDevRoleListenersLock) {
+            if (!devRoleListeners.removeDevRoleListener(listener)) {
+                return AudioSystem.BAD_VALUE;
+            }
+            if (devRoleListeners.mListenerInfos.size() == 0) {
+                // unregister binder for callbacks
+                synchronized (mDevRoleForCapturePresetListenersLock) {
+                    mDeviceRoleListenersStatus ^= (1 << deviceRole);
+                    if (mDeviceRoleListenersStatus != 0) {
+                        // There are some other device role changed listeners active.
+                        return AudioSystem.SUCCESS;
+                    }
+                    try {
+                        getService().unregisterCapturePresetDevicesRoleDispatcher(
+                                mDevicesRoleForCapturePresetDispatcherStub);
+                    } catch (RemoteException e) {
+                        throw e.rethrowFromSystemServer();
+                    }
+                }
+            }
+        }
+        return AudioSystem.SUCCESS;
+    }
+
+    private final Map<Integer, Object> mDevRoleForCapturePresetListeners = new HashMap<>(){{
+            put(AudioSystem.DEVICE_ROLE_PREFERRED,
+                    new DevRoleListeners<OnPreferredDevicesForCapturePresetChangedListener>());
+        }};
+
+    private class DevRoleListenerInfo<T> {
+        final @NonNull Executor mExecutor;
+        final @NonNull T mListener;
+        DevRoleListenerInfo(Executor executor, T listener) {
+            mExecutor = executor;
+            mListener = listener;
+        }
+    }
+
+    private class DevRoleListeners<T> {
+        private final Object mDevRoleListenersLock = new Object();
+        @GuardedBy("mDevRoleListenersLock")
+        private @Nullable ArrayList<DevRoleListenerInfo<T>> mListenerInfos;
+
+        @GuardedBy("mDevRoleListenersLock")
+        private @Nullable DevRoleListenerInfo<T> getDevRoleListenerInfo(T listener) {
+            if (mListenerInfos == null) {
+                return null;
+            }
+            for (DevRoleListenerInfo<T> listenerInfo : mListenerInfos) {
+                if (listenerInfo.mListener == listener) {
+                    return listenerInfo;
+                }
+            }
+            return null;
+        }
+
+        @GuardedBy("mDevRoleListenersLock")
+        private boolean hasDevRoleListener(T listener) {
+            return getDevRoleListenerInfo(listener) != null;
+        }
+
+        @GuardedBy("mDevRoleListenersLock")
+        private boolean removeDevRoleListener(T listener) {
+            final DevRoleListenerInfo<T> infoToRemove = getDevRoleListenerInfo(listener);
+            if (infoToRemove != null) {
+                mListenerInfos.remove(infoToRemove);
+                return true;
+            }
+            return false;
+        }
+    }
+
+    private final Object mDevRoleForCapturePresetListenersLock = new Object();
+    /**
+     * Record if there is a listener added for device role change. If there is a listener added for
+     * a specified device role change, the bit at position `1 << device_role` is set.
+     */
+    @GuardedBy("mDevRoleForCapturePresetListenersLock")
+    private int mDeviceRoleListenersStatus = 0;
+    @GuardedBy("mDevRoleForCapturePresetListenersLock")
+    private CapturePresetDevicesRoleDispatcherStub mDevicesRoleForCapturePresetDispatcherStub;
+
+    private final class CapturePresetDevicesRoleDispatcherStub
+            extends ICapturePresetDevicesRoleDispatcher.Stub {
+
+        @Override
+        public void dispatchDevicesRoleChanged(
+                int capturePreset, int role, List<AudioDeviceAttributes> devices) {
+            final Object listenersObj = mDevRoleForCapturePresetListeners.get(role);
+            if (listenersObj == null) {
+                return;
+            }
+            switch (role) {
+                case AudioSystem.DEVICE_ROLE_PREFERRED: {
+                    final DevRoleListeners<OnPreferredDevicesForCapturePresetChangedListener>
+                            listeners =
+                            (DevRoleListeners<OnPreferredDevicesForCapturePresetChangedListener>)
+                            listenersObj;
+                    final ArrayList<DevRoleListenerInfo<
+                            OnPreferredDevicesForCapturePresetChangedListener>> prefDevListeners;
+                    synchronized (listeners.mDevRoleListenersLock) {
+                        if (listeners.mListenerInfos.isEmpty()) {
+                            return;
+                        }
+                        prefDevListeners = (ArrayList<DevRoleListenerInfo<
+                                OnPreferredDevicesForCapturePresetChangedListener>>)
+                                listeners.mListenerInfos.clone();
+                    }
+                    final long ident = Binder.clearCallingIdentity();
+                    try {
+                        for (DevRoleListenerInfo<
+                                OnPreferredDevicesForCapturePresetChangedListener> info :
+                                prefDevListeners) {
+                            info.mExecutor.execute(() ->
+                                    info.mListener.onPreferredDevicesForCapturePresetChanged(
+                                            capturePreset, devices));
+                        }
+                    } finally {
+                        Binder.restoreCallingIdentity(ident);
+                    }
+                } break;
+                default:
+                    break;
+            }
+        }
+    }
+
+    //====================================================================
     // Offload query
     /**
      * Returns whether offloaded playback of an audio format is supported on the device.
@@ -5781,6 +6124,29 @@
     }
 
     /**
+     * Returns an {@link AudioDeviceInfo} corresponding to the specified {@link AudioPort} ID.
+     * @param portId The audio port ID to look up for.
+     * @param flags A set of bitflags specifying the criteria to test.
+     * @see #GET_DEVICES_OUTPUTS
+     * @see #GET_DEVICES_INPUTS
+     * @see #GET_DEVICES_ALL
+     * @return An AudioDeviceInfo or null if no device with matching port ID is found.
+     * @hide
+     */
+    public static AudioDeviceInfo getDeviceForPortId(int portId, int flags) {
+        if (portId == 0) {
+            return null;
+        }
+        AudioDeviceInfo[] devices = getDevicesStatic(flags);
+        for (AudioDeviceInfo device : devices) {
+            if (device.getId() == portId) {
+                return device;
+            }
+        }
+        return null;
+    }
+
+    /**
      * Registers an {@link AudioDeviceCallback} object to receive notifications of changes
      * to the set of connected audio devices.
      * @param callback The {@link AudioDeviceCallback} object to receive connect/disconnect
@@ -6323,6 +6689,297 @@
         }
     }
 
+    /**
+     * Selects the audio device that should be used for communication use cases, for instance voice
+     * or video calls. This method can be used by voice or video chat applications to select a
+     * different audio device than the one selected by default by the platform.
+     * <p>The device selection is expressed as an {@link AudioDeviceInfo}, of role sink
+     * ({@link AudioDeviceInfo#isSink()} is <code>true</code>) and of one of the following types:
+     * <ul>
+     *   <li> {@link AudioDeviceInfo#TYPE_BUILTIN_EARPIECE}
+     *   <li> {@link AudioDeviceInfo#TYPE_BUILTIN_SPEAKER}
+     *   <li> {@link AudioDeviceInfo#TYPE_WIRED_HEADSET}
+     *   <li> {@link AudioDeviceInfo#TYPE_BLUETOOTH_SCO}
+     *   <li> {@link AudioDeviceInfo#TYPE_USB_HEADSET}
+     *   <li> {@link AudioDeviceInfo#TYPE_BLE_HEADSET}
+     * </ul>
+     * The selection is active as long as the requesting application lives, until
+     * {@link #clearDeviceForCommunication} is called or until the device is disconnected.
+     * It is therefore important for applications to clear the request when a call ends or the
+     * application is paused.
+     * <p>In case of simultaneous requests by multiple applications the priority is given to the
+     * application currently controlling the audio mode (see {@link #setMode(int)}). This is the
+     * latest application having selected mode {@link #MODE_IN_COMMUNICATION} or mode
+     * {@link #MODE_IN_CALL}. Note that <code>MODE_IN_CALL</code> can only be selected by the main
+     * telephony application with permission
+     * {@link android.Manifest.permission#MODIFY_PHONE_STATE}.
+     * <p> If the requested devices is not currently available, the request will be rejected and
+     * the method will return false.
+     * <p>This API replaces the following deprecated APIs:
+     * <ul>
+     *   <li> {@link #startBluetoothSco()}
+     *   <li> {@link #stopBluetoothSco()}
+     *   <li> {@link #setSpeakerphoneOn(boolean)}
+     * </ul>
+     * <h4>Example</h4>
+     * <p>The example below shows how to enable and disable speakerphone mode.
+     * <pre class="prettyprint">
+     * // Get an AudioManager instance
+     * AudioManager audioManager = Context.getSystemService(AudioManager.class);
+     * try {
+     *     AudioDeviceInfo speakerDevice = null;
+     *     AudioDeviceInfo[] devices = audioManager.getDevices(GET_DEVICES_OUTPUTS);
+     *     for (AudioDeviceInfo device : devices) {
+     *         if (device.getType() == AudioDeviceInfo.TYPE_BUILTIN_SPEAKER) {
+     *             speakerDevice = device;
+     *             break;
+     *         }
+     *     }
+     *     if (speakerDevice != null) {
+     *         // Turn speakerphone ON.
+     *         boolean result = audioManager.setDeviceForCommunication(speakerDevice);
+     *         if (!result) {
+     *             // Handle error.
+     *         }
+     *         // Turn speakerphone OFF.
+     *         audioManager.clearDeviceForCommunication();
+     *     }
+     * } catch (IllegalArgumentException e) {
+     *     // Handle exception.
+     * }
+     * </pre>
+     * @param device the requested audio device.
+     * @return <code>true</code> if the request was accepted, <code>false</code> otherwise.
+     * @throws IllegalArgumentException If an invalid device is specified.
+     */
+    public boolean setDeviceForCommunication(@NonNull AudioDeviceInfo device) {
+        Objects.requireNonNull(device);
+        try {
+            if (device.getId() == 0) {
+                throw new IllegalArgumentException("In valid device: " + device);
+            }
+            return getService().setDeviceForCommunication(mICallBack, device.getId());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Cancels previous communication device selection made with
+     * {@link #setDeviceForCommunication(AudioDeviceInfo)}.
+     */
+    public void clearDeviceForCommunication() {
+        try {
+            getService().setDeviceForCommunication(mICallBack, 0);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns currently selected audio device for communication.
+     * <p>This API replaces the following deprecated APIs:
+     * <ul>
+     *   <li> {@link #isBluetoothScoOn()}
+     *   <li> {@link #isSpeakerphoneOn()}
+     * </ul>
+     * @return an {@link AudioDeviceInfo} indicating which audio device is
+     * currently selected or communication use cases or null if default selection
+     * is used.
+     */
+    @Nullable
+    public AudioDeviceInfo getDeviceForCommunication() {
+        try {
+            return getDeviceForPortId(
+                    getService().getDeviceForCommunication(), GET_DEVICES_OUTPUTS);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     * Returns an {@link AudioDeviceInfo} corresponding to a connected device of the type provided.
+     * The type must be a valid output type defined in <code>AudioDeviceInfo</code> class,
+     * for instance {@link AudioDeviceInfo#TYPE_BUILTIN_SPEAKER}.
+     * The method will return null if no device of the provided type is connected.
+     * If more than one device of the provided type is connected, an object corresponding to the
+     * first device encountered in the enumeration list will be returned.
+     * @param deviceType The device device for which an <code>AudioDeviceInfo</code>
+     * object is queried.
+     * @return An AudioDeviceInfo object or null if no device with the requested type is connected.
+     * @throws IllegalArgumentException If an invalid device type is specified.
+     */
+    @TestApi
+    @Nullable
+    public static AudioDeviceInfo getDeviceInfoFromType(
+            @AudioDeviceInfo.AudioDeviceTypeOut int deviceType) {
+        AudioDeviceInfo[] devices = getDevicesStatic(GET_DEVICES_OUTPUTS);
+        for (AudioDeviceInfo device : devices) {
+            if (device.getType() == deviceType) {
+                return device;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Listener registered by client to be notified upon communication audio device change.
+     * See {@link #setDeviceForCommunication(AudioDeviceInfo)}.
+     */
+    public interface OnCommunicationDeviceChangedListener {
+        /**
+         * Callback method called upon communication audio device change.
+         * @param device the audio device selected for communication use cases
+         */
+        void onCommunicationDeviceChanged(@Nullable AudioDeviceInfo device);
+    }
+
+    /**
+     * Adds a listener for being notified of changes to the communication audio device.
+     * See {@link #setDeviceForCommunication(AudioDeviceInfo)}.
+     * @param executor
+     * @param listener
+     */
+    public void addOnCommunicationDeviceChangedListener(
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull OnCommunicationDeviceChangedListener listener) {
+        Objects.requireNonNull(executor);
+        Objects.requireNonNull(listener);
+        synchronized (mCommDevListenerLock) {
+            if (hasCommDevListener(listener)) {
+                throw new IllegalArgumentException(
+                        "attempt to call addOnCommunicationDeviceChangedListener() "
+                                + "on a previously registered listener");
+            }
+            // lazy initialization of the list of strategy-preferred device listener
+            if (mCommDevListeners == null) {
+                mCommDevListeners = new ArrayList<>();
+            }
+            final int oldCbCount = mCommDevListeners.size();
+            mCommDevListeners.add(new CommDevListenerInfo(listener, executor));
+            if (oldCbCount == 0 && mCommDevListeners.size() > 0) {
+                // register binder for callbacks
+                if (mCommDevDispatcherStub == null) {
+                    mCommDevDispatcherStub = new CommunicationDeviceDispatcherStub();
+                }
+                try {
+                    getService().registerCommunicationDeviceDispatcher(mCommDevDispatcherStub);
+                } catch (RemoteException e) {
+                    throw e.rethrowFromSystemServer();
+                }
+            }
+        }
+    }
+
+    /**
+     * Removes a previously added listener of changes to the communication audio device.
+     * See {@link #setDeviceForCommunication(AudioDeviceInfo)}.
+     * @param listener
+     */
+    public void removeOnCommunicationDeviceChangedListener(
+            @NonNull OnCommunicationDeviceChangedListener listener) {
+        Objects.requireNonNull(listener);
+        synchronized (mCommDevListenerLock) {
+            if (!removeCommDevListener(listener)) {
+                throw new IllegalArgumentException(
+                        "attempt to call removeOnCommunicationDeviceChangedListener() "
+                                + "on an unregistered listener");
+            }
+            if (mCommDevListeners.size() == 0) {
+                // unregister binder for callbacks
+                try {
+                    getService().unregisterCommunicationDeviceDispatcher(
+                            mCommDevDispatcherStub);
+                } catch (RemoteException e) {
+                    throw e.rethrowFromSystemServer();
+                } finally {
+                    mCommDevDispatcherStub = null;
+                    mCommDevListeners = null;
+                }
+            }
+        }
+    }
+
+    private final Object mCommDevListenerLock = new Object();
+    /**
+     * List of listeners for preferred device for strategy and their associated Executor.
+     * List is lazy-initialized on first registration
+     */
+    @GuardedBy("mCommDevListenerLock")
+    private @Nullable ArrayList<CommDevListenerInfo> mCommDevListeners;
+
+    private static class CommDevListenerInfo {
+        final @NonNull OnCommunicationDeviceChangedListener mListener;
+        final @NonNull Executor mExecutor;
+
+        CommDevListenerInfo(OnCommunicationDeviceChangedListener listener, Executor exe) {
+            mListener = listener;
+            mExecutor = exe;
+        }
+    }
+
+    @GuardedBy("mCommDevListenerLock")
+    private CommunicationDeviceDispatcherStub mCommDevDispatcherStub;
+
+    private final class CommunicationDeviceDispatcherStub
+            extends ICommunicationDeviceDispatcher.Stub {
+
+        @Override
+        public void dispatchCommunicationDeviceChanged(int portId) {
+            // make a shallow copy of listeners so callback is not executed under lock
+            final ArrayList<CommDevListenerInfo> commDevListeners;
+            synchronized (mCommDevListenerLock) {
+                if (mCommDevListeners == null || mCommDevListeners.size() == 0) {
+                    return;
+                }
+                commDevListeners = (ArrayList<CommDevListenerInfo>) mCommDevListeners.clone();
+            }
+            AudioDeviceInfo device = getDeviceForPortId(portId, GET_DEVICES_OUTPUTS);
+            final long ident = Binder.clearCallingIdentity();
+            try {
+                for (CommDevListenerInfo info : commDevListeners) {
+                    info.mExecutor.execute(() ->
+                            info.mListener.onCommunicationDeviceChanged(device));
+                }
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+    }
+
+    @GuardedBy("mCommDevListenerLock")
+    private @Nullable CommDevListenerInfo getCommDevListenerInfo(
+            OnCommunicationDeviceChangedListener listener) {
+        if (mCommDevListeners == null) {
+            return null;
+        }
+        for (CommDevListenerInfo info : mCommDevListeners) {
+            if (info.mListener == listener) {
+                return info;
+            }
+        }
+        return null;
+    }
+
+    @GuardedBy("mCommDevListenerLock")
+    private boolean hasCommDevListener(OnCommunicationDeviceChangedListener listener) {
+        return getCommDevListenerInfo(listener) != null;
+    }
+
+    @GuardedBy("mCommDevListenerLock")
+    /**
+     * @return true if the listener was removed from the list
+     */
+    private boolean removeCommDevListener(OnCommunicationDeviceChangedListener listener) {
+        final CommDevListenerInfo infoToRemove = getCommDevListenerInfo(listener);
+        if (infoToRemove != null) {
+            mCommDevListeners.remove(infoToRemove);
+            return true;
+        }
+        return false;
+    }
+
     //---------------------------------------------------------
     // Inner classes
     //--------------------
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index 1590485..18c8a72 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -28,6 +28,7 @@
 import android.os.Build;
 import android.telephony.TelephonyManager;
 import android.util.Log;
+import android.util.Pair;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -1711,7 +1712,7 @@
         int[] types = new int[devices.size()];
         String[] addresses = new String[devices.size()];
         for (int i = 0; i < devices.size(); ++i) {
-            types[i] = AudioDeviceInfo.convertDeviceTypeToInternalDevice(devices.get(i).getType());
+            types[i] = devices.get(i).getInternalType();
             addresses[i] = devices.get(i).getAddress();
         }
         return setDevicesRoleForStrategy(strategy, role, types, addresses);
@@ -1750,6 +1751,134 @@
     public static native int getDevicesForRoleAndStrategy(
             int strategy, int role, @NonNull List<AudioDeviceAttributes> devices);
 
+    // use case routing by capture preset
+
+    private static Pair<int[], String[]> populateInputDevicesTypeAndAddress(
+            @NonNull List<AudioDeviceAttributes> devices) {
+        int[] types = new int[devices.size()];
+        String[] addresses = new String[devices.size()];
+        for (int i = 0; i < devices.size(); ++i) {
+            types[i] = devices.get(i).getInternalType();
+            if (types[i] == AudioSystem.DEVICE_NONE) {
+                types[i] = AudioDeviceInfo.convertDeviceTypeToInternalInputDevice(
+                        devices.get(i).getType());
+            }
+            addresses[i] = devices.get(i).getAddress();
+        }
+        return new Pair<int[], String[]>(types, addresses);
+    }
+
+    /**
+     * @hide
+     * Set devices as role for capture preset.
+     * @param capturePreset the capture preset to configure
+     * @param role the role of the devices
+     * @param devices the list of devices to be set as role for the given capture preset
+     * @return {@link #SUCCESS} if successfully set
+     */
+    public static int setDevicesRoleForCapturePreset(
+            int capturePreset, int role, @NonNull List<AudioDeviceAttributes> devices) {
+        if (devices.isEmpty()) {
+            return BAD_VALUE;
+        }
+        Pair<int[], String[]> typeAddresses = populateInputDevicesTypeAndAddress(devices);
+        return setDevicesRoleForCapturePreset(
+                capturePreset, role, typeAddresses.first, typeAddresses.second);
+    }
+
+    /**
+     * @hide
+     * Set devices as role for capture preset.
+     * @param capturePreset the capture preset to configure
+     * @param role the role of the devices
+     * @param types all device types
+     * @param addresses all device addresses
+     * @return {@link #SUCCESS} if successfully set
+     */
+    private static native int setDevicesRoleForCapturePreset(
+            int capturePreset, int role, @NonNull int[] types, @NonNull String[] addresses);
+
+    /**
+     * @hide
+     * Add devices as role for capture preset.
+     * @param capturePreset the capture preset to configure
+     * @param role the role of the devices
+     * @param devices the list of devices to be added as role for the given capture preset
+     * @return {@link #SUCCESS} if successfully add
+     */
+    public static int addDevicesRoleForCapturePreset(
+            int capturePreset, int role, @NonNull List<AudioDeviceAttributes> devices) {
+        if (devices.isEmpty()) {
+            return BAD_VALUE;
+        }
+        Pair<int[], String[]> typeAddresses = populateInputDevicesTypeAndAddress(devices);
+        return addDevicesRoleForCapturePreset(
+                capturePreset, role, typeAddresses.first, typeAddresses.second);
+    }
+
+    /**
+     * @hide
+     * Add devices as role for capture preset.
+     * @param capturePreset the capture preset to configure
+     * @param role the role of the devices
+     * @param types all device types
+     * @param addresses all device addresses
+     * @return {@link #SUCCESS} if successfully set
+     */
+    private static native int addDevicesRoleForCapturePreset(
+            int capturePreset, int role, @NonNull int[] types, @NonNull String[] addresses);
+
+    /**
+     * @hide
+     * Remove devices as role for the capture preset
+     * @param capturePreset the capture preset to configure
+     * @param role the role of the devices
+     * @param devices the devices to be removed
+     * @return {@link #SUCCESS} if successfully removed
+     */
+    public static int removeDevicesRoleForCapturePreset(
+            int capturePreset, int role, @NonNull List<AudioDeviceAttributes> devices) {
+        if (devices.isEmpty()) {
+            return BAD_VALUE;
+        }
+        Pair<int[], String[]> typeAddresses = populateInputDevicesTypeAndAddress(devices);
+        return removeDevicesRoleForCapturePreset(
+                capturePreset, role, typeAddresses.first, typeAddresses.second);
+    }
+
+    /**
+     * @hide
+     * Remove devices as role for capture preset.
+     * @param capturePreset the capture preset to configure
+     * @param role the role of the devices
+     * @param types all device types
+     * @param addresses all device addresses
+     * @return {@link #SUCCESS} if successfully set
+     */
+    private static native int removeDevicesRoleForCapturePreset(
+            int capturePreset, int role, @NonNull int[] types, @NonNull String[] addresses);
+
+    /**
+     * @hide
+     * Remove all devices as role for the capture preset
+     * @param capturePreset the capture preset to configure
+     * @param role the role of the devices
+     * @return {@link #SUCCESS} if successfully removed
+     */
+    public static native int clearDevicesRoleForCapturePreset(int capturePreset, int role);
+
+    /**
+     * @hide
+     * Query previously set devices as role for a capture preset
+     * @param capturePreset the capture preset to query for
+     * @param role the role of the devices
+     * @param devices a list that will contain the devices of role
+     * @return {@link #SUCCESS} if there is a preferred device and it was successfully retrieved
+     *     and written to the array
+     */
+    public static native int getDevicesForRoleAndCapturePreset(
+            int capturePreset, int role, @NonNull List<AudioDeviceAttributes> devices);
+
     // Items shared with audio service
 
     /**
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index bc2839e..ebaa316 100755
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -26,6 +26,8 @@
 import android.media.IAudioFocusDispatcher;
 import android.media.IAudioRoutesObserver;
 import android.media.IAudioServerStateDispatcher;
+import android.media.ICapturePresetDevicesRoleDispatcher;
+import android.media.ICommunicationDeviceDispatcher;
 import android.media.IPlaybackConfigDispatcher;
 import android.media.IRecordingConfigDispatcher;
 import android.media.IRingtonePlayer;
@@ -307,4 +309,25 @@
     // code via IAudioManager.h need to be added to the top section.
 
     oneway void setMultiAudioFocusEnabled(in boolean enabled);
+
+    int setPreferredDevicesForCapturePreset(
+            in int capturePreset, in List<AudioDeviceAttributes> devices);
+
+    int clearPreferredDevicesForCapturePreset(in int capturePreset);
+
+    List<AudioDeviceAttributes> getPreferredDevicesForCapturePreset(in int capturePreset);
+
+    void registerCapturePresetDevicesRoleDispatcher(ICapturePresetDevicesRoleDispatcher dispatcher);
+
+    oneway void unregisterCapturePresetDevicesRoleDispatcher(
+            ICapturePresetDevicesRoleDispatcher dispatcher);
+
+    boolean setDeviceForCommunication(IBinder cb, int portId);
+
+    int getDeviceForCommunication();
+
+    void registerCommunicationDeviceDispatcher(ICommunicationDeviceDispatcher dispatcher);
+
+    oneway void unregisterCommunicationDeviceDispatcher(
+            ICommunicationDeviceDispatcher dispatcher);
 }
diff --git a/wifi/java/android/net/wifi/IWifiConnectedNetworkScorer.aidl b/media/java/android/media/ICapturePresetDevicesRoleDispatcher.aidl
similarity index 65%
rename from wifi/java/android/net/wifi/IWifiConnectedNetworkScorer.aidl
rename to media/java/android/media/ICapturePresetDevicesRoleDispatcher.aidl
index f96d037c..5e03e63 100644
--- a/wifi/java/android/net/wifi/IWifiConnectedNetworkScorer.aidl
+++ b/media/java/android/media/ICapturePresetDevicesRoleDispatcher.aidl
@@ -14,20 +14,18 @@
  * limitations under the License.
  */
 
-package android.net.wifi;
+package android.media;
 
-import android.net.wifi.IScoreUpdateObserver;
+import android.media.AudioDeviceAttributes;
 
 /**
- * Interface for Wi-Fi connected network scorer.
+ * AIDL for AudioService to signal devices role for capture preset updates.
  *
- * @hide
+ * {@hide}
  */
-oneway interface IWifiConnectedNetworkScorer
-{
-    void onStart(int sessionId);
+oneway interface ICapturePresetDevicesRoleDispatcher {
 
-    void onStop(int sessionId);
+    void dispatchDevicesRoleChanged(
+            int capturePreset, int role, in List<AudioDeviceAttributes> devices);
 
-    void onSetScoreUpdateObserver(IScoreUpdateObserver observerImpl);
 }
diff --git a/wifi/java/android/net/wifi/IScoreUpdateObserver.aidl b/media/java/android/media/ICommunicationDeviceDispatcher.aidl
similarity index 73%
rename from wifi/java/android/net/wifi/IScoreUpdateObserver.aidl
rename to media/java/android/media/ICommunicationDeviceDispatcher.aidl
index 775fed7..429f934 100644
--- a/wifi/java/android/net/wifi/IScoreUpdateObserver.aidl
+++ b/media/java/android/media/ICommunicationDeviceDispatcher.aidl
@@ -14,16 +14,15 @@
  * limitations under the License.
  */
 
-package android.net.wifi;
+package android.media;
 
 /**
- * Interface for Wi-Fi score callback.
+ * AIDL for AudioService to signal audio communication device updates.
  *
- * @hide
+ * {@hide}
  */
-oneway interface IScoreUpdateObserver
-{
-    void notifyScoreUpdate(int sessionId, int score);
+oneway interface ICommunicationDeviceDispatcher {
 
-    void triggerUpdateOfWifiUsabilityStats(int sessionId);
+    void dispatchCommunicationDeviceChanged(int portId);
+
 }
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index 73ef315..c61a2eb 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -404,6 +404,32 @@
         }
     }
 
+    /**
+     * @hide
+     * @param source An audio source to test
+     * @return true if the source is a valid one
+     */
+    public static boolean isValidAudioSource(int source) {
+        switch(source) {
+            case AudioSource.MIC:
+            case AudioSource.VOICE_UPLINK:
+            case AudioSource.VOICE_DOWNLINK:
+            case AudioSource.VOICE_CALL:
+            case AudioSource.CAMCORDER:
+            case AudioSource.VOICE_RECOGNITION:
+            case AudioSource.VOICE_COMMUNICATION:
+            case AudioSource.REMOTE_SUBMIX:
+            case AudioSource.UNPROCESSED:
+            case AudioSource.VOICE_PERFORMANCE:
+            case AudioSource.ECHO_REFERENCE:
+            case AudioSource.RADIO_TUNER:
+            case AudioSource.HOTWORD:
+                return true;
+            default:
+                return false;
+        }
+    }
+
     /** @hide */
     public static final String toLogFriendlyAudioSource(int source) {
         switch(source) {
diff --git a/media/java/android/media/tv/tuner/Tuner.java b/media/java/android/media/tv/tuner/Tuner.java
index 8bf688d..b743a95 100644
--- a/media/java/android/media/tv/tuner/Tuner.java
+++ b/media/java/android/media/tv/tuner/Tuner.java
@@ -60,6 +60,7 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -210,6 +211,7 @@
     @Nullable
     private FrontendInfo mFrontendInfo;
     private Integer mFrontendHandle;
+    private Boolean mIsSharedFrontend = false;
     private int mFrontendType = FrontendSettings.TYPE_UNDEFINED;
     private int mUserId;
     private Lnb mLnb;
@@ -228,8 +230,8 @@
     private Executor mOnResourceLostListenerExecutor;
 
     private Integer mDemuxHandle;
-    private Map<Integer, Descrambler> mDescramblers = new HashMap<>();
-    private List<Filter> mFilters = new ArrayList<>();
+    private Map<Integer, WeakReference<Descrambler>> mDescramblers = new HashMap<>();
+    private List<WeakReference<Filter>> mFilters = new ArrayList<WeakReference<Filter>>();
 
     private final TunerResourceManager.ResourcesReclaimListener mResourceListener =
             new TunerResourceManager.ResourcesReclaimListener() {
@@ -240,6 +242,7 @@
                                 .write(FrameworkStatsLog.TV_TUNER_STATE_CHANGED, mUserId,
                                     FrameworkStatsLog.TV_TUNER_STATE_CHANGED__STATE__UNKNOWN);
                     }
+                    releaseAll();
                     mHandler.sendMessage(mHandler.obtainMessage(MSG_RESOURCE_LOST));
                 }
             };
@@ -336,8 +339,11 @@
      */
     public void shareFrontendFromTuner(@NonNull Tuner tuner) {
         mTunerResourceManager.shareFrontend(mClientId, tuner.mClientId);
-        mFrontendHandle = tuner.mFrontendHandle;
-        mFrontend = nativeOpenFrontendByHandle(mFrontendHandle);
+        synchronized (mIsSharedFrontend) {
+            mFrontendHandle = tuner.mFrontendHandle;
+            mFrontend = tuner.mFrontend;
+            mIsSharedFrontend = true;
+        }
     }
 
     /**
@@ -362,33 +368,53 @@
      */
     @Override
     public void close() {
+        releaseAll();
+        TunerUtils.throwExceptionForResult(nativeClose(), "failed to close tuner");
+    }
+
+    private void releaseAll() {
         if (mFrontendHandle != null) {
-            int res = nativeCloseFrontend(mFrontendHandle);
-            if (res != Tuner.RESULT_SUCCESS) {
-                TunerUtils.throwExceptionForResult(res, "failed to close frontend");
+            synchronized (mIsSharedFrontend) {
+                if (!mIsSharedFrontend) {
+                    int res = nativeCloseFrontend(mFrontendHandle);
+                    if (res != Tuner.RESULT_SUCCESS) {
+                        TunerUtils.throwExceptionForResult(res, "failed to close frontend");
+                    }
+                }
+                mIsSharedFrontend = false;
             }
             mTunerResourceManager.releaseFrontend(mFrontendHandle, mClientId);
             FrameworkStatsLog
                     .write(FrameworkStatsLog.TV_TUNER_STATE_CHANGED, mUserId,
-                        FrameworkStatsLog.TV_TUNER_STATE_CHANGED__STATE__UNKNOWN);
+                    FrameworkStatsLog.TV_TUNER_STATE_CHANGED__STATE__UNKNOWN);
             mFrontendHandle = null;
             mFrontend = null;
         }
         if (mLnb != null) {
             mLnb.close();
         }
-        if (!mDescramblers.isEmpty()) {
-            for (Map.Entry<Integer, Descrambler> d : mDescramblers.entrySet()) {
-                d.getValue().close();
-                mTunerResourceManager.releaseDescrambler(d.getKey(), mClientId);
+        synchronized (mDescramblers) {
+            if (!mDescramblers.isEmpty()) {
+                for (Map.Entry<Integer, WeakReference<Descrambler>> d : mDescramblers.entrySet()) {
+                    Descrambler descrambler = d.getValue().get();
+                    if (descrambler != null) {
+                        descrambler.close();
+                    }
+                    mTunerResourceManager.releaseDescrambler(d.getKey(), mClientId);
+                }
+                mDescramblers.clear();
             }
-            mDescramblers.clear();
         }
-        if (!mFilters.isEmpty()) {
-            for (Filter f : mFilters) {
-                f.close();
+        synchronized (mFilters) {
+            if (!mFilters.isEmpty()) {
+                for (WeakReference<Filter> weakFilter : mFilters) {
+                    Filter filter = weakFilter.get();
+                    if (filter != null) {
+                        filter.close();
+                    }
+                }
+                mFilters.clear();
             }
-            mFilters.clear();
         }
         if (mDemuxHandle != null) {
             int res = nativeCloseDemux(mDemuxHandle);
@@ -396,9 +422,9 @@
                 TunerUtils.throwExceptionForResult(res, "failed to close demux");
             }
             mTunerResourceManager.releaseDemux(mDemuxHandle, mClientId);
-            mFrontendHandle = null;
+            mDemuxHandle = null;
         }
-        TunerUtils.throwExceptionForResult(nativeClose(), "failed to close tuner");
+
     }
 
     /**
@@ -610,10 +636,14 @@
     @Result
     public int scan(@NonNull FrontendSettings settings, @ScanType int scanType,
             @NonNull @CallbackExecutor Executor executor, @NonNull ScanCallback scanCallback) {
-        if (mScanCallback != null || mScanCallbackExecutor != null) {
+        /**
+         * Scan can be called again for blink scan if scanCallback and executor are same as before.
+         */
+        if (((mScanCallback != null) && (mScanCallback != scanCallback))
+                || ((mScanCallbackExecutor != null) && (mScanCallbackExecutor != executor))) {
             throw new IllegalStateException(
-                    "Scan already in progress.  stopScan must be called before a new scan can be "
-                            + "started.");
+                    "Different Scan session already in progress.  stopScan must be called "
+                        + "before a new scan session can be " + "started.");
         }
         mFrontendType = settings.getType();
         if (checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND)) {
@@ -944,7 +974,10 @@
             if (mHandler == null) {
                 mHandler = createEventHandler();
             }
-            mFilters.add(filter);
+            synchronized (mFilters) {
+                WeakReference<Filter> weakFilter = new WeakReference<Filter>(filter);
+                mFilters.add(weakFilter);
+            }
         }
         return filter;
     }
@@ -1112,7 +1145,10 @@
         int handle = descramblerHandle[0];
         Descrambler descrambler = nativeOpenDescramblerByHandle(handle);
         if (descrambler != null) {
-            mDescramblers.put(handle, descrambler);
+            synchronized (mDescramblers) {
+                WeakReference weakDescrambler = new WeakReference<Descrambler>(descrambler);
+                mDescramblers.put(handle, weakDescrambler);
+            }
         } else {
             mTunerResourceManager.releaseDescrambler(handle, mClientId);
         }
diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp
index 515d610..5daf8b0 100644
--- a/media/jni/android_media_tv_Tuner.cpp
+++ b/media/jni/android_media_tv_Tuner.cpp
@@ -171,6 +171,12 @@
 
 void DestroyCallback(const C2Buffer * /* buf */, void *arg) {
     android::sp<android::MediaEvent> event = (android::MediaEvent *)arg;
+    if (event->mLinearBlockObj != NULL) {
+        JNIEnv *env = android::AndroidRuntime::getJNIEnv();
+        env->DeleteWeakGlobalRef(event->mLinearBlockObj);
+        event->mLinearBlockObj = NULL;
+    }
+
     event->mAvHandleRefCnt--;
     event->finalize();
 }
@@ -182,6 +188,12 @@
     mLnb = env->NewWeakGlobalRef(lnbObj);
 }
 
+LnbCallback::~LnbCallback() {
+    JNIEnv *env = AndroidRuntime::getJNIEnv();
+    env->DeleteWeakGlobalRef(mLnb);
+    mLnb = NULL;
+}
+
 Return<void> LnbCallback::onEvent(LnbEventType lnbEventType) {
     ALOGD("LnbCallback::onEvent, type=%d", lnbEventType);
     JNIEnv *env = AndroidRuntime::getJNIEnv();
@@ -291,8 +303,9 @@
 C2DataIdInfo::C2DataIdInfo(uint32_t index, uint64_t value) : C2Param(kParamSize, index) {
     CHECK(isGlobal());
     CHECK_EQ(C2Param::INFO, kind());
-    DummyInfo info{value};
-    memcpy(this + 1, static_cast<C2Param *>(&info) + 1, kParamSize - sizeof(C2Param));
+    mInfo = StubInfo(value);
+    memcpy(static_cast<C2Param *>(this) + 1, static_cast<C2Param *>(&mInfo) + 1,
+            kParamSize - sizeof(C2Param));
 }
 
 /////////////// MediaEvent ///////////////////////
@@ -304,6 +317,7 @@
     JNIEnv *env = AndroidRuntime::getJNIEnv();
     mMediaEventObj = env->NewWeakGlobalRef(obj);
     mAvHandle = native_handle_clone(avHandle.getNativeHandle());
+    mLinearBlockObj = NULL;
 }
 
 MediaEvent::~MediaEvent() {
@@ -337,33 +351,44 @@
     }
     mIonHandle = new C2HandleIon(dup(mAvHandle->data[0]), mDataLength);
     std::shared_ptr<C2LinearBlock> block = _C2BlockFactory::CreateLinearBlock(mIonHandle);
-
-    JNIEnv *env = AndroidRuntime::getJNIEnv();
-    std::unique_ptr<JMediaCodecLinearBlock> context{new JMediaCodecLinearBlock};
-    context->mBlock = block;
-    std::shared_ptr<C2Buffer> pC2Buffer = context->toC2Buffer(0, mDataLength);
-    context->mBuffer = pC2Buffer;
-    mC2Buffer = pC2Buffer;
-    if (mAvHandle->numInts > 0) {
-        // use first int in the native_handle as the index
-        int index = mAvHandle->data[mAvHandle->numFds];
-        std::shared_ptr<C2Param> c2param = std::make_shared<C2DataIdInfo>(index, mDataId);
-        std::shared_ptr<C2Info> info(std::static_pointer_cast<C2Info>(c2param));
-        pC2Buffer->setInfo(info);
+    if (block != nullptr) {
+        // CreateLinearBlock delete mIonHandle after it create block successfully.
+        // ToDo: coordinate who is response to delete mIonHandle
+        mIonHandle = NULL;
+        JNIEnv *env = AndroidRuntime::getJNIEnv();
+        std::unique_ptr<JMediaCodecLinearBlock> context{new JMediaCodecLinearBlock};
+        context->mBlock = block;
+        std::shared_ptr<C2Buffer> pC2Buffer = context->toC2Buffer(0, mDataLength);
+        context->mBuffer = pC2Buffer;
+        mC2Buffer = pC2Buffer;
+        if (mAvHandle->numInts > 0) {
+            // use first int in the native_handle as the index
+            int index = mAvHandle->data[mAvHandle->numFds];
+            std::shared_ptr<C2Param> c2param = std::make_shared<C2DataIdInfo>(index, mDataId);
+            std::shared_ptr<C2Info> info(std::static_pointer_cast<C2Info>(c2param));
+            pC2Buffer->setInfo(info);
+        }
+        pC2Buffer->registerOnDestroyNotify(&DestroyCallback, this);
+        jobject linearBlock =
+                env->NewObject(
+                        env->FindClass("android/media/MediaCodec$LinearBlock"),
+                        gFields.linearBlockInitID);
+        env->CallVoidMethod(
+                linearBlock,
+                gFields.linearBlockSetInternalStateID,
+                (jlong)context.release(),
+                true);
+        mLinearBlockObj = env->NewWeakGlobalRef(linearBlock);
+        mAvHandleRefCnt++;
+        return linearBlock;
+    } else {
+        native_handle_close(const_cast<native_handle_t*>(
+                    reinterpret_cast<const native_handle_t*>(mIonHandle)));
+        native_handle_delete(const_cast<native_handle_t*>(
+                    reinterpret_cast<const native_handle_t*>(mIonHandle)));
+        mIonHandle = NULL;
+        return NULL;
     }
-    pC2Buffer->registerOnDestroyNotify(&DestroyCallback, this);
-    jobject linearBlock =
-            env->NewObject(
-                    env->FindClass("android/media/MediaCodec$LinearBlock"),
-                    gFields.linearBlockInitID);
-    env->CallVoidMethod(
-            linearBlock,
-            gFields.linearBlockSetInternalStateID,
-            (jlong)context.release(),
-            true);
-    mLinearBlockObj = env->NewWeakGlobalRef(linearBlock);
-    mAvHandleRefCnt++;
-    return mLinearBlockObj;
 }
 
 uint64_t MediaEvent::getAudioHandle() {
@@ -447,7 +472,7 @@
         if (mediaEvent.avMemory.getNativeHandle() != NULL || mediaEvent.avDataId != 0) {
             sp<MediaEvent> mediaEventSp =
                            new MediaEvent(mIFilter, mediaEvent.avMemory,
-                               mediaEvent.avDataId, dataLength, obj);
+                               mediaEvent.avDataId, dataLength + offset, obj);
             mediaEventSp->mAvHandleRefCnt++;
             env->SetLongField(obj, eventContext, (jlong) mediaEventSp.get());
             mediaEventSp->incStrong(obj);
@@ -2048,7 +2073,7 @@
                     env->GetIntField(settings, env->GetFieldID(clazz, "mModulation", "I")));
     FrontendInnerFec innerFec =
             static_cast<FrontendInnerFec>(
-                    env->GetLongField(settings, env->GetFieldID(clazz, "mFec", "J")));
+                    env->GetLongField(settings, env->GetFieldID(clazz, "mInnerFec", "J")));
     uint32_t symbolRate =
             static_cast<uint32_t>(
                     env->GetIntField(settings, env->GetFieldID(clazz, "mSymbolRate", "I")));
@@ -2057,7 +2082,7 @@
                     env->GetIntField(settings, env->GetFieldID(clazz, "mOuterFec", "I")));
     FrontendDvbcAnnex annex =
             static_cast<FrontendDvbcAnnex>(
-                    env->GetByteField(settings, env->GetFieldID(clazz, "mAnnex", "B")));
+                    env->GetIntField(settings, env->GetFieldID(clazz, "mAnnex", "I")));
     FrontendDvbcSpectralInversion spectralInversion =
             static_cast<FrontendDvbcSpectralInversion>(
                     env->GetIntField(
@@ -3497,6 +3522,10 @@
     } else {
         ALOGE("dvrMq.beginWrite failed");
     }
+
+    if (ret > 0) {
+        dvrSp->mDvrMQEventFlag->wake(static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_READY));
+    }
     return (jlong) ret;
 }
 
@@ -3524,7 +3553,7 @@
 
     if (dvrSp->mDvrMQ->write(reinterpret_cast<unsigned char*>(src) + offset, size)) {
         env->ReleaseByteArrayElements(buffer, src, 0);
-        dvrSp->mDvrMQEventFlag->wake(static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_CONSUMED));
+        dvrSp->mDvrMQEventFlag->wake(static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_READY));
     } else {
         ALOGD("Failed to write FMQ");
         env->ReleaseByteArrayElements(buffer, src, 0);
@@ -3585,6 +3614,9 @@
     } else {
         ALOGE("dvrMq.beginRead failed");
     }
+    if (ret > 0) {
+        dvrSp->mDvrMQEventFlag->wake(static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_CONSUMED));
+    }
 
     return (jlong) ret;
 }
diff --git a/media/jni/android_media_tv_Tuner.h b/media/jni/android_media_tv_Tuner.h
index 83e9db7..c4deeaf 100644
--- a/media/jni/android_media_tv_Tuner.h
+++ b/media/jni/android_media_tv_Tuner.h
@@ -73,6 +73,7 @@
 
 struct LnbCallback : public ILnbCallback {
     LnbCallback(jweak tunerObj, LnbId id);
+    ~LnbCallback();
     virtual Return<void> onEvent(LnbEventType lnbEventType);
     virtual Return<void> onDiseqcMessage(const hidl_vec<uint8_t>& diseqcMessage);
     jweak mLnb;
@@ -250,8 +251,9 @@
 public:
     C2DataIdInfo(uint32_t index, uint64_t value);
 private:
-    typedef C2GlobalParam<C2Info, C2Int64Value, 0> DummyInfo;
-    static const size_t kParamSize = sizeof(DummyInfo);
+    typedef C2GlobalParam<C2Info, C2Int64Value, 0> StubInfo;
+    StubInfo mInfo;
+    static const size_t kParamSize = sizeof(StubInfo);
 };
 
 }  // namespace android
diff --git a/native/android/OWNERS b/native/android/OWNERS
index 266764a..ac5a895 100644
--- a/native/android/OWNERS
+++ b/native/android/OWNERS
@@ -1,4 +1,3 @@
-set noparent
-
+per-file libandroid_net.map.txt, net.c = set noparent
 per-file libandroid_net.map.txt, net.c = codewiz@google.com, jchalard@google.com, junyulai@google.com
 per-file libandroid_net.map.txt, net.c = lorenzo@google.com, reminv@google.com, satk@google.com
diff --git a/packages/Connectivity/service/Android.bp b/packages/Connectivity/service/Android.bp
new file mode 100644
index 0000000..a26f715
--- /dev/null
+++ b/packages/Connectivity/service/Android.bp
@@ -0,0 +1,79 @@
+//
+// 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.
+//
+
+cc_defaults {
+    name: "libservice-connectivity-defaults",
+    // TODO: build against the NDK (sdk_version: "30" for example)
+    cflags: [
+        "-Wall",
+        "-Werror",
+        "-Wno-unused-parameter",
+        "-Wthread-safety",
+    ],
+    srcs: [
+        "jni/com_android_server_TestNetworkService.cpp",
+        "jni/com_android_server_connectivity_Vpn.cpp",
+    ],
+    shared_libs: [
+        "libbase",
+        "liblog",
+        "libnativehelper",
+        // TODO: remove dependency on ifc_[add/del]_address by having Java code to add/delete
+        // addresses, and remove dependency on libnetutils.
+        "libnetutils",
+    ],
+}
+
+cc_library_shared {
+    name: "libservice-connectivity",
+    defaults: ["libservice-connectivity-defaults"],
+    srcs: [
+        "jni/onload.cpp",
+    ],
+    apex_available: [
+        // TODO: move this library to the tethering APEX and remove libservice-connectivity-static
+        // "com.android.tethering",
+    ],
+}
+
+// Static library linked into libservices.core until libservice-connectivity can be loaded from
+// the tethering APEX instead.
+cc_library_static {
+    name: "libservice-connectivity-static",
+    defaults: ["libservice-connectivity-defaults"],
+}
+
+java_library {
+    name: "service-connectivity",
+    srcs: [
+        ":connectivity-service-srcs",
+    ],
+    installable: true,
+    jarjar_rules: "jarjar-rules.txt",
+    libs: [
+        "android.net.ipsec.ike",
+        "services.core",
+        "services.net",
+        "unsupportedappusage",
+    ],
+    static_libs: [
+        "net-utils-device-common",
+        "net-utils-framework-common",
+    ],
+    apex_available: [
+        "//apex_available:platform",
+    ],
+}
diff --git a/packages/Connectivity/service/jarjar-rules.txt b/packages/Connectivity/service/jarjar-rules.txt
new file mode 100644
index 0000000..ef53ebb
--- /dev/null
+++ b/packages/Connectivity/service/jarjar-rules.txt
@@ -0,0 +1 @@
+rule com.android.net.module.util.** com.android.connectivity.util.@1
\ No newline at end of file
diff --git a/services/core/jni/com_android_server_TestNetworkService.cpp b/packages/Connectivity/service/jni/com_android_server_TestNetworkService.cpp
similarity index 100%
rename from services/core/jni/com_android_server_TestNetworkService.cpp
rename to packages/Connectivity/service/jni/com_android_server_TestNetworkService.cpp
diff --git a/services/core/jni/com_android_server_connectivity_Vpn.cpp b/packages/Connectivity/service/jni/com_android_server_connectivity_Vpn.cpp
similarity index 99%
rename from services/core/jni/com_android_server_connectivity_Vpn.cpp
rename to packages/Connectivity/service/jni/com_android_server_connectivity_Vpn.cpp
index 836d6d8..ea5e718 100644
--- a/services/core/jni/com_android_server_connectivity_Vpn.cpp
+++ b/packages/Connectivity/service/jni/com_android_server_connectivity_Vpn.cpp
@@ -34,6 +34,7 @@
 #include <sys/types.h>
 
 #include <log/log.h>
+#include <android/log.h>
 
 #include "netutils/ifc.h"
 
diff --git a/packages/Connectivity/service/jni/onload.cpp b/packages/Connectivity/service/jni/onload.cpp
new file mode 100644
index 0000000..3afcb0e
--- /dev/null
+++ b/packages/Connectivity/service/jni/onload.cpp
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+
+#include <nativehelper/JNIHelp.h>
+#include <log/log.h>
+
+namespace android {
+
+int register_android_server_connectivity_Vpn(JNIEnv* env);
+int register_android_server_TestNetworkService(JNIEnv* env);
+
+extern "C" jint JNI_OnLoad(JavaVM* vm, void*) {
+    JNIEnv *env;
+    if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
+        ALOGE("GetEnv failed");
+        return JNI_ERR;
+    }
+
+    if (register_android_server_connectivity_Vpn(env) < 0
+        || register_android_server_TestNetworkService(env) < 0) {
+        return JNI_ERR;
+    }
+
+    return JNI_VERSION_1_6;
+}
+
+};
\ No newline at end of file
diff --git a/packages/DynamicSystemInstallationService/OWNERS b/packages/DynamicSystemInstallationService/OWNERS
new file mode 100644
index 0000000..c1b7ec4
--- /dev/null
+++ b/packages/DynamicSystemInstallationService/OWNERS
@@ -0,0 +1,3 @@
+howardsoc@google.com
+pchsueh@google.com
+yochiang@google.com
diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java
index ac27580..a4896cb2 100644
--- a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java
+++ b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java
@@ -211,10 +211,10 @@
 
     @Override
     public void onProgressUpdate(InstallationAsyncTask.Progress progress) {
-        mCurrentPartitionName = progress.mPartitionName;
-        mCurrentPartitionSize = progress.mPartitionSize;
-        mCurrentPartitionInstalledSize = progress.mInstalledSize;
-        mNumInstalledPartitions = progress.mNumInstalledPartitions;
+        mCurrentPartitionName = progress.partitionName;
+        mCurrentPartitionSize = progress.partitionSize;
+        mCurrentPartitionInstalledSize = progress.installedSize;
+        mNumInstalledPartitions = progress.numInstalledPartitions;
 
         postStatus(STATUS_IN_PROGRESS, CAUSE_NOT_SPECIFIED, null);
     }
diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java
index 4d31ce9..ac73f35 100644
--- a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java
+++ b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java
@@ -102,20 +102,16 @@
     static final int RESULT_ERROR_UNSUPPORTED_FORMAT = 5;
     static final int RESULT_ERROR_EXCEPTION = 6;
 
-    class Progress {
-        String mPartitionName;
-        long mPartitionSize;
-        long mInstalledSize;
+    static class Progress {
+        public final String partitionName;
+        public final long partitionSize;
+        public final int numInstalledPartitions;
+        public long installedSize;
 
-        int mNumInstalledPartitions;
-
-        Progress(String partitionName, long partitionSize, long installedSize,
-                int numInstalled) {
-            mPartitionName = partitionName;
-            mPartitionSize = partitionSize;
-            mInstalledSize = installedSize;
-
-            mNumInstalledPartitions = numInstalled;
+        Progress(String partitionName, long partitionSize, int numInstalledPartitions) {
+            this.partitionName = partitionName;
+            this.partitionSize = partitionSize;
+            this.numInstalledPartitions = numInstalledPartitions;
         }
     }
 
@@ -141,6 +137,8 @@
     private boolean mIsZip;
     private boolean mIsCompleted;
 
+    private int mNumInstalledPartitions;
+
     private InputStream mStream;
     private ZipFile mZipFile;
 
@@ -312,18 +310,17 @@
         Log.d(TAG, "Creating partition: userdata");
         thread.start();
 
-        long installedSize = 0;
-        Progress progress = new Progress("userdata", mUserdataSize, installedSize, 0);
+        Progress progress = new Progress("userdata", mUserdataSize, mNumInstalledPartitions++);
 
         while (thread.isAlive()) {
             if (isCancelled()) {
                 return;
             }
 
-            installedSize = mDynSystem.getInstallationProgress().bytes_processed;
+            final long installedSize = mDynSystem.getInstallationProgress().bytes_processed;
 
-            if (installedSize > progress.mInstalledSize + MIN_PROGRESS_TO_PUBLISH) {
-                progress.mInstalledSize = installedSize;
+            if (installedSize > progress.installedSize + MIN_PROGRESS_TO_PUBLISH) {
+                progress.installedSize = installedSize;
                 publishProgress(progress);
             }
 
@@ -357,7 +354,7 @@
     private void installStreamingGzUpdate()
             throws IOException, InterruptedException, ImageValidationException {
         Log.d(TAG, "To install a streaming GZ update");
-        installImage("system", mSystemSize, new GZIPInputStream(mStream), 1);
+        installImage("system", mSystemSize, new GZIPInputStream(mStream));
     }
 
     private void installStreamingZipUpdate()
@@ -367,12 +364,8 @@
         ZipInputStream zis = new ZipInputStream(mStream);
         ZipEntry zipEntry = null;
 
-        int numInstalledPartitions = 1;
-
         while ((zipEntry = zis.getNextEntry()) != null) {
-            if (installImageFromAnEntry(zipEntry, zis, numInstalledPartitions)) {
-                numInstalledPartitions++;
-            }
+            installImageFromAnEntry(zipEntry, zis);
 
             if (isCancelled()) {
                 break;
@@ -385,14 +378,10 @@
         Log.d(TAG, "To install a local ZIP update");
 
         Enumeration<? extends ZipEntry> entries = mZipFile.entries();
-        int numInstalledPartitions = 1;
 
         while (entries.hasMoreElements()) {
             ZipEntry entry = entries.nextElement();
-            if (installImageFromAnEntry(
-                    entry, mZipFile.getInputStream(entry), numInstalledPartitions)) {
-                numInstalledPartitions++;
-            }
+            installImageFromAnEntry(entry, mZipFile.getInputStream(entry));
 
             if (isCancelled()) {
                 break;
@@ -400,8 +389,7 @@
         }
     }
 
-    private boolean installImageFromAnEntry(
-            ZipEntry entry, InputStream is, int numInstalledPartitions)
+    private boolean installImageFromAnEntry(ZipEntry entry, InputStream is)
             throws IOException, InterruptedException, ImageValidationException {
         String name = entry.getName();
 
@@ -420,13 +408,12 @@
 
         long uncompressedSize = entry.getSize();
 
-        installImage(partitionName, uncompressedSize, is, numInstalledPartitions);
+        installImage(partitionName, uncompressedSize, is);
 
         return true;
     }
 
-    private void installImage(
-            String partitionName, long uncompressedSize, InputStream is, int numInstalledPartitions)
+    private void installImage(String partitionName, long uncompressedSize, InputStream is)
             throws IOException, InterruptedException, ImageValidationException {
 
         SparseInputStream sis = new SparseInputStream(new BufferedInputStream(is));
@@ -473,10 +460,9 @@
 
         mInstallationSession.setAshmem(pfd, READ_BUFFER_SIZE);
 
-        long installedSize = 0;
-        Progress progress = new Progress(
-                partitionName, partitionSize, installedSize, numInstalledPartitions);
+        Progress progress = new Progress(partitionName, partitionSize, mNumInstalledPartitions++);
 
+        long installedSize = 0;
         byte[] bytes = new byte[READ_BUFFER_SIZE];
         int numBytesRead;
 
@@ -493,8 +479,8 @@
 
             installedSize += numBytesRead;
 
-            if (installedSize > progress.mInstalledSize + MIN_PROGRESS_TO_PUBLISH) {
-                progress.mInstalledSize = installedSize;
+            if (installedSize > progress.installedSize + MIN_PROGRESS_TO_PUBLISH) {
+                progress.installedSize = installedSize;
                 publishProgress(progress);
             }
         }
diff --git a/packages/OsuLogin/Android.bp b/packages/OsuLogin/Android.bp
deleted file mode 100644
index 445c81b..0000000
--- a/packages/OsuLogin/Android.bp
+++ /dev/null
@@ -1,18 +0,0 @@
-android_app {
-    name: "OsuLogin",
-    defaults: ["wifi-module-sdk-version-defaults"],
-    static_libs: ["androidx.legacy_legacy-support-v4"],
-    resource_dirs: ["res"],
-    srcs: ["src/**/*.java"],
-    sdk_version: "system_current",
-    certificate: ":com.android.hotspot2.osulogin.certificate",
-    apex_available: [
-        "com.android.wifi",
-        "test_com.android.wifi",
-    ],
-}
-
-android_app_certificate {
-    name: "com.android.hotspot2.osulogin.certificate",
-    certificate: "certs/com.android.hotspot2.osulogin"
-}
diff --git a/packages/OsuLogin/AndroidManifest.xml b/packages/OsuLogin/AndroidManifest.xml
deleted file mode 100644
index a428cb3..0000000
--- a/packages/OsuLogin/AndroidManifest.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.hotspot2.osulogin">
-    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
-    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
-    <uses-permission android:name="android.permission.INTERNET"/>
-
-    <application
-        android:networkSecurityConfig="@xml/network_security_config"
-        android:enabled="true"
-        android:label="@string/app_name"
-        android:configChanges="keyboardHidden|orientation|screenSize"
-        android:supportsRtl="true">
-        <activity android:name="com.android.hotspot2.osulogin.OsuLoginActivity"
-                  android:label="@string/action_bar_label"
-                  android:theme="@style/AppTheme"
-                  android:configChanges="keyboardHidden|orientation|screenSize">
-            <intent-filter>
-                <action android:name="android.net.wifi.action.PASSPOINT_LAUNCH_OSU_VIEW"/>
-                <category android:name="android.intent.category.DEFAULT"/>
-            </intent-filter>
-        </activity>
-    </application>
-</manifest>
diff --git a/packages/OsuLogin/OWNERS b/packages/OsuLogin/OWNERS
deleted file mode 100644
index aa7c3e6..0000000
--- a/packages/OsuLogin/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-satk@google.com
-etancohen@google.com
diff --git a/packages/OsuLogin/certs/com.android.hotspot2.osulogin.pk8 b/packages/OsuLogin/certs/com.android.hotspot2.osulogin.pk8
deleted file mode 100644
index 87fd622..0000000
--- a/packages/OsuLogin/certs/com.android.hotspot2.osulogin.pk8
+++ /dev/null
Binary files differ
diff --git a/packages/OsuLogin/certs/com.android.hotspot2.osulogin.x509.pem b/packages/OsuLogin/certs/com.android.hotspot2.osulogin.x509.pem
deleted file mode 100644
index 1dfe701..0000000
--- a/packages/OsuLogin/certs/com.android.hotspot2.osulogin.x509.pem
+++ /dev/null
@@ -1,35 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIGDzCCA/egAwIBAgIUHzkh0UCF/H+1mZZp0ROX4nXKOUowDQYJKoZIhvcNAQEL
-BQAwgZUxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQH
-DA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAwDgYDVQQLDAdBbmRy
-b2lkMREwDwYDVQQDDAhPc3VMb2dpbjEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBh
-bmRyb2lkLmNvbTAgFw0yMDAzMjUwMjQ5MTNaGA80NzU4MDIxOTAyNDkxM1owgZUx
-CzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1Nb3Vu
-dGFpbiBWaWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAwDgYDVQQLDAdBbmRyb2lkMREw
-DwYDVQQDDAhPc3VMb2dpbjEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lk
-LmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMJDnjAeIZ2KUvKc
-ONwxuzIhLvXr6LRm+Uz0ebjz++5IzQJLwr/COPBG9zbIm8izj2acp+l4WVEYT6I4
-Es5LEp556ySCuZx8IjOd0Zd6NCdaKmYouDTjYTrELWUlZjfA7Km2L5x2M6ArnDO5
-zJ1BIsQ06S3C7iR3ktAQ1cFdidg6Ha2gainS0A1JKN3kL9BL1pvHRLzWZX4gsNhB
-C/6Ue3W3Sx2JRQkaaLksDdoKq0QswEk5tGfKbVr9+hHv/pztaaqEXSeV6f305cAx
-Hzd6+QJ8f8AJz2Rhnv43y72UO8b02CSP3laUj8geidR8XXw+R7Kzu8NfFDL7uVIh
-ktPaBxfWPNYtedp3JrGeZhkzljsushY+bVHECEzROhY2CiUZBEn+wwZLWe2W7oee
-VCL1EZBYctK5CfrrV6x0wvbBUF/ViwV+2LQXQNp08xB8bJBqoBn4KZjK0tTN86Dq
-qRALyoVIVh5VDU9Wbi3vrJb0/9TEQtMjuo0DS3hdtnowdRyAyhwbQHO26dqnnzBI
-XtTAve4RkOwnb8QzZde56qvRgweDE9Im1jpx4E+MMGqVYs8Txurmd/t6bCjTvp1P
-4i88crk/zqCoHEQEbiaNdfkULJAWg9wqxPjqPCTVNtOXoJwuHsNymQVSztIUSySz
-ZQ8Trk0ApqQf8yH2mjM6HJJZoNpBAgMBAAGjUzBRMB0GA1UdDgQWBBRdpduh1P+I
-BMbg5S4n1kbj5hQsOzAfBgNVHSMEGDAWgBRdpduh1P+IBMbg5S4n1kbj5hQsOzAP
-BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4ICAQB+FzSuoA7LCvn8l86V
-sSI4lH1KLLH+wrXp20w/wYcBY+s4hYPpAJ8YbEMOT9uibK/HpEWYFqiVCqk4gKXr
-Qraxvmtqq0WNSwkjeopTYlZeBzTC/If3UoOCp7KCfMdydIcxvk6LNokMWWqSCNP8
-QiD872XuBvj/uQeBsbHZTqruqPnu+LZwpuHFVRp/Pyj9rT61PsvGitb7q/chW0G7
-7csHOc5q2223LKlNknPsfbcR6nVEg4KfN7kPKny8iJtl2pdbfBjFDp+73nzW8qZU
-5JWO5nWL7cJh4mt5sPGrzpt/Hf8/Dngg69sImRqjv/6/wCV0pEmmNjKJkXcMaZ0T
-2TSs+A7K6l15NYk8exkMymTU7jk+iDud3tnQ68YHf/A9pDu15OCw6U/pTgOgu9co
-rBLLhGV0Tb6XAnsWKe9tsLcumQXU5ZUn9m5VJl58wQHNhUqpT7L0fWtpiTMTStVA
-/yZbndPO4SbjR5rjcAk1xge8lyIIp0WBWmwoQ/1y4DXF/yPaX733wO7uWUljgKuy
-MM/zM4zklB8nFjXfPNf3j24Bzqmy7rqy4XB64enVmYQ2mVNqfwXvINoo2XOrAmj/
-bhSWXiCFltJFM7fmJGOMEEHBt9QfbmCgmM4aoWMgH7P+HxGW+Vc3tGixBbsxNRC+
-/VrPAINQV4x5q8zGYNQBqNFn/A==
------END CERTIFICATE-----
diff --git a/packages/OsuLogin/certs/key.pem b/packages/OsuLogin/certs/key.pem
deleted file mode 100644
index f560a8d..0000000
--- a/packages/OsuLogin/certs/key.pem
+++ /dev/null
@@ -1,52 +0,0 @@
------BEGIN PRIVATE KEY-----
-MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQDCQ54wHiGdilLy
-nDjcMbsyIS716+i0ZvlM9Hm48/vuSM0CS8K/wjjwRvc2yJvIs49mnKfpeFlRGE+i
-OBLOSxKeeeskgrmcfCIzndGXejQnWipmKLg042E6xC1lJWY3wOypti+cdjOgK5wz
-ucydQSLENOktwu4kd5LQENXBXYnYOh2toGop0tANSSjd5C/QS9abx0S81mV+ILDY
-QQv+lHt1t0sdiUUJGmi5LA3aCqtELMBJObRnym1a/foR7/6c7WmqhF0nlen99OXA
-MR83evkCfH/ACc9kYZ7+N8u9lDvG9Ngkj95WlI/IHonUfF18Pkeys7vDXxQy+7lS
-IZLT2gcX1jzWLXnadyaxnmYZM5Y7LrIWPm1RxAhM0ToWNgolGQRJ/sMGS1ntlu6H
-nlQi9RGQWHLSuQn661esdML2wVBf1YsFfti0F0DadPMQfGyQaqAZ+CmYytLUzfOg
-6qkQC8qFSFYeVQ1PVm4t76yW9P/UxELTI7qNA0t4XbZ6MHUcgMocG0Bztunap58w
-SF7UwL3uEZDsJ2/EM2XXueqr0YMHgxPSJtY6ceBPjDBqlWLPE8bq5nf7emwo076d
-T+IvPHK5P86gqBxEBG4mjXX5FCyQFoPcKsT46jwk1TbTl6CcLh7DcpkFUs7SFEsk
-s2UPE65NAKakH/Mh9pozOhySWaDaQQIDAQABAoICAGgX7XKhIqgVD59aoIk0yLby
-2wQBdf780ocu1O6LJiqnrdqWF/PCsdnmXN9pHTitJqD4Pm03BL0Uhs9ItqL9zStH
-7vzwY177kSQRY9aEL+AKS3/UP+hvEpF3v09ce+pSIT5LFjYDjGQ+GgQJgh+dYHC8
-XVodAphdzjhZXQCxC4TmlzKLK3ffs4X69r/3XruBd6yfWTDKvTWZdMlcCX5Pt9v6
-7HAWNvzKvuTCO2Xjo6PzStGx7v5SlMhWISJtdARInv80z+m/RdPD3zxd1flXloiD
-h7yyRQPn31cfNLgP7vwMBKmKwbuo/WZhHr/SKBHEGY0jC/CDSQKMqd/dh5ynTnbC
-vi/qjKFIHofmhzgQ+fiHMeMsAO1c9eYs8a6bDeJjhA5qJP1HjSie9Ss9z94mp6Ww
-TRkU93yVX04DU4TCCf0IcFpKdbtKp84i6iLV9lKGh9juM42hSOFUV6bhxmlJ9zvM
-yl7vfhhuFHy1SypmaK/oJ+nwac4vIMaHCX9ifl6hm/z4PrGFSYJGQoJtVOz0vT15
-lSwCJVdHkGAe0LI+3iFn5jJlluD7TqsLmZLxqTTmzDZ3U9WhAslmn5TcZd92mL0i
-ZVTfCkjyl1wUHeif2992oTUH6CFZ1jKd8xwdWvyKkvQcjhiS9GUsm7j6jolR/QI7
-VPQlocM/vCCusrMWnR7xAoIBAQDv9O8kboz6WzN6Xw5UC7MWpi2jZg1bTs/uKcfz
-biAEC96iJQ33YSkYi6QzV4jSaackU99vGkHbQIdaBTkudz+FK5XqH0auImB2xxcR
-Xu9G2j2fhzESchVTtOnotVgjiuv18SLZ/GQoSIccs0QxcisPiTa5Ij9pl8xVoS6J
-sxfqAe15hASqLh+9Ula3+Orb1kCkqK0UwU0nM9nfUH88BKvUwQIMA7kipTA8jJog
-MJOlYPQUGxkltlim8Vip//P336E7CWT6fWbfo62US6IEu6HcC6T8u8jcLjIKsmjJ
-YJyqrepZqAVMPlv2Z+mNhxRR0ct6blfjJSrEZEtxBRn98kZ1AoIBAQDPQJ1z7Mfy
-AOfjSO6Dlfr7V9SWmGvexosH0gu6H8KO+n1/ZPH5fHGt7ORubUDhkNI/fqZK0Hls
-Q9Jwgq1QI9UwMTogF8DgmZ6L6jiXhUScIk0BFhUxOBoplugaI0jdTW350D2quFUJ
-LjYo+VcRapTfXXVehHSjbUh3nmTWj0WboA+//7xq8q9KHPb1Sbiwjf7N1iYD5R8p
-PaaG0DMET+l90bxI+QVX1enwjZGcFjo8VI+qXGGkpB/1zK5yWm29ZWypLw8TZreM
-7rLUdBY1/m7MB54zOaJ2jSsxLQSXIVSGPI1ugkmFr6OxeuLdcCLN4yca3+HYHewa
-w3GCBP3kfYMdAoIBAAxG0slhYpMYgWy8WkZQhuwcum8GtJ48TQUZXCKHOtoaJVzU
-Wn+SmACqfE8oJlblkuiX5fGQPVhTV9lyNPe8oCJXFYdx7DLSjW7mRrbbzZApcEeu
-KgOQlKjAs8r1JDpFTEc7/BV9BT7OXyNHxLBm7+8OjR8xsl7bplenNHNVF18glB7I
-c1ilnXgZM1icQp/WuV3zR0+tiB3+WCJFwwy2DHiJG2qz8g/ktbATXXtSIOuwJyy0
-Kjg0uRppdKjV8Ix5A426sFDkg5PjkujoabSmSOSyL9HCZcdmEadcc2ICMGHHHhtS
-Lls1QY08ycU06QQ6oJd198cmSqbbnsR8h1TnxVUCggEBAI2zF/QSiAImLGVxj+HX
-wWnneyobvGTsSlJmgi4XWOZ4zSU011xEgVTxCp2VhS6z3YwcA4ZTUzF6jX7vWZ/Z
-YAE7JwqaMv1dCtGOqnKuY2J88Tk05/hm6zxUOQzl4wOr1O1gO0lmDn3gYpdRIv59
-aJvvQjgFR9oU9d8TJM6t1mG45gvXxfM5Si/Z7d93MBdGflgteoBfPxbrV9gEsVzZ
-ZkLoC1u5JrYPQ4t8v3mAmQB2sGNCFmCC9ncQIpV8zlsX5VsnGZ+iMwzghtRLKoRw
-GUDWVIuhdDqp+kX9CY5q82d0Lx7HZY1JsRm/cy0DZkhubmYpfDhO/QavagQDdbOr
-POECggEAXOliqX4yFvy6USXihHVM44s63gK+yH0+0iRppqoB3+E5tDyhvvvBMPLZ
-7EBkhd7ILTDXbc0c8nSl8I/556YSlIaOB4Xbf4UQbsmD4fNGEnNWFbCzcEWYOjpQ
-5QyXjIzK/k8eg22OZlC3XNjGHgb/mA5f+v2enGQNuy7WRTl1mKYZB2h/2p6xy+jV
-CGhd4btB2bOu+1XR/B2KFvI5NdtPPti05LmsYgsU00yYJfQkpc7VvOSH5Jyy3eZL
-L9xTAy7NWBQ3LGdIpX+V1jcn3SzVits0m6hOUCtJLT1snMXAKFweTvWAQynuGomc
-VPf88ITMTOBjOH6YC8jKd/n2lVWLjw==
------END PRIVATE KEY-----
diff --git a/packages/OsuLogin/res/layout/osu_web_view.xml b/packages/OsuLogin/res/layout/osu_web_view.xml
deleted file mode 100644
index 4436aab..0000000
--- a/packages/OsuLogin/res/layout/osu_web_view.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-             xmlns:tools="http://schemas.android.com/tools"
-             android:id="@+id/container"
-             android:layout_width="match_parent"
-             android:layout_height="match_parent"
-             tools:context="com.android.hotspot2.osulogin.OsuLoginActivity">
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:orientation="vertical">
-        <FrameLayout
-            android:layout_width="match_parent"
-            android:layout_height="4dp">
-
-            <!-- Eliminates ProgressBar padding by boxing it into a 4dp high container -->
-            <ProgressBar
-                android:id="@+id/progress_bar"
-                style="@android:style/Widget.Material.Light.ProgressBar.Horizontal"
-                android:indeterminate="false"
-                android:max="100"
-                android:progress="0"
-                android:layout_gravity="center"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"/>
-        </FrameLayout>
-        <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
-            android:id="@+id/swipe_refresh"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent">
-        <WebView
-            android:id="@+id/webview"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:layout_alignParentBottom="false"
-            android:layout_alignParentRight="false"/>
-        </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
-    </LinearLayout>
-</FrameLayout>
diff --git a/packages/OsuLogin/res/values-af/strings.xml b/packages/OsuLogin/res/values-af/strings.xml
deleted file mode 100644
index bfeee10..0000000
--- a/packages/OsuLogin/res/values-af/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Sluit aanlyn aan"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Kon nie aanmeld nie"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-am/strings.xml b/packages/OsuLogin/res/values-am/strings.xml
deleted file mode 100644
index e27c578..0000000
--- a/packages/OsuLogin/res/values-am/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"የመስመር ላይ ምዝገባ"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"ምዝገባ አልተሳካም"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ar/strings.xml b/packages/OsuLogin/res/values-ar/strings.xml
deleted file mode 100644
index b72d7c1..0000000
--- a/packages/OsuLogin/res/values-ar/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"الاشتراك على الإنترنت"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"تعذّر الاشتراك."</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-as/strings.xml b/packages/OsuLogin/res/values-as/strings.xml
deleted file mode 100644
index 422de32..0000000
--- a/packages/OsuLogin/res/values-as/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"অনলাইনত ছাই আপ কৰক"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"ছাইন আপ কৰিব পৰা নগ’ল"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-az/strings.xml b/packages/OsuLogin/res/values-az/strings.xml
deleted file mode 100644
index 977f939..0000000
--- a/packages/OsuLogin/res/values-az/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Onlayn Qeydiyyat"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Qeydiyyat alınmadı"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-b+sr+Latn/strings.xml b/packages/OsuLogin/res/values-b+sr+Latn/strings.xml
deleted file mode 100644
index 6eb2cc1..0000000
--- a/packages/OsuLogin/res/values-b+sr+Latn/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Onlajn registracija"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Registracija nije uspela"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-be/strings.xml b/packages/OsuLogin/res/values-be/strings.xml
deleted file mode 100644
index 158c3f2..0000000
--- a/packages/OsuLogin/res/values-be/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Зарэгістравацца ў інтэрнэце"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Не ўдалося зарэгістравацца"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-bg/strings.xml b/packages/OsuLogin/res/values-bg/strings.xml
deleted file mode 100644
index ea3145d..0000000
--- a/packages/OsuLogin/res/values-bg/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Онлайн регистрация"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Регистрацията не бе успешна"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-bn/strings.xml b/packages/OsuLogin/res/values-bn/strings.xml
deleted file mode 100644
index c9f615e..0000000
--- a/packages/OsuLogin/res/values-bn/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"অনলাইনে সাইন-আপ করুন"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"সাইন-আপ করা যায়নি"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-bs/strings.xml b/packages/OsuLogin/res/values-bs/strings.xml
deleted file mode 100644
index e9b9751..0000000
--- a/packages/OsuLogin/res/values-bs/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Online registracija"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Registracija nije uspjela"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ca/strings.xml b/packages/OsuLogin/res/values-ca/strings.xml
deleted file mode 100644
index 7d93096..0000000
--- a/packages/OsuLogin/res/values-ca/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Registre en línia"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Ha fallat el registre"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-cs/strings.xml b/packages/OsuLogin/res/values-cs/strings.xml
deleted file mode 100644
index b9cb794..0000000
--- a/packages/OsuLogin/res/values-cs/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Online registrace"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Registrace selhala"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-da/strings.xml b/packages/OsuLogin/res/values-da/strings.xml
deleted file mode 100644
index 68c93b7..0000000
--- a/packages/OsuLogin/res/values-da/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Online registrering"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Registrering mislykkedes"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-de/strings.xml b/packages/OsuLogin/res/values-de/strings.xml
deleted file mode 100644
index 7e5a310..0000000
--- a/packages/OsuLogin/res/values-de/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Online-Registrierung"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Registrierung fehlgeschlagen"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-el/strings.xml b/packages/OsuLogin/res/values-el/strings.xml
deleted file mode 100644
index a58e481..0000000
--- a/packages/OsuLogin/res/values-el/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Εγγραφή στο διαδίκτυο"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Αποτυχία εγγραφής"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-en-rAU/strings.xml b/packages/OsuLogin/res/values-en-rAU/strings.xml
deleted file mode 100644
index fbbcab1..0000000
--- a/packages/OsuLogin/res/values-en-rAU/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Online sign-up"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Sign-up failed"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-en-rCA/strings.xml b/packages/OsuLogin/res/values-en-rCA/strings.xml
deleted file mode 100644
index fbbcab1..0000000
--- a/packages/OsuLogin/res/values-en-rCA/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Online sign-up"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Sign-up failed"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-en-rGB/strings.xml b/packages/OsuLogin/res/values-en-rGB/strings.xml
deleted file mode 100644
index fbbcab1..0000000
--- a/packages/OsuLogin/res/values-en-rGB/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Online sign-up"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Sign-up failed"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-en-rIN/strings.xml b/packages/OsuLogin/res/values-en-rIN/strings.xml
deleted file mode 100644
index fbbcab1..0000000
--- a/packages/OsuLogin/res/values-en-rIN/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Online sign-up"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Sign-up failed"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-en-rXC/strings.xml b/packages/OsuLogin/res/values-en-rXC/strings.xml
deleted file mode 100644
index af7ff67..0000000
--- a/packages/OsuLogin/res/values-en-rXC/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‎‎‏‎‏‏‏‎‏‏‎‏‎‏‏‏‏‎‎‏‏‏‎‏‎‏‎‏‏‎‎‎‏‎‏‎‏‏‎‎‎‎‏‎‏‏‎‏‎‎‏‎‏‎OsuLogin‎‏‎‎‏‎"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‏‏‎‏‎‎‏‎‏‏‎‎‎‎‏‏‏‏‎‎‎‏‎‏‎‏‏‏‏‎‏‏‎‏‏‏‏‏‎‎‏‎‎‎‏‎‎‏‎‎‏‎‏‎‏‎‏‎Online Sign Up‎‏‎‎‏‎"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‏‎‎‏‏‏‏‎‎‏‏‎‎‎‏‏‏‎‏‏‏‏‎‏‎‎‎‏‏‎‏‏‏‏‎‎‏‏‎‎‏‏‎‏‎‎‎‏‏‎‏‏‎‎‎‎‎Sign-up failed‎‏‎‎‏‎"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-es-rUS/strings.xml b/packages/OsuLogin/res/values-es-rUS/strings.xml
deleted file mode 100644
index 144804c..0000000
--- a/packages/OsuLogin/res/values-es-rUS/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Registrarse en línea"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Se produjo un error de registro"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-es/strings.xml b/packages/OsuLogin/res/values-es/strings.xml
deleted file mode 100644
index 3ad95cd..0000000
--- a/packages/OsuLogin/res/values-es/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Registro online"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Error al completar el registro"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-et/strings.xml b/packages/OsuLogin/res/values-et/strings.xml
deleted file mode 100644
index 94c5cea..0000000
--- a/packages/OsuLogin/res/values-et/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Veebis registreerimine"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Registreerimine ebaõnnestus"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-eu/strings.xml b/packages/OsuLogin/res/values-eu/strings.xml
deleted file mode 100644
index 30caa87..0000000
--- a/packages/OsuLogin/res/values-eu/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Sarean izen-ematea"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Ezin izan da eman izena"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-fa/strings.xml b/packages/OsuLogin/res/values-fa/strings.xml
deleted file mode 100644
index 3005203..0000000
--- a/packages/OsuLogin/res/values-fa/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"ثبت‌نام آنلاین"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"ثبت‌نام انجام نشد"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-fi/strings.xml b/packages/OsuLogin/res/values-fi/strings.xml
deleted file mode 100644
index 24eac8a..0000000
--- a/packages/OsuLogin/res/values-fi/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Rekisteröidy verkossa"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Rekisteröityminen ei onnistunut"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-fr-rCA/strings.xml b/packages/OsuLogin/res/values-fr-rCA/strings.xml
deleted file mode 100644
index bcaa662..0000000
--- a/packages/OsuLogin/res/values-fr-rCA/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Inscription en ligne"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Échec de l\'inscription"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-fr/strings.xml b/packages/OsuLogin/res/values-fr/strings.xml
deleted file mode 100644
index bcaa662..0000000
--- a/packages/OsuLogin/res/values-fr/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Inscription en ligne"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Échec de l\'inscription"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-gl/strings.xml b/packages/OsuLogin/res/values-gl/strings.xml
deleted file mode 100644
index 5fc4444..0000000
--- a/packages/OsuLogin/res/values-gl/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Rexistro en liña"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Produciuse un erro co rexistro"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-gu/strings.xml b/packages/OsuLogin/res/values-gu/strings.xml
deleted file mode 100644
index 8449963..0000000
--- a/packages/OsuLogin/res/values-gu/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"ઑનલાઇન સાઇન અપ કરો"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"સાઇન અપ નિષ્ફળ"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-hi/strings.xml b/packages/OsuLogin/res/values-hi/strings.xml
deleted file mode 100644
index 9e07438..0000000
--- a/packages/OsuLogin/res/values-hi/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"ऑनलाइन साइन अप करें"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"साइन अप नहीं किया जा सका"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-hr/strings.xml b/packages/OsuLogin/res/values-hr/strings.xml
deleted file mode 100644
index e9b9751..0000000
--- a/packages/OsuLogin/res/values-hr/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Online registracija"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Registracija nije uspjela"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-hu/strings.xml b/packages/OsuLogin/res/values-hu/strings.xml
deleted file mode 100644
index cb0e036..0000000
--- a/packages/OsuLogin/res/values-hu/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Online regisztráció"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"A regisztráció nem sikerült"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-hy/strings.xml b/packages/OsuLogin/res/values-hy/strings.xml
deleted file mode 100644
index ae1c36a..0000000
--- a/packages/OsuLogin/res/values-hy/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Առցանց գրանցում"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Չհաջողվեց գրանցվել"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-in/strings.xml b/packages/OsuLogin/res/values-in/strings.xml
deleted file mode 100644
index 6aaf694..0000000
--- a/packages/OsuLogin/res/values-in/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Pendaftaran Online"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Pendaftaran gagal"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-is/strings.xml b/packages/OsuLogin/res/values-is/strings.xml
deleted file mode 100644
index f1ae520..0000000
--- a/packages/OsuLogin/res/values-is/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Skráning á netinu"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Skráning mistókst"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-it/strings.xml b/packages/OsuLogin/res/values-it/strings.xml
deleted file mode 100644
index fbff7b0..0000000
--- a/packages/OsuLogin/res/values-it/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Registrazione online"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Registrazione non riuscita"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-iw/strings.xml b/packages/OsuLogin/res/values-iw/strings.xml
deleted file mode 100644
index 866ef88..0000000
--- a/packages/OsuLogin/res/values-iw/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"הרשמה אונליין"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"ההרשמה נכשלה"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ja/strings.xml b/packages/OsuLogin/res/values-ja/strings.xml
deleted file mode 100644
index 8a220d6..0000000
--- a/packages/OsuLogin/res/values-ja/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"オンライン登録"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"登録できませんでした"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ka/strings.xml b/packages/OsuLogin/res/values-ka/strings.xml
deleted file mode 100644
index bf08006..0000000
--- a/packages/OsuLogin/res/values-ka/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"ონლაინ რეგისტრაცია"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"რეგისტრაცია ვერ მოხერხდა"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-kk/strings.xml b/packages/OsuLogin/res/values-kk/strings.xml
deleted file mode 100644
index 8b87356..0000000
--- a/packages/OsuLogin/res/values-kk/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Онлайн тіркелу"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Тіркелмеді."</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-km/strings.xml b/packages/OsuLogin/res/values-km/strings.xml
deleted file mode 100644
index f58ccc3..0000000
--- a/packages/OsuLogin/res/values-km/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"ការចុះឈ្មោះ​លើអ៊ីនធឺណិត"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"ការចុះឈ្មោះ​មិនបានសម្រេច"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-kn/strings.xml b/packages/OsuLogin/res/values-kn/strings.xml
deleted file mode 100644
index 49a6562..0000000
--- a/packages/OsuLogin/res/values-kn/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"ಆನ್‌ಲೈನ್ ಸೈನ್ ಅಪ್"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"ಸೈನ್ ಅಪ್ ವಿಫಲವಾಗಿದೆ"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ko/strings.xml b/packages/OsuLogin/res/values-ko/strings.xml
deleted file mode 100644
index e647ca0..0000000
--- a/packages/OsuLogin/res/values-ko/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"온라인 가입"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"가입에 실패했습니다."</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ky/strings.xml b/packages/OsuLogin/res/values-ky/strings.xml
deleted file mode 100644
index 42da248..0000000
--- a/packages/OsuLogin/res/values-ky/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Интернет аркылуу катталуу"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Катталган жоксуз"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-lo/strings.xml b/packages/OsuLogin/res/values-lo/strings.xml
deleted file mode 100644
index 9ff2241..0000000
--- a/packages/OsuLogin/res/values-lo/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"ສະໝັກອອນລາຍ"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"ສະໝັກບໍ່ສຳເລັດ"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-lt/strings.xml b/packages/OsuLogin/res/values-lt/strings.xml
deleted file mode 100644
index 1a4c06e..0000000
--- a/packages/OsuLogin/res/values-lt/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Internetinis prisiregistravimas"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Nepavyko prisiregistruoti"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-lv/strings.xml b/packages/OsuLogin/res/values-lv/strings.xml
deleted file mode 100644
index 11cdb97..0000000
--- a/packages/OsuLogin/res/values-lv/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Reģistrācija tiešsaistē"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Reģistrācija neizdevās."</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-mk/strings.xml b/packages/OsuLogin/res/values-mk/strings.xml
deleted file mode 100644
index de608e1..0000000
--- a/packages/OsuLogin/res/values-mk/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Онлајн регистрација"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Регистрацијата не успеа"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ml/strings.xml b/packages/OsuLogin/res/values-ml/strings.xml
deleted file mode 100644
index 8e797c8..0000000
--- a/packages/OsuLogin/res/values-ml/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"ഓൺലെെൻ സെെൻ അപ്പ്"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"സൈൻ അപ്പ് ചെയ്യാനായില്ല"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-mn/strings.xml b/packages/OsuLogin/res/values-mn/strings.xml
deleted file mode 100644
index 59d79d0..0000000
--- a/packages/OsuLogin/res/values-mn/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Онлайнаар бүртгүүлэх"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Бүртгүүлж чадсангүй"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-mr/strings.xml b/packages/OsuLogin/res/values-mr/strings.xml
deleted file mode 100644
index 15479a6..0000000
--- a/packages/OsuLogin/res/values-mr/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"ऑनलाइन साइन अप करा"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"साइन-अप करता आले नाही"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ms/strings.xml b/packages/OsuLogin/res/values-ms/strings.xml
deleted file mode 100644
index 7e1cf95..0000000
--- a/packages/OsuLogin/res/values-ms/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Pendaftaran Dalam Talian"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Pendaftaran gagal"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-my/strings.xml b/packages/OsuLogin/res/values-my/strings.xml
deleted file mode 100644
index 1bd992e..0000000
--- a/packages/OsuLogin/res/values-my/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"အွန်လိုင်း အကောင့်ဖွင့်ရန်"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"အကောင့်ဖွင့်၍ မရပါ"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-nb/strings.xml b/packages/OsuLogin/res/values-nb/strings.xml
deleted file mode 100644
index 2e0c47a1..0000000
--- a/packages/OsuLogin/res/values-nb/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Registrering på nettet"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Registreringen mislyktes"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ne/strings.xml b/packages/OsuLogin/res/values-ne/strings.xml
deleted file mode 100644
index 16bd92f..0000000
--- a/packages/OsuLogin/res/values-ne/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"अनलाइन साइन अप"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"साइन अप गर्न सकिएन"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-nl/strings.xml b/packages/OsuLogin/res/values-nl/strings.xml
deleted file mode 100644
index 7cf8bd2..0000000
--- a/packages/OsuLogin/res/values-nl/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Online aanmelding"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Aanmelding mislukt"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-or/strings.xml b/packages/OsuLogin/res/values-or/strings.xml
deleted file mode 100644
index e0584d7..0000000
--- a/packages/OsuLogin/res/values-or/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"ଅନଲାଇନ୍ ସାଇନ୍ ଅପ୍ କରନ୍ତୁ"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"ସାଇନ୍ ଅପ୍ ବିଫଳ ହୋଇଛି"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-pa/strings.xml b/packages/OsuLogin/res/values-pa/strings.xml
deleted file mode 100644
index 7e47d0e..0000000
--- a/packages/OsuLogin/res/values-pa/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"ਆਨਲਾਈਨ ਸਾਈਨ-ਅੱਪ ਕਰੋ"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"ਸਾਈਨ-ਅੱਪ ਕਰਨਾ ਅਸਫਲ ਰਿਹਾ"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-pl/strings.xml b/packages/OsuLogin/res/values-pl/strings.xml
deleted file mode 100644
index c0722ab..0000000
--- a/packages/OsuLogin/res/values-pl/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Rejestracja online"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Nie udało się zarejestrować"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-pt-rBR/strings.xml b/packages/OsuLogin/res/values-pt-rBR/strings.xml
deleted file mode 100644
index c9fe377..0000000
--- a/packages/OsuLogin/res/values-pt-rBR/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Inscrição on-line"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Falha na inscrição"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-pt-rPT/strings.xml b/packages/OsuLogin/res/values-pt-rPT/strings.xml
deleted file mode 100644
index 0059281..0000000
--- a/packages/OsuLogin/res/values-pt-rPT/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Inscrição online"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Falha na inscrição."</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-pt/strings.xml b/packages/OsuLogin/res/values-pt/strings.xml
deleted file mode 100644
index c9fe377..0000000
--- a/packages/OsuLogin/res/values-pt/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Inscrição on-line"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Falha na inscrição"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ro/strings.xml b/packages/OsuLogin/res/values-ro/strings.xml
deleted file mode 100644
index eead127..0000000
--- a/packages/OsuLogin/res/values-ro/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Înscriere online"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Nu s-a înscris"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ru/strings.xml b/packages/OsuLogin/res/values-ru/strings.xml
deleted file mode 100644
index a271ef7..0000000
--- a/packages/OsuLogin/res/values-ru/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Регистрация в Интернете"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Не удалось зарегистрироваться."</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-si/strings.xml b/packages/OsuLogin/res/values-si/strings.xml
deleted file mode 100644
index 52e5979..0000000
--- a/packages/OsuLogin/res/values-si/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"සබැඳි ලියාපදිංචිය"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"ලියාපදිංචිය අසාර්ථක විය"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-sk/strings.xml b/packages/OsuLogin/res/values-sk/strings.xml
deleted file mode 100644
index f6b9f70..0000000
--- a/packages/OsuLogin/res/values-sk/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Online registrácia"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Registrácia zlyhala"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-sl/strings.xml b/packages/OsuLogin/res/values-sl/strings.xml
deleted file mode 100644
index 6e6b95c..0000000
--- a/packages/OsuLogin/res/values-sl/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Spletna registracija"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Registracija ni uspela"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-sq/strings.xml b/packages/OsuLogin/res/values-sq/strings.xml
deleted file mode 100644
index f67a238..0000000
--- a/packages/OsuLogin/res/values-sq/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Regjistrimi në linjë"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Regjistrimi dështoi"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-sr/strings.xml b/packages/OsuLogin/res/values-sr/strings.xml
deleted file mode 100644
index 14e0828..0000000
--- a/packages/OsuLogin/res/values-sr/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Онлајн регистрација"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Регистрација није успела"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-sv/strings.xml b/packages/OsuLogin/res/values-sv/strings.xml
deleted file mode 100644
index ea5fdfd..0000000
--- a/packages/OsuLogin/res/values-sv/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Registrering online"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Registreringen misslyckades"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-sw/strings.xml b/packages/OsuLogin/res/values-sw/strings.xml
deleted file mode 100644
index c20a402..0000000
--- a/packages/OsuLogin/res/values-sw/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Kujisajili Mtandaoni"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Imeshindwa kukusajili"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ta/strings.xml b/packages/OsuLogin/res/values-ta/strings.xml
deleted file mode 100644
index e2eb567..0000000
--- a/packages/OsuLogin/res/values-ta/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"ஆன்லைனில் பதிவு செய்"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"பதிவு செய்ய முடியவில்லை"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-te/strings.xml b/packages/OsuLogin/res/values-te/strings.xml
deleted file mode 100644
index 56b0b44..0000000
--- a/packages/OsuLogin/res/values-te/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"ఆన్‌లైన్ సైన్ అప్"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"సైన్-అప్ విఫలమయ్యింది"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-th/strings.xml b/packages/OsuLogin/res/values-th/strings.xml
deleted file mode 100644
index 552dca2..0000000
--- a/packages/OsuLogin/res/values-th/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"การลงชื่อสมัครใช้ออนไลน์"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"ลงชื่อสมัครใช้ไม่สำเร็จ"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-tl/strings.xml b/packages/OsuLogin/res/values-tl/strings.xml
deleted file mode 100644
index ba89e96..0000000
--- a/packages/OsuLogin/res/values-tl/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Pag-sign Up Online"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Hindi nakapag-sign up"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-tr/strings.xml b/packages/OsuLogin/res/values-tr/strings.xml
deleted file mode 100644
index 1d927fe..0000000
--- a/packages/OsuLogin/res/values-tr/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Online Kaydolma"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Kaydolma işlemi başarısız oldu"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-uk/strings.xml b/packages/OsuLogin/res/values-uk/strings.xml
deleted file mode 100644
index 6e60ff0..0000000
--- a/packages/OsuLogin/res/values-uk/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Онлайн-реєстрація"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Не вдалося зареєструватись"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ur/strings.xml b/packages/OsuLogin/res/values-ur/strings.xml
deleted file mode 100644
index eed7686..0000000
--- a/packages/OsuLogin/res/values-ur/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"آن لائن سائن اپ کریں"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"سائن اپ ناکام ہو گیا"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-uz/strings.xml b/packages/OsuLogin/res/values-uz/strings.xml
deleted file mode 100644
index 152d129..0000000
--- a/packages/OsuLogin/res/values-uz/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Onlayn registratsiya"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Registratsiya qilinmadi"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-vi/strings.xml b/packages/OsuLogin/res/values-vi/strings.xml
deleted file mode 100644
index 84558076..0000000
--- a/packages/OsuLogin/res/values-vi/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Đăng ký trực tuyến"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Không đăng ký được"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-zh-rCN/strings.xml b/packages/OsuLogin/res/values-zh-rCN/strings.xml
deleted file mode 100644
index 7f13647..0000000
--- a/packages/OsuLogin/res/values-zh-rCN/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"在线注册"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"注册失败"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-zh-rHK/strings.xml b/packages/OsuLogin/res/values-zh-rHK/strings.xml
deleted file mode 100644
index 8731791..0000000
--- a/packages/OsuLogin/res/values-zh-rHK/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"網上申請"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"無法申請"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-zh-rTW/strings.xml b/packages/OsuLogin/res/values-zh-rTW/strings.xml
deleted file mode 100644
index 79208c8..0000000
--- a/packages/OsuLogin/res/values-zh-rTW/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"線上註冊"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"註冊失敗"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-zu/strings.xml b/packages/OsuLogin/res/values-zu/strings.xml
deleted file mode 100644
index 27ac6bb..0000000
--- a/packages/OsuLogin/res/values-zu/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8288271429327488421">"I-OsuLogin"</string>
-    <string name="action_bar_label" msgid="550995560341508693">"Ukubhalisa Okuku-inthanethi"</string>
-    <string name="sign_up_failed" msgid="837216244603867568">"Ukubhalisa kuhlulekile"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values/dimens.xml b/packages/OsuLogin/res/values/dimens.xml
deleted file mode 100644
index 47c8224..0000000
--- a/packages/OsuLogin/res/values/dimens.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<resources>
-    <!-- Default screen margins, per the Android Design guidelines. -->
-    <dimen name="activity_horizontal_margin">16dp</dimen>
-    <dimen name="activity_vertical_margin">16dp</dimen>
-</resources>
diff --git a/packages/OsuLogin/res/values/strings.xml b/packages/OsuLogin/res/values/strings.xml
deleted file mode 100644
index 14de0f5..0000000
--- a/packages/OsuLogin/res/values/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<resources>
-    <!-- application name [CHAR LIMIT=32] -->
-    <string name="app_name">OsuLogin</string>
-    <!-- action bar label [CHAR LIMIT=32] -->
-    <string name="action_bar_label">Online Sign Up</string>
-    <!-- toast message [CHAR LIMIT=32] -->
-    <string name="sign_up_failed">Sign-up failed</string>
-</resources>
diff --git a/packages/OsuLogin/res/values/styles.xml b/packages/OsuLogin/res/values/styles.xml
deleted file mode 100644
index f6c2339..0000000
--- a/packages/OsuLogin/res/values/styles.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<resources>
-
-    <!--
-        Base application theme, dependent on API level. This theme is replaced
-        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
-    -->
-    <style name="AppBaseTheme" parent="@android:style/Theme.DeviceDefault.Settings">
-        <!--
-            Theme customizations available in newer API levels can go in
-            res/values-vXX/styles.xml, while customizations related to
-            backward-compatibility can go here.
-        -->
-    </style>
-
-    <!-- Application theme. -->
-    <style name="AppTheme" parent="AppBaseTheme">
-        <!-- All customizations that are NOT specific to a particular API-level can go here. -->
-    </style>
-</resources>
diff --git a/packages/OsuLogin/res/xml/network_security_config.xml b/packages/OsuLogin/res/xml/network_security_config.xml
deleted file mode 100644
index 3ef4b84..0000000
--- a/packages/OsuLogin/res/xml/network_security_config.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<network-security-config>
-<base-config cleartextTrafficPermitted="true">
-    <trust-anchors>
-        <certificates src="system" />
-        <certificates src="wfa" />
-    </trust-anchors>
-</base-config>
-</network-security-config>
diff --git a/packages/OsuLogin/src/com/android/hotspot2/osulogin/OsuLoginActivity.java b/packages/OsuLogin/src/com/android/hotspot2/osulogin/OsuLoginActivity.java
deleted file mode 100644
index 9797846..0000000
--- a/packages/OsuLogin/src/com/android/hotspot2/osulogin/OsuLoginActivity.java
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.hotspot2.osulogin;
-
-import static android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED;
-
-import android.app.Activity;
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.net.ConnectivityManager;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.net.NetworkRequest;
-import android.net.wifi.WifiManager;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.view.View;
-import android.webkit.WebChromeClient;
-import android.webkit.WebResourceError;
-import android.webkit.WebResourceRequest;
-import android.webkit.WebSettings;
-import android.webkit.WebView;
-import android.webkit.WebViewClient;
-import android.widget.ProgressBar;
-import android.widget.Toast;
-
-import androidx.annotation.Nullable;
-import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
-
-import java.net.MalformedURLException;
-import java.net.URL;
-
-/**
- * Online Sign Up Login Web View launched during Provision Process of Hotspot 2.0 rel2.
- */
-public class OsuLoginActivity extends Activity {
-    private static final String TAG = "OsuLogin";
-    private static final boolean DBG = true;
-
-    private String mUrl;
-    private String mHostName;
-    private Network mNetwork;
-    private ConnectivityManager mCm;
-    private ConnectivityManager.NetworkCallback mNetworkCallback;
-    private WifiManager mWifiManager;
-    private WebView mWebView;
-    private SwipeRefreshLayout mSwipeRefreshLayout;
-    private ProgressBar mProgressBar;
-    private boolean mForceDisconnect = true;
-    boolean mRedirectResponseReceived = false;
-
-    @Override
-    protected void onCreate(@Nullable Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        if (DBG) {
-            Log.d(TAG, "onCreate: Opening OSU Web View");
-        }
-
-        mWifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
-        if (mWifiManager == null) {
-            Log.e(TAG, "Cannot get wifi service");
-            finishAndRemoveTask();
-            return;
-        }
-
-        if (getIntent() == null) {
-            Log.e(TAG, "Intent is null");
-            finishAndRemoveTask();
-            return;
-        }
-
-        mNetwork = getIntent().getParcelableExtra(WifiManager.EXTRA_OSU_NETWORK);
-        if (mNetwork == null) {
-            Log.e(TAG, "Cannot get the network instance for OSU from intent");
-            finishAndRemoveTask();
-            return;
-        }
-
-        mUrl = getIntent().getStringExtra(WifiManager.EXTRA_URL);
-        if (mUrl == null) {
-            Log.e(TAG, "Cannot get OSU server url from intent");
-            finishAndRemoveTask();
-            return;
-        }
-
-        mHostName = getHost(mUrl);
-        if (mHostName == null) {
-            Log.e(TAG, "Cannot get host from the url");
-            finishAndRemoveTask();
-            return;
-        }
-
-        mCm = (ConnectivityManager) getApplicationContext().getSystemService(
-                Context.CONNECTIVITY_SERVICE);
-        if (mCm == null) {
-            Log.e(TAG, "Cannot get connectivity service");
-            finishAndRemoveTask();
-            return;
-        }
-
-        if (!mCm.bindProcessToNetwork(mNetwork)) {
-            Log.e(TAG, "Network is no longer valid");
-            finishAndRemoveTask();
-            return;
-        }
-
-        final NetworkCapabilities networkCapabilities = mCm.getNetworkCapabilities(mNetwork);
-        if (networkCapabilities == null || !networkCapabilities.hasTransport(
-                NetworkCapabilities.TRANSPORT_WIFI)) {
-            Log.e(TAG, "WiFi is not supported for the Network");
-            finishAndRemoveTask();
-            return;
-        }
-
-        getActionBar().setDisplayShowHomeEnabled(false);
-        getActionBar().setElevation(0); // remove shadow
-        getActionBar().setTitle(getString(R.string.action_bar_label));
-        getActionBar().setSubtitle("");
-        setContentView(R.layout.osu_web_view);
-
-        // Exit this app if network disappeared.
-        mNetworkCallback = new ConnectivityManager.NetworkCallback() {
-            @Override
-            public void onLost(Network network) {
-                if (DBG) {
-                    Log.d(TAG, "Lost for the current Network, close the browser");
-                }
-                mForceDisconnect = false; // It is already disconnected.
-                if (!mRedirectResponseReceived) {
-                    showSignUpFailedToast();
-                }
-                if (mNetwork.equals(network)) {
-                    finishAndRemoveTask();
-                }
-            }
-        };
-
-        mCm.registerNetworkCallback(
-                new NetworkRequest.Builder().addTransportType(
-                        NetworkCapabilities.TRANSPORT_WIFI).removeCapability(
-                        NET_CAPABILITY_TRUSTED).build(),
-                mNetworkCallback);
-
-        mWebView = findViewById(R.id.webview);
-        mWebView.clearCache(true);
-        WebSettings webSettings = mWebView.getSettings();
-        webSettings.setJavaScriptEnabled(true);
-        webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE);
-        webSettings.setUseWideViewPort(true);
-        webSettings.setLoadWithOverviewMode(true);
-        webSettings.setSupportZoom(true);
-        webSettings.setBuiltInZoomControls(true);
-        webSettings.setDisplayZoomControls(false);
-        mProgressBar = findViewById(R.id.progress_bar);
-        mWebView.setWebViewClient(new OsuWebViewClient());
-        mWebView.setWebChromeClient(new WebChromeClient() {
-            @Override
-            public void onProgressChanged(WebView view, int newProgress) {
-                mProgressBar.setProgress(newProgress);
-            }
-        });
-
-        if (DBG) {
-            Log.d(TAG, "OSU Web View to " + mUrl);
-        }
-
-        mWebView.loadUrl(mUrl);
-        mSwipeRefreshLayout = findViewById(R.id.swipe_refresh);
-        mSwipeRefreshLayout.setOnRefreshListener(() -> {
-            mWebView.reload();
-            mSwipeRefreshLayout.setRefreshing(true);
-        });
-    }
-
-    @Override
-    public boolean onKeyDown(int keyCode, KeyEvent event) {
-        // Check if the key event was the Back button.
-        if ((keyCode == KeyEvent.KEYCODE_BACK)) {
-            // If there is a history to move back
-            if (mWebView.canGoBack()) {
-                mWebView.goBack();
-                return true;
-            }
-        }
-        return super.onKeyDown(keyCode, event);
-    }
-
-    @Override
-    protected void onDestroy() {
-        if (mNetworkCallback != null) {
-            mCm.unregisterNetworkCallback(mNetworkCallback);
-            mNetworkCallback = null;
-        }
-        if (mWifiManager != null && mForceDisconnect) {
-            mWifiManager.disconnect();
-            mWifiManager = null;
-        }
-        super.onDestroy();
-    }
-
-    private String getHost(String url) {
-        try {
-            return new URL(url).getHost();
-        } catch (MalformedURLException e) {
-            Log.e(TAG, "Invalid URL " + url);
-        }
-        return null;
-    }
-
-    private String getHeaderSubtitle(String urlString) {
-        try {
-            URL url = new URL(urlString);
-            return url.getProtocol() + "://" +  url.getHost();
-        } catch (MalformedURLException e) {
-            Log.e(TAG, "Invalid URL " + urlString);
-        }
-        return "";
-    }
-
-    private void showSignUpFailedToast() {
-        Toast.makeText(getApplicationContext(), R.string.sign_up_failed,
-                Toast.LENGTH_SHORT).show();
-    }
-
-    private class OsuWebViewClient extends WebViewClient {
-        boolean mPageError = false;
-
-        @Override
-        public void onPageStarted(WebView view, String urlString, Bitmap favicon) {
-            String subtitle = getHeaderSubtitle(urlString);
-            getActionBar().setSubtitle(subtitle);
-            mProgressBar.setVisibility(View.VISIBLE);
-        }
-
-        @Override
-        public void onPageFinished(WebView view, String url) {
-            mProgressBar.setVisibility(View.INVISIBLE);
-            mSwipeRefreshLayout.setRefreshing(false);
-
-            // Do not show the page error on UI.
-            if (mPageError) {
-                if (mRedirectResponseReceived) {
-                    // Do not disconnect current connection while provisioning is in progress.
-                    mForceDisconnect = false;
-                }
-                finishAndRemoveTask();
-            }
-        }
-
-        @Override
-        public void onReceivedError(WebView view, WebResourceRequest request,
-                WebResourceError error) {
-            if (request.getUrl().toString().startsWith("http://127.0.0.1")) {
-                mRedirectResponseReceived = true;
-                view.stopLoading();
-            }
-
-            if (request.isForMainFrame()) {
-                // This happens right after getting HTTP redirect response from an OSU server
-                // since no more Http request is allowed to send to the OSU server.
-                mPageError = true;
-                Log.e(TAG, "onReceived Error for MainFrame: " + error.getErrorCode());
-            }
-        }
-    }
-}
diff --git a/packages/SettingsLib/HelpUtils/res/values-uz/strings.xml b/packages/SettingsLib/HelpUtils/res/values-uz/strings.xml
index 81d0dd9..cb56912 100644
--- a/packages/SettingsLib/HelpUtils/res/values-uz/strings.xml
+++ b/packages/SettingsLib/HelpUtils/res/values-uz/strings.xml
@@ -17,5 +17,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="help_feedback_label" msgid="7106780063063027882">"Yordam va fikr-mulohaza"</string>
+    <string name="help_feedback_label" msgid="7106780063063027882">"Yordam/fikr-mulohaza"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index b040958..c45255c 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -409,7 +409,7 @@
     <string name="convert_to_file_encryption_done" msgid="8965831011811180627">"El fitxer ja està encriptat"</string>
     <string name="title_convert_fbe" msgid="5780013350366495149">"S\'està convertint en l\'encriptació basada en fitxers"</string>
     <string name="convert_to_fbe_warning" msgid="34294381569282109">"Converteix la partició de dades en una encriptació basada en fitxers.\n Advertiment: s\'esborraran totes les teves dades.\n Aquesta funció és alfa i és possible que no funcioni correctament.\n Per continuar, prem Esborra i converteix…"</string>
-    <string name="button_convert_fbe" msgid="1159861795137727671">"Esborra i converteix…"</string>
+    <string name="button_convert_fbe" msgid="1159861795137727671">"Neteja i converteix…"</string>
     <string name="picture_color_mode" msgid="1013807330552931903">"Mode de color de la imatge"</string>
     <string name="picture_color_mode_desc" msgid="151780973768136200">"Utilitza sRGB"</string>
     <string name="daltonizer_mode_disabled" msgid="403424372812399228">"Desactivat"</string>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index 3d28f1d..0854e8d 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -487,8 +487,8 @@
     <string name="status_unavailable" msgid="5279036186589861608">"Ei käytettävissä"</string>
     <string name="wifi_status_mac_randomized" msgid="466382542497832189">"MAC-osoite satunnaistetaan"</string>
     <plurals name="wifi_tether_connected_summary" formatted="false" msgid="6317236306047306139">
-      <item quantity="other">%1$d laitetta liitetty</item>
-      <item quantity="one">%1$d laite liitetty</item>
+      <item quantity="other">%1$d laitetta yhdistettynä</item>
+      <item quantity="one">%1$d laite yhdistettynä</item>
     </plurals>
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Enemmän aikaa"</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Vähemmän aikaa"</string>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index fff881c..a65fc19 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -212,9 +212,9 @@
     <string name="adb_wireless_settings" msgid="2295017847215680229">"ניפוי באגים אלחוטי"</string>
     <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"כדי להציג את המכשירים הזמינים ולהשתמש בהם, יש להפעיל ניפוי באגים אלחוטי"</string>
     <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"‏התאמת מכשיר באמצעות קוד QR"</string>
-    <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"‏התאמת מכשירים חדשים באמצעות סורק של קודי QR"</string>
+    <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"‏התאמת מכשירים חדשים באמצעות סורק קודי QR"</string>
     <string name="adb_pair_method_code_title" msgid="1122590300445142904">"התאמת מכשיר באמצעות קוד התאמה"</string>
-    <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"התאמת מכשירים חדשים באמצעות קוד בן שש ספרות"</string>
+    <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"התאמת מכשירים חדשים באמצעות קוד בן 6 ספרות"</string>
     <string name="adb_paired_devices_title" msgid="5268997341526217362">"מכשירים מותאמים"</string>
     <string name="adb_wireless_device_connected_summary" msgid="3039660790249148713">"מחובר עכשיו"</string>
     <string name="adb_wireless_device_details_title" msgid="7129369670526565786">"פרטי מכשיר"</string>
@@ -226,12 +226,12 @@
     <string name="adb_pairing_device_dialog_pairing_code_label" msgid="3639239786669722731">"‏קוד התאמה של Wi-Fi"</string>
     <string name="adb_pairing_device_dialog_failed_title" msgid="3426758947882091735">"ההתאמה נכשלה"</string>
     <string name="adb_pairing_device_dialog_failed_msg" msgid="6611097519661997148">"יש לוודא שהמכשיר מחובר לאותה רשת."</string>
-    <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"‏יש לסרוק קוד QR כדי להתאים מכשיר באמצעות Wi‑Fi"</string>
+    <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"‏כדי להתאים מכשיר דרך Wi‑Fi, יש לסרוק קוד QR"</string>
     <string name="adb_wireless_verifying_qrcode_text" msgid="6123192424916029207">"המכשיר בתהליך התאמה…"</string>
     <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"‏התאמת המכשיר נכשלה. קוד ה-QR היה שגוי או שהמכשיר לא מחובר לאותה רשת."</string>
     <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"‏יציאה וכתובת IP"</string>
     <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"‏סריקת קוד QR"</string>
-    <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"‏יש לסרוק קוד QR כדי להתאים מכשיר באמצעות Wi‑Fi"</string>
+    <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"‏כדי להתאים מכשיר דרך Wi‑Fi, יש לסרוק קוד QR"</string>
     <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"‏יש להתחבר לרשת Wi-Fi"</string>
     <string name="keywords_adb_wireless" msgid="6507505581882171240">"‏adb, ניפוי באגים, פיתוח"</string>
     <string name="bugreport_in_power" msgid="8664089072534638709">"קיצור של דוח באגים"</string>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index 3c281c8..11506a4 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -145,7 +145,7 @@
     <string name="data_usage_ota" msgid="7984667793701597001">"സിസ്‌റ്റം അപ്‌ഡേറ്റുകൾ"</string>
     <string name="tether_settings_title_usb" msgid="3728686573430917722">"USB ടെതറിംഗ്"</string>
     <string name="tether_settings_title_wifi" msgid="4803402057533895526">"പോർട്ടബിൾ ഹോട്ട്സ്‌പോട്ട്"</string>
-    <string name="tether_settings_title_bluetooth" msgid="916519902721399656">"ബ്ലൂടൂത്ത് ടെതറിംഗ്"</string>
+    <string name="tether_settings_title_bluetooth" msgid="916519902721399656">"Bluetooth ടെതറിംഗ്"</string>
     <string name="tether_settings_title_usb_bluetooth" msgid="1727111807207577322">"ടെതറിംഗ്"</string>
     <string name="tether_settings_title_all" msgid="8910259483383010470">"ടെതറിംഗും പോർട്ടബിൾ ഹോട്ട്സ്‌പോട്ടും"</string>
     <string name="managed_user_title" msgid="449081789742645723">"എല്ലാ ഔദ്യോഗിക ആപ്‌സും"</string>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index 002c7fc..9ebab4d 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -203,9 +203,9 @@
     <string name="vpn_settings_not_available" msgid="2894137119965668920">"Cilësimet e VPN-së nuk ofrohen për këtë përdorues"</string>
     <string name="tethering_settings_not_available" msgid="266821736434699780">"Cilësimet e ndarjes nuk ofrohen për këtë përdorues"</string>
     <string name="apn_settings_not_available" msgid="1147111671403342300">"Cilësimet e \"Emrit të pikës së qasjes\" nuk mund të përdoren për këtë përdorues"</string>
-    <string name="enable_adb" msgid="8072776357237289039">"Korrigjimi i USB-së"</string>
+    <string name="enable_adb" msgid="8072776357237289039">"Korrigjimi përmes USB-së"</string>
     <string name="enable_adb_summary" msgid="3711526030096574316">"Korrigjo gabimet e modalitetit kur UBS-ja është e lidhur"</string>
-    <string name="clear_adb_keys" msgid="3010148733140369917">"Anulo autorizimet e korrigjimeve të gabimeve të USB-së"</string>
+    <string name="clear_adb_keys" msgid="3010148733140369917">"Anulo autorizimet e korrigjimeve përmes USB-së"</string>
     <string name="enable_adb_wireless" msgid="6973226350963971018">"Korrigjimi përmes Wi-Fi"</string>
     <string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Modaliteti i korrigjimit kur Wi‑Fi është i lidhur"</string>
     <string name="adb_wireless_error" msgid="721958772149779856">"Gabim"</string>
@@ -225,7 +225,7 @@
     <string name="adb_pairing_device_dialog_title" msgid="7141739231018530210">"Çifto me pajisjen"</string>
     <string name="adb_pairing_device_dialog_pairing_code_label" msgid="3639239786669722731">"Kodi i çiftimit të Wi‑Fi"</string>
     <string name="adb_pairing_device_dialog_failed_title" msgid="3426758947882091735">"Çiftimi ishte i pasuksesshëm"</string>
-    <string name="adb_pairing_device_dialog_failed_msg" msgid="6611097519661997148">"Sigurohu që pajisja të jetë e lidhur me të njëjtin rrjet"</string>
+    <string name="adb_pairing_device_dialog_failed_msg" msgid="6611097519661997148">"Sigurohu që pajisja të jetë e lidhur me të njëjtin rrjet."</string>
     <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"Çifto pajisjen përmes Wi‑Fi duke skanuar një kod QR"</string>
     <string name="adb_wireless_verifying_qrcode_text" msgid="6123192424916029207">"Po çifton pajisjen…"</string>
     <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Çiftimi i pajisjes dështoi. Ose kodi QR nuk ishte i saktë, ose pajisja nuk është e lidhur me të njëjtin rrjet."</string>
@@ -299,11 +299,11 @@
     <string name="debug_view_attributes" msgid="3539609843984208216">"Aktivizo shikimin e inspektimit të atributeve"</string>
     <string name="mobile_data_always_on_summary" msgid="1112156365594371019">"Mbaji të dhënat celulare gjithmonë aktive edhe kur Wi‑Fi është aktiv (për ndërrim të shpejtë të rrjetit)."</string>
     <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Përdor përshpejtimin e harduerit për ndarjen e lidhjes (internet) nëse është i disponueshëm"</string>
-    <string name="adb_warning_title" msgid="7708653449506485728">"Të lejohet korrigjimi i USB-së?"</string>
-    <string name="adb_warning_message" msgid="8145270656419669221">"Korrigjuesi i USB-së është vetëm për qëllime zhvillimore. Përdore për të kopjuar të dhëna mes kompjuterit dhe pajisjes tënde, për të instaluar aplikacione në pajisjen tënde pa asnjë njoftim si dhe për të lexuar të dhënat e ditarit."</string>
+    <string name="adb_warning_title" msgid="7708653449506485728">"Të lejohet korrigjimi përmes USB-së?"</string>
+    <string name="adb_warning_message" msgid="8145270656419669221">"Korrigjuesi përmes USB-së është vetëm për qëllime zhvillimore. Përdore për të kopjuar të dhëna mes kompjuterit dhe pajisjes tënde, për të instaluar aplikacione në pajisjen tënde pa asnjë njoftim si dhe për të lexuar të dhënat e evidencave."</string>
     <string name="adbwifi_warning_title" msgid="727104571653031865">"Të lejohet korrigjimi përmes Wi-Fi?"</string>
     <string name="adbwifi_warning_message" msgid="8005936574322702388">"Korrigjimin përmes Wi-Fi është vetëm për qëllime zhvillimore. Përdore për të kopjuar të dhëna mes kompjuterit dhe pajisjes sate, për të instaluar aplikacione në pajisjen tënde pa asnjë njoftim si dhe për të lexuar të dhënat e regjistrit."</string>
-    <string name="adb_keys_warning_message" msgid="2968555274488101220">"Të bllokohet qasja për korrigjim të USB-së nga të gjithë kompjuterët që ke autorizuar më parë?"</string>
+    <string name="adb_keys_warning_message" msgid="2968555274488101220">"Të bllokohet qasja për korrigjim përmes USB-së nga të gjithë kompjuterët që ke autorizuar më parë?"</string>
     <string name="dev_settings_warning_title" msgid="8251234890169074553">"Të lejohen cilësimet e zhvillimit?"</string>
     <string name="dev_settings_warning_message" msgid="37741686486073668">"Këto cilësime janë të projektuara vetëm për përdorim në programim. Ato mund të shkaktojnë që pajisja dhe aplikacionet në të, të mos punojnë ose të veprojnë në mënyrë të gabuar."</string>
     <string name="verify_apps_over_usb_title" msgid="6031809675604442636">"Verifiko apl. përmes USB-së"</string>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index e944c64..5a3b872 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -210,7 +210,7 @@
     <string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Hali ya utatuzi wakati Wi-Fi imeunganishwa"</string>
     <string name="adb_wireless_error" msgid="721958772149779856">"Hitilafu"</string>
     <string name="adb_wireless_settings" msgid="2295017847215680229">"Utatuzi usiotumia waya"</string>
-    <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Ili kungalia na kutumia vifaa vinavyopatikana, washa utatuzi usiotumia waya"</string>
+    <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Ili kuangalia na kutumia vifaa vinavyopatikana, washa utatuzi usiotumia waya"</string>
     <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Oanisha kifaa ukitumia msimbo wa QR"</string>
     <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Oanisha vifaa vipya ukitumia kichanganuzi cha Msimbo wa QR"</string>
     <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Oanisha kifaa ukitumia msimbo wa kuoanisha"</string>
@@ -487,8 +487,8 @@
     <string name="status_unavailable" msgid="5279036186589861608">"Hamna"</string>
     <string name="wifi_status_mac_randomized" msgid="466382542497832189">"Imechagua anwani ya MAC kwa nasibu"</string>
     <plurals name="wifi_tether_connected_summary" formatted="false" msgid="6317236306047306139">
-      <item quantity="other">Imeunganisha vifaa %1$d</item>
-      <item quantity="one">Imeunganisha kifaa %1$d</item>
+      <item quantity="other">Vifaa %1$d vimeunganishwa</item>
+      <item quantity="one">Kifaa %1$d kimeunganishwa</item>
     </plurals>
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Muda zaidi."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Muda kidogo."</string>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index 7468d04..4ba1c7a 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -284,7 +284,7 @@
     <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"เพิ่มระดับการบันทึก Wi‑Fi แสดงต่อ SSID RSSI ในตัวเลือก Wi‑Fi"</string>
     <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"ลดการเปลืองแบตเตอรี่และเพิ่มประสิทธิภาพเครือข่าย"</string>
     <string name="wifi_enhanced_mac_randomization_summary" msgid="1210663439867489931">"เมื่อเปิดใช้โหมดนี้ ที่อยู่ MAC ของอุปกรณ์นี้อาจเปลี่ยนทุกครั้งที่เชื่อมต่อกับเครือข่ายที่มีการเปิดใช้การสุ่ม MAC"</string>
-    <string name="wifi_metered_label" msgid="8737187690304098638">"มีการวัดปริมาณอินเทอร์เน็ต"</string>
+    <string name="wifi_metered_label" msgid="8737187690304098638">"แบบจำกัดปริมาณอินเทอร์เน็ต"</string>
     <string name="wifi_unmetered_label" msgid="6174142840934095093">"ไม่มีการวัดปริมาณอินเทอร์เน็ต"</string>
     <string name="select_logd_size_title" msgid="1604578195914595173">"ขนาดบัฟเฟอร์ของตัวบันทึก"</string>
     <string name="select_logd_size_dialog_title" msgid="2105401994681013578">"เลือกขนาด Logger ต่อบัฟเฟอร์ไฟล์บันทึก"</string>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index de90c9a..b14049a 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -31,7 +31,7 @@
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"توثیق کا مسئلہ"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"منسلک نہیں ہو سکتا ہے"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"\'<xliff:g id="AP_NAME">%1$s</xliff:g>\' سے منسلک نہیں ہو سکتا ہے"</string>
-    <string name="wifi_check_password_try_again" msgid="8817789642851605628">"پاسورڈ چیک کر کے دوبارہ کوشش کریں"</string>
+    <string name="wifi_check_password_try_again" msgid="8817789642851605628">"پاس ورڈ چیک کر کے دوبارہ کوشش کریں"</string>
     <string name="wifi_not_in_range" msgid="1541760821805777772">"رینج میں نہیں ہے"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"خودکار طور پر منسلک نہیں ہو گا"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"انٹرنیٹ تک کوئی رسائی نہیں"</string>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index 2325efd..1347cdd 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -423,12 +423,12 @@
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Taxminan <xliff:g id="TIME_REMAINING">%1$s</xliff:g> qoldi"</string>
     <string name="power_discharging_duration" msgid="1076561255466053220">"Taxminan <xliff:g id="TIME_REMAINING">%1$s</xliff:g> qoldi (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
-    <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Joriy holatda taxminan <xliff:g id="TIME_REMAINING">%1$s</xliff:g> qoldi"</string>
-    <string name="power_discharging_duration_enhanced" msgid="1800465736237672323">"Joriy holatda taxminan <xliff:g id="TIME_REMAINING">%1$s</xliff:g> qoldi (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Quvvati tugashiga taxminan <xliff:g id="TIME_REMAINING">%1$s</xliff:g> qoldi"</string>
+    <string name="power_discharging_duration_enhanced" msgid="1800465736237672323">"Quvvati tugahsiga taxminan <xliff:g id="TIME_REMAINING">%1$s</xliff:g> qoldi (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
     <!-- no translation found for power_remaining_duration_only_short (7438846066602840588) -->
     <skip />
-    <string name="power_discharge_by_enhanced" msgid="563438403581662942">"Joriy holatda taxminan <xliff:g id="TIME">%1$s</xliff:g> gacha davom etadi (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
-    <string name="power_discharge_by_only_enhanced" msgid="3268796172652988877">"Joriy holatda taxminan <xliff:g id="TIME">%1$s</xliff:g> gacha davom etadi"</string>
+    <string name="power_discharge_by_enhanced" msgid="563438403581662942">"Shunday ishlatishda taxminan <xliff:g id="TIME">%1$s</xliff:g> gacha yetadi (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+    <string name="power_discharge_by_only_enhanced" msgid="3268796172652988877">"Quvvati tugashiga taxminan <xliff:g id="TIME">%1$s</xliff:g> qoldi"</string>
     <string name="power_discharge_by" msgid="4113180890060388350">"Taxminan <xliff:g id="TIME">%1$s</xliff:g> gacha yetadi (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
     <string name="power_discharge_by_only" msgid="92545648425937000">"Taxminan <xliff:g id="TIME">%1$s</xliff:g> gacha yetadi"</string>
     <string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> gacha"</string>
@@ -510,7 +510,7 @@
     <string name="media_transfer_this_device_name" msgid="2716555073132169240">"Telefon karnayi"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Ulanishda muammo yuz berdi. Qurilmani oʻchiring va yoqing"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Simli audio qurilma"</string>
-    <string name="help_label" msgid="3528360748637781274">"Yordam va fikr-mulohaza"</string>
+    <string name="help_label" msgid="3528360748637781274">"Yordam/fikr-mulohaza"</string>
     <string name="storage_category" msgid="2287342585424631813">"Xotira"</string>
     <string name="shared_data_title" msgid="1017034836800864953">"Umumiy maʼlumotlar"</string>
     <string name="shared_data_summary" msgid="5516326713822885652">"Umumiy maʼlumotlarni ochish va oʻzgartirish"</string>
diff --git a/packages/SettingsProvider/OWNERS b/packages/SettingsProvider/OWNERS
index b2ac4f4..cf9799c 100644
--- a/packages/SettingsProvider/OWNERS
+++ b/packages/SettingsProvider/OWNERS
@@ -1,3 +1,4 @@
+hackbod@android.com
 hackbod@google.com
 narayan@google.com
 svetoslavganov@google.com
diff --git a/packages/SettingsProvider/res/values-iw/strings.xml b/packages/SettingsProvider/res/values-iw/strings.xml
index 8d8594d..10765fe 100644
--- a/packages/SettingsProvider/res/values-iw/strings.xml
+++ b/packages/SettingsProvider/res/values-iw/strings.xml
@@ -20,6 +20,6 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4567566098528588863">"אחסון הגדרות"</string>
-    <string name="wifi_softap_config_change" msgid="5688373762357941645">"ההגדרות של הנקודה לשיתוף אינטרנט השתנו"</string>
+    <string name="wifi_softap_config_change" msgid="5688373762357941645">"‏הגדרות נקודת האינטרנט (hotspot) השתנו"</string>
     <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"יש להקיש להצגת פרטים"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-ur/strings.xml b/packages/SystemUI/res-keyguard/values-ur/strings.xml
index 0fd5e17..7f8d160 100644
--- a/packages/SystemUI/res-keyguard/values-ur/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ur/strings.xml
@@ -25,7 +25,7 @@
     <string name="keyguard_password_enter_puk_code" msgid="3813154965969758868">"‏SIM PUK اور نیا PIN کوڈ ٹائپ کریں"</string>
     <string name="keyguard_password_enter_puk_prompt" msgid="3529260761374385243">"‏SIM PUK کوڈ"</string>
     <string name="keyguard_password_enter_pin_prompt" msgid="2304037870481240781">"‏نیا SIM PIN کوڈ"</string>
-    <string name="keyguard_password_entry_touch_hint" msgid="6180028658339706333"><font size="17">"پاسورڈ ٹائپ کرنے کیلئے ٹچ کریں"</font></string>
+    <string name="keyguard_password_entry_touch_hint" msgid="6180028658339706333"><font size="17">"پاس ورڈ ٹائپ کرنے کیلئے ٹچ کریں"</font></string>
     <string name="keyguard_password_enter_password_code" msgid="7393393239623946777">"غیر مقفل کرنے کیلئے پاس ورڈ ٹائپ کریں"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="3692259677395250509">"‏غیر مقفل کرنے کیلئے PIN ٹائپ کریں"</string>
     <string name="keyguard_enter_your_pin" msgid="5429932527814874032">"‏اپنا PIN درج کریں"</string>
@@ -72,7 +72,7 @@
     <string name="kg_sim_pin_instructions_multi" msgid="3639863309953109649">"‏\"<xliff:g id="CARRIER">%1$s</xliff:g>\" کیلئے SIM PIN درج کریں۔"</string>
     <string name="kg_sim_lock_esim_instructions" msgid="5577169988158738030">"‏<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> موبائل سروس کے بغیر آلہ کا استعمال کرنے کیلئے eSIM غیر فعال کریں۔"</string>
     <string name="kg_pin_instructions" msgid="822353548385014361">"‏‫PIN درج کریں"</string>
-    <string name="kg_password_instructions" msgid="324455062831719903">"پاسورڈ درج کریں"</string>
+    <string name="kg_password_instructions" msgid="324455062831719903">"پاس ورڈ درج کریں"</string>
     <string name="kg_puk_enter_puk_hint" msgid="3005288372875367017">"‏SIM اب غیر فعال ہوگیا ہے۔ جاری رکھنے کیلئے PUK کوڈ درج کریں۔ تفصیلات کیلئے کیریئر سے رابطہ کریں۔"</string>
     <string name="kg_puk_enter_puk_hint_multi" msgid="4876780689904862943">"‏SIM \"<xliff:g id="CARRIER">%1$s</xliff:g>\" اب غیر فعال ہے۔ جاری رکھنے کیلئے PUK کوڈ درج کریں۔ تفصیلات کیلئے کیریئر سے رابطہ کریں۔"</string>
     <string name="kg_puk_enter_pin_hint" msgid="6028432138916150399">"‏پسندیدہ PIN کوڈ درج کریں"</string>
@@ -83,7 +83,7 @@
     <string name="kg_invalid_puk" msgid="1774337070084931186">"‏صحیح PUK کوڈ دوبارہ درج کریں۔ بار بار کی کوششیں SIM کو مستقل طور پر غیر فعال کر دیں گی۔"</string>
     <string name="kg_login_too_many_attempts" msgid="4519957179182578690">"پیٹرن کی بہت ساری کوششیں"</string>
     <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"‏آپ نے اپنا PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> بار غلط طریقے سے ٹائپ کیا ہے۔ \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> سیکنڈ میں دوبارہ کوشش کریں۔"</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"آپ نے اپنا پاسورڈ <xliff:g id="NUMBER_0">%1$d</xliff:g> بار غلط طریقے سے ٹائپ کیا ہے۔ \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> سیکنڈ میں دوبارہ کوشش کریں۔"</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"آپ نے اپنا پاس ورڈ <xliff:g id="NUMBER_0">%1$d</xliff:g> بار غلط طریقے سے ٹائپ کیا ہے۔ \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> سیکنڈ میں دوبارہ کوشش کریں۔"</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"آپ نے اپنا غیر مقفل کرنے کا پیٹرن <xliff:g id="NUMBER_0">%1$d</xliff:g> بار غلط طریقے سے ڈرا کیا ہے۔ \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> سیکنڈ میں دوبارہ کوشش کریں۔"</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"‏غلط SIM PIN کوڈ، اب آپ کو اپنا آلہ غیر مقفل کرنے کیلئے اپنے کیریئر سے رابطہ کرنا ہوگا۔"</string>
     <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
@@ -103,13 +103,13 @@
     <string name="airplane_mode" msgid="2528005343938497866">"ہوائی جہاز وضع"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"آلہ دوبارہ چالو ہونے کے بعد پیٹرن درکار ہوتا ہے"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"‏آلہ دوبارہ چالو ہونے کے بعد PIN درکار ہوتا ہے"</string>
-    <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"آلہ دوبارہ چالو ہونے کے بعد پاسورڈ درکار ہوتا ہے"</string>
+    <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"آلہ دوبارہ چالو ہونے کے بعد پاس ورڈ درکار ہوتا ہے"</string>
     <string name="kg_prompt_reason_timeout_pattern" msgid="9170360502528959889">"اضافی سیکیورٹی کیلئے پیٹرن درکار ہے"</string>
     <string name="kg_prompt_reason_timeout_pin" msgid="5945186097160029201">"‏اضافی سیکیورٹی کیلئے PIN درکار ہے"</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="2258263949430384278">"اضافی سیکیورٹی کیلئے پاسورڈ درکار ہے"</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="2258263949430384278">"اضافی سیکیورٹی کیلئے پاس ورڈ درکار ہے"</string>
     <string name="kg_prompt_reason_switch_profiles_pattern" msgid="1922016914701991230">"جب آپ پروفائل سوئچ کرتے ہیں تو پیٹرن درکار ہوتا ہے"</string>
     <string name="kg_prompt_reason_switch_profiles_pin" msgid="6490434826361055400">"‏جب آپ پروفائل سوئچ کرتے ہیں تو PIN درکار ہوتا ہے"</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="1680374696393804441">"جب آپ پروفائل سوئچ کرتے ہیں تو پاسورڈ درکار ہوتا ہے"</string>
+    <string name="kg_prompt_reason_switch_profiles_password" msgid="1680374696393804441">"جب آپ پروفائل سوئچ کرتے ہیں تو پاس ورڈ درکار ہوتا ہے"</string>
     <string name="kg_prompt_reason_device_admin" msgid="6961159596224055685">"آلہ منتظم کی جانب سے مقفل ہے"</string>
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"آلہ کو دستی طور پر مقفل کیا گیا تھا"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="1337428979661197957">
@@ -121,8 +121,8 @@
       <item quantity="one">‏آلہ <xliff:g id="NUMBER_0">%d</xliff:g> گھنٹہ سے غیر مقفل نہیں کیا گیا۔ PIN کی توثیق کریں۔</item>
     </plurals>
     <plurals name="kg_prompt_reason_time_password" formatted="false" msgid="5343961527665116914">
-      <item quantity="other">آلہ <xliff:g id="NUMBER_1">%d</xliff:g> گھنٹوں سے غیر مقفل نہیں کیا گيا۔ پاسورڈ کی توثیق کریں۔</item>
-      <item quantity="one">آلہ <xliff:g id="NUMBER_0">%d</xliff:g> گھنٹہ سے غیر مقفل نہیں کیا گیا۔ پاسورڈ کی توثیق کریں۔</item>
+      <item quantity="other">آلہ <xliff:g id="NUMBER_1">%d</xliff:g> گھنٹوں سے غیر مقفل نہیں کیا گيا۔ پاس ورڈ کی توثیق کریں۔</item>
+      <item quantity="one">آلہ <xliff:g id="NUMBER_0">%d</xliff:g> گھنٹہ سے غیر مقفل نہیں کیا گیا۔ پاس ورڈ کی توثیق کریں۔</item>
     </plurals>
     <string name="kg_fingerprint_not_recognized" msgid="5982606907039479545">"تسلیم شدہ نہیں ہے"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"تسلیم شدہ نہیں ہے"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 87233dc..88bb88c 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -35,7 +35,7 @@
     <string name="battery_low_why" msgid="2056750982959359863">"הגדרות"</string>
     <string name="battery_saver_confirmation_title" msgid="1234998463717398453">"להפעיל את תכונת החיסכון בסוללה?"</string>
     <string name="battery_saver_confirmation_title_generic" msgid="2299231884234959849">"מידע על מצב החיסכון בסוללה"</string>
-    <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"הפעל"</string>
+    <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"הפעלה"</string>
     <string name="battery_saver_start_action" msgid="4553256017945469937">"הפעלת תכונת החיסכון בסוללה"</string>
     <string name="status_bar_settings_settings_button" msgid="534331565185171556">"הגדרות"</string>
     <string name="status_bar_settings_wifi_button" msgid="7243072479837270946">"Wi-Fi"</string>
@@ -298,8 +298,8 @@
     <string name="accessibility_quick_settings_flashlight_changed_on" msgid="4747870681508334200">"הפנס הופעל."</string>
     <string name="accessibility_quick_settings_color_inversion_changed_off" msgid="7548045840282925393">"היפוך צבעים כבוי."</string>
     <string name="accessibility_quick_settings_color_inversion_changed_on" msgid="4711141858364404084">"היפוך צבעים מופעל."</string>
-    <string name="accessibility_quick_settings_hotspot_changed_off" msgid="7002061268910095176">"נקודה לשיתוף אינטרנט בנייד כבויה."</string>
-    <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2576895346762408840">"נקודה לשיתוף אינטרנט בנייד מופעלת."</string>
+    <string name="accessibility_quick_settings_hotspot_changed_off" msgid="7002061268910095176">"‏נקודת האינטרנט (hotspot) כבויה."</string>
+    <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2576895346762408840">"‏נקודת האינטרנט (hotspot) מופעלת."</string>
     <string name="accessibility_casting_turned_off" msgid="1387906158563374962">"העברת המסך הופסקה."</string>
     <string name="accessibility_quick_settings_work_mode_off" msgid="562749867895549696">"מצב עבודה כבוי."</string>
     <string name="accessibility_quick_settings_work_mode_on" msgid="2779253456042059110">"מצב עבודה מופעל."</string>
@@ -397,7 +397,7 @@
     <string name="quick_settings_connected_battery_level" msgid="1322075669498906959">"מחובר, הסוללה ב-<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="2381969772953268809">"מתחבר..."</string>
     <string name="quick_settings_tethering_label" msgid="5257299852322475780">"שיתוף אינטרנט בין ניידים"</string>
-    <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"נקודה לשיתוף אינטרנט"</string>
+    <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"‏נקודת אינטרנט (hotspot)"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"ההפעלה מתבצעת…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"חוסך הנתונים פועל"</string>
     <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
@@ -666,7 +666,7 @@
     <string name="alarm_template" msgid="2234991538018805736">"בשעה <xliff:g id="WHEN">%1$s</xliff:g>"</string>
     <string name="alarm_template_far" msgid="3561752195856839456">"ב-<xliff:g id="WHEN">%1$s</xliff:g>"</string>
     <string name="accessibility_quick_settings_detail" msgid="544463655956179791">"הגדרות מהירות, <xliff:g id="TITLE">%s</xliff:g>."</string>
-    <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"נקודה לשיתוף אינטרנט"</string>
+    <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"‏נקודת אינטרנט (hotspot)"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"פרופיל עבודה"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"מהנה בשביל חלק מהאנשים, אבל לא בשביל כולם"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"‏System UI Tuner מספק לך דרכים נוספות להתאים אישית את ממשק המשתמש של Android. התכונות הניסיוניות האלה עשויות להשתנות, להתקלקל או להיעלם בגרסאות עתידיות. המשך בזהירות."</string>
@@ -683,7 +683,7 @@
     <string name="experimental" msgid="3549865454812314826">"ניסיוני"</string>
     <string name="enable_bluetooth_title" msgid="866883307336662596">"‏האם להפעיל את ה-Bluetooth?"</string>
     <string name="enable_bluetooth_message" msgid="6740938333772779717">"‏כדי לחבר את המקלדת לטאבלט, תחילה עליך להפעיל את ה-Bluetooth."</string>
-    <string name="enable_bluetooth_confirmation_ok" msgid="2866408183324184876">"הפעל"</string>
+    <string name="enable_bluetooth_confirmation_ok" msgid="2866408183324184876">"הפעלה"</string>
     <string name="show_silently" msgid="5629369640872236299">"הצגת התראות בלי להשמיע צליל"</string>
     <string name="block" msgid="188483833983476566">"חסימת כל ההתראות"</string>
     <string name="do_not_silence" msgid="4982217934250511227">"לא להשתיק"</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index caab00f..30ecf7a 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -63,7 +63,7 @@
     <string name="usb_debugging_allow" msgid="1722643858015321328">"अनुमती द्या"</string>
     <string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"USB डीबग करण्‍यास अनुमती नाही"</string>
     <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"सध्‍या या डीव्हाइसमध्‍ये साइन इन केलेला वापरकर्ता USB डीबग करणे सुरू करू शकत नाही. हे वैशिष्‍ट्य वापरण्‍यासाठी, प्राथमिक वापरकर्त्‍यावर स्विच करा."</string>
-    <string name="wifi_debugging_title" msgid="7300007687492186076">"या नेटवर्कवर वायरलेस डीबगिंग करण्याला अनुमती द्यायची का?"</string>
+    <string name="wifi_debugging_title" msgid="7300007687492186076">"या नेटवर्कवर वायरलेस डीबगिंग करण्यासाठी अनुमती द्यायची का?"</string>
     <string name="wifi_debugging_message" msgid="5461204211731802995">"नेटवर्कचे नाव (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nवाय-फाय ॲड्रेस (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string>
     <string name="wifi_debugging_always" msgid="2968383799517975155">"या नेटवर्कवर नेहमी अनुमती द्या"</string>
     <string name="wifi_debugging_allow" msgid="4573224609684957886">"अनुमती द्या"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 9aae6ce..d304098 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -422,7 +422,7 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4063448287758262485">"Do wschodu słońca"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="3584738542293528235">"Włącz o <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="1883981263191927372">"Do <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="1398928270610780470">"Tryb ciemny"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="1398928270610780470">"Ciemny motyw"</string>
     <string name="quick_settings_dark_mode_secondary_label_battery_saver" msgid="4990712734503013251">"Oszczędzanie baterii"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at_sunset" msgid="6017379738102015710">"Włącz o zachodzie"</string>
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Do wschodu słońca"</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 912b25e..5b186fa 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -57,15 +57,15 @@
     <string name="label_view" msgid="6815442985276363364">"Pamje"</string>
     <string name="always_use_device" msgid="210535878779644679">"Hap gjithmonë <xliff:g id="APPLICATION">%1$s</xliff:g> kur lidhet <xliff:g id="USB_DEVICE">%2$s</xliff:g>"</string>
     <string name="always_use_accessory" msgid="1977225429341838444">"Hap gjithmonë <xliff:g id="APPLICATION">%1$s</xliff:g> kur lidhet <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>"</string>
-    <string name="usb_debugging_title" msgid="8274884945238642726">"Të lejohet korrigjimi i USB-së?"</string>
+    <string name="usb_debugging_title" msgid="8274884945238642726">"Të lejohet korrigjimi përmes USB-së?"</string>
     <string name="usb_debugging_message" msgid="5794616114463921773">"Gjurma e gishtit të tastit \"RSA\" së kompjuterit është:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
     <string name="usb_debugging_always" msgid="4003121804294739548">"Lejo gjithmonë nga ky kompjuter"</string>
     <string name="usb_debugging_allow" msgid="1722643858015321328">"Lejo"</string>
-    <string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"Korrigjimi i USB-së nuk lejohet"</string>
-    <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Përdoruesi i identifikuar aktualisht në këtë pajisje nuk mund ta aktivizojë korrigjimin e USB-së. Për ta përdorur këtë funksion, kalo te përdoruesi parësor."</string>
+    <string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"Korrigjimi përmes USB-së nuk lejohet"</string>
+    <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Përdoruesi i identifikuar aktualisht në këtë pajisje nuk mund ta aktivizojë korrigjimin përmes USB-së. Për ta përdorur këtë veçori, kalo te përdoruesi parësor."</string>
     <string name="wifi_debugging_title" msgid="7300007687492186076">"Do ta lejosh korrigjimin përmes Wi-Fi në këtë rrjet?"</string>
     <string name="wifi_debugging_message" msgid="5461204211731802995">"Emri i rrjetit (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nAdresa Wi‑Fi (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string>
-    <string name="wifi_debugging_always" msgid="2968383799517975155">"Shfaq gjithmonë në këtë rrjet"</string>
+    <string name="wifi_debugging_always" msgid="2968383799517975155">"Lejo gjithmonë në këtë rrjet"</string>
     <string name="wifi_debugging_allow" msgid="4573224609684957886">"Lejo"</string>
     <string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Korrigjimi përmes Wi-Fi nuk lejohet"</string>
     <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"Përdoruesi i identifikuar aktualisht në këtë pajisje nuk mund ta aktivizojë korrigjimin përmes Wi-Fi. Për ta përdorur këtë veçori, kalo te përdoruesi parësor."</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 51124aa..06eeb0d 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -26,7 +26,7 @@
     <string name="status_bar_latest_events_title" msgid="202755896454005436">"Eslatmalar"</string>
     <string name="battery_low_title" msgid="6891106956328275225">"Batareya tez orada tugaydi"</string>
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> qoldi"</string>
-    <string name="battery_low_percent_format_hybrid" msgid="3985614339605686167">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> (joriy holatda taxminan <xliff:g id="TIME">%2$s</xliff:g> qoldi)"</string>
+    <string name="battery_low_percent_format_hybrid" msgid="3985614339605686167">"Batareya qivvati – <xliff:g id="PERCENTAGE">%1$s</xliff:g>, tugashiga taxminan <xliff:g id="TIME">%2$s</xliff:g> qoldi"</string>
     <string name="battery_low_percent_format_hybrid_short" msgid="5917433188456218857">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> (taxminan <xliff:g id="TIME">%2$s</xliff:g> qoldi)"</string>
     <string name="battery_low_percent_format_saver_started" msgid="4968468824040940688">"<xliff:g id="PERCENTAGE">%s</xliff:g> qoldi. Quvvat tejash rejimi yoniq."</string>
     <string name="invalid_charger" msgid="4370074072117767416">"USB orqali quvvatlash imkonsiz. Qurilmangiz bilan kelgan quvvatlash moslamasidan foydalaning."</string>
@@ -700,13 +700,13 @@
     <string name="inline_block_button" msgid="479892866568378793">"Bloklash"</string>
     <string name="inline_keep_button" msgid="299631874103662170">"Ha"</string>
     <string name="inline_minimize_button" msgid="1474436209299333445">"Kichraytirish"</string>
-    <string name="inline_silent_button_silent" msgid="525243786649275816">"Tovushsiz"</string>
+    <string name="inline_silent_button_silent" msgid="525243786649275816">"Sokin"</string>
     <string name="inline_silent_button_stay_silent" msgid="2129254868305468743">"Ovozsiz qolsin"</string>
     <string name="inline_silent_button_alert" msgid="5705343216858250354">"Ogohlantirish"</string>
     <string name="inline_silent_button_keep_alerting" msgid="6577845442184724992">"Signal berishda davom etilsin"</string>
     <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Bildirishnoma kelmasin"</string>
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Bu ilovadan keladigan bildirishnomalar chiqaversinmi?"</string>
-    <string name="notification_silence_title" msgid="8608090968400832335">"Tovushsiz"</string>
+    <string name="notification_silence_title" msgid="8608090968400832335">"Sokin"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Standart"</string>
     <string name="notification_bubble_title" msgid="8330481035191903164">"Pufaklar"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Tovush yoki tebranishsiz"</string>
@@ -718,8 +718,8 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Sozlamalar"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Muhim"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ilovasida suhbat funksiyalari ishlamaydi"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Avvalgi bulutchalar topilmadi"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Bu yerda oxirgi va yopilgan bulutcha shaklidagi bildirishnomalar chiqadi"</string>
+    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Hech qanday bulutcha topilmadi"</string>
+    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Eng oxirgi va yopilgan bulutchali chatlar shu yerda chiqadi"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Bu bildirishnomalarni tahrirlash imkonsiz."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Ushbu bildirishnomalar guruhi bu yerda sozlanmaydi"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Ishonchli bildirishnoma"</string>
diff --git a/services/core/Android.bp b/services/core/Android.bp
index 77cb125..6adf66c 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -210,17 +210,3 @@
         "java/com/android/server/net/LockdownVpnTracker.java",
     ],
 }
-
-java_library {
-    name: "service-connectivity",
-    srcs: [
-        ":connectivity-service-srcs",
-    ],
-    installable: true,
-    libs: [
-        "android.net.ipsec.ike",
-        "services.core",
-        "services.net",
-        "unsupportedappusage",
-    ],
-}
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index 651f941..d09f44f 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -3369,7 +3369,9 @@
                     if (mMaxDelayTime < thisDelayTime) {
                         mMaxDelayTime = thisDelayTime;
                     }
-                    deliverAlarmsLocked(mPendingNonWakeupAlarms, nowELAPSED);
+                    ArrayList<Alarm> triggerList =
+                            (ArrayList<Alarm>) mPendingNonWakeupAlarms.clone();
+                    deliverAlarmsLocked(triggerList, nowELAPSED);
                     mPendingNonWakeupAlarms.clear();
                 }
                 if (mNonInteractiveStartTime > 0) {
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 2e1fbb7..26c0e59 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -83,6 +83,7 @@
 import android.net.ConnectivityDiagnosticsManager.DataStallReport;
 import android.net.ConnectivityManager;
 import android.net.DataStallReportParcelable;
+import android.net.DnsResolverServiceManager;
 import android.net.ICaptivePortal;
 import android.net.IConnectivityDiagnosticsCallback;
 import android.net.IConnectivityManager;
@@ -201,7 +202,6 @@
 import com.android.server.connectivity.KeepaliveTracker;
 import com.android.server.connectivity.LingerMonitor;
 import com.android.server.connectivity.MockableSystemProperties;
-import com.android.server.connectivity.MultipathPolicyTracker;
 import com.android.server.connectivity.NetworkAgentInfo;
 import com.android.server.connectivity.NetworkDiagnostics;
 import com.android.server.connectivity.NetworkNotificationManager;
@@ -442,11 +442,6 @@
     private static final int EVENT_EXPIRE_NET_TRANSITION_WAKELOCK = 24;
 
     /**
-     * Used internally to indicate the system is ready.
-     */
-    private static final int EVENT_SYSTEM_READY = 25;
-
-    /**
      * used to add a network request with a pending intent
      * obj = NetworkRequestInfo
      */
@@ -577,9 +572,8 @@
         return sMagicDecoderRing.get(what, Integer.toString(what));
     }
 
-    private static IDnsResolver getDnsResolver() {
-        return IDnsResolver.Stub
-                .asInterface(ServiceManager.getService("dnsresolver"));
+    private static IDnsResolver getDnsResolver(Context context) {
+        return IDnsResolver.Stub.asInterface(DnsResolverServiceManager.getService(context));
     }
 
     /** Handler thread used for all of the handlers below. */
@@ -661,9 +655,6 @@
     final MultinetworkPolicyTracker mMultinetworkPolicyTracker;
 
     @VisibleForTesting
-    final MultipathPolicyTracker mMultipathPolicyTracker;
-
-    @VisibleForTesting
     final Map<IBinder, ConnectivityDiagnosticsCallbackInfo> mConnectivityDiagnosticsCallbacks =
             new HashMap<>();
 
@@ -955,7 +946,7 @@
 
     public ConnectivityService(Context context, INetworkManagementService netManager,
             INetworkStatsService statsService, INetworkPolicyManager policyManager) {
-        this(context, netManager, statsService, policyManager, getDnsResolver(),
+        this(context, netManager, statsService, policyManager, getDnsResolver(context),
                 new IpConnectivityLog(), NetdService.getInstance(), new Dependencies());
     }
 
@@ -1167,8 +1158,6 @@
                 mContext, mHandler, () -> rematchForAvoidBadWifiUpdate());
         mMultinetworkPolicyTracker.start();
 
-        mMultipathPolicyTracker = new MultipathPolicyTracker(mContext, mHandler);
-
         mDnsManager = new DnsManager(mContext, mDnsResolver);
         registerPrivateDnsSettingsCallbacks();
     }
@@ -1803,9 +1792,9 @@
 
     private INetworkManagementEventObserver mDataActivityObserver = new BaseNetworkObserver() {
         @Override
-        public void interfaceClassDataActivityChanged(String label, boolean active, long tsNanos) {
-            int deviceType = Integer.parseInt(label);
-            sendDataActivityBroadcast(deviceType, active, tsNanos);
+        public void interfaceClassDataActivityChanged(int networkType, boolean active, long tsNanos,
+                int uid) {
+            sendDataActivityBroadcast(networkType, active, tsNanos);
         }
     };
 
@@ -2314,10 +2303,13 @@
      */
     @VisibleForTesting
     public void systemReadyInternal() {
-        // Let PermissionMonitor#startMonitoring() running in the beginning of the systemReady
-        // before MultipathPolicyTracker.start(). Since mApps in PermissionMonitor needs to be
-        // populated first to ensure that listening network request which is sent by
-        // MultipathPolicyTracker won't be added NET_CAPABILITY_FOREGROUND capability.
+        // Since mApps in PermissionMonitor needs to be populated first to ensure that
+        // listening network request which is sent by MultipathPolicyTracker won't be added
+        // NET_CAPABILITY_FOREGROUND capability. Thus, MultipathPolicyTracker.start() must
+        // be called after PermissionMonitor#startMonitoring().
+        // Calling PermissionMonitor#startMonitoring() in systemReadyInternal() and the
+        // MultipathPolicyTracker.start() is called in NetworkPolicyManagerService#systemReady()
+        // to ensure the tracking will be initialized correctly.
         mPermissionMonitor.startMonitoring();
         mProxyTracker.loadGlobalProxy();
         registerNetdEventCallback();
@@ -2336,8 +2328,6 @@
 
         // Create network requests for always-on networks.
         mHandler.sendMessage(mHandler.obtainMessage(EVENT_CONFIGURE_ALWAYS_ON_NETWORKS));
-
-        mHandler.sendMessage(mHandler.obtainMessage(EVENT_SYSTEM_READY));
     }
 
     /**
@@ -2637,7 +2627,6 @@
         dumpAvoidBadWifiSettings(pw);
 
         pw.println();
-        mMultipathPolicyTracker.dump(pw);
 
         if (ArrayUtils.contains(args, SHORT_ARG) == false) {
             pw.println();
@@ -4185,11 +4174,13 @@
             return ConnectivityManager.MULTIPATH_PREFERENCE_UNMETERED;
         }
 
-        Integer networkPreference = mMultipathPolicyTracker.getMultipathPreference(network);
-        if (networkPreference != null) {
+        final NetworkPolicyManager netPolicyManager =
+                 mContext.getSystemService(NetworkPolicyManager.class);
+
+        final int networkPreference = netPolicyManager.getMultipathPreference(network);
+        if (networkPreference != 0) {
             return networkPreference;
         }
-
         return mMultinetworkPolicyTracker.getMeteredMultipathPreference();
     }
 
@@ -4293,10 +4284,6 @@
                     mKeepaliveTracker.handleStopKeepalive(nai, slot, reason);
                     break;
                 }
-                case EVENT_SYSTEM_READY: {
-                    mMultipathPolicyTracker.start();
-                    break;
-                }
                 case EVENT_REVALIDATE_NETWORK: {
                     handleReportNetworkConnectivity((Network) msg.obj, msg.arg1, toBool(msg.arg2));
                     break;
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 636da6f..1ea4a89 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -187,10 +187,10 @@
     /** Set of interfaces with active alerts. */
     @GuardedBy("mQuotaLock")
     private HashMap<String, Long> mActiveAlerts = Maps.newHashMap();
-    /** Set of UIDs denylisted on metered networks. */
+    /** Set of UIDs denied on metered networks. */
     @GuardedBy("mRulesLock")
     private SparseBooleanArray mUidRejectOnMetered = new SparseBooleanArray();
-    /** Set of UIDs allowlisted on metered networks. */
+    /** Set of UIDs allowed on metered networks. */
     @GuardedBy("mRulesLock")
     private SparseBooleanArray mUidAllowOnMetered = new SparseBooleanArray();
     /** Set of UIDs with cleartext penalties. */
@@ -396,22 +396,12 @@
      * Notify our observers of a change in the data activity state of the interface
      */
     private void notifyInterfaceClassActivity(int type, boolean isActive, long tsNanos,
-            int uid, boolean fromRadio) {
+            int uid) {
         final boolean isMobile = ConnectivityManager.isNetworkTypeMobile(type);
         int powerState = isActive
                 ? DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH
                 : DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
         if (isMobile) {
-            if (!fromRadio) {
-                if (mMobileActivityFromRadio) {
-                    // If this call is not coming from a report from the radio itself, but we
-                    // have previously received reports from the radio, then we will take the
-                    // power state to just be whatever the radio last reported.
-                    powerState = mLastPowerStateFromRadio;
-                }
-            } else {
-                mMobileActivityFromRadio = true;
-            }
             if (mLastPowerStateFromRadio != powerState) {
                 mLastPowerStateFromRadio = powerState;
                 try {
@@ -431,15 +421,9 @@
             }
         }
 
-        if (!isMobile || fromRadio || !mMobileActivityFromRadio) {
-            // Report the change in data activity.  We don't do this if this is a change
-            // on the mobile network, that is not coming from the radio itself, and we
-            // have previously seen change reports from the radio.  In that case only
-            // the radio is the authority for the current state.
-            final boolean active = isActive;
-            invokeForAllObservers(o -> o.interfaceClassDataActivityChanged(
-                    Integer.toString(type), active, tsNanos));
-        }
+        final boolean active = isActive;
+        invokeForAllObservers(o -> o.interfaceClassDataActivityChanged(
+                type, active, tsNanos, uid));
 
         boolean report = false;
         synchronized (mIdleTimerLock) {
@@ -577,13 +561,13 @@
             }
             if (uidRejectOnQuota != null) {
                 for (int i = 0; i < uidRejectOnQuota.size(); i++) {
-                    setUidMeteredNetworkDenylist(uidRejectOnQuota.keyAt(i),
+                    setUidOnMeteredNetworkDenylist(uidRejectOnQuota.keyAt(i),
                             uidRejectOnQuota.valueAt(i));
                 }
             }
             if (uidAcceptOnQuota != null) {
                 for (int i = 0; i < uidAcceptOnQuota.size(); i++) {
-                    setUidMeteredNetworkAllowlist(uidAcceptOnQuota.keyAt(i),
+                    setUidOnMeteredNetworkAllowlist(uidAcceptOnQuota.keyAt(i),
                             uidAcceptOnQuota.valueAt(i));
                 }
             }
@@ -671,7 +655,7 @@
                 timestampNanos = timestamp;
             }
             mDaemonHandler.post(() ->
-                    notifyInterfaceClassActivity(label, isActive, timestampNanos, uid, false));
+                    notifyInterfaceClassActivity(label, isActive, timestampNanos, uid));
         }
 
         @Override
@@ -1157,7 +1141,7 @@
                 mNetworkActive = false;
             }
             mDaemonHandler.post(() -> notifyInterfaceClassActivity(type, true,
-                    SystemClock.elapsedRealtimeNanos(), -1, false));
+                    SystemClock.elapsedRealtimeNanos(), -1));
         }
     }
 
@@ -1181,7 +1165,7 @@
             }
             mActiveIdleTimers.remove(iface);
             mDaemonHandler.post(() -> notifyInterfaceClassActivity(params.type, false,
-                    SystemClock.elapsedRealtimeNanos(), -1, false));
+                    SystemClock.elapsedRealtimeNanos(), -1));
         }
     }
 
@@ -1304,14 +1288,14 @@
         }
     }
 
-    private void setUidOnMeteredNetworkList(int uid, boolean denylist, boolean enable) {
+    private void setUidOnMeteredNetworkList(int uid, boolean allowlist, boolean enable) {
         NetworkStack.checkNetworkStackPermission(mContext);
 
         synchronized (mQuotaLock) {
             boolean oldEnable;
             SparseBooleanArray quotaList;
             synchronized (mRulesLock) {
-                quotaList = denylist ? mUidRejectOnMetered : mUidAllowOnMetered;
+                quotaList = allowlist ?  mUidAllowOnMetered : mUidRejectOnMetered;
                 oldEnable = quotaList.get(uid, false);
             }
             if (oldEnable == enable) {
@@ -1321,18 +1305,18 @@
 
             Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "inetd bandwidth");
             try {
-                if (denylist) {
-                    if (enable) {
-                        mNetdService.bandwidthAddNaughtyApp(uid);
-                    } else {
-                        mNetdService.bandwidthRemoveNaughtyApp(uid);
-                    }
-                } else {
+                if (allowlist) {
                     if (enable) {
                         mNetdService.bandwidthAddNiceApp(uid);
                     } else {
                         mNetdService.bandwidthRemoveNiceApp(uid);
                     }
+                } else {
+                    if (enable) {
+                        mNetdService.bandwidthAddNaughtyApp(uid);
+                    } else {
+                        mNetdService.bandwidthRemoveNaughtyApp(uid);
+                    }
                 }
                 synchronized (mRulesLock) {
                     if (enable) {
@@ -1350,13 +1334,13 @@
     }
 
     @Override
-    public void setUidMeteredNetworkDenylist(int uid, boolean enable) {
-        setUidOnMeteredNetworkList(uid, true, enable);
+    public void setUidOnMeteredNetworkDenylist(int uid, boolean enable) {
+        setUidOnMeteredNetworkList(uid, false, enable);
     }
 
     @Override
-    public void setUidMeteredNetworkAllowlist(int uid, boolean enable) {
-        setUidOnMeteredNetworkList(uid, false, enable);
+    public void setUidOnMeteredNetworkAllowlist(int uid, boolean enable) {
+        setUidOnMeteredNetworkList(uid, true, enable);
     }
 
     @Override
@@ -1779,7 +1763,7 @@
             } else {
                 ruleName = "deny";
             }
-        } else { // Denylist mode
+        } else { // Deny mode
             if (rule == FIREWALL_RULE_DENY) {
                 ruleName = "deny";
             } else {
@@ -1866,8 +1850,8 @@
             pw.print("Active alert ifaces: "); pw.println(mActiveAlerts.toString());
             pw.print("Data saver mode: "); pw.println(mDataSaverMode);
             synchronized (mRulesLock) {
-                dumpUidRuleOnQuotaLocked(pw, "denylist", mUidRejectOnMetered);
-                dumpUidRuleOnQuotaLocked(pw, "allowlist", mUidAllowOnMetered);
+                dumpUidRuleOnQuotaLocked(pw, "denied UIDs", mUidRejectOnMetered);
+                dumpUidRuleOnQuotaLocked(pw, "allowed UIDs", mUidAllowOnMetered);
             }
         }
 
@@ -1920,7 +1904,7 @@
     private void dumpUidRuleOnQuotaLocked(PrintWriter pw, String name, SparseBooleanArray list) {
         pw.print("UID bandwith control ");
         pw.print(name);
-        pw.print(" rule: [");
+        pw.print(": [");
         final int size = list.size();
         for (int i = 0; i < size; i++) {
             pw.print(list.keyAt(i));
diff --git a/services/core/java/com/android/server/OWNERS b/services/core/java/com/android/server/OWNERS
index 85523f7..a82e146 100644
--- a/services/core/java/com/android/server/OWNERS
+++ b/services/core/java/com/android/server/OWNERS
@@ -23,6 +23,7 @@
 per-file *Storage* = file:/core/java/android/os/storage/OWNERS
 per-file *TimeUpdate* = file:/core/java/android/app/timezone/OWNERS
 per-file ConnectivityService.java = file:/services/core/java/com/android/server/net/OWNERS
+per-file DynamicSystemService.java = file:/packages/DynamicSystemInstallationService/OWNERS
 per-file GestureLauncherService.java = file:platform/packages/apps/EmergencyInfo:/OWNERS
 per-file IpSecService.java = file:/services/core/java/com/android/server/net/OWNERS
 per-file MmsServiceBroker.java = file:/telephony/OWNERS
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index dd497a6..c8d457d 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -3298,6 +3298,9 @@
             try {
                 mVold.unlockUserKey(userId, serialNumber, encodeBytes(token),
                         encodeBytes(secret));
+            } catch (ServiceSpecificException sse) {
+                Slog.d(TAG, "Expected if the user has not unlocked the device.", sse);
+                return;
             } catch (Exception e) {
                 Slog.wtf(TAG, e);
                 return;
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index e4cdfe9..40f2428 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -13744,6 +13744,10 @@
                 // set on ION VMAs, therefore consider the entire ION heap as used kernel memory
                 kernelUsed += ionHeap;
             }
+            final long gpuUsage = Debug.getGpuTotalUsageKb();
+            if (gpuUsage >= 0) {
+                pw.print("      GPU: "); pw.println(stringifyKBSize(gpuUsage));
+            }
             final long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
                     - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
                     - kernelUsed - memInfo.getZramTotalSizeKb();
@@ -14552,6 +14556,12 @@
             // set on ION VMAs, therefore consider the entire ION heap as used kernel memory
             kernelUsed += ionHeap;
         }
+        final long gpuUsage = Debug.getGpuTotalUsageKb();
+        if (gpuUsage >= 0) {
+            memInfoBuilder.append("       GPU: ");
+            memInfoBuilder.append(stringifyKBSize(gpuUsage));
+            memInfoBuilder.append("\n");
+        }
         memInfoBuilder.append("  Used RAM: ");
         memInfoBuilder.append(stringifyKBSize(
                                   totalPss - cachedPss + kernelUsed));
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index a2e8216..58f3894 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -387,7 +387,7 @@
                 ActiveUids uids = mTmpUidRecords;
                 uids.clear();
                 uids.put(uidRec.uid, uidRec);
-                updateUidsLocked(uids, now);
+                updateUidsLocked(uids, SystemClock.elapsedRealtime());
                 mProcessList.incrementProcStateSeqAndNotifyAppsLocked(uids);
             }
         }
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index 5447605..26f5c4c 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -16,6 +16,7 @@
 package com.android.server.audio;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.bluetooth.BluetoothA2dp;
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothHeadset;
@@ -25,19 +26,26 @@
 import android.content.Context;
 import android.content.Intent;
 import android.media.AudioDeviceAttributes;
+import android.media.AudioDeviceInfo;
+import android.media.AudioManager;
 import android.media.AudioRoutesInfo;
 import android.media.AudioSystem;
 import android.media.IAudioRoutesObserver;
+import android.media.ICapturePresetDevicesRoleDispatcher;
+import android.media.ICommunicationDeviceDispatcher;
 import android.media.IStrategyPreferredDevicesDispatcher;
 import android.media.MediaMetrics;
+import android.media.audiopolicy.AudioProductStrategy;
 import android.os.Binder;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
 import android.os.PowerManager;
+import android.os.RemoteCallbackList;
 import android.os.RemoteException;
 import android.os.SystemClock;
+import android.os.UserHandle;
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.PrintWriterPrinter;
@@ -45,8 +53,9 @@
 import com.android.internal.annotations.GuardedBy;
 
 import java.io.PrintWriter;
-import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashSet;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.NoSuchElementException;
 import java.util.Set;
@@ -71,11 +80,8 @@
     private final @NonNull Context mContext;
 
     /** Forced device usage for communications sent to AudioSystem */
-    private int mForcedUseForComm;
-    /**
-     * Externally reported force device usage state returned by getters: always consistent
-     * with requests by setters */
-    private int mForcedUseForCommExt;
+    private AudioDeviceAttributes mPreferredDeviceforComm;
+    private int mCommunicationStrategyId = -1;
 
     // Manages all connected devices, only ever accessed on the message loop
     private final AudioDeviceInventory mDeviceInventory;
@@ -131,11 +137,23 @@
         init();
     }
 
+    private void initCommunicationStrategyId() {
+        List<AudioProductStrategy> strategies = AudioProductStrategy.getAudioProductStrategies();
+        for (AudioProductStrategy strategy : strategies) {
+            if (strategy.getAudioAttributesForLegacyStreamType(AudioSystem.STREAM_VOICE_CALL)
+                    != null) {
+                mCommunicationStrategyId = strategy.getId();
+                return;
+            }
+        }
+        mCommunicationStrategyId = -1;
+    }
+
     private void init() {
         setupMessaging(mContext);
 
-        mForcedUseForComm = AudioSystem.FORCE_NONE;
-        mForcedUseForCommExt = mForcedUseForComm;
+        mPreferredDeviceforComm = null;
+        initCommunicationStrategyId();
     }
 
     /*package*/ Context getContext() {
@@ -158,15 +176,6 @@
     }
 
     /*package*/ void onAudioServerDied() {
-        // Restore forced usage for communications and record
-        synchronized (mDeviceStateLock) {
-            AudioSystem.setParameters(
-                    "BT_SCO=" + (mForcedUseForComm == AudioSystem.FORCE_BT_SCO ? "on" : "off"));
-            onSetForceUse(AudioSystem.FOR_COMMUNICATION, mForcedUseForComm,
-                          false /*fromA2dp*/, "onAudioServerDied");
-            onSetForceUse(AudioSystem.FOR_RECORD, mForcedUseForComm,
-                          false /*fromA2dp*/, "onAudioServerDied");
-        }
         // restore devices
         sendMsgNoDelay(MSG_RESTORE_DEVICES, SENDMSG_REPLACE);
     }
@@ -218,85 +227,210 @@
      * Turns speakerphone on/off
      * @param on
      * @param eventSource for logging purposes
-     * @return true if speakerphone state changed
      */
-    /*package*/ boolean setSpeakerphoneOn(IBinder cb, int pid, boolean on, String eventSource) {
-        synchronized (mDeviceStateLock) {
-            if (!addSpeakerphoneClient(cb, pid, on)) {
-                return false;
+    /*package*/ void setSpeakerphoneOn(IBinder cb, int pid, boolean on, String eventSource) {
+
+        if (AudioService.DEBUG_COMM_RTE) {
+            Log.v(TAG, "setSpeakerphoneOn, on: " + on + " pid: " + pid);
+        }
+
+        synchronized (mSetModeLock) {
+            synchronized (mDeviceStateLock) {
+                AudioDeviceAttributes device = null;
+                if (on) {
+                    device = new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_SPEAKER, "");
+                } else {
+                    CommunicationRouteClient client = getCommunicationRouteClientForPid(pid);
+                    if (client == null || !client.requestsSpeakerphone()) {
+                        return;
+                    }
+                }
+                setCommunicationRouteForClient(
+                        cb, pid, device, BtHelper.SCO_MODE_UNDEFINED, eventSource);
             }
-            if (on) {
-                // Cancel BT SCO ON request by this same client: speakerphone and BT SCO routes
-                // are mutually exclusive.
-                // See symmetrical operation for startBluetoothScoForClient_Sync().
-                mBtHelper.stopBluetoothScoForPid(pid);
-            }
-            final boolean wasOn = isSpeakerphoneOn();
-            updateSpeakerphoneOn(eventSource);
-            return (wasOn != isSpeakerphoneOn());
         }
     }
 
     /**
-     * Turns speakerphone off for a given pid and update speakerphone state.
-     * @param pid
+     * Select device for use for communication use cases.
+     * @param cb Client binder for death detection
+     * @param pid Client pid
+     * @param device Device selected or null to unselect.
+     * @param eventSource for logging purposes
      */
+    /*package*/ boolean setDeviceForCommunication(
+            IBinder cb, int pid, AudioDeviceInfo device, String eventSource) {
+
+        if (AudioService.DEBUG_COMM_RTE) {
+            Log.v(TAG, "setDeviceForCommunication, device: " + device + ", pid: " + pid);
+        }
+
+        synchronized (mSetModeLock) {
+            synchronized (mDeviceStateLock) {
+                AudioDeviceAttributes deviceAttr = null;
+                if (device != null) {
+                    deviceAttr = new AudioDeviceAttributes(device);
+                } else {
+                    CommunicationRouteClient client = getCommunicationRouteClientForPid(pid);
+                    if (client == null) {
+                        return false;
+                    }
+                }
+                setCommunicationRouteForClient(
+                        cb, pid, deviceAttr, BtHelper.SCO_MODE_UNDEFINED, eventSource);
+            }
+        }
+        return true;
+    }
+
     @GuardedBy("mDeviceStateLock")
-    private void setSpeakerphoneOffForPid(int pid) {
-        SpeakerphoneClient client = getSpeakerphoneClientForPid(pid);
+    /*package*/ void setCommunicationRouteForClient(
+                            IBinder cb, int pid, AudioDeviceAttributes device,
+                            int scoAudioMode, String eventSource) {
+
+        if (AudioService.DEBUG_COMM_RTE) {
+            Log.v(TAG, "setCommunicationRouteForClient: device: " + device);
+        }
+        AudioService.sDeviceLogger.log((new AudioEventLogger.StringEvent(
+                                        "setCommunicationRouteForClient for pid: " + pid
+                                        + " device: " + device
+                                        + " from API: " + eventSource)).printLog(TAG));
+
+        final boolean wasBtScoRequested = isBluetoothScoRequested();
+        final boolean wasSpeakerphoneRequested = isSpeakerphoneRequested();
+        CommunicationRouteClient client;
+
+
+        // Save previous client route in case of failure to start BT SCO audio
+        AudioDeviceAttributes prevClientDevice = null;
+        client = getCommunicationRouteClientForPid(pid);
+        if (client != null) {
+            prevClientDevice = client.getDevice();
+        }
+
+        if (device != null) {
+            client = addCommunicationRouteClient(cb, pid, device);
+            if (client == null) {
+                Log.w(TAG, "setCommunicationRouteForClient: could not add client for pid: "
+                        + pid + " and device: " + device);
+            }
+        } else {
+            client = removeCommunicationRouteClient(cb, true);
+        }
         if (client == null) {
             return;
         }
-        client.unregisterDeathRecipient();
-        mSpeakerphoneClients.remove(client);
-        final String eventSource = new StringBuilder("setSpeakerphoneOffForPid(")
-                .append(pid).append(")").toString();
-        updateSpeakerphoneOn(eventSource);
-    }
 
-    @GuardedBy("mDeviceStateLock")
-    private void updateSpeakerphoneOn(String eventSource) {
-        if (isSpeakerphoneOnRequested()) {
-            if (mForcedUseForComm == AudioSystem.FORCE_BT_SCO) {
-                setForceUse_Async(AudioSystem.FOR_RECORD, AudioSystem.FORCE_NONE, eventSource);
+        boolean isBtScoRequested = isBluetoothScoRequested();
+        if (isBtScoRequested && !wasBtScoRequested) {
+            if (!mBtHelper.startBluetoothSco(scoAudioMode, eventSource)) {
+                Log.w(TAG, "setCommunicationRouteForClient: failure to start BT SCO for pid: "
+                        + pid);
+                // clean up or restore previous client selection
+                if (prevClientDevice != null) {
+                    addCommunicationRouteClient(cb, pid, prevClientDevice);
+                } else {
+                    removeCommunicationRouteClient(cb, true);
+                }
+                postBroadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
             }
-            mForcedUseForComm = AudioSystem.FORCE_SPEAKER;
-        } else if (mForcedUseForComm == AudioSystem.FORCE_SPEAKER) {
-            if (mBtHelper.isBluetoothScoOn()) {
-                mForcedUseForComm = AudioSystem.FORCE_BT_SCO;
-                setForceUse_Async(
-                        AudioSystem.FOR_RECORD, AudioSystem.FORCE_BT_SCO, eventSource);
-            } else {
-                mForcedUseForComm = AudioSystem.FORCE_NONE;
+        } else if (!isBtScoRequested && wasBtScoRequested) {
+            mBtHelper.stopBluetoothSco(eventSource);
+        }
+
+        if (wasSpeakerphoneRequested != isSpeakerphoneRequested()) {
+            try {
+                mContext.sendBroadcastAsUser(
+                        new Intent(AudioManager.ACTION_SPEAKERPHONE_STATE_CHANGED)
+                                .setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY), UserHandle.ALL);
+            } catch (Exception e) {
+                Log.w(TAG, "failed to broadcast ACTION_SPEAKERPHONE_STATE_CHANGED: " + e);
             }
         }
-        mForcedUseForCommExt = mForcedUseForComm;
-        setForceUse_Async(AudioSystem.FOR_COMMUNICATION, mForcedUseForComm, eventSource);
+
+        sendLMsgNoDelay(MSG_L_UPDATE_COMMUNICATION_ROUTE, SENDMSG_QUEUE, eventSource);
     }
 
     /**
-     * Returns if speakerphone is requested ON or OFF.
-     * If the current audio mode owner is in the speakerphone client list, use this preference.
+     * Returns the device currently requested for communication use case.
+     * If the current audio mode owner is in the communication route client list,
+     * use this preference.
      * Otherwise use first client's preference (first client corresponds to latest request).
-     * Speakerphone is requested OFF if no client is in the list.
-     * @return true if speakerphone is requested ON, false otherwise
+     * null is returned if no client is in the list.
+     * @return AudioDeviceAttributes the requested device for communication.
      */
+
     @GuardedBy("mDeviceStateLock")
-    private boolean isSpeakerphoneOnRequested() {
-        if (mSpeakerphoneClients.isEmpty()) {
-            return false;
-        }
-        for (SpeakerphoneClient cl : mSpeakerphoneClients) {
+    private AudioDeviceAttributes requestedCommunicationDevice() {
+        AudioDeviceAttributes device = null;
+        for (CommunicationRouteClient cl : mCommunicationRouteClients) {
             if (cl.getPid() == mModeOwnerPid) {
-                return cl.isOn();
+                device = cl.getDevice();
             }
         }
-        return mSpeakerphoneClients.get(0).isOn();
+        if (!mCommunicationRouteClients.isEmpty() && mModeOwnerPid == 0) {
+            device = mCommunicationRouteClients.get(0).getDevice();
+        }
+
+        if (AudioService.DEBUG_COMM_RTE) {
+            Log.v(TAG, "requestedCommunicationDevice, device: "
+                    + device + " mode owner pid: " + mModeOwnerPid);
+        }
+        return device;
     }
 
-    /*package*/ boolean isSpeakerphoneOn() {
+    /**
+     * Returns the device currently requested for communication use case.
+     * @return AudioDeviceInfo the requested device for communication.
+     */
+    AudioDeviceInfo getDeviceForCommunication() {
         synchronized (mDeviceStateLock) {
-            return (mForcedUseForCommExt == AudioSystem.FORCE_SPEAKER);
+            AudioDeviceAttributes device = requestedCommunicationDevice();
+            if (device == null) {
+                return null;
+            }
+            return AudioManager.getDeviceInfoFromType(device.getType());
+        }
+    }
+
+    /**
+     * Helper method on top of requestedCommunicationDevice() indicating if
+     * speakerphone ON is currently requested or not.
+     * @return true if speakerphone ON requested, false otherwise.
+     */
+
+    private boolean isSpeakerphoneRequested() {
+        synchronized (mDeviceStateLock) {
+            AudioDeviceAttributes device = requestedCommunicationDevice();
+            return device != null
+                    && device.getType()
+                        == AudioDeviceInfo.TYPE_BUILTIN_SPEAKER;
+        }
+    }
+
+    /**
+     * Indicates if active route selection for communication is speakerphone.
+     * @return true if speakerphone is active, false otherwise.
+     */
+    /*package*/ boolean isSpeakerphoneOn() {
+        AudioDeviceAttributes device = getPreferredDeviceForComm();
+        if (device == null) {
+            return false;
+        }
+        return device.getInternalType() == AudioSystem.DEVICE_OUT_SPEAKER;
+    }
+
+    /**
+     * Helper method on top of requestedCommunicationDevice() indicating if
+     * Bluetooth SCO ON is currently requested or not.
+     * @return true if Bluetooth SCO ON is requested, false otherwise.
+     */
+    /*package*/ boolean isBluetoothScoRequested() {
+        synchronized (mDeviceStateLock) {
+            AudioDeviceAttributes device = requestedCommunicationDevice();
+            return device != null
+                    && device.getType()
+                        == AudioDeviceInfo.TYPE_BLUETOOTH_SCO;
         }
     }
 
@@ -347,7 +481,6 @@
         }
     }
 
-
     /*package*/ void postBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(
             @NonNull BluetoothDevice device, @AudioService.BtProfileConnectionState int state,
             int profile, boolean suppressNoisyIntent, int a2dpVolume) {
@@ -430,42 +563,32 @@
         sendLMsgNoDelay(MSG_L_HEARING_AID_DEVICE_CONNECTION_CHANGE_EXT, SENDMSG_QUEUE, info);
     }
 
-    // never called by system components
-    /*package*/ void setBluetoothScoOnByApp(boolean on) {
-        synchronized (mDeviceStateLock) {
-            mForcedUseForCommExt = on ? AudioSystem.FORCE_BT_SCO : AudioSystem.FORCE_NONE;
-        }
-    }
 
-    /*package*/ boolean isBluetoothScoOnForApp() {
-        synchronized (mDeviceStateLock) {
-            return mForcedUseForCommExt == AudioSystem.FORCE_BT_SCO;
-        }
-    }
+    /**
+     * Current Bluetooth SCO audio active state indicated by BtHelper via setBluetoothScoOn().
+     */
+    private boolean mBluetoothScoOn;
 
     /*package*/ void setBluetoothScoOn(boolean on, String eventSource) {
-        //Log.i(TAG, "setBluetoothScoOn: " + on + " " + eventSource);
-        synchronized (mDeviceStateLock) {
-            if (on) {
-                // do not accept SCO ON if SCO audio is not connected
-                if (!mBtHelper.isBluetoothScoOn()) {
-                    mForcedUseForCommExt = AudioSystem.FORCE_BT_SCO;
-                    return;
-                }
-                mForcedUseForComm = AudioSystem.FORCE_BT_SCO;
-            } else if (mForcedUseForComm == AudioSystem.FORCE_BT_SCO) {
-                mForcedUseForComm = isSpeakerphoneOnRequested()
-                        ? AudioSystem.FORCE_SPEAKER : AudioSystem.FORCE_NONE;
-            }
-            mForcedUseForCommExt = mForcedUseForComm;
-            AudioSystem.setParameters("BT_SCO=" + (on ? "on" : "off"));
-            sendIILMsgNoDelay(MSG_IIL_SET_FORCE_USE, SENDMSG_QUEUE,
-                    AudioSystem.FOR_COMMUNICATION, mForcedUseForComm, eventSource);
-            sendIILMsgNoDelay(MSG_IIL_SET_FORCE_USE, SENDMSG_QUEUE,
-                    AudioSystem.FOR_RECORD, mForcedUseForComm, eventSource);
+        if (AudioService.DEBUG_COMM_RTE) {
+            Log.v(TAG, "setBluetoothScoOn: " + on + " " + eventSource);
         }
-        // Un-mute ringtone stream volume
-        mAudioService.postUpdateRingerModeServiceInt();
+        synchronized (mDeviceStateLock) {
+            mBluetoothScoOn = on;
+            sendLMsgNoDelay(MSG_L_UPDATE_COMMUNICATION_ROUTE, SENDMSG_QUEUE, eventSource);
+        }
+    }
+
+    /**
+     * Indicates if active route selection for communication is Bluetooth SCO.
+     * @return true if Bluetooth SCO is active , false otherwise.
+     */
+    /*package*/ boolean isBluetoothScoOn() {
+        AudioDeviceAttributes device = getPreferredDeviceForComm();
+        if (device == null) {
+            return false;
+        }
+        return AudioSystem.DEVICE_OUT_ALL_SCO_SET.contains(device.getInternalType());
     }
 
     /*package*/ AudioRoutesInfo startWatchingRoutes(IAudioRoutesObserver observer) {
@@ -508,22 +631,38 @@
         sendLMsgNoDelay(MSG_L_A2DP_DEVICE_CONFIG_CHANGE, SENDMSG_QUEUE, device);
     }
 
-    @GuardedBy("mSetModeLock")
-    /*package*/ void startBluetoothScoForClient_Sync(IBinder cb, int scoAudioMode,
+    /*package*/ void startBluetoothScoForClient(IBinder cb, int pid, int scoAudioMode,
                 @NonNull String eventSource) {
-        synchronized (mDeviceStateLock) {
-            // Cancel speakerphone ON request by this same client: speakerphone and BT SCO routes
-            // are mutually exclusive.
-            // See symmetrical operation for setSpeakerphoneOn(true).
-            setSpeakerphoneOffForPid(Binder.getCallingPid());
-            mBtHelper.startBluetoothScoForClient(cb, scoAudioMode, eventSource);
+
+        if (AudioService.DEBUG_COMM_RTE) {
+            Log.v(TAG, "startBluetoothScoForClient_Sync, pid: " + pid);
+        }
+
+        synchronized (mSetModeLock) {
+            synchronized (mDeviceStateLock) {
+                AudioDeviceAttributes device =
+                        new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_BLUETOOTH_SCO, "");
+                setCommunicationRouteForClient(cb, pid, device, scoAudioMode, eventSource);
+            }
         }
     }
 
-    @GuardedBy("mSetModeLock")
-    /*package*/ void stopBluetoothScoForClient_Sync(IBinder cb, @NonNull String eventSource) {
-        synchronized (mDeviceStateLock) {
-            mBtHelper.stopBluetoothScoForClient(cb, eventSource);
+    /*package*/ void stopBluetoothScoForClient(
+                        IBinder cb, int pid, @NonNull String eventSource) {
+
+        if (AudioService.DEBUG_COMM_RTE) {
+            Log.v(TAG, "stopBluetoothScoForClient_Sync, pid: " + pid);
+        }
+
+        synchronized (mSetModeLock) {
+            synchronized (mDeviceStateLock) {
+                CommunicationRouteClient client = getCommunicationRouteClientForPid(pid);
+                if (client == null || !client.requestsBluetoothSco()) {
+                    return;
+                }
+                setCommunicationRouteForClient(
+                        cb, pid, null, BtHelper.SCO_MODE_UNDEFINED, eventSource);
+            }
         }
     }
 
@@ -532,10 +671,19 @@
         return mDeviceInventory.setPreferredDevicesForStrategySync(strategy, devices);
     }
 
+    /*package*/ void postSetPreferredDevicesForStrategy(int strategy,
+            @NonNull List<AudioDeviceAttributes> devices) {
+        sendILMsgNoDelay(MSG_IL_SET_PREF_DEVICES_FOR_STRATEGY, SENDMSG_REPLACE, strategy, devices);
+    }
+
     /*package*/ int removePreferredDevicesForStrategySync(int strategy) {
         return mDeviceInventory.removePreferredDevicesForStrategySync(strategy);
     }
 
+    /*package*/ void postRemovePreferredDevicesForStrategy(int strategy) {
+        sendIMsgNoDelay(MSG_I_REMOVE_PREF_DEVICES_FOR_STRATEGY, SENDMSG_REPLACE, strategy);
+    }
+
     /*package*/ void registerStrategyPreferredDevicesDispatcher(
             @NonNull IStrategyPreferredDevicesDispatcher dispatcher) {
         mDeviceInventory.registerStrategyPreferredDevicesDispatcher(dispatcher);
@@ -546,6 +694,64 @@
         mDeviceInventory.unregisterStrategyPreferredDevicesDispatcher(dispatcher);
     }
 
+    /*package*/ int setPreferredDevicesForCapturePresetSync(int capturePreset,
+            @NonNull List<AudioDeviceAttributes> devices) {
+        return mDeviceInventory.setPreferredDevicesForCapturePresetSync(capturePreset, devices);
+    }
+
+    /*package*/ int clearPreferredDevicesForCapturePresetSync(int capturePreset) {
+        return mDeviceInventory.clearPreferredDevicesForCapturePresetSync(capturePreset);
+    }
+
+    /*package*/ void registerCapturePresetDevicesRoleDispatcher(
+            @NonNull ICapturePresetDevicesRoleDispatcher dispatcher) {
+        mDeviceInventory.registerCapturePresetDevicesRoleDispatcher(dispatcher);
+    }
+
+    /*package*/ void unregisterCapturePresetDevicesRoleDispatcher(
+            @NonNull ICapturePresetDevicesRoleDispatcher dispatcher) {
+        mDeviceInventory.unregisterCapturePresetDevicesRoleDispatcher(dispatcher);
+    }
+
+    /*package*/ void registerCommunicationDeviceDispatcher(
+            @NonNull ICommunicationDeviceDispatcher dispatcher) {
+        mCommDevDispatchers.register(dispatcher);
+    }
+
+    /*package*/ void unregisterCommunicationDeviceDispatcher(
+            @NonNull ICommunicationDeviceDispatcher dispatcher) {
+        mCommDevDispatchers.unregister(dispatcher);
+    }
+
+    // Monitoring of communication device
+    final RemoteCallbackList<ICommunicationDeviceDispatcher> mCommDevDispatchers =
+            new RemoteCallbackList<ICommunicationDeviceDispatcher>();
+
+    // portId of the device currently selected for communication: avoids broadcasting changes
+    // when same communication route is applied
+    @GuardedBy("mDeviceStateLock")
+    int mCurCommunicationPortId = -1;
+
+    @GuardedBy("mDeviceStateLock")
+    private void dispatchCommunicationDevice() {
+        AudioDeviceInfo device = getDeviceForCommunication();
+        int portId = (getDeviceForCommunication() == null) ? 0 : device.getId();
+        if (portId == mCurCommunicationPortId) {
+            return;
+        }
+        mCurCommunicationPortId = portId;
+
+        final int nbDispatchers = mCommDevDispatchers.beginBroadcast();
+        for (int i = 0; i < nbDispatchers; i++) {
+            try {
+                mCommDevDispatchers.getBroadcastItem(i)
+                        .dispatchCommunicationDeviceChanged(portId);
+            } catch (RemoteException e) {
+            }
+        }
+        mCommDevDispatchers.finishBroadcast();
+    }
+
     //---------------------------------------------------------------------
     // Communication with (to) AudioService
     //TODO check whether the AudioService methods are candidates to move here
@@ -676,12 +882,8 @@
                 hearingAidProfile);
     }
 
-    /*package*/ void postScoClientDied(Object obj) {
-        sendLMsgNoDelay(MSG_L_SCOCLIENT_DIED, SENDMSG_QUEUE, obj);
-    }
-
-    /*package*/ void postSpeakerphoneClientDied(Object obj) {
-        sendLMsgNoDelay(MSG_L_SPEAKERPHONE_CLIENT_DIED, SENDMSG_QUEUE, obj);
+    /*package*/ void postCommunicationRouteClientDied(CommunicationRouteClient client) {
+        sendLMsgNoDelay(MSG_L_COMMUNICATION_ROUTE_CLIENT_DIED, SENDMSG_QUEUE, client);
     }
 
     /*package*/ void postSaveSetPreferredDevicesForStrategy(int strategy,
@@ -694,6 +896,17 @@
         sendIMsgNoDelay(MSG_I_SAVE_REMOVE_PREF_DEVICES_FOR_STRATEGY, SENDMSG_QUEUE, strategy);
     }
 
+    /*package*/ void postSaveSetPreferredDevicesForCapturePreset(
+            int capturePreset, List<AudioDeviceAttributes> devices) {
+        sendILMsgNoDelay(
+                MSG_IL_SAVE_PREF_DEVICES_FOR_CAPTURE_PRESET, SENDMSG_QUEUE, capturePreset, devices);
+    }
+
+    /*package*/ void postSaveClearPreferredDevicesForCapturePreset(int capturePreset) {
+        sendIMsgNoDelay(
+                MSG_I_SAVE_CLEAR_PREF_DEVICES_FOR_CAPTURE_PRESET, SENDMSG_QUEUE, capturePreset);
+    }
+
     //---------------------------------------------------------------------
     // Method forwarding between the helper classes (BtHelper, AudioDeviceInventory)
     // only call from a "handle"* method or "on"* method
@@ -790,15 +1003,17 @@
 
         mDeviceInventory.dump(pw, prefix);
 
-        pw.println("\n" + prefix + "mForcedUseForComm: "
-                +  AudioSystem.forceUseConfigToString(mForcedUseForComm));
-        pw.println(prefix + "mForcedUseForCommExt: "
-                + AudioSystem.forceUseConfigToString(mForcedUseForCommExt));
-        pw.println(prefix + "mModeOwnerPid: " + mModeOwnerPid);
-        pw.println(prefix + "Speakerphone clients:");
-        mSpeakerphoneClients.forEach((cl) -> {
-            pw.println("  " + prefix + "pid: " + cl.getPid() + " on: "
-                        + cl.isOn() + " cb: " + cl.getBinder()); });
+        pw.println("\n" + prefix + "Communication route clients:");
+        mCommunicationRouteClients.forEach((cl) -> {
+            pw.println("  " + prefix + "pid: " + cl.getPid() + " device: "
+                        + cl.getDevice() + " cb: " + cl.getBinder()); });
+
+        pw.println("\n" + prefix + "mPreferredDeviceforComm: "
+                +  mPreferredDeviceforComm);
+        pw.println(prefix + "mCommunicationStrategyId: "
+                +  mCommunicationStrategyId);
+
+        pw.println("\n" + prefix + "mModeOwnerPid: " + mModeOwnerPid);
 
         mBtHelper.dump(pw, prefix);
     }
@@ -821,6 +1036,11 @@
                 .set(MediaMetrics.Property.FORCE_USE_MODE,
                         AudioSystem.forceUseConfigToString(config))
                 .record();
+
+        if (AudioService.DEBUG_COMM_RTE) {
+            Log.v(TAG, "onSetForceUse(useCase<" + useCase + ">, config<" + config + ">, fromA2dp<"
+                    + fromA2dp + ">, eventSource<" + eventSource + ">)");
+        }
         AudioSystem.setForceUse(useCase, config);
     }
 
@@ -886,9 +1106,13 @@
         public void handleMessage(Message msg) {
             switch (msg.what) {
                 case MSG_RESTORE_DEVICES:
-                    synchronized (mDeviceStateLock) {
-                        mDeviceInventory.onRestoreDevices();
-                        mBtHelper.onAudioServerDiedRestoreA2dp();
+                    synchronized (mSetModeLock) {
+                        synchronized (mDeviceStateLock) {
+                            initCommunicationStrategyId();
+                            mDeviceInventory.onRestoreDevices();
+                            mBtHelper.onAudioServerDiedRestoreA2dp();
+                            onUpdateCommunicationRoute("MSG_RESTORE_DEVICES");
+                        }
                     }
                     break;
                 case MSG_L_SET_WIRED_DEVICE_CONNECTION_STATE:
@@ -978,25 +1202,24 @@
                             if (mModeOwnerPid != msg.arg1) {
                                 mModeOwnerPid = msg.arg1;
                                 if (msg.arg2 != AudioSystem.MODE_RINGTONE) {
-                                    updateSpeakerphoneOn("setNewModeOwner");
-                                }
-                                if (mModeOwnerPid != 0) {
-                                    mBtHelper.disconnectBluetoothSco(mModeOwnerPid);
+                                    onUpdateCommunicationRoute("setNewModeOwner");
                                 }
                             }
                         }
                     }
                     break;
-                case MSG_L_SCOCLIENT_DIED:
+                case MSG_L_COMMUNICATION_ROUTE_CLIENT_DIED:
                     synchronized (mSetModeLock) {
                         synchronized (mDeviceStateLock) {
-                            mBtHelper.scoClientDied(msg.obj);
+                            onCommunicationRouteClientDied((CommunicationRouteClient) msg.obj);
                         }
                     }
                     break;
-                case MSG_L_SPEAKERPHONE_CLIENT_DIED:
-                    synchronized (mDeviceStateLock) {
-                        speakerphoneClientDied(msg.obj);
+                case MSG_L_UPDATE_COMMUNICATION_ROUTE:
+                    synchronized (mSetModeLock) {
+                        synchronized (mDeviceStateLock) {
+                            onUpdateCommunicationRoute((String) msg.obj);
+                        }
                     }
                     break;
                 case MSG_TOGGLE_HDMI:
@@ -1095,9 +1318,31 @@
                     final int strategy = msg.arg1;
                     mDeviceInventory.onSaveRemovePreferredDevices(strategy);
                 } break;
+                case MSG_IL_SET_PREF_DEVICES_FOR_STRATEGY: {
+                    final int strategy = msg.arg1;
+                    final List<AudioDeviceAttributes> devices =
+                            (List<AudioDeviceAttributes>) msg.obj;
+                    setPreferredDevicesForStrategySync(strategy, devices);
+
+                } break;
+                case MSG_I_REMOVE_PREF_DEVICES_FOR_STRATEGY: {
+                    final int strategy = msg.arg1;
+                    removePreferredDevicesForStrategySync(strategy);
+                } break;
                 case MSG_CHECK_MUTE_MUSIC:
                     checkMessagesMuteMusic(0);
                     break;
+                case MSG_IL_SAVE_PREF_DEVICES_FOR_CAPTURE_PRESET: {
+                    final int capturePreset = msg.arg1;
+                    final List<AudioDeviceAttributes> devices =
+                            (List<AudioDeviceAttributes>) msg.obj;
+                    mDeviceInventory.onSaveSetPreferredDevicesForCapturePreset(
+                            capturePreset, devices);
+                } break;
+                case MSG_I_SAVE_CLEAR_PREF_DEVICES_FOR_CAPTURE_PRESET: {
+                    final int capturePreset = msg.arg1;
+                    mDeviceInventory.onSaveClearPreferredDevicesForCapturePreset(capturePreset);
+                } break;
                 default:
                     Log.wtf(TAG, "Invalid message " + msg.what);
             }
@@ -1165,15 +1410,19 @@
     // process external command to (dis)connect a hearing aid device
     private static final int MSG_L_HEARING_AID_DEVICE_CONNECTION_CHANGE_EXT = 31;
 
-    // a ScoClient died in BtHelper
-    private static final int MSG_L_SCOCLIENT_DIED = 32;
-    private static final int MSG_IL_SAVE_PREF_DEVICES_FOR_STRATEGY = 33;
-    private static final int MSG_I_SAVE_REMOVE_PREF_DEVICES_FOR_STRATEGY = 34;
+    private static final int MSG_IL_SAVE_PREF_DEVICES_FOR_STRATEGY = 32;
+    private static final int MSG_I_SAVE_REMOVE_PREF_DEVICES_FOR_STRATEGY = 33;
 
-    private static final int MSG_L_SPEAKERPHONE_CLIENT_DIED = 35;
-    private static final int MSG_CHECK_MUTE_MUSIC = 36;
-    private static final int MSG_REPORT_NEW_ROUTES_A2DP = 37;
+    private static final int MSG_L_COMMUNICATION_ROUTE_CLIENT_DIED = 34;
+    private static final int MSG_CHECK_MUTE_MUSIC = 35;
+    private static final int MSG_REPORT_NEW_ROUTES_A2DP = 36;
 
+    private static final int MSG_IL_SAVE_PREF_DEVICES_FOR_CAPTURE_PRESET = 37;
+    private static final int MSG_I_SAVE_CLEAR_PREF_DEVICES_FOR_CAPTURE_PRESET = 38;
+
+    private static final int MSG_L_UPDATE_COMMUNICATION_ROUTE = 39;
+    private static final int MSG_IL_SET_PREF_DEVICES_FOR_STRATEGY = 40;
+    private static final int MSG_I_REMOVE_PREF_DEVICES_FOR_STRATEGY = 41;
 
     private static boolean isMessageHandledUnderWakelock(int msgId) {
         switch(msgId) {
@@ -1327,14 +1576,20 @@
         }
     }
 
-    private class SpeakerphoneClient implements IBinder.DeathRecipient {
+    // List of applications requesting a specific route for communication.
+    @GuardedBy("mDeviceStateLock")
+    private final @NonNull LinkedList<CommunicationRouteClient> mCommunicationRouteClients =
+            new LinkedList<CommunicationRouteClient>();
+
+    private class CommunicationRouteClient implements IBinder.DeathRecipient {
         private final IBinder mCb;
         private final int mPid;
-        private final boolean mOn;
-        SpeakerphoneClient(IBinder cb, int pid, boolean on) {
+        private AudioDeviceAttributes mDevice;
+
+        CommunicationRouteClient(IBinder cb, int pid, AudioDeviceAttributes device) {
             mCb = cb;
             mPid = pid;
-            mOn = on;
+            mDevice = device;
         }
 
         public boolean registerDeathRecipient() {
@@ -1343,7 +1598,7 @@
                 mCb.linkToDeath(this, 0);
                 status = true;
             } catch (RemoteException e) {
-                Log.w(TAG, "SpeakerphoneClient could not link to " + mCb + " binder death");
+                Log.w(TAG, "CommunicationRouteClient could not link to " + mCb + " binder death");
             }
             return status;
         }
@@ -1352,13 +1607,13 @@
             try {
                 mCb.unlinkToDeath(this, 0);
             } catch (NoSuchElementException e) {
-                Log.w(TAG, "SpeakerphoneClient could not not unregistered to binder");
+                Log.w(TAG, "CommunicationRouteClient could not not unregistered to binder");
             }
         }
 
         @Override
         public void binderDied() {
-            postSpeakerphoneClientDied(this);
+            postCommunicationRouteClientDied(this);
         }
 
         IBinder getBinder() {
@@ -1369,29 +1624,103 @@
             return mPid;
         }
 
-        boolean isOn() {
-            return mOn;
+        AudioDeviceAttributes getDevice() {
+            return mDevice;
+        }
+
+        boolean requestsBluetoothSco() {
+            return mDevice != null
+                    && mDevice.getType()
+                        == AudioDeviceInfo.TYPE_BLUETOOTH_SCO;
+        }
+
+        boolean requestsSpeakerphone() {
+            return mDevice != null
+                    && mDevice.getType()
+                        == AudioDeviceInfo.TYPE_BUILTIN_SPEAKER;
         }
     }
 
+    // @GuardedBy("mSetModeLock")
     @GuardedBy("mDeviceStateLock")
-    private void speakerphoneClientDied(Object obj) {
-        if (obj == null) {
+    private void onCommunicationRouteClientDied(CommunicationRouteClient client) {
+        if (client == null) {
             return;
         }
         Log.w(TAG, "Speaker client died");
-        if (removeSpeakerphoneClient(((SpeakerphoneClient) obj).getBinder(), false) != null) {
-            updateSpeakerphoneOn("speakerphoneClientDied");
+        if (removeCommunicationRouteClient(client.getBinder(), false)
+                != null) {
+            onUpdateCommunicationRoute("onCommunicationRouteClientDied");
         }
     }
 
-    private SpeakerphoneClient removeSpeakerphoneClient(IBinder cb, boolean unregister) {
-        for (SpeakerphoneClient cl : mSpeakerphoneClients) {
+    /**
+     * Determines which forced usage for communication should be sent to audio policy manager
+     * as a function of current SCO audio activation state and active communication route requests.
+     * SCO audio state has the highest priority as it can result from external activation by
+     * telephony service.
+     * @return selected forced usage for communication.
+     */
+    @GuardedBy("mDeviceStateLock")
+    @Nullable private AudioDeviceAttributes getPreferredDeviceForComm() {
+        boolean btSCoOn = mBluetoothScoOn && mBtHelper.isBluetoothScoOn();
+        if (btSCoOn) {
+            // Use the SCO device known to BtHelper so that it matches exactly
+            // what has been communicated to audio policy manager. The device
+            // returned by requestedCommunicationDevice() can be a dummy SCO device if legacy
+            // APIs are used to start SCO audio.
+            AudioDeviceAttributes device = mBtHelper.getHeadsetAudioDevice();
+            if (device != null) {
+                return device;
+            }
+        }
+        AudioDeviceAttributes device = requestedCommunicationDevice();
+        if (device == null
+                || AudioSystem.DEVICE_OUT_ALL_SCO_SET.contains(device.getInternalType())) {
+            // Do not indicate BT SCO selection if SCO is requested but SCO is not ON
+            return null;
+        }
+        return device;
+    }
+
+    /**
+     * Configures audio policy manager and audio HAL according to active communication route.
+     * Always called from message Handler.
+     */
+    // @GuardedBy("mSetModeLock")
+    @GuardedBy("mDeviceStateLock")
+    private void onUpdateCommunicationRoute(String eventSource) {
+        mPreferredDeviceforComm = getPreferredDeviceForComm();
+        if (AudioService.DEBUG_COMM_RTE) {
+            Log.v(TAG, "onUpdateCommunicationRoute, mPreferredDeviceforComm: "
+                    + mPreferredDeviceforComm + " eventSource: " + eventSource);
+        }
+
+        if (mPreferredDeviceforComm == null
+                || !AudioSystem.DEVICE_OUT_ALL_SCO_SET.contains(
+                        mPreferredDeviceforComm.getInternalType())) {
+            AudioSystem.setParameters("BT_SCO=off");
+        } else {
+            AudioSystem.setParameters("BT_SCO=on");
+        }
+        if (mPreferredDeviceforComm == null) {
+            postRemovePreferredDevicesForStrategy(mCommunicationStrategyId);
+        } else {
+            postSetPreferredDevicesForStrategy(
+                    mCommunicationStrategyId, Arrays.asList(mPreferredDeviceforComm));
+        }
+        mAudioService.postUpdateRingerModeServiceInt();
+        dispatchCommunicationDevice();
+    }
+
+    private CommunicationRouteClient removeCommunicationRouteClient(
+                    IBinder cb, boolean unregister) {
+        for (CommunicationRouteClient cl : mCommunicationRouteClients) {
             if (cl.getBinder() == cb) {
                 if (unregister) {
                     cl.unregisterDeathRecipient();
                 }
-                mSpeakerphoneClients.remove(cl);
+                mCommunicationRouteClients.remove(cl);
                 return cl;
             }
         }
@@ -1399,30 +1728,25 @@
     }
 
     @GuardedBy("mDeviceStateLock")
-    private boolean addSpeakerphoneClient(IBinder cb, int pid, boolean on) {
+    private CommunicationRouteClient addCommunicationRouteClient(
+                    IBinder cb, int pid, AudioDeviceAttributes device) {
         // always insert new request at first position
-        removeSpeakerphoneClient(cb, true);
-        SpeakerphoneClient client = new SpeakerphoneClient(cb, pid, on);
+        removeCommunicationRouteClient(cb, true);
+        CommunicationRouteClient client = new CommunicationRouteClient(cb, pid, device);
         if (client.registerDeathRecipient()) {
-            mSpeakerphoneClients.add(0, client);
-            return true;
+            mCommunicationRouteClients.add(0, client);
+            return client;
         }
-        return false;
+        return null;
     }
 
     @GuardedBy("mDeviceStateLock")
-    private SpeakerphoneClient getSpeakerphoneClientForPid(int pid) {
-        for (SpeakerphoneClient cl : mSpeakerphoneClients) {
+    private CommunicationRouteClient getCommunicationRouteClientForPid(int pid) {
+        for (CommunicationRouteClient cl : mCommunicationRouteClients) {
             if (cl.getPid() == pid) {
                 return cl;
             }
         }
         return null;
     }
-
-    // List of clients requesting speakerPhone ON
-    @GuardedBy("mDeviceStateLock")
-    private final @NonNull ArrayList<SpeakerphoneClient> mSpeakerphoneClients =
-            new ArrayList<SpeakerphoneClient>();
-
 }
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index fbf07cc..82586b8 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -31,6 +31,7 @@
 import android.media.AudioRoutesInfo;
 import android.media.AudioSystem;
 import android.media.IAudioRoutesObserver;
+import android.media.ICapturePresetDevicesRoleDispatcher;
 import android.media.IStrategyPreferredDevicesDispatcher;
 import android.media.MediaMetrics;
 import android.os.Binder;
@@ -140,6 +141,10 @@
     private final ArrayMap<Integer, List<AudioDeviceAttributes>> mPreferredDevices =
             new ArrayMap<>();
 
+    // List of preferred devices of capture preset
+    private final ArrayMap<Integer, List<AudioDeviceAttributes>> mPreferredDevicesForCapturePreset =
+            new ArrayMap<>();
+
     // the wrapper for AudioSystem static methods, allows us to spy AudioSystem
     private final @NonNull AudioSystemAdapter mAudioSystem;
 
@@ -154,6 +159,10 @@
     final RemoteCallbackList<IStrategyPreferredDevicesDispatcher> mPrefDevDispatchers =
             new RemoteCallbackList<IStrategyPreferredDevicesDispatcher>();
 
+    // Monitoring of devices for role and capture preset
+    final RemoteCallbackList<ICapturePresetDevicesRoleDispatcher> mDevRoleCapturePresetDispatchers =
+            new RemoteCallbackList<ICapturePresetDevicesRoleDispatcher>();
+
     /*package*/ AudioDeviceInventory(@NonNull AudioDeviceBroker broker) {
         mDeviceBroker = broker;
         mAudioSystem = AudioSystemAdapter.getDefaultAdapter();
@@ -243,6 +252,9 @@
             pw.println("  " + prefix + " type:0x" + Integer.toHexString(keyType)
                     + " (" + AudioSystem.getDeviceName(keyType)
                     + ") addr:" + valueAddress); });
+        mPreferredDevicesForCapturePreset.forEach((capturePreset, devices) -> {
+            pw.println("  " + prefix + "capturePreset:" + capturePreset
+                    + " devices:" + devices); });
     }
 
     //------------------------------------------------------------
@@ -270,6 +282,9 @@
                 mAudioSystem.setDevicesRoleForStrategy(
                         strategy, AudioSystem.DEVICE_ROLE_PREFERRED, devices); });
         }
+        synchronized (mPreferredDevicesForCapturePreset) {
+            // TODO: call audiosystem to restore
+        }
     }
 
     // only public for mocking/spying
@@ -613,12 +628,30 @@
         dispatchPreferredDevice(strategy, new ArrayList<AudioDeviceAttributes>());
     }
 
+    /*package*/ void onSaveSetPreferredDevicesForCapturePreset(
+            int capturePreset, @NonNull List<AudioDeviceAttributes> devices) {
+        mPreferredDevicesForCapturePreset.put(capturePreset, devices);
+        dispatchDevicesRoleForCapturePreset(
+                capturePreset, AudioSystem.DEVICE_ROLE_PREFERRED, devices);
+    }
+
+    /*package*/ void onSaveClearPreferredDevicesForCapturePreset(int capturePreset) {
+        mPreferredDevicesForCapturePreset.remove(capturePreset);
+        dispatchDevicesRoleForCapturePreset(
+                capturePreset, AudioSystem.DEVICE_ROLE_PREFERRED,
+                new ArrayList<AudioDeviceAttributes>());
+    }
+
     //------------------------------------------------------------
     //
 
     /*package*/ int setPreferredDevicesForStrategySync(int strategy,
             @NonNull List<AudioDeviceAttributes> devices) {
         final long identity = Binder.clearCallingIdentity();
+
+        AudioService.sDeviceLogger.log((new AudioEventLogger.StringEvent(
+                                "setPreferredDevicesForStrategySync, strategy: " + strategy
+                                + " devices: " + devices)).printLog(TAG));
         final int status = mAudioSystem.setDevicesRoleForStrategy(
                 strategy, AudioSystem.DEVICE_ROLE_PREFERRED, devices);
         Binder.restoreCallingIdentity(identity);
@@ -651,6 +684,41 @@
         mPrefDevDispatchers.unregister(dispatcher);
     }
 
+    /*package*/ int setPreferredDevicesForCapturePresetSync(
+            int capturePreset, @NonNull List<AudioDeviceAttributes> devices) {
+        final long identity = Binder.clearCallingIdentity();
+        final int status = mAudioSystem.setDevicesRoleForCapturePreset(
+                capturePreset, AudioSystem.DEVICE_ROLE_PREFERRED, devices);
+        Binder.restoreCallingIdentity(identity);
+
+        if (status == AudioSystem.SUCCESS) {
+            mDeviceBroker.postSaveSetPreferredDevicesForCapturePreset(capturePreset, devices);
+        }
+        return status;
+    }
+
+    /*package*/ int clearPreferredDevicesForCapturePresetSync(int capturePreset) {
+        final long identity = Binder.clearCallingIdentity();
+        final int status = mAudioSystem.clearDevicesRoleForCapturePreset(
+                capturePreset, AudioSystem.DEVICE_ROLE_PREFERRED);
+        Binder.restoreCallingIdentity(identity);
+
+        if (status == AudioSystem.SUCCESS) {
+            mDeviceBroker.postSaveClearPreferredDevicesForCapturePreset(capturePreset);
+        }
+        return status;
+    }
+
+    /*package*/ void registerCapturePresetDevicesRoleDispatcher(
+            @NonNull ICapturePresetDevicesRoleDispatcher dispatcher) {
+        mDevRoleCapturePresetDispatchers.register(dispatcher);
+    }
+
+    /*package*/ void unregisterCapturePresetDevicesRoleDispatcher(
+            @NonNull ICapturePresetDevicesRoleDispatcher dispatcher) {
+        mDevRoleCapturePresetDispatchers.unregister(dispatcher);
+    }
+
     /**
      * Implements the communication with AudioSystem to (dis)connect a device in the native layers
      * @param connect true if connection
@@ -1306,6 +1374,19 @@
         mPrefDevDispatchers.finishBroadcast();
     }
 
+    private void dispatchDevicesRoleForCapturePreset(
+            int capturePreset, int role, @NonNull List<AudioDeviceAttributes> devices) {
+        final int nbDispatchers = mDevRoleCapturePresetDispatchers.beginBroadcast();
+        for (int i = 0; i < nbDispatchers; ++i) {
+            try {
+                mDevRoleCapturePresetDispatchers.getBroadcastItem(i).dispatchDevicesRoleChanged(
+                        capturePreset, role, devices);
+            } catch (RemoteException e) {
+            }
+        }
+        mDevRoleCapturePresetDispatchers.finishBroadcast();
+    }
+
     //----------------------------------------------------------
     // For tests only
 
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index dda57d0..024dca7 100755
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -84,6 +84,8 @@
 import android.media.IAudioRoutesObserver;
 import android.media.IAudioServerStateDispatcher;
 import android.media.IAudioService;
+import android.media.ICapturePresetDevicesRoleDispatcher;
+import android.media.ICommunicationDeviceDispatcher;
 import android.media.IPlaybackConfigDispatcher;
 import android.media.IRecordingConfigDispatcher;
 import android.media.IRingtonePlayer;
@@ -206,6 +208,9 @@
     /** debug calls to devices APIs */
     protected static final boolean DEBUG_DEVICES = false;
 
+    /** Debug communication route */
+    protected static final boolean DEBUG_COMM_RTE = false;
+
     /** How long to delay before persisting a change in volume/ringer mode. */
     private static final int PERSIST_DELAY = 500;
 
@@ -1938,6 +1943,94 @@
         mDeviceBroker.unregisterStrategyPreferredDevicesDispatcher(dispatcher);
     }
 
+    /**
+     * @see AudioManager#setPreferredDeviceForCapturePreset(int, AudioDeviceAttributes)
+     */
+    public int setPreferredDevicesForCapturePreset(
+            int capturePreset, List<AudioDeviceAttributes> devices) {
+        if (devices == null) {
+            return AudioSystem.ERROR;
+        }
+        enforceModifyAudioRoutingPermission();
+        final String logString = String.format(
+                "setPreferredDevicesForCapturePreset u/pid:%d/%d source:%d dev:%s",
+                Binder.getCallingUid(), Binder.getCallingPid(), capturePreset,
+                devices.stream().map(e -> e.toString()).collect(Collectors.joining(",")));
+        sDeviceLogger.log(new AudioEventLogger.StringEvent(logString).printLog(TAG));
+        if (devices.stream().anyMatch(device ->
+                device.getRole() == AudioDeviceAttributes.ROLE_OUTPUT)) {
+            Log.e(TAG, "Unsupported output routing in " + logString);
+            return AudioSystem.ERROR;
+        }
+
+        final int status = mDeviceBroker.setPreferredDevicesForCapturePresetSync(
+                capturePreset, devices);
+        if (status != AudioSystem.SUCCESS) {
+            Log.e(TAG, String.format("Error %d in %s)", status, logString));
+        }
+
+        return status;
+    }
+
+    /** @see AudioManager#clearPreferredDevicesForCapturePreset(int) */
+    public int clearPreferredDevicesForCapturePreset(int capturePreset) {
+        enforceModifyAudioRoutingPermission();
+        final String logString = String.format(
+                "removePreferredDeviceForCapturePreset source:%d", capturePreset);
+        sDeviceLogger.log(new AudioEventLogger.StringEvent(logString).printLog(TAG));
+
+        final int status = mDeviceBroker.clearPreferredDevicesForCapturePresetSync(capturePreset);
+        if (status != AudioSystem.SUCCESS) {
+            Log.e(TAG, String.format("Error %d in %s", status, logString));
+        }
+        return status;
+    }
+
+    /**
+     * @see AudioManager#getPreferredDevicesForCapturePreset(int)
+     */
+    public List<AudioDeviceAttributes> getPreferredDevicesForCapturePreset(int capturePreset) {
+        enforceModifyAudioRoutingPermission();
+        List<AudioDeviceAttributes> devices = new ArrayList<>();
+        final long identity = Binder.clearCallingIdentity();
+        final int status = AudioSystem.getDevicesForRoleAndCapturePreset(
+                capturePreset, AudioSystem.DEVICE_ROLE_PREFERRED, devices);
+        Binder.restoreCallingIdentity(identity);
+        if (status != AudioSystem.SUCCESS) {
+            Log.e(TAG, String.format("Error %d in getPreferredDeviceForCapturePreset(%d)",
+                    status, capturePreset));
+            return new ArrayList<AudioDeviceAttributes>();
+        } else {
+            return devices;
+        }
+    }
+
+    /**
+     * @see AudioManager#addOnPreferredDevicesForCapturePresetChangedListener(
+     *              Executor, OnPreferredDevicesForCapturePresetChangedListener)
+     */
+    public void registerCapturePresetDevicesRoleDispatcher(
+            @Nullable ICapturePresetDevicesRoleDispatcher dispatcher) {
+        if (dispatcher == null) {
+            return;
+        }
+        enforceModifyAudioRoutingPermission();
+        mDeviceBroker.registerCapturePresetDevicesRoleDispatcher(dispatcher);
+    }
+
+    /**
+     * @see AudioManager#removeOnPreferredDevicesForCapturePresetChangedListener(
+     *              AudioManager.OnPreferredDevicesForCapturePresetChangedListener)
+     */
+    public void unregisterCapturePresetDevicesRoleDispatcher(
+            @Nullable ICapturePresetDevicesRoleDispatcher dispatcher) {
+        if (dispatcher == null) {
+            return;
+        }
+        enforceModifyAudioRoutingPermission();
+        mDeviceBroker.unregisterCapturePresetDevicesRoleDispatcher(dispatcher);
+    }
+
     /** @see AudioManager#getDevicesForAttributes(AudioAttributes) */
     public @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributes(
             @NonNull AudioAttributes attributes) {
@@ -3600,7 +3693,7 @@
         final boolean ringerModeMute = ringerMode == AudioManager.RINGER_MODE_VIBRATE
                 || ringerMode == AudioManager.RINGER_MODE_SILENT;
         final boolean shouldRingSco = ringerMode == AudioManager.RINGER_MODE_VIBRATE
-                && isBluetoothScoOn();
+                && mDeviceBroker.isBluetoothScoOn();
         // Ask audio policy engine to force use Bluetooth SCO channel if needed
         final String eventSource = "muteRingerModeStreams() from u/pid:" + Binder.getCallingUid()
                 + "/" + Binder.getCallingPid();
@@ -4176,6 +4269,115 @@
         restoreDeviceVolumeBehavior();
     }
 
+    private static final int[] VALID_COMMUNICATION_DEVICE_TYPES = {
+        AudioDeviceInfo.TYPE_BUILTIN_SPEAKER,
+        AudioDeviceInfo.TYPE_BLUETOOTH_SCO,
+        AudioDeviceInfo.TYPE_WIRED_HEADSET,
+        AudioDeviceInfo.TYPE_USB_HEADSET,
+        AudioDeviceInfo.TYPE_BUILTIN_EARPIECE,
+        AudioDeviceInfo.TYPE_WIRED_HEADPHONES,
+        AudioDeviceInfo.TYPE_HEARING_AID,
+        AudioDeviceInfo.TYPE_BLE_HEADSET,
+        AudioDeviceInfo.TYPE_USB_DEVICE,
+        AudioDeviceInfo.TYPE_BLE_SPEAKER,
+        AudioDeviceInfo.TYPE_LINE_ANALOG,
+        AudioDeviceInfo.TYPE_HDMI,
+        AudioDeviceInfo.TYPE_AUX_LINE
+    };
+
+    private boolean isValidCommunicationDevice(AudioDeviceInfo device) {
+        for (int type : VALID_COMMUNICATION_DEVICE_TYPES) {
+            if (device.getType() == type) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /** @see AudioManager#setDeviceForCommunication(int) */
+    public boolean setDeviceForCommunication(IBinder cb, int portId) {
+        final int uid = Binder.getCallingUid();
+        final int pid = Binder.getCallingPid();
+
+        AudioDeviceInfo device = null;
+        if (portId != 0) {
+            device = AudioManager.getDeviceForPortId(portId, AudioManager.GET_DEVICES_OUTPUTS);
+            if (device == null) {
+                throw new IllegalArgumentException("invalid portID " + portId);
+            }
+            if (!isValidCommunicationDevice(device)) {
+                throw new IllegalArgumentException("invalid device type " + device.getType());
+            }
+        }
+        final String eventSource = new StringBuilder("setDeviceForCommunication(")
+                .append(") from u/pid:").append(uid).append("/")
+                .append(pid).toString();
+
+        int deviceType = AudioSystem.DEVICE_OUT_DEFAULT;
+        String deviceAddress = null;
+        if (device != null) {
+            deviceType = device.getPort().type();
+            deviceAddress = device.getAddress();
+        } else {
+            AudioDeviceInfo curDevice = mDeviceBroker.getDeviceForCommunication();
+            if (curDevice != null) {
+                deviceType = curDevice.getPort().type();
+                deviceAddress = curDevice.getAddress();
+            }
+        }
+        // do not log metrics if clearing communication device while no communication device
+        // was selected
+        if (deviceType != AudioSystem.DEVICE_OUT_DEFAULT) {
+            new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE
+                    + MediaMetrics.SEPARATOR + "setDeviceForCommunication")
+                    .set(MediaMetrics.Property.DEVICE,
+                            AudioSystem.getDeviceName(deviceType))
+                    .set(MediaMetrics.Property.ADDRESS, deviceAddress)
+                    .set(MediaMetrics.Property.STATE, device != null
+                            ? MediaMetrics.Value.CONNECTED : MediaMetrics.Value.DISCONNECTED)
+                    .record();
+        }
+
+        final long ident = Binder.clearCallingIdentity();
+        boolean status =
+                mDeviceBroker.setDeviceForCommunication(cb, pid, device, eventSource);
+        Binder.restoreCallingIdentity(ident);
+        return status;
+    }
+
+    /** @see AudioManager#getDeviceForCommunication() */
+    public int getDeviceForCommunication() {
+        final long ident = Binder.clearCallingIdentity();
+        AudioDeviceInfo device = mDeviceBroker.getDeviceForCommunication();
+        Binder.restoreCallingIdentity(ident);
+        if (device == null) {
+            return 0;
+        }
+        return device.getId();
+    }
+
+    /** @see AudioManager#addOnCommunicationDeviceChangedListener(
+     *               Executor, AudioManager.OnCommunicationDeviceChangedListener)
+     */
+    public void registerCommunicationDeviceDispatcher(
+            @Nullable ICommunicationDeviceDispatcher dispatcher) {
+        if (dispatcher == null) {
+            return;
+        }
+        mDeviceBroker.registerCommunicationDeviceDispatcher(dispatcher);
+    }
+
+    /** @see AudioManager#removeOnCommunicationDeviceChangedListener(
+     *               AudioManager.OnCommunicationDeviceChangedListener)
+     */
+    public void unregisterCommunicationDeviceDispatcher(
+            @Nullable ICommunicationDeviceDispatcher dispatcher) {
+        if (dispatcher == null) {
+            return;
+        }
+        mDeviceBroker.unregisterCommunicationDeviceDispatcher(dispatcher);
+    }
+
     /** @see AudioManager#setSpeakerphoneOn(boolean) */
     public void setSpeakerphoneOn(IBinder cb, boolean on) {
         if (!checkAudioSettingsPermission("setSpeakerphoneOn()")) {
@@ -4185,10 +4387,10 @@
         // for logging only
         final int uid = Binder.getCallingUid();
         final int pid = Binder.getCallingPid();
+
         final String eventSource = new StringBuilder("setSpeakerphoneOn(").append(on)
                 .append(") from u/pid:").append(uid).append("/")
                 .append(pid).toString();
-        final boolean stateChanged = mDeviceBroker.setSpeakerphoneOn(cb, pid, on, eventSource);
         new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE
                 + MediaMetrics.SEPARATOR + "setSpeakerphoneOn")
                 .setUid(uid)
@@ -4196,17 +4398,9 @@
                 .set(MediaMetrics.Property.STATE, on
                         ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF)
                 .record();
-
-        if (stateChanged) {
-            final long ident = Binder.clearCallingIdentity();
-            try {
-                mContext.sendBroadcastAsUser(
-                        new Intent(AudioManager.ACTION_SPEAKERPHONE_STATE_CHANGED)
-                                .setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY), UserHandle.ALL);
-            } finally {
-                Binder.restoreCallingIdentity(ident);
-            }
-        }
+        final long ident = Binder.clearCallingIdentity();
+        mDeviceBroker.setSpeakerphoneOn(cb, pid, on, eventSource);
+        Binder.restoreCallingIdentity(ident);
     }
 
     /** @see AudioManager#isSpeakerphoneOn() */
@@ -4214,6 +4408,11 @@
         return mDeviceBroker.isSpeakerphoneOn();
     }
 
+
+    /** BT SCO audio state seen by apps using the deprecated API setBluetoothScoOn().
+     * @see isBluetoothScoOn() */
+    private boolean mBtScoOnByApp;
+
     /** @see AudioManager#setBluetoothScoOn(boolean) */
     public void setBluetoothScoOn(boolean on) {
         if (!checkAudioSettingsPermission("setBluetoothScoOn()")) {
@@ -4222,7 +4421,7 @@
 
         // Only enable calls from system components
         if (UserHandle.getCallingAppId() >= FIRST_APPLICATION_UID) {
-            mDeviceBroker.setBluetoothScoOnByApp(on);
+            mBtScoOnByApp = on;
             return;
         }
 
@@ -4248,7 +4447,7 @@
      * Note that it doesn't report internal state, but state seen by apps (which may have
      * called setBluetoothScoOn() */
     public boolean isBluetoothScoOn() {
-        return mDeviceBroker.isBluetoothScoOnForApp();
+        return mBtScoOnByApp || mDeviceBroker.isBluetoothScoOn();
     }
 
     // TODO investigate internal users due to deprecation of SDK API
@@ -4295,7 +4494,7 @@
                 .set(MediaMetrics.Property.SCO_AUDIO_MODE,
                         BtHelper.scoAudioModeToString(scoAudioMode))
                 .record();
-        startBluetoothScoInt(cb, scoAudioMode, eventSource);
+        startBluetoothScoInt(cb, pid, scoAudioMode, eventSource);
 
     }
 
@@ -4314,10 +4513,10 @@
                 .set(MediaMetrics.Property.SCO_AUDIO_MODE,
                         BtHelper.scoAudioModeToString(BtHelper.SCO_MODE_VIRTUAL_CALL))
                 .record();
-        startBluetoothScoInt(cb, BtHelper.SCO_MODE_VIRTUAL_CALL, eventSource);
+        startBluetoothScoInt(cb, pid, BtHelper.SCO_MODE_VIRTUAL_CALL, eventSource);
     }
 
-    void startBluetoothScoInt(IBinder cb, int scoAudioMode, @NonNull String eventSource) {
+    void startBluetoothScoInt(IBinder cb, int pid, int scoAudioMode, @NonNull String eventSource) {
         MediaMetrics.Item mmi = new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH)
                 .set(MediaMetrics.Property.EVENT, "startBluetoothScoInt")
                 .set(MediaMetrics.Property.SCO_AUDIO_MODE,
@@ -4328,9 +4527,9 @@
             mmi.set(MediaMetrics.Property.EARLY_RETURN, "permission or systemReady").record();
             return;
         }
-        synchronized (mDeviceBroker.mSetModeLock) {
-            mDeviceBroker.startBluetoothScoForClient_Sync(cb, scoAudioMode, eventSource);
-        }
+        final long ident = Binder.clearCallingIdentity();
+        mDeviceBroker.startBluetoothScoForClient(cb, pid, scoAudioMode, eventSource);
+        Binder.restoreCallingIdentity(ident);
         mmi.record();
     }
 
@@ -4345,9 +4544,9 @@
         final String eventSource =  new StringBuilder("stopBluetoothSco()")
                 .append(") from u/pid:").append(uid).append("/")
                 .append(pid).toString();
-        synchronized (mDeviceBroker.mSetModeLock) {
-            mDeviceBroker.stopBluetoothScoForClient_Sync(cb, eventSource);
-        }
+        final long ident = Binder.clearCallingIdentity();
+        mDeviceBroker.stopBluetoothScoForClient(cb, pid, eventSource);
+        Binder.restoreCallingIdentity(ident);
         new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH)
                 .setUid(uid)
                 .setPid(pid)
@@ -4773,8 +4972,7 @@
         switch (mPlatformType) {
         case AudioSystem.PLATFORM_VOICE:
             if (isInCommunication()) {
-                if (AudioSystem.getForceUse(AudioSystem.FOR_COMMUNICATION)
-                        == AudioSystem.FORCE_BT_SCO) {
+                if (mDeviceBroker.isBluetoothScoOn()) {
                     // Log.v(TAG, "getActiveStreamType: Forcing STREAM_BLUETOOTH_SCO...");
                     return AudioSystem.STREAM_BLUETOOTH_SCO;
                 } else {
@@ -4810,8 +5008,7 @@
             }
         default:
             if (isInCommunication()) {
-                if (AudioSystem.getForceUse(AudioSystem.FOR_COMMUNICATION)
-                        == AudioSystem.FORCE_BT_SCO) {
+                if (mDeviceBroker.isBluetoothScoOn()) {
                     if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_BLUETOOTH_SCO");
                     return AudioSystem.STREAM_BLUETOOTH_SCO;
                 } else {
@@ -7581,6 +7778,7 @@
         pw.print("  mHasVibrator="); pw.println(mHasVibrator);
         pw.print("  mVolumePolicy="); pw.println(mVolumePolicy);
         pw.print("  mAvrcpAbsVolSupported="); pw.println(mAvrcpAbsVolSupported);
+        pw.print("  mBtScoOnByApp="); pw.println(mBtScoOnByApp);
         pw.print("  mIsSingleVolume="); pw.println(mIsSingleVolume);
         pw.print("  mUseFixedVolume="); pw.println(mUseFixedVolume);
         pw.print("  mFixedVolumeDevices="); pw.println(dumpDeviceTypes(mFixedVolumeDevices));
diff --git a/services/core/java/com/android/server/audio/AudioSystemAdapter.java b/services/core/java/com/android/server/audio/AudioSystemAdapter.java
index a0e1ca7..ae64990 100644
--- a/services/core/java/com/android/server/audio/AudioSystemAdapter.java
+++ b/services/core/java/com/android/server/audio/AudioSystemAdapter.java
@@ -101,6 +101,40 @@
     }
 
     /**
+     * Same as (@link AudioSystem#setDevicesRoleForCapturePreset(int, List))
+     * @param capturePreset
+     * @param role
+     * @param devices
+     * @return
+     */
+    public int setDevicesRoleForCapturePreset(int capturePreset, int role,
+                                              @NonNull List<AudioDeviceAttributes> devices) {
+        return AudioSystem.setDevicesRoleForCapturePreset(capturePreset, role, devices);
+    }
+
+    /**
+     * Same as {@link AudioSystem#removeDevicesRoleForCapturePreset(int, int)}
+     * @param capturePreset
+     * @param role
+     * @param devicesToRemove
+     * @return
+     */
+    public int removeDevicesRoleForCapturePreset(
+            int capturePreset, int role, @NonNull List<AudioDeviceAttributes> devicesToRemove) {
+        return AudioSystem.removeDevicesRoleForCapturePreset(capturePreset, role, devicesToRemove);
+    }
+
+    /**
+     * Same as {@link AudioSystem#}
+     * @param capturePreset
+     * @param role
+     * @return
+     */
+    public int clearDevicesRoleForCapturePreset(int capturePreset, int role) {
+        return AudioSystem.clearDevicesRoleForCapturePreset(capturePreset, role);
+    }
+
+    /**
      * Same as {@link AudioSystem#setParameters(String)}
      * @param keyValuePairs
      * @return
diff --git a/services/core/java/com/android/server/audio/BtHelper.java b/services/core/java/com/android/server/audio/BtHelper.java
index 7616557..c9a1fcf 100644
--- a/services/core/java/com/android/server/audio/BtHelper.java
+++ b/services/core/java/com/android/server/audio/BtHelper.java
@@ -27,11 +27,10 @@
 import android.bluetooth.BluetoothHearingAid;
 import android.bluetooth.BluetoothProfile;
 import android.content.Intent;
+import android.media.AudioDeviceAttributes;
 import android.media.AudioManager;
 import android.media.AudioSystem;
 import android.os.Binder;
-import android.os.IBinder;
-import android.os.RemoteException;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.util.Log;
@@ -39,9 +38,7 @@
 import com.android.internal.annotations.GuardedBy;
 
 import java.io.PrintWriter;
-import java.util.ArrayList;
 import java.util.List;
-import java.util.NoSuchElementException;
 import java.util.Objects;
 
 /**
@@ -58,10 +55,6 @@
         mDeviceBroker = broker;
     }
 
-    // List of clients having issued a SCO start request
-    @GuardedBy("BtHelper.this")
-    private final @NonNull ArrayList<ScoClient> mScoClients = new ArrayList<ScoClient>();
-
     // BluetoothHeadset API to control SCO connection
     private @Nullable BluetoothHeadset mBluetoothHeadset;
 
@@ -301,6 +294,8 @@
     @GuardedBy("AudioDeviceBroker.mDeviceStateLock")
     /*package*/ synchronized void receiveBtEvent(Intent intent) {
         final String action = intent.getAction();
+
+        Log.i(TAG, "receiveBtEvent action: " + action + " mScoAudioState: " + mScoAudioState);
         if (action.equals(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED)) {
             BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
             setBtScoActiveDevice(btDevice);
@@ -308,20 +303,16 @@
             boolean broadcast = false;
             int scoAudioState = AudioManager.SCO_AUDIO_STATE_ERROR;
             int btState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1);
-            // broadcast intent if the connection was initated by AudioService
-            if (!mScoClients.isEmpty()
-                    && (mScoAudioState == SCO_STATE_ACTIVE_INTERNAL
-                    || mScoAudioState == SCO_STATE_ACTIVATE_REQ
-                    || mScoAudioState == SCO_STATE_DEACTIVATE_REQ
-                    || mScoAudioState == SCO_STATE_DEACTIVATING)) {
-                broadcast = true;
-            }
+            Log.i(TAG, "receiveBtEvent ACTION_AUDIO_STATE_CHANGED: " + btState);
             switch (btState) {
                 case BluetoothHeadset.STATE_AUDIO_CONNECTED:
                     scoAudioState = AudioManager.SCO_AUDIO_STATE_CONNECTED;
                     if (mScoAudioState != SCO_STATE_ACTIVE_INTERNAL
                             && mScoAudioState != SCO_STATE_DEACTIVATE_REQ) {
                         mScoAudioState = SCO_STATE_ACTIVE_EXTERNAL;
+                    } else if (mDeviceBroker.isBluetoothScoRequested()) {
+                        // broadcast intent if the connection was initated by AudioService
+                        broadcast = true;
                     }
                     mDeviceBroker.setBluetoothScoOn(true, "BtHelper.receiveBtEvent");
                     break;
@@ -333,21 +324,21 @@
                     // notified by requestScoState() setting state to SCO_STATE_ACTIVATE_REQ.
                     // 2) If audio was connected then disconnected via Bluetooth APIs and
                     // we still have pending activation requests by apps: this is indicated by
-                    // state SCO_STATE_ACTIVE_EXTERNAL and the mScoClients list not empty.
+                    // state SCO_STATE_ACTIVE_EXTERNAL and BT SCO is requested.
                     if (mScoAudioState == SCO_STATE_ACTIVATE_REQ
                             || (mScoAudioState == SCO_STATE_ACTIVE_EXTERNAL
-                                    && !mScoClients.isEmpty())) {
+                                    && mDeviceBroker.isBluetoothScoRequested())) {
                         if (mBluetoothHeadset != null && mBluetoothHeadsetDevice != null
                                 && connectBluetoothScoAudioHelper(mBluetoothHeadset,
                                 mBluetoothHeadsetDevice, mScoAudioMode)) {
                             mScoAudioState = SCO_STATE_ACTIVE_INTERNAL;
-                            broadcast = false;
+                            scoAudioState = AudioManager.SCO_AUDIO_STATE_CONNECTING;
+                            broadcast = true;
                             break;
                         }
                     }
-                    // Tear down SCO if disconnected from external
-                    if (mScoAudioState == SCO_STATE_DEACTIVATING) {
-                        clearAllScoClients(0, false);
+                    if (mScoAudioState != SCO_STATE_ACTIVE_EXTERNAL) {
+                        broadcast = true;
                     }
                     mScoAudioState = SCO_STATE_INACTIVE;
                     break;
@@ -356,11 +347,8 @@
                             && mScoAudioState != SCO_STATE_DEACTIVATE_REQ) {
                         mScoAudioState = SCO_STATE_ACTIVE_EXTERNAL;
                     }
-                    broadcast = false;
                     break;
                 default:
-                    // do not broadcast CONNECTING or invalid state
-                    broadcast = false;
                     break;
             }
             if (broadcast) {
@@ -386,81 +374,19 @@
                 == BluetoothHeadset.STATE_AUDIO_CONNECTED;
     }
 
-    /**
-     * Disconnect all SCO connections started by {@link AudioManager} except those started by
-     * {@param exceptPid}
-     *
-     * @param exceptPid pid whose SCO connections through {@link AudioManager} should be kept
-     */
     // @GuardedBy("AudioDeviceBroker.mSetModeLock")
     @GuardedBy("AudioDeviceBroker.mDeviceStateLock")
-    /*package*/ synchronized void disconnectBluetoothSco(int exceptPid) {
-        checkScoAudioState();
-        if (mScoAudioState == SCO_STATE_ACTIVE_EXTERNAL) {
-            return;
-        }
-        clearAllScoClients(exceptPid, true);
-    }
-
-    // @GuardedBy("AudioDeviceBroker.mSetModeLock")
-    @GuardedBy("AudioDeviceBroker.mDeviceStateLock")
-    /*package*/ synchronized void startBluetoothScoForClient(IBinder cb, int scoAudioMode,
+    /*package*/ synchronized boolean startBluetoothSco(int scoAudioMode,
                 @NonNull String eventSource) {
-        ScoClient client = getScoClient(cb, true);
-        // The calling identity must be cleared before calling ScoClient.incCount().
-        // inCount() calls requestScoState() which in turn can call BluetoothHeadset APIs
-        // and this must be done on behalf of system server to make sure permissions are granted.
-        // The caller identity must be cleared after getScoClient() because it is needed if a new
-        // client is created.
-        final long ident = Binder.clearCallingIdentity();
-        try {
-            AudioService.sDeviceLogger.log(new AudioEventLogger.StringEvent(eventSource));
-            client.requestScoState(BluetoothHeadset.STATE_AUDIO_CONNECTED, scoAudioMode);
-        } catch (NullPointerException e) {
-            Log.e(TAG, "Null ScoClient", e);
-        }
-        Binder.restoreCallingIdentity(ident);
-    }
-
-    // @GuardedBy("AudioDeviceBroker.mSetModeLock")
-    @GuardedBy("AudioDeviceBroker.mDeviceStateLock")
-    /*package*/ synchronized void stopBluetoothScoForClient(IBinder cb,
-            @NonNull String eventSource) {
-        ScoClient client = getScoClient(cb, false);
-        // The calling identity must be cleared before calling ScoClient.decCount().
-        // decCount() calls requestScoState() which in turn can call BluetoothHeadset APIs
-        // and this must be done on behalf of system server to make sure permissions are granted.
-        final long ident = Binder.clearCallingIdentity();
-        if (client != null) {
-            stopAndRemoveClient(client, eventSource);
-        }
-        Binder.restoreCallingIdentity(ident);
-    }
-
-    // @GuardedBy("AudioDeviceBroker.mSetModeLock")
-    @GuardedBy("AudioDeviceBroker.mDeviceStateLock")
-    /*package*/ synchronized void stopBluetoothScoForPid(int pid) {
-        ScoClient client = getScoClientForPid(pid);
-        if (client == null) {
-            return;
-        }
-        final String eventSource = new StringBuilder("stopBluetoothScoForPid(")
-                .append(pid).append(")").toString();
-        stopAndRemoveClient(client, eventSource);
-    }
-
-    @GuardedBy("AudioDeviceBroker.mDeviceStateLock")
-    // @GuardedBy("BtHelper.this")
-    private void stopAndRemoveClient(ScoClient client, @NonNull String eventSource) {
         AudioService.sDeviceLogger.log(new AudioEventLogger.StringEvent(eventSource));
-        client.requestScoState(BluetoothHeadset.STATE_AUDIO_DISCONNECTED,
-                SCO_MODE_VIRTUAL_CALL);
-        // If a disconnection is pending, the client will be removed when clearAllScoClients()
-        // is called form receiveBtEvent()
-        if (mScoAudioState != SCO_STATE_DEACTIVATE_REQ
-                && mScoAudioState != SCO_STATE_DEACTIVATING) {
-            client.remove(false /*stop */, true /*unregister*/);
-        }
+        return requestScoState(BluetoothHeadset.STATE_AUDIO_CONNECTED, scoAudioMode);
+    }
+
+    // @GuardedBy("AudioDeviceBroker.mSetModeLock")
+    @GuardedBy("AudioDeviceBroker.mDeviceStateLock")
+    /*package*/ synchronized boolean stopBluetoothSco(@NonNull String eventSource) {
+        AudioService.sDeviceLogger.log(new AudioEventLogger.StringEvent(eventSource));
+        return requestScoState(BluetoothHeadset.STATE_AUDIO_DISCONNECTED, SCO_MODE_VIRTUAL_CALL);
     }
 
     /*package*/ synchronized void setHearingAidVolume(int index, int streamType) {
@@ -507,7 +433,6 @@
     // @GuardedBy("AudioDeviceBroker.mSetModeLock")
     @GuardedBy("AudioDeviceBroker.mDeviceStateLock")
     /*package*/ synchronized void resetBluetoothSco() {
-        clearAllScoClients(0, false);
         mScoAudioState = SCO_STATE_INACTIVE;
         broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
         AudioSystem.setParameters("A2dpSuspended=false");
@@ -606,46 +531,64 @@
         mDeviceBroker.postBroadcastScoConnectionState(state);
     }
 
-    private boolean handleBtScoActiveDeviceChange(BluetoothDevice btDevice, boolean isActive) {
-        if (btDevice == null) {
-            return true;
+    @Nullable AudioDeviceAttributes getHeadsetAudioDevice() {
+        if (mBluetoothHeadsetDevice == null) {
+            return null;
         }
+        return btHeadsetDeviceToAudioDevice(mBluetoothHeadsetDevice);
+    }
+
+    private AudioDeviceAttributes btHeadsetDeviceToAudioDevice(BluetoothDevice btDevice) {
         String address = btDevice.getAddress();
+        if (!BluetoothAdapter.checkBluetoothAddress(address)) {
+            address = "";
+        }
         BluetoothClass btClass = btDevice.getBluetoothClass();
-        int inDevice = AudioSystem.DEVICE_IN_BLUETOOTH_SCO_HEADSET;
-        int[] outDeviceTypes = {
-                AudioSystem.DEVICE_OUT_BLUETOOTH_SCO,
-                AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_HEADSET,
-                AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_CARKIT
-        };
+        int nativeType = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO;
         if (btClass != null) {
             switch (btClass.getDeviceClass()) {
                 case BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET:
                 case BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE:
-                    outDeviceTypes = new int[] { AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_HEADSET };
+                    nativeType = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
                     break;
                 case BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO:
-                    outDeviceTypes = new int[] { AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_CARKIT };
+                    nativeType = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
                     break;
             }
         }
-        if (!BluetoothAdapter.checkBluetoothAddress(address)) {
-            address = "";
+        if (AudioService.DEBUG_DEVICES) {
+            Log.i(TAG, "btHeadsetDeviceToAudioDevice btDevice: " + btDevice
+                    + " btClass: " + (btClass == null ? "Unknown" : btClass)
+                    + " nativeType: " + nativeType + " address: " + address);
         }
+        return new AudioDeviceAttributes(nativeType, address);
+    }
+
+    private boolean handleBtScoActiveDeviceChange(BluetoothDevice btDevice, boolean isActive) {
+        if (btDevice == null) {
+            return true;
+        }
+        int inDevice = AudioSystem.DEVICE_IN_BLUETOOTH_SCO_HEADSET;
+        AudioDeviceAttributes audioDevice =  btHeadsetDeviceToAudioDevice(btDevice);
         String btDeviceName =  getName(btDevice);
         boolean result = false;
         if (isActive) {
-            result |= mDeviceBroker.handleDeviceConnection(
-                    isActive, outDeviceTypes[0], address, btDeviceName);
+            result |= mDeviceBroker.handleDeviceConnection(isActive, audioDevice.getInternalType(),
+                    audioDevice.getAddress(), btDeviceName);
         } else {
+            int[] outDeviceTypes = {
+                    AudioSystem.DEVICE_OUT_BLUETOOTH_SCO,
+                    AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_HEADSET,
+                    AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_CARKIT
+            };
             for (int outDeviceType : outDeviceTypes) {
                 result |= mDeviceBroker.handleDeviceConnection(
-                        isActive, outDeviceType, address, btDeviceName);
+                        isActive, outDeviceType, audioDevice.getAddress(), btDeviceName);
             }
         }
         // handleDeviceConnection() && result to make sure the method get executed
         result = mDeviceBroker.handleDeviceConnection(
-                isActive, inDevice, address, btDeviceName) && result;
+                isActive, inDevice, audioDevice.getAddress(), btDeviceName) && result;
         return result;
     }
 
@@ -733,195 +676,122 @@
             };
 
     //----------------------------------------------------------------------
+
     // @GuardedBy("AudioDeviceBroker.mSetModeLock")
-    @GuardedBy("AudioDeviceBroker.mDeviceStateLock")
-    /*package*/ synchronized void scoClientDied(Object obj) {
-        final ScoClient client = (ScoClient) obj;
-        client.remove(true /*stop*/, false /*unregister*/);
-        Log.w(TAG, "SCO client died");
-    }
-
-    private class ScoClient implements IBinder.DeathRecipient {
-        private IBinder mCb; // To be notified of client's death
-        private int mCreatorPid;
-
-        ScoClient(IBinder cb) {
-            mCb = cb;
-            mCreatorPid = Binder.getCallingPid();
-        }
-
-        public void registerDeathRecipient() {
-            try {
-                mCb.linkToDeath(this, 0);
-            } catch (RemoteException e) {
-                Log.w(TAG, "ScoClient could not link to " + mCb + " binder death");
-            }
-        }
-
-        public void unregisterDeathRecipient() {
-            try {
-                mCb.unlinkToDeath(this, 0);
-            } catch (NoSuchElementException e) {
-                Log.w(TAG, "ScoClient could not not unregistered to binder");
-            }
-        }
-
-        @Override
-        public void binderDied() {
-            // process this from DeviceBroker's message queue to take the right locks since
-            // this event can impact SCO mode and requires querying audio mode stack
-            mDeviceBroker.postScoClientDied(this);
-        }
-
-        IBinder getBinder() {
-            return mCb;
-        }
-
-        int getPid() {
-            return mCreatorPid;
-        }
-
-        // @GuardedBy("AudioDeviceBroker.mSetModeLock")
-        //@GuardedBy("AudioDeviceBroker.mDeviceStateLock")
-        @GuardedBy("BtHelper.this")
-        private boolean requestScoState(int state, int scoAudioMode) {
-            checkScoAudioState();
-            if (mScoClients.size() != 1) {
-                Log.i(TAG, "requestScoState: state=" + state + ", scoAudioMode=" + scoAudioMode
-                        + ", num SCO clients=" + mScoClients.size());
-                return true;
-            }
-            if (state == BluetoothHeadset.STATE_AUDIO_CONNECTED) {
-                // Make sure that the state transitions to CONNECTING even if we cannot initiate
-                // the connection.
-                broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_CONNECTING);
-                // Accept SCO audio activation only in NORMAL audio mode or if the mode is
-                // currently controlled by the same client process.
-                final int modeOwnerPid =  mDeviceBroker.getModeOwnerPid();
-                if (modeOwnerPid != 0 && (modeOwnerPid != mCreatorPid)) {
-                    Log.w(TAG, "requestScoState: audio mode is not NORMAL and modeOwnerPid "
-                            + modeOwnerPid + " != creatorPid " + mCreatorPid);
+    //@GuardedBy("AudioDeviceBroker.mDeviceStateLock")
+    @GuardedBy("BtHelper.this")
+    private boolean requestScoState(int state, int scoAudioMode) {
+        checkScoAudioState();
+        if (state == BluetoothHeadset.STATE_AUDIO_CONNECTED) {
+            // Make sure that the state transitions to CONNECTING even if we cannot initiate
+            // the connection.
+            broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_CONNECTING);
+            switch (mScoAudioState) {
+                case SCO_STATE_INACTIVE:
+                    mScoAudioMode = scoAudioMode;
+                    if (scoAudioMode == SCO_MODE_UNDEFINED) {
+                        mScoAudioMode = SCO_MODE_VIRTUAL_CALL;
+                        if (mBluetoothHeadsetDevice != null) {
+                            mScoAudioMode = Settings.Global.getInt(
+                                    mDeviceBroker.getContentResolver(),
+                                    "bluetooth_sco_channel_"
+                                            + mBluetoothHeadsetDevice.getAddress(),
+                                    SCO_MODE_VIRTUAL_CALL);
+                            if (mScoAudioMode > SCO_MODE_MAX || mScoAudioMode < 0) {
+                                mScoAudioMode = SCO_MODE_VIRTUAL_CALL;
+                            }
+                        }
+                    }
+                    if (mBluetoothHeadset == null) {
+                        if (getBluetoothHeadset()) {
+                            mScoAudioState = SCO_STATE_ACTIVATE_REQ;
+                        } else {
+                            Log.w(TAG, "requestScoState: getBluetoothHeadset failed during"
+                                    + " connection, mScoAudioMode=" + mScoAudioMode);
+                            broadcastScoConnectionState(
+                                    AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
+                            return false;
+                        }
+                        break;
+                    }
+                    if (mBluetoothHeadsetDevice == null) {
+                        Log.w(TAG, "requestScoState: no active device while connecting,"
+                                + " mScoAudioMode=" + mScoAudioMode);
+                        broadcastScoConnectionState(
+                                AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
+                        return false;
+                    }
+                    if (connectBluetoothScoAudioHelper(mBluetoothHeadset,
+                            mBluetoothHeadsetDevice, mScoAudioMode)) {
+                        mScoAudioState = SCO_STATE_ACTIVE_INTERNAL;
+                    } else {
+                        Log.w(TAG, "requestScoState: connect to "
+                                + mBluetoothHeadsetDevice
+                                + " failed, mScoAudioMode=" + mScoAudioMode);
+                        broadcastScoConnectionState(
+                                AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
+                        return false;
+                    }
+                    break;
+                case SCO_STATE_DEACTIVATING:
+                    mScoAudioState = SCO_STATE_ACTIVATE_REQ;
+                    break;
+                case SCO_STATE_DEACTIVATE_REQ:
+                    mScoAudioState = SCO_STATE_ACTIVE_INTERNAL;
+                    broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_CONNECTED);
+                    break;
+                case SCO_STATE_ACTIVE_INTERNAL:
+                    Log.w(TAG, "requestScoState: already in ACTIVE mode, simply return");
+                    break;
+                default:
+                    Log.w(TAG, "requestScoState: failed to connect in state "
+                            + mScoAudioState + ", scoAudioMode=" + scoAudioMode);
                     broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
                     return false;
-                }
-                switch (mScoAudioState) {
-                    case SCO_STATE_INACTIVE:
-                        mScoAudioMode = scoAudioMode;
-                        if (scoAudioMode == SCO_MODE_UNDEFINED) {
-                            mScoAudioMode = SCO_MODE_VIRTUAL_CALL;
-                            if (mBluetoothHeadsetDevice != null) {
-                                mScoAudioMode = Settings.Global.getInt(
-                                        mDeviceBroker.getContentResolver(),
-                                        "bluetooth_sco_channel_"
-                                                + mBluetoothHeadsetDevice.getAddress(),
-                                        SCO_MODE_VIRTUAL_CALL);
-                                if (mScoAudioMode > SCO_MODE_MAX || mScoAudioMode < 0) {
-                                    mScoAudioMode = SCO_MODE_VIRTUAL_CALL;
-                                }
-                            }
-                        }
-                        if (mBluetoothHeadset == null) {
-                            if (getBluetoothHeadset()) {
-                                mScoAudioState = SCO_STATE_ACTIVATE_REQ;
-                            } else {
-                                Log.w(TAG, "requestScoState: getBluetoothHeadset failed during"
-                                        + " connection, mScoAudioMode=" + mScoAudioMode);
-                                broadcastScoConnectionState(
-                                        AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
-                                return false;
-                            }
-                            break;
-                        }
-                        if (mBluetoothHeadsetDevice == null) {
-                            Log.w(TAG, "requestScoState: no active device while connecting,"
-                                    + " mScoAudioMode=" + mScoAudioMode);
-                            broadcastScoConnectionState(
-                                    AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
-                            return false;
-                        }
-                        if (connectBluetoothScoAudioHelper(mBluetoothHeadset,
-                                mBluetoothHeadsetDevice, mScoAudioMode)) {
-                            mScoAudioState = SCO_STATE_ACTIVE_INTERNAL;
+            }
+        } else if (state == BluetoothHeadset.STATE_AUDIO_DISCONNECTED) {
+            switch (mScoAudioState) {
+                case SCO_STATE_ACTIVE_INTERNAL:
+                    if (mBluetoothHeadset == null) {
+                        if (getBluetoothHeadset()) {
+                            mScoAudioState = SCO_STATE_DEACTIVATE_REQ;
                         } else {
-                            Log.w(TAG, "requestScoState: connect to " + mBluetoothHeadsetDevice
-                                    + " failed, mScoAudioMode=" + mScoAudioMode);
+                            Log.w(TAG, "requestScoState: getBluetoothHeadset failed during"
+                                    + " disconnection, mScoAudioMode=" + mScoAudioMode);
+                            mScoAudioState = SCO_STATE_INACTIVE;
                             broadcastScoConnectionState(
                                     AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
                             return false;
                         }
                         break;
-                    case SCO_STATE_DEACTIVATING:
-                        mScoAudioState = SCO_STATE_ACTIVATE_REQ;
-                        break;
-                    case SCO_STATE_DEACTIVATE_REQ:
-                        mScoAudioState = SCO_STATE_ACTIVE_INTERNAL;
-                        broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_CONNECTED);
-                        break;
-                    case SCO_STATE_ACTIVE_INTERNAL:
-                        Log.w(TAG, "requestScoState: already in ACTIVE mode, simply return");
-                        break;
-                    default:
-                        Log.w(TAG, "requestScoState: failed to connect in state "
-                                + mScoAudioState + ", scoAudioMode=" + scoAudioMode);
-                        broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
-                        return false;
-                }
-            } else if (state == BluetoothHeadset.STATE_AUDIO_DISCONNECTED) {
-                switch (mScoAudioState) {
-                    case SCO_STATE_ACTIVE_INTERNAL:
-                        if (mBluetoothHeadset == null) {
-                            if (getBluetoothHeadset()) {
-                                mScoAudioState = SCO_STATE_DEACTIVATE_REQ;
-                            } else {
-                                Log.w(TAG, "requestScoState: getBluetoothHeadset failed during"
-                                        + " disconnection, mScoAudioMode=" + mScoAudioMode);
-                                mScoAudioState = SCO_STATE_INACTIVE;
-                                broadcastScoConnectionState(
-                                        AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
-                                return false;
-                            }
-                            break;
-                        }
-                        if (mBluetoothHeadsetDevice == null) {
-                            mScoAudioState = SCO_STATE_INACTIVE;
-                            broadcastScoConnectionState(
-                                    AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
-                            break;
-                        }
-                        if (disconnectBluetoothScoAudioHelper(mBluetoothHeadset,
-                                mBluetoothHeadsetDevice, mScoAudioMode)) {
-                            mScoAudioState = SCO_STATE_DEACTIVATING;
-                        } else {
-                            mScoAudioState = SCO_STATE_INACTIVE;
-                            broadcastScoConnectionState(
-                                    AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
-                        }
-                        break;
-                    case SCO_STATE_ACTIVATE_REQ:
+                    }
+                    if (mBluetoothHeadsetDevice == null) {
                         mScoAudioState = SCO_STATE_INACTIVE;
-                        broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
+                        broadcastScoConnectionState(
+                                AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
                         break;
-                    default:
-                        Log.w(TAG, "requestScoState: failed to disconnect in state "
-                                + mScoAudioState + ", scoAudioMode=" + scoAudioMode);
-                        broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
-                        return false;
-                }
+                    }
+                    if (disconnectBluetoothScoAudioHelper(mBluetoothHeadset,
+                            mBluetoothHeadsetDevice, mScoAudioMode)) {
+                        mScoAudioState = SCO_STATE_DEACTIVATING;
+                    } else {
+                        mScoAudioState = SCO_STATE_INACTIVE;
+                        broadcastScoConnectionState(
+                                AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
+                    }
+                    break;
+                case SCO_STATE_ACTIVATE_REQ:
+                    mScoAudioState = SCO_STATE_INACTIVE;
+                    broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
+                    break;
+                default:
+                    Log.w(TAG, "requestScoState: failed to disconnect in state "
+                            + mScoAudioState + ", scoAudioMode=" + scoAudioMode);
+                    broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
+                    return false;
             }
-            return true;
         }
-
-        @GuardedBy("BtHelper.this")
-        void remove(boolean stop, boolean unregister) {
-            if (unregister) {
-                unregisterDeathRecipient();
-            }
-            if (stop) {
-                requestScoState(BluetoothHeadset.STATE_AUDIO_DISCONNECTED,
-                        SCO_MODE_VIRTUAL_CALL);
-            }
-            mScoClients.remove(this);
-        }
+        return true;
     }
 
     //-----------------------------------------------------
@@ -974,49 +844,6 @@
         }
     }
 
-
-    @GuardedBy("BtHelper.this")
-    private ScoClient getScoClient(IBinder cb, boolean create) {
-        for (ScoClient existingClient : mScoClients) {
-            if (existingClient.getBinder() == cb) {
-                return existingClient;
-            }
-        }
-        if (create) {
-            ScoClient newClient = new ScoClient(cb);
-            newClient.registerDeathRecipient();
-            mScoClients.add(newClient);
-            return newClient;
-        }
-        return null;
-    }
-
-    @GuardedBy("BtHelper.this")
-    private ScoClient getScoClientForPid(int pid) {
-        for (ScoClient cl : mScoClients) {
-            if (cl.getPid() == pid) {
-                return cl;
-            }
-        }
-        return null;
-    }
-
-    // @GuardedBy("AudioDeviceBroker.mSetModeLock")
-    //@GuardedBy("AudioDeviceBroker.mDeviceStateLock")
-    @GuardedBy("BtHelper.this")
-    private void clearAllScoClients(int exceptPid, boolean stopSco) {
-        final ArrayList<ScoClient> clients = new ArrayList<ScoClient>();
-        for (ScoClient cl : mScoClients) {
-            if (cl.getPid() != exceptPid) {
-                clients.add(cl);
-            }
-        }
-        for (ScoClient cl : clients) {
-            cl.remove(stopSco, true /*unregister*/);
-        }
-
-    }
-
     private boolean getBluetoothHeadset() {
         boolean result = false;
         BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
@@ -1062,10 +889,6 @@
         pw.println(prefix + "mBluetoothHeadsetDevice: " + mBluetoothHeadsetDevice);
         pw.println(prefix + "mScoAudioState: " + scoAudioStateToString(mScoAudioState));
         pw.println(prefix + "mScoAudioMode: " + scoAudioModeToString(mScoAudioMode));
-        pw.println(prefix + "Sco clients:");
-        mScoClients.forEach((cl) -> {
-            pw.println("  " + prefix + "pid: " + cl.getPid() + " cb: " + cl.getBinder()); });
-
         pw.println("\n" + prefix + "mHearingAid: " + mHearingAid);
         pw.println(prefix + "mA2dp: " + mA2dp);
         pw.println(prefix + "mAvrcpAbsVolSupported: " + mAvrcpAbsVolSupported);
diff --git a/services/core/java/com/android/server/compat/PlatformCompat.java b/services/core/java/com/android/server/compat/PlatformCompat.java
index 4bd01d4..aa85f7f 100644
--- a/services/core/java/com/android/server/compat/PlatformCompat.java
+++ b/services/core/java/com/android/server/compat/PlatformCompat.java
@@ -60,7 +60,6 @@
     private final CompatConfig mCompatConfig;
 
     private static int sMinTargetSdk = Build.VERSION_CODES.Q;
-    private static int sMaxTargetSdk = Build.VERSION_CODES.R;
 
     public PlatformCompat(Context context) {
         mContext = context;
@@ -384,8 +383,7 @@
             return false;
         }
         if (change.getEnableSinceTargetSdk() > 0) {
-            if (change.getEnableSinceTargetSdk() < sMinTargetSdk
-                    || change.getEnableSinceTargetSdk() > sMaxTargetSdk) {
+            if (change.getEnableSinceTargetSdk() < sMinTargetSdk) {
                 return false;
             }
         }
diff --git a/services/core/java/com/android/server/connectivity/PacManager.java b/services/core/java/com/android/server/connectivity/PacManager.java
index 198de78..06721ae 100644
--- a/services/core/java/com/android/server/connectivity/PacManager.java
+++ b/services/core/java/com/android/server/connectivity/PacManager.java
@@ -390,7 +390,7 @@
             return;
         }
         if (!mHasSentBroadcast) {
-            sendPacBroadcast(new ProxyInfo(mPacUrl, mLastPort));
+            sendPacBroadcast(ProxyInfo.buildPacProxy(mPacUrl, mLastPort));
             mHasSentBroadcast = true;
         }
     }
diff --git a/services/core/java/com/android/server/connectivity/ProxyTracker.java b/services/core/java/com/android/server/connectivity/ProxyTracker.java
index 5cb3d94..f6ca152 100644
--- a/services/core/java/com/android/server/connectivity/ProxyTracker.java
+++ b/services/core/java/com/android/server/connectivity/ProxyTracker.java
@@ -38,7 +38,9 @@
 import android.util.Log;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.net.module.util.ProxyUtils;
 
+import java.util.Collections;
 import java.util.Objects;
 
 /**
@@ -163,9 +165,10 @@
         if (!TextUtils.isEmpty(host) || !TextUtils.isEmpty(pacFileUrl)) {
             ProxyInfo proxyProperties;
             if (!TextUtils.isEmpty(pacFileUrl)) {
-                proxyProperties = new ProxyInfo(Uri.parse(pacFileUrl));
+                proxyProperties = ProxyInfo.buildPacProxy(Uri.parse(pacFileUrl));
             } else {
-                proxyProperties = new ProxyInfo(host, port, exclList);
+                proxyProperties = ProxyInfo.buildDirectProxy(host, port,
+                        ProxyUtils.exclusionStringAsList(exclList));
             }
             if (!proxyProperties.isValid()) {
                 if (DBG) Log.d(TAG, "Invalid proxy properties, ignoring: " + proxyProperties);
@@ -204,7 +207,8 @@
                     return false;
                 }
             }
-            final ProxyInfo p = new ProxyInfo(proxyHost, proxyPort, "");
+            final ProxyInfo p = ProxyInfo.buildDirectProxy(proxyHost, proxyPort,
+                    Collections.emptyList());
             setGlobalProxy(p);
             return true;
         }
@@ -219,7 +223,8 @@
      */
     public void sendProxyBroadcast() {
         final ProxyInfo defaultProxy = getDefaultProxy();
-        final ProxyInfo proxyInfo = null != defaultProxy ? defaultProxy : new ProxyInfo("", 0, "");
+        final ProxyInfo proxyInfo = null != defaultProxy ?
+                defaultProxy : ProxyInfo.buildDirectProxy("", 0, Collections.emptyList());
         if (mPacManager.setCurrentProxyScriptUrl(proxyInfo) == PacManager.DONT_SEND_BROADCAST) {
             return;
         }
@@ -261,7 +266,7 @@
                 mGlobalProxy = new ProxyInfo(proxyInfo);
                 host = mGlobalProxy.getHost();
                 port = mGlobalProxy.getPort();
-                exclList = mGlobalProxy.getExclusionListAsString();
+                exclList = ProxyUtils.exclusionListAsString(mGlobalProxy.getExclusionList());
                 pacFileUrl = Uri.EMPTY.equals(proxyInfo.getPacFileUrl())
                         ? "" : proxyInfo.getPacFileUrl().toString();
             } else {
diff --git a/services/core/java/com/android/server/location/timezone/OWNERS b/services/core/java/com/android/server/location/timezone/OWNERS
new file mode 100644
index 0000000..28aff18
--- /dev/null
+++ b/services/core/java/com/android/server/location/timezone/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 847766
+nfuller@google.com
+include /core/java/android/app/timedetector/OWNERS
diff --git a/services/core/java/com/android/server/net/IpConfigStore.java b/services/core/java/com/android/server/net/IpConfigStore.java
index 9c5abd4..cc3a002 100644
--- a/services/core/java/com/android/server/net/IpConfigStore.java
+++ b/services/core/java/com/android/server/net/IpConfigStore.java
@@ -30,6 +30,7 @@
 import android.util.SparseArray;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.net.module.util.ProxyUtils;
 
 import java.io.BufferedInputStream;
 import java.io.DataInputStream;
@@ -123,7 +124,8 @@
             switch (config.proxySettings) {
                 case STATIC:
                     ProxyInfo proxyProperties = config.httpProxy;
-                    String exclusionList = proxyProperties.getExclusionListAsString();
+                    String exclusionList = ProxyUtils.exclusionListAsString(
+                            proxyProperties.getExclusionList());
                     out.writeUTF(PROXY_SETTINGS_KEY);
                     out.writeUTF(config.proxySettings.toString());
                     out.writeUTF(PROXY_HOST_KEY);
@@ -370,13 +372,14 @@
 
                     switch (proxySettings) {
                         case STATIC:
-                            ProxyInfo proxyInfo =
-                                    new ProxyInfo(proxyHost, proxyPort, exclusionList);
+                            ProxyInfo proxyInfo = ProxyInfo.buildDirectProxy(proxyHost, proxyPort,
+                                    ProxyUtils.exclusionStringAsList(exclusionList));
                             config.proxySettings = proxySettings;
                             config.httpProxy = proxyInfo;
                             break;
                         case PAC:
-                            ProxyInfo proxyPacProperties = new ProxyInfo(Uri.parse(pacFileUrl));
+                            ProxyInfo proxyPacProperties =
+                                    ProxyInfo.buildPacProxy(Uri.parse(pacFileUrl));
                             config.proxySettings = proxySettings;
                             config.httpProxy = proxyPacProperties;
                             break;
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 9dd70b7..bd80bef 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -236,6 +236,7 @@
 import com.android.server.LocalServices;
 import com.android.server.ServiceThread;
 import com.android.server.SystemConfig;
+import com.android.server.connectivity.MultipathPolicyTracker;
 import com.android.server.usage.AppStandbyInternal;
 import com.android.server.usage.AppStandbyInternal.AppIdleStateChangeListener;
 
@@ -415,6 +416,7 @@
     private final Clock mClock;
     private final UserManager mUserManager;
     private final CarrierConfigManager mCarrierConfigManager;
+    private final MultipathPolicyTracker mMultipathPolicyTracker;
 
     private IConnectivityManager mConnManager;
     private PowerManagerInternal mPowerManagerInternal;
@@ -655,7 +657,7 @@
         mPolicyFile = new AtomicFile(new File(systemDir, "netpolicy.xml"), "net-policy");
 
         mAppOps = context.getSystemService(AppOpsManager.class);
-
+        mMultipathPolicyTracker = new MultipathPolicyTracker(mContext, mHandler);
         // Expose private service for system components to use.
         LocalServices.addService(NetworkPolicyManagerInternal.class,
                 new NetworkPolicyManagerInternalImpl());
@@ -684,7 +686,7 @@
      * Allows pre-defined apps for restrict background, but only if the user didn't already
      * revoked them.
      *
-     * @return whether any uid has been allowlisted.
+     * @return whether any uid has been added to allowlist.
      */
     @GuardedBy("mUidRulesFirstLock")
     boolean addDefaultRestrictBackgroundAllowlistUidsUL() {
@@ -708,7 +710,7 @@
         for (int i = 0; i < allowDataUsage.size(); i++) {
             final String pkg = allowDataUsage.valueAt(i);
             if (LOGD)
-                Slog.d(TAG, "checking restricted background allowlisting for package " + pkg
+                Slog.d(TAG, "checking restricted background exemption for package " + pkg
                         + " and user " + userId);
             final ApplicationInfo app;
             try {
@@ -923,6 +925,7 @@
             if (!initCompleteSignal.await(30, TimeUnit.SECONDS)) {
                 throw new IllegalStateException("Service " + TAG +" init timeout");
             }
+            mMultipathPolicyTracker.start();
         } catch (InterruptedException e) {
             Thread.currentThread().interrupt();
             throw new IllegalStateException("Service " + TAG + " init interrupted", e);
@@ -1024,7 +1027,7 @@
                         // user resets app preferences.
                         mMeteredRestrictedUids.remove(userId);
                         if (action == ACTION_USER_ADDED) {
-                            // Add apps that are allowlisted by default.
+                            // Add apps that are allowed by default.
                             addDefaultRestrictBackgroundAllowlistUidsUL(userId);
                         }
                         // Update global restrict for that user
@@ -2230,8 +2233,8 @@
             in.setInput(fis, StandardCharsets.UTF_8.name());
 
              // Must save the <restrict-background> tags and convert them to <uid-policy> later,
-             // to skip UIDs that were explicitly denylisted.
-            final SparseBooleanArray allowlistedRestrictBackground = new SparseBooleanArray();
+             // to skip UIDs that were explicitly denied.
+            final SparseBooleanArray restrictBackgroundAllowedUids = new SparseBooleanArray();
 
             int type;
             int version = VERSION_INIT;
@@ -2389,7 +2392,7 @@
                         insideAllowlist = true;
                     } else if (TAG_RESTRICT_BACKGROUND.equals(tag) && insideAllowlist) {
                         final int uid = readIntAttribute(in, ATTR_UID);
-                        allowlistedRestrictBackground.append(uid, true);
+                        restrictBackgroundAllowedUids.append(uid, true);
                     } else if (TAG_REVOKED_RESTRICT_BACKGROUND.equals(tag) && insideAllowlist) {
                         final int uid = readIntAttribute(in, ATTR_UID);
                         mRestrictBackgroundAllowlistRevokedUids.put(uid, true);
@@ -2402,9 +2405,9 @@
                 }
             }
 
-            final int size = allowlistedRestrictBackground.size();
+            final int size = restrictBackgroundAllowedUids.size();
             for (int i = 0; i < size; i++) {
-                final int uid = allowlistedRestrictBackground.keyAt(i);
+                final int uid = restrictBackgroundAllowedUids.keyAt(i);
                 final int policy = mUidPolicy.get(uid, POLICY_NONE);
                 if ((policy & POLICY_REJECT_METERED_BACKGROUND) != 0) {
                     Slog.w(TAG, "ignoring restrict-background-allowlist for " + uid
@@ -2671,13 +2674,13 @@
         if (!isUidValidForAllowlistRulesUL(uid)) {
             notifyApp = false;
         } else {
-            final boolean wasDenylisted = oldPolicy == POLICY_REJECT_METERED_BACKGROUND;
-            final boolean isDenylisted = policy == POLICY_REJECT_METERED_BACKGROUND;
-            final boolean wasAllowlisted = oldPolicy == POLICY_ALLOW_METERED_BACKGROUND;
-            final boolean isAllowlisted = policy == POLICY_ALLOW_METERED_BACKGROUND;
-            final boolean wasBlocked = wasDenylisted || (mRestrictBackground && !wasAllowlisted);
-            final boolean isBlocked = isDenylisted || (mRestrictBackground && !isAllowlisted);
-            if ((wasAllowlisted && (!isAllowlisted || isDenylisted))
+            final boolean wasDenied = oldPolicy == POLICY_REJECT_METERED_BACKGROUND;
+            final boolean isDenied = policy == POLICY_REJECT_METERED_BACKGROUND;
+            final boolean wasAllowed = oldPolicy == POLICY_ALLOW_METERED_BACKGROUND;
+            final boolean isAllowed = policy == POLICY_ALLOW_METERED_BACKGROUND;
+            final boolean wasBlocked = wasDenied || (mRestrictBackground && !wasAllowed);
+            final boolean isBlocked = isDenied || (mRestrictBackground && !isAllowed);
+            if ((wasAllowed && (!isAllowed || isDenied))
                     && mDefaultRestrictBackgroundAllowlistUids.get(uid)
                     && !mRestrictBackgroundAllowlistRevokedUids.get(uid)) {
                 if (LOGD)
@@ -2962,7 +2965,7 @@
             Slog.d(TAG, "setRestrictBackgroundUL(): " + restrictBackground + "; reason: " + reason);
             final boolean oldRestrictBackground = mRestrictBackground;
             mRestrictBackground = restrictBackground;
-            // Must allowlist foreground apps before turning data saver mode on.
+            // Must allow foreground apps before turning data saver mode on.
             // TODO: there is no need to iterate through all apps here, just those in the foreground,
             // so it could call AM to get the UIDs of such apps, and iterate through them instead.
             updateRulesForRestrictBackgroundUL();
@@ -3015,7 +3018,7 @@
                 Binder.restoreCallingIdentity(token);
             }
             if (policy == POLICY_REJECT_METERED_BACKGROUND) {
-                // App is denylisted.
+                // App is restricted.
                 return RESTRICT_BACKGROUND_STATUS_ENABLED;
             }
             if (!mRestrictBackground) {
@@ -3458,6 +3461,17 @@
         }
     }
 
+    /**
+     * Get multipath preference value for the given network.
+     */
+    public int getMultipathPreference(Network network) {
+        final Integer preference = mMultipathPolicyTracker.getMultipathPreference(network);
+        if (preference != null) {
+            return preference;
+        }
+        return 0;
+    }
+
     @Override
     protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
         if (!DumpUtils.checkDumpPermission(mContext, TAG, writer)) return;
@@ -3678,6 +3692,8 @@
                 mLogger.dumpLogs(fout);
             }
         }
+        fout.println();
+        mMultipathPolicyTracker.dump(fout);
     }
 
     @Override
@@ -4294,9 +4310,9 @@
      * <ul>
      * <li>@{code bw_penalty_box}: UIDs added to this chain do not have access (denylist).
      * <li>@{code bw_happy_box}: UIDs added to this chain have access (allowlist), unless they're
-     *     also denylisted.
+     *     also in denylist.
      * <li>@{code bw_data_saver}: when enabled (through {@link #setRestrictBackground(boolean)}),
-     *     no UIDs other than those allowlisted will have access.
+     *     no UIDs other than those in allowlist will have access.
      * <ul>
      *
      * <p>The @{code bw_penalty_box} and @{code bw_happy_box} are primarily managed through the
@@ -4311,7 +4327,8 @@
      * <ul>
      * <li>When Data Saver mode is on, the foreground app should be temporarily added to
      *     {@code bw_happy_box} before the @{code bw_data_saver} chain is enabled.
-     * <li>If the foreground app is denylisted by the user, it should be temporarily removed from
+     * <li>If the foreground app was restricted by the user (i.e. has the policy
+     *     {@code POLICY_REJECT_METERED_BACKGROUND}), it should be temporarily removed from
      *     {@code bw_penalty_box}.
      * <li>When the app leaves foreground state, the temporary changes above should be reverted.
      * </ul>
@@ -4346,8 +4363,8 @@
         final boolean isForeground = isUidForegroundOnRestrictBackgroundUL(uid);
         final boolean isRestrictedByAdmin = isRestrictedByAdminUL(uid);
 
-        final boolean isDenylisted = (uidPolicy & POLICY_REJECT_METERED_BACKGROUND) != 0;
-        final boolean isAllowlisted = (uidPolicy & POLICY_ALLOW_METERED_BACKGROUND) != 0;
+        final boolean isDenied = (uidPolicy & POLICY_REJECT_METERED_BACKGROUND) != 0;
+        final boolean isAllowed = (uidPolicy & POLICY_ALLOW_METERED_BACKGROUND) != 0;
         final int oldRule = oldUidRules & MASK_METERED_NETWORKS;
         int newRule = RULE_NONE;
 
@@ -4355,15 +4372,15 @@
         if (isRestrictedByAdmin) {
             newRule = RULE_REJECT_METERED;
         } else if (isForeground) {
-            if (isDenylisted || (mRestrictBackground && !isAllowlisted)) {
+            if (isDenied || (mRestrictBackground && !isAllowed)) {
                 newRule = RULE_TEMPORARY_ALLOW_METERED;
-            } else if (isAllowlisted) {
+            } else if (isAllowed) {
                 newRule = RULE_ALLOW_METERED;
             }
         } else {
-            if (isDenylisted) {
+            if (isDenied) {
                 newRule = RULE_REJECT_METERED;
-            } else if (mRestrictBackground && isAllowlisted) {
+            } else if (mRestrictBackground && isAllowed) {
                 newRule = RULE_ALLOW_METERED;
             }
         }
@@ -4372,8 +4389,8 @@
         if (LOGV) {
             Log.v(TAG, "updateRuleForRestrictBackgroundUL(" + uid + ")"
                     + ": isForeground=" +isForeground
-                    + ", isDenylisted=" + isDenylisted
-                    + ", isAllowlisted=" + isAllowlisted
+                    + ", isDenied=" + isDenied
+                    + ", isAllowed=" + isAllowed
                     + ", isRestrictedByAdmin=" + isRestrictedByAdmin
                     + ", oldRule=" + uidRulesToString(oldRule)
                     + ", newRule=" + uidRulesToString(newRule)
@@ -4390,49 +4407,49 @@
         // Second step: apply bw changes based on change of state.
         if (newRule != oldRule) {
             if (hasRule(newRule, RULE_TEMPORARY_ALLOW_METERED)) {
-                // Temporarily allowlist foreground app, removing from denylist if necessary
+                // Temporarily allow foreground app, removing from denylist if necessary
                 // (since bw_penalty_box prevails over bw_happy_box).
 
                 setMeteredNetworkAllowlist(uid, true);
                 // TODO: if statement below is used to avoid an unnecessary call to netd / iptables,
                 // but ideally it should be just:
-                //    setMeteredNetworkDenylist(uid, isDenylisted);
-                if (isDenylisted) {
+                //    setMeteredNetworkDenylist(uid, isDenied);
+                if (isDenied) {
                     setMeteredNetworkDenylist(uid, false);
                 }
             } else if (hasRule(oldRule, RULE_TEMPORARY_ALLOW_METERED)) {
-                // Remove temporary allowlist from app that is not on foreground anymore.
+                // Remove temporary exemption from app that is not on foreground anymore.
 
                 // TODO: if statements below are used to avoid unnecessary calls to netd / iptables,
                 // but ideally they should be just:
-                //    setMeteredNetworkAllowlist(uid, isAllowlisted);
-                //    setMeteredNetworkDenylist(uid, isDenylisted);
-                if (!isAllowlisted) {
+                //    setMeteredNetworkAllowlist(uid, isAllowed);
+                //    setMeteredNetworkDenylist(uid, isDenied);
+                if (!isAllowed) {
                     setMeteredNetworkAllowlist(uid, false);
                 }
-                if (isDenylisted || isRestrictedByAdmin) {
+                if (isDenied || isRestrictedByAdmin) {
                     setMeteredNetworkDenylist(uid, true);
                 }
             } else if (hasRule(newRule, RULE_REJECT_METERED)
                     || hasRule(oldRule, RULE_REJECT_METERED)) {
                 // Flip state because app was explicitly added or removed to denylist.
-                setMeteredNetworkDenylist(uid, (isDenylisted || isRestrictedByAdmin));
-                if (hasRule(oldRule, RULE_REJECT_METERED) && isAllowlisted) {
-                    // Since denylist prevails over allowlist, we need to handle the special case
-                    // where app is allowlisted and denylisted at the same time (although such
-                    // scenario should be blocked by the UI), then denylist is removed.
-                    setMeteredNetworkAllowlist(uid, isAllowlisted);
+                setMeteredNetworkDenylist(uid, (isDenied || isRestrictedByAdmin));
+                if (hasRule(oldRule, RULE_REJECT_METERED) && isAllowed) {
+                    // Since denial prevails over allowance, we need to handle the special case
+                    // where app is allowed and denied at the same time (although such
+                    // scenario should be blocked by the UI), then it is removed from the denylist.
+                    setMeteredNetworkAllowlist(uid, isAllowed);
                 }
             } else if (hasRule(newRule, RULE_ALLOW_METERED)
                     || hasRule(oldRule, RULE_ALLOW_METERED)) {
                 // Flip state because app was explicitly added or removed to allowlist.
-                setMeteredNetworkAllowlist(uid, isAllowlisted);
+                setMeteredNetworkAllowlist(uid, isAllowed);
             } else {
                 // All scenarios should have been covered above.
                 Log.wtf(TAG, "Unexpected change of metered UID state for " + uid
                         + ": foreground=" + isForeground
-                        + ", allowlisted=" + isAllowlisted
-                        + ", denylisted=" + isDenylisted
+                        + ", allowlisted=" + isAllowed
+                        + ", denylisted=" + isDenied
                         + ", isRestrictedByAdmin=" + isRestrictedByAdmin
                         + ", newRule=" + uidRulesToString(newUidRules)
                         + ", oldRule=" + uidRulesToString(oldUidRules));
@@ -4448,7 +4465,7 @@
      * listeners in case of change.
      * <p>
      * There are 3 power-related rules that affects whether an app has background access on
-     * non-metered networks, and when the condition applies and the UID is not allowlisted for power
+     * non-metered networks, and when the condition applies and the UID is not allowed for power
      * restriction, it's added to the equivalent firewall chain:
      * <ul>
      * <li>App is idle: {@code fw_standby} firewall chain.
@@ -4913,7 +4930,7 @@
     private void setMeteredNetworkDenylist(int uid, boolean enable) {
         if (LOGV) Slog.v(TAG, "setMeteredNetworkDenylist " + uid + ": " + enable);
         try {
-            mNetworkManager.setUidMeteredNetworkDenylist(uid, enable);
+            mNetworkManager.setUidOnMeteredNetworkDenylist(uid, enable);
         } catch (IllegalStateException e) {
             Log.wtf(TAG, "problem setting denylist (" + enable + ") rules for " + uid, e);
         } catch (RemoteException e) {
@@ -4924,7 +4941,7 @@
     private void setMeteredNetworkAllowlist(int uid, boolean enable) {
         if (LOGV) Slog.v(TAG, "setMeteredNetworkAllowlist " + uid + ": " + enable);
         try {
-            mNetworkManager.setUidMeteredNetworkAllowlist(uid, enable);
+            mNetworkManager.setUidOnMeteredNetworkAllowlist(uid, enable);
         } catch (IllegalStateException e) {
             Log.wtf(TAG, "problem setting allowlist (" + enable + ") rules for " + uid, e);
         } catch (RemoteException e) {
@@ -5046,8 +5063,8 @@
             mNetworkManager.setFirewallUidRule(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DEFAULT);
             mNetworkManager
                     .setFirewallUidRule(FIREWALL_CHAIN_POWERSAVE, uid, FIREWALL_RULE_DEFAULT);
-            mNetworkManager.setUidMeteredNetworkAllowlist(uid, false);
-            mNetworkManager.setUidMeteredNetworkDenylist(uid, false);
+            mNetworkManager.setUidOnMeteredNetworkAllowlist(uid, false);
+            mNetworkManager.setUidOnMeteredNetworkDenylist(uid, false);
         } catch (IllegalStateException e) {
             Log.wtf(TAG, "problem resetting firewall uid rules for " + uid, e);
         } catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/net/NetworkStatsCollection.java b/services/core/java/com/android/server/net/NetworkStatsCollection.java
index 342a11b..c4beddd4 100644
--- a/services/core/java/com/android/server/net/NetworkStatsCollection.java
+++ b/services/core/java/com/android/server/net/NetworkStatsCollection.java
@@ -28,9 +28,9 @@
 import static android.net.NetworkStats.TAG_NONE;
 import static android.net.NetworkStats.UID_ALL;
 import static android.net.TrafficStats.UID_REMOVED;
-import static android.net.NetworkUtils.multiplySafeByRational;
 import static android.text.format.DateUtils.WEEK_IN_MILLIS;
 
+import static com.android.internal.net.NetworkUtilsInternal.multiplySafeByRational;
 import static com.android.server.net.NetworkStatsService.TAG;
 
 import android.net.NetworkIdentity;
diff --git a/services/core/java/com/android/server/pm/ApexManager.java b/services/core/java/com/android/server/pm/ApexManager.java
index f116a24..c6a55b4 100644
--- a/services/core/java/com/android/server/pm/ApexManager.java
+++ b/services/core/java/com/android/server/pm/ApexManager.java
@@ -323,9 +323,9 @@
      * Copies the CE apex data directory for the given {@code userId} to a backup location, for use
      * in case of rollback.
      *
-     * @return long inode for the snapshot directory if the snapshot was successful, or -1 if not
+     * @return boolean true if the snapshot was successful
      */
-    public abstract long snapshotCeData(int userId, int rollbackId, String apexPackageName);
+    public abstract boolean snapshotCeData(int userId, int rollbackId, String apexPackageName);
 
     /**
      * Restores the snapshot of the CE apex data directory for the given {@code userId}.
@@ -826,7 +826,7 @@
         }
 
         @Override
-        public long snapshotCeData(int userId, int rollbackId, String apexPackageName) {
+        public boolean snapshotCeData(int userId, int rollbackId, String apexPackageName) {
             String apexModuleName;
             synchronized (mLock) {
                 Preconditions.checkState(mPackageNameToApexModuleName != null,
@@ -835,13 +835,14 @@
             }
             if (apexModuleName == null) {
                 Slog.e(TAG, "Invalid apex package name: " + apexPackageName);
-                return -1;
+                return false;
             }
             try {
-                return waitForApexService().snapshotCeData(userId, rollbackId, apexModuleName);
+                waitForApexService().snapshotCeData(userId, rollbackId, apexModuleName);
+                return true;
             } catch (Exception e) {
                 Slog.e(TAG, e.getMessage(), e);
-                return -1;
+                return false;
             }
         }
 
@@ -1124,7 +1125,7 @@
         }
 
         @Override
-        public long snapshotCeData(int userId, int rollbackId, String apexPackageName) {
+        public boolean snapshotCeData(int userId, int rollbackId, String apexPackageName) {
             throw new UnsupportedOperationException();
         }
 
diff --git a/services/core/java/com/android/server/rollback/AppDataRollbackHelper.java b/services/core/java/com/android/server/rollback/AppDataRollbackHelper.java
index 524ae54..0213cc6 100644
--- a/services/core/java/com/android/server/rollback/AppDataRollbackHelper.java
+++ b/services/core/java/com/android/server/rollback/AppDataRollbackHelper.java
@@ -129,13 +129,8 @@
         if (packageRollbackInfo.isApex()) {
             // For APEX, only snapshot CE here
             if ((flags & Installer.FLAG_STORAGE_CE) != 0) {
-                long ceSnapshotInode = mApexManager.snapshotCeData(
+                return mApexManager.snapshotCeData(
                         userId, rollbackId, packageRollbackInfo.getPackageName());
-                if (ceSnapshotInode > 0) {
-                    packageRollbackInfo.putCeSnapshotInode(userId, ceSnapshotInode);
-                } else {
-                    return false;
-                }
             }
         } else {
             // APK
diff --git a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
index ca382c4..81878e7 100644
--- a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
+++ b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
@@ -1292,7 +1292,7 @@
     private SparseIntArray getExtensionVersions() {
         // This list must be updated whenever the current API level is increased, or should be
         // replaced when we have another way of determining the relevant SDK versions.
-        final int[] relevantSdkVersions = { Build.VERSION_CODES.R };
+        final int[] relevantSdkVersions = { Build.VERSION_CODES.R, Build.VERSION_CODES.S };
 
         SparseIntArray result = new SparseIntArray(relevantSdkVersions.length);
         for (int i = 0; i < relevantSdkVersions.length; i++) {
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index bedcf9c..6cd0258 100755
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -97,6 +97,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.UUID;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -1176,7 +1177,8 @@
             final int resolvedUserId = resolveCallingUserId(callingPid, callingUid,
                     userId, "createSession");
             final long identity = Binder.clearCallingIdentity();
-            StringBuilder sessionId = new StringBuilder();
+            // Generate a unique session id with a random UUID.
+            String uniqueSessionId = UUID.randomUUID().toString();
             try {
                 synchronized (mLock) {
                     if (userId != mCurrentUserId && !isRecordingSession) {
@@ -1205,20 +1207,17 @@
                         return;
                     }
 
-                    // Create a unique session id with pid, uid and resolved user id
-                    sessionId.append(callingUid).append(callingPid).append(resolvedUserId);
-
                     // Create a new session token and a session state.
                     IBinder sessionToken = new Binder();
                     SessionState sessionState = new SessionState(sessionToken, info.getId(),
                             info.getComponent(), isRecordingSession, client, seq, callingUid,
-                            callingPid, resolvedUserId, sessionId.toString());
+                            callingPid, resolvedUserId, uniqueSessionId);
 
                     // Add them to the global session state map of the current user.
                     userState.sessionStateMap.put(sessionToken, sessionState);
 
                     // Map the session id to the sessionStateMap in the user state
-                    mSessionIdToSessionStateMap.put(sessionId.toString(), sessionState);
+                    mSessionIdToSessionStateMap.put(uniqueSessionId, sessionState);
 
                     // Also, add them to the session state map of the current service.
                     serviceState.sessionTokens.add(sessionToken);
diff --git a/services/core/java/com/android/server/tv/tunerresourcemanager/ClientProfile.java b/services/core/java/com/android/server/tv/tunerresourcemanager/ClientProfile.java
index 2b0fe8a..2fc17fe 100644
--- a/services/core/java/com/android/server/tv/tunerresourcemanager/ClientProfile.java
+++ b/services/core/java/com/android/server/tv/tunerresourcemanager/ClientProfile.java
@@ -68,6 +68,11 @@
     private Set<Integer> mUsingFrontendIds = new HashSet<>();
 
     /**
+     * List of the client ids that share frontend with the current client.
+     */
+    private Set<Integer> mShareFeClientIds = new HashSet<>();
+
+    /**
      * List of the Lnb ids that are used by the current client.
      */
     private Set<Integer> mUsingLnbIds = new HashSet<>();
@@ -113,11 +118,7 @@
     }
 
     public int getPriority() {
-        return mPriority;
-    }
-
-    public int getNiceValue() {
-        return mNiceValue;
+        return mPriority - mNiceValue;
     }
 
     public void setGroupId(int groupId) {
@@ -141,17 +142,38 @@
         mUsingFrontendIds.add(frontendId);
     }
 
+    /**
+     * Update the set of client that share frontend with the current client.
+     *
+     * @param clientId the client to share the fe with the current client.
+     */
+    public void shareFrontend(int clientId) {
+        mShareFeClientIds.add(clientId);
+    }
+
+    /**
+     * Remove the given client id from the share frontend client id set.
+     *
+     * @param clientId the client to stop sharing the fe with the current client.
+     */
+    public void stopSharingFrontend(int clientId) {
+        mShareFeClientIds.remove(clientId);
+    }
+
     public Set<Integer> getInUseFrontendIds() {
         return mUsingFrontendIds;
     }
 
+    public Set<Integer> getShareFeClientIds() {
+        return mShareFeClientIds;
+    }
+
     /**
      * Called when the client released a frontend.
-     *
-     * @param frontendId being released.
      */
-    public void releaseFrontend(int frontendId) {
-        mUsingFrontendIds.remove(frontendId);
+    public void releaseFrontend() {
+        mUsingFrontendIds.clear();
+        mShareFeClientIds.clear();
     }
 
     /**
@@ -201,6 +223,7 @@
      */
     public void reclaimAllResources() {
         mUsingFrontendIds.clear();
+        mShareFeClientIds.clear();
         mUsingLnbIds.clear();
         mUsingCasSystemId = INVALID_RESOURCE_ID;
     }
diff --git a/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java b/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java
index 7cb59dc..fb2347e8 100644
--- a/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java
+++ b/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java
@@ -210,19 +210,36 @@
             }
             synchronized (mLock) {
                 if (!checkClientExists(request.getClientId())) {
-                    throw new RemoteException("Request frontend from unregistered client:"
+                    throw new RemoteException("Request frontend from unregistered client: "
                             + request.getClientId());
                 }
+                // If the request client is holding or sharing a frontend, throw an exception.
+                if (!getClientProfile(request.getClientId()).getInUseFrontendIds().isEmpty()) {
+                    throw new RemoteException("Release frontend before requesting another one. "
+                            + "Client id: " + request.getClientId());
+                }
                 return requestFrontendInternal(request, frontendHandle);
             }
         }
 
         @Override
-        public void shareFrontend(int selfClientId, int targetClientId) {
+        public void shareFrontend(int selfClientId, int targetClientId) throws RemoteException {
             enforceTunerAccessPermission("shareFrontend");
             enforceTrmAccessPermission("shareFrontend");
-            if (DEBUG) {
-                Slog.d(TAG, "shareFrontend from " + selfClientId + " with " + targetClientId);
+            synchronized (mLock) {
+                if (!checkClientExists(selfClientId)) {
+                    throw new RemoteException("Share frontend request from an unregistered client:"
+                            + selfClientId);
+                }
+                if (!checkClientExists(targetClientId)) {
+                    throw new RemoteException("Request to share frontend with an unregistered "
+                            + "client:" + targetClientId);
+                }
+                if (getClientProfile(targetClientId).getInUseFrontendIds().isEmpty()) {
+                    throw new RemoteException("Request to share frontend with a client that has no "
+                            + "frontend resources. Target client id:" + targetClientId);
+                }
+                shareFrontendInternal(selfClientId, targetClientId);
             }
         }
 
@@ -315,7 +332,7 @@
                     throw new RemoteException(
                             "Client is not the current owner of the releasing fe.");
                 }
-                releaseFrontendInternal(fe);
+                releaseFrontendInternal(fe, clientId);
             }
         }
 
@@ -649,6 +666,17 @@
     }
 
     @VisibleForTesting
+    protected void shareFrontendInternal(int selfClientId, int targetClientId) {
+        if (DEBUG) {
+            Slog.d(TAG, "shareFrontend from " + selfClientId + " with " + targetClientId);
+        }
+        for (int feId : getClientProfile(targetClientId).getInUseFrontendIds()) {
+            getClientProfile(selfClientId).useFrontend(feId);
+        }
+        getClientProfile(targetClientId).shareFrontend(selfClientId);
+    }
+
+    @VisibleForTesting
     protected boolean requestLnbInternal(TunerLnbRequest request, int[] lnbHandle) {
         if (DEBUG) {
             Slog.d(TAG, "requestLnb(request=" + request + ")");
@@ -777,11 +805,17 @@
     }
 
     @VisibleForTesting
-    protected void releaseFrontendInternal(FrontendResource fe) {
+    protected void releaseFrontendInternal(FrontendResource fe, int clientId) {
         if (DEBUG) {
-            Slog.d(TAG, "releaseFrontend(id=" + fe.getId() + ")");
+            Slog.d(TAG, "releaseFrontend(id=" + fe.getId() + ", clientId=" + clientId + " )");
         }
-        updateFrontendClientMappingOnRelease(fe);
+        if (clientId == fe.getOwnerClientId()) {
+            ClientProfile ownerClient = getClientProfile(fe.getOwnerClientId());
+            for (int shareOwnerId : ownerClient.getShareFeClientIds()) {
+                clearFrontendAndClientMapping(getClientProfile(shareOwnerId));
+            }
+        }
+        clearFrontendAndClientMapping(getClientProfile(clientId));
     }
 
     @VisibleForTesting
@@ -882,8 +916,21 @@
             Slog.e(TAG, "Failed to reclaim resources on client " + reclaimingClientId, e);
             return false;
         }
+
+        // Reclaim all the resources of the share owners of the frontend that is used by the current
+        // resource reclaimed client.
         ClientProfile profile = getClientProfile(reclaimingClientId);
-        reclaimingResourcesFromClient(profile);
+        Set<Integer> shareFeClientIds = profile.getShareFeClientIds();
+        for (int clientId : shareFeClientIds) {
+            try {
+                mListeners.get(clientId).getListener().onReclaimResources();
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Failed to reclaim resources on client " + clientId, e);
+                return false;
+            }
+            clearAllResourcesAndClientMapping(getClientProfile(clientId));
+        }
+        clearAllResourcesAndClientMapping(profile);
         return true;
     }
 
@@ -929,16 +976,6 @@
         }
     }
 
-    private void updateFrontendClientMappingOnRelease(@NonNull FrontendResource releasingFrontend) {
-        ClientProfile ownerProfile = getClientProfile(releasingFrontend.getOwnerClientId());
-        releasingFrontend.removeOwner();
-        ownerProfile.releaseFrontend(releasingFrontend.getId());
-        for (int exclusiveGroupMember : releasingFrontend.getExclusiveGroupMemberFeIds()) {
-            getFrontendResource(exclusiveGroupMember).removeOwner();
-            ownerProfile.releaseFrontend(exclusiveGroupMember);
-        }
-    }
-
     private void updateLnbClientMappingOnNewGrant(int grantingId, int ownerClientId) {
         LnbResource grantingLnb = getLnbResource(grantingId);
         ClientProfile ownerProfile = getClientProfile(ownerClientId);
@@ -967,10 +1004,10 @@
     }
 
     /**
-     * Get the owner client's priority from the resource id.
+     * Get the owner client's priority.
      *
      * @param clientId the owner client id.
-     * @return the priority of the owner client of the resource.
+     * @return the priority of the owner client.
      */
     private int getOwnerClientPriority(int clientId) {
         return getClientProfile(clientId).getPriority();
@@ -1011,7 +1048,11 @@
             return;
         }
         if (fe.isInUse()) {
-            releaseFrontendInternal(fe);
+            ClientProfile ownerClient = getClientProfile(fe.getOwnerClientId());
+            for (int shareOwnerId : ownerClient.getShareFeClientIds()) {
+                clearFrontendAndClientMapping(getClientProfile(shareOwnerId));
+            }
+            clearFrontendAndClientMapping(ownerClient);
         }
         for (int excGroupmemberFeId : fe.getExclusiveGroupMemberFeIds()) {
             getFrontendResource(excGroupmemberFeId)
@@ -1093,21 +1134,37 @@
     }
 
     private void removeClientProfile(int clientId) {
-        reclaimingResourcesFromClient(getClientProfile(clientId));
+        for (int shareOwnerId : getClientProfile(clientId).getShareFeClientIds()) {
+            clearFrontendAndClientMapping(getClientProfile(shareOwnerId));
+        }
+        clearAllResourcesAndClientMapping(getClientProfile(clientId));
         mClientProfiles.remove(clientId);
         mListeners.remove(clientId);
     }
 
-    private void reclaimingResourcesFromClient(ClientProfile profile) {
+    private void clearFrontendAndClientMapping(ClientProfile profile) {
         for (Integer feId : profile.getInUseFrontendIds()) {
-            getFrontendResource(feId).removeOwner();
+            FrontendResource fe = getFrontendResource(feId);
+            if (fe.getOwnerClientId() == profile.getId()) {
+                fe.removeOwner();
+                continue;
+            }
+            getClientProfile(fe.getOwnerClientId()).stopSharingFrontend(profile.getId());
         }
+        profile.releaseFrontend();
+    }
+
+    private void clearAllResourcesAndClientMapping(ClientProfile profile) {
+        // Clear Lnb
         for (Integer lnbId : profile.getInUseLnbIds()) {
             getLnbResource(lnbId).removeOwner();
         }
+        // Clear Cas
         if (profile.getInUseCasSystemId() != ClientProfile.INVALID_RESOURCE_ID) {
             getCasResource(profile.getInUseCasSystemId()).removeOwner(profile.getId());
         }
+        // Clear Frontend
+        clearFrontendAndClientMapping(profile);
         profile.reclaimAllResources();
     }
 
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index da9d321..4f95696 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -43,7 +43,6 @@
         "com_android_server_stats_pull_StatsPullAtomService.cpp",
         "com_android_server_storage_AppFuseBridge.cpp",
         "com_android_server_SystemServer.cpp",
-        "com_android_server_TestNetworkService.cpp",
         "com_android_server_tv_TvUinputBridge.cpp",
         "com_android_server_tv_TvInputHal.cpp",
         "com_android_server_vr_VrManagerService.cpp",
@@ -59,8 +58,6 @@
         "com_android_server_pm_PackageManagerShellCommandDataLoader.cpp",
         "onload.cpp",
         ":lib_networkStatsFactory_native",
-        // TODO: move the file below to the connectivity APEX
-        "com_android_server_connectivity_Vpn.cpp",
     ],
 
     include_dirs: [
@@ -171,6 +168,7 @@
 
     static_libs: [
         "android.hardware.broadcastradio@common-utils-1x-lib",
+        "libservice-connectivity-static",
     ],
 
     product_variables: {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index faf3f06..43537d0 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -195,7 +195,6 @@
 import android.media.IAudioService;
 import android.net.ConnectivityManager;
 import android.net.IIpConnectivityMetrics;
-import android.net.NetworkUtils;
 import android.net.ProxyInfo;
 import android.net.Uri;
 import android.net.metrics.IpConnectivityLog;
@@ -267,6 +266,7 @@
 import com.android.internal.compat.IPlatformCompat;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
+import com.android.internal.net.NetworkUtilsInternal;
 import com.android.internal.notification.SystemNotificationChannels;
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.statusbar.IStatusBarService;
@@ -285,6 +285,7 @@
 import com.android.internal.widget.LockSettingsInternal;
 import com.android.internal.widget.LockscreenCredential;
 import com.android.internal.widget.PasswordValidationError;
+import com.android.net.module.util.ProxyUtils;
 import com.android.server.LocalServices;
 import com.android.server.LockGuard;
 import com.android.server.PersistentDataBlockManagerInternal;
@@ -7759,7 +7760,8 @@
         }
         exclusionList = exclusionList.trim();
 
-        ProxyInfo proxyProperties = new ProxyInfo(data[0], proxyPort, exclusionList);
+        ProxyInfo proxyProperties = ProxyInfo.buildDirectProxy(data[0], proxyPort,
+                ProxyUtils.exclusionStringAsList(exclusionList));
         if (!proxyProperties.isValid()) {
             Slog.e(LOG_TAG, "Invalid proxy properties, ignoring: " + proxyProperties.toString());
             return;
@@ -15540,7 +15542,7 @@
                 return PRIVATE_DNS_SET_NO_ERROR;
             case PRIVATE_DNS_MODE_PROVIDER_HOSTNAME:
                 if (TextUtils.isEmpty(privateDnsHost)
-                        || !NetworkUtils.isWeaklyValidatedHostname(privateDnsHost)) {
+                        || !NetworkUtilsInternal.isWeaklyValidatedHostname(privateDnsHost)) {
                     throw new IllegalArgumentException(
                             String.format("Provided hostname %s is not valid", privateDnsHost));
                 }
diff --git a/services/incremental/IncrementalService.cpp b/services/incremental/IncrementalService.cpp
index f3940e6..d07e70c 100644
--- a/services/incremental/IncrementalService.cpp
+++ b/services/incremental/IncrementalService.cpp
@@ -476,6 +476,9 @@
         if (!mkdirOrLog(path::join(backing, ".index"), 0777)) {
             return kInvalidStorageId;
         }
+        if (!mkdirOrLog(path::join(backing, ".incomplete"), 0777)) {
+            return kInvalidStorageId;
+        }
         auto status = mVold->mountIncFs(backing, mountTarget, 0, &controlParcel);
         if (!status.isOk()) {
             LOG(ERROR) << "Vold::mountIncFs() failed: " << status.toString8();
diff --git a/services/net/Android.bp b/services/net/Android.bp
index ae9bd41..eaf177e 100644
--- a/services/net/Android.bp
+++ b/services/net/Android.bp
@@ -57,6 +57,8 @@
     visibility: [
         "//frameworks/opt/net/wifi/service",
         "//frameworks/opt/net/wifi/tests/wifitests",
+        "//packages/modules/Wifi/service",
+        "//packages/modules/Wifi/service/tests/wifitests",
     ],
 }
 
diff --git a/services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/uidA-allowlisted-restrict-background-off.xml b/services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/uidA-allowed-restrict-background-off.xml
similarity index 100%
rename from services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/uidA-allowlisted-restrict-background-off.xml
rename to services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/uidA-allowed-restrict-background-off.xml
diff --git a/services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/uidA-allowlisted-restrict-background-on.xml b/services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/uidA-allowed-restrict-background-on.xml
similarity index 100%
rename from services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/uidA-allowlisted-restrict-background-on.xml
rename to services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/uidA-allowed-restrict-background-on.xml
diff --git a/services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/uidA-denylisted-restrict-background-off.xml b/services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/uidA-denied-restrict-background-off.xml
similarity index 100%
rename from services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/uidA-denylisted-restrict-background-off.xml
rename to services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/uidA-denied-restrict-background-off.xml
diff --git a/services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/uidA-denylisted-restrict-background-on.xml b/services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/uidA-denied-restrict-background-on.xml
similarity index 100%
rename from services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/uidA-denylisted-restrict-background-on.xml
rename to services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/uidA-denied-restrict-background-on.xml
diff --git a/services/tests/servicestests/src/com/android/internal/location/timezone/OWNERS b/services/tests/servicestests/src/com/android/internal/location/timezone/OWNERS
new file mode 100644
index 0000000..28aff18
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/internal/location/timezone/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 847766
+nfuller@google.com
+include /core/java/android/app/timedetector/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/audio/NoOpAudioSystemAdapter.java b/services/tests/servicestests/src/com/android/server/audio/NoOpAudioSystemAdapter.java
index 609af8d..8d706cb 100644
--- a/services/tests/servicestests/src/com/android/server/audio/NoOpAudioSystemAdapter.java
+++ b/services/tests/servicestests/src/com/android/server/audio/NoOpAudioSystemAdapter.java
@@ -79,6 +79,23 @@
     }
 
     @Override
+    public int setDevicesRoleForCapturePreset(int capturePreset, int role,
+                                              @NonNull List<AudioDeviceAttributes> devices) {
+        return AudioSystem.AUDIO_STATUS_OK;
+    }
+
+    @Override
+    public int removeDevicesRoleForCapturePreset(
+            int capturePreset, int role, @NonNull List<AudioDeviceAttributes> devicesToRemove) {
+        return AudioSystem.AUDIO_STATUS_OK;
+    }
+
+    @Override
+    public int clearDevicesRoleForCapturePreset(int capturePreset, int role) {
+        return AudioSystem.AUDIO_STATUS_OK;
+    }
+
+    @Override
     public int setParameters(String keyValuePairs) {
         return AudioSystem.AUDIO_STATUS_OK;
     }
diff --git a/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java b/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java
index 64014ba..1d3b643 100644
--- a/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java
+++ b/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java
@@ -107,18 +107,20 @@
         mCompatConfig = CompatConfigBuilder.create(mBuildClassifier, mContext)
                 .addEnabledChangeWithId(1L)
                 .addDisabledChangeWithIdAndName(2L, "change2")
-                .addEnableAfterSdkChangeWithIdAndDescription(Build.VERSION_CODES.O, 3L, "desc")
-                .addEnableAfterSdkChangeWithId(Build.VERSION_CODES.P, 4L)
-                .addEnableAfterSdkChangeWithId(Build.VERSION_CODES.Q, 5L)
-                .addEnableAfterSdkChangeWithId(Build.VERSION_CODES.R, 6L)
+                .addEnableSinceSdkChangeWithIdAndDescription(Build.VERSION_CODES.O, 3L, "desc")
+                .addEnableSinceSdkChangeWithId(Build.VERSION_CODES.P, 4L)
+                .addEnableSinceSdkChangeWithId(Build.VERSION_CODES.Q, 5L)
+                .addEnableSinceSdkChangeWithId(Build.VERSION_CODES.R, 6L)
                 .addLoggingOnlyChangeWithId(7L)
                 .build();
         mPlatformCompat = new PlatformCompat(mContext, mCompatConfig);
         assertThat(mPlatformCompat.listUIChanges()).asList().containsExactly(
                 new CompatibilityChangeInfo(1L, "", -1, -1, false, false, ""),
                 new CompatibilityChangeInfo(2L, "change2", -1, -1, true, false, ""),
-                new CompatibilityChangeInfo(4L, "", Build.VERSION_CODES.P, -1, false, false, ""),
-                new CompatibilityChangeInfo(5L, "", Build.VERSION_CODES.Q, -1, false, false, ""));
+                new CompatibilityChangeInfo(5L, "", /*enableAfter*/ -1,
+                        /*enableSince*/ Build.VERSION_CODES.Q, false, false, ""),
+                new CompatibilityChangeInfo(6L, "", /*enableAfter*/ -1,
+                        /*enableSince*/ Build.VERSION_CODES.R, false, false, ""));
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/net/IpConfigStoreTest.java b/services/tests/servicestests/src/com/android/server/net/IpConfigStoreTest.java
index 9d300a6..401d6e3 100644
--- a/services/tests/servicestests/src/com/android/server/net/IpConfigStoreTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/IpConfigStoreTest.java
@@ -39,6 +39,7 @@
 import java.io.DataOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.Arrays;
 
 /**
  * Unit tests for {@link IpConfigStore}
@@ -82,7 +83,8 @@
         staticIpConfiguration.dnsServers.add(InetAddresses.parseNumericAddress(DNS_IP_ADDR_1));
         staticIpConfiguration.dnsServers.add(InetAddresses.parseNumericAddress(DNS_IP_ADDR_2));
 
-        ProxyInfo proxyInfo = new ProxyInfo("10.10.10.10", 88, "host1,host2");
+        ProxyInfo proxyInfo =
+                ProxyInfo.buildDirectProxy("10.10.10.10", 88, Arrays.asList("host1", "host2"));
 
         IpConfiguration expectedConfig1 = new IpConfiguration(IpAssignment.STATIC,
                 ProxySettings.STATIC, staticIpConfiguration, proxyInfo);
diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
index f8043fa..fec0273 100644
--- a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
@@ -479,7 +479,7 @@
     }
 
     /**
-     * Adds allowlist when restrict background is on - app should receive an intent.
+     * Adds an app to allowlist when restrict background is on - app should receive an intent.
      */
     @Test
     @NetPolicyXml("restrict-background-on.xml")
@@ -490,7 +490,7 @@
     }
 
     /**
-     * Adds allowlist when restrict background is off - app should not receive an intent.
+     * Adds an app to allowlist when restrict background is off - app should not receive an intent.
      */
     @Test
     public void testAddRestrictBackgroundAllowlist_restrictBackgroundOff() throws Exception {
@@ -499,7 +499,7 @@
     }
 
     private void addRestrictBackgroundAllowlist(boolean expectIntent) throws Exception {
-        assertAllowlistUids();
+        assertRestrictBackgroundAllowedUids();
         assertUidPolicy(UID_A, POLICY_NONE);
 
         final FutureIntent futureIntent = newRestrictBackgroundChangedFuture();
@@ -507,7 +507,7 @@
 
         mService.setUidPolicy(UID_A, POLICY_ALLOW_METERED_BACKGROUND);
 
-        assertAllowlistUids(UID_A);
+        assertRestrictBackgroundAllowedUids(UID_A);
         assertUidPolicy(UID_A, POLICY_ALLOW_METERED_BACKGROUND);
         mPolicyListener.waitAndVerify()
                 .onUidPoliciesChanged(APP_ID_A, POLICY_ALLOW_METERED_BACKGROUND);
@@ -519,10 +519,10 @@
     }
 
     /**
-     * Removes allowlist when restrict background is on - app should receive an intent.
+     * Removes an app from allowlist when restrict background is on - app should receive an intent.
      */
     @Test
-    @NetPolicyXml("uidA-allowlisted-restrict-background-on.xml")
+    @NetPolicyXml("uidA-allowed-restrict-background-on.xml")
     public void testRemoveRestrictBackgroundAllowlist_restrictBackgroundOn() throws Exception {
         assertRestrictBackgroundOn();
         assertRestrictBackgroundChangedReceived(mFutureIntent, null);
@@ -530,10 +530,11 @@
     }
 
     /**
-     * Removes allowlist when restrict background is off - app should not receive an intent.
+     * Removes an app from allowlist when restrict background is off - app should not
+     * receive an intent.
      */
     @Test
-    @NetPolicyXml("uidA-allowlisted-restrict-background-off.xml")
+    @NetPolicyXml("uidA-allowed-restrict-background-off.xml")
     public void testRemoveRestrictBackgroundAllowlist_restrictBackgroundOff() throws Exception {
         assertRestrictBackgroundOff();
         removeRestrictBackgroundAllowlist(false);
@@ -688,7 +689,7 @@
     }
 
     private void removeRestrictBackgroundAllowlist(boolean expectIntent) throws Exception {
-        assertAllowlistUids(UID_A);
+        assertRestrictBackgroundAllowedUids(UID_A);
         assertUidPolicy(UID_A, POLICY_ALLOW_METERED_BACKGROUND);
 
         final FutureIntent futureIntent = newRestrictBackgroundChangedFuture();
@@ -696,7 +697,7 @@
 
         mService.setUidPolicy(UID_A, POLICY_NONE);
 
-        assertAllowlistUids();
+        assertRestrictBackgroundAllowedUids();
         assertUidPolicy(UID_A, POLICY_NONE);
         mPolicyListener.waitAndVerify().onUidPoliciesChanged(APP_ID_A, POLICY_NONE);
         if (expectIntent) {
@@ -707,7 +708,7 @@
     }
 
     /**
-     * Adds denylist when restrict background is on - app should not receive an intent.
+     * Adds an app to denylist when restrict background is on - app should not receive an intent.
      */
     @Test
     @NetPolicyXml("restrict-background-on.xml")
@@ -718,7 +719,7 @@
     }
 
     /**
-     * Adds denylist when restrict background is off - app should receive an intent.
+     * Adds an app to denylist when restrict background is off - app should receive an intent.
      */
     @Test
     public void testAddRestrictBackgroundDenylist_restrictBackgroundOff() throws Exception {
@@ -744,10 +745,11 @@
     }
 
     /**
-     * Removes denylist when restrict background is on - app should not receive an intent.
+     * Removes an app from denylist when restrict background is on - app should not
+     * receive an intent.
      */
     @Test
-    @NetPolicyXml("uidA-denylisted-restrict-background-on.xml")
+    @NetPolicyXml("uidA-denied-restrict-background-on.xml")
     public void testRemoveRestrictBackgroundDenylist_restrictBackgroundOn() throws Exception {
         assertRestrictBackgroundOn();
         assertRestrictBackgroundChangedReceived(mFutureIntent, null);
@@ -755,10 +757,11 @@
     }
 
     /**
-     * Removes denylist when restrict background is off - app should receive an intent.
+     * Removes an app from denylist when restrict background is off - app should
+     * receive an intent.
      */
     @Test
-    @NetPolicyXml("uidA-denylisted-restrict-background-off.xml")
+    @NetPolicyXml("uidA-denied-restrict-background-off.xml")
     public void testRemoveRestrictBackgroundDenylist_restrictBackgroundOff() throws Exception {
         assertRestrictBackgroundOff();
         removeRestrictBackgroundDenylist(true);
@@ -782,8 +785,8 @@
     }
 
     @Test
-    @NetPolicyXml("uidA-denylisted-restrict-background-on.xml")
-    public void testDenylistedAppIsNotNotifiedWhenRestrictBackgroundIsOn() throws Exception {
+    @NetPolicyXml("uidA-denied-restrict-background-on.xml")
+    public void testDeniedAppIsNotNotifiedWhenRestrictBackgroundIsOn() throws Exception {
         assertRestrictBackgroundOn();
         assertRestrictBackgroundChangedReceived(mFutureIntent, null);
         assertUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND);
@@ -794,11 +797,11 @@
     }
 
     @Test
-    @NetPolicyXml("uidA-allowlisted-restrict-background-on.xml")
-    public void testAllowlistedAppIsNotNotifiedWhenRestrictBackgroundIsOn() throws Exception {
+    @NetPolicyXml("uidA-allowed-restrict-background-on.xml")
+    public void testAllowedAppIsNotNotifiedWhenRestrictBackgroundIsOn() throws Exception {
         assertRestrictBackgroundOn();
         assertRestrictBackgroundChangedReceived(mFutureIntent, null);
-        assertAllowlistUids(UID_A);
+        assertRestrictBackgroundAllowedUids(UID_A);
 
         final FutureIntent futureIntent = newRestrictBackgroundChangedFuture();
         setRestrictBackground(true);
@@ -806,11 +809,11 @@
     }
 
     @Test
-    @NetPolicyXml("uidA-allowlisted-restrict-background-on.xml")
-    public void testAllowlistedAppIsNotifiedWhenDenylisted() throws Exception {
+    @NetPolicyXml("uidA-allowed-restrict-background-on.xml")
+    public void testAllowedAppIsNotifiedWhenDenylisted() throws Exception {
         assertRestrictBackgroundOn();
         assertRestrictBackgroundChangedReceived(mFutureIntent, null);
-        assertAllowlistUids(UID_A);
+        assertRestrictBackgroundAllowedUids(UID_A);
 
         final FutureIntent futureIntent = newRestrictBackgroundChangedFuture();
         mService.setUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND);
@@ -830,33 +833,33 @@
     }
 
     private void restrictBackgroundListsTest() throws Exception {
-        // UIds that are allowlisted.
-        assertAllowlistUids(UID_A, UID_B, UID_C);
+        // UIds that are in allowlist.
+        assertRestrictBackgroundAllowedUids(UID_A, UID_B, UID_C);
         assertUidPolicy(UID_A, POLICY_ALLOW_METERED_BACKGROUND);
         assertUidPolicy(UID_B, POLICY_ALLOW_METERED_BACKGROUND);
         assertUidPolicy(UID_C, POLICY_ALLOW_METERED_BACKGROUND);
 
-        // UIDs that are denylisted.
+        // UIDs that are in denylist.
         assertUidPolicy(UID_D, POLICY_NONE);
         assertUidPolicy(UID_E, POLICY_REJECT_METERED_BACKGROUND);
 
         // UIDS that have legacy policies.
         assertUidPolicy(UID_F, 2); // POLICY_ALLOW_BACKGROUND_BATTERY_SAVE
 
-        // Remove allowlist.
+        // Remove an uid from allowlist.
         mService.setUidPolicy(UID_A, POLICY_NONE);
         assertUidPolicy(UID_A, POLICY_NONE);
-        assertAllowlistUids(UID_B, UID_C);
+        assertRestrictBackgroundAllowedUids(UID_B, UID_C);
 
-        // Add allowlist when denylisted.
+        // Add an app to allowlist which is currently in denylist.
         mService.setUidPolicy(UID_E, POLICY_ALLOW_METERED_BACKGROUND);
         assertUidPolicy(UID_E, POLICY_ALLOW_METERED_BACKGROUND);
-        assertAllowlistUids(UID_B, UID_C, UID_E);
+        assertRestrictBackgroundAllowedUids(UID_B, UID_C, UID_E);
 
-        // Add denylist when allowlisted.
+        // Add an app to denylist when is currently in allowlist.
         mService.setUidPolicy(UID_B, POLICY_REJECT_METERED_BACKGROUND);
         assertUidPolicy(UID_B, POLICY_REJECT_METERED_BACKGROUND);
-        assertAllowlistUids(UID_C, UID_E);
+        assertRestrictBackgroundAllowedUids(UID_C, UID_E);
     }
 
     /**
@@ -865,7 +868,7 @@
     @Test
     @NetPolicyXml("restrict-background-lists-mixed-format.xml")
     public void testRestrictBackgroundLists_mixedFormat() throws Exception {
-        assertAllowlistUids(UID_A, UID_C, UID_D);
+        assertRestrictBackgroundAllowedUids(UID_A, UID_C, UID_D);
         assertUidPolicy(UID_A, POLICY_ALLOW_METERED_BACKGROUND);
         assertUidPolicy(UID_B, POLICY_REJECT_METERED_BACKGROUND); // Denylist prevails.
         assertUidPolicy(UID_C, (POLICY_ALLOW_METERED_BACKGROUND | 2));
@@ -2040,7 +2043,7 @@
         }
     }
 
-    private void assertAllowlistUids(int... uids) {
+    private void assertRestrictBackgroundAllowedUids(int... uids) {
         assertContainsInAnyOrder(mService.getUidsWithPolicy(POLICY_ALLOW_METERED_BACKGROUND), uids);
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/tv/tunerresourcemanager/TunerResourceManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/tv/tunerresourcemanager/TunerResourceManagerServiceTest.java
index 2372dd2..1055069 100644
--- a/services/tests/servicestests/src/com/android/server/tv/tunerresourcemanager/TunerResourceManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/tv/tunerresourcemanager/TunerResourceManagerServiceTest.java
@@ -74,7 +74,7 @@
             mReclaimed = true;
         }
 
-        public boolean isRelaimed() {
+        public boolean isReclaimed() {
             return mReclaimed;
         }
     }
@@ -379,13 +379,13 @@
                 new TunerFrontendRequest(clientId1[0] /*clientId*/, FrontendSettings.TYPE_DVBT);
         assertThat(mTunerResourceManagerService
                 .requestFrontendInternal(request, frontendHandle)).isFalse();
-        assertThat(listener.isRelaimed()).isFalse();
+        assertThat(listener.isReclaimed()).isFalse();
 
         request =
                 new TunerFrontendRequest(clientId1[0] /*clientId*/, FrontendSettings.TYPE_DVBS);
         assertThat(mTunerResourceManagerService
                 .requestFrontendInternal(request, frontendHandle)).isFalse();
-        assertThat(listener.isRelaimed()).isFalse();
+        assertThat(listener.isReclaimed()).isFalse();
     }
 
     @Test
@@ -444,7 +444,7 @@
                 .getOwnerClientId()).isEqualTo(clientId1[0]);
         assertThat(mTunerResourceManagerService.getFrontendResource(infos[1].getId())
                 .getOwnerClientId()).isEqualTo(clientId1[0]);
-        assertThat(listener.isRelaimed()).isTrue();
+        assertThat(listener.isReclaimed()).isTrue();
     }
 
     @Test
@@ -478,7 +478,7 @@
 
         // Release frontend
         mTunerResourceManagerService.releaseFrontendInternal(mTunerResourceManagerService
-                .getFrontendResource(frontendId));
+                .getFrontendResource(frontendId), clientId[0]);
         assertThat(mTunerResourceManagerService
                 .getFrontendResource(frontendId).isInUse()).isFalse();
         assertThat(mTunerResourceManagerService
@@ -540,7 +540,7 @@
         assertThat(mTunerResourceManagerService.getCasResource(1)
                 .getOwnerClientIds()).isEqualTo(new HashSet<Integer>(Arrays.asList(clientId1[0])));
         assertThat(mTunerResourceManagerService.getCasResource(1).isFullyUsed()).isFalse();
-        assertThat(listener.isRelaimed()).isTrue();
+        assertThat(listener.isReclaimed()).isTrue();
     }
 
     @Test
@@ -625,7 +625,7 @@
                 .isInUse()).isTrue();
         assertThat(mTunerResourceManagerService.getLnbResource(lnbIds[0])
                 .getOwnerClientId()).isEqualTo(clientId1[0]);
-        assertThat(listener.isRelaimed()).isTrue();
+        assertThat(listener.isReclaimed()).isTrue();
         assertThat(mTunerResourceManagerService.getClientProfile(clientId0[0])
                 .getInUseLnbIds().size()).isEqualTo(0);
     }
@@ -753,4 +753,293 @@
                 backgroundRecordProfile)).isEqualTo(
                         (backgroundPlaybackPriority > backgroundRecordPriority));
     }
+
+    @Test
+    public void shareFrontendTest_FrontendWithExclusiveGroupReadyToShare() {
+        /**** Register Clients and Set Priority ****/
+
+        // Int array to save the returned client ids
+        int[] ownerClientId0 = new int[1];
+        int[] ownerClientId1 = new int[1];
+        int[] shareClientId0 = new int[1];
+        int[] shareClientId1 = new int[1];
+
+        // Predefined client profiles
+        ResourceClientProfile[] ownerProfiles = new ResourceClientProfile[2];
+        ResourceClientProfile[] shareProfiles = new ResourceClientProfile[2];
+        ownerProfiles[0] = new ResourceClientProfile(
+                "0" /*sessionId*/,
+                TvInputService.PRIORITY_HINT_USE_CASE_TYPE_LIVE);
+        ownerProfiles[1] = new ResourceClientProfile(
+                "1" /*sessionId*/,
+                TvInputService.PRIORITY_HINT_USE_CASE_TYPE_LIVE);
+        shareProfiles[0] = new ResourceClientProfile(
+                "2" /*sessionId*/,
+                TvInputService.PRIORITY_HINT_USE_CASE_TYPE_RECORD);
+        shareProfiles[1] = new ResourceClientProfile(
+                "3" /*sessionId*/,
+                TvInputService.PRIORITY_HINT_USE_CASE_TYPE_RECORD);
+
+        // Predefined client reclaim listeners
+        TestResourcesReclaimListener ownerListener0 = new TestResourcesReclaimListener();
+        TestResourcesReclaimListener shareListener0 = new TestResourcesReclaimListener();
+        TestResourcesReclaimListener ownerListener1 = new TestResourcesReclaimListener();
+        TestResourcesReclaimListener shareListener1 = new TestResourcesReclaimListener();
+        // Register clients and validate the returned client ids
+        mTunerResourceManagerService
+                .registerClientProfileInternal(ownerProfiles[0], ownerListener0, ownerClientId0);
+        mTunerResourceManagerService
+                .registerClientProfileInternal(shareProfiles[0], shareListener0, shareClientId0);
+        mTunerResourceManagerService
+                .registerClientProfileInternal(ownerProfiles[1], ownerListener1, ownerClientId1);
+        mTunerResourceManagerService
+                .registerClientProfileInternal(shareProfiles[1], shareListener1, shareClientId1);
+        assertThat(ownerClientId0[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
+        assertThat(shareClientId0[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
+        assertThat(ownerClientId1[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
+        assertThat(shareClientId1[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
+
+        mTunerResourceManagerService.updateClientPriorityInternal(
+                ownerClientId0[0],
+                100/*priority*/,
+                0/*niceValue*/);
+        mTunerResourceManagerService.updateClientPriorityInternal(
+                shareClientId0[0],
+                200/*priority*/,
+                0/*niceValue*/);
+        mTunerResourceManagerService.updateClientPriorityInternal(
+                ownerClientId1[0],
+                300/*priority*/,
+                0/*niceValue*/);
+        mTunerResourceManagerService.updateClientPriorityInternal(
+                shareClientId1[0],
+                400/*priority*/,
+                0/*niceValue*/);
+
+        /**** Init Frontend Resources ****/
+
+        // Predefined frontend info
+        TunerFrontendInfo[] infos = new TunerFrontendInfo[2];
+        infos[0] = new TunerFrontendInfo(
+                0 /*id*/,
+                FrontendSettings.TYPE_DVBT,
+                1 /*exclusiveGroupId*/);
+        infos[1] = new TunerFrontendInfo(
+                1 /*id*/,
+                FrontendSettings.TYPE_DVBS,
+                1 /*exclusiveGroupId*/);
+
+        /**** Init Lnb Resources ****/
+        int[] lnbIds = {1};
+        mTunerResourceManagerService.setLnbInfoListInternal(lnbIds);
+
+        // Update frontend list in TRM
+        mTunerResourceManagerService.setFrontendInfoListInternal(infos);
+
+        /**** Request Frontend ****/
+
+        // Predefined frontend request and array to save returned frontend handle
+        int[] frontendHandle = new int[1];
+        TunerFrontendRequest request = new TunerFrontendRequest(
+                ownerClientId0[0] /*clientId*/,
+                FrontendSettings.TYPE_DVBT);
+
+        // Request call and validate granted resource and internal mapping
+        assertThat(mTunerResourceManagerService
+                .requestFrontendInternal(request, frontendHandle))
+                .isTrue();
+        assertThat(mTunerResourceManagerService
+                .getResourceIdFromHandle(frontendHandle[0]))
+                .isEqualTo(infos[0].getId());
+        assertThat(mTunerResourceManagerService
+                .getClientProfile(ownerClientId0[0])
+                .getInUseFrontendIds())
+                .isEqualTo(new HashSet<Integer>(Arrays.asList(
+                        infos[0].getId(),
+                        infos[1].getId())));
+
+        /**** Share Frontend ****/
+
+        // Share frontend call and validate the internal mapping
+        mTunerResourceManagerService.shareFrontendInternal(
+                shareClientId0[0]/*selfClientId*/,
+                ownerClientId0[0]/*targetClientId*/);
+        mTunerResourceManagerService.shareFrontendInternal(
+                shareClientId1[0]/*selfClientId*/,
+                ownerClientId0[0]/*targetClientId*/);
+        // Verify fe in use status
+        assertThat(mTunerResourceManagerService.getFrontendResource(infos[0].getId())
+                .isInUse()).isTrue();
+        assertThat(mTunerResourceManagerService.getFrontendResource(infos[1].getId())
+                .isInUse()).isTrue();
+        // Verify fe owner status
+        assertThat(mTunerResourceManagerService.getFrontendResource(infos[0].getId())
+                .getOwnerClientId()).isEqualTo(ownerClientId0[0]);
+        assertThat(mTunerResourceManagerService.getFrontendResource(infos[1].getId())
+                .getOwnerClientId()).isEqualTo(ownerClientId0[0]);
+        // Verify share fe client status in the primary owner client
+        assertThat(mTunerResourceManagerService.getClientProfile(ownerClientId0[0])
+                .getShareFeClientIds())
+                .isEqualTo(new HashSet<Integer>(Arrays.asList(
+                        shareClientId0[0],
+                        shareClientId1[0])));
+        // Verify in use frontend list in all the primary owner and share owner clients
+        assertThat(mTunerResourceManagerService
+                .getClientProfile(ownerClientId0[0])
+                .getInUseFrontendIds())
+                .isEqualTo(new HashSet<Integer>(Arrays.asList(
+                        infos[0].getId(),
+                        infos[1].getId())));
+        assertThat(mTunerResourceManagerService
+                .getClientProfile(shareClientId0[0])
+                .getInUseFrontendIds())
+                .isEqualTo(new HashSet<Integer>(Arrays.asList(
+                        infos[0].getId(),
+                        infos[1].getId())));
+        assertThat(mTunerResourceManagerService
+                .getClientProfile(shareClientId1[0])
+                .getInUseFrontendIds())
+                .isEqualTo(new HashSet<Integer>(Arrays.asList(
+                        infos[0].getId(),
+                        infos[1].getId())));
+
+        /**** Remove Frontend Share Owner ****/
+
+        // Unregister the second share fe client
+        mTunerResourceManagerService.unregisterClientProfileInternal(shareClientId1[0]);
+
+        // Validate the internal mapping
+        assertThat(mTunerResourceManagerService.getClientProfile(ownerClientId0[0])
+                .getShareFeClientIds())
+                .isEqualTo(new HashSet<Integer>(Arrays.asList(
+                        shareClientId0[0])));
+        assertThat(mTunerResourceManagerService
+                .getClientProfile(ownerClientId0[0])
+                .getInUseFrontendIds())
+                .isEqualTo(new HashSet<Integer>(Arrays.asList(
+                        infos[0].getId(),
+                        infos[1].getId())));
+        assertThat(mTunerResourceManagerService
+                .getClientProfile(shareClientId0[0])
+                .getInUseFrontendIds())
+                .isEqualTo(new HashSet<Integer>(Arrays.asList(
+                        infos[0].getId(),
+                        infos[1].getId())));
+
+        /**** Request Shared Frontend with Higher Priority Client ****/
+
+        // Predefined second frontend request
+        request = new TunerFrontendRequest(
+                ownerClientId1[0] /*clientId*/,
+                FrontendSettings.TYPE_DVBT);
+
+        // Second request call
+        assertThat(mTunerResourceManagerService
+                .requestFrontendInternal(request, frontendHandle))
+                .isTrue();
+
+        // Validate granted resource and internal mapping
+        assertThat(mTunerResourceManagerService
+                .getResourceIdFromHandle(frontendHandle[0]))
+                .isEqualTo(infos[0].getId());
+        assertThat(mTunerResourceManagerService.getFrontendResource(infos[0].getId())
+                .getOwnerClientId()).isEqualTo(ownerClientId1[0]);
+        assertThat(mTunerResourceManagerService.getFrontendResource(infos[1].getId())
+                .getOwnerClientId()).isEqualTo(ownerClientId1[0]);
+        assertThat(mTunerResourceManagerService
+                .getClientProfile(ownerClientId1[0])
+                .getInUseFrontendIds())
+                .isEqualTo(new HashSet<Integer>(Arrays.asList(
+                        infos[0].getId(),
+                        infos[1].getId())));
+        assertThat(mTunerResourceManagerService
+                .getClientProfile(ownerClientId0[0])
+                .getInUseFrontendIds()
+                .isEmpty())
+                .isTrue();
+        assertThat(mTunerResourceManagerService
+                .getClientProfile(shareClientId0[0])
+                .getInUseFrontendIds()
+                .isEmpty())
+                .isTrue();
+        assertThat(mTunerResourceManagerService
+                .getClientProfile(ownerClientId0[0])
+                .getShareFeClientIds()
+                .isEmpty())
+                .isTrue();
+        assertThat(ownerListener0.isReclaimed()).isTrue();
+        assertThat(shareListener0.isReclaimed()).isTrue();
+
+        /**** Release Frontend Resource From Primary Owner ****/
+
+        // Reshare the frontend
+        mTunerResourceManagerService.shareFrontendInternal(
+                shareClientId0[0]/*selfClientId*/,
+                ownerClientId1[0]/*targetClientId*/);
+
+        // Release the frontend resource from the primary owner
+        mTunerResourceManagerService.releaseFrontendInternal(mTunerResourceManagerService
+                .getFrontendResource(infos[0].getId()), ownerClientId1[0]);
+
+        // Validate the internal mapping
+        assertThat(mTunerResourceManagerService.getFrontendResource(infos[0].getId())
+                .isInUse()).isFalse();
+        assertThat(mTunerResourceManagerService.getFrontendResource(infos[1].getId())
+                .isInUse()).isFalse();
+        // Verify client status
+        assertThat(mTunerResourceManagerService
+                .getClientProfile(ownerClientId1[0])
+                .getInUseFrontendIds()
+                .isEmpty())
+                .isTrue();
+        assertThat(mTunerResourceManagerService
+                .getClientProfile(shareClientId0[0])
+                .getInUseFrontendIds()
+                .isEmpty())
+                .isTrue();
+        assertThat(mTunerResourceManagerService
+                .getClientProfile(ownerClientId1[0])
+                .getShareFeClientIds()
+                .isEmpty())
+                .isTrue();
+
+        /**** Unregister Primary Owner when the Share owner owns an Lnb ****/
+
+        // Predefined Lnb request and handle array
+        TunerLnbRequest requestLnb = new TunerLnbRequest(shareClientId0[0]);
+        int[] lnbHandle = new int[1];
+
+        // Request for an Lnb
+        assertThat(mTunerResourceManagerService
+                .requestLnbInternal(requestLnb, lnbHandle))
+                .isTrue();
+
+        // Request and share the frontend resource again
+        assertThat(mTunerResourceManagerService
+                .requestFrontendInternal(request, frontendHandle))
+                .isTrue();
+        mTunerResourceManagerService.shareFrontendInternal(
+                shareClientId0[0]/*selfClientId*/,
+                ownerClientId1[0]/*targetClientId*/);
+
+        // Unregister the primary owner of the shared frontend
+        mTunerResourceManagerService.unregisterClientProfileInternal(ownerClientId1[0]);
+
+        // Validate the internal mapping
+        assertThat(mTunerResourceManagerService.getFrontendResource(infos[0].getId())
+                .isInUse()).isFalse();
+        assertThat(mTunerResourceManagerService.getFrontendResource(infos[1].getId())
+                .isInUse()).isFalse();
+        // Verify client status
+        assertThat(mTunerResourceManagerService
+                .getClientProfile(shareClientId0[0])
+                .getInUseFrontendIds()
+                .isEmpty())
+                .isTrue();
+        assertThat(mTunerResourceManagerService
+                .getClientProfile(shareClientId0[0])
+                .getInUseLnbIds())
+                .isEqualTo(new HashSet<Integer>(Arrays.asList(
+                        lnbIds[0])));
+    }
 }
diff --git a/telephony/java/android/telephony/AccessNetworkUtils.java b/telephony/java/android/telephony/AccessNetworkUtils.java
index 981ed450..7661a32 100644
--- a/telephony/java/android/telephony/AccessNetworkUtils.java
+++ b/telephony/java/android/telephony/AccessNetworkUtils.java
@@ -5,8 +5,11 @@
 import static android.telephony.ServiceState.DUPLEX_MODE_UNKNOWN;
 
 import android.telephony.AccessNetworkConstants.EutranBand;
+import android.telephony.AccessNetworkConstants.GeranBand;
+import android.telephony.AccessNetworkConstants.UtranBand;
 import android.telephony.ServiceState.DuplexMode;
 
+import java.util.Arrays;
 
 /**
  * Utilities to map between radio constants.
@@ -20,6 +23,9 @@
 
     public static final int INVALID_BAND = -1;
 
+    /** ISO country code of Japan. */
+    private static final String JAPAN_ISO_COUNTRY_CODE = "jp";
+
     /**
      * Gets the duplex mode for the given EUTRAN operating band.
      *
@@ -50,7 +56,7 @@
     /**
      * Gets the EUTRAN Operating band for a given downlink EARFCN.
      *
-     * <p>See 3GPP 36.101 sec 5.7.3-1 for calculation.
+     * <p>See 3GPP TS 36.101 clause 5.7.3-1 for calculation.
      *
      * @param earfcn The downlink EARFCN
      * @return Operating band number, or {@link #INVALID_BAND} if no corresponding band exists
@@ -198,4 +204,125 @@
 
         return INVALID_BAND;
     }
+
+    /**
+     * Gets the GERAN Operating band for a given ARFCN.
+     *
+     * <p>See 3GPP TS 45.005 clause 2 for calculation.
+     *
+     * @param arfcn The ARFCN
+     * @return Operating band number, or {@link #INVALID_BAND} if no corresponding band exists
+     */
+    public static int getOperatingBandForArfcn(int arfcn) {
+        if (arfcn >= 0 && arfcn <= 124) {
+            return GeranBand.BAND_E900;
+        } else if (arfcn >= 128 && arfcn <= 251) {
+            return GeranBand.BAND_850;
+        } else if (arfcn >= 259 && arfcn <= 293) {
+            return GeranBand.BAND_450;
+        } else if (arfcn >= 306 && arfcn <= 340) {
+            return GeranBand.BAND_480;
+        } else if (arfcn >= 438 && arfcn <= 511) {
+            return GeranBand.BAND_750;
+        } else if (arfcn >= 512 && arfcn <= 885) {
+            // ARFCN between 512 and 810 are also part of BAND_PCS1900.
+            // Returning BAND_DCS1800 in both cases.
+            return GeranBand.BAND_DCS1800;
+        } else if (arfcn >= 940 && arfcn <= 974) {
+            return GeranBand.BAND_ER900;
+        } else if (arfcn >= 975 && arfcn <= 1023) {
+            return GeranBand.BAND_E900;
+        }
+        return INVALID_BAND;
+    }
+
+    /**
+     * Gets the UTRAN Operating band for a given downlink UARFCN.
+     *
+     * <p>See 3GPP TS 25.101 clause 5.4.4 for calculation.
+     *
+     * @param uarfcn The downlink UARFCN
+     * @return Operating band number, or {@link #INVALID_BAND} if no corresponding band exists
+     */
+    public static int getOperatingBandForUarfcn(int uarfcn) {
+        // List of additional bands defined in TS 25.101.
+        int[] addlBand2 = {412, 437, 462, 487, 512, 537, 562, 587, 612, 637, 662, 687};
+        int[] addlBand4 = {1887, 1912, 1937, 1962, 1987, 2012, 2037, 2062, 2087};
+        int[] addlBand5 = {1007, 1012, 1032, 1037, 1062, 1087};
+        int[] addlBand6 = {1037, 1062};
+        int[] addlBand7 =
+                {2587, 2612, 2637, 2662, 2687, 2712, 2737, 2762, 2787, 2812, 2837, 2862,
+                2887, 2912};
+        int[] addlBand10 =
+                {3412, 3437, 3462, 3487, 3512, 3537, 3562, 3587, 3612, 3637, 3662, 3687};
+        int[] addlBand12 = {3932, 3957, 3962, 3987, 3992};
+        int[] addlBand13 = {4067, 4092};
+        int[] addlBand14 = {4167, 4192};
+        int[] addlBand19 = {787, 812, 837};
+        int[] addlBand25 =
+                {6292, 6317, 6342, 6367, 6392, 6417, 6442, 6467, 6492, 6517, 6542, 6567, 6592};
+        int[] addlBand26 = {5937, 5962, 5987, 5992, 6012, 6017, 6037, 6042, 6062, 6067, 6087};
+
+        if (uarfcn >= 10562 && uarfcn <= 10838) {
+            return UtranBand.BAND_1;
+        } else if ((uarfcn >= 9662 && uarfcn <= 9938)
+                || Arrays.binarySearch(addlBand2, uarfcn) >= 0) {
+            return UtranBand.BAND_2;
+        } else if (uarfcn >= 1162 && uarfcn <= 1513) {
+            return UtranBand.BAND_3;
+        } else if ((uarfcn >= 1537 && uarfcn <= 1738)
+                || Arrays.binarySearch(addlBand4, uarfcn) >= 0) {
+            return UtranBand.BAND_4;
+        } else if (uarfcn >= 4387 && uarfcn <= 4413) {
+            // Band 6 is a subset of band 5. Only Japan uses band 6 and Japan does not have band 5.
+            String country = TelephonyManager.getDefault().getNetworkCountryIso();
+            if (JAPAN_ISO_COUNTRY_CODE.compareToIgnoreCase(country) == 0) {
+                return UtranBand.BAND_6;
+            } else {
+                return UtranBand.BAND_5;
+            }
+        } else if ((uarfcn >= 4357 && uarfcn <= 4458)
+                || Arrays.binarySearch(addlBand5, uarfcn) >= 0) {
+            return UtranBand.BAND_5;
+        } else if (Arrays.binarySearch(addlBand6, uarfcn) >= 0) {
+            return UtranBand.BAND_6;
+        } else if ((uarfcn >= 2237 && uarfcn <= 2563)
+                || Arrays.binarySearch(addlBand7, uarfcn) >= 0) {
+            return UtranBand.BAND_7;
+        } else if (uarfcn >= 2937 && uarfcn <= 3088) {
+            return UtranBand.BAND_8;
+        } else if (uarfcn >= 9237 && uarfcn <= 9387) {
+            return UtranBand.BAND_9;
+        } else if ((uarfcn >= 3112 && uarfcn <= 3388)
+                || Arrays.binarySearch(addlBand10, uarfcn) >= 0) {
+            return UtranBand.BAND_10;
+        } else if (uarfcn >= 3712 && uarfcn <= 3787) {
+            return UtranBand.BAND_11;
+        } else if ((uarfcn >= 3842 && uarfcn <= 3903)
+                || Arrays.binarySearch(addlBand12, uarfcn) >= 0) {
+            return UtranBand.BAND_12;
+        } else if ((uarfcn >= 4017 && uarfcn <= 4043)
+                || Arrays.binarySearch(addlBand13, uarfcn) >= 0) {
+            return UtranBand.BAND_13;
+        } else if ((uarfcn >= 4117 && uarfcn <= 4143)
+                || Arrays.binarySearch(addlBand14, uarfcn) >= 0) {
+            return UtranBand.BAND_14;
+        } else if ((uarfcn >= 712 && uarfcn <= 763)
+                || Arrays.binarySearch(addlBand19, uarfcn) >= 0) {
+            return UtranBand.BAND_19;
+        } else if (uarfcn >= 4512 && uarfcn <= 4638) {
+            return UtranBand.BAND_20;
+        } else if (uarfcn >= 862 && uarfcn <= 912) {
+            return UtranBand.BAND_21;
+        } else if (uarfcn >= 4662 && uarfcn <= 5038) {
+            return UtranBand.BAND_22;
+        } else if ((uarfcn >= 5112 && uarfcn <= 5413)
+                || Arrays.binarySearch(addlBand25, uarfcn) >= 0) {
+            return UtranBand.BAND_25;
+        } else if ((uarfcn >= 5762 && uarfcn <= 5913)
+                || Arrays.binarySearch(addlBand26, uarfcn) >= 0) {
+            return UtranBand.BAND_26;
+        }
+        return INVALID_BAND;
+    }
 }
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 26fd99d..7d3cef5 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -9275,6 +9275,35 @@
     }
 
     /**
+     * Get the mobile provisioning url that is used to launch a browser to allow users to manage
+     * their mobile plan.
+     *
+     * <p>Requires Permission:
+     * {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE}.
+     *
+     * TODO: The legacy design only supports single sim design. Ideally, this should support
+     * multi-sim design in current world.
+     *
+     * {@hide}
+     */
+    @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    public @Nullable String getMobileProvisioningUrl() {
+        try {
+            final ITelephony service = getITelephony();
+            if (service != null) {
+                return service.getMobileProvisioningUrl();
+            } else {
+                throw new IllegalStateException("telephony service is null.");
+            }
+        } catch (RemoteException ex) {
+            if (!isSystemProcess()) {
+                ex.rethrowAsRuntimeException();
+            }
+        }
+        return null;
+    }
+
+    /**
      * Turns mobile data on or off.
      * If this object has been created with {@link #createForSubscriptionId}, applies to the given
      * subId. Otherwise, applies to {@link SubscriptionManager#getDefaultDataSubscriptionId()}
@@ -9338,10 +9367,9 @@
      * @return true if mobile data is enabled.
      */
     @RequiresPermission(anyOf = {android.Manifest.permission.ACCESS_NETWORK_STATE,
-            android.Manifest.permission.MODIFY_PHONE_STATE,
-            android.Manifest.permission.READ_PHONE_STATE})
+            android.Manifest.permission.MODIFY_PHONE_STATE})
     public boolean isDataEnabled() {
-        return isDataEnabledForReason(DATA_ENABLED_REASON_USER);
+        return getDataEnabled(getSubId(SubscriptionManager.getDefaultDataSubscriptionId()));
     }
 
     /**
@@ -9586,7 +9614,7 @@
     @SystemApi
     public boolean getDataEnabled(int subId) {
         try {
-            return isDataEnabledForReason(subId, DATA_ENABLED_REASON_USER);
+            return isDataEnabledForReason(DATA_ENABLED_REASON_USER);
         } catch (RuntimeException e) {
             Log.e(TAG, "Error calling isDataEnabledForReason e:" + e);
         }
@@ -12301,23 +12329,15 @@
     @NonNull
     public Map<Integer, List<EmergencyNumber>> getEmergencyNumberList(
             @EmergencyServiceCategories int categories) {
-        Map<Integer, List<EmergencyNumber>> emergencyNumberList = new HashMap<>();
+        Map<Integer, List<EmergencyNumber>> emergencyNumberListForCategories = new HashMap<>();
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
-                emergencyNumberList = telephony.getEmergencyNumberList(
-                        mContext.getOpPackageName(), mContext.getAttributionTag());
-                if (emergencyNumberList != null) {
-                    for (Integer subscriptionId : emergencyNumberList.keySet()) {
-                        List<EmergencyNumber> numberList = emergencyNumberList.get(subscriptionId);
-                        for (EmergencyNumber number : numberList) {
-                            if (!number.isInEmergencyServiceCategories(categories)) {
-                                numberList.remove(number);
-                            }
-                        }
-                    }
-                }
-                return emergencyNumberList;
+                Map<Integer, List<EmergencyNumber>> emergencyNumberList =
+                        telephony.getEmergencyNumberList(mContext.getOpPackageName(),
+                                mContext.getAttributionTag());
+                emergencyNumberListForCategories =
+                        filterEmergencyNumbersByCategories(emergencyNumberList, categories);
             } else {
                 throw new IllegalStateException("telephony service is null.");
             }
@@ -12325,7 +12345,34 @@
             Log.e(TAG, "getEmergencyNumberList with Categories RemoteException", ex);
             ex.rethrowAsRuntimeException();
         }
-        return emergencyNumberList;
+        return emergencyNumberListForCategories;
+    }
+
+    /**
+     * Filter emergency numbers with categories.
+     *
+     * @hide
+     */
+    @VisibleForTesting
+    public Map<Integer, List<EmergencyNumber>> filterEmergencyNumbersByCategories(
+            Map<Integer, List<EmergencyNumber>> emergencyNumberList,
+                    @EmergencyServiceCategories int categories) {
+        Map<Integer, List<EmergencyNumber>> emergencyNumberListForCategories = new HashMap<>();
+        if (emergencyNumberList != null) {
+            for (Integer subscriptionId : emergencyNumberList.keySet()) {
+                List<EmergencyNumber> allNumbersForSub = emergencyNumberList.get(
+                        subscriptionId);
+                List<EmergencyNumber> numbersForCategoriesPerSub = new ArrayList<>();
+                for (EmergencyNumber number : allNumbersForSub) {
+                    if (number.isInEmergencyServiceCategories(categories)) {
+                        numbersForCategoriesPerSub.add(number);
+                    }
+                }
+                emergencyNumberListForCategories.put(
+                        subscriptionId, numbersForCategoriesPerSub);
+            }
+        }
+        return emergencyNumberListForCategories;
     }
 
     /**
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 7c5047c..33acc15 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -2352,4 +2352,10 @@
      * Gets the config of RCS VoLTE single registration enabled for the carrier/subscription.
      */
     boolean getCarrierSingleRegistrationEnabled(int subId);
+
+    /**
+     *  Return the mobile provisioning url that is used to launch a browser to allow users to manage
+     *  their mobile plan.
+     */
+    String getMobileProvisioningUrl();
 }
diff --git a/tests/net/common/java/android/net/NetworkProviderTest.kt b/tests/net/common/java/android/net/NetworkProviderTest.kt
index 77e9f12..bcc9072 100644
--- a/tests/net/common/java/android/net/NetworkProviderTest.kt
+++ b/tests/net/common/java/android/net/NetworkProviderTest.kt
@@ -29,6 +29,7 @@
 import com.android.net.module.util.ArrayTrackRecord
 import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
 import com.android.testutils.DevSdkIgnoreRunner
+import com.android.testutils.isDevSdkInRange
 import org.junit.After
 import org.junit.Before
 import org.junit.Test
@@ -173,10 +174,12 @@
     @Test
     fun testDeclareNetworkRequestUnfulfillable() {
         val mockContext = mock(Context::class.java)
-        val provider = createNetworkProvider(mockContext)
-        // ConnectivityManager not required at creation time
-        verifyNoMoreInteractions(mockContext)
         doReturn(mCm).`when`(mockContext).getSystemService(Context.CONNECTIVITY_SERVICE)
+        val provider = createNetworkProvider(mockContext)
+        // ConnectivityManager not required at creation time after R
+        if (!isDevSdkInRange(0, Build.VERSION_CODES.R)) {
+            verifyNoMoreInteractions(mockContext)
+        }
 
         mCm.registerNetworkProvider(provider)
 
diff --git a/tests/net/java/android/net/Ikev2VpnProfileTest.java b/tests/net/java/android/net/Ikev2VpnProfileTest.java
index ada5494..076e41d 100644
--- a/tests/net/java/android/net/Ikev2VpnProfileTest.java
+++ b/tests/net/java/android/net/Ikev2VpnProfileTest.java
@@ -29,6 +29,7 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.internal.net.VpnProfile;
+import com.android.net.module.util.ProxyUtils;
 import com.android.org.bouncycastle.x509.X509V1CertificateGenerator;
 
 import org.junit.Before;
@@ -67,7 +68,8 @@
                     return "fooPackage";
                 }
             };
-    private final ProxyInfo mProxy = new ProxyInfo(SERVER_ADDR_STRING, -1, EXCL_LIST);
+    private final ProxyInfo mProxy = ProxyInfo.buildDirectProxy(
+            SERVER_ADDR_STRING, -1, ProxyUtils.exclusionStringAsList(EXCL_LIST));
 
     private X509Certificate mUserCert;
     private X509Certificate mServerRootCa;
diff --git a/tests/net/java/android/net/NetworkUtilsTest.java b/tests/net/java/android/net/NetworkUtilsTest.java
index 3158cc8..7748288 100644
--- a/tests/net/java/android/net/NetworkUtilsTest.java
+++ b/tests/net/java/android/net/NetworkUtilsTest.java
@@ -16,24 +16,10 @@
 
 package android.net;
 
-import static android.system.OsConstants.AF_INET;
-import static android.system.OsConstants.AF_INET6;
-import static android.system.OsConstants.AF_UNIX;
-import static android.system.OsConstants.EPERM;
-import static android.system.OsConstants.SOCK_DGRAM;
-import static android.system.OsConstants.SOCK_STREAM;
-
 import static junit.framework.Assert.assertEquals;
 
-import static org.junit.Assert.fail;
-
-import android.system.ErrnoException;
-import android.system.Os;
-
 import androidx.test.runner.AndroidJUnit4;
 
-import libcore.io.IoUtils;
-
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -139,50 +125,4 @@
         assertEquals(BigInteger.valueOf(7l - 4 + 4 + 16 + 65536),
                 NetworkUtils.routedIPv6AddressCount(set));
     }
-
-    private static void expectSocketSuccess(String msg, int domain, int type) {
-        try {
-            IoUtils.closeQuietly(Os.socket(domain, type, 0));
-        } catch (ErrnoException e) {
-            fail(msg + e.getMessage());
-        }
-    }
-
-    private static void expectSocketPemissionError(String msg, int domain, int type) {
-        try {
-            IoUtils.closeQuietly(Os.socket(domain, type, 0));
-            fail(msg);
-        } catch (ErrnoException e) {
-            assertEquals(msg, e.errno, EPERM);
-        }
-    }
-
-    private static void expectHasNetworking() {
-        expectSocketSuccess("Creating a UNIX socket should not have thrown ErrnoException",
-                AF_UNIX, SOCK_STREAM);
-        expectSocketSuccess("Creating a AF_INET socket shouldn't have thrown ErrnoException",
-                AF_INET, SOCK_DGRAM);
-        expectSocketSuccess("Creating a AF_INET6 socket shouldn't have thrown ErrnoException",
-                AF_INET6, SOCK_DGRAM);
-    }
-
-    private static void expectNoNetworking() {
-        expectSocketSuccess("Creating a UNIX socket should not have thrown ErrnoException",
-                AF_UNIX, SOCK_STREAM);
-        expectSocketPemissionError(
-                "Creating a AF_INET socket should have thrown ErrnoException(EPERM)",
-                AF_INET, SOCK_DGRAM);
-        expectSocketPemissionError(
-                "Creating a AF_INET6 socket should have thrown ErrnoException(EPERM)",
-                AF_INET6, SOCK_DGRAM);
-    }
-
-    @Test
-    public void testSetAllowNetworkingForProcess() {
-        expectHasNetworking();
-        NetworkUtils.setAllowNetworkingForProcess(false);
-        expectNoNetworking();
-        NetworkUtils.setAllowNetworkingForProcess(true);
-        expectHasNetworking();
-    }
 }
diff --git a/tests/net/java/com/android/internal/net/NetworkUtilsInternalTest.java b/tests/net/java/com/android/internal/net/NetworkUtilsInternalTest.java
new file mode 100644
index 0000000..3cfecd5
--- /dev/null
+++ b/tests/net/java/com/android/internal/net/NetworkUtilsInternalTest.java
@@ -0,0 +1,89 @@
+/*
+ * 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 com.android.internal.net;
+
+import static android.system.OsConstants.AF_INET;
+import static android.system.OsConstants.AF_INET6;
+import static android.system.OsConstants.AF_UNIX;
+import static android.system.OsConstants.EPERM;
+import static android.system.OsConstants.SOCK_DGRAM;
+import static android.system.OsConstants.SOCK_STREAM;
+
+import static junit.framework.Assert.assertEquals;
+
+import static org.junit.Assert.fail;
+
+import android.system.ErrnoException;
+import android.system.Os;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import libcore.io.IoUtils;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@androidx.test.filters.SmallTest
+public class NetworkUtilsInternalTest {
+
+    private static void expectSocketSuccess(String msg, int domain, int type) {
+        try {
+            IoUtils.closeQuietly(Os.socket(domain, type, 0));
+        } catch (ErrnoException e) {
+            fail(msg + e.getMessage());
+        }
+    }
+
+    private static void expectSocketPemissionError(String msg, int domain, int type) {
+        try {
+            IoUtils.closeQuietly(Os.socket(domain, type, 0));
+            fail(msg);
+        } catch (ErrnoException e) {
+            assertEquals(msg, e.errno, EPERM);
+        }
+    }
+
+    private static void expectHasNetworking() {
+        expectSocketSuccess("Creating a UNIX socket should not have thrown ErrnoException",
+                AF_UNIX, SOCK_STREAM);
+        expectSocketSuccess("Creating a AF_INET socket shouldn't have thrown ErrnoException",
+                AF_INET, SOCK_DGRAM);
+        expectSocketSuccess("Creating a AF_INET6 socket shouldn't have thrown ErrnoException",
+                AF_INET6, SOCK_DGRAM);
+    }
+
+    private static void expectNoNetworking() {
+        expectSocketSuccess("Creating a UNIX socket should not have thrown ErrnoException",
+                AF_UNIX, SOCK_STREAM);
+        expectSocketPemissionError(
+                "Creating a AF_INET socket should have thrown ErrnoException(EPERM)",
+                AF_INET, SOCK_DGRAM);
+        expectSocketPemissionError(
+                "Creating a AF_INET6 socket should have thrown ErrnoException(EPERM)",
+                AF_INET6, SOCK_DGRAM);
+    }
+
+    @Test
+    public void testSetAllowNetworkingForProcess() {
+        expectHasNetworking();
+        NetworkUtilsInternal.setAllowNetworkingForProcess(false);
+        expectNoNetworking();
+        NetworkUtilsInternal.setAllowNetworkingForProcess(true);
+        expectHasNetworking();
+    }
+}
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index a68044a..a613e5e 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -4742,11 +4742,9 @@
 
     @Test
     public void testNetworkCallbackMaximum() {
-        // We can only have 99 callbacks, because MultipathPolicyTracker is
-        // already one of them.
-        final int MAX_REQUESTS = 99;
+        final int MAX_REQUESTS = 100;
         final int CALLBACKS = 89;
-        final int INTENTS = 10;
+        final int INTENTS = 11;
         assertEquals(MAX_REQUESTS, CALLBACKS + INTENTS);
 
         NetworkRequest networkRequest = new NetworkRequest.Builder().build();
diff --git a/tests/net/java/com/android/server/NetworkManagementServiceTest.java b/tests/net/java/com/android/server/NetworkManagementServiceTest.java
index ea763d2..13516d7 100644
--- a/tests/net/java/com/android/server/NetworkManagementServiceTest.java
+++ b/tests/net/java/com/android/server/NetworkManagementServiceTest.java
@@ -68,11 +68,12 @@
 @SmallTest
 public class NetworkManagementServiceTest {
     private NetworkManagementService mNMService;
-
     @Mock private Context mContext;
     @Mock private IBatteryStats.Stub mBatteryStatsService;
     @Mock private INetd.Stub mNetdService;
 
+    private static final int TEST_UID = 111;
+
     @NonNull
     @Captor
     private ArgumentCaptor<INetdUnsolicitedEventListener> mUnsolListenerCaptor;
@@ -165,14 +166,14 @@
         /**
          * Interface class activity.
          */
-        unsolListener.onInterfaceClassActivityChanged(true, 1, 1234, 0);
-        expectSoon(observer).interfaceClassDataActivityChanged("1", true, 1234);
+        unsolListener.onInterfaceClassActivityChanged(true, 1, 1234, TEST_UID);
+        expectSoon(observer).interfaceClassDataActivityChanged(1, true, 1234, TEST_UID);
 
-        unsolListener.onInterfaceClassActivityChanged(false, 9, 5678, 0);
-        expectSoon(observer).interfaceClassDataActivityChanged("9", false, 5678);
+        unsolListener.onInterfaceClassActivityChanged(false, 9, 5678, TEST_UID);
+        expectSoon(observer).interfaceClassDataActivityChanged(9, false, 5678, TEST_UID);
 
-        unsolListener.onInterfaceClassActivityChanged(false, 9, 4321, 0);
-        expectSoon(observer).interfaceClassDataActivityChanged("9", false, 4321);
+        unsolListener.onInterfaceClassActivityChanged(false, 9, 4321, TEST_UID);
+        expectSoon(observer).interfaceClassDataActivityChanged(9, false, 4321, TEST_UID);
 
         /**
          * IP address changes.
@@ -222,8 +223,6 @@
         assertFalse(mNMService.isFirewallEnabled());
     }
 
-    private static final int TEST_UID = 111;
-
     @Test
     public void testNetworkRestrictedDefault() {
         assertFalse(mNMService.isNetworkRestricted(TEST_UID));
@@ -235,23 +234,23 @@
         doReturn(true).when(mNetdService).bandwidthEnableDataSaver(anyBoolean());
 
         // Restrict usage of mobile data in background
-        mNMService.setUidMeteredNetworkDenylist(TEST_UID, true);
+        mNMService.setUidOnMeteredNetworkDenylist(TEST_UID, true);
         assertTrue("Should be true since mobile data usage is restricted",
                 mNMService.isNetworkRestricted(TEST_UID));
 
         mNMService.setDataSaverModeEnabled(true);
         verify(mNetdService).bandwidthEnableDataSaver(true);
 
-        mNMService.setUidMeteredNetworkDenylist(TEST_UID, false);
+        mNMService.setUidOnMeteredNetworkDenylist(TEST_UID, false);
         assertTrue("Should be true since data saver is on and the uid is not allowlisted",
                 mNMService.isNetworkRestricted(TEST_UID));
 
-        mNMService.setUidMeteredNetworkAllowlist(TEST_UID, true);
+        mNMService.setUidOnMeteredNetworkAllowlist(TEST_UID, true);
         assertFalse("Should be false since data saver is on and the uid is allowlisted",
                 mNMService.isNetworkRestricted(TEST_UID));
 
         // remove uid from allowlist and turn datasaver off again
-        mNMService.setUidMeteredNetworkAllowlist(TEST_UID, false);
+        mNMService.setUidOnMeteredNetworkAllowlist(TEST_UID, false);
         mNMService.setDataSaverModeEnabled(false);
         verify(mNetdService).bandwidthEnableDataSaver(false);
         assertFalse("Network should not be restricted when data saver is off",
diff --git a/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java b/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java
index fb0cfc0..89146f9 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java
@@ -23,11 +23,11 @@
 import static android.net.NetworkStats.UID_ALL;
 import static android.net.NetworkStatsHistory.FIELD_ALL;
 import static android.net.NetworkTemplate.buildTemplateMobileAll;
-import static android.net.NetworkUtils.multiplySafeByRational;
 import static android.os.Process.myUid;
 import static android.text.format.DateUtils.HOUR_IN_MILLIS;
 import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
 
+import static com.android.internal.net.NetworkUtilsInternal.multiplySafeByRational;
 import static com.android.testutils.MiscAsserts.assertThrows;
 
 import static org.junit.Assert.assertArrayEquals;
diff --git a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
index cd9406c..c783629 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -23,6 +23,7 @@
 import static android.net.ConnectivityManager.TYPE_WIFI;
 import static android.net.ConnectivityManager.TYPE_WIMAX;
 import static android.net.NetworkStats.DEFAULT_NETWORK_ALL;
+import static android.net.NetworkStats.DEFAULT_NETWORK_NO;
 import static android.net.NetworkStats.DEFAULT_NETWORK_YES;
 import static android.net.NetworkStats.IFACE_ALL;
 import static android.net.NetworkStats.INTERFACES_ALL;
@@ -917,7 +918,8 @@
     public void testMetered() throws Exception {
         // pretend that network comes online
         expectDefaultSettings();
-        NetworkState[] states = new NetworkState[] {buildWifiState(true /* isMetered */)};
+        NetworkState[] states =
+                new NetworkState[] {buildWifiState(true /* isMetered */, TEST_IFACE)};
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(buildEmptyStats());
 
@@ -1146,7 +1148,8 @@
     public void testStatsProviderUpdateStats() throws Exception {
         // Pretend that network comes online.
         expectDefaultSettings();
-        final NetworkState[] states = new NetworkState[]{buildWifiState(true /* isMetered */)};
+        final NetworkState[] states =
+                new NetworkState[]{buildWifiState(true /* isMetered */, TEST_IFACE)};
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(buildEmptyStats());
 
@@ -1206,7 +1209,8 @@
     public void testStatsProviderSetAlert() throws Exception {
         // Pretend that network comes online.
         expectDefaultSettings();
-        NetworkState[] states = new NetworkState[]{buildWifiState(true /* isMetered */)};
+        NetworkState[] states =
+                new NetworkState[]{buildWifiState(true /* isMetered */, TEST_IFACE)};
         mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]);
 
         // Register custom provider and retrieve callback.
@@ -1319,6 +1323,47 @@
         assertUidTotal(templateAll, UID_RED, 22L + 35L, 26L + 29L, 19L + 7L, 5L + 11L, 1);
     }
 
+    @Test
+    public void testOperationCount_nonDefault_traffic() throws Exception {
+        // Pretend mobile network comes online, but wifi is the default network.
+        expectDefaultSettings();
+        NetworkState[] states = new NetworkState[]{
+                buildWifiState(true /*isMetered*/, TEST_IFACE2), buildMobile3gState(IMSI_1)};
+        expectNetworkStatsUidDetail(buildEmptyStats());
+        mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]);
+
+        // Create some traffic on mobile network.
+        incrementCurrentTime(HOUR_IN_MILLIS);
+        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 4)
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                        DEFAULT_NETWORK_NO, 2L, 1L, 3L, 4L, 0L)
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                        DEFAULT_NETWORK_YES, 1L, 3L, 2L, 1L, 0L)
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 5L, 4L, 1L, 4L, 0L));
+        // Increment operation count, which must have a specific tag.
+        mService.incrementOperationCount(UID_RED, 0xF00D, 2);
+        forcePollAndWaitForIdle();
+
+        // Verify mobile summary is not changed by the operation count.
+        final NetworkTemplate templateMobile =
+                buildTemplateMobileWithRatType(null, NETWORK_TYPE_ALL);
+        final NetworkStats statsMobile = mSession.getSummaryForAllUid(
+                templateMobile, Long.MIN_VALUE, Long.MAX_VALUE, true);
+        assertValues(statsMobile, IFACE_ALL, UID_RED, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
+                DEFAULT_NETWORK_ALL, 3L, 4L, 5L, 5L, 0);
+        assertValues(statsMobile, IFACE_ALL, UID_RED, SET_ALL, 0xF00D, METERED_ALL, ROAMING_ALL,
+                DEFAULT_NETWORK_ALL, 5L, 4L, 1L, 4L, 0);
+
+        // Verify the operation count is blamed onto the default network.
+        // TODO: Blame onto the default network is not very reasonable. Consider blame onto the
+        //  network that generates the traffic.
+        final NetworkTemplate templateWifi = buildTemplateWifiWildcard();
+        final NetworkStats statsWifi = mSession.getSummaryForAllUid(
+                templateWifi, Long.MIN_VALUE, Long.MAX_VALUE, true);
+        assertValues(statsWifi, IFACE_ALL, UID_RED, SET_ALL, 0xF00D, METERED_ALL, ROAMING_ALL,
+                DEFAULT_NETWORK_ALL, 0L, 0L, 0L, 0L, 2);
+    }
+
     private static File getBaseDir(File statsDir) {
         File baseDir = new File(statsDir, "netstats");
         baseDir.mkdirs();
@@ -1446,14 +1491,14 @@
     }
 
     private static NetworkState buildWifiState() {
-        return buildWifiState(false);
+        return buildWifiState(false, TEST_IFACE);
     }
 
-    private static NetworkState buildWifiState(boolean isMetered) {
+    private static NetworkState buildWifiState(boolean isMetered, @NonNull String iface) {
         final NetworkInfo info = new NetworkInfo(TYPE_WIFI, 0, null, null);
         info.setDetailedState(DetailedState.CONNECTED, null, null);
         final LinkProperties prop = new LinkProperties();
-        prop.setInterfaceName(TEST_IFACE);
+        prop.setInterfaceName(iface);
         final NetworkCapabilities capabilities = new NetworkCapabilities();
         capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, !isMetered);
         capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, true);
diff --git a/wifi/Android.bp b/wifi/Android.bp
deleted file mode 100644
index e3aafd6..0000000
--- a/wifi/Android.bp
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-java_defaults {
-    name: "wifi-module-sdk-version-defaults",
-    min_sdk_version: "30",
-    target_sdk_version: "30",
-}
-
-filegroup {
-    name: "framework-wifi-updatable-exported-aidl-sources",
-    srcs: ["aidl-export/**/*.aidl"],
-    path: "aidl-export",
-    visibility: ["//visibility:private"],
-}
-
-filegroup {
-    name: "framework-wifi-updatable-java-sources",
-    srcs: [
-        "java/**/*.java",
-        "java/**/*.aidl",
-    ],
-    path: "java",
-    visibility: ["//visibility:private"],
-}
-
-filegroup {
-    name: "framework-wifi-updatable-sources",
-    srcs: [
-        ":framework-wifi-updatable-java-sources",
-        ":framework-wifi-updatable-exported-aidl-sources",
-    ],
-}
-
-filegroup {
-    name: "framework-wifi-annotations",
-    srcs: ["java/android/net/wifi/WifiAnnotations.java"],
-}
-
-// list of tests that are allowed to access @hide APIs from framework-wifi
-test_access_hidden_api_whitelist = [
-    "//frameworks/base/wifi/tests",
-    "//frameworks/base/wifi/non-updatable/tests",
-    "//frameworks/opt/net/wifi/tests/wifitests:__subpackages__",
-
-    "//external/robolectric-shadows:__subpackages__",
-    "//frameworks/base/packages/SettingsLib/tests/integ",
-    "//external/sl4a:__subpackages__",
-    "//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/TEST_MAPPING b/wifi/TEST_MAPPING
new file mode 100644
index 0000000..94e4f4d
--- /dev/null
+++ b/wifi/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+      "name": "FrameworksWifiNonUpdatableApiTests"
+    }
+  ]
+}
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 53c3b33..0000000
--- a/wifi/api/current.txt
+++ /dev/null
@@ -1,1199 +0,0 @@
-// Signature format: 2.0
-package android.net.wifi {
-
-  public abstract class EasyConnectStatusCallback {
-    field public static final int EASY_CONNECT_EVENT_FAILURE_AUTHENTICATION = -2; // 0xfffffffe
-    field public static final int EASY_CONNECT_EVENT_FAILURE_BUSY = -5; // 0xfffffffb
-    field public static final int EASY_CONNECT_EVENT_FAILURE_CANNOT_FIND_NETWORK = -10; // 0xfffffff6
-    field public static final int EASY_CONNECT_EVENT_FAILURE_CONFIGURATION = -4; // 0xfffffffc
-    field public static final int EASY_CONNECT_EVENT_FAILURE_ENROLLEE_AUTHENTICATION = -11; // 0xfffffff5
-    field public static final int EASY_CONNECT_EVENT_FAILURE_ENROLLEE_REJECTED_CONFIGURATION = -12; // 0xfffffff4
-    field public static final int EASY_CONNECT_EVENT_FAILURE_GENERIC = -7; // 0xfffffff9
-    field public static final int EASY_CONNECT_EVENT_FAILURE_INVALID_NETWORK = -9; // 0xfffffff7
-    field public static final int EASY_CONNECT_EVENT_FAILURE_INVALID_URI = -1; // 0xffffffff
-    field public static final int EASY_CONNECT_EVENT_FAILURE_NOT_COMPATIBLE = -3; // 0xfffffffd
-    field public static final int EASY_CONNECT_EVENT_FAILURE_NOT_SUPPORTED = -8; // 0xfffffff8
-    field public static final int EASY_CONNECT_EVENT_FAILURE_TIMEOUT = -6; // 0xfffffffa
-  }
-
-  public final class ScanResult implements android.os.Parcelable {
-    ctor public ScanResult(@NonNull android.net.wifi.ScanResult);
-    ctor public ScanResult();
-    method public int describeContents();
-    method @NonNull public java.util.List<android.net.wifi.ScanResult.InformationElement> getInformationElements();
-    method public int getWifiStandard();
-    method public boolean is80211mcResponder();
-    method public boolean isPasspointNetwork();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public String BSSID;
-    field public static final int CHANNEL_WIDTH_160MHZ = 3; // 0x3
-    field public static final int CHANNEL_WIDTH_20MHZ = 0; // 0x0
-    field public static final int CHANNEL_WIDTH_40MHZ = 1; // 0x1
-    field public static final int CHANNEL_WIDTH_80MHZ = 2; // 0x2
-    field public static final int CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 4; // 0x4
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.ScanResult> CREATOR;
-    field public String SSID;
-    field public static final int WIFI_STANDARD_11AC = 5; // 0x5
-    field public static final int WIFI_STANDARD_11AX = 6; // 0x6
-    field public static final int WIFI_STANDARD_11N = 4; // 0x4
-    field public static final int WIFI_STANDARD_LEGACY = 1; // 0x1
-    field public static final int WIFI_STANDARD_UNKNOWN = 0; // 0x0
-    field public String capabilities;
-    field public int centerFreq0;
-    field public int centerFreq1;
-    field public int channelWidth;
-    field public int frequency;
-    field public int level;
-    field public CharSequence operatorFriendlyName;
-    field public long timestamp;
-    field public CharSequence venueName;
-  }
-
-  public static class ScanResult.InformationElement {
-    ctor public ScanResult.InformationElement(@NonNull android.net.wifi.ScanResult.InformationElement);
-    method @NonNull public java.nio.ByteBuffer getBytes();
-    method public int getId();
-    method public int getIdExt();
-  }
-
-  public final class SoftApConfiguration implements android.os.Parcelable {
-    method public int describeContents();
-    method @Nullable public android.net.MacAddress getBssid();
-    method @Nullable public String getPassphrase();
-    method public int getSecurityType();
-    method @Nullable public String getSsid();
-    method public boolean isHiddenSsid();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.SoftApConfiguration> CREATOR;
-    field public static final int SECURITY_TYPE_OPEN = 0; // 0x0
-    field public static final int SECURITY_TYPE_WPA2_PSK = 1; // 0x1
-    field public static final int SECURITY_TYPE_WPA3_SAE = 3; // 0x3
-    field public static final int SECURITY_TYPE_WPA3_SAE_TRANSITION = 2; // 0x2
-  }
-
-  public enum SupplicantState implements android.os.Parcelable {
-    method public int describeContents();
-    method public static boolean isValidState(android.net.wifi.SupplicantState);
-    method public void writeToParcel(android.os.Parcel, int);
-    enum_constant public static final android.net.wifi.SupplicantState ASSOCIATED;
-    enum_constant public static final android.net.wifi.SupplicantState ASSOCIATING;
-    enum_constant public static final android.net.wifi.SupplicantState AUTHENTICATING;
-    enum_constant public static final android.net.wifi.SupplicantState COMPLETED;
-    enum_constant public static final android.net.wifi.SupplicantState DISCONNECTED;
-    enum_constant public static final android.net.wifi.SupplicantState DORMANT;
-    enum_constant public static final android.net.wifi.SupplicantState FOUR_WAY_HANDSHAKE;
-    enum_constant public static final android.net.wifi.SupplicantState GROUP_HANDSHAKE;
-    enum_constant public static final android.net.wifi.SupplicantState INACTIVE;
-    enum_constant public static final android.net.wifi.SupplicantState INTERFACE_DISABLED;
-    enum_constant public static final android.net.wifi.SupplicantState INVALID;
-    enum_constant public static final android.net.wifi.SupplicantState SCANNING;
-    enum_constant public static final android.net.wifi.SupplicantState UNINITIALIZED;
-  }
-
-  @Deprecated public class WifiConfiguration implements android.os.Parcelable {
-    ctor @Deprecated public WifiConfiguration();
-    ctor @Deprecated public WifiConfiguration(@NonNull android.net.wifi.WifiConfiguration);
-    method public int describeContents();
-    method @Deprecated public android.net.ProxyInfo getHttpProxy();
-    method @Deprecated @NonNull public String getKey();
-    method @Deprecated @NonNull public android.net.MacAddress getRandomizedMacAddress();
-    method @Deprecated public boolean isPasspoint();
-    method @Deprecated public void setHttpProxy(android.net.ProxyInfo);
-    method @Deprecated public void setSecurityParams(int);
-    method public void writeToParcel(android.os.Parcel, int);
-    field @Deprecated public String BSSID;
-    field @Deprecated public String FQDN;
-    field @Deprecated public static final int SECURITY_TYPE_EAP = 3; // 0x3
-    field @Deprecated public static final int SECURITY_TYPE_EAP_SUITE_B = 5; // 0x5
-    field @Deprecated public static final int SECURITY_TYPE_OPEN = 0; // 0x0
-    field @Deprecated public static final int SECURITY_TYPE_OWE = 6; // 0x6
-    field @Deprecated public static final int SECURITY_TYPE_PSK = 2; // 0x2
-    field @Deprecated public static final int SECURITY_TYPE_SAE = 4; // 0x4
-    field @Deprecated public static final int SECURITY_TYPE_WAPI_CERT = 8; // 0x8
-    field @Deprecated public static final int SECURITY_TYPE_WAPI_PSK = 7; // 0x7
-    field @Deprecated public static final int SECURITY_TYPE_WEP = 1; // 0x1
-    field @Deprecated public String SSID;
-    field @Deprecated @NonNull public java.util.BitSet allowedAuthAlgorithms;
-    field @Deprecated @NonNull public java.util.BitSet allowedGroupCiphers;
-    field @Deprecated @NonNull public java.util.BitSet allowedGroupManagementCiphers;
-    field @Deprecated @NonNull public java.util.BitSet allowedKeyManagement;
-    field @Deprecated @NonNull public java.util.BitSet allowedPairwiseCiphers;
-    field @Deprecated @NonNull public java.util.BitSet allowedProtocols;
-    field @Deprecated @NonNull public java.util.BitSet allowedSuiteBCiphers;
-    field @Deprecated public android.net.wifi.WifiEnterpriseConfig enterpriseConfig;
-    field @Deprecated public boolean hiddenSSID;
-    field @Deprecated public boolean isHomeProviderNetwork;
-    field @Deprecated public int networkId;
-    field @Deprecated public String preSharedKey;
-    field @Deprecated public int priority;
-    field @Deprecated public String providerFriendlyName;
-    field @Deprecated public long[] roamingConsortiumIds;
-    field @Deprecated public int status;
-    field @Deprecated public String[] wepKeys;
-    field @Deprecated public int wepTxKeyIndex;
-  }
-
-  @Deprecated public static class WifiConfiguration.AuthAlgorithm {
-    field @Deprecated public static final int LEAP = 2; // 0x2
-    field @Deprecated public static final int OPEN = 0; // 0x0
-    field @Deprecated public static final int SAE = 3; // 0x3
-    field @Deprecated public static final int SHARED = 1; // 0x1
-    field @Deprecated public static final String[] strings;
-    field @Deprecated public static final String varName = "auth_alg";
-  }
-
-  @Deprecated public static class WifiConfiguration.GroupCipher {
-    field @Deprecated public static final int CCMP = 3; // 0x3
-    field @Deprecated public static final int GCMP_256 = 5; // 0x5
-    field @Deprecated public static final int SMS4 = 6; // 0x6
-    field @Deprecated public static final int TKIP = 2; // 0x2
-    field @Deprecated public static final int WEP104 = 1; // 0x1
-    field @Deprecated public static final int WEP40 = 0; // 0x0
-    field @Deprecated public static final String[] strings;
-    field @Deprecated public static final String varName = "group";
-  }
-
-  @Deprecated public static class WifiConfiguration.GroupMgmtCipher {
-    field @Deprecated public static final int BIP_CMAC_256 = 0; // 0x0
-    field @Deprecated public static final int BIP_GMAC_128 = 1; // 0x1
-    field @Deprecated public static final int BIP_GMAC_256 = 2; // 0x2
-  }
-
-  @Deprecated public static class WifiConfiguration.KeyMgmt {
-    field @Deprecated public static final int IEEE8021X = 3; // 0x3
-    field @Deprecated public static final int NONE = 0; // 0x0
-    field @Deprecated public static final int OWE = 9; // 0x9
-    field @Deprecated public static final int SAE = 8; // 0x8
-    field @Deprecated public static final int SUITE_B_192 = 10; // 0xa
-    field @Deprecated public static final int WPA_EAP = 2; // 0x2
-    field @Deprecated public static final int WPA_PSK = 1; // 0x1
-    field @Deprecated public static final String[] strings;
-    field @Deprecated public static final String varName = "key_mgmt";
-  }
-
-  @Deprecated public static class WifiConfiguration.PairwiseCipher {
-    field @Deprecated public static final int CCMP = 2; // 0x2
-    field @Deprecated public static final int GCMP_256 = 3; // 0x3
-    field @Deprecated public static final int NONE = 0; // 0x0
-    field @Deprecated public static final int SMS4 = 4; // 0x4
-    field @Deprecated public static final int TKIP = 1; // 0x1
-    field @Deprecated public static final String[] strings;
-    field @Deprecated public static final String varName = "pairwise";
-  }
-
-  @Deprecated public static class WifiConfiguration.Protocol {
-    field @Deprecated public static final int RSN = 1; // 0x1
-    field @Deprecated public static final int WAPI = 3; // 0x3
-    field @Deprecated public static final int WPA = 0; // 0x0
-    field @Deprecated public static final String[] strings;
-    field @Deprecated public static final String varName = "proto";
-  }
-
-  @Deprecated public static class WifiConfiguration.Status {
-    field @Deprecated public static final int CURRENT = 0; // 0x0
-    field @Deprecated public static final int DISABLED = 1; // 0x1
-    field @Deprecated public static final int ENABLED = 2; // 0x2
-    field @Deprecated public static final String[] strings;
-  }
-
-  public class WifiEnterpriseConfig implements android.os.Parcelable {
-    ctor public WifiEnterpriseConfig();
-    ctor public WifiEnterpriseConfig(android.net.wifi.WifiEnterpriseConfig);
-    method public int describeContents();
-    method public String getAltSubjectMatch();
-    method public String getAnonymousIdentity();
-    method @Nullable public java.security.cert.X509Certificate getCaCertificate();
-    method @Nullable public java.security.cert.X509Certificate[] getCaCertificates();
-    method public java.security.cert.X509Certificate getClientCertificate();
-    method @Nullable public java.security.cert.X509Certificate[] getClientCertificateChain();
-    method @Nullable public java.security.PrivateKey getClientPrivateKey();
-    method public String getDomainSuffixMatch();
-    method public int getEapMethod();
-    method public String getIdentity();
-    method public String getPassword();
-    method public int getPhase2Method();
-    method public String getPlmn();
-    method public String getRealm();
-    method @Deprecated public String getSubjectMatch();
-    method public boolean isAuthenticationSimBased();
-    method public void setAltSubjectMatch(String);
-    method public void setAnonymousIdentity(String);
-    method public void setCaCertificate(@Nullable java.security.cert.X509Certificate);
-    method public void setCaCertificates(@Nullable java.security.cert.X509Certificate[]);
-    method public void setClientKeyEntry(java.security.PrivateKey, java.security.cert.X509Certificate);
-    method public void setClientKeyEntryWithCertificateChain(java.security.PrivateKey, java.security.cert.X509Certificate[]);
-    method public void setDomainSuffixMatch(String);
-    method public void setEapMethod(int);
-    method public void setIdentity(String);
-    method public void setPassword(String);
-    method public void setPhase2Method(int);
-    method public void setPlmn(String);
-    method public void setRealm(String);
-    method @Deprecated public void setSubjectMatch(String);
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.WifiEnterpriseConfig> CREATOR;
-    field public static final String EXTRA_WAPI_AS_CERTIFICATE_DATA = "android.net.wifi.extra.WAPI_AS_CERTIFICATE_DATA";
-    field public static final String EXTRA_WAPI_AS_CERTIFICATE_NAME = "android.net.wifi.extra.WAPI_AS_CERTIFICATE_NAME";
-    field public static final String EXTRA_WAPI_USER_CERTIFICATE_DATA = "android.net.wifi.extra.WAPI_USER_CERTIFICATE_DATA";
-    field public static final String EXTRA_WAPI_USER_CERTIFICATE_NAME = "android.net.wifi.extra.WAPI_USER_CERTIFICATE_NAME";
-    field public static final String WAPI_AS_CERTIFICATE = "WAPIAS_";
-    field public static final String WAPI_USER_CERTIFICATE = "WAPIUSR_";
-  }
-
-  public static final class WifiEnterpriseConfig.Eap {
-    field public static final int AKA = 5; // 0x5
-    field public static final int AKA_PRIME = 6; // 0x6
-    field public static final int NONE = -1; // 0xffffffff
-    field public static final int PEAP = 0; // 0x0
-    field public static final int PWD = 3; // 0x3
-    field public static final int SIM = 4; // 0x4
-    field public static final int TLS = 1; // 0x1
-    field public static final int TTLS = 2; // 0x2
-    field public static final int UNAUTH_TLS = 7; // 0x7
-    field public static final int WAPI_CERT = 8; // 0x8
-  }
-
-  public static final class WifiEnterpriseConfig.Phase2 {
-    field public static final int AKA = 6; // 0x6
-    field public static final int AKA_PRIME = 7; // 0x7
-    field public static final int GTC = 4; // 0x4
-    field public static final int MSCHAP = 2; // 0x2
-    field public static final int MSCHAPV2 = 3; // 0x3
-    field public static final int NONE = 0; // 0x0
-    field public static final int PAP = 1; // 0x1
-    field public static final int SIM = 5; // 0x5
-  }
-
-  public class WifiInfo implements android.os.Parcelable {
-    method public int describeContents();
-    method public String getBSSID();
-    method public static android.net.NetworkInfo.DetailedState getDetailedStateOf(android.net.wifi.SupplicantState);
-    method public int getFrequency();
-    method public boolean getHiddenSSID();
-    method public int getIpAddress();
-    method public int getLinkSpeed();
-    method public String getMacAddress();
-    method public int getMaxSupportedRxLinkSpeedMbps();
-    method public int getMaxSupportedTxLinkSpeedMbps();
-    method public int getNetworkId();
-    method @Nullable public String getPasspointFqdn();
-    method @Nullable public String getPasspointProviderFriendlyName();
-    method public int getRssi();
-    method @IntRange(from=0xffffffff) public int getRxLinkSpeedMbps();
-    method public String getSSID();
-    method public android.net.wifi.SupplicantState getSupplicantState();
-    method @IntRange(from=0xffffffff) public int getTxLinkSpeedMbps();
-    method public int getWifiStandard();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final String FREQUENCY_UNITS = "MHz";
-    field public static final String LINK_SPEED_UNITS = "Mbps";
-    field public static final int LINK_SPEED_UNKNOWN = -1; // 0xffffffff
-  }
-
-  public static final class WifiInfo.Builder {
-    ctor public WifiInfo.Builder();
-    method @NonNull public android.net.wifi.WifiInfo build();
-    method @NonNull public android.net.wifi.WifiInfo.Builder setBssid(@NonNull String);
-    method @NonNull public android.net.wifi.WifiInfo.Builder setNetworkId(int);
-    method @NonNull public android.net.wifi.WifiInfo.Builder setRssi(int);
-    method @NonNull public android.net.wifi.WifiInfo.Builder setSsid(@NonNull byte[]);
-  }
-
-  public class WifiManager {
-    method @Deprecated public int addNetwork(android.net.wifi.WifiConfiguration);
-    method @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE) public int addNetworkSuggestions(@NonNull java.util.List<android.net.wifi.WifiNetworkSuggestion>);
-    method public void addOrUpdatePasspointConfiguration(android.net.wifi.hotspot2.PasspointConfiguration);
-    method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_WIFI_STATE}) public void addSuggestionConnectionStatusListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.SuggestionConnectionStatusListener);
-    method @Deprecated public static int calculateSignalLevel(int, int);
-    method @IntRange(from=0) public int calculateSignalLevel(int);
-    method @Deprecated public void cancelWps(android.net.wifi.WifiManager.WpsCallback);
-    method public static int compareSignalLevel(int, int);
-    method public android.net.wifi.WifiManager.MulticastLock createMulticastLock(String);
-    method public android.net.wifi.WifiManager.WifiLock createWifiLock(int, String);
-    method @Deprecated public android.net.wifi.WifiManager.WifiLock createWifiLock(String);
-    method @Deprecated public boolean disableNetwork(int);
-    method @Deprecated public boolean disconnect();
-    method @Deprecated public boolean enableNetwork(int, boolean);
-    method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_WIFI_STATE}) public java.util.List<android.net.wifi.WifiConfiguration> getConfiguredNetworks();
-    method public android.net.wifi.WifiInfo getConnectionInfo();
-    method public android.net.DhcpInfo getDhcpInfo();
-    method public int getMaxNumberOfNetworkSuggestionsPerApp();
-    method @IntRange(from=0) public int getMaxSignalLevel();
-    method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public java.util.List<android.net.wifi.WifiNetworkSuggestion> getNetworkSuggestions();
-    method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.List<android.net.wifi.hotspot2.PasspointConfiguration> getPasspointConfigurations();
-    method public java.util.List<android.net.wifi.ScanResult> getScanResults();
-    method public int getWifiState();
-    method public boolean is5GHzBandSupported();
-    method public boolean is6GHzBandSupported();
-    method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public boolean isAutoWakeupEnabled();
-    method @Deprecated public boolean isDeviceToApRttSupported();
-    method public boolean isEasyConnectSupported();
-    method public boolean isEnhancedOpenSupported();
-    method public boolean isEnhancedPowerReportingSupported();
-    method public boolean isP2pSupported();
-    method public boolean isPreferredNetworkOffloadSupported();
-    method @Deprecated public boolean isScanAlwaysAvailable();
-    method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public boolean isScanThrottleEnabled();
-    method public boolean isStaApConcurrencySupported();
-    method public boolean isTdlsSupported();
-    method public boolean isWapiSupported();
-    method public boolean isWifiEnabled();
-    method public boolean isWifiStandardSupported(int);
-    method public boolean isWpa3SaeSupported();
-    method public boolean isWpa3SuiteBSupported();
-    method @Deprecated public boolean pingSupplicant();
-    method @Deprecated public boolean reassociate();
-    method @Deprecated public boolean reconnect();
-    method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public void registerScanResultsCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.ScanResultsCallback);
-    method @Deprecated public boolean removeNetwork(int);
-    method @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE) public int removeNetworkSuggestions(@NonNull java.util.List<android.net.wifi.WifiNetworkSuggestion>);
-    method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_CARRIER_PROVISIONING}) public void removePasspointConfiguration(String);
-    method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public void removeSuggestionConnectionStatusListener(@NonNull android.net.wifi.WifiManager.SuggestionConnectionStatusListener);
-    method @Deprecated public boolean saveConfiguration();
-    method public void setTdlsEnabled(java.net.InetAddress, boolean);
-    method public void setTdlsEnabledWithMacAddress(String, boolean);
-    method @Deprecated public boolean setWifiEnabled(boolean);
-    method @RequiresPermission(allOf={android.Manifest.permission.CHANGE_WIFI_STATE, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void startLocalOnlyHotspot(android.net.wifi.WifiManager.LocalOnlyHotspotCallback, @Nullable android.os.Handler);
-    method @Deprecated public boolean startScan();
-    method @Deprecated public void startWps(android.net.wifi.WpsInfo, android.net.wifi.WifiManager.WpsCallback);
-    method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public void unregisterScanResultsCallback(@NonNull android.net.wifi.WifiManager.ScanResultsCallback);
-    method @Deprecated public int updateNetwork(android.net.wifi.WifiConfiguration);
-    field public static final String ACTION_PICK_WIFI_NETWORK = "android.net.wifi.PICK_WIFI_NETWORK";
-    field public static final String ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE = "android.net.wifi.action.REQUEST_SCAN_ALWAYS_AVAILABLE";
-    field public static final String ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION = "android.net.wifi.action.WIFI_NETWORK_SUGGESTION_POST_CONNECTION";
-    field public static final String ACTION_WIFI_SCAN_AVAILABILITY_CHANGED = "android.net.wifi.action.WIFI_SCAN_AVAILABILITY_CHANGED";
-    field @Deprecated public static final int ERROR_AUTHENTICATING = 1; // 0x1
-    field @Deprecated public static final String EXTRA_BSSID = "bssid";
-    field public static final String EXTRA_NETWORK_INFO = "networkInfo";
-    field public static final String EXTRA_NETWORK_SUGGESTION = "android.net.wifi.extra.NETWORK_SUGGESTION";
-    field public static final String EXTRA_NEW_RSSI = "newRssi";
-    field @Deprecated public static final String EXTRA_NEW_STATE = "newState";
-    field public static final String EXTRA_PREVIOUS_WIFI_STATE = "previous_wifi_state";
-    field public static final String EXTRA_RESULTS_UPDATED = "resultsUpdated";
-    field public static final String EXTRA_SCAN_AVAILABLE = "android.net.wifi.extra.SCAN_AVAILABLE";
-    field @Deprecated public static final String EXTRA_SUPPLICANT_CONNECTED = "connected";
-    field @Deprecated public static final String EXTRA_SUPPLICANT_ERROR = "supplicantError";
-    field @Deprecated public static final String EXTRA_WIFI_INFO = "wifiInfo";
-    field public static final String EXTRA_WIFI_STATE = "wifi_state";
-    field public static final String NETWORK_IDS_CHANGED_ACTION = "android.net.wifi.NETWORK_IDS_CHANGED";
-    field public static final String NETWORK_STATE_CHANGED_ACTION = "android.net.wifi.STATE_CHANGE";
-    field public static final String RSSI_CHANGED_ACTION = "android.net.wifi.RSSI_CHANGED";
-    field public static final String SCAN_RESULTS_AVAILABLE_ACTION = "android.net.wifi.SCAN_RESULTS";
-    field public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_DUPLICATE = 3; // 0x3
-    field public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_EXCEEDS_MAX_PER_APP = 4; // 0x4
-    field public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_INVALID = 7; // 0x7
-    field public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_NOT_ALLOWED = 6; // 0x6
-    field public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_APP_DISALLOWED = 2; // 0x2
-    field public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_INTERNAL = 1; // 0x1
-    field public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_REMOVE_INVALID = 5; // 0x5
-    field public static final int STATUS_NETWORK_SUGGESTIONS_SUCCESS = 0; // 0x0
-    field public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_ASSOCIATION = 1; // 0x1
-    field public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION = 2; // 0x2
-    field public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_IP_PROVISIONING = 3; // 0x3
-    field public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_UNKNOWN = 0; // 0x0
-    field @Deprecated public static final String SUPPLICANT_CONNECTION_CHANGE_ACTION = "android.net.wifi.supplicant.CONNECTION_CHANGE";
-    field @Deprecated public static final String SUPPLICANT_STATE_CHANGED_ACTION = "android.net.wifi.supplicant.STATE_CHANGE";
-    field public static final String UNKNOWN_SSID = "<unknown ssid>";
-    field @Deprecated public static final int WIFI_MODE_FULL = 1; // 0x1
-    field public static final int WIFI_MODE_FULL_HIGH_PERF = 3; // 0x3
-    field public static final int WIFI_MODE_FULL_LOW_LATENCY = 4; // 0x4
-    field @Deprecated public static final int WIFI_MODE_SCAN_ONLY = 2; // 0x2
-    field public static final String WIFI_STATE_CHANGED_ACTION = "android.net.wifi.WIFI_STATE_CHANGED";
-    field public static final int WIFI_STATE_DISABLED = 1; // 0x1
-    field public static final int WIFI_STATE_DISABLING = 0; // 0x0
-    field public static final int WIFI_STATE_ENABLED = 3; // 0x3
-    field public static final int WIFI_STATE_ENABLING = 2; // 0x2
-    field public static final int WIFI_STATE_UNKNOWN = 4; // 0x4
-    field @Deprecated public static final int WPS_AUTH_FAILURE = 6; // 0x6
-    field @Deprecated public static final int WPS_OVERLAP_ERROR = 3; // 0x3
-    field @Deprecated public static final int WPS_TIMED_OUT = 7; // 0x7
-    field @Deprecated public static final int WPS_TKIP_ONLY_PROHIBITED = 5; // 0x5
-    field @Deprecated public static final int WPS_WEP_PROHIBITED = 4; // 0x4
-  }
-
-  public static class WifiManager.LocalOnlyHotspotCallback {
-    ctor public WifiManager.LocalOnlyHotspotCallback();
-    method public void onFailed(int);
-    method public void onStarted(android.net.wifi.WifiManager.LocalOnlyHotspotReservation);
-    method public void onStopped();
-    field public static final int ERROR_GENERIC = 2; // 0x2
-    field public static final int ERROR_INCOMPATIBLE_MODE = 3; // 0x3
-    field public static final int ERROR_NO_CHANNEL = 1; // 0x1
-    field public static final int ERROR_TETHERING_DISALLOWED = 4; // 0x4
-  }
-
-  public class WifiManager.LocalOnlyHotspotReservation implements java.lang.AutoCloseable {
-    method public void close();
-    method @NonNull public android.net.wifi.SoftApConfiguration getSoftApConfiguration();
-    method @Deprecated @Nullable public android.net.wifi.WifiConfiguration getWifiConfiguration();
-  }
-
-  public class WifiManager.MulticastLock {
-    method public void acquire();
-    method public boolean isHeld();
-    method public void release();
-    method public void setReferenceCounted(boolean);
-  }
-
-  public abstract static class WifiManager.ScanResultsCallback {
-    ctor public WifiManager.ScanResultsCallback();
-    method public abstract void onScanResultsAvailable();
-  }
-
-  public static interface WifiManager.SuggestionConnectionStatusListener {
-    method public void onConnectionStatus(@NonNull android.net.wifi.WifiNetworkSuggestion, int);
-  }
-
-  public class WifiManager.WifiLock {
-    method public void acquire();
-    method public boolean isHeld();
-    method public void release();
-    method public void setReferenceCounted(boolean);
-    method public void setWorkSource(android.os.WorkSource);
-  }
-
-  @Deprecated public abstract static class WifiManager.WpsCallback {
-    ctor @Deprecated public WifiManager.WpsCallback();
-    method @Deprecated public abstract void onFailed(int);
-    method @Deprecated public abstract void onStarted(String);
-    method @Deprecated public abstract void onSucceeded();
-  }
-
-  public final class WifiNetworkSpecifier extends android.net.NetworkSpecifier implements android.os.Parcelable {
-    method public int describeContents();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.WifiNetworkSpecifier> CREATOR;
-  }
-
-  public static final class WifiNetworkSpecifier.Builder {
-    ctor public WifiNetworkSpecifier.Builder();
-    method @NonNull public android.net.wifi.WifiNetworkSpecifier build();
-    method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setBssid(@NonNull android.net.MacAddress);
-    method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setBssidPattern(@NonNull android.net.MacAddress, @NonNull android.net.MacAddress);
-    method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setIsEnhancedOpen(boolean);
-    method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setIsHiddenSsid(boolean);
-    method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setSsid(@NonNull String);
-    method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setSsidPattern(@NonNull android.os.PatternMatcher);
-    method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setWpa2EnterpriseConfig(@NonNull android.net.wifi.WifiEnterpriseConfig);
-    method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setWpa2Passphrase(@NonNull String);
-    method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setWpa3EnterpriseConfig(@NonNull android.net.wifi.WifiEnterpriseConfig);
-    method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setWpa3Passphrase(@NonNull String);
-  }
-
-  public final class WifiNetworkSuggestion implements android.os.Parcelable {
-    method public int describeContents();
-    method @Nullable public android.net.MacAddress getBssid();
-    method @Nullable public android.net.wifi.WifiEnterpriseConfig getEnterpriseConfig();
-    method @Nullable public String getPassphrase();
-    method @Nullable public android.net.wifi.hotspot2.PasspointConfiguration getPasspointConfig();
-    method @IntRange(from=0) public int getPriority();
-    method @Nullable public String getSsid();
-    method public boolean isAppInteractionRequired();
-    method public boolean isCredentialSharedWithUser();
-    method public boolean isEnhancedOpen();
-    method public boolean isHiddenSsid();
-    method public boolean isInitialAutojoinEnabled();
-    method public boolean isMetered();
-    method public boolean isUntrusted();
-    method public boolean isUserInteractionRequired();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.WifiNetworkSuggestion> CREATOR;
-  }
-
-  public static final class WifiNetworkSuggestion.Builder {
-    ctor public WifiNetworkSuggestion.Builder();
-    method @NonNull public android.net.wifi.WifiNetworkSuggestion build();
-    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setBssid(@NonNull android.net.MacAddress);
-    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setCredentialSharedWithUser(boolean);
-    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setIsAppInteractionRequired(boolean);
-    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setIsEnhancedOpen(boolean);
-    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setIsHiddenSsid(boolean);
-    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setIsInitialAutojoinEnabled(boolean);
-    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setIsMetered(boolean);
-    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setIsUserInteractionRequired(boolean);
-    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setPasspointConfig(@NonNull android.net.wifi.hotspot2.PasspointConfiguration);
-    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setPriority(@IntRange(from=0) int);
-    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setSsid(@NonNull String);
-    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setUntrusted(boolean);
-    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setWapiEnterpriseConfig(@NonNull android.net.wifi.WifiEnterpriseConfig);
-    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setWapiPassphrase(@NonNull String);
-    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setWpa2EnterpriseConfig(@NonNull android.net.wifi.WifiEnterpriseConfig);
-    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setWpa2Passphrase(@NonNull String);
-    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setWpa3EnterpriseConfig(@NonNull android.net.wifi.WifiEnterpriseConfig);
-    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setWpa3Passphrase(@NonNull String);
-  }
-
-  public class WpsInfo implements android.os.Parcelable {
-    ctor public WpsInfo();
-    ctor public WpsInfo(android.net.wifi.WpsInfo);
-    method public int describeContents();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public String BSSID;
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.WpsInfo> CREATOR;
-    field public static final int DISPLAY = 1; // 0x1
-    field public static final int INVALID = 4; // 0x4
-    field public static final int KEYPAD = 2; // 0x2
-    field public static final int LABEL = 3; // 0x3
-    field public static final int PBC = 0; // 0x0
-    field public String pin;
-    field public int setup;
-  }
-
-}
-
-package android.net.wifi.aware {
-
-  public class AttachCallback {
-    ctor public AttachCallback();
-    method public void onAttachFailed();
-    method public void onAttached(android.net.wifi.aware.WifiAwareSession);
-  }
-
-  public final class Characteristics implements android.os.Parcelable {
-    method public int describeContents();
-    method public int getMaxMatchFilterLength();
-    method public int getMaxServiceNameLength();
-    method public int getMaxServiceSpecificInfoLength();
-    method public int getSupportedCipherSuites();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.aware.Characteristics> CREATOR;
-    field public static final int WIFI_AWARE_CIPHER_SUITE_NCS_SK_128 = 1; // 0x1
-    field public static final int WIFI_AWARE_CIPHER_SUITE_NCS_SK_256 = 2; // 0x2
-  }
-
-  public class DiscoverySession implements java.lang.AutoCloseable {
-    method public void close();
-    method @Deprecated public android.net.NetworkSpecifier createNetworkSpecifierOpen(@NonNull android.net.wifi.aware.PeerHandle);
-    method @Deprecated public android.net.NetworkSpecifier createNetworkSpecifierPassphrase(@NonNull android.net.wifi.aware.PeerHandle, @NonNull String);
-    method public void sendMessage(@NonNull android.net.wifi.aware.PeerHandle, int, @Nullable byte[]);
-  }
-
-  public class DiscoverySessionCallback {
-    ctor public DiscoverySessionCallback();
-    method public void onMessageReceived(android.net.wifi.aware.PeerHandle, byte[]);
-    method public void onMessageSendFailed(int);
-    method public void onMessageSendSucceeded(int);
-    method public void onPublishStarted(@NonNull android.net.wifi.aware.PublishDiscoverySession);
-    method public void onServiceDiscovered(android.net.wifi.aware.PeerHandle, byte[], java.util.List<byte[]>);
-    method public void onServiceDiscoveredWithinRange(android.net.wifi.aware.PeerHandle, byte[], java.util.List<byte[]>, int);
-    method public void onSessionConfigFailed();
-    method public void onSessionConfigUpdated();
-    method public void onSessionTerminated();
-    method public void onSubscribeStarted(@NonNull android.net.wifi.aware.SubscribeDiscoverySession);
-  }
-
-  public class IdentityChangedListener {
-    ctor public IdentityChangedListener();
-    method public void onIdentityChanged(byte[]);
-  }
-
-  public final class ParcelablePeerHandle extends android.net.wifi.aware.PeerHandle implements android.os.Parcelable {
-    ctor public ParcelablePeerHandle(@NonNull android.net.wifi.aware.PeerHandle);
-    method public int describeContents();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.aware.ParcelablePeerHandle> CREATOR;
-  }
-
-  public class PeerHandle {
-  }
-
-  public final class PublishConfig implements android.os.Parcelable {
-    method public int describeContents();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.aware.PublishConfig> CREATOR;
-    field public static final int PUBLISH_TYPE_SOLICITED = 1; // 0x1
-    field public static final int PUBLISH_TYPE_UNSOLICITED = 0; // 0x0
-  }
-
-  public static final class PublishConfig.Builder {
-    ctor public PublishConfig.Builder();
-    method public android.net.wifi.aware.PublishConfig build();
-    method public android.net.wifi.aware.PublishConfig.Builder setMatchFilter(@Nullable java.util.List<byte[]>);
-    method public android.net.wifi.aware.PublishConfig.Builder setPublishType(int);
-    method public android.net.wifi.aware.PublishConfig.Builder setRangingEnabled(boolean);
-    method public android.net.wifi.aware.PublishConfig.Builder setServiceName(@NonNull String);
-    method public android.net.wifi.aware.PublishConfig.Builder setServiceSpecificInfo(@Nullable byte[]);
-    method public android.net.wifi.aware.PublishConfig.Builder setTerminateNotificationEnabled(boolean);
-    method public android.net.wifi.aware.PublishConfig.Builder setTtlSec(int);
-  }
-
-  public class PublishDiscoverySession extends android.net.wifi.aware.DiscoverySession {
-    method public void updatePublish(@NonNull android.net.wifi.aware.PublishConfig);
-  }
-
-  public final class SubscribeConfig implements android.os.Parcelable {
-    method public int describeContents();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.aware.SubscribeConfig> CREATOR;
-    field public static final int SUBSCRIBE_TYPE_ACTIVE = 1; // 0x1
-    field public static final int SUBSCRIBE_TYPE_PASSIVE = 0; // 0x0
-  }
-
-  public static final class SubscribeConfig.Builder {
-    ctor public SubscribeConfig.Builder();
-    method public android.net.wifi.aware.SubscribeConfig build();
-    method public android.net.wifi.aware.SubscribeConfig.Builder setMatchFilter(@Nullable java.util.List<byte[]>);
-    method public android.net.wifi.aware.SubscribeConfig.Builder setMaxDistanceMm(int);
-    method public android.net.wifi.aware.SubscribeConfig.Builder setMinDistanceMm(int);
-    method public android.net.wifi.aware.SubscribeConfig.Builder setServiceName(@NonNull String);
-    method public android.net.wifi.aware.SubscribeConfig.Builder setServiceSpecificInfo(@Nullable byte[]);
-    method public android.net.wifi.aware.SubscribeConfig.Builder setSubscribeType(int);
-    method public android.net.wifi.aware.SubscribeConfig.Builder setTerminateNotificationEnabled(boolean);
-    method public android.net.wifi.aware.SubscribeConfig.Builder setTtlSec(int);
-  }
-
-  public class SubscribeDiscoverySession extends android.net.wifi.aware.DiscoverySession {
-    method public void updateSubscribe(@NonNull android.net.wifi.aware.SubscribeConfig);
-  }
-
-  public class WifiAwareManager {
-    method public void attach(@NonNull android.net.wifi.aware.AttachCallback, @Nullable android.os.Handler);
-    method public void attach(@NonNull android.net.wifi.aware.AttachCallback, @NonNull android.net.wifi.aware.IdentityChangedListener, @Nullable android.os.Handler);
-    method public android.net.wifi.aware.Characteristics getCharacteristics();
-    method public boolean isAvailable();
-    field public static final String ACTION_WIFI_AWARE_STATE_CHANGED = "android.net.wifi.aware.action.WIFI_AWARE_STATE_CHANGED";
-    field public static final int WIFI_AWARE_DATA_PATH_ROLE_INITIATOR = 0; // 0x0
-    field public static final int WIFI_AWARE_DATA_PATH_ROLE_RESPONDER = 1; // 0x1
-  }
-
-  public final class WifiAwareNetworkInfo implements android.os.Parcelable android.net.TransportInfo {
-    method public int describeContents();
-    method @Nullable public java.net.Inet6Address getPeerIpv6Addr();
-    method public int getPort();
-    method public int getTransportProtocol();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.aware.WifiAwareNetworkInfo> CREATOR;
-  }
-
-  public final class WifiAwareNetworkSpecifier extends android.net.NetworkSpecifier implements android.os.Parcelable {
-    method public int describeContents();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.aware.WifiAwareNetworkSpecifier> CREATOR;
-  }
-
-  public static final class WifiAwareNetworkSpecifier.Builder {
-    ctor public WifiAwareNetworkSpecifier.Builder(@NonNull android.net.wifi.aware.DiscoverySession, @NonNull android.net.wifi.aware.PeerHandle);
-    method @NonNull public android.net.wifi.aware.WifiAwareNetworkSpecifier build();
-    method @NonNull public android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder setPmk(@NonNull byte[]);
-    method @NonNull public android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder setPort(@IntRange(from=0, to=65535) int);
-    method @NonNull public android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder setPskPassphrase(@NonNull String);
-    method @NonNull public android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder setTransportProtocol(@IntRange(from=0, to=255) int);
-  }
-
-  public class WifiAwareSession implements java.lang.AutoCloseable {
-    method public void close();
-    method public android.net.NetworkSpecifier createNetworkSpecifierOpen(int, @NonNull byte[]);
-    method public android.net.NetworkSpecifier createNetworkSpecifierPassphrase(int, @NonNull byte[], @NonNull String);
-    method public void publish(@NonNull android.net.wifi.aware.PublishConfig, @NonNull android.net.wifi.aware.DiscoverySessionCallback, @Nullable android.os.Handler);
-    method public void subscribe(@NonNull android.net.wifi.aware.SubscribeConfig, @NonNull android.net.wifi.aware.DiscoverySessionCallback, @Nullable android.os.Handler);
-  }
-
-}
-
-package android.net.wifi.hotspot2 {
-
-  public final class ConfigParser {
-    method public static android.net.wifi.hotspot2.PasspointConfiguration parsePasspointConfig(String, byte[]);
-  }
-
-  public final class PasspointConfiguration implements android.os.Parcelable {
-    ctor public PasspointConfiguration();
-    ctor public PasspointConfiguration(android.net.wifi.hotspot2.PasspointConfiguration);
-    method public int describeContents();
-    method public android.net.wifi.hotspot2.pps.Credential getCredential();
-    method public android.net.wifi.hotspot2.pps.HomeSp getHomeSp();
-    method public long getSubscriptionExpirationTimeMillis();
-    method @NonNull public String getUniqueId();
-    method public boolean isOsuProvisioned();
-    method public void setCredential(android.net.wifi.hotspot2.pps.Credential);
-    method public void setHomeSp(android.net.wifi.hotspot2.pps.HomeSp);
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.PasspointConfiguration> CREATOR;
-  }
-
-}
-
-package android.net.wifi.hotspot2.omadm {
-
-  public final class PpsMoParser {
-    method public static android.net.wifi.hotspot2.PasspointConfiguration parseMoText(String);
-  }
-
-}
-
-package android.net.wifi.hotspot2.pps {
-
-  public final class Credential implements android.os.Parcelable {
-    ctor public Credential();
-    ctor public Credential(android.net.wifi.hotspot2.pps.Credential);
-    method public int describeContents();
-    method public java.security.cert.X509Certificate getCaCertificate();
-    method public android.net.wifi.hotspot2.pps.Credential.CertificateCredential getCertCredential();
-    method public java.security.cert.X509Certificate[] getClientCertificateChain();
-    method public java.security.PrivateKey getClientPrivateKey();
-    method public String getRealm();
-    method public android.net.wifi.hotspot2.pps.Credential.SimCredential getSimCredential();
-    method public android.net.wifi.hotspot2.pps.Credential.UserCredential getUserCredential();
-    method public void setCaCertificate(java.security.cert.X509Certificate);
-    method public void setCertCredential(android.net.wifi.hotspot2.pps.Credential.CertificateCredential);
-    method public void setClientCertificateChain(java.security.cert.X509Certificate[]);
-    method public void setClientPrivateKey(java.security.PrivateKey);
-    method public void setRealm(String);
-    method public void setSimCredential(android.net.wifi.hotspot2.pps.Credential.SimCredential);
-    method public void setUserCredential(android.net.wifi.hotspot2.pps.Credential.UserCredential);
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential> CREATOR;
-  }
-
-  public static final class Credential.CertificateCredential implements android.os.Parcelable {
-    ctor public Credential.CertificateCredential();
-    ctor public Credential.CertificateCredential(android.net.wifi.hotspot2.pps.Credential.CertificateCredential);
-    method public int describeContents();
-    method public byte[] getCertSha256Fingerprint();
-    method public String getCertType();
-    method public void setCertSha256Fingerprint(byte[]);
-    method public void setCertType(String);
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential.CertificateCredential> CREATOR;
-  }
-
-  public static final class Credential.SimCredential implements android.os.Parcelable {
-    ctor public Credential.SimCredential();
-    ctor public Credential.SimCredential(android.net.wifi.hotspot2.pps.Credential.SimCredential);
-    method public int describeContents();
-    method public int getEapType();
-    method public String getImsi();
-    method public void setEapType(int);
-    method public void setImsi(String);
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential.SimCredential> CREATOR;
-  }
-
-  public static final class Credential.UserCredential implements android.os.Parcelable {
-    ctor public Credential.UserCredential();
-    ctor public Credential.UserCredential(android.net.wifi.hotspot2.pps.Credential.UserCredential);
-    method public int describeContents();
-    method public int getEapType();
-    method public String getNonEapInnerMethod();
-    method public String getPassword();
-    method public String getUsername();
-    method public void setEapType(int);
-    method public void setNonEapInnerMethod(String);
-    method public void setPassword(String);
-    method public void setUsername(String);
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential.UserCredential> CREATOR;
-  }
-
-  public final class HomeSp implements android.os.Parcelable {
-    ctor public HomeSp();
-    ctor public HomeSp(android.net.wifi.hotspot2.pps.HomeSp);
-    method public int describeContents();
-    method public String getFqdn();
-    method public String getFriendlyName();
-    method public long[] getRoamingConsortiumOis();
-    method public void setFqdn(String);
-    method public void setFriendlyName(String);
-    method public void setRoamingConsortiumOis(long[]);
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.HomeSp> CREATOR;
-  }
-
-}
-
-package android.net.wifi.p2p {
-
-  public class WifiP2pConfig implements android.os.Parcelable {
-    ctor public WifiP2pConfig();
-    ctor public WifiP2pConfig(android.net.wifi.p2p.WifiP2pConfig);
-    method public int describeContents();
-    method public int getGroupOwnerBand();
-    method public int getNetworkId();
-    method @Nullable public String getNetworkName();
-    method @Nullable public String getPassphrase();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.p2p.WifiP2pConfig> CREATOR;
-    field public static final int GROUP_OWNER_BAND_2GHZ = 1; // 0x1
-    field public static final int GROUP_OWNER_BAND_5GHZ = 2; // 0x2
-    field public static final int GROUP_OWNER_BAND_AUTO = 0; // 0x0
-    field public static final int GROUP_OWNER_INTENT_AUTO = -1; // 0xffffffff
-    field public static final int GROUP_OWNER_INTENT_MAX = 15; // 0xf
-    field public static final int GROUP_OWNER_INTENT_MIN = 0; // 0x0
-    field public String deviceAddress;
-    field @IntRange(from=0, to=15) public int groupOwnerIntent;
-    field public android.net.wifi.WpsInfo wps;
-  }
-
-  public static final class WifiP2pConfig.Builder {
-    ctor public WifiP2pConfig.Builder();
-    method @NonNull public android.net.wifi.p2p.WifiP2pConfig build();
-    method @NonNull public android.net.wifi.p2p.WifiP2pConfig.Builder enablePersistentMode(boolean);
-    method @NonNull public android.net.wifi.p2p.WifiP2pConfig.Builder setDeviceAddress(@Nullable android.net.MacAddress);
-    method @NonNull public android.net.wifi.p2p.WifiP2pConfig.Builder setGroupOperatingBand(int);
-    method @NonNull public android.net.wifi.p2p.WifiP2pConfig.Builder setGroupOperatingFrequency(int);
-    method @NonNull public android.net.wifi.p2p.WifiP2pConfig.Builder setNetworkName(@NonNull String);
-    method @NonNull public android.net.wifi.p2p.WifiP2pConfig.Builder setPassphrase(@NonNull String);
-  }
-
-  public class WifiP2pDevice implements android.os.Parcelable {
-    ctor public WifiP2pDevice();
-    ctor public WifiP2pDevice(android.net.wifi.p2p.WifiP2pDevice);
-    method public int describeContents();
-    method @Nullable public android.net.wifi.p2p.WifiP2pWfdInfo getWfdInfo();
-    method public boolean isGroupOwner();
-    method public boolean isServiceDiscoveryCapable();
-    method public void update(@NonNull android.net.wifi.p2p.WifiP2pDevice);
-    method public boolean wpsDisplaySupported();
-    method public boolean wpsKeypadSupported();
-    method public boolean wpsPbcSupported();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final int AVAILABLE = 3; // 0x3
-    field public static final int CONNECTED = 0; // 0x0
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.p2p.WifiP2pDevice> CREATOR;
-    field public static final int FAILED = 2; // 0x2
-    field public static final int INVITED = 1; // 0x1
-    field public static final int UNAVAILABLE = 4; // 0x4
-    field public String deviceAddress;
-    field public String deviceName;
-    field public String primaryDeviceType;
-    field public String secondaryDeviceType;
-    field public int status;
-  }
-
-  public class WifiP2pDeviceList implements android.os.Parcelable {
-    ctor public WifiP2pDeviceList();
-    ctor public WifiP2pDeviceList(android.net.wifi.p2p.WifiP2pDeviceList);
-    method public int describeContents();
-    method public android.net.wifi.p2p.WifiP2pDevice get(String);
-    method public java.util.Collection<android.net.wifi.p2p.WifiP2pDevice> getDeviceList();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.p2p.WifiP2pDeviceList> CREATOR;
-  }
-
-  public class WifiP2pGroup implements android.os.Parcelable {
-    ctor public WifiP2pGroup();
-    ctor public WifiP2pGroup(android.net.wifi.p2p.WifiP2pGroup);
-    method public int describeContents();
-    method public java.util.Collection<android.net.wifi.p2p.WifiP2pDevice> getClientList();
-    method public int getFrequency();
-    method public String getInterface();
-    method public int getNetworkId();
-    method public String getNetworkName();
-    method public android.net.wifi.p2p.WifiP2pDevice getOwner();
-    method public String getPassphrase();
-    method public boolean isGroupOwner();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.p2p.WifiP2pGroup> CREATOR;
-    field public static final int NETWORK_ID_PERSISTENT = -2; // 0xfffffffe
-    field public static final int NETWORK_ID_TEMPORARY = -1; // 0xffffffff
-  }
-
-  public class WifiP2pInfo implements android.os.Parcelable {
-    ctor public WifiP2pInfo();
-    ctor public WifiP2pInfo(android.net.wifi.p2p.WifiP2pInfo);
-    method public int describeContents();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.p2p.WifiP2pInfo> CREATOR;
-    field public boolean groupFormed;
-    field public java.net.InetAddress groupOwnerAddress;
-    field public boolean isGroupOwner;
-  }
-
-  public class WifiP2pManager {
-    method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void addLocalService(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.nsd.WifiP2pServiceInfo, android.net.wifi.p2p.WifiP2pManager.ActionListener);
-    method public void addServiceRequest(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.nsd.WifiP2pServiceRequest, android.net.wifi.p2p.WifiP2pManager.ActionListener);
-    method public void cancelConnect(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener);
-    method public void clearLocalServices(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener);
-    method public void clearServiceRequests(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener);
-    method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void connect(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pConfig, android.net.wifi.p2p.WifiP2pManager.ActionListener);
-    method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void createGroup(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener);
-    method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void createGroup(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @Nullable android.net.wifi.p2p.WifiP2pConfig, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener);
-    method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void discoverPeers(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener);
-    method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void discoverServices(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener);
-    method public android.net.wifi.p2p.WifiP2pManager.Channel initialize(android.content.Context, android.os.Looper, android.net.wifi.p2p.WifiP2pManager.ChannelListener);
-    method public void removeGroup(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener);
-    method public void removeLocalService(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.nsd.WifiP2pServiceInfo, android.net.wifi.p2p.WifiP2pManager.ActionListener);
-    method public void removeServiceRequest(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.nsd.WifiP2pServiceRequest, android.net.wifi.p2p.WifiP2pManager.ActionListener);
-    method public void requestConnectionInfo(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ConnectionInfoListener);
-    method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void requestDeviceInfo(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @NonNull android.net.wifi.p2p.WifiP2pManager.DeviceInfoListener);
-    method public void requestDiscoveryState(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @NonNull android.net.wifi.p2p.WifiP2pManager.DiscoveryStateListener);
-    method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void requestGroupInfo(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.GroupInfoListener);
-    method public void requestNetworkInfo(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @NonNull android.net.wifi.p2p.WifiP2pManager.NetworkInfoListener);
-    method public void requestP2pState(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @NonNull android.net.wifi.p2p.WifiP2pManager.P2pStateListener);
-    method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void requestPeers(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.PeerListListener);
-    method public void setDnsSdResponseListeners(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.DnsSdServiceResponseListener, android.net.wifi.p2p.WifiP2pManager.DnsSdTxtRecordListener);
-    method public void setServiceResponseListener(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ServiceResponseListener);
-    method public void setUpnpServiceResponseListener(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.UpnpServiceResponseListener);
-    method public void stopPeerDiscovery(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener);
-    field public static final int BUSY = 2; // 0x2
-    field public static final int ERROR = 0; // 0x0
-    field public static final String EXTRA_DISCOVERY_STATE = "discoveryState";
-    field public static final String EXTRA_NETWORK_INFO = "networkInfo";
-    field public static final String EXTRA_P2P_DEVICE_LIST = "wifiP2pDeviceList";
-    field public static final String EXTRA_WIFI_P2P_DEVICE = "wifiP2pDevice";
-    field public static final String EXTRA_WIFI_P2P_GROUP = "p2pGroupInfo";
-    field public static final String EXTRA_WIFI_P2P_INFO = "wifiP2pInfo";
-    field public static final String EXTRA_WIFI_STATE = "wifi_p2p_state";
-    field public static final int NO_SERVICE_REQUESTS = 3; // 0x3
-    field public static final int P2P_UNSUPPORTED = 1; // 0x1
-    field public static final String WIFI_P2P_CONNECTION_CHANGED_ACTION = "android.net.wifi.p2p.CONNECTION_STATE_CHANGE";
-    field public static final String WIFI_P2P_DISCOVERY_CHANGED_ACTION = "android.net.wifi.p2p.DISCOVERY_STATE_CHANGE";
-    field public static final int WIFI_P2P_DISCOVERY_STARTED = 2; // 0x2
-    field public static final int WIFI_P2P_DISCOVERY_STOPPED = 1; // 0x1
-    field public static final String WIFI_P2P_PEERS_CHANGED_ACTION = "android.net.wifi.p2p.PEERS_CHANGED";
-    field public static final String WIFI_P2P_STATE_CHANGED_ACTION = "android.net.wifi.p2p.STATE_CHANGED";
-    field public static final int WIFI_P2P_STATE_DISABLED = 1; // 0x1
-    field public static final int WIFI_P2P_STATE_ENABLED = 2; // 0x2
-    field public static final String WIFI_P2P_THIS_DEVICE_CHANGED_ACTION = "android.net.wifi.p2p.THIS_DEVICE_CHANGED";
-  }
-
-  public static interface WifiP2pManager.ActionListener {
-    method public void onFailure(int);
-    method public void onSuccess();
-  }
-
-  public static class WifiP2pManager.Channel implements java.lang.AutoCloseable {
-    method public void close();
-  }
-
-  public static interface WifiP2pManager.ChannelListener {
-    method public void onChannelDisconnected();
-  }
-
-  public static interface WifiP2pManager.ConnectionInfoListener {
-    method public void onConnectionInfoAvailable(android.net.wifi.p2p.WifiP2pInfo);
-  }
-
-  public static interface WifiP2pManager.DeviceInfoListener {
-    method public void onDeviceInfoAvailable(@Nullable android.net.wifi.p2p.WifiP2pDevice);
-  }
-
-  public static interface WifiP2pManager.DiscoveryStateListener {
-    method public void onDiscoveryStateAvailable(int);
-  }
-
-  public static interface WifiP2pManager.DnsSdServiceResponseListener {
-    method public void onDnsSdServiceAvailable(String, String, android.net.wifi.p2p.WifiP2pDevice);
-  }
-
-  public static interface WifiP2pManager.DnsSdTxtRecordListener {
-    method public void onDnsSdTxtRecordAvailable(String, java.util.Map<java.lang.String,java.lang.String>, android.net.wifi.p2p.WifiP2pDevice);
-  }
-
-  public static interface WifiP2pManager.GroupInfoListener {
-    method public void onGroupInfoAvailable(android.net.wifi.p2p.WifiP2pGroup);
-  }
-
-  public static interface WifiP2pManager.NetworkInfoListener {
-    method public void onNetworkInfoAvailable(@NonNull android.net.NetworkInfo);
-  }
-
-  public static interface WifiP2pManager.P2pStateListener {
-    method public void onP2pStateAvailable(int);
-  }
-
-  public static interface WifiP2pManager.PeerListListener {
-    method public void onPeersAvailable(android.net.wifi.p2p.WifiP2pDeviceList);
-  }
-
-  public static interface WifiP2pManager.ServiceResponseListener {
-    method public void onServiceAvailable(int, byte[], android.net.wifi.p2p.WifiP2pDevice);
-  }
-
-  public static interface WifiP2pManager.UpnpServiceResponseListener {
-    method public void onUpnpServiceAvailable(java.util.List<java.lang.String>, android.net.wifi.p2p.WifiP2pDevice);
-  }
-
-  public final class WifiP2pWfdInfo implements android.os.Parcelable {
-    ctor public WifiP2pWfdInfo();
-    ctor public WifiP2pWfdInfo(@Nullable android.net.wifi.p2p.WifiP2pWfdInfo);
-    method public int describeContents();
-    method public int getControlPort();
-    method public int getDeviceType();
-    method public int getMaxThroughput();
-    method public boolean isContentProtectionSupported();
-    method public boolean isEnabled();
-    method public boolean isSessionAvailable();
-    method public void setContentProtectionSupported(boolean);
-    method public void setControlPort(@IntRange(from=0) int);
-    method public boolean setDeviceType(int);
-    method public void setEnabled(boolean);
-    method public void setMaxThroughput(@IntRange(from=0) int);
-    method public void setSessionAvailable(boolean);
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.p2p.WifiP2pWfdInfo> CREATOR;
-    field public static final int DEVICE_TYPE_PRIMARY_SINK = 1; // 0x1
-    field public static final int DEVICE_TYPE_SECONDARY_SINK = 2; // 0x2
-    field public static final int DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK = 3; // 0x3
-    field public static final int DEVICE_TYPE_WFD_SOURCE = 0; // 0x0
-  }
-
-}
-
-package android.net.wifi.p2p.nsd {
-
-  public class WifiP2pDnsSdServiceInfo extends android.net.wifi.p2p.nsd.WifiP2pServiceInfo {
-    method public static android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceInfo newInstance(String, String, java.util.Map<java.lang.String,java.lang.String>);
-  }
-
-  public class WifiP2pDnsSdServiceRequest extends android.net.wifi.p2p.nsd.WifiP2pServiceRequest {
-    method public static android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceRequest newInstance();
-    method public static android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceRequest newInstance(String);
-    method public static android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceRequest newInstance(String, String);
-  }
-
-  public class WifiP2pServiceInfo implements android.os.Parcelable {
-    method public int describeContents();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final int SERVICE_TYPE_ALL = 0; // 0x0
-    field public static final int SERVICE_TYPE_BONJOUR = 1; // 0x1
-    field public static final int SERVICE_TYPE_UPNP = 2; // 0x2
-    field public static final int SERVICE_TYPE_VENDOR_SPECIFIC = 255; // 0xff
-  }
-
-  public class WifiP2pServiceRequest implements android.os.Parcelable {
-    method public int describeContents();
-    method public static android.net.wifi.p2p.nsd.WifiP2pServiceRequest newInstance(int, String);
-    method public static android.net.wifi.p2p.nsd.WifiP2pServiceRequest newInstance(int);
-    method public void writeToParcel(android.os.Parcel, int);
-  }
-
-  public class WifiP2pUpnpServiceInfo extends android.net.wifi.p2p.nsd.WifiP2pServiceInfo {
-    method public static android.net.wifi.p2p.nsd.WifiP2pUpnpServiceInfo newInstance(String, String, java.util.List<java.lang.String>);
-  }
-
-  public class WifiP2pUpnpServiceRequest extends android.net.wifi.p2p.nsd.WifiP2pServiceRequest {
-    method public static android.net.wifi.p2p.nsd.WifiP2pUpnpServiceRequest newInstance();
-    method public static android.net.wifi.p2p.nsd.WifiP2pUpnpServiceRequest newInstance(String);
-  }
-
-}
-
-package android.net.wifi.rtt {
-
-  public class CivicLocationKeys {
-    field public static final int ADDITIONAL_CODE = 32; // 0x20
-    field public static final int APT = 26; // 0x1a
-    field public static final int BOROUGH = 4; // 0x4
-    field public static final int BRANCH_ROAD_NAME = 36; // 0x24
-    field public static final int BUILDING = 25; // 0x19
-    field public static final int CITY = 3; // 0x3
-    field public static final int COUNTY = 2; // 0x2
-    field public static final int DESK = 33; // 0x21
-    field public static final int FLOOR = 27; // 0x1b
-    field public static final int GROUP_OF_STREETS = 6; // 0x6
-    field public static final int HNO = 19; // 0x13
-    field public static final int HNS = 20; // 0x14
-    field public static final int LANGUAGE = 0; // 0x0
-    field public static final int LMK = 21; // 0x15
-    field public static final int LOC = 22; // 0x16
-    field public static final int NAM = 23; // 0x17
-    field public static final int NEIGHBORHOOD = 5; // 0x5
-    field public static final int PCN = 30; // 0x1e
-    field public static final int POD = 17; // 0x11
-    field public static final int POSTAL_CODE = 24; // 0x18
-    field public static final int PO_BOX = 31; // 0x1f
-    field public static final int PRD = 16; // 0x10
-    field public static final int PRIMARY_ROAD_NAME = 34; // 0x22
-    field public static final int ROAD_SECTION = 35; // 0x23
-    field public static final int ROOM = 28; // 0x1c
-    field public static final int SCRIPT = 128; // 0x80
-    field public static final int STATE = 1; // 0x1
-    field public static final int STREET_NAME_POST_MODIFIER = 39; // 0x27
-    field public static final int STREET_NAME_PRE_MODIFIER = 38; // 0x26
-    field public static final int STS = 18; // 0x12
-    field public static final int SUBBRANCH_ROAD_NAME = 37; // 0x25
-    field public static final int TYPE_OF_PLACE = 29; // 0x1d
-  }
-
-  public final class RangingRequest implements android.os.Parcelable {
-    method public int describeContents();
-    method public static int getMaxPeers();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.rtt.RangingRequest> CREATOR;
-  }
-
-  public static final class RangingRequest.Builder {
-    ctor public RangingRequest.Builder();
-    method public android.net.wifi.rtt.RangingRequest.Builder addAccessPoint(@NonNull android.net.wifi.ScanResult);
-    method public android.net.wifi.rtt.RangingRequest.Builder addAccessPoints(@NonNull java.util.List<android.net.wifi.ScanResult>);
-    method public android.net.wifi.rtt.RangingRequest.Builder addWifiAwarePeer(@NonNull android.net.MacAddress);
-    method public android.net.wifi.rtt.RangingRequest.Builder addWifiAwarePeer(@NonNull android.net.wifi.aware.PeerHandle);
-    method public android.net.wifi.rtt.RangingRequest build();
-  }
-
-  public final class RangingResult implements android.os.Parcelable {
-    method public int describeContents();
-    method public int getDistanceMm();
-    method public int getDistanceStdDevMm();
-    method @Nullable public android.net.MacAddress getMacAddress();
-    method public int getNumAttemptedMeasurements();
-    method public int getNumSuccessfulMeasurements();
-    method @Nullable public android.net.wifi.aware.PeerHandle getPeerHandle();
-    method public long getRangingTimestampMillis();
-    method public int getRssi();
-    method public int getStatus();
-    method @Nullable public android.net.wifi.rtt.ResponderLocation getUnverifiedResponderLocation();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.rtt.RangingResult> CREATOR;
-    field public static final int STATUS_FAIL = 1; // 0x1
-    field public static final int STATUS_RESPONDER_DOES_NOT_SUPPORT_IEEE80211MC = 2; // 0x2
-    field public static final int STATUS_SUCCESS = 0; // 0x0
-  }
-
-  public abstract class RangingResultCallback {
-    ctor public RangingResultCallback();
-    method public abstract void onRangingFailure(int);
-    method public abstract void onRangingResults(@NonNull java.util.List<android.net.wifi.rtt.RangingResult>);
-    field public static final int STATUS_CODE_FAIL = 1; // 0x1
-    field public static final int STATUS_CODE_FAIL_RTT_NOT_AVAILABLE = 2; // 0x2
-  }
-
-  public final class ResponderLocation implements android.os.Parcelable {
-    method public int describeContents();
-    method public double getAltitude();
-    method public int getAltitudeType();
-    method public double getAltitudeUncertainty();
-    method public java.util.List<android.net.MacAddress> getColocatedBssids();
-    method public int getDatum();
-    method public int getExpectedToMove();
-    method public double getFloorNumber();
-    method public double getHeightAboveFloorMeters();
-    method public double getHeightAboveFloorUncertaintyMeters();
-    method public double getLatitude();
-    method public double getLatitudeUncertainty();
-    method public int getLciVersion();
-    method public double getLongitude();
-    method public double getLongitudeUncertainty();
-    method @Nullable public String getMapImageMimeType();
-    method @Nullable public android.net.Uri getMapImageUri();
-    method public boolean getRegisteredLocationAgreementIndication();
-    method public boolean isLciSubelementValid();
-    method public boolean isZaxisSubelementValid();
-    method @Nullable public android.location.Address toCivicLocationAddress();
-    method @Nullable public android.util.SparseArray<java.lang.String> toCivicLocationSparseArray();
-    method @NonNull public android.location.Location toLocation();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final int ALTITUDE_FLOORS = 2; // 0x2
-    field public static final int ALTITUDE_METERS = 1; // 0x1
-    field public static final int ALTITUDE_UNDEFINED = 0; // 0x0
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.rtt.ResponderLocation> CREATOR;
-    field public static final int DATUM_NAD83_MLLW = 3; // 0x3
-    field public static final int DATUM_NAD83_NAV88 = 2; // 0x2
-    field public static final int DATUM_UNDEFINED = 0; // 0x0
-    field public static final int DATUM_WGS84 = 1; // 0x1
-    field public static final int LCI_VERSION_1 = 1; // 0x1
-    field public static final int LOCATION_FIXED = 0; // 0x0
-    field public static final int LOCATION_MOVEMENT_UNKNOWN = 2; // 0x2
-    field public static final int LOCATION_RESERVED = 3; // 0x3
-    field public static final int LOCATION_VARIABLE = 1; // 0x1
-  }
-
-  public class WifiRttManager {
-    method public boolean isAvailable();
-    method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.CHANGE_WIFI_STATE, android.Manifest.permission.ACCESS_WIFI_STATE}) public void startRanging(@NonNull android.net.wifi.rtt.RangingRequest, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.rtt.RangingResultCallback);
-    field public static final String ACTION_WIFI_RTT_STATE_CHANGED = "android.net.wifi.rtt.action.WIFI_RTT_STATE_CHANGED";
-  }
-
-}
-
diff --git a/wifi/api/lint-baseline.txt b/wifi/api/lint-baseline.txt
deleted file mode 100644
index 892411f..0000000
--- a/wifi/api/lint-baseline.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-// Baseline format: 1.0
-GenericException: android.net.wifi.WifiManager.LocalOnlyHotspotReservation#finalize():
-    Methods must not throw generic exceptions (`java.lang.Throwable`)
-GenericException: android.net.wifi.WifiManager.MulticastLock#finalize():
-    Methods must not throw generic exceptions (`java.lang.Throwable`)
-GenericException: android.net.wifi.WifiManager.WifiLock#finalize():
-    Methods must not throw generic exceptions (`java.lang.Throwable`)
-
-
-VisiblySynchronized: PsiThisExpression:WifiManager.this:
-    Internal locks must not be exposed (synchronizing on this or class is still externally observable): method android.net.wifi.WifiManager.WifiLock.finalize()
-VisiblySynchronized: android.net.wifi.WifiManager.WifiLock#finalize():
-    Internal locks must not be exposed (synchronizing on this or class is still externally observable): method android.net.wifi.WifiManager.WifiLock.finalize()
diff --git a/wifi/api/module-lib-current.txt b/wifi/api/module-lib-current.txt
deleted file mode 100644
index d802177..0000000
--- a/wifi/api/module-lib-current.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/wifi/api/module-lib-removed.txt b/wifi/api/module-lib-removed.txt
deleted file mode 100644
index d802177..0000000
--- a/wifi/api/module-lib-removed.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/wifi/api/removed.txt b/wifi/api/removed.txt
deleted file mode 100644
index d802177..0000000
--- a/wifi/api/removed.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/wifi/api/system-current.txt b/wifi/api/system-current.txt
deleted file mode 100644
index 07793c1..0000000
--- a/wifi/api/system-current.txt
+++ /dev/null
@@ -1,939 +0,0 @@
-// Signature format: 2.0
-package android.net.wifi {
-
-  public abstract class EasyConnectStatusCallback {
-    ctor public EasyConnectStatusCallback();
-    method public abstract void onConfiguratorSuccess(int);
-    method public abstract void onEnrolleeSuccess(int);
-    method public void onFailure(int);
-    method public void onFailure(int, @Nullable String, @NonNull android.util.SparseArray<int[]>, @NonNull int[]);
-    method public abstract void onProgress(int);
-    field public static final int EASY_CONNECT_EVENT_PROGRESS_AUTHENTICATION_SUCCESS = 0; // 0x0
-    field public static final int EASY_CONNECT_EVENT_PROGRESS_CONFIGURATION_ACCEPTED = 3; // 0x3
-    field public static final int EASY_CONNECT_EVENT_PROGRESS_CONFIGURATION_SENT_WAITING_RESPONSE = 2; // 0x2
-    field public static final int EASY_CONNECT_EVENT_PROGRESS_RESPONSE_PENDING = 1; // 0x1
-    field public static final int EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_APPLIED = 1; // 0x1
-    field public static final int EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_SENT = 0; // 0x0
-  }
-
-  @Deprecated public class RttManager {
-    method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void disableResponder(android.net.wifi.RttManager.ResponderCallback);
-    method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void enableResponder(android.net.wifi.RttManager.ResponderCallback);
-    method @Deprecated public android.net.wifi.RttManager.Capabilities getCapabilities();
-    method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public android.net.wifi.RttManager.RttCapabilities getRttCapabilities();
-    method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void startRanging(android.net.wifi.RttManager.RttParams[], android.net.wifi.RttManager.RttListener);
-    method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void stopRanging(android.net.wifi.RttManager.RttListener);
-    field @Deprecated public static final int BASE = 160256; // 0x27200
-    field @Deprecated public static final int CMD_OP_ABORTED = 160260; // 0x27204
-    field @Deprecated public static final int CMD_OP_DISABLE_RESPONDER = 160262; // 0x27206
-    field @Deprecated public static final int CMD_OP_ENABLE_RESPONDER = 160261; // 0x27205
-    field @Deprecated public static final int CMD_OP_ENALBE_RESPONDER_FAILED = 160264; // 0x27208
-    field @Deprecated public static final int CMD_OP_ENALBE_RESPONDER_SUCCEEDED = 160263; // 0x27207
-    field @Deprecated public static final int CMD_OP_FAILED = 160258; // 0x27202
-    field @Deprecated public static final int CMD_OP_START_RANGING = 160256; // 0x27200
-    field @Deprecated public static final int CMD_OP_STOP_RANGING = 160257; // 0x27201
-    field @Deprecated public static final int CMD_OP_SUCCEEDED = 160259; // 0x27203
-    field @Deprecated public static final String DESCRIPTION_KEY = "android.net.wifi.RttManager.Description";
-    field @Deprecated public static final int PREAMBLE_HT = 2; // 0x2
-    field @Deprecated public static final int PREAMBLE_LEGACY = 1; // 0x1
-    field @Deprecated public static final int PREAMBLE_VHT = 4; // 0x4
-    field @Deprecated public static final int REASON_INITIATOR_NOT_ALLOWED_WHEN_RESPONDER_ON = -6; // 0xfffffffa
-    field @Deprecated public static final int REASON_INVALID_LISTENER = -3; // 0xfffffffd
-    field @Deprecated public static final int REASON_INVALID_REQUEST = -4; // 0xfffffffc
-    field @Deprecated public static final int REASON_NOT_AVAILABLE = -2; // 0xfffffffe
-    field @Deprecated public static final int REASON_PERMISSION_DENIED = -5; // 0xfffffffb
-    field @Deprecated public static final int REASON_UNSPECIFIED = -1; // 0xffffffff
-    field @Deprecated public static final int RTT_BW_10_SUPPORT = 2; // 0x2
-    field @Deprecated public static final int RTT_BW_160_SUPPORT = 32; // 0x20
-    field @Deprecated public static final int RTT_BW_20_SUPPORT = 4; // 0x4
-    field @Deprecated public static final int RTT_BW_40_SUPPORT = 8; // 0x8
-    field @Deprecated public static final int RTT_BW_5_SUPPORT = 1; // 0x1
-    field @Deprecated public static final int RTT_BW_80_SUPPORT = 16; // 0x10
-    field @Deprecated public static final int RTT_CHANNEL_WIDTH_10 = 6; // 0x6
-    field @Deprecated public static final int RTT_CHANNEL_WIDTH_160 = 3; // 0x3
-    field @Deprecated public static final int RTT_CHANNEL_WIDTH_20 = 0; // 0x0
-    field @Deprecated public static final int RTT_CHANNEL_WIDTH_40 = 1; // 0x1
-    field @Deprecated public static final int RTT_CHANNEL_WIDTH_5 = 5; // 0x5
-    field @Deprecated public static final int RTT_CHANNEL_WIDTH_80 = 2; // 0x2
-    field @Deprecated public static final int RTT_CHANNEL_WIDTH_80P80 = 4; // 0x4
-    field @Deprecated public static final int RTT_CHANNEL_WIDTH_UNSPECIFIED = -1; // 0xffffffff
-    field @Deprecated public static final int RTT_PEER_NAN = 5; // 0x5
-    field @Deprecated public static final int RTT_PEER_P2P_CLIENT = 4; // 0x4
-    field @Deprecated public static final int RTT_PEER_P2P_GO = 3; // 0x3
-    field @Deprecated public static final int RTT_PEER_TYPE_AP = 1; // 0x1
-    field @Deprecated public static final int RTT_PEER_TYPE_STA = 2; // 0x2
-    field @Deprecated public static final int RTT_PEER_TYPE_UNSPECIFIED = 0; // 0x0
-    field @Deprecated public static final int RTT_STATUS_ABORTED = 8; // 0x8
-    field @Deprecated public static final int RTT_STATUS_FAILURE = 1; // 0x1
-    field @Deprecated public static final int RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL = 6; // 0x6
-    field @Deprecated public static final int RTT_STATUS_FAIL_BUSY_TRY_LATER = 12; // 0xc
-    field @Deprecated public static final int RTT_STATUS_FAIL_FTM_PARAM_OVERRIDE = 15; // 0xf
-    field @Deprecated public static final int RTT_STATUS_FAIL_INVALID_TS = 9; // 0x9
-    field @Deprecated public static final int RTT_STATUS_FAIL_NOT_SCHEDULED_YET = 4; // 0x4
-    field @Deprecated public static final int RTT_STATUS_FAIL_NO_CAPABILITY = 7; // 0x7
-    field @Deprecated public static final int RTT_STATUS_FAIL_NO_RSP = 2; // 0x2
-    field @Deprecated public static final int RTT_STATUS_FAIL_PROTOCOL = 10; // 0xa
-    field @Deprecated public static final int RTT_STATUS_FAIL_REJECTED = 3; // 0x3
-    field @Deprecated public static final int RTT_STATUS_FAIL_SCHEDULE = 11; // 0xb
-    field @Deprecated public static final int RTT_STATUS_FAIL_TM_TIMEOUT = 5; // 0x5
-    field @Deprecated public static final int RTT_STATUS_INVALID_REQ = 13; // 0xd
-    field @Deprecated public static final int RTT_STATUS_NO_WIFI = 14; // 0xe
-    field @Deprecated public static final int RTT_STATUS_SUCCESS = 0; // 0x0
-    field @Deprecated public static final int RTT_TYPE_11_MC = 4; // 0x4
-    field @Deprecated public static final int RTT_TYPE_11_V = 2; // 0x2
-    field @Deprecated public static final int RTT_TYPE_ONE_SIDED = 1; // 0x1
-    field @Deprecated public static final int RTT_TYPE_TWO_SIDED = 2; // 0x2
-    field @Deprecated public static final int RTT_TYPE_UNSPECIFIED = 0; // 0x0
-  }
-
-  @Deprecated public class RttManager.Capabilities {
-    ctor @Deprecated public RttManager.Capabilities();
-    field @Deprecated public int supportedPeerType;
-    field @Deprecated public int supportedType;
-  }
-
-  @Deprecated public static class RttManager.ParcelableRttParams implements android.os.Parcelable {
-    field @Deprecated @NonNull public android.net.wifi.RttManager.RttParams[] mParams;
-  }
-
-  @Deprecated public static class RttManager.ParcelableRttResults implements android.os.Parcelable {
-    ctor @Deprecated public RttManager.ParcelableRttResults(android.net.wifi.RttManager.RttResult[]);
-    field @Deprecated public android.net.wifi.RttManager.RttResult[] mResults;
-  }
-
-  @Deprecated public abstract static class RttManager.ResponderCallback {
-    ctor @Deprecated public RttManager.ResponderCallback();
-    method @Deprecated public abstract void onResponderEnableFailure(int);
-    method @Deprecated public abstract void onResponderEnabled(android.net.wifi.RttManager.ResponderConfig);
-  }
-
-  @Deprecated public static class RttManager.ResponderConfig implements android.os.Parcelable {
-    ctor @Deprecated public RttManager.ResponderConfig();
-    method @Deprecated public int describeContents();
-    method @Deprecated public void writeToParcel(android.os.Parcel, int);
-    field @Deprecated @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.RttManager.ResponderConfig> CREATOR;
-    field @Deprecated public int centerFreq0;
-    field @Deprecated public int centerFreq1;
-    field @Deprecated public int channelWidth;
-    field @Deprecated public int frequency;
-    field @Deprecated public String macAddress;
-    field @Deprecated public int preamble;
-  }
-
-  @Deprecated public static class RttManager.RttCapabilities implements android.os.Parcelable {
-    ctor @Deprecated public RttManager.RttCapabilities();
-    field @Deprecated public int bwSupported;
-    field @Deprecated public boolean lciSupported;
-    field @Deprecated public boolean lcrSupported;
-    field @Deprecated public int mcVersion;
-    field @Deprecated public boolean oneSidedRttSupported;
-    field @Deprecated public int preambleSupported;
-    field @Deprecated public boolean responderSupported;
-    field @Deprecated public boolean secureRttSupported;
-    field @Deprecated public boolean supportedPeerType;
-    field @Deprecated public boolean supportedType;
-    field @Deprecated public boolean twoSided11McRttSupported;
-  }
-
-  @Deprecated public static interface RttManager.RttListener {
-    method @Deprecated public void onAborted();
-    method @Deprecated public void onFailure(int, String);
-    method @Deprecated public void onSuccess(android.net.wifi.RttManager.RttResult[]);
-  }
-
-  @Deprecated public static class RttManager.RttParams {
-    ctor @Deprecated public RttManager.RttParams();
-    field @Deprecated public boolean LCIRequest;
-    field @Deprecated public boolean LCRRequest;
-    field @Deprecated public int bandwidth;
-    field @Deprecated public String bssid;
-    field @Deprecated public int burstTimeout;
-    field @Deprecated public int centerFreq0;
-    field @Deprecated public int centerFreq1;
-    field @Deprecated public int channelWidth;
-    field @Deprecated public int deviceType;
-    field @Deprecated public int frequency;
-    field @Deprecated public int interval;
-    field @Deprecated public int numRetriesPerFTMR;
-    field @Deprecated public int numRetriesPerMeasurementFrame;
-    field @Deprecated public int numSamplesPerBurst;
-    field @Deprecated public int num_retries;
-    field @Deprecated public int num_samples;
-    field @Deprecated public int numberBurst;
-    field @Deprecated public int preamble;
-    field @Deprecated public int requestType;
-    field @Deprecated public boolean secure;
-  }
-
-  @Deprecated public static class RttManager.RttResult {
-    ctor @Deprecated public RttManager.RttResult();
-    field @Deprecated public android.net.wifi.RttManager.WifiInformationElement LCI;
-    field @Deprecated public android.net.wifi.RttManager.WifiInformationElement LCR;
-    field @Deprecated public String bssid;
-    field @Deprecated public int burstDuration;
-    field @Deprecated public int burstNumber;
-    field @Deprecated public int distance;
-    field @Deprecated public int distanceSpread;
-    field @Deprecated public int distanceStandardDeviation;
-    field @Deprecated public int distance_cm;
-    field @Deprecated public int distance_sd_cm;
-    field @Deprecated public int distance_spread_cm;
-    field @Deprecated public int frameNumberPerBurstPeer;
-    field @Deprecated public int measurementFrameNumber;
-    field @Deprecated public int measurementType;
-    field @Deprecated public int negotiatedBurstNum;
-    field @Deprecated public int requestType;
-    field @Deprecated public int retryAfterDuration;
-    field @Deprecated public int rssi;
-    field @Deprecated public int rssiSpread;
-    field @Deprecated public int rssi_spread;
-    field @Deprecated public long rtt;
-    field @Deprecated public long rttSpread;
-    field @Deprecated public long rttStandardDeviation;
-    field @Deprecated public long rtt_ns;
-    field @Deprecated public long rtt_sd_ns;
-    field @Deprecated public long rtt_spread_ns;
-    field @Deprecated public int rxRate;
-    field @Deprecated public boolean secure;
-    field @Deprecated public int status;
-    field @Deprecated public int successMeasurementFrameNumber;
-    field @Deprecated public long ts;
-    field @Deprecated public int txRate;
-    field @Deprecated public int tx_rate;
-  }
-
-  @Deprecated public static class RttManager.WifiInformationElement {
-    ctor @Deprecated public RttManager.WifiInformationElement();
-    field @Deprecated public byte[] data;
-    field @Deprecated public byte id;
-  }
-
-  public final class ScanResult implements android.os.Parcelable {
-    field public static final int CIPHER_CCMP = 3; // 0x3
-    field public static final int CIPHER_GCMP_256 = 4; // 0x4
-    field public static final int CIPHER_NONE = 0; // 0x0
-    field public static final int CIPHER_NO_GROUP_ADDRESSED = 1; // 0x1
-    field public static final int CIPHER_SMS4 = 5; // 0x5
-    field public static final int CIPHER_TKIP = 2; // 0x2
-    field public static final int KEY_MGMT_EAP = 2; // 0x2
-    field public static final int KEY_MGMT_EAP_SHA256 = 6; // 0x6
-    field public static final int KEY_MGMT_EAP_SUITE_B_192 = 10; // 0xa
-    field public static final int KEY_MGMT_FT_EAP = 4; // 0x4
-    field public static final int KEY_MGMT_FT_PSK = 3; // 0x3
-    field public static final int KEY_MGMT_FT_SAE = 11; // 0xb
-    field public static final int KEY_MGMT_NONE = 0; // 0x0
-    field public static final int KEY_MGMT_OSEN = 7; // 0x7
-    field public static final int KEY_MGMT_OWE = 9; // 0x9
-    field public static final int KEY_MGMT_OWE_TRANSITION = 12; // 0xc
-    field public static final int KEY_MGMT_PSK = 1; // 0x1
-    field public static final int KEY_MGMT_PSK_SHA256 = 5; // 0x5
-    field public static final int KEY_MGMT_SAE = 8; // 0x8
-    field public static final int KEY_MGMT_WAPI_CERT = 14; // 0xe
-    field public static final int KEY_MGMT_WAPI_PSK = 13; // 0xd
-    field public static final int PROTOCOL_NONE = 0; // 0x0
-    field public static final int PROTOCOL_OSEN = 3; // 0x3
-    field public static final int PROTOCOL_RSN = 2; // 0x2
-    field public static final int PROTOCOL_WAPI = 4; // 0x4
-    field public static final int PROTOCOL_WPA = 1; // 0x1
-  }
-
-  public final class SoftApCapability implements android.os.Parcelable {
-    method public boolean areFeaturesSupported(long);
-    method public int describeContents();
-    method public int getMaxSupportedClients();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.SoftApCapability> CREATOR;
-    field public static final long SOFTAP_FEATURE_ACS_OFFLOAD = 1L; // 0x1L
-    field public static final long SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT = 2L; // 0x2L
-    field public static final long SOFTAP_FEATURE_WPA3_SAE = 4L; // 0x4L
-  }
-
-  public final class SoftApConfiguration implements android.os.Parcelable {
-    method @NonNull public java.util.List<android.net.MacAddress> getAllowedClientList();
-    method public int getBand();
-    method @NonNull public java.util.List<android.net.MacAddress> getBlockedClientList();
-    method public int getChannel();
-    method public int getMaxNumberOfClients();
-    method public long getShutdownTimeoutMillis();
-    method public boolean isAutoShutdownEnabled();
-    method public boolean isClientControlByUserEnabled();
-    method @Nullable public android.net.wifi.WifiConfiguration toWifiConfiguration();
-    field public static final int BAND_2GHZ = 1; // 0x1
-    field public static final int BAND_5GHZ = 2; // 0x2
-    field public static final int BAND_6GHZ = 4; // 0x4
-    field public static final int BAND_ANY = 7; // 0x7
-  }
-
-  public static final class SoftApConfiguration.Builder {
-    ctor public SoftApConfiguration.Builder();
-    ctor public SoftApConfiguration.Builder(@NonNull android.net.wifi.SoftApConfiguration);
-    method @NonNull public android.net.wifi.SoftApConfiguration build();
-    method @NonNull public android.net.wifi.SoftApConfiguration.Builder setAllowedClientList(@NonNull java.util.List<android.net.MacAddress>);
-    method @NonNull public android.net.wifi.SoftApConfiguration.Builder setAutoShutdownEnabled(boolean);
-    method @NonNull public android.net.wifi.SoftApConfiguration.Builder setBand(int);
-    method @NonNull public android.net.wifi.SoftApConfiguration.Builder setBlockedClientList(@NonNull java.util.List<android.net.MacAddress>);
-    method @NonNull public android.net.wifi.SoftApConfiguration.Builder setBssid(@Nullable android.net.MacAddress);
-    method @NonNull public android.net.wifi.SoftApConfiguration.Builder setChannel(int, int);
-    method @NonNull public android.net.wifi.SoftApConfiguration.Builder setClientControlByUserEnabled(boolean);
-    method @NonNull public android.net.wifi.SoftApConfiguration.Builder setHiddenSsid(boolean);
-    method @NonNull public android.net.wifi.SoftApConfiguration.Builder setMaxNumberOfClients(@IntRange(from=0) int);
-    method @NonNull public android.net.wifi.SoftApConfiguration.Builder setPassphrase(@Nullable String, int);
-    method @NonNull public android.net.wifi.SoftApConfiguration.Builder setShutdownTimeoutMillis(@IntRange(from=0) long);
-    method @NonNull public android.net.wifi.SoftApConfiguration.Builder setSsid(@Nullable String);
-  }
-
-  public final class SoftApInfo implements android.os.Parcelable {
-    method public int describeContents();
-    method public int getBandwidth();
-    method public int getFrequency();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field public static final int CHANNEL_WIDTH_160MHZ = 6; // 0x6
-    field public static final int CHANNEL_WIDTH_20MHZ = 2; // 0x2
-    field public static final int CHANNEL_WIDTH_20MHZ_NOHT = 1; // 0x1
-    field public static final int CHANNEL_WIDTH_40MHZ = 3; // 0x3
-    field public static final int CHANNEL_WIDTH_80MHZ = 4; // 0x4
-    field public static final int CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 5; // 0x5
-    field public static final int CHANNEL_WIDTH_INVALID = 0; // 0x0
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.SoftApInfo> CREATOR;
-  }
-
-  public final class WifiClient implements android.os.Parcelable {
-    method public int describeContents();
-    method @NonNull public android.net.MacAddress getMacAddress();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.WifiClient> CREATOR;
-  }
-
-  @Deprecated public class WifiConfiguration implements android.os.Parcelable {
-    method @Deprecated public int getAuthType();
-    method @Deprecated @NonNull public android.net.IpConfiguration getIpConfiguration();
-    method @Deprecated @NonNull public android.net.wifi.WifiConfiguration.NetworkSelectionStatus getNetworkSelectionStatus();
-    method @Deprecated @NonNull public String getPrintableSsid();
-    method @Deprecated public int getRecentFailureReason();
-    method @Deprecated public boolean hasNoInternetAccess();
-    method @Deprecated public boolean isEphemeral();
-    method @Deprecated public static boolean isMetered(@Nullable android.net.wifi.WifiConfiguration, @Nullable android.net.wifi.WifiInfo);
-    method @Deprecated public boolean isNoInternetAccessExpected();
-    method @Deprecated public void setIpConfiguration(@Nullable android.net.IpConfiguration);
-    method @Deprecated public void setNetworkSelectionStatus(@NonNull android.net.wifi.WifiConfiguration.NetworkSelectionStatus);
-    field @Deprecated public static final int INVALID_NETWORK_ID = -1; // 0xffffffff
-    field @Deprecated public static final int METERED_OVERRIDE_METERED = 1; // 0x1
-    field @Deprecated public static final int METERED_OVERRIDE_NONE = 0; // 0x0
-    field @Deprecated public static final int METERED_OVERRIDE_NOT_METERED = 2; // 0x2
-    field @Deprecated public static final int RANDOMIZATION_NONE = 0; // 0x0
-    field @Deprecated public static final int RANDOMIZATION_PERSISTENT = 1; // 0x1
-    field @Deprecated public static final int RECENT_FAILURE_AP_UNABLE_TO_HANDLE_NEW_STA = 17; // 0x11
-    field @Deprecated public static final int RECENT_FAILURE_NONE = 0; // 0x0
-    field @Deprecated public boolean allowAutojoin;
-    field @Deprecated public int carrierId;
-    field @Deprecated public String creatorName;
-    field @Deprecated public int creatorUid;
-    field @Deprecated public boolean fromWifiNetworkSpecifier;
-    field @Deprecated public boolean fromWifiNetworkSuggestion;
-    field @Deprecated public String lastUpdateName;
-    field @Deprecated public int lastUpdateUid;
-    field @Deprecated public int macRandomizationSetting;
-    field @Deprecated public boolean meteredHint;
-    field @Deprecated public int meteredOverride;
-    field @Deprecated public int numAssociation;
-    field @Deprecated public int numScorerOverride;
-    field @Deprecated public int numScorerOverrideAndSwitchedNetwork;
-    field @Deprecated public boolean requirePmf;
-    field @Deprecated public boolean shared;
-    field @Deprecated public boolean useExternalScores;
-  }
-
-  @Deprecated public static class WifiConfiguration.KeyMgmt {
-    field @Deprecated public static final int WAPI_CERT = 14; // 0xe
-    field @Deprecated public static final int WAPI_PSK = 13; // 0xd
-    field @Deprecated public static final int WPA2_PSK = 4; // 0x4
-  }
-
-  @Deprecated public static class WifiConfiguration.NetworkSelectionStatus {
-    method @Deprecated public int getDisableReasonCounter(int);
-    method @Deprecated public long getDisableTime();
-    method @Deprecated public static int getMaxNetworkSelectionDisableReason();
-    method @Deprecated public int getNetworkSelectionDisableReason();
-    method @Deprecated @Nullable public static String getNetworkSelectionDisableReasonString(int);
-    method @Deprecated public int getNetworkSelectionStatus();
-    method @Deprecated @NonNull public String getNetworkStatusString();
-    method @Deprecated public boolean hasEverConnected();
-    field @Deprecated public static final int DISABLED_ASSOCIATION_REJECTION = 1; // 0x1
-    field @Deprecated public static final int DISABLED_AUTHENTICATION_FAILURE = 2; // 0x2
-    field @Deprecated public static final int DISABLED_AUTHENTICATION_NO_CREDENTIALS = 5; // 0x5
-    field @Deprecated public static final int DISABLED_AUTHENTICATION_NO_SUBSCRIPTION = 9; // 0x9
-    field @Deprecated public static final int DISABLED_BY_WIFI_MANAGER = 7; // 0x7
-    field @Deprecated public static final int DISABLED_BY_WRONG_PASSWORD = 8; // 0x8
-    field @Deprecated public static final int DISABLED_DHCP_FAILURE = 3; // 0x3
-    field @Deprecated public static final int DISABLED_NONE = 0; // 0x0
-    field @Deprecated public static final int DISABLED_NO_INTERNET_PERMANENT = 6; // 0x6
-    field @Deprecated public static final int DISABLED_NO_INTERNET_TEMPORARY = 4; // 0x4
-    field @Deprecated public static final int NETWORK_SELECTION_ENABLED = 0; // 0x0
-    field @Deprecated public static final int NETWORK_SELECTION_PERMANENTLY_DISABLED = 2; // 0x2
-    field @Deprecated public static final int NETWORK_SELECTION_TEMPORARY_DISABLED = 1; // 0x1
-  }
-
-  @Deprecated public static final class WifiConfiguration.NetworkSelectionStatus.Builder {
-    ctor @Deprecated public WifiConfiguration.NetworkSelectionStatus.Builder();
-    method @Deprecated @NonNull public android.net.wifi.WifiConfiguration.NetworkSelectionStatus build();
-    method @Deprecated @NonNull public android.net.wifi.WifiConfiguration.NetworkSelectionStatus.Builder setNetworkSelectionDisableReason(int);
-    method @Deprecated @NonNull public android.net.wifi.WifiConfiguration.NetworkSelectionStatus.Builder setNetworkSelectionStatus(int);
-  }
-
-  public class WifiEnterpriseConfig implements android.os.Parcelable {
-    method @Nullable public String[] getCaCertificateAliases();
-    method @NonNull public String getCaPath();
-    method @NonNull public String getClientCertificateAlias();
-    method public int getOcsp();
-    method @NonNull public String getWapiCertSuite();
-    method public void setCaCertificateAliases(@Nullable String[]);
-    method public void setCaPath(@NonNull String);
-    method public void setClientCertificateAlias(@NonNull String);
-    method public void setOcsp(int);
-    method public void setWapiCertSuite(@NonNull String);
-    field public static final int OCSP_NONE = 0; // 0x0
-    field public static final int OCSP_REQUEST_CERT_STATUS = 1; // 0x1
-    field public static final int OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS = 3; // 0x3
-    field public static final int OCSP_REQUIRE_CERT_STATUS = 2; // 0x2
-  }
-
-  public class WifiFrameworkInitializer {
-    method public static void registerServiceWrappers();
-  }
-
-  public class WifiInfo implements android.os.Parcelable {
-    method public double getLostTxPacketsPerSecond();
-    method @Nullable public String getRequestingPackageName();
-    method public double getRetriedTxPacketsPerSecond();
-    method public int getScore();
-    method public double getSuccessfulRxPacketsPerSecond();
-    method public double getSuccessfulTxPacketsPerSecond();
-    method public boolean isEphemeral();
-    method public boolean isOsuAp();
-    method public boolean isPasspointAp();
-    method @Nullable public static String sanitizeSsid(@Nullable String);
-    field public static final String DEFAULT_MAC_ADDRESS = "02:00:00:00:00:00";
-    field public static final int INVALID_RSSI = -127; // 0xffffff81
-  }
-
-  public class WifiManager {
-    method @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE) public void addOnWifiUsabilityStatsListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.OnWifiUsabilityStatsListener);
-    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void allowAutojoin(int, boolean);
-    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void allowAutojoinGlobal(boolean);
-    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void allowAutojoinPasspoint(@NonNull String, boolean);
-    method @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE) public void clearWifiConnectedNetworkScorer();
-    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void connect(@NonNull android.net.wifi.WifiConfiguration, @Nullable android.net.wifi.WifiManager.ActionListener);
-    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void connect(int, @Nullable android.net.wifi.WifiManager.ActionListener);
-    method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void disable(int, @Nullable android.net.wifi.WifiManager.ActionListener);
-    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK}) public void disableEphemeralNetwork(@NonNull String);
-    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void factoryReset();
-    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void forget(int, @Nullable android.net.wifi.WifiManager.ActionListener);
-    method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.List<android.util.Pair<android.net.wifi.WifiConfiguration,java.util.Map<java.lang.Integer,java.util.List<android.net.wifi.ScanResult>>>> getAllMatchingWifiConfigs(@NonNull java.util.List<android.net.wifi.ScanResult>);
-    method @Nullable @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public String getCountryCode();
-    method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public android.net.Network getCurrentNetwork();
-    method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public String[] getFactoryMacAddresses();
-    method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.Map<android.net.wifi.hotspot2.OsuProvider,java.util.List<android.net.wifi.ScanResult>> getMatchingOsuProviders(@Nullable java.util.List<android.net.wifi.ScanResult>);
-    method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.Map<android.net.wifi.hotspot2.OsuProvider,android.net.wifi.hotspot2.PasspointConfiguration> getMatchingPasspointConfigsForOsuProviders(@NonNull java.util.Set<android.net.wifi.hotspot2.OsuProvider>);
-    method @NonNull @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_WIFI_STATE}) public java.util.Map<android.net.wifi.WifiNetworkSuggestion,java.util.List<android.net.wifi.ScanResult>> getMatchingScanResults(@NonNull java.util.List<android.net.wifi.WifiNetworkSuggestion>, @Nullable java.util.List<android.net.wifi.ScanResult>);
-    method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_WIFI_STATE, android.Manifest.permission.READ_WIFI_CREDENTIAL}) public java.util.List<android.net.wifi.WifiConfiguration> getPrivilegedConfiguredNetworks();
-    method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public android.net.wifi.SoftApConfiguration getSoftApConfiguration();
-    method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public void getWifiActivityEnergyInfoAsync(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.OnWifiActivityEnergyInfoListener);
-    method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public android.net.wifi.WifiConfiguration getWifiApConfiguration();
-    method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public int getWifiApState();
-    method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.List<android.net.wifi.WifiConfiguration> getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(@NonNull java.util.List<android.net.wifi.ScanResult>);
-    method public boolean isApMacRandomizationSupported();
-    method public boolean isConnectedMacRandomizationSupported();
-    method @Deprecated public boolean isDeviceToDeviceRttSupported();
-    method public boolean isPortableHotspotSupported();
-    method public boolean isVerboseLoggingEnabled();
-    method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public boolean isWifiApEnabled();
-    method public boolean isWifiScannerSupported();
-    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void registerNetworkRequestMatchCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.NetworkRequestMatchCallback);
-    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void registerSoftApCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.SoftApCallback);
-    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void registerTrafficStateCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.TrafficStateCallback);
-    method @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE) public void removeOnWifiUsabilityStatsListener(@NonNull android.net.wifi.WifiManager.OnWifiUsabilityStatsListener);
-    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void restoreBackupData(@NonNull byte[]);
-    method @Nullable @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public android.net.wifi.SoftApConfiguration restoreSoftApBackupData(@NonNull byte[]);
-    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void restoreSupplicantBackupData(@NonNull byte[], @NonNull byte[]);
-    method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public byte[] retrieveBackupData();
-    method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public byte[] retrieveSoftApBackupData();
-    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void save(@NonNull android.net.wifi.WifiConfiguration, @Nullable android.net.wifi.WifiManager.ActionListener);
-    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void setAutoWakeupEnabled(boolean);
-    method @RequiresPermission(android.Manifest.permission.WIFI_SET_DEVICE_MOBILITY_STATE) public void setDeviceMobilityState(int);
-    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void setMacRandomizationSettingPasspointEnabled(@NonNull String, boolean);
-    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void setPasspointMeteredOverride(@NonNull String, int);
-    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void setScanAlwaysAvailable(boolean);
-    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void setScanThrottleEnabled(boolean);
-    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public boolean setSoftApConfiguration(@NonNull android.net.wifi.SoftApConfiguration);
-    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void setVerboseLoggingEnabled(boolean);
-    method @Deprecated @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE) public boolean setWifiApConfiguration(android.net.wifi.WifiConfiguration);
-    method @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE) public boolean setWifiConnectedNetworkScorer(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.WifiConnectedNetworkScorer);
-    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startEasyConnectAsConfiguratorInitiator(@NonNull String, int, int, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.EasyConnectStatusCallback);
-    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startEasyConnectAsEnrolleeInitiator(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.EasyConnectStatusCallback);
-    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startLocalOnlyHotspot(@NonNull android.net.wifi.SoftApConfiguration, @Nullable java.util.concurrent.Executor, @Nullable android.net.wifi.WifiManager.LocalOnlyHotspotCallback);
-    method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public boolean startScan(android.os.WorkSource);
-    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startSubscriptionProvisioning(@NonNull android.net.wifi.hotspot2.OsuProvider, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.hotspot2.ProvisioningCallback);
-    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public boolean startTetheredHotspot(@Nullable android.net.wifi.SoftApConfiguration);
-    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void stopEasyConnectSession();
-    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public boolean stopSoftAp();
-    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void unregisterNetworkRequestMatchCallback(@NonNull android.net.wifi.WifiManager.NetworkRequestMatchCallback);
-    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void unregisterSoftApCallback(@NonNull android.net.wifi.WifiManager.SoftApCallback);
-    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void unregisterTrafficStateCallback(@NonNull android.net.wifi.WifiManager.TrafficStateCallback);
-    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void updateInterfaceIpState(@Nullable String, int);
-    method @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE) public void updateWifiUsabilityScore(int, int, int);
-    field public static final String ACTION_LINK_CONFIGURATION_CHANGED = "android.net.wifi.LINK_CONFIGURATION_CHANGED";
-    field @RequiresPermission(android.Manifest.permission.NETWORK_CARRIER_PROVISIONING) public static final String ACTION_NETWORK_SETTINGS_RESET = "android.net.wifi.action.NETWORK_SETTINGS_RESET";
-    field public static final String ACTION_PASSPOINT_LAUNCH_OSU_VIEW = "android.net.wifi.action.PASSPOINT_LAUNCH_OSU_VIEW";
-    field public static final String ACTION_REQUEST_DISABLE = "android.net.wifi.action.REQUEST_DISABLE";
-    field public static final String ACTION_REQUEST_ENABLE = "android.net.wifi.action.REQUEST_ENABLE";
-    field public static final int CHANGE_REASON_ADDED = 0; // 0x0
-    field public static final int CHANGE_REASON_CONFIG_CHANGE = 2; // 0x2
-    field public static final int CHANGE_REASON_REMOVED = 1; // 0x1
-    field public static final String CONFIGURED_NETWORKS_CHANGED_ACTION = "android.net.wifi.CONFIGURED_NETWORKS_CHANGE";
-    field public static final int DEVICE_MOBILITY_STATE_HIGH_MVMT = 1; // 0x1
-    field public static final int DEVICE_MOBILITY_STATE_LOW_MVMT = 2; // 0x2
-    field public static final int DEVICE_MOBILITY_STATE_STATIONARY = 3; // 0x3
-    field public static final int DEVICE_MOBILITY_STATE_UNKNOWN = 0; // 0x0
-    field public static final int EASY_CONNECT_NETWORK_ROLE_AP = 1; // 0x1
-    field public static final int EASY_CONNECT_NETWORK_ROLE_STA = 0; // 0x0
-    field public static final String EXTRA_CHANGE_REASON = "changeReason";
-    field public static final String EXTRA_LINK_PROPERTIES = "android.net.wifi.extra.LINK_PROPERTIES";
-    field public static final String EXTRA_MULTIPLE_NETWORKS_CHANGED = "multipleChanges";
-    field public static final String EXTRA_OSU_NETWORK = "android.net.wifi.extra.OSU_NETWORK";
-    field public static final String EXTRA_PREVIOUS_WIFI_AP_STATE = "previous_wifi_state";
-    field public static final String EXTRA_URL = "android.net.wifi.extra.URL";
-    field public static final String EXTRA_WIFI_AP_FAILURE_REASON = "android.net.wifi.extra.WIFI_AP_FAILURE_REASON";
-    field public static final String EXTRA_WIFI_AP_INTERFACE_NAME = "android.net.wifi.extra.WIFI_AP_INTERFACE_NAME";
-    field public static final String EXTRA_WIFI_AP_MODE = "android.net.wifi.extra.WIFI_AP_MODE";
-    field public static final String EXTRA_WIFI_AP_STATE = "wifi_state";
-    field public static final String EXTRA_WIFI_CONFIGURATION = "wifiConfiguration";
-    field public static final String EXTRA_WIFI_CREDENTIAL_EVENT_TYPE = "et";
-    field public static final String EXTRA_WIFI_CREDENTIAL_SSID = "ssid";
-    field public static final int IFACE_IP_MODE_CONFIGURATION_ERROR = 0; // 0x0
-    field public static final int IFACE_IP_MODE_LOCAL_ONLY = 2; // 0x2
-    field public static final int IFACE_IP_MODE_TETHERED = 1; // 0x1
-    field public static final int IFACE_IP_MODE_UNSPECIFIED = -1; // 0xffffffff
-    field public static final int PASSPOINT_HOME_NETWORK = 0; // 0x0
-    field public static final int PASSPOINT_ROAMING_NETWORK = 1; // 0x1
-    field public static final int SAP_CLIENT_BLOCK_REASON_CODE_BLOCKED_BY_USER = 0; // 0x0
-    field public static final int SAP_CLIENT_BLOCK_REASON_CODE_NO_MORE_STAS = 1; // 0x1
-    field public static final int SAP_START_FAILURE_GENERAL = 0; // 0x0
-    field public static final int SAP_START_FAILURE_NO_CHANNEL = 1; // 0x1
-    field public static final int SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION = 2; // 0x2
-    field public static final String WIFI_AP_STATE_CHANGED_ACTION = "android.net.wifi.WIFI_AP_STATE_CHANGED";
-    field public static final int WIFI_AP_STATE_DISABLED = 11; // 0xb
-    field public static final int WIFI_AP_STATE_DISABLING = 10; // 0xa
-    field public static final int WIFI_AP_STATE_ENABLED = 13; // 0xd
-    field public static final int WIFI_AP_STATE_ENABLING = 12; // 0xc
-    field public static final int WIFI_AP_STATE_FAILED = 14; // 0xe
-    field public static final String WIFI_CREDENTIAL_CHANGED_ACTION = "android.net.wifi.WIFI_CREDENTIAL_CHANGED";
-    field public static final int WIFI_CREDENTIAL_FORGOT = 1; // 0x1
-    field public static final int WIFI_CREDENTIAL_SAVED = 0; // 0x0
-  }
-
-  public static interface WifiManager.ActionListener {
-    method public void onFailure(int);
-    method public void onSuccess();
-  }
-
-  public static interface WifiManager.NetworkRequestMatchCallback {
-    method public default void onAbort();
-    method public default void onMatch(@NonNull java.util.List<android.net.wifi.ScanResult>);
-    method public default void onUserSelectionCallbackRegistration(@NonNull android.net.wifi.WifiManager.NetworkRequestUserSelectionCallback);
-    method public default void onUserSelectionConnectFailure(@NonNull android.net.wifi.WifiConfiguration);
-    method public default void onUserSelectionConnectSuccess(@NonNull android.net.wifi.WifiConfiguration);
-  }
-
-  public static interface WifiManager.NetworkRequestUserSelectionCallback {
-    method public default void reject();
-    method public default void select(@NonNull android.net.wifi.WifiConfiguration);
-  }
-
-  public static interface WifiManager.OnWifiActivityEnergyInfoListener {
-    method public void onWifiActivityEnergyInfo(@Nullable android.os.connectivity.WifiActivityEnergyInfo);
-  }
-
-  public static interface WifiManager.OnWifiUsabilityStatsListener {
-    method public void onWifiUsabilityStats(int, boolean, @NonNull android.net.wifi.WifiUsabilityStatsEntry);
-  }
-
-  public static interface WifiManager.ScoreUpdateObserver {
-    method public void notifyScoreUpdate(int, int);
-    method public void triggerUpdateOfWifiUsabilityStats(int);
-  }
-
-  public static interface WifiManager.SoftApCallback {
-    method public default void onBlockedClientConnecting(@NonNull android.net.wifi.WifiClient, int);
-    method public default void onCapabilityChanged(@NonNull android.net.wifi.SoftApCapability);
-    method public default void onConnectedClientsChanged(@NonNull java.util.List<android.net.wifi.WifiClient>);
-    method public default void onInfoChanged(@NonNull android.net.wifi.SoftApInfo);
-    method public default void onStateChanged(int, int);
-  }
-
-  public static interface WifiManager.TrafficStateCallback {
-    method public void onStateChanged(int);
-    field public static final int DATA_ACTIVITY_IN = 1; // 0x1
-    field public static final int DATA_ACTIVITY_INOUT = 3; // 0x3
-    field public static final int DATA_ACTIVITY_NONE = 0; // 0x0
-    field public static final int DATA_ACTIVITY_OUT = 2; // 0x2
-  }
-
-  public static interface WifiManager.WifiConnectedNetworkScorer {
-    method public void onSetScoreUpdateObserver(@NonNull android.net.wifi.WifiManager.ScoreUpdateObserver);
-    method public void onStart(int);
-    method public void onStop(int);
-  }
-
-  public class WifiNetworkConnectionStatistics implements android.os.Parcelable {
-    ctor public WifiNetworkConnectionStatistics(int, int);
-    ctor public WifiNetworkConnectionStatistics();
-    ctor public WifiNetworkConnectionStatistics(android.net.wifi.WifiNetworkConnectionStatistics);
-    method public int describeContents();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.WifiNetworkConnectionStatistics> CREATOR;
-    field public int numConnection;
-    field public int numUsage;
-  }
-
-  public final class WifiNetworkSuggestion implements android.os.Parcelable {
-    method @NonNull public android.net.wifi.WifiConfiguration getWifiConfiguration();
-  }
-
-  public static final class WifiNetworkSuggestion.Builder {
-    method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_CARRIER_PROVISIONING) public android.net.wifi.WifiNetworkSuggestion.Builder setCarrierId(int);
-  }
-
-  public class WifiScanner {
-    method @Deprecated public void configureWifiChange(int, int, int, int, int, android.net.wifi.WifiScanner.BssidInfo[]);
-    method @Deprecated public void configureWifiChange(android.net.wifi.WifiScanner.WifiChangeSettings);
-    method @NonNull @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public java.util.List<java.lang.Integer> getAvailableChannels(int);
-    method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public boolean getScanResults();
-    method @NonNull @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public java.util.List<android.net.wifi.ScanResult> getSingleScanResults();
-    method @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public void registerScanListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiScanner.ScanListener);
-    method @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public void setScanningEnabled(boolean);
-    method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void startBackgroundScan(android.net.wifi.WifiScanner.ScanSettings, android.net.wifi.WifiScanner.ScanListener);
-    method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void startBackgroundScan(android.net.wifi.WifiScanner.ScanSettings, android.net.wifi.WifiScanner.ScanListener, android.os.WorkSource);
-    method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void startScan(android.net.wifi.WifiScanner.ScanSettings, android.net.wifi.WifiScanner.ScanListener);
-    method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void startScan(android.net.wifi.WifiScanner.ScanSettings, android.net.wifi.WifiScanner.ScanListener, android.os.WorkSource);
-    method @Deprecated public void startTrackingBssids(android.net.wifi.WifiScanner.BssidInfo[], int, android.net.wifi.WifiScanner.BssidListener);
-    method @Deprecated public void startTrackingWifiChange(android.net.wifi.WifiScanner.WifiChangeListener);
-    method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void stopBackgroundScan(android.net.wifi.WifiScanner.ScanListener);
-    method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void stopScan(android.net.wifi.WifiScanner.ScanListener);
-    method @Deprecated public void stopTrackingBssids(android.net.wifi.WifiScanner.BssidListener);
-    method @Deprecated public void stopTrackingWifiChange(android.net.wifi.WifiScanner.WifiChangeListener);
-    method public void unregisterScanListener(@NonNull android.net.wifi.WifiScanner.ScanListener);
-    field public static final int MAX_SCAN_PERIOD_MS = 1024000; // 0xfa000
-    field public static final int MIN_SCAN_PERIOD_MS = 1000; // 0x3e8
-    field public static final int REASON_DUPLICATE_REQEUST = -5; // 0xfffffffb
-    field public static final int REASON_INVALID_LISTENER = -2; // 0xfffffffe
-    field public static final int REASON_INVALID_REQUEST = -3; // 0xfffffffd
-    field public static final int REASON_NOT_AUTHORIZED = -4; // 0xfffffffc
-    field public static final int REASON_SUCCEEDED = 0; // 0x0
-    field public static final int REASON_UNSPECIFIED = -1; // 0xffffffff
-    field @Deprecated public static final int REPORT_EVENT_AFTER_BUFFER_FULL = 0; // 0x0
-    field public static final int REPORT_EVENT_AFTER_EACH_SCAN = 1; // 0x1
-    field public static final int REPORT_EVENT_FULL_SCAN_RESULT = 2; // 0x2
-    field public static final int REPORT_EVENT_NO_BATCH = 4; // 0x4
-    field public static final int SCAN_TYPE_HIGH_ACCURACY = 2; // 0x2
-    field public static final int SCAN_TYPE_LOW_LATENCY = 0; // 0x0
-    field public static final int SCAN_TYPE_LOW_POWER = 1; // 0x1
-    field public static final int WIFI_BAND_24_5_6_GHZ = 11; // 0xb
-    field public static final int WIFI_BAND_24_5_WITH_DFS_6_GHZ = 15; // 0xf
-    field public static final int WIFI_BAND_24_GHZ = 1; // 0x1
-    field public static final int WIFI_BAND_5_GHZ = 2; // 0x2
-    field public static final int WIFI_BAND_5_GHZ_DFS_ONLY = 4; // 0x4
-    field public static final int WIFI_BAND_5_GHZ_WITH_DFS = 6; // 0x6
-    field public static final int WIFI_BAND_6_GHZ = 8; // 0x8
-    field public static final int WIFI_BAND_BOTH = 3; // 0x3
-    field public static final int WIFI_BAND_BOTH_WITH_DFS = 7; // 0x7
-    field public static final int WIFI_BAND_UNSPECIFIED = 0; // 0x0
-  }
-
-  public static interface WifiScanner.ActionListener {
-    method public void onFailure(int, String);
-    method public void onSuccess();
-  }
-
-  @Deprecated public static class WifiScanner.BssidInfo {
-    ctor @Deprecated public WifiScanner.BssidInfo();
-    field @Deprecated public String bssid;
-    field @Deprecated public int frequencyHint;
-    field @Deprecated public int high;
-    field @Deprecated public int low;
-  }
-
-  @Deprecated public static interface WifiScanner.BssidListener extends android.net.wifi.WifiScanner.ActionListener {
-    method @Deprecated public void onFound(android.net.wifi.ScanResult[]);
-    method @Deprecated public void onLost(android.net.wifi.ScanResult[]);
-  }
-
-  public static class WifiScanner.ChannelSpec {
-    ctor public WifiScanner.ChannelSpec(int);
-    field public int frequency;
-  }
-
-  @Deprecated public static class WifiScanner.HotlistSettings implements android.os.Parcelable {
-    ctor @Deprecated public WifiScanner.HotlistSettings();
-    field @Deprecated public int apLostThreshold;
-    field @Deprecated public android.net.wifi.WifiScanner.BssidInfo[] bssidInfos;
-  }
-
-  public static class WifiScanner.ParcelableScanData implements android.os.Parcelable {
-    ctor public WifiScanner.ParcelableScanData(android.net.wifi.WifiScanner.ScanData[]);
-    method public android.net.wifi.WifiScanner.ScanData[] getResults();
-    field public android.net.wifi.WifiScanner.ScanData[] mResults;
-  }
-
-  public static class WifiScanner.ParcelableScanResults implements android.os.Parcelable {
-    ctor public WifiScanner.ParcelableScanResults(android.net.wifi.ScanResult[]);
-    method public android.net.wifi.ScanResult[] getResults();
-    field public android.net.wifi.ScanResult[] mResults;
-  }
-
-  public static class WifiScanner.ScanData implements android.os.Parcelable {
-    ctor public WifiScanner.ScanData(int, int, android.net.wifi.ScanResult[]);
-    ctor public WifiScanner.ScanData(android.net.wifi.WifiScanner.ScanData);
-    method public int getFlags();
-    method public int getId();
-    method public android.net.wifi.ScanResult[] getResults();
-  }
-
-  public static interface WifiScanner.ScanListener extends android.net.wifi.WifiScanner.ActionListener {
-    method public void onFullResult(android.net.wifi.ScanResult);
-    method @Deprecated public void onPeriodChanged(int);
-    method public void onResults(android.net.wifi.WifiScanner.ScanData[]);
-  }
-
-  public static class WifiScanner.ScanSettings implements android.os.Parcelable {
-    ctor public WifiScanner.ScanSettings();
-    field public int band;
-    field public android.net.wifi.WifiScanner.ChannelSpec[] channels;
-    field @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public final java.util.List<android.net.wifi.WifiScanner.ScanSettings.HiddenNetwork> hiddenNetworks;
-    field public boolean hideFromAppOps;
-    field public boolean ignoreLocationSettings;
-    field @Deprecated public int maxPeriodInMs;
-    field @Deprecated public int maxScansToCache;
-    field @Deprecated public int numBssidsPerScan;
-    field @Deprecated public int periodInMs;
-    field @Deprecated public int reportEvents;
-    field @Deprecated public int stepCount;
-    field @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public int type;
-  }
-
-  public static class WifiScanner.ScanSettings.HiddenNetwork {
-    ctor public WifiScanner.ScanSettings.HiddenNetwork(@NonNull String);
-    field @NonNull public final String ssid;
-  }
-
-  @Deprecated public static interface WifiScanner.WifiChangeListener extends android.net.wifi.WifiScanner.ActionListener {
-    method @Deprecated public void onChanging(android.net.wifi.ScanResult[]);
-    method @Deprecated public void onQuiescence(android.net.wifi.ScanResult[]);
-  }
-
-  @Deprecated public static class WifiScanner.WifiChangeSettings implements android.os.Parcelable {
-    ctor @Deprecated public WifiScanner.WifiChangeSettings();
-    field @Deprecated public android.net.wifi.WifiScanner.BssidInfo[] bssidInfos;
-    field @Deprecated public int lostApSampleSize;
-    field @Deprecated public int minApsBreachingThreshold;
-    field @Deprecated public int periodInMs;
-    field @Deprecated public int rssiSampleSize;
-    field @Deprecated public int unchangedSampleSize;
-  }
-
-  public final class WifiUsabilityStatsEntry implements android.os.Parcelable {
-    method public int describeContents();
-    method public int getCellularDataNetworkType();
-    method public int getCellularSignalStrengthDb();
-    method public int getCellularSignalStrengthDbm();
-    method public int getLinkSpeedMbps();
-    method public int getProbeElapsedTimeSinceLastUpdateMillis();
-    method public int getProbeMcsRateSinceLastUpdate();
-    method public int getProbeStatusSinceLastUpdate();
-    method public int getRssi();
-    method public int getRxLinkSpeedMbps();
-    method public long getTimeStampMillis();
-    method public long getTotalBackgroundScanTimeMillis();
-    method public long getTotalBeaconRx();
-    method public long getTotalCcaBusyFreqTimeMillis();
-    method public long getTotalHotspot2ScanTimeMillis();
-    method public long getTotalNanScanTimeMillis();
-    method public long getTotalPnoScanTimeMillis();
-    method public long getTotalRadioOnFreqTimeMillis();
-    method public long getTotalRadioOnTimeMillis();
-    method public long getTotalRadioRxTimeMillis();
-    method public long getTotalRadioTxTimeMillis();
-    method public long getTotalRoamScanTimeMillis();
-    method public long getTotalRxSuccess();
-    method public long getTotalScanTimeMillis();
-    method public long getTotalTxBad();
-    method public long getTotalTxRetries();
-    method public long getTotalTxSuccess();
-    method public boolean isSameRegisteredCell();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.WifiUsabilityStatsEntry> CREATOR;
-    field public static final int PROBE_STATUS_FAILURE = 3; // 0x3
-    field public static final int PROBE_STATUS_NO_PROBE = 1; // 0x1
-    field public static final int PROBE_STATUS_SUCCESS = 2; // 0x2
-    field public static final int PROBE_STATUS_UNKNOWN = 0; // 0x0
-  }
-
-}
-
-package android.net.wifi.aware {
-
-  public class DiscoverySession implements java.lang.AutoCloseable {
-    method @Deprecated public android.net.NetworkSpecifier createNetworkSpecifierPmk(@NonNull android.net.wifi.aware.PeerHandle, @NonNull byte[]);
-  }
-
-  public class WifiAwareSession implements java.lang.AutoCloseable {
-    method public android.net.NetworkSpecifier createNetworkSpecifierPmk(int, @NonNull byte[], @NonNull byte[]);
-  }
-
-}
-
-package android.net.wifi.hotspot2 {
-
-  public final class OsuProvider implements android.os.Parcelable {
-    method public int describeContents();
-    method @Nullable public String getFriendlyName();
-    method @Nullable public android.net.Uri getServerUri();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.OsuProvider> CREATOR;
-  }
-
-  public final class PasspointConfiguration implements android.os.Parcelable {
-    method public int getMeteredOverride();
-    method public boolean isAutojoinEnabled();
-    method public boolean isMacRandomizationEnabled();
-  }
-
-  public abstract class ProvisioningCallback {
-    ctor public ProvisioningCallback();
-    method public abstract void onProvisioningComplete();
-    method public abstract void onProvisioningFailure(int);
-    method public abstract void onProvisioningStatus(int);
-    field public static final int OSU_FAILURE_ADD_PASSPOINT_CONFIGURATION = 22; // 0x16
-    field public static final int OSU_FAILURE_AP_CONNECTION = 1; // 0x1
-    field public static final int OSU_FAILURE_INVALID_URL_FORMAT_FOR_OSU = 8; // 0x8
-    field public static final int OSU_FAILURE_NO_AAA_SERVER_TRUST_ROOT_NODE = 17; // 0x11
-    field public static final int OSU_FAILURE_NO_AAA_TRUST_ROOT_CERTIFICATE = 21; // 0x15
-    field public static final int OSU_FAILURE_NO_OSU_ACTIVITY_FOUND = 14; // 0xe
-    field public static final int OSU_FAILURE_NO_POLICY_SERVER_TRUST_ROOT_NODE = 19; // 0x13
-    field public static final int OSU_FAILURE_NO_PPS_MO = 16; // 0x10
-    field public static final int OSU_FAILURE_NO_REMEDIATION_SERVER_TRUST_ROOT_NODE = 18; // 0x12
-    field public static final int OSU_FAILURE_OSU_PROVIDER_NOT_FOUND = 23; // 0x17
-    field public static final int OSU_FAILURE_PROVISIONING_ABORTED = 6; // 0x6
-    field public static final int OSU_FAILURE_PROVISIONING_NOT_AVAILABLE = 7; // 0x7
-    field public static final int OSU_FAILURE_RETRIEVE_TRUST_ROOT_CERTIFICATES = 20; // 0x14
-    field public static final int OSU_FAILURE_SERVER_CONNECTION = 3; // 0x3
-    field public static final int OSU_FAILURE_SERVER_URL_INVALID = 2; // 0x2
-    field public static final int OSU_FAILURE_SERVER_VALIDATION = 4; // 0x4
-    field public static final int OSU_FAILURE_SERVICE_PROVIDER_VERIFICATION = 5; // 0x5
-    field public static final int OSU_FAILURE_SOAP_MESSAGE_EXCHANGE = 11; // 0xb
-    field public static final int OSU_FAILURE_START_REDIRECT_LISTENER = 12; // 0xc
-    field public static final int OSU_FAILURE_TIMED_OUT_REDIRECT_LISTENER = 13; // 0xd
-    field public static final int OSU_FAILURE_UNEXPECTED_COMMAND_TYPE = 9; // 0x9
-    field public static final int OSU_FAILURE_UNEXPECTED_SOAP_MESSAGE_STATUS = 15; // 0xf
-    field public static final int OSU_FAILURE_UNEXPECTED_SOAP_MESSAGE_TYPE = 10; // 0xa
-    field public static final int OSU_STATUS_AP_CONNECTED = 2; // 0x2
-    field public static final int OSU_STATUS_AP_CONNECTING = 1; // 0x1
-    field public static final int OSU_STATUS_INIT_SOAP_EXCHANGE = 6; // 0x6
-    field public static final int OSU_STATUS_REDIRECT_RESPONSE_RECEIVED = 8; // 0x8
-    field public static final int OSU_STATUS_RETRIEVING_TRUST_ROOT_CERTS = 11; // 0xb
-    field public static final int OSU_STATUS_SECOND_SOAP_EXCHANGE = 9; // 0x9
-    field public static final int OSU_STATUS_SERVER_CONNECTED = 5; // 0x5
-    field public static final int OSU_STATUS_SERVER_CONNECTING = 3; // 0x3
-    field public static final int OSU_STATUS_SERVER_VALIDATED = 4; // 0x4
-    field public static final int OSU_STATUS_THIRD_SOAP_EXCHANGE = 10; // 0xa
-    field public static final int OSU_STATUS_WAITING_FOR_REDIRECT_RESPONSE = 7; // 0x7
-  }
-
-}
-
-package android.net.wifi.p2p {
-
-  public final class WifiP2pGroupList implements android.os.Parcelable {
-    method public int describeContents();
-    method @NonNull public java.util.List<android.net.wifi.p2p.WifiP2pGroup> getGroupList();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.p2p.WifiP2pGroupList> CREATOR;
-  }
-
-  public class WifiP2pManager {
-    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.OVERRIDE_WIFI_CONFIG}) public void deletePersistentGroup(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, int, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener);
-    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void factoryReset(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener);
-    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.READ_WIFI_CREDENTIAL}) public void requestPersistentGroupInfo(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @Nullable android.net.wifi.p2p.WifiP2pManager.PersistentGroupInfoListener);
-    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.OVERRIDE_WIFI_CONFIG}) public void setDeviceName(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @NonNull String, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener);
-    method @RequiresPermission(android.Manifest.permission.CONFIGURE_WIFI_DISPLAY) public void setMiracastMode(int);
-    method @RequiresPermission(android.Manifest.permission.CONFIGURE_WIFI_DISPLAY) public void setWfdInfo(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @NonNull android.net.wifi.p2p.WifiP2pWfdInfo, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener);
-    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.OVERRIDE_WIFI_CONFIG}) public void setWifiP2pChannels(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, int, int, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener);
-    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void startListening(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener);
-    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void stopListening(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener);
-    field public static final String ACTION_WIFI_P2P_PERSISTENT_GROUPS_CHANGED = "android.net.wifi.p2p.action.WIFI_P2P_PERSISTENT_GROUPS_CHANGED";
-    field public static final int MIRACAST_DISABLED = 0; // 0x0
-    field public static final int MIRACAST_SINK = 2; // 0x2
-    field public static final int MIRACAST_SOURCE = 1; // 0x1
-  }
-
-  public static interface WifiP2pManager.PersistentGroupInfoListener {
-    method public void onPersistentGroupInfoAvailable(@NonNull android.net.wifi.p2p.WifiP2pGroupList);
-  }
-
-}
-
-package android.net.wifi.rtt {
-
-  public static final class RangingRequest.Builder {
-    method public android.net.wifi.rtt.RangingRequest.Builder addResponder(@NonNull android.net.wifi.rtt.ResponderConfig);
-  }
-
-  public final class RangingResult implements android.os.Parcelable {
-    method @NonNull public byte[] getLci();
-    method @NonNull public byte[] getLcr();
-  }
-
-  public final class ResponderConfig implements android.os.Parcelable {
-    ctor public ResponderConfig(@NonNull android.net.MacAddress, int, boolean, int, int, int, int, int);
-    ctor public ResponderConfig(@NonNull android.net.wifi.aware.PeerHandle, int, boolean, int, int, int, int, int);
-    method public int describeContents();
-    method public static android.net.wifi.rtt.ResponderConfig fromScanResult(android.net.wifi.ScanResult);
-    method public static android.net.wifi.rtt.ResponderConfig fromWifiAwarePeerHandleWithDefaults(android.net.wifi.aware.PeerHandle);
-    method public static android.net.wifi.rtt.ResponderConfig fromWifiAwarePeerMacAddressWithDefaults(android.net.MacAddress);
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final int CHANNEL_WIDTH_160MHZ = 3; // 0x3
-    field public static final int CHANNEL_WIDTH_20MHZ = 0; // 0x0
-    field public static final int CHANNEL_WIDTH_40MHZ = 1; // 0x1
-    field public static final int CHANNEL_WIDTH_80MHZ = 2; // 0x2
-    field public static final int CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 4; // 0x4
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.rtt.ResponderConfig> CREATOR;
-    field public static final int PREAMBLE_HE = 3; // 0x3
-    field public static final int PREAMBLE_HT = 1; // 0x1
-    field public static final int PREAMBLE_LEGACY = 0; // 0x0
-    field public static final int PREAMBLE_VHT = 2; // 0x2
-    field public static final int RESPONDER_AP = 0; // 0x0
-    field public static final int RESPONDER_AWARE = 4; // 0x4
-    field public static final int RESPONDER_P2P_CLIENT = 3; // 0x3
-    field public static final int RESPONDER_P2P_GO = 2; // 0x2
-    field public static final int RESPONDER_STA = 1; // 0x1
-    field public final int centerFreq0;
-    field public final int centerFreq1;
-    field public final int channelWidth;
-    field public final int frequency;
-    field public final android.net.MacAddress macAddress;
-    field public final android.net.wifi.aware.PeerHandle peerHandle;
-    field public final int preamble;
-    field public final int responderType;
-    field public final boolean supports80211mc;
-  }
-
-  public final class ResponderLocation implements android.os.Parcelable {
-    method public boolean getExtraInfoOnAssociationIndication();
-  }
-
-  public class WifiRttManager {
-    method @RequiresPermission(allOf={android.Manifest.permission.LOCATION_HARDWARE}) public void cancelRanging(@Nullable android.os.WorkSource);
-    method @RequiresPermission(allOf={android.Manifest.permission.LOCATION_HARDWARE, android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.CHANGE_WIFI_STATE, android.Manifest.permission.ACCESS_WIFI_STATE}) public void startRanging(@Nullable android.os.WorkSource, @NonNull android.net.wifi.rtt.RangingRequest, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.rtt.RangingResultCallback);
-  }
-
-}
-
diff --git a/wifi/api/system-lint-baseline.txt b/wifi/api/system-lint-baseline.txt
deleted file mode 100644
index 6547ee8..0000000
--- a/wifi/api/system-lint-baseline.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-// Baseline format: 1.0
-MissingGetterMatchingBuilder: android.net.wifi.rtt.RangingRequest.Builder#addResponder(android.net.wifi.rtt.ResponderConfig):
-    android.net.wifi.rtt.RangingRequest does not declare a `getResponders()` method matching method android.net.wifi.rtt.RangingRequest.Builder.addResponder(android.net.wifi.rtt.ResponderConfig)
-
-MissingNullability: android.net.wifi.rtt.RangingRequest.Builder#addResponder(android.net.wifi.rtt.ResponderConfig):
-
diff --git a/wifi/api/system-removed.txt b/wifi/api/system-removed.txt
deleted file mode 100644
index a2d0dff..0000000
--- a/wifi/api/system-removed.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-// Signature format: 2.0
-package android.net.wifi {
-
-  @Deprecated public class BatchedScanResult implements android.os.Parcelable {
-    ctor public BatchedScanResult();
-    ctor public BatchedScanResult(android.net.wifi.BatchedScanResult);
-    field public final java.util.List<android.net.wifi.ScanResult> scanResults;
-    field public boolean truncated;
-  }
-
-  public final class ScanResult implements android.os.Parcelable {
-    field public boolean untrusted;
-  }
-
-}
-
diff --git a/wifi/jarjar-rules.txt b/wifi/jarjar-rules.txt
deleted file mode 100644
index 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/non-updatable/java/Android.bp b/wifi/java/Android.bp
similarity index 100%
rename from wifi/non-updatable/java/Android.bp
rename to wifi/java/Android.bp
diff --git a/wifi/java/android/net/wifi/AnqpInformationElement.java b/wifi/java/android/net/wifi/AnqpInformationElement.java
deleted file mode 100644
index 47b7129..0000000
--- a/wifi/java/android/net/wifi/AnqpInformationElement.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-/**
- * This object contains the payload of an ANQP element.
- * Vendor id is the vendor ID for the element, or 0 if it is an 802.11(u) element.
- * Hotspot 2.0 uses the WFA Vendor ID which is 0x506f9a
- * The payload contains the bytes of the payload, starting after the length octet(s).
- * @hide
- */
-public class AnqpInformationElement {
-    public static final int HOTSPOT20_VENDOR_ID = 0x506f9a;
-
-    public static final int ANQP_QUERY_LIST = 256;
-    public static final int ANQP_CAPABILITY_LIST = 257;
-    public static final int ANQP_VENUE_NAME = 258;
-    public static final int ANQP_EMERGENCY_NUMBER = 259;
-    public static final int ANQP_NWK_AUTH_TYPE = 260;
-    public static final int ANQP_ROAMING_CONSORTIUM = 261;
-    public static final int ANQP_IP_ADDR_AVAILABILITY = 262;
-    public static final int ANQP_NAI_REALM = 263;
-    public static final int ANQP_3GPP_NETWORK = 264;
-    public static final int ANQP_GEO_LOC = 265;
-    public static final int ANQP_CIVIC_LOC = 266;
-    public static final int ANQP_LOC_URI = 267;
-    public static final int ANQP_DOM_NAME = 268;
-    public static final int ANQP_EMERGENCY_ALERT = 269;
-    public static final int ANQP_TDLS_CAP = 270;
-    public static final int ANQP_EMERGENCY_NAI = 271;
-    public static final int ANQP_NEIGHBOR_REPORT = 272;
-    public static final int ANQP_VENDOR_SPEC = 56797;
-
-    public static final int HS_QUERY_LIST = 1;
-    public static final int HS_CAPABILITY_LIST = 2;
-    public static final int HS_FRIENDLY_NAME = 3;
-    public static final int HS_WAN_METRICS = 4;
-    public static final int HS_CONN_CAPABILITY = 5;
-    public static final int HS_NAI_HOME_REALM_QUERY = 6;
-    public static final int HS_OPERATING_CLASS = 7;
-    public static final int HS_OSU_PROVIDERS = 8;
-    public static final int HS_ICON_REQUEST = 10;
-    public static final int HS_ICON_FILE = 11;
-
-    private final int mVendorId;
-    private final int mElementId;
-    private final byte[] mPayload;
-
-    public AnqpInformationElement(int vendorId, int elementId, byte[] payload) {
-        mVendorId = vendorId;
-        mElementId = elementId;
-        mPayload = payload;
-    }
-
-    public int getVendorId() {
-        return mVendorId;
-    }
-
-    public int getElementId() {
-        return mElementId;
-    }
-
-    public byte[] getPayload() {
-        return mPayload;
-    }
-}
diff --git a/wifi/java/android/net/wifi/BatchedScanResult.java b/wifi/java/android/net/wifi/BatchedScanResult.java
deleted file mode 100644
index ed8845dd..0000000
--- a/wifi/java/android/net/wifi/BatchedScanResult.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import android.os.Parcelable;
-import android.annotation.SystemApi;
-import android.os.Parcel;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Describes the Results of a batched set of wifi scans where the firmware performs many
- * scans and stores the timestamped results without waking the main processor each time.
- * @hide
- * @removed
- */
-@Deprecated
-@SystemApi
-public class BatchedScanResult implements Parcelable {
-    private static final String TAG = "BatchedScanResult";
-
-    /** Inidcates this scan was interrupted and may only have partial results. */
-    public boolean truncated;
-
-    /** The result of this particular scan. */
-    public final List<ScanResult> scanResults = new ArrayList<ScanResult>();
-
-
-    public BatchedScanResult() {
-    }
-
-    public BatchedScanResult(BatchedScanResult source) {
-        truncated = source.truncated;
-        for (ScanResult s : source.scanResults) scanResults.add(new ScanResult(s));
-    }
-
-    @Override
-    public String toString() {
-        StringBuffer sb = new StringBuffer();
-
-        sb.append("BatchedScanResult: ").
-                append("truncated: ").append(String.valueOf(truncated)).
-                append("scanResults: [");
-        for (ScanResult s : scanResults) {
-            sb.append(" <").append(s.toString()).append("> ");
-        }
-        sb.append(" ]");
-        return sb.toString();
-    }
-
-    /** Implement the Parcelable interface {@hide} */
-    public int describeContents() {
-        return 0;
-    }
-
-    /** Implement the Parcelable interface {@hide} */
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(truncated ? 1 : 0);
-        dest.writeInt(scanResults.size());
-        for (ScanResult s : scanResults) {
-            s.writeToParcel(dest, flags);
-        }
-    }
-
-    /** Implement the Parcelable interface {@hide} */
-    public static final @android.annotation.NonNull Creator<BatchedScanResult> CREATOR =
-        new Creator<BatchedScanResult>() {
-            public BatchedScanResult createFromParcel(Parcel in) {
-                BatchedScanResult result = new BatchedScanResult();
-                result.truncated = (in.readInt() == 1);
-                int count = in.readInt();
-                while (count-- > 0) {
-                    result.scanResults.add(ScanResult.CREATOR.createFromParcel(in));
-                }
-                return result;
-            }
-
-            public BatchedScanResult[] newArray(int size) {
-                return new BatchedScanResult[size];
-            }
-        };
-}
diff --git a/wifi/java/android/net/wifi/EAPConstants.java b/wifi/java/android/net/wifi/EAPConstants.java
deleted file mode 100644
index b5f7c94..0000000
--- a/wifi/java/android/net/wifi/EAPConstants.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- * Copyright (c) 2016, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-/**
- * Utility class containing EAP (Extensible Authentication Protocol) Related constants.
- *
- * @hide
- */
-public final class EAPConstants {
-    // Constant definition for EAP types. Refer to
-    // http://www.iana.org/assignments/eap-numbers/eap-numbers.xhtml for more info.
-    public static final int EAP_MD5 = 4;
-    public static final int EAP_OTP = 5;
-    public static final int EAP_RSA = 9;
-    public static final int EAP_KEA = 11;
-    public static final int EAP_KEA_VALIDATE = 12;
-    public static final int EAP_TLS = 13;
-    public static final int EAP_LEAP = 17;
-    public static final int EAP_SIM = 18;
-    public static final int EAP_TTLS = 21;
-    public static final int EAP_AKA = 23;
-    public static final int EAP_3Com = 24;
-    public static final int EAP_MSCHAPv2 = 26;
-    public static final int EAP_PEAP = 29;
-    public static final int EAP_POTP = 32;
-    public static final int EAP_ActiontecWireless = 35;
-    public static final int EAP_HTTPDigest = 38;
-    public static final int EAP_SPEKE = 41;
-    public static final int EAP_MOBAC = 42;
-    public static final int EAP_FAST = 43;
-    public static final int EAP_ZLXEAP = 44;
-    public static final int EAP_Link = 45;
-    public static final int EAP_PAX = 46;
-    public static final int EAP_PSK = 47;
-    public static final int EAP_SAKE = 48;
-    public static final int EAP_IKEv2 = 49;
-    public static final int EAP_AKA_PRIME = 50;
-    public static final int EAP_GPSK = 51;
-    public static final int EAP_PWD = 52;
-    public static final int EAP_EKE = 53;
-    public static final int EAP_TEAP = 55;
-}
diff --git a/wifi/java/android/net/wifi/EasyConnectStatusCallback.java b/wifi/java/android/net/wifi/EasyConnectStatusCallback.java
deleted file mode 100644
index 6c2e6dd..0000000
--- a/wifi/java/android/net/wifi/EasyConnectStatusCallback.java
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.util.SparseArray;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.concurrent.Executor;
-
-/**
- * Easy Connect (DPP) Status Callback. Use this callback to get status updates (success, failure,
- * progress) from the Easy Connect operations.
- */
-public abstract class EasyConnectStatusCallback {
-    /**
-     * Easy Connect R1 Success event: Configuration sent (Configurator mode). This is the last
-     * and final Easy Connect event when either the local device or remote device implement R1.
-     * If both devices implement R2, this event will never be received, and the
-     * {@link #EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_APPLIED} will be received.
-     * @hide
-     */
-    @SystemApi
-    public static final int EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_SENT = 0;
-
-    /**
-     * Easy Connect R2 Success event: Configuration applied by Enrollee (Configurator mode).
-     * This is the last and final Easy Connect event when both the local device and remote device
-     * implement R2. If either the local device or remote device implement R1, this event will never
-     * be received, and the {@link #EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_SENT} will be received.
-     * @hide
-     */
-    @SystemApi
-    public static final int EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_APPLIED = 1;
-
-    /** @hide */
-    @IntDef(prefix = {"EASY_CONNECT_EVENT_SUCCESS_"}, value = {
-            EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_SENT,
-            EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_APPLIED,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface EasyConnectSuccessStatusCode {
-    }
-
-    /**
-     * Easy Connect Progress event: Initial authentication with peer succeeded.
-     * @hide
-     */
-    @SystemApi
-    public static final int EASY_CONNECT_EVENT_PROGRESS_AUTHENTICATION_SUCCESS = 0;
-
-    /**
-     * Easy Connect Progress event: Peer requires more time to process bootstrapping.
-     * @hide
-     */
-    @SystemApi
-    public static final int EASY_CONNECT_EVENT_PROGRESS_RESPONSE_PENDING = 1;
-
-    /**
-     * Easy Connect R2 Progress event: Configuration sent to Enrollee, waiting for response
-     * @hide
-     */
-    @SystemApi
-    public static final int EASY_CONNECT_EVENT_PROGRESS_CONFIGURATION_SENT_WAITING_RESPONSE = 2;
-
-    /**
-     * Easy Connect R2 Progress event: Configuration accepted by Enrollee, waiting for response
-     * @hide
-     */
-    @SystemApi
-    public static final int EASY_CONNECT_EVENT_PROGRESS_CONFIGURATION_ACCEPTED = 3;
-
-    /** @hide */
-    @IntDef(prefix = {"EASY_CONNECT_EVENT_PROGRESS_"}, value = {
-            EASY_CONNECT_EVENT_PROGRESS_AUTHENTICATION_SUCCESS,
-            EASY_CONNECT_EVENT_PROGRESS_RESPONSE_PENDING,
-            EASY_CONNECT_EVENT_PROGRESS_CONFIGURATION_SENT_WAITING_RESPONSE,
-            EASY_CONNECT_EVENT_PROGRESS_CONFIGURATION_ACCEPTED,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface EasyConnectProgressStatusCode {
-    }
-
-    /**
-     * Easy Connect Failure event: Scanned QR code is either not a Easy Connect URI, or the Easy
-     * Connect URI has errors.
-     */
-    public static final int EASY_CONNECT_EVENT_FAILURE_INVALID_URI = -1;
-
-    /**
-     * Easy Connect Failure event: Bootstrapping/Authentication initialization process failure.
-     */
-    public static final int EASY_CONNECT_EVENT_FAILURE_AUTHENTICATION = -2;
-
-    /**
-     * Easy Connect Failure event: Both devices are implementing the same role and are incompatible.
-     */
-    public static final int EASY_CONNECT_EVENT_FAILURE_NOT_COMPATIBLE = -3;
-
-    /**
-     * Easy Connect Failure event: Configuration process has failed due to malformed message.
-     */
-    public static final int EASY_CONNECT_EVENT_FAILURE_CONFIGURATION = -4;
-
-    /**
-     * Easy Connect Failure event: Easy Connect request while in another Easy Connect exchange.
-     */
-    public static final int EASY_CONNECT_EVENT_FAILURE_BUSY = -5;
-
-    /**
-     * Easy Connect Failure event: No response from the peer.
-     */
-    public static final int EASY_CONNECT_EVENT_FAILURE_TIMEOUT = -6;
-
-    /**
-     * Easy Connect Failure event: General protocol failure.
-     */
-    public static final int EASY_CONNECT_EVENT_FAILURE_GENERIC = -7;
-
-    /**
-     * Easy Connect Failure event: Feature or option is not supported.
-     */
-    public static final int EASY_CONNECT_EVENT_FAILURE_NOT_SUPPORTED = -8;
-
-    /**
-     * Easy Connect Failure event: Invalid network provided to Easy Connect configurator.
-     * Network must either be WPA3-Personal (SAE) or WPA2-Personal (PSK).
-     */
-    public static final int EASY_CONNECT_EVENT_FAILURE_INVALID_NETWORK = -9;
-
-    /**
-     * Easy Connect R2 Failure event: Enrollee cannot find the network.
-     */
-    public static final int EASY_CONNECT_EVENT_FAILURE_CANNOT_FIND_NETWORK = -10;
-
-    /**
-     * Easy Connect R2 Failure event: Enrollee failed to authenticate with the network.
-     */
-    public static final int EASY_CONNECT_EVENT_FAILURE_ENROLLEE_AUTHENTICATION = -11;
-
-    /**
-     * Easy Connect R2 Failure event: Enrollee rejected the configuration.
-     */
-    public static final int EASY_CONNECT_EVENT_FAILURE_ENROLLEE_REJECTED_CONFIGURATION = -12;
-
-    /** @hide */
-    @IntDef(prefix = {"EASY_CONNECT_EVENT_FAILURE_"}, value = {
-            EASY_CONNECT_EVENT_FAILURE_INVALID_URI,
-            EASY_CONNECT_EVENT_FAILURE_AUTHENTICATION,
-            EASY_CONNECT_EVENT_FAILURE_NOT_COMPATIBLE,
-            EASY_CONNECT_EVENT_FAILURE_CONFIGURATION,
-            EASY_CONNECT_EVENT_FAILURE_BUSY,
-            EASY_CONNECT_EVENT_FAILURE_TIMEOUT,
-            EASY_CONNECT_EVENT_FAILURE_GENERIC,
-            EASY_CONNECT_EVENT_FAILURE_NOT_SUPPORTED,
-            EASY_CONNECT_EVENT_FAILURE_INVALID_NETWORK,
-            EASY_CONNECT_EVENT_FAILURE_CANNOT_FIND_NETWORK,
-            EASY_CONNECT_EVENT_FAILURE_ENROLLEE_AUTHENTICATION,
-            EASY_CONNECT_EVENT_FAILURE_ENROLLEE_REJECTED_CONFIGURATION,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface EasyConnectFailureStatusCode {
-    }
-
-    /** @hide */
-    @SystemApi
-    public EasyConnectStatusCallback() {
-        // Fully-static utility classes must not have constructor
-    }
-
-    /**
-     * Called when local Easy Connect Enrollee successfully receives a new Wi-Fi configuration from
-     * the
-     * peer Easy Connect configurator. This callback marks the successful end of the Easy Connect
-     * current Easy Connect
-     * session, and no further callbacks will be called. This callback is the successful outcome
-     * of a Easy Connect flow starting with
-     * {@link WifiManager#startEasyConnectAsEnrolleeInitiator(String, Executor,
-     * EasyConnectStatusCallback)} .
-     *
-     * @param newNetworkId New Wi-Fi configuration with a network ID received from the configurator
-     * @hide
-     */
-    @SystemApi
-    public abstract void onEnrolleeSuccess(int newNetworkId);
-
-    /**
-     * Called when a Easy Connect success event takes place, except for when configuration is
-     * received from an external Configurator. The callback onSuccessConfigReceived will be used in
-     * this case. This callback marks the successful end of the current Easy Connect session, and no
-     * further callbacks will be called. This callback is the successful outcome of a Easy Connect
-     * flow starting with {@link WifiManager#startEasyConnectAsConfiguratorInitiator(String, int,
-     * int, Executor,EasyConnectStatusCallback)}.
-     *
-     * @param code Easy Connect success status code.
-     * @hide
-     */
-    @SystemApi
-    public abstract void onConfiguratorSuccess(@EasyConnectSuccessStatusCode int code);
-
-    /**
-     * Called when a Easy Connect Failure event takes place. This callback marks the unsuccessful
-     * end of the current Easy Connect session, and no further callbacks will be called.
-     *
-     * @param code Easy Connect failure status code.
-     * @hide
-     */
-    @SystemApi
-    public void onFailure(@EasyConnectFailureStatusCode int code) {}
-
-    /**
-     * Called when a Easy Connect Failure event takes place. This callback marks the unsuccessful
-     * end of the current Easy Connect session, and no further callbacks will be called.
-     *
-     * Note: Easy Connect (DPP) R2, provides additional details for the Configurator when the
-     * remote Enrollee is unable to connect to a network. The ssid, channelList and bandList
-     * inputs are initialized only for the EASY_CONNECT_EVENT_FAILURE_CANNOT_FIND_NETWORK failure
-     * code, and the ssid and bandList are initialized for the
-     * EASY_CONNECT_EVENT_FAILURE_ENROLLEE_AUTHENTICATION failure code.
-     *
-     * @param code Easy Connect failure status code.
-     * @param ssid SSID of the network the Enrollee tried to connect to.
-     * @param channelListArray List of Global Operating classes and channel sets the Enrollee used
-     *                         to scan to find the network, see the "DPP Connection Status Object"
-     *                         section in the specification for the format, and Table E-4 in
-     *                         IEEE Std 802.11-2016 - Global operating classes for more details.
-     *                         The sparse array key is the Global Operating class, and the value
-     *                         is an integer array of Wi-Fi channels.
-     * @param operatingClassArray Array of bands the Enrollee supports as expressed as the Global
-     *                            Operating Class, see Table E-4 in IEEE Std 802.11-2016 - Global
-     *                            operating classes.
-     * @hide
-     */
-    @SystemApi
-    public void onFailure(@EasyConnectFailureStatusCode int code, @Nullable String ssid,
-            @NonNull SparseArray<int[]> channelListArray, @NonNull int[] operatingClassArray) {
-        onFailure(code);
-    }
-
-    /**
-     * Called when Easy Connect events that indicate progress take place. Can be used by UI elements
-     * to show progress.
-     *
-     * @param code Easy Connect progress status code.
-     * @hide
-     */
-    @SystemApi
-    public abstract void onProgress(@EasyConnectProgressStatusCode int code);
-}
diff --git a/wifi/java/android/net/wifi/IActionListener.aidl b/wifi/java/android/net/wifi/IActionListener.aidl
deleted file mode 100644
index faa0901..0000000
--- a/wifi/java/android/net/wifi/IActionListener.aidl
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-/**
- * Interface for generic wifi callbacks.
- * @hide
- */
-oneway interface IActionListener
-{
-    void onSuccess();
-    void onFailure(int reason);
-}
diff --git a/wifi/java/android/net/wifi/IDppCallback.aidl b/wifi/java/android/net/wifi/IDppCallback.aidl
deleted file mode 100644
index d7a958a..0000000
--- a/wifi/java/android/net/wifi/IDppCallback.aidl
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-/**
- * Interface for DPP callback.
- *
- * @hide
- */
-oneway interface IDppCallback
-{
-    /**
-     * Called when local DPP Enrollee successfully receives a new Wi-Fi configuratrion from the
-     * peer DPP configurator.
-     */
-    void onSuccessConfigReceived(int newNetworkId);
-
-    /**
-     * Called when DPP success events take place, except for when configuration is received from
-     * an external Configurator. The callback onSuccessConfigReceived will be used in this case.
-     */
-    void onSuccess(int status);
-
-    /**
-     * Called when DPP Failure events take place.
-     */
-    void onFailure(int status, String ssid, String channelList, in int[] bandArray);
-
-    /**
-     * Called when DPP events that indicate progress take place. Can be used by UI elements
-     * to show progress.
-     */
-    void onProgress(int status);
-}
diff --git a/wifi/java/android/net/wifi/ILocalOnlyHotspotCallback.aidl b/wifi/java/android/net/wifi/ILocalOnlyHotspotCallback.aidl
deleted file mode 100644
index b567f29..0000000
--- a/wifi/java/android/net/wifi/ILocalOnlyHotspotCallback.aidl
+++ /dev/null
@@ -1,30 +0,0 @@
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import android.net.wifi.SoftApConfiguration;
-
-/**
- * Communicates LOHS status back to the application process.
- *
- * @hide
- */
-oneway interface ILocalOnlyHotspotCallback {
-    void onHotspotStarted(in SoftApConfiguration config);
-    void onHotspotStopped();
-    void onHotspotFailed(int reason);
-}
diff --git a/wifi/java/android/net/wifi/INetworkRequestMatchCallback.aidl b/wifi/java/android/net/wifi/INetworkRequestMatchCallback.aidl
deleted file mode 100644
index d14ec57..0000000
--- a/wifi/java/android/net/wifi/INetworkRequestMatchCallback.aidl
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import android.net.wifi.INetworkRequestUserSelectionCallback;
-import android.net.wifi.ScanResult;
-import android.net.wifi.WifiConfiguration;
-
-/**
- * Interface for network request match callback.
- *
- * @hide
- */
-oneway interface INetworkRequestMatchCallback
-{
-   void onUserSelectionCallbackRegistration(in INetworkRequestUserSelectionCallback userSelectionCallback);
-
-   void onAbort();
-
-   void onMatch(in List<ScanResult> scanResults);
-
-   void onUserSelectionConnectSuccess(in WifiConfiguration wificonfiguration);
-
-   void onUserSelectionConnectFailure(in WifiConfiguration wificonfiguration);
-}
diff --git a/wifi/java/android/net/wifi/INetworkRequestUserSelectionCallback.aidl b/wifi/java/android/net/wifi/INetworkRequestUserSelectionCallback.aidl
deleted file mode 100644
index 524cefb..0000000
--- a/wifi/java/android/net/wifi/INetworkRequestUserSelectionCallback.aidl
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import android.net.wifi.WifiConfiguration;
-
-/**
- * Interface for providing user selection in response to
- * network request match callback.
- * @hide
- */
-oneway interface INetworkRequestUserSelectionCallback
-{
-   void select(in WifiConfiguration wificonfiguration);
-
-   void reject();
-}
diff --git a/wifi/java/android/net/wifi/IOnWifiActivityEnergyInfoListener.aidl b/wifi/java/android/net/wifi/IOnWifiActivityEnergyInfoListener.aidl
deleted file mode 100644
index 7e25fd8a..0000000
--- a/wifi/java/android/net/wifi/IOnWifiActivityEnergyInfoListener.aidl
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import android.os.connectivity.WifiActivityEnergyInfo;
-
-/**
- * Interface for Wi-Fi activity energy info listener.
- *
- * @hide
- */
-oneway interface IOnWifiActivityEnergyInfoListener
-{
-    /**
-     * Service to manager callback providing current Wi-Fi activity energy info.
-     * @param info the Wi-Fi activity energy info
-     */
-    void onWifiActivityEnergyInfo(in WifiActivityEnergyInfo info);
-}
diff --git a/wifi/java/android/net/wifi/IOnWifiUsabilityStatsListener.aidl b/wifi/java/android/net/wifi/IOnWifiUsabilityStatsListener.aidl
deleted file mode 100644
index 4687f30..0000000
--- a/wifi/java/android/net/wifi/IOnWifiUsabilityStatsListener.aidl
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import android.net.wifi.WifiUsabilityStatsEntry;
-
-/**
- * Interface for Wi-Fi usability stats listener.
- *
- * @hide
- */
-oneway interface IOnWifiUsabilityStatsListener
-{
-    /**
-     * Service to manager callback providing current Wi-Fi usability stats.
-     *
-     * @param seqNum The sequence number of stats, used to derive the timing of updated Wi-Fi
-     *               usability statistics, set by framework and shall be incremented by one
-     *               after each update.
-     * @param isSameBssidAndFreq The flag to indicate whether the BSSID and the frequency of
-     *                           network stays the same or not relative to the last update of
-     *                           Wi-Fi usability stats.
-     * @param stats The updated Wi-Fi usability statistics.
-     */
-    void onWifiUsabilityStats(int seqNum, boolean isSameBssidAndFreq,
-            in WifiUsabilityStatsEntry stats);
-}
diff --git a/wifi/java/android/net/wifi/IScanResultsCallback.aidl b/wifi/java/android/net/wifi/IScanResultsCallback.aidl
deleted file mode 100644
index 56f6025..0000000
--- a/wifi/java/android/net/wifi/IScanResultsCallback.aidl
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-/**
- * Interface for Wi-Fi scan result available callback.
- *
- * @hide
- */
-oneway interface IScanResultsCallback
-{
-    void onScanResultsAvailable();
-}
diff --git a/wifi/java/android/net/wifi/IScanResultsListener.aidl b/wifi/java/android/net/wifi/IScanResultsListener.aidl
deleted file mode 100644
index e7eaddd..0000000
--- a/wifi/java/android/net/wifi/IScanResultsListener.aidl
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-/** @hide */
-
-oneway interface IScanResultsListener
-{
-    void onScanResultsAvailable();
-}
diff --git a/wifi/java/android/net/wifi/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/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 5388367..0000000
--- a/wifi/java/android/net/wifi/WifiInfo.java
+++ /dev/null
@@ -1,1051 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import android.annotation.IntRange;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.net.NetworkInfo.DetailedState;
-import android.os.Build;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-
-import com.android.net.module.util.Inet4AddressUtils;
-
-import java.net.Inet4Address;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.EnumMap;
-import java.util.Locale;
-
-/**
- * Describes the state of any Wi-Fi connection that is active or
- * is in the process of being set up.
- */
-public class WifiInfo implements Parcelable {
-    private static final String TAG = "WifiInfo";
-    /**
-     * This is the map described in the Javadoc comment above. The positions
-     * of the elements of the array must correspond to the ordinal values
-     * of <code>DetailedState</code>.
-     */
-    private static final EnumMap<SupplicantState, DetailedState> stateMap =
-            new EnumMap<SupplicantState, DetailedState>(SupplicantState.class);
-
-    /**
-     * Default MAC address reported to a client that does not have the
-     * android.permission.LOCAL_MAC_ADDRESS permission.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final String DEFAULT_MAC_ADDRESS = "02:00:00:00:00:00";
-
-    static {
-        stateMap.put(SupplicantState.DISCONNECTED, DetailedState.DISCONNECTED);
-        stateMap.put(SupplicantState.INTERFACE_DISABLED, DetailedState.DISCONNECTED);
-        stateMap.put(SupplicantState.INACTIVE, DetailedState.IDLE);
-        stateMap.put(SupplicantState.SCANNING, DetailedState.SCANNING);
-        stateMap.put(SupplicantState.AUTHENTICATING, DetailedState.CONNECTING);
-        stateMap.put(SupplicantState.ASSOCIATING, DetailedState.CONNECTING);
-        stateMap.put(SupplicantState.ASSOCIATED, DetailedState.CONNECTING);
-        stateMap.put(SupplicantState.FOUR_WAY_HANDSHAKE, DetailedState.AUTHENTICATING);
-        stateMap.put(SupplicantState.GROUP_HANDSHAKE, DetailedState.AUTHENTICATING);
-        stateMap.put(SupplicantState.COMPLETED, DetailedState.OBTAINING_IPADDR);
-        stateMap.put(SupplicantState.DORMANT, DetailedState.DISCONNECTED);
-        stateMap.put(SupplicantState.UNINITIALIZED, DetailedState.IDLE);
-        stateMap.put(SupplicantState.INVALID, DetailedState.FAILED);
-    }
-
-    private SupplicantState mSupplicantState;
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
-    private String mBSSID;
-    @UnsupportedAppUsage
-    private WifiSsid mWifiSsid;
-    private int mNetworkId;
-
-    /**
-     * Used to indicate that the RSSI is invalid, for example if no RSSI measurements are available
-     * yet.
-     * @hide
-     */
-    @SystemApi
-    public static final int INVALID_RSSI = -127;
-
-    /** @hide **/
-    public static final int MIN_RSSI = -126;
-
-    /** @hide **/
-    public static final int MAX_RSSI = 200;
-
-
-    /**
-     * Received Signal Strength Indicator
-     */
-    private int mRssi;
-
-    /**
-     * Wi-Fi standard for the connection
-     */
-    private @WifiAnnotations.WifiStandard int mWifiStandard;
-
-    /**
-     * The unit in which links speeds are expressed.
-     */
-    public static final String LINK_SPEED_UNITS = "Mbps";
-    private int mLinkSpeed;
-
-    /**
-     * Constant for unknown link speed.
-     */
-    public static final int LINK_SPEED_UNKNOWN = -1;
-
-    /**
-     * Tx(transmit) Link speed in Mbps
-     */
-    private int mTxLinkSpeed;
-
-    /**
-     * Max supported Tx(transmit) link speed in Mbps
-     */
-    private int mMaxSupportedTxLinkSpeed;
-
-    /**
-     * Rx(receive) Link speed in Mbps
-     */
-    private int mRxLinkSpeed;
-
-    /**
-     * Max supported Rx(receive) link speed in Mbps
-     */
-    private int mMaxSupportedRxLinkSpeed;
-
-    /**
-     * Frequency in MHz
-     */
-    public static final String FREQUENCY_UNITS = "MHz";
-    private int mFrequency;
-
-    @UnsupportedAppUsage
-    private InetAddress mIpAddress;
-    @UnsupportedAppUsage
-    private String mMacAddress = DEFAULT_MAC_ADDRESS;
-
-    /**
-     * Whether the network is ephemeral or not.
-     */
-    private boolean mEphemeral;
-
-    /**
-     * Whether the network is trusted or not.
-     */
-    private boolean mTrusted;
-
-    /**
-     * OSU (Online Sign Up) AP for Passpoint R2.
-     */
-    private boolean mOsuAp;
-
-    /**
-     * Fully qualified domain name of a Passpoint configuration
-     */
-    private String mFqdn;
-
-    /**
-     * Name of Passpoint credential provider
-     */
-    private String mProviderFriendlyName;
-
-    /**
-     * If connected to a network suggestion or specifier, store the package name of the app,
-     * else null.
-     */
-    private String mRequestingPackageName;
-
-    /**
-     * Running total count of lost (not ACKed) transmitted unicast data packets.
-     * @hide
-     */
-    public long txBad;
-    /**
-     * Running total count of transmitted unicast data retry packets.
-     * @hide
-     */
-    public long txRetries;
-    /**
-     * Running total count of successfully transmitted (ACKed) unicast data packets.
-     * @hide
-     */
-    public long txSuccess;
-    /**
-     * Running total count of received unicast data packets.
-     * @hide
-     */
-    public long rxSuccess;
-
-    private double mLostTxPacketsPerSecond;
-
-    /**
-     * Average rate of lost transmitted packets, in units of packets per second.
-     * @hide
-     */
-    @SystemApi
-    public double getLostTxPacketsPerSecond() {
-        return mLostTxPacketsPerSecond;
-    }
-
-    /** @hide */
-    public void setLostTxPacketsPerSecond(double lostTxPacketsPerSecond) {
-        mLostTxPacketsPerSecond = lostTxPacketsPerSecond;
-    }
-
-    private double mTxRetriedTxPacketsPerSecond;
-
-    /**
-     * Average rate of transmitted retry packets, in units of packets per second.
-     * @hide
-     */
-    @SystemApi
-    public double getRetriedTxPacketsPerSecond() {
-        return mTxRetriedTxPacketsPerSecond;
-    }
-
-    /** @hide */
-    public void setRetriedTxPacketsRate(double txRetriedTxPacketsPerSecond) {
-        mTxRetriedTxPacketsPerSecond = txRetriedTxPacketsPerSecond;
-    }
-
-    private double mSuccessfulTxPacketsPerSecond;
-
-    /**
-     * Average rate of successfully transmitted unicast packets, in units of packets per second.
-     * @hide
-     */
-    @SystemApi
-    public double getSuccessfulTxPacketsPerSecond() {
-        return mSuccessfulTxPacketsPerSecond;
-    }
-
-    /** @hide */
-    public void setSuccessfulTxPacketsPerSecond(double successfulTxPacketsPerSecond) {
-        mSuccessfulTxPacketsPerSecond = successfulTxPacketsPerSecond;
-    }
-
-    private double mSuccessfulRxPacketsPerSecond;
-
-    /**
-     * Average rate of received unicast data packets, in units of packets per second.
-     * @hide
-     */
-    @SystemApi
-    public double getSuccessfulRxPacketsPerSecond() {
-        return mSuccessfulRxPacketsPerSecond;
-    }
-
-    /** @hide */
-    public void setSuccessfulRxPacketsPerSecond(double successfulRxPacketsPerSecond) {
-        mSuccessfulRxPacketsPerSecond = successfulRxPacketsPerSecond;
-    }
-
-    /** @hide */
-    @UnsupportedAppUsage
-    public int score;
-
-    /**
-     * The current Wifi score.
-     * NOTE: this value should only be used for debugging purposes. Do not rely on this value for
-     * any computations. The meaning of this value can and will change at any time without warning.
-     * @hide
-     */
-    @SystemApi
-    public int getScore() {
-        return score;
-    }
-
-    /** @hide */
-    public void setScore(int score) {
-        this.score = score;
-    }
-
-    /**
-     * Flag indicating that AP has hinted that upstream connection is metered,
-     * and sensitive to heavy data transfers.
-     */
-    private boolean mMeteredHint;
-
-    /**
-     * Passpoint unique key
-     */
-    private String mPasspointUniqueId;
-
-    /** @hide */
-    @UnsupportedAppUsage
-    public WifiInfo() {
-        mWifiSsid = null;
-        mBSSID = null;
-        mNetworkId = -1;
-        mSupplicantState = SupplicantState.UNINITIALIZED;
-        mRssi = INVALID_RSSI;
-        mLinkSpeed = LINK_SPEED_UNKNOWN;
-        mFrequency = -1;
-    }
-
-    /** @hide */
-    public void reset() {
-        setInetAddress(null);
-        setBSSID(null);
-        setSSID(null);
-        setNetworkId(-1);
-        setRssi(INVALID_RSSI);
-        setLinkSpeed(LINK_SPEED_UNKNOWN);
-        setTxLinkSpeedMbps(LINK_SPEED_UNKNOWN);
-        setRxLinkSpeedMbps(LINK_SPEED_UNKNOWN);
-        setMaxSupportedTxLinkSpeedMbps(LINK_SPEED_UNKNOWN);
-        setMaxSupportedRxLinkSpeedMbps(LINK_SPEED_UNKNOWN);
-        setFrequency(-1);
-        setMeteredHint(false);
-        setEphemeral(false);
-        setOsuAp(false);
-        setRequestingPackageName(null);
-        setFQDN(null);
-        setProviderFriendlyName(null);
-        setPasspointUniqueId(null);
-        txBad = 0;
-        txSuccess = 0;
-        rxSuccess = 0;
-        txRetries = 0;
-        mLostTxPacketsPerSecond = 0;
-        mSuccessfulTxPacketsPerSecond = 0;
-        mSuccessfulRxPacketsPerSecond = 0;
-        mTxRetriedTxPacketsPerSecond = 0;
-        score = 0;
-    }
-
-    /**
-     * Copy constructor
-     * @hide
-     */
-    public WifiInfo(WifiInfo source) {
-        if (source != null) {
-            mSupplicantState = source.mSupplicantState;
-            mBSSID = source.mBSSID;
-            mWifiSsid = source.mWifiSsid;
-            mNetworkId = source.mNetworkId;
-            mRssi = source.mRssi;
-            mLinkSpeed = source.mLinkSpeed;
-            mTxLinkSpeed = source.mTxLinkSpeed;
-            mRxLinkSpeed = source.mRxLinkSpeed;
-            mFrequency = source.mFrequency;
-            mIpAddress = source.mIpAddress;
-            mMacAddress = source.mMacAddress;
-            mMeteredHint = source.mMeteredHint;
-            mEphemeral = source.mEphemeral;
-            mTrusted = source.mTrusted;
-            mRequestingPackageName =
-                    source.mRequestingPackageName;
-            mOsuAp = source.mOsuAp;
-            mFqdn = source.mFqdn;
-            mProviderFriendlyName = source.mProviderFriendlyName;
-            txBad = source.txBad;
-            txRetries = source.txRetries;
-            txSuccess = source.txSuccess;
-            rxSuccess = source.rxSuccess;
-            mLostTxPacketsPerSecond = source.mLostTxPacketsPerSecond;
-            mTxRetriedTxPacketsPerSecond = source.mTxRetriedTxPacketsPerSecond;
-            mSuccessfulTxPacketsPerSecond = source.mSuccessfulTxPacketsPerSecond;
-            mSuccessfulRxPacketsPerSecond = source.mSuccessfulRxPacketsPerSecond;
-            score = source.score;
-            mWifiStandard = source.mWifiStandard;
-            mMaxSupportedTxLinkSpeed = source.mMaxSupportedTxLinkSpeed;
-            mMaxSupportedRxLinkSpeed = source.mMaxSupportedRxLinkSpeed;
-            mPasspointUniqueId = source.mPasspointUniqueId;
-        }
-    }
-
-    /** Builder for WifiInfo */
-    public static final class Builder {
-        private final WifiInfo mWifiInfo = new WifiInfo();
-
-        /**
-         * Set the SSID, in the form of a raw byte array.
-         * @see WifiInfo#getSSID()
-         */
-        @NonNull
-        public Builder setSsid(@NonNull byte[] ssid) {
-            mWifiInfo.setSSID(WifiSsid.createFromByteArray(ssid));
-            return this;
-        }
-
-        /**
-         * Set the BSSID.
-         * @see WifiInfo#getBSSID()
-         */
-        @NonNull
-        public Builder setBssid(@NonNull String bssid) {
-            mWifiInfo.setBSSID(bssid);
-            return this;
-        }
-
-        /**
-         * Set the RSSI, in dBm.
-         * @see WifiInfo#getRssi()
-         */
-        @NonNull
-        public Builder setRssi(int rssi) {
-            mWifiInfo.setRssi(rssi);
-            return this;
-        }
-
-        /**
-         * Set the network ID.
-         * @see WifiInfo#getNetworkId()
-         */
-        @NonNull
-        public Builder setNetworkId(int networkId) {
-            mWifiInfo.setNetworkId(networkId);
-            return this;
-        }
-
-        /**
-         * Build a WifiInfo object.
-         */
-        @NonNull
-        public WifiInfo build() {
-            return new WifiInfo(mWifiInfo);
-        }
-    }
-
-    /** @hide */
-    public void setSSID(WifiSsid wifiSsid) {
-        mWifiSsid = wifiSsid;
-    }
-
-    /**
-     * Returns the service set identifier (SSID) of the current 802.11 network.
-     * <p>
-     * If the SSID can be decoded as UTF-8, it will be returned surrounded by double
-     * quotation marks. Otherwise, it is returned as a string of hex digits.
-     * The SSID may be {@link WifiManager#UNKNOWN_SSID}, if there is no network currently connected
-     * or if the caller has insufficient permissions to access the SSID.
-     * </p>
-     * <p>
-     * Prior to {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}, this method
-     * always returned the SSID with no quotes around it.
-     * </p>
-     *
-     * @return the SSID.
-     */
-    public String getSSID() {
-        if (mWifiSsid != null) {
-            String unicode = mWifiSsid.toString();
-            if (!TextUtils.isEmpty(unicode)) {
-                return "\"" + unicode + "\"";
-            } else {
-                String hex = mWifiSsid.getHexString();
-                return (hex != null) ? hex : WifiManager.UNKNOWN_SSID;
-            }
-        }
-        return WifiManager.UNKNOWN_SSID;
-    }
-
-    /** @hide */
-    @UnsupportedAppUsage
-    public WifiSsid getWifiSsid() {
-        return mWifiSsid;
-    }
-
-    /** @hide */
-    @UnsupportedAppUsage
-    public void setBSSID(String BSSID) {
-        mBSSID = BSSID;
-    }
-
-    /**
-     * Return the basic service set identifier (BSSID) of the current access point.
-     * <p>
-     * The BSSID may be
-     * <lt>{@code null}, if there is no network currently connected.</lt>
-     * <lt>{@code "02:00:00:00:00:00"}, if the caller has insufficient permissions to access the
-     * BSSID.<lt>
-     * </p>
-     *
-     * @return the BSSID, in the form of a six-byte MAC address: {@code XX:XX:XX:XX:XX:XX}
-     */
-    public String getBSSID() {
-        return mBSSID;
-    }
-
-    /**
-     * Returns the received signal strength indicator of the current 802.11
-     * network, in dBm.
-     *
-     * <p>Use {@link android.net.wifi.WifiManager#calculateSignalLevel} to convert this number into
-     * an absolute signal level which can be displayed to a user.
-     *
-     * @return the RSSI.
-     */
-    public int getRssi() {
-        return mRssi;
-    }
-
-    /** @hide */
-    @UnsupportedAppUsage
-    public void setRssi(int rssi) {
-        if (rssi < INVALID_RSSI)
-            rssi = INVALID_RSSI;
-        if (rssi > MAX_RSSI)
-            rssi = MAX_RSSI;
-        mRssi = rssi;
-    }
-
-    /**
-     * Sets the Wi-Fi standard
-     * @hide
-     */
-    public void setWifiStandard(@WifiAnnotations.WifiStandard int wifiStandard) {
-        mWifiStandard = wifiStandard;
-    }
-
-    /**
-     * Get connection Wi-Fi standard
-     * @return the connection Wi-Fi standard
-     */
-    public @WifiAnnotations.WifiStandard int getWifiStandard() {
-        return mWifiStandard;
-    }
-
-    /**
-     * Returns the current link speed in {@link #LINK_SPEED_UNITS}.
-     * @return the link speed or {@link #LINK_SPEED_UNKNOWN} if link speed is unknown.
-     * @see #LINK_SPEED_UNITS
-     * @see #LINK_SPEED_UNKNOWN
-     */
-    public int getLinkSpeed() {
-        return mLinkSpeed;
-    }
-
-    /** @hide */
-    @UnsupportedAppUsage
-    public void setLinkSpeed(int linkSpeed) {
-        mLinkSpeed = linkSpeed;
-    }
-
-    /**
-     * Returns the current transmit link speed in Mbps.
-     * @return the Tx link speed or {@link #LINK_SPEED_UNKNOWN} if link speed is unknown.
-     * @see #LINK_SPEED_UNKNOWN
-     */
-    @IntRange(from = -1)
-    public int getTxLinkSpeedMbps() {
-        return mTxLinkSpeed;
-    }
-
-    /**
-     * Returns the maximum supported transmit link speed in Mbps
-     * @return the max supported tx link speed or {@link #LINK_SPEED_UNKNOWN} if link speed is
-     * unknown. @see #LINK_SPEED_UNKNOWN
-     */
-    public int getMaxSupportedTxLinkSpeedMbps() {
-        return mMaxSupportedTxLinkSpeed;
-    }
-
-    /**
-     * Update the last transmitted packet bit rate in Mbps.
-     * @hide
-     */
-    public void setTxLinkSpeedMbps(int txLinkSpeed) {
-        mTxLinkSpeed = txLinkSpeed;
-    }
-
-    /**
-     * Set the maximum supported transmit link speed in Mbps
-     * @hide
-     */
-    public void setMaxSupportedTxLinkSpeedMbps(int maxSupportedTxLinkSpeed) {
-        mMaxSupportedTxLinkSpeed = maxSupportedTxLinkSpeed;
-    }
-
-    /**
-     * Returns the current receive link speed in Mbps.
-     * @return the Rx link speed or {@link #LINK_SPEED_UNKNOWN} if link speed is unknown.
-     * @see #LINK_SPEED_UNKNOWN
-     */
-    @IntRange(from = -1)
-    public int getRxLinkSpeedMbps() {
-        return mRxLinkSpeed;
-    }
-
-    /**
-     * Returns the maximum supported receive link speed in Mbps
-     * @return the max supported Rx link speed or {@link #LINK_SPEED_UNKNOWN} if link speed is
-     * unknown. @see #LINK_SPEED_UNKNOWN
-     */
-    public int getMaxSupportedRxLinkSpeedMbps() {
-        return mMaxSupportedRxLinkSpeed;
-    }
-
-    /**
-     * Update the last received packet bit rate in Mbps.
-     * @hide
-     */
-    public void setRxLinkSpeedMbps(int rxLinkSpeed) {
-        mRxLinkSpeed = rxLinkSpeed;
-    }
-
-    /**
-     * Set the maximum supported receive link speed in Mbps
-     * @hide
-     */
-    public void setMaxSupportedRxLinkSpeedMbps(int maxSupportedRxLinkSpeed) {
-        mMaxSupportedRxLinkSpeed = maxSupportedRxLinkSpeed;
-    }
-
-    /**
-     * Returns the current frequency in {@link #FREQUENCY_UNITS}.
-     * @return the frequency.
-     * @see #FREQUENCY_UNITS
-     */
-    public int getFrequency() {
-        return mFrequency;
-    }
-
-    /** @hide */
-    public void setFrequency(int frequency) {
-        this.mFrequency = frequency;
-    }
-
-    /**
-     * @hide
-     */
-    public boolean is24GHz() {
-        return ScanResult.is24GHz(mFrequency);
-    }
-
-    /**
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public boolean is5GHz() {
-        return ScanResult.is5GHz(mFrequency);
-    }
-
-    /**
-     * @hide
-     */
-    public boolean is6GHz() {
-        return ScanResult.is6GHz(mFrequency);
-    }
-
-    /**
-     * Record the MAC address of the WLAN interface
-     * @param macAddress the MAC address in {@code XX:XX:XX:XX:XX:XX} form
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public void setMacAddress(String macAddress) {
-        this.mMacAddress = macAddress;
-    }
-
-    public String getMacAddress() {
-        return mMacAddress;
-    }
-
-    /**
-     * @return true if {@link #getMacAddress()} has a real MAC address.
-     *
-     * @hide
-     */
-    public boolean hasRealMacAddress() {
-        return mMacAddress != null && !DEFAULT_MAC_ADDRESS.equals(mMacAddress);
-    }
-
-    /**
-     * Indicates if we've dynamically detected this active network connection as
-     * being metered.
-     *
-     * @see WifiConfiguration#isMetered(WifiConfiguration, WifiInfo)
-     * @hide
-     */
-    public void setMeteredHint(boolean meteredHint) {
-        mMeteredHint = meteredHint;
-    }
-
-    /** {@hide} */
-    @UnsupportedAppUsage
-    public boolean getMeteredHint() {
-        return mMeteredHint;
-    }
-
-    /** {@hide} */
-    public void setEphemeral(boolean ephemeral) {
-        mEphemeral = ephemeral;
-    }
-
-    /**
-     * Returns true if the current Wifi network is ephemeral, false otherwise.
-     * An ephemeral network is a network that is temporary and not persisted in the system.
-     * Ephemeral networks cannot be forgotten, only disabled with
-     * {@link WifiManager#disableEphemeralNetwork(String)}.
-     *
-     * @hide
-     */
-    @SystemApi
-    public boolean isEphemeral() {
-        return mEphemeral;
-    }
-
-    /** {@hide} */
-    public void setTrusted(boolean trusted) {
-        mTrusted = trusted;
-    }
-
-    /** {@hide} */
-    public boolean isTrusted() {
-        return mTrusted;
-    }
-
-    /** {@hide} */
-    public void setOsuAp(boolean osuAp) {
-        mOsuAp = osuAp;
-    }
-
-    /** {@hide} */
-    @SystemApi
-    public boolean isOsuAp() {
-        return mOsuAp;
-    }
-
-    /** {@hide} */
-    @SystemApi
-    public boolean isPasspointAp() {
-        return mFqdn != null && mProviderFriendlyName != null;
-    }
-
-    /** {@hide} */
-    public void setFQDN(@Nullable String fqdn) {
-        mFqdn = fqdn;
-    }
-
-    /**
-     * Returns the Fully Qualified Domain Name of the network if it is a Passpoint network.
-     * <p>
-     * The FQDN may be
-     * <lt>{@code null} if no network currently connected, currently connected network is not
-     * passpoint network or the caller has insufficient permissions to access the FQDN.</lt>
-     * </p>
-     */
-    public @Nullable String getPasspointFqdn() {
-        return mFqdn;
-    }
-
-    /** {@hide} */
-    public void setProviderFriendlyName(@Nullable String providerFriendlyName) {
-        mProviderFriendlyName = providerFriendlyName;
-    }
-
-    /**
-     * Returns the Provider Friendly Name of the network if it is a Passpoint network.
-     * <p>
-     * The Provider Friendly Name may be
-     * <lt>{@code null} if no network currently connected, currently connected network is not
-     * passpoint network or the caller has insufficient permissions to access the Provider Friendly
-     * Name. </lt>
-     * </p>
-     */
-    public @Nullable String getPasspointProviderFriendlyName() {
-        return mProviderFriendlyName;
-    }
-
-    /** {@hide} */
-    public void setRequestingPackageName(@Nullable String packageName) {
-        mRequestingPackageName = packageName;
-    }
-
-    /**
-     * If this network was created in response to an app request (e.g. through Network Suggestion
-     * or Network Specifier), return the package name of the app that made the request.
-     * Null otherwise.
-     * @hide
-     */
-    @SystemApi
-    public @Nullable String getRequestingPackageName() {
-        return mRequestingPackageName;
-    }
-
-
-    /** @hide */
-    @UnsupportedAppUsage
-    public void setNetworkId(int id) {
-        mNetworkId = id;
-    }
-
-    /**
-     * Each configured network has a unique small integer ID, used to identify
-     * the network. This method returns the ID for the currently connected network.
-     * <p>
-     * The networkId may be {@code -1} if there is no currently connected network or if the caller
-     * has insufficient permissions to access the network ID.
-     * </p>
-     *
-     * @return the network ID.
-     */
-    public int getNetworkId() {
-        return mNetworkId;
-    }
-
-    /**
-     * Return the detailed state of the supplicant's negotiation with an
-     * access point, in the form of a {@link SupplicantState SupplicantState} object.
-     * @return the current {@link SupplicantState SupplicantState}
-     */
-    public SupplicantState getSupplicantState() {
-        return mSupplicantState;
-    }
-
-    /** @hide */
-    @UnsupportedAppUsage
-    public void setSupplicantState(SupplicantState state) {
-        mSupplicantState = state;
-    }
-
-    /** @hide */
-    public void setInetAddress(InetAddress address) {
-        mIpAddress = address;
-    }
-
-    public int getIpAddress() {
-        int result = 0;
-        if (mIpAddress instanceof Inet4Address) {
-            result = Inet4AddressUtils.inet4AddressToIntHTL((Inet4Address) mIpAddress);
-        }
-        return result;
-    }
-
-    /**
-     * @return {@code true} if this network does not broadcast its SSID, so an
-     * SSID-specific probe request must be used for scans.
-     */
-    public boolean getHiddenSSID() {
-        if (mWifiSsid == null) return false;
-        return mWifiSsid.isHidden();
-    }
-
-    /**
-     * Map a supplicant state into a fine-grained network connectivity state.
-     * @param suppState the supplicant state
-     * @return the corresponding {@link DetailedState}
-     */
-    public static DetailedState getDetailedStateOf(SupplicantState suppState) {
-        return stateMap.get(suppState);
-    }
-
-    /**
-     * Set the <code>SupplicantState</code> from the string name
-     * of the state.
-     * @param stateName the name of the state, as a <code>String</code> returned
-     * in an event sent by {@code wpa_supplicant}.
-     */
-    @UnsupportedAppUsage
-    void setSupplicantState(String stateName) {
-        mSupplicantState = valueOf(stateName);
-    }
-
-    static SupplicantState valueOf(String stateName) {
-        if ("4WAY_HANDSHAKE".equalsIgnoreCase(stateName))
-            return SupplicantState.FOUR_WAY_HANDSHAKE;
-        else {
-            try {
-                return SupplicantState.valueOf(stateName.toUpperCase(Locale.ROOT));
-            } catch (IllegalArgumentException e) {
-                return SupplicantState.INVALID;
-            }
-        }
-    }
-
-    /**
-     * Remove double quotes (") surrounding a SSID string, if present. Otherwise, return the
-     * string unmodified. Return null if the input string was null.
-     * @hide
-     */
-    @Nullable
-    @SystemApi
-    public static String sanitizeSsid(@Nullable String string) {
-        return removeDoubleQuotes(string);
-    }
-
-    /** @hide */
-    @UnsupportedAppUsage
-    @Nullable
-    public static String removeDoubleQuotes(@Nullable String string) {
-        if (string == null) return null;
-        final int length = string.length();
-        if ((length > 1) && (string.charAt(0) == '"') && (string.charAt(length - 1) == '"')) {
-            return string.substring(1, length - 1);
-        }
-        return string;
-    }
-
-    @Override
-    public String toString() {
-        StringBuffer sb = new StringBuffer();
-        String none = "<none>";
-
-        sb.append("SSID: ").append(mWifiSsid == null ? WifiManager.UNKNOWN_SSID : mWifiSsid)
-                .append(", BSSID: ").append(mBSSID == null ? none : mBSSID)
-                .append(", MAC: ").append(mMacAddress == null ? none : mMacAddress)
-                .append(", Supplicant state: ")
-                .append(mSupplicantState == null ? none : mSupplicantState)
-                .append(", Wi-Fi standard: ").append(mWifiStandard)
-                .append(", RSSI: ").append(mRssi)
-                .append(", Link speed: ").append(mLinkSpeed).append(LINK_SPEED_UNITS)
-                .append(", Tx Link speed: ").append(mTxLinkSpeed).append(LINK_SPEED_UNITS)
-                .append(", Max Supported Tx Link speed: ")
-                .append(mMaxSupportedTxLinkSpeed).append(LINK_SPEED_UNITS)
-                .append(", Rx Link speed: ").append(mRxLinkSpeed).append(LINK_SPEED_UNITS)
-                .append(", Max Supported Rx Link speed: ")
-                .append(mMaxSupportedRxLinkSpeed).append(LINK_SPEED_UNITS)
-                .append(", Frequency: ").append(mFrequency).append(FREQUENCY_UNITS)
-                .append(", Net ID: ").append(mNetworkId)
-                .append(", Metered hint: ").append(mMeteredHint)
-                .append(", score: ").append(Integer.toString(score));
-        return sb.toString();
-    }
-
-    /** Implement the Parcelable interface {@hide} */
-    public int describeContents() {
-        return 0;
-    }
-
-    /** Implement the Parcelable interface {@hide} */
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mNetworkId);
-        dest.writeInt(mRssi);
-        dest.writeInt(mLinkSpeed);
-        dest.writeInt(mTxLinkSpeed);
-        dest.writeInt(mRxLinkSpeed);
-        dest.writeInt(mFrequency);
-        if (mIpAddress != null) {
-            dest.writeByte((byte)1);
-            dest.writeByteArray(mIpAddress.getAddress());
-        } else {
-            dest.writeByte((byte)0);
-        }
-        if (mWifiSsid != null) {
-            dest.writeInt(1);
-            mWifiSsid.writeToParcel(dest, flags);
-        } else {
-            dest.writeInt(0);
-        }
-        dest.writeString(mBSSID);
-        dest.writeString(mMacAddress);
-        dest.writeInt(mMeteredHint ? 1 : 0);
-        dest.writeInt(mEphemeral ? 1 : 0);
-        dest.writeInt(mTrusted ? 1 : 0);
-        dest.writeInt(score);
-        dest.writeLong(txSuccess);
-        dest.writeDouble(mSuccessfulTxPacketsPerSecond);
-        dest.writeLong(txRetries);
-        dest.writeDouble(mTxRetriedTxPacketsPerSecond);
-        dest.writeLong(txBad);
-        dest.writeDouble(mLostTxPacketsPerSecond);
-        dest.writeLong(rxSuccess);
-        dest.writeDouble(mSuccessfulRxPacketsPerSecond);
-        mSupplicantState.writeToParcel(dest, flags);
-        dest.writeInt(mOsuAp ? 1 : 0);
-        dest.writeString(mRequestingPackageName);
-        dest.writeString(mFqdn);
-        dest.writeString(mProviderFriendlyName);
-        dest.writeInt(mWifiStandard);
-        dest.writeInt(mMaxSupportedTxLinkSpeed);
-        dest.writeInt(mMaxSupportedRxLinkSpeed);
-        dest.writeString(mPasspointUniqueId);
-    }
-
-    /** Implement the Parcelable interface {@hide} */
-    @UnsupportedAppUsage
-    public static final @android.annotation.NonNull Creator<WifiInfo> CREATOR =
-        new Creator<WifiInfo>() {
-            public WifiInfo createFromParcel(Parcel in) {
-                WifiInfo info = new WifiInfo();
-                info.setNetworkId(in.readInt());
-                info.setRssi(in.readInt());
-                info.setLinkSpeed(in.readInt());
-                info.setTxLinkSpeedMbps(in.readInt());
-                info.setRxLinkSpeedMbps(in.readInt());
-                info.setFrequency(in.readInt());
-                if (in.readByte() == 1) {
-                    try {
-                        info.setInetAddress(InetAddress.getByAddress(in.createByteArray()));
-                    } catch (UnknownHostException e) {}
-                }
-                if (in.readInt() == 1) {
-                    info.mWifiSsid = WifiSsid.CREATOR.createFromParcel(in);
-                }
-                info.mBSSID = in.readString();
-                info.mMacAddress = in.readString();
-                info.mMeteredHint = in.readInt() != 0;
-                info.mEphemeral = in.readInt() != 0;
-                info.mTrusted = in.readInt() != 0;
-                info.score = in.readInt();
-                info.txSuccess = in.readLong();
-                info.mSuccessfulTxPacketsPerSecond = in.readDouble();
-                info.txRetries = in.readLong();
-                info.mTxRetriedTxPacketsPerSecond = in.readDouble();
-                info.txBad = in.readLong();
-                info.mLostTxPacketsPerSecond = in.readDouble();
-                info.rxSuccess = in.readLong();
-                info.mSuccessfulRxPacketsPerSecond = in.readDouble();
-                info.mSupplicantState = SupplicantState.CREATOR.createFromParcel(in);
-                info.mOsuAp = in.readInt() != 0;
-                info.mRequestingPackageName = in.readString();
-                info.mFqdn = in.readString();
-                info.mProviderFriendlyName = in.readString();
-                info.mWifiStandard = in.readInt();
-                info.mMaxSupportedTxLinkSpeed = in.readInt();
-                info.mMaxSupportedRxLinkSpeed = in.readInt();
-                info.mPasspointUniqueId = in.readString();
-                return info;
-            }
-
-            public WifiInfo[] newArray(int size) {
-                return new WifiInfo[size];
-            }
-        };
-
-    /**
-     * Set the Passpoint unique identifier for the current connection
-     *
-     * @param passpointUniqueId Unique identifier
-     * @hide
-     */
-    public void setPasspointUniqueId(@Nullable String passpointUniqueId) {
-        mPasspointUniqueId = passpointUniqueId;
-    }
-
-    /**
-     * Get the Passpoint unique identifier for the current connection
-     *
-     * @return Passpoint unique identifier
-     * @hide
-     */
-    public @Nullable String getPasspointUniqueId() {
-        return mPasspointUniqueId;
-    }
-}
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
deleted file mode 100644
index ccf8a80..0000000
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ /dev/null
@@ -1,6239 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import static android.Manifest.permission.ACCESS_FINE_LOCATION;
-import static android.Manifest.permission.ACCESS_WIFI_STATE;
-import static android.Manifest.permission.READ_WIFI_CREDENTIAL;
-
-import android.annotation.CallbackExecutor;
-import android.annotation.IntDef;
-import android.annotation.IntRange;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.annotation.SuppressLint;
-import android.annotation.SystemApi;
-import android.annotation.SystemService;
-import android.app.ActivityManager;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.content.Context;
-import android.content.pm.ParceledListSlice;
-import android.net.ConnectivityManager;
-import android.net.DhcpInfo;
-import android.net.MacAddress;
-import android.net.Network;
-import android.net.NetworkStack;
-import android.net.wifi.hotspot2.IProvisioningCallback;
-import android.net.wifi.hotspot2.OsuProvider;
-import android.net.wifi.hotspot2.PasspointConfiguration;
-import android.net.wifi.hotspot2.ProvisioningCallback;
-import android.os.Binder;
-import android.os.Build;
-import android.os.Handler;
-import android.os.HandlerExecutor;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.RemoteException;
-import android.os.WorkSource;
-import android.os.connectivity.WifiActivityEnergyInfo;
-import android.text.TextUtils;
-import android.util.CloseGuard;
-import android.util.Log;
-import android.util.Pair;
-import android.util.SparseArray;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.ref.Reference;
-import java.lang.ref.WeakReference;
-import java.net.InetAddress;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.StringTokenizer;
-import java.util.concurrent.Executor;
-
-/**
- * This class provides the primary API for managing all aspects of Wi-Fi
- * connectivity.
- * <p>
- * On releases before {@link android.os.Build.VERSION_CODES#N}, this object
- * should only be obtained from an {@linkplain Context#getApplicationContext()
- * application context}, and not from any other derived context to avoid memory
- * leaks within the calling process.
- * <p>
- * It deals with several categories of items:
- * </p>
- * <ul>
- * <li>The list of configured networks. The list can be viewed and updated, and
- * attributes of individual entries can be modified.</li>
- * <li>The currently active Wi-Fi network, if any. Connectivity can be
- * established or torn down, and dynamic information about the state of the
- * network can be queried.</li>
- * <li>Results of access point scans, containing enough information to make
- * decisions about what access point to connect to.</li>
- * <li>It defines the names of various Intent actions that are broadcast upon
- * any sort of change in Wi-Fi state.
- * </ul>
- * <p>
- * This is the API to use when performing Wi-Fi specific operations. To perform
- * operations that pertain to network connectivity at an abstract level, use
- * {@link android.net.ConnectivityManager}.
- * </p>
- */
-@SystemService(Context.WIFI_SERVICE)
-public class WifiManager {
-
-    private static final String TAG = "WifiManager";
-    // Supplicant error codes:
-    /**
-     * The error code if there was a problem authenticating.
-     * @deprecated This is no longer supported.
-     */
-    @Deprecated
-    public static final int ERROR_AUTHENTICATING = 1;
-
-    /**
-     * The reason code if there is no error during authentication.
-     * It could also imply that there no authentication in progress,
-     * this reason code also serves as a reset value.
-     * @deprecated This is no longer supported.
-     * @hide
-     */
-    @Deprecated
-    public static final int ERROR_AUTH_FAILURE_NONE = 0;
-
-    /**
-     * The reason code if there was a timeout authenticating.
-     * @deprecated This is no longer supported.
-     * @hide
-     */
-    @Deprecated
-    public static final int ERROR_AUTH_FAILURE_TIMEOUT = 1;
-
-    /**
-     * The reason code if there was a wrong password while
-     * authenticating.
-     * @deprecated This is no longer supported.
-     * @hide
-     */
-    @Deprecated
-    public static final int ERROR_AUTH_FAILURE_WRONG_PSWD = 2;
-
-    /**
-     * The reason code if there was EAP failure while
-     * authenticating.
-     * @deprecated This is no longer supported.
-     * @hide
-     */
-    @Deprecated
-    public static final int ERROR_AUTH_FAILURE_EAP_FAILURE = 3;
-
-    /** @hide */
-    public static final int NETWORK_SUGGESTIONS_MAX_PER_APP_LOW_RAM = 256;
-
-    /** @hide */
-    public static final int NETWORK_SUGGESTIONS_MAX_PER_APP_HIGH_RAM = 1024;
-
-    /**
-     * Reason code if all of the network suggestions were successfully added or removed.
-     */
-    public static final int STATUS_NETWORK_SUGGESTIONS_SUCCESS = 0;
-
-    /**
-     * Reason code if there was an internal error in the platform while processing the addition or
-     * removal of suggestions.
-     */
-    public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_INTERNAL = 1;
-
-    /**
-     * Reason code if the user has disallowed "android:change_wifi_state" app-ops from the app.
-     * @see android.app.AppOpsManager#unsafeCheckOp(String, int, String).
-     */
-    public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_APP_DISALLOWED = 2;
-
-    /**
-     * Reason code if one or more of the network suggestions added already exists in platform's
-     * database.
-     * Note: this code will not be returned with Android 11 as in-place modification is allowed,
-     * please check {@link #addNetworkSuggestions(List)}.
-     * @see WifiNetworkSuggestion#equals(Object)
-     */
-    public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_DUPLICATE = 3;
-
-    /**
-     * Reason code if the number of network suggestions provided by the app crosses the max
-     * threshold set per app.
-     * The framework will reject all suggestions provided by {@link #addNetworkSuggestions(List)} if
-     * the total size exceeds the limit.
-     * @see #getMaxNumberOfNetworkSuggestionsPerApp()
-     */
-    public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_EXCEEDS_MAX_PER_APP = 4;
-
-    /**
-     * Reason code if one or more of the network suggestions removed does not exist in platform's
-     * database.
-     * The framework won't remove any suggestions if one or more of suggestions provided
-     * by {@link #removeNetworkSuggestions(List)} does not exist in database.
-     * @see WifiNetworkSuggestion#equals(Object)
-     */
-    public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_REMOVE_INVALID = 5;
-
-    /**
-     * Reason code if one or more of the network suggestions added is not allowed.
-     * The framework will reject all suggestions provided by {@link #addNetworkSuggestions(List)}
-     * if one or more of them is not allowed.
-     * This error may be caused by suggestion is using SIM-based encryption method, but calling app
-     * is not carrier privileged.
-     */
-    public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_NOT_ALLOWED = 6;
-
-    /**
-     * Reason code if one or more of the network suggestions added is invalid. Framework will reject
-     * all the suggestions in the list.
-     * The framework will reject all suggestions provided by {@link #addNetworkSuggestions(List)}
-     * if one or more of them is invalid.
-     * Please use {@link WifiNetworkSuggestion.Builder} to create network suggestions.
-     */
-    public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_INVALID = 7;
-
-    /** @hide */
-    @IntDef(prefix = { "STATUS_NETWORK_SUGGESTIONS_" }, value = {
-            STATUS_NETWORK_SUGGESTIONS_SUCCESS,
-            STATUS_NETWORK_SUGGESTIONS_ERROR_INTERNAL,
-            STATUS_NETWORK_SUGGESTIONS_ERROR_APP_DISALLOWED,
-            STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_DUPLICATE,
-            STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_EXCEEDS_MAX_PER_APP,
-            STATUS_NETWORK_SUGGESTIONS_ERROR_REMOVE_INVALID,
-            STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_NOT_ALLOWED,
-            STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_INVALID,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface NetworkSuggestionsStatusCode {}
-
-    /**
-     * Reason code if suggested network connection attempt failed with an unknown failure.
-     */
-    public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_UNKNOWN = 0;
-    /**
-     * Reason code if suggested network connection attempt failed with association failure.
-     */
-    public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_ASSOCIATION = 1;
-    /**
-     * Reason code if suggested network connection attempt failed with an authentication failure.
-     */
-    public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION = 2;
-    /**
-     * Reason code if suggested network connection attempt failed with an IP provision failure.
-     */
-    public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_IP_PROVISIONING = 3;
-
-    /** @hide */
-    @IntDef(prefix = {"STATUS_SUGGESTION_CONNECTION_FAILURE_"},
-            value = {STATUS_SUGGESTION_CONNECTION_FAILURE_UNKNOWN,
-                    STATUS_SUGGESTION_CONNECTION_FAILURE_ASSOCIATION,
-                    STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION,
-                    STATUS_SUGGESTION_CONNECTION_FAILURE_IP_PROVISIONING
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface SuggestionConnectionStatusCode {}
-
-    /**
-     * Broadcast intent action indicating whether Wi-Fi scanning is currently available.
-     * Available extras:
-     * - {@link #EXTRA_SCAN_AVAILABLE}
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_WIFI_SCAN_AVAILABILITY_CHANGED =
-            "android.net.wifi.action.WIFI_SCAN_AVAILABILITY_CHANGED";
-
-    /**
-     * A boolean extra indicating whether scanning is currently available.
-     * Sent in the broadcast {@link #ACTION_WIFI_SCAN_AVAILABILITY_CHANGED}.
-     * Its value is true if scanning is currently available, false otherwise.
-     */
-    public static final String EXTRA_SCAN_AVAILABLE = "android.net.wifi.extra.SCAN_AVAILABLE";
-
-    /**
-     * Broadcast intent action indicating that the credential of a Wi-Fi network
-     * has been changed. One extra provides the ssid of the network. Another
-     * extra provides the event type, whether the credential is saved or forgot.
-     * @hide
-     */
-    @SystemApi
-    public static final String WIFI_CREDENTIAL_CHANGED_ACTION =
-            "android.net.wifi.WIFI_CREDENTIAL_CHANGED";
-    /** @hide */
-    @SystemApi
-    public static final String EXTRA_WIFI_CREDENTIAL_EVENT_TYPE = "et";
-    /** @hide */
-    @SystemApi
-    public static final String EXTRA_WIFI_CREDENTIAL_SSID = "ssid";
-    /** @hide */
-    @SystemApi
-    public static final int WIFI_CREDENTIAL_SAVED = 0;
-    /** @hide */
-    @SystemApi
-    public static final int WIFI_CREDENTIAL_FORGOT = 1;
-
-    /** @hide */
-    @SystemApi
-    public static final int PASSPOINT_HOME_NETWORK = 0;
-
-    /** @hide */
-    @SystemApi
-    public static final int PASSPOINT_ROAMING_NETWORK = 1;
-
-    /**
-     * Broadcast intent action indicating that a Passpoint provider icon has been received.
-     *
-     * Included extras:
-     * {@link #EXTRA_BSSID_LONG}
-     * {@link #EXTRA_FILENAME}
-     * {@link #EXTRA_ICON}
-     *
-     * Receiver Required Permission: android.Manifest.permission.ACCESS_WIFI_STATE
-     *
-     * <p>Note: The broadcast is only delivered to registered receivers - no manifest registered
-     * components will be launched.
-     *
-     * @hide
-     */
-    public static final String ACTION_PASSPOINT_ICON = "android.net.wifi.action.PASSPOINT_ICON";
-    /**
-     * BSSID of an AP in long representation.  The {@link #EXTRA_BSSID} contains BSSID in
-     * String representation.
-     *
-     * Retrieve with {@link android.content.Intent#getLongExtra(String, long)}.
-     *
-     * @hide
-     */
-    public static final String EXTRA_BSSID_LONG = "android.net.wifi.extra.BSSID_LONG";
-    /**
-     * Icon data.
-     *
-     * Retrieve with {@link android.content.Intent#getParcelableExtra(String)} and cast into
-     * {@link android.graphics.drawable.Icon}.
-     *
-     * @hide
-     */
-    public static final String EXTRA_ICON = "android.net.wifi.extra.ICON";
-    /**
-     * Name of a file.
-     *
-     * Retrieve with {@link android.content.Intent#getStringExtra(String)}.
-     *
-     * @hide
-     */
-    public static final String EXTRA_FILENAME = "android.net.wifi.extra.FILENAME";
-
-    /**
-     * Broadcast intent action indicating a Passpoint OSU Providers List element has been received.
-     *
-     * Included extras:
-     * {@link #EXTRA_BSSID_LONG}
-     * {@link #EXTRA_ANQP_ELEMENT_DATA}
-     *
-     * Receiver Required Permission: android.Manifest.permission.ACCESS_WIFI_STATE
-     *
-     * <p>Note: The broadcast is only delivered to registered receivers - no manifest registered
-     * components will be launched.
-     *
-     * @hide
-     */
-    public static final String ACTION_PASSPOINT_OSU_PROVIDERS_LIST =
-            "android.net.wifi.action.PASSPOINT_OSU_PROVIDERS_LIST";
-    /**
-     * Raw binary data of an ANQP (Access Network Query Protocol) element.
-     *
-     * Retrieve with {@link android.content.Intent#getByteArrayExtra(String)}.
-     *
-     * @hide
-     */
-    public static final String EXTRA_ANQP_ELEMENT_DATA =
-            "android.net.wifi.extra.ANQP_ELEMENT_DATA";
-
-    /**
-     * Broadcast intent action indicating that a Passpoint Deauth Imminent frame has been received.
-     *
-     * Included extras:
-     * {@link #EXTRA_BSSID_LONG}
-     * {@link #EXTRA_ESS}
-     * {@link #EXTRA_DELAY}
-     * {@link #EXTRA_URL}
-     *
-     * Receiver Required Permission: android.Manifest.permission.ACCESS_WIFI_STATE
-     *
-     * <p>Note: The broadcast is only delivered to registered receivers - no manifest registered
-     * components will be launched.
-     *
-     * @hide
-     */
-    public static final String ACTION_PASSPOINT_DEAUTH_IMMINENT =
-            "android.net.wifi.action.PASSPOINT_DEAUTH_IMMINENT";
-    /**
-     * Flag indicating BSS (Basic Service Set) or ESS (Extended Service Set). This will be set to
-     * {@code true} for ESS.
-     *
-     * Retrieve with {@link android.content.Intent#getBooleanExtra(String, boolean)}.
-     *
-     * @hide
-     */
-    public static final String EXTRA_ESS = "android.net.wifi.extra.ESS";
-    /**
-     * Delay in seconds.
-     *
-     * Retrieve with {@link android.content.Intent#getIntExtra(String, int)}.
-     *
-     * @hide
-     */
-    public static final String EXTRA_DELAY = "android.net.wifi.extra.DELAY";
-
-    /**
-     * Broadcast intent action indicating a Passpoint subscription remediation frame has been
-     * received.
-     *
-     * Included extras:
-     * {@link #EXTRA_BSSID_LONG}
-     * {@link #EXTRA_SUBSCRIPTION_REMEDIATION_METHOD}
-     * {@link #EXTRA_URL}
-     *
-     * Receiver Required Permission: android.Manifest.permission.ACCESS_WIFI_STATE
-     *
-     * <p>Note: The broadcast is only delivered to registered receivers - no manifest registered
-     * components will be launched.
-     *
-     * @hide
-     */
-    public static final String ACTION_PASSPOINT_SUBSCRIPTION_REMEDIATION =
-            "android.net.wifi.action.PASSPOINT_SUBSCRIPTION_REMEDIATION";
-    /**
-     * The protocol supported by the subscription remediation server. The possible values are:
-     * 0 - OMA DM
-     * 1 - SOAP XML SPP
-     *
-     * Retrieve with {@link android.content.Intent#getIntExtra(String, int)}.
-     *
-     * @hide
-     */
-    public static final String EXTRA_SUBSCRIPTION_REMEDIATION_METHOD =
-            "android.net.wifi.extra.SUBSCRIPTION_REMEDIATION_METHOD";
-
-    /**
-     * Activity Action: Receiver should launch Passpoint OSU (Online Sign Up) view.
-     * Included extras:
-     *
-     * {@link #EXTRA_OSU_NETWORK}: {@link Network} instance associated with OSU AP.
-     * {@link #EXTRA_URL}: String representation of a server URL used for OSU process.
-     *
-     * @hide
-     */
-    @SystemApi
-    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
-    public static final String ACTION_PASSPOINT_LAUNCH_OSU_VIEW =
-            "android.net.wifi.action.PASSPOINT_LAUNCH_OSU_VIEW";
-
-    /**
-     * The lookup key for a {@link android.net.Network} associated with a Passpoint OSU server.
-     * Included in the {@link #ACTION_PASSPOINT_LAUNCH_OSU_VIEW} broadcast.
-     *
-     * Retrieve with {@link android.content.Intent#getParcelableExtra(String)}.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final String EXTRA_OSU_NETWORK = "android.net.wifi.extra.OSU_NETWORK";
-
-    /**
-     * String representation of an URL for Passpoint OSU.
-     * Included in the {@link #ACTION_PASSPOINT_LAUNCH_OSU_VIEW} broadcast.
-     *
-     * Retrieve with {@link android.content.Intent#getStringExtra(String)}.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final String EXTRA_URL = "android.net.wifi.extra.URL";
-
-    /**
-     * Broadcast intent action indicating that Wi-Fi has been enabled, disabled,
-     * enabling, disabling, or unknown. One extra provides this state as an int.
-     * Another extra provides the previous state, if available.  No network-related
-     * permissions are required to subscribe to this broadcast.
-     *
-     * <p class="note">This broadcast is not delivered to manifest receivers in
-     * applications that target API version 26 or later.
-     *
-     * @see #EXTRA_WIFI_STATE
-     * @see #EXTRA_PREVIOUS_WIFI_STATE
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String WIFI_STATE_CHANGED_ACTION =
-        "android.net.wifi.WIFI_STATE_CHANGED";
-    /**
-     * The lookup key for an int that indicates whether Wi-Fi is enabled,
-     * disabled, enabling, disabling, or unknown.  Retrieve it with
-     * {@link android.content.Intent#getIntExtra(String,int)}.
-     *
-     * @see #WIFI_STATE_DISABLED
-     * @see #WIFI_STATE_DISABLING
-     * @see #WIFI_STATE_ENABLED
-     * @see #WIFI_STATE_ENABLING
-     * @see #WIFI_STATE_UNKNOWN
-     */
-    public static final String EXTRA_WIFI_STATE = "wifi_state";
-    /**
-     * The previous Wi-Fi state.
-     *
-     * @see #EXTRA_WIFI_STATE
-     */
-    public static final String EXTRA_PREVIOUS_WIFI_STATE = "previous_wifi_state";
-
-    /**
-     * Wi-Fi is currently being disabled. The state will change to {@link #WIFI_STATE_DISABLED} if
-     * it finishes successfully.
-     *
-     * @see #WIFI_STATE_CHANGED_ACTION
-     * @see #getWifiState()
-     */
-    public static final int WIFI_STATE_DISABLING = 0;
-    /**
-     * Wi-Fi is disabled.
-     *
-     * @see #WIFI_STATE_CHANGED_ACTION
-     * @see #getWifiState()
-     */
-    public static final int WIFI_STATE_DISABLED = 1;
-    /**
-     * Wi-Fi is currently being enabled. The state will change to {@link #WIFI_STATE_ENABLED} if
-     * it finishes successfully.
-     *
-     * @see #WIFI_STATE_CHANGED_ACTION
-     * @see #getWifiState()
-     */
-    public static final int WIFI_STATE_ENABLING = 2;
-    /**
-     * Wi-Fi is enabled.
-     *
-     * @see #WIFI_STATE_CHANGED_ACTION
-     * @see #getWifiState()
-     */
-    public static final int WIFI_STATE_ENABLED = 3;
-    /**
-     * Wi-Fi is in an unknown state. This state will occur when an error happens while enabling
-     * or disabling.
-     *
-     * @see #WIFI_STATE_CHANGED_ACTION
-     * @see #getWifiState()
-     */
-    public static final int WIFI_STATE_UNKNOWN = 4;
-
-    /**
-     * Broadcast intent action indicating that Wi-Fi AP has been enabled, disabled,
-     * enabling, disabling, or failed.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final String WIFI_AP_STATE_CHANGED_ACTION =
-        "android.net.wifi.WIFI_AP_STATE_CHANGED";
-
-    /**
-     * The lookup key for an int that indicates whether Wi-Fi AP is enabled,
-     * disabled, enabling, disabling, or failed.  Retrieve it with
-     * {@link android.content.Intent#getIntExtra(String,int)}.
-     *
-     * @see #WIFI_AP_STATE_DISABLED
-     * @see #WIFI_AP_STATE_DISABLING
-     * @see #WIFI_AP_STATE_ENABLED
-     * @see #WIFI_AP_STATE_ENABLING
-     * @see #WIFI_AP_STATE_FAILED
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final String EXTRA_WIFI_AP_STATE = "wifi_state";
-
-    /**
-     * An extra containing the int error code for Soft AP start failure.
-     * Can be obtained from the {@link #WIFI_AP_STATE_CHANGED_ACTION} using
-     * {@link android.content.Intent#getIntExtra}.
-     * This extra will only be attached if {@link #EXTRA_WIFI_AP_STATE} is
-     * attached and is equal to {@link #WIFI_AP_STATE_FAILED}.
-     *
-     * The error code will be one of:
-     * {@link #SAP_START_FAILURE_GENERAL},
-     * {@link #SAP_START_FAILURE_NO_CHANNEL},
-     * {@link #SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION}
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final String EXTRA_WIFI_AP_FAILURE_REASON =
-            "android.net.wifi.extra.WIFI_AP_FAILURE_REASON";
-    /**
-     * The previous Wi-Fi state.
-     *
-     * @see #EXTRA_WIFI_AP_STATE
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final String EXTRA_PREVIOUS_WIFI_AP_STATE = "previous_wifi_state";
-    /**
-     * The lookup key for a String extra that stores the interface name used for the Soft AP.
-     * This extra is included in the broadcast {@link #WIFI_AP_STATE_CHANGED_ACTION}.
-     * Retrieve its value with {@link android.content.Intent#getStringExtra(String)}.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final String EXTRA_WIFI_AP_INTERFACE_NAME =
-            "android.net.wifi.extra.WIFI_AP_INTERFACE_NAME";
-    /**
-     * The lookup key for an int extra that stores the intended IP mode for this Soft AP.
-     * One of {@link #IFACE_IP_MODE_TETHERED} or {@link #IFACE_IP_MODE_LOCAL_ONLY}.
-     * This extra is included in the broadcast {@link #WIFI_AP_STATE_CHANGED_ACTION}.
-     * Retrieve its value with {@link android.content.Intent#getIntExtra(String, int)}.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final String EXTRA_WIFI_AP_MODE = "android.net.wifi.extra.WIFI_AP_MODE";
-
-    /** @hide */
-    @IntDef(flag = false, prefix = { "WIFI_AP_STATE_" }, value = {
-        WIFI_AP_STATE_DISABLING,
-        WIFI_AP_STATE_DISABLED,
-        WIFI_AP_STATE_ENABLING,
-        WIFI_AP_STATE_ENABLED,
-        WIFI_AP_STATE_FAILED,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface WifiApState {}
-
-    /**
-     * Wi-Fi AP is currently being disabled. The state will change to
-     * {@link #WIFI_AP_STATE_DISABLED} if it finishes successfully.
-     *
-     * @see #WIFI_AP_STATE_CHANGED_ACTION
-     * @see #getWifiApState()
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int WIFI_AP_STATE_DISABLING = 10;
-    /**
-     * Wi-Fi AP is disabled.
-     *
-     * @see #WIFI_AP_STATE_CHANGED_ACTION
-     * @see #getWifiState()
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int WIFI_AP_STATE_DISABLED = 11;
-    /**
-     * Wi-Fi AP is currently being enabled. The state will change to
-     * {@link #WIFI_AP_STATE_ENABLED} if it finishes successfully.
-     *
-     * @see #WIFI_AP_STATE_CHANGED_ACTION
-     * @see #getWifiApState()
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int WIFI_AP_STATE_ENABLING = 12;
-    /**
-     * Wi-Fi AP is enabled.
-     *
-     * @see #WIFI_AP_STATE_CHANGED_ACTION
-     * @see #getWifiApState()
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int WIFI_AP_STATE_ENABLED = 13;
-    /**
-     * Wi-Fi AP is in a failed state. This state will occur when an error occurs during
-     * enabling or disabling
-     *
-     * @see #WIFI_AP_STATE_CHANGED_ACTION
-     * @see #getWifiApState()
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int WIFI_AP_STATE_FAILED = 14;
-
-    /** @hide */
-    @IntDef(flag = false, prefix = { "SAP_START_FAILURE_" }, value = {
-        SAP_START_FAILURE_GENERAL,
-        SAP_START_FAILURE_NO_CHANNEL,
-        SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface SapStartFailure {}
-
-    /**
-     *  All other reasons for AP start failure besides {@link #SAP_START_FAILURE_NO_CHANNEL} and
-     *  {@link #SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION}.
-     *
-     *  @hide
-     */
-    @SystemApi
-    public static final int SAP_START_FAILURE_GENERAL= 0;
-
-    /**
-     *  If Wi-Fi AP start failed, this reason code means that no legal channel exists on user
-     *  selected band due to regulatory constraints.
-     *
-     *  @hide
-     */
-    @SystemApi
-    public static final int SAP_START_FAILURE_NO_CHANNEL = 1;
-
-    /**
-     *  If Wi-Fi AP start failed, this reason code means that the specified configuration
-     *  is not supported by the current HAL version.
-     *
-     *  @hide
-     */
-    @SystemApi
-    public static final int SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION = 2;
-
-
-    /** @hide */
-    @IntDef(flag = false, prefix = { "SAP_CLIENT_BLOCKED_REASON_" }, value = {
-        SAP_CLIENT_BLOCK_REASON_CODE_BLOCKED_BY_USER,
-        SAP_CLIENT_BLOCK_REASON_CODE_NO_MORE_STAS,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface SapClientBlockedReason {}
-
-    /**
-     *  If Soft Ap client is blocked, this reason code means that client doesn't exist in the
-     *  specified configuration {@link SoftApConfiguration.Builder#setBlockedClientList(List)}
-     *  and {@link SoftApConfiguration.Builder#setAllowedClientList(List)}
-     *  and the {@link SoftApConfiguration.Builder#setClientControlByUserEnabled(boolean)}
-     *  is configured as well.
-     *  @hide
-     */
-    @SystemApi
-    public static final int SAP_CLIENT_BLOCK_REASON_CODE_BLOCKED_BY_USER = 0;
-
-    /**
-     *  If Soft Ap client is blocked, this reason code means that no more clients can be
-     *  associated to this AP since it reached maximum capacity. The maximum capacity is
-     *  the minimum of {@link SoftApConfiguration.Builder#setMaxNumberOfClients(int)} and
-     *  {@link SoftApCapability#getMaxSupportedClients} which get from
-     *  {@link WifiManager.SoftApCallback#onCapabilityChanged(SoftApCapability)}.
-     *
-     *  @hide
-     */
-    @SystemApi
-    public static final int SAP_CLIENT_BLOCK_REASON_CODE_NO_MORE_STAS = 1;
-
-    /**
-     * Client disconnected for unspecified reason. This could for example be because the AP is being
-     * shut down.
-     * @hide
-     */
-    public static final int SAP_CLIENT_DISCONNECT_REASON_CODE_UNSPECIFIED = 2;
-
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(prefix = {"IFACE_IP_MODE_"}, value = {
-            IFACE_IP_MODE_UNSPECIFIED,
-            IFACE_IP_MODE_CONFIGURATION_ERROR,
-            IFACE_IP_MODE_TETHERED,
-            IFACE_IP_MODE_LOCAL_ONLY})
-    public @interface IfaceIpMode {}
-
-    /**
-     * Interface IP mode unspecified.
-     *
-     * @see #updateInterfaceIpState(String, int)
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int IFACE_IP_MODE_UNSPECIFIED = -1;
-
-    /**
-     * Interface IP mode for configuration error.
-     *
-     * @see #updateInterfaceIpState(String, int)
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int IFACE_IP_MODE_CONFIGURATION_ERROR = 0;
-
-    /**
-     * Interface IP mode for tethering.
-     *
-     * @see #updateInterfaceIpState(String, int)
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int IFACE_IP_MODE_TETHERED = 1;
-
-    /**
-     * Interface IP mode for Local Only Hotspot.
-     *
-     * @see #updateInterfaceIpState(String, int)
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int IFACE_IP_MODE_LOCAL_ONLY = 2;
-
-    /**
-     * Broadcast intent action indicating that the wifi network settings
-     * had been reset.
-     *
-     * Note: This intent is sent as a directed broadcast to each manifest registered receiver.
-     * Intent will not be received by dynamically registered receivers.
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_CARRIER_PROVISIONING)
-    public static final String ACTION_NETWORK_SETTINGS_RESET =
-            "android.net.wifi.action.NETWORK_SETTINGS_RESET";
-
-    /**
-     * Broadcast intent action indicating that a connection to the supplicant has
-     * been established (and it is now possible
-     * to perform Wi-Fi operations) or the connection to the supplicant has been
-     * lost. One extra provides the connection state as a boolean, where {@code true}
-     * means CONNECTED.
-     * @deprecated This is no longer supported.
-     * @see #EXTRA_SUPPLICANT_CONNECTED
-     */
-    @Deprecated
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String SUPPLICANT_CONNECTION_CHANGE_ACTION =
-        "android.net.wifi.supplicant.CONNECTION_CHANGE";
-    /**
-     * The lookup key for a boolean that indicates whether a connection to
-     * the supplicant daemon has been gained or lost. {@code true} means
-     * a connection now exists.
-     * Retrieve it with {@link android.content.Intent#getBooleanExtra(String,boolean)}.
-     * @deprecated This is no longer supported.
-     */
-    @Deprecated
-    public static final String EXTRA_SUPPLICANT_CONNECTED = "connected";
-    /**
-     * Broadcast intent action indicating that the state of Wi-Fi connectivity
-     * has changed. An extra provides the new state
-     * in the form of a {@link android.net.NetworkInfo} object.  No network-related
-     * permissions are required to subscribe to this broadcast.
-     *
-     * <p class="note">This broadcast is not delivered to manifest receivers in
-     * applications that target API version 26 or later.
-     * @see #EXTRA_NETWORK_INFO
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String NETWORK_STATE_CHANGED_ACTION = "android.net.wifi.STATE_CHANGE";
-    /**
-     * The lookup key for a {@link android.net.NetworkInfo} object associated with the
-     * Wi-Fi network. Retrieve with
-     * {@link android.content.Intent#getParcelableExtra(String)}.
-     */
-    public static final String EXTRA_NETWORK_INFO = "networkInfo";
-    /**
-     * The lookup key for a String giving the BSSID of the access point to which
-     * we are connected. No longer used.
-     */
-    @Deprecated
-    public static final String EXTRA_BSSID = "bssid";
-    /**
-     * The lookup key for a {@link android.net.wifi.WifiInfo} object giving the
-     * information about the access point to which we are connected.
-     * No longer used.
-     */
-    @Deprecated
-    public static final String EXTRA_WIFI_INFO = "wifiInfo";
-    /**
-     * Broadcast intent action indicating that the state of establishing a connection to
-     * an access point has changed.One extra provides the new
-     * {@link SupplicantState}. Note that the supplicant state is Wi-Fi specific, and
-     * is not generally the most useful thing to look at if you are just interested in
-     * the overall state of connectivity.
-     * @see #EXTRA_NEW_STATE
-     * @see #EXTRA_SUPPLICANT_ERROR
-     * @deprecated This is no longer supported.
-     */
-    @Deprecated
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String SUPPLICANT_STATE_CHANGED_ACTION =
-        "android.net.wifi.supplicant.STATE_CHANGE";
-    /**
-     * The lookup key for a {@link SupplicantState} describing the new state
-     * Retrieve with
-     * {@link android.content.Intent#getParcelableExtra(String)}.
-     * @deprecated This is no longer supported.
-     */
-    @Deprecated
-    public static final String EXTRA_NEW_STATE = "newState";
-
-    /**
-     * The lookup key for a {@link SupplicantState} describing the supplicant
-     * error code if any
-     * Retrieve with
-     * {@link android.content.Intent#getIntExtra(String, int)}.
-     * @see #ERROR_AUTHENTICATING
-     * @deprecated This is no longer supported.
-     */
-    @Deprecated
-    public static final String EXTRA_SUPPLICANT_ERROR = "supplicantError";
-
-    /**
-     * The lookup key for a {@link SupplicantState} describing the supplicant
-     * error reason if any
-     * Retrieve with
-     * {@link android.content.Intent#getIntExtra(String, int)}.
-     * @see #ERROR_AUTH_FAILURE_#REASON_CODE
-     * @deprecated This is no longer supported.
-     * @hide
-     */
-    @Deprecated
-    public static final String EXTRA_SUPPLICANT_ERROR_REASON = "supplicantErrorReason";
-
-    /**
-     * Broadcast intent action indicating that the configured networks changed.
-     * This can be as a result of adding/updating/deleting a network.
-     * <br />
-     * {@link #EXTRA_CHANGE_REASON} contains whether the configuration was added/changed/removed.
-     * {@link #EXTRA_WIFI_CONFIGURATION} is never set starting in Android 11.
-     * {@link #EXTRA_MULTIPLE_NETWORKS_CHANGED} is set for backwards compatibility reasons, but
-     * its value is always true, even if only a single network changed.
-     * <br />
-     * The {@link android.Manifest.permission#ACCESS_WIFI_STATE ACCESS_WIFI_STATE} permission is
-     * required to receive this broadcast.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final String CONFIGURED_NETWORKS_CHANGED_ACTION =
-        "android.net.wifi.CONFIGURED_NETWORKS_CHANGE";
-    /**
-     * The lookup key for a {@link android.net.wifi.WifiConfiguration} object representing
-     * the changed Wi-Fi configuration when the {@link #CONFIGURED_NETWORKS_CHANGED_ACTION}
-     * broadcast is sent.
-     * Note: this extra is never set starting in Android 11.
-     * @hide
-     */
-    @SystemApi
-    public static final String EXTRA_WIFI_CONFIGURATION = "wifiConfiguration";
-    /**
-     * Multiple network configurations have changed.
-     * @see #CONFIGURED_NETWORKS_CHANGED_ACTION
-     * Note: this extra is always true starting in Android 11.
-     * @hide
-     */
-    @SystemApi
-    public static final String EXTRA_MULTIPLE_NETWORKS_CHANGED = "multipleChanges";
-    /**
-     * The lookup key for an integer indicating the reason a Wi-Fi network configuration
-     * has changed. One of {@link #CHANGE_REASON_ADDED}, {@link #CHANGE_REASON_REMOVED},
-     * {@link #CHANGE_REASON_CONFIG_CHANGE}.
-     *
-     * @see #CONFIGURED_NETWORKS_CHANGED_ACTION
-     * @hide
-     */
-    @SystemApi
-    public static final String EXTRA_CHANGE_REASON = "changeReason";
-    /**
-     * The configuration is new and was added.
-     * @hide
-     */
-    @SystemApi
-    public static final int CHANGE_REASON_ADDED = 0;
-    /**
-     * The configuration was removed and is no longer present in the system's list of
-     * configured networks.
-     * @hide
-     */
-    @SystemApi
-    public static final int CHANGE_REASON_REMOVED = 1;
-    /**
-     * The configuration has changed as a result of explicit action or because the system
-     * took an automated action such as disabling a malfunctioning configuration.
-     * @hide
-     */
-    @SystemApi
-    public static final int CHANGE_REASON_CONFIG_CHANGE = 2;
-    /**
-     * An access point scan has completed, and results are available.
-     * Call {@link #getScanResults()} to obtain the results.
-     * The broadcast intent may contain an extra field with the key {@link #EXTRA_RESULTS_UPDATED}
-     * and a {@code boolean} value indicating if the scan was successful.
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String SCAN_RESULTS_AVAILABLE_ACTION = "android.net.wifi.SCAN_RESULTS";
-
-    /**
-     * Lookup key for a {@code boolean} extra in intent {@link #SCAN_RESULTS_AVAILABLE_ACTION}
-     * representing if the scan was successful or not.
-     * Scans may fail for multiple reasons, these may include:
-     * <ol>
-     * <li>An app requested too many scans in a certain period of time.
-     * This may lead to additional scan request rejections via "scan throttling" for both
-     * foreground and background apps.
-     * Note: Apps holding android.Manifest.permission.NETWORK_SETTINGS permission are
-     * exempted from scan throttling.
-     * </li>
-     * <li>The device is idle and scanning is disabled.</li>
-     * <li>Wifi hardware reported a scan failure.</li>
-     * </ol>
-     * @return true scan was successful, results are updated
-     * @return false scan was not successful, results haven't been updated since previous scan
-     */
-    public static final String EXTRA_RESULTS_UPDATED = "resultsUpdated";
-
-    /**
-     * A batch of access point scans has been completed and the results areavailable.
-     * Call {@link #getBatchedScanResults()} to obtain the results.
-     * @deprecated This API is nolonger supported.
-     * Use {@link android.net.wifi.WifiScanner} API
-     * @hide
-     */
-    @Deprecated
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String BATCHED_SCAN_RESULTS_AVAILABLE_ACTION =
-            "android.net.wifi.BATCHED_RESULTS";
-
-    /**
-     * The RSSI (signal strength) has changed.
-     *
-     * Receiver Required Permission: android.Manifest.permission.ACCESS_WIFI_STATE
-     * @see #EXTRA_NEW_RSSI
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String RSSI_CHANGED_ACTION = "android.net.wifi.RSSI_CHANGED";
-    /**
-     * The lookup key for an {@code int} giving the new RSSI in dBm.
-     */
-    public static final String EXTRA_NEW_RSSI = "newRssi";
-
-    /**
-     * @see #ACTION_LINK_CONFIGURATION_CHANGED
-     * @hide
-     */
-    @UnsupportedAppUsage(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>
-     * In the connected state, access to the SSID and BSSID requires
-     * the same permissions as {@link #getScanResults}. If such access is not allowed,
-     * {@link WifiInfo#getSSID} will return {@link #UNKNOWN_SSID} and
-     * {@link WifiInfo#getBSSID} will return {@code "02:00:00:00:00:00"}.
-     * {@link WifiInfo#getPasspointFqdn()} will return null.
-     * {@link WifiInfo#getPasspointProviderFriendlyName()} will return null.
-     *
-     * @return the Wi-Fi information, contained in {@link WifiInfo}.
-     */
-    public WifiInfo getConnectionInfo() {
-        try {
-            return mService.getConnectionInfo(mContext.getOpPackageName(),
-                    mContext.getAttributionTag());
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Return the results of the latest access point scan.
-     * @return the list of access points found in the most recent scan. An app must hold
-     * {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission
-     * in order to get valid results.
-     */
-    public List<ScanResult> getScanResults() {
-        try {
-            return mService.getScanResults(mContext.getOpPackageName(),
-                    mContext.getAttributionTag());
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Get the filtered ScanResults which match the network configurations specified by the
-     * {@code networkSuggestionsToMatch}. Suggestions which use {@link WifiConfiguration} use
-     * SSID and the security type to match. Suggestions which use {@link PasspointConfigration}
-     * use the matching rules of Hotspot 2.0.
-     * @param networkSuggestionsToMatch The list of {@link WifiNetworkSuggestion} to match against.
-     * These may or may not be suggestions which are installed on the device.
-     * @param scanResults The scan results to be filtered. Optional - if not provided(empty list),
-     * the Wi-Fi service will use the most recent scan results which the system has.
-     * @return The map of {@link WifiNetworkSuggestion} to the list of {@link ScanResult}
-     * corresponding to networks which match them.
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(allOf = {ACCESS_FINE_LOCATION, ACCESS_WIFI_STATE})
-    @NonNull
-    public Map<WifiNetworkSuggestion, List<ScanResult>> getMatchingScanResults(
-            @NonNull List<WifiNetworkSuggestion> networkSuggestionsToMatch,
-            @Nullable List<ScanResult> scanResults) {
-        if (networkSuggestionsToMatch == null) {
-            throw new IllegalArgumentException("networkSuggestions must not be null.");
-        }
-        try {
-            return mService.getMatchingScanResults(
-                    networkSuggestionsToMatch, scanResults,
-                    mContext.getOpPackageName(), mContext.getAttributionTag());
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Set if scanning is always available.
-     *
-     * If set to {@code true}, apps can issue {@link #startScan} and fetch scan results
-     * even when Wi-Fi is turned off.
-     *
-     * @param isAvailable true to enable, false to disable.
-     * @hide
-     * @see #isScanAlwaysAvailable()
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public void setScanAlwaysAvailable(boolean isAvailable) {
-        try {
-            mService.setScanAlwaysAvailable(isAvailable);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Check if scanning is always available.
-     *
-     * If this return {@code true}, apps can issue {@link #startScan} and fetch scan results
-     * even when Wi-Fi is turned off.
-     *
-     * To change this setting, see {@link #ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE}.
-     * @deprecated The ability for apps to trigger scan requests will be removed in a future
-     * release.
-     */
-    @Deprecated
-    public boolean isScanAlwaysAvailable() {
-        try {
-            return mService.isScanAlwaysAvailable();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Tell the device to persist the current list of configured networks.
-     * <p>
-     * Note: It is possible for this method to change the network IDs of
-     * existing networks. You should assume the network IDs can be different
-     * after calling this method.
-     *
-     * @return {@code false}.
-     * @deprecated There is no need to call this method -
-     * {@link #addNetwork(WifiConfiguration)}, {@link #updateNetwork(WifiConfiguration)}
-     * and {@link #removeNetwork(int)} already persist the configurations automatically.
-     */
-    @Deprecated
-    public boolean saveConfiguration() {
-        return false;
-    }
-
-    /**
-     * Get the country code.
-     * @return the country code in ISO 3166 alpha-2 (2-letter) uppercase format, or null if
-     * there is no country code configured.
-     * @hide
-     */
-    @Nullable
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public String getCountryCode() {
-        try {
-            return mService.getCountryCode();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Return the DHCP-assigned addresses from the last successful DHCP request,
-     * if any.
-     * @return the DHCP information
-     */
-    public DhcpInfo getDhcpInfo() {
-        try {
-            return mService.getDhcpInfo();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Enable or disable Wi-Fi.
-     * <p>
-     * Applications must have the {@link android.Manifest.permission#CHANGE_WIFI_STATE}
-     * permission to toggle wifi.
-     *
-     * @param enabled {@code true} to enable, {@code false} to disable.
-     * @return {@code false} if the request cannot be satisfied; {@code true} indicates that wifi is
-     *         either already in the requested state, or in progress toward the requested state.
-     * @throws  {@link java.lang.SecurityException} if the caller is missing required permissions.
-     *
-     * @deprecated Starting with Build.VERSION_CODES#Q, applications are not allowed to
-     * enable/disable Wi-Fi.
-     * <b>Compatibility Note:</b> For applications targeting
-     * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always fail and return
-     * {@code false}. If apps are targeting an older SDK ({@link android.os.Build.VERSION_CODES#P}
-     * or below), they can continue to use this API.
-     * <p>
-     * Deprecation Exemptions:
-     * <ul>
-     * <li>Device Owner (DO), Profile Owner (PO) and system apps.
-     * </ul>
-     */
-    @Deprecated
-    public boolean setWifiEnabled(boolean enabled) {
-        try {
-            return mService.setWifiEnabled(mContext.getOpPackageName(), enabled);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Gets the Wi-Fi enabled state.
-     * @return One of {@link #WIFI_STATE_DISABLED},
-     *         {@link #WIFI_STATE_DISABLING}, {@link #WIFI_STATE_ENABLED},
-     *         {@link #WIFI_STATE_ENABLING}, {@link #WIFI_STATE_UNKNOWN}
-     * @see #isWifiEnabled()
-     */
-    public int getWifiState() {
-        try {
-            return mService.getWifiEnabledState();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Return whether Wi-Fi is enabled or disabled.
-     * @return {@code true} if Wi-Fi is enabled
-     * @see #getWifiState()
-     */
-    public boolean isWifiEnabled() {
-        return getWifiState() == WIFI_STATE_ENABLED;
-    }
-
-    /**
-     * Calculates the level of the signal. This should be used any time a signal
-     * is being shown.
-     *
-     * @param rssi The power of the signal measured in RSSI.
-     * @param numLevels The number of levels to consider in the calculated level.
-     * @return A level of the signal, given in the range of 0 to numLevels-1 (both inclusive).
-     * @deprecated Callers should use {@link #calculateSignalLevel(int)} instead to get the
-     * signal level using the system default RSSI thresholds, or otherwise compute the RSSI level
-     * themselves using their own formula.
-     */
-    @Deprecated
-    public static int calculateSignalLevel(int rssi, int numLevels) {
-        if (rssi <= MIN_RSSI) {
-            return 0;
-        } else if (rssi >= MAX_RSSI) {
-            return numLevels - 1;
-        } else {
-            float inputRange = (MAX_RSSI - MIN_RSSI);
-            float outputRange = (numLevels - 1);
-            return (int)((float)(rssi - MIN_RSSI) * outputRange / inputRange);
-        }
-    }
-
-    /**
-     * Given a raw RSSI, return the RSSI signal quality rating using the system default RSSI
-     * quality rating thresholds.
-     * @param rssi a raw RSSI value, in dBm, usually between -55 and -90
-     * @return the RSSI signal quality rating, in the range
-     * [0, {@link #getMaxSignalLevel()}], where 0 is the lowest (worst signal) RSSI
-     * rating and {@link #getMaxSignalLevel()} is the highest (best signal) RSSI rating.
-     */
-    @IntRange(from = 0)
-    public int calculateSignalLevel(int rssi) {
-        try {
-            return mService.calculateSignalLevel(rssi);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Get the system default maximum signal level.
-     * This is the maximum RSSI level returned by {@link #calculateSignalLevel(int)}.
-     */
-    @IntRange(from = 0)
-    public int getMaxSignalLevel() {
-        return calculateSignalLevel(Integer.MAX_VALUE);
-    }
-
-    /**
-     * Compares two signal strengths.
-     *
-     * @param rssiA The power of the first signal measured in RSSI.
-     * @param rssiB The power of the second signal measured in RSSI.
-     * @return Returns <0 if the first signal is weaker than the second signal,
-     *         0 if the two signals have the same strength, and >0 if the first
-     *         signal is stronger than the second signal.
-     */
-    public static int compareSignalLevel(int rssiA, int rssiB) {
-        return rssiA - rssiB;
-    }
-
-    /**
-     * Call allowing ConnectivityService to update WifiService with interface mode changes.
-     *
-     * @param ifaceName String name of the updated interface, or null to represent all interfaces
-     * @param mode int representing the new mode, one of:
-     *             {@link #IFACE_IP_MODE_TETHERED},
-     *             {@link #IFACE_IP_MODE_LOCAL_ONLY},
-     *             {@link #IFACE_IP_MODE_CONFIGURATION_ERROR},
-     *             {@link #IFACE_IP_MODE_UNSPECIFIED}
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(anyOf = {
-            android.Manifest.permission.NETWORK_STACK,
-            NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK
-    })
-    public void updateInterfaceIpState(@Nullable String ifaceName, @IfaceIpMode int mode) {
-        try {
-            mService.updateInterfaceIpState(ifaceName, mode);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Start Soft AP (hotspot) mode for tethering purposes with the specified configuration.
-     * Note that starting Soft AP mode may disable station mode operation if the device does not
-     * support concurrency.
-     * @param wifiConfig SSID, security and channel details as part of WifiConfiguration, or null to
-     *                   use the persisted Soft AP configuration that was previously set using
-     *                   {@link #setWifiApConfiguration(WifiConfiguration)}.
-     * @return {@code true} if the operation succeeded, {@code false} otherwise
-     *
-     * @hide
-     */
-    @RequiresPermission(anyOf = {
-            android.Manifest.permission.NETWORK_STACK,
-            NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK
-    })
-    public boolean startSoftAp(@Nullable WifiConfiguration wifiConfig) {
-        try {
-            return mService.startSoftAp(wifiConfig);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Start Soft AP (hotspot) mode for tethering purposes with the specified configuration.
-     * Note that starting Soft AP mode may disable station mode operation if the device does not
-     * support concurrency.
-     * @param softApConfig A valid SoftApConfiguration specifying the configuration of the SAP,
-     *                     or null to use the persisted Soft AP configuration that was previously
-     *                     set using {@link #setSoftApConfiguration(softApConfiguration)}.
-     * @return {@code true} if the operation succeeded, {@code false} otherwise
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(anyOf = {
-            android.Manifest.permission.NETWORK_STACK,
-            NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK
-    })
-    public boolean startTetheredHotspot(@Nullable SoftApConfiguration softApConfig) {
-        try {
-            return mService.startTetheredHotspot(softApConfig);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-
-    /**
-     * Stop SoftAp mode.
-     * Note that stopping softap mode will restore the previous wifi mode.
-     * @return {@code true} if the operation succeeds, {@code false} otherwise
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(anyOf = {
-            android.Manifest.permission.NETWORK_STACK,
-            NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK
-    })
-    public boolean stopSoftAp() {
-        try {
-            return mService.stopSoftAp();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Request a local only hotspot that an application can use to communicate between co-located
-     * devices connected to the created WiFi hotspot.  The network created by this method will not
-     * have Internet access.  Each application can make a single request for the hotspot, but
-     * multiple applications could be requesting the hotspot at the same time.  When multiple
-     * applications have successfully registered concurrently, they will be sharing the underlying
-     * hotspot. {@link LocalOnlyHotspotCallback#onStarted(LocalOnlyHotspotReservation)} is called
-     * when the hotspot is ready for use by the application.
-     * <p>
-     * Each application can make a single active call to this method. The {@link
-     * LocalOnlyHotspotCallback#onStarted(LocalOnlyHotspotReservation)} callback supplies the
-     * requestor with a {@link LocalOnlyHotspotReservation} that contains a
-     * {@link SoftApConfiguration} with the SSID, security type and credentials needed to connect
-     * to the hotspot.  Communicating this information is up to the application.
-     * <p>
-     * If the LocalOnlyHotspot cannot be created, the {@link LocalOnlyHotspotCallback#onFailed(int)}
-     * method will be called. Example failures include errors bringing up the network or if
-     * there is an incompatible operating mode.  For example, if the user is currently using Wifi
-     * Tethering to provide an upstream to another device, LocalOnlyHotspot will not start due to
-     * an incompatible mode. The possible error codes include:
-     * {@link LocalOnlyHotspotCallback#ERROR_NO_CHANNEL},
-     * {@link LocalOnlyHotspotCallback#ERROR_GENERIC},
-     * {@link LocalOnlyHotspotCallback#ERROR_INCOMPATIBLE_MODE} and
-     * {@link LocalOnlyHotspotCallback#ERROR_TETHERING_DISALLOWED}.
-     * <p>
-     * Internally, requests will be tracked to prevent the hotspot from being torn down while apps
-     * are still using it.  The {@link LocalOnlyHotspotReservation} object passed in the  {@link
-     * LocalOnlyHotspotCallback#onStarted(LocalOnlyHotspotReservation)} call should be closed when
-     * the LocalOnlyHotspot is no longer needed using {@link LocalOnlyHotspotReservation#close()}.
-     * Since the hotspot may be shared among multiple applications, removing the final registered
-     * application request will trigger the hotspot teardown.  This means that applications should
-     * not listen to broadcasts containing wifi state to determine if the hotspot was stopped after
-     * they are done using it. Additionally, once {@link LocalOnlyHotspotReservation#close()} is
-     * called, applications will not receive callbacks of any kind.
-     * <p>
-     * Applications should be aware that the user may also stop the LocalOnlyHotspot through the
-     * Settings UI; it is not guaranteed to stay up as long as there is a requesting application.
-     * The requestors will be notified of this case via
-     * {@link LocalOnlyHotspotCallback#onStopped()}.  Other cases may arise where the hotspot is
-     * torn down (Emergency mode, etc).  Application developers should be aware that it can stop
-     * unexpectedly, but they will receive a notification if they have properly registered.
-     * <p>
-     * Applications should also be aware that this network will be shared with other applications.
-     * Applications are responsible for protecting their data on this network (e.g., TLS).
-     * <p>
-     * Applications need to have the following permissions to start LocalOnlyHotspot: {@link
-     * android.Manifest.permission#CHANGE_WIFI_STATE} and {@link
-     * android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION}.  Callers without
-     * the permissions will trigger a {@link java.lang.SecurityException}.
-     * <p>
-     * @param callback LocalOnlyHotspotCallback for the application to receive updates about
-     * operating status.
-     * @param handler Handler to be used for callbacks.  If the caller passes a null Handler, the
-     * main thread will be used.
-     */
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.CHANGE_WIFI_STATE,
-            android.Manifest.permission.ACCESS_FINE_LOCATION})
-    public void startLocalOnlyHotspot(LocalOnlyHotspotCallback callback,
-            @Nullable Handler handler) {
-        Executor executor = handler == null ? null : new HandlerExecutor(handler);
-        startLocalOnlyHotspotInternal(null, executor, callback);
-    }
-
-    /**
-     * Starts a local-only hotspot with a specific configuration applied. See
-     * {@link #startLocalOnlyHotspot(LocalOnlyHotspotCallback, Handler)}.
-     *
-     * Applications need either {@link android.Manifest.permission#NETWORK_SETUP_WIZARD} or
-     * {@link android.Manifest.permission#NETWORK_SETTINGS} to call this method.
-     *
-     * Since custom configuration settings may be incompatible with each other, the hotspot started
-     * through this method cannot coexist with another hotspot created through
-     * startLocalOnlyHotspot. If this is attempted, the first hotspot request wins and others
-     * receive {@link LocalOnlyHotspotCallback#ERROR_GENERIC} through
-     * {@link LocalOnlyHotspotCallback#onFailed}.
-     *
-     * @param config Custom configuration for the hotspot. See {@link SoftApConfiguration}.
-     * @param executor Executor to run callback methods on, or null to use the main thread.
-     * @param callback Callback object for updates about hotspot status, or null for no updates.
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(anyOf = {
-            android.Manifest.permission.NETWORK_SETTINGS,
-            android.Manifest.permission.NETWORK_SETUP_WIZARD})
-    public void startLocalOnlyHotspot(@NonNull SoftApConfiguration config,
-            @Nullable Executor executor,
-            @Nullable LocalOnlyHotspotCallback callback) {
-        Objects.requireNonNull(config);
-        startLocalOnlyHotspotInternal(config, executor, callback);
-    }
-
-    /**
-     * Common implementation of both configurable and non-configurable LOHS.
-     *
-     * @param config App-specified configuration, or null. When present, additional privileges are
-     *               required, and the hotspot cannot be shared with other clients.
-     * @param executor Executor to run callback methods on, or null to use the main thread.
-     * @param callback Callback object for updates about hotspot status, or null for no updates.
-     */
-    private void startLocalOnlyHotspotInternal(
-            @Nullable SoftApConfiguration config,
-            @Nullable Executor executor,
-            @Nullable LocalOnlyHotspotCallback callback) {
-        if (executor == null) {
-            executor = mContext.getMainExecutor();
-        }
-        synchronized (mLock) {
-            LocalOnlyHotspotCallbackProxy proxy =
-                    new LocalOnlyHotspotCallbackProxy(this, executor, callback);
-            try {
-                String packageName = mContext.getOpPackageName();
-                String featureId = mContext.getAttributionTag();
-                int returnCode = mService.startLocalOnlyHotspot(proxy, packageName, featureId,
-                        config);
-                if (returnCode != LocalOnlyHotspotCallback.REQUEST_REGISTERED) {
-                    // Send message to the proxy to make sure we call back on the correct thread
-                    proxy.onHotspotFailed(returnCode);
-                    return;
-                }
-                mLOHSCallbackProxy = proxy;
-            } catch (RemoteException e) {
-                throw e.rethrowFromSystemServer();
-            }
-        }
-    }
-
-    /**
-     * Cancels a pending local only hotspot request.  This can be used by the calling application to
-     * cancel the existing request if the provided callback has not been triggered.  Calling this
-     * method will be equivalent to closing the returned LocalOnlyHotspotReservation, but it is not
-     * explicitly required.
-     * <p>
-     * When cancelling this request, application developers should be aware that there may still be
-     * outstanding local only hotspot requests and the hotspot may still start, or continue running.
-     * Additionally, if a callback was registered, it will no longer be triggered after calling
-     * cancel.
-     *
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public void cancelLocalOnlyHotspotRequest() {
-        synchronized (mLock) {
-            stopLocalOnlyHotspot();
-        }
-    }
-
-    /**
-     *  Method used to inform WifiService that the LocalOnlyHotspot is no longer needed.  This
-     *  method is used by WifiManager to release LocalOnlyHotspotReservations held by calling
-     *  applications and removes the internal tracking for the hotspot request.  When all requesting
-     *  applications are finished using the hotspot, it will be stopped and WiFi will return to the
-     *  previous operational mode.
-     *
-     *  This method should not be called by applications.  Instead, they should call the close()
-     *  method on their LocalOnlyHotspotReservation.
-     */
-    private void stopLocalOnlyHotspot() {
-        synchronized (mLock) {
-            if (mLOHSCallbackProxy == null) {
-                // nothing to do, the callback was already cleaned up.
-                return;
-            }
-            mLOHSCallbackProxy = null;
-            try {
-                mService.stopLocalOnlyHotspot();
-            } catch (RemoteException e) {
-                throw e.rethrowFromSystemServer();
-            }
-        }
-    }
-
-    /**
-     * Allow callers (Settings UI) to watch LocalOnlyHotspot state changes.  Callers will
-     * receive a {@link LocalOnlyHotspotSubscription} object as a parameter of the
-     * {@link LocalOnlyHotspotObserver#onRegistered(LocalOnlyHotspotSubscription)}. The registered
-     * callers will receive the {@link LocalOnlyHotspotObserver#onStarted(SoftApConfiguration)} and
-     * {@link LocalOnlyHotspotObserver#onStopped()} callbacks.
-     * <p>
-     * Applications should have the
-     * {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION}
-     * permission.  Callers without the permission will trigger a
-     * {@link java.lang.SecurityException}.
-     * <p>
-     * @param observer LocalOnlyHotspotObserver callback.
-     * @param handler Handler to use for callbacks
-     *
-     * @hide
-     */
-    public void watchLocalOnlyHotspot(LocalOnlyHotspotObserver observer,
-            @Nullable Handler handler) {
-        Executor executor = handler == null ? mContext.getMainExecutor()
-                : new HandlerExecutor(handler);
-        synchronized (mLock) {
-            mLOHSObserverProxy =
-                    new LocalOnlyHotspotObserverProxy(this, executor, observer);
-            try {
-                mService.startWatchLocalOnlyHotspot(mLOHSObserverProxy);
-                mLOHSObserverProxy.registered();
-            } catch (RemoteException e) {
-                mLOHSObserverProxy = null;
-                throw e.rethrowFromSystemServer();
-            }
-        }
-    }
-
-    /**
-     * Allow callers to stop watching LocalOnlyHotspot state changes.  After calling this method,
-     * applications will no longer receive callbacks.
-     *
-     * @hide
-     */
-    public void unregisterLocalOnlyHotspotObserver() {
-        synchronized (mLock) {
-            if (mLOHSObserverProxy == null) {
-                // nothing to do, the callback was already cleaned up
-                return;
-            }
-            mLOHSObserverProxy = null;
-            try {
-                mService.stopWatchLocalOnlyHotspot();
-            } catch (RemoteException e) {
-                throw e.rethrowFromSystemServer();
-            }
-        }
-    }
-
-    /**
-     * Gets the tethered Wi-Fi hotspot enabled state.
-     * @return One of {@link #WIFI_AP_STATE_DISABLED},
-     *         {@link #WIFI_AP_STATE_DISABLING}, {@link #WIFI_AP_STATE_ENABLED},
-     *         {@link #WIFI_AP_STATE_ENABLING}, {@link #WIFI_AP_STATE_FAILED}
-     * @see #isWifiApEnabled()
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE)
-    public int getWifiApState() {
-        try {
-            return mService.getWifiApEnabledState();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Return whether tethered Wi-Fi AP is enabled or disabled.
-     * @return {@code true} if tethered  Wi-Fi AP is enabled
-     * @see #getWifiApState()
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE)
-    public boolean isWifiApEnabled() {
-        return getWifiApState() == WIFI_AP_STATE_ENABLED;
-    }
-
-    /**
-     * Gets the tethered Wi-Fi AP Configuration.
-     * @return AP details in WifiConfiguration
-     *
-     * Note that AP detail may contain configuration which is cannot be represented
-     * by the legacy WifiConfiguration, in such cases a null will be returned.
-     *
-     * @deprecated This API is deprecated. Use {@link #getSoftApConfiguration()} instead.
-     * @hide
-     */
-    @Nullable
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE)
-    @Deprecated
-    public WifiConfiguration getWifiApConfiguration() {
-        try {
-            return mService.getWifiApConfiguration();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Gets the Wi-Fi tethered AP Configuration.
-     * @return AP details in {@link SoftApConfiguration}
-     *
-     * @hide
-     */
-    @NonNull
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public SoftApConfiguration getSoftApConfiguration() {
-        try {
-            return mService.getSoftApConfiguration();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Sets the tethered Wi-Fi AP Configuration.
-     * @return {@code true} if the operation succeeded, {@code false} otherwise
-     *
-     * @deprecated This API is deprecated. Use {@link #setSoftApConfiguration(SoftApConfiguration)}
-     * instead.
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE)
-    @Deprecated
-    public boolean setWifiApConfiguration(WifiConfiguration wifiConfig) {
-        try {
-            return mService.setWifiApConfiguration(wifiConfig, mContext.getOpPackageName());
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Sets the tethered Wi-Fi AP Configuration.
-     *
-     * If the API is called while the tethered soft AP is enabled, the configuration will apply to
-     * the current soft AP if the new configuration only includes
-     * {@link SoftApConfiguration.Builder#setMaxNumberOfClients(int)}
-     * or {@link SoftApConfiguration.Builder#setShutdownTimeoutMillis(long)}
-     * or {@link SoftApConfiguration.Builder#setClientControlByUserEnabled(boolean)}
-     * or {@link SoftApConfiguration.Builder#setBlockedClientList(List)}
-     * or {@link SoftApConfiguration.Builder#setAllowedClientList(List)}
-     *
-     * Otherwise, the configuration changes will be applied when the Soft AP is next started
-     * (the framework will not stop/start the AP).
-     *
-     * @param softApConfig  A valid SoftApConfiguration specifying the configuration of the SAP.
-     * @return {@code true} if the operation succeeded, {@code false} otherwise
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public boolean setSoftApConfiguration(@NonNull SoftApConfiguration softApConfig) {
-        try {
-            return mService.setSoftApConfiguration(
-                    softApConfig, mContext.getOpPackageName());
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Enable/Disable TDLS on a specific local route.
-     *
-     * <p>
-     * TDLS enables two wireless endpoints to talk to each other directly
-     * without going through the access point that is managing the local
-     * network. It saves bandwidth and improves quality of the link.
-     * </p>
-     * <p>
-     * This API enables/disables the option of using TDLS. If enabled, the
-     * underlying hardware is free to use TDLS or a hop through the access
-     * point. If disabled, existing TDLS session is torn down and
-     * hardware is restricted to use access point for transferring wireless
-     * packets. Default value for all routes is 'disabled', meaning restricted
-     * to use access point for transferring packets.
-     * </p>
-     *
-     * @param remoteIPAddress IP address of the endpoint to setup TDLS with
-     * @param enable true = setup and false = tear down TDLS
-     */
-    public void setTdlsEnabled(InetAddress remoteIPAddress, boolean enable) {
-        try {
-            mService.enableTdls(remoteIPAddress.getHostAddress(), enable);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Similar to {@link #setTdlsEnabled(InetAddress, boolean) }, except
-     * this version allows you to specify remote endpoint with a MAC address.
-     * @param remoteMacAddress MAC address of the remote endpoint such as 00:00:0c:9f:f2:ab
-     * @param enable true = setup and false = tear down TDLS
-     */
-    public void setTdlsEnabledWithMacAddress(String remoteMacAddress, boolean enable) {
-        try {
-            mService.enableTdlsWithMacAddress(remoteMacAddress, enable);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Passed with {@link ActionListener#onFailure}.
-     * Indicates that the operation failed due to an internal error.
-     * @hide
-     */
-    public static final int ERROR                       = 0;
-
-    /**
-     * Passed with {@link ActionListener#onFailure}.
-     * Indicates that the operation is already in progress
-     * @hide
-     */
-    public static final int IN_PROGRESS                 = 1;
-
-    /**
-     * Passed with {@link ActionListener#onFailure}.
-     * Indicates that the operation failed because the framework is busy and
-     * unable to service the request
-     * @hide
-     */
-    public static final int BUSY                        = 2;
-
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({ERROR, IN_PROGRESS, BUSY})
-    public @interface ActionListenerFailureReason {}
-
-    /* WPS specific errors */
-    /** WPS overlap detected
-     * @deprecated This is deprecated
-     */
-    public static final int WPS_OVERLAP_ERROR           = 3;
-    /** WEP on WPS is prohibited
-     * @deprecated This is deprecated
-     */
-    public static final int WPS_WEP_PROHIBITED          = 4;
-    /** TKIP only prohibited
-     * @deprecated This is deprecated
-     */
-    public static final int WPS_TKIP_ONLY_PROHIBITED    = 5;
-    /** Authentication failure on WPS
-     * @deprecated This is deprecated
-     */
-    public static final int WPS_AUTH_FAILURE            = 6;
-    /** WPS timed out
-     * @deprecated This is deprecated
-     */
-    public static final int WPS_TIMED_OUT               = 7;
-
-    /**
-     * Passed with {@link ActionListener#onFailure}.
-     * Indicates that the operation failed due to invalid inputs
-     * @hide
-     */
-    public static final int INVALID_ARGS                = 8;
-
-    /**
-     * Passed with {@link ActionListener#onFailure}.
-     * Indicates that the operation failed due to user permissions.
-     * @hide
-     */
-    public static final int NOT_AUTHORIZED              = 9;
-
-    /**
-     * Interface for callback invocation on an application action
-     * @hide
-     */
-    @SystemApi
-    public interface ActionListener {
-        /**
-         * The operation succeeded.
-         */
-        void onSuccess();
-        /**
-         * The operation failed.
-         * @param reason The reason for failure depends on the operation.
-         */
-        void onFailure(@ActionListenerFailureReason int reason);
-    }
-
-    /** Interface for callback invocation on a start WPS action
-     * @deprecated This is deprecated
-     */
-    public static abstract class WpsCallback {
-
-        /** WPS start succeeded
-         * @deprecated This API is deprecated
-         */
-        public abstract void onStarted(String pin);
-
-        /** WPS operation completed successfully
-         * @deprecated This API is deprecated
-         */
-        public abstract void onSucceeded();
-
-        /**
-         * WPS operation failed
-         * @param reason The reason for failure could be one of
-         * {@link #WPS_TKIP_ONLY_PROHIBITED}, {@link #WPS_OVERLAP_ERROR},
-         * {@link #WPS_WEP_PROHIBITED}, {@link #WPS_TIMED_OUT} or {@link #WPS_AUTH_FAILURE}
-         * and some generic errors.
-         * @deprecated This API is deprecated
-         */
-        public abstract void onFailed(int reason);
-    }
-
-    /**
-     * Base class for soft AP callback. Should be extended by applications and set when calling
-     * {@link WifiManager#registerSoftApCallback(Executor, SoftApCallback)}.
-     *
-     * @hide
-     */
-    @SystemApi
-    public interface SoftApCallback {
-        /**
-         * Called when soft AP state changes.
-         *
-         * @param state         the new AP state. One of {@link #WIFI_AP_STATE_DISABLED},
-         *                      {@link #WIFI_AP_STATE_DISABLING}, {@link #WIFI_AP_STATE_ENABLED},
-         *                      {@link #WIFI_AP_STATE_ENABLING}, {@link #WIFI_AP_STATE_FAILED}
-         * @param failureReason reason when in failed state. One of
-         *                      {@link #SAP_START_FAILURE_GENERAL},
-         *                      {@link #SAP_START_FAILURE_NO_CHANNEL},
-         *                      {@link #SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION}
-         */
-        default void onStateChanged(@WifiApState int state, @SapStartFailure int failureReason) {}
-
-        /**
-         * Called when the connected clients to soft AP changes.
-         *
-         * @param clients the currently connected clients
-         */
-        default void onConnectedClientsChanged(@NonNull List<WifiClient> clients) {}
-
-        /**
-         * Called when information of softap changes.
-         *
-         * @param softApInfo is the softap information. {@link SoftApInfo}
-         */
-        default void onInfoChanged(@NonNull SoftApInfo softApInfo) {
-            // Do nothing: can be updated to add SoftApInfo details (e.g. channel) to the UI.
-        }
-
-        /**
-         * Called when capability of softap changes.
-         *
-         * @param softApCapability is the softap capability. {@link SoftApCapability}
-         */
-        default void onCapabilityChanged(@NonNull SoftApCapability softApCapability) {
-            // Do nothing: can be updated to add SoftApCapability details (e.g. meximum supported
-            // client number) to the UI.
-        }
-
-        /**
-         * Called when client trying to connect but device blocked the client with specific reason.
-         *
-         * Can be used to ask user to update client to allowed list or blocked list
-         * when reason is {@link SAP_CLIENT_BLOCK_REASON_CODE_BLOCKED_BY_USER}, or
-         * indicate the block due to maximum supported client number limitation when reason is
-         * {@link SAP_CLIENT_BLOCK_REASON_CODE_NO_MORE_STAS}.
-         *
-         * @param client the currently blocked client.
-         * @param blockedReason one of blocked reason from {@link SapClientBlockedReason}
-         */
-        default void onBlockedClientConnecting(@NonNull WifiClient client,
-                @SapClientBlockedReason int blockedReason) {
-            // Do nothing: can be used to ask user to update client to allowed list or blocked list.
-        }
-    }
-
-    /**
-     * Callback proxy for SoftApCallback objects.
-     *
-     * @hide
-     */
-    private class SoftApCallbackProxy extends ISoftApCallback.Stub {
-        private final Executor mExecutor;
-        private final SoftApCallback mCallback;
-
-        SoftApCallbackProxy(Executor executor, SoftApCallback callback) {
-            mExecutor = executor;
-            mCallback = callback;
-        }
-
-        @Override
-        public void onStateChanged(int state, int failureReason) {
-            if (mVerboseLoggingEnabled) {
-                Log.v(TAG, "SoftApCallbackProxy: onStateChanged: state=" + state
-                        + ", failureReason=" + failureReason);
-            }
-
-            Binder.clearCallingIdentity();
-            mExecutor.execute(() -> {
-                mCallback.onStateChanged(state, failureReason);
-            });
-        }
-
-        @Override
-        public void onConnectedClientsChanged(List<WifiClient> clients) {
-            if (mVerboseLoggingEnabled) {
-                Log.v(TAG, "SoftApCallbackProxy: onConnectedClientsChanged: clients="
-                        + clients.size() + " clients");
-            }
-
-            Binder.clearCallingIdentity();
-            mExecutor.execute(() -> {
-                mCallback.onConnectedClientsChanged(clients);
-            });
-        }
-
-        @Override
-        public void onInfoChanged(SoftApInfo softApInfo) {
-            if (mVerboseLoggingEnabled) {
-                Log.v(TAG, "SoftApCallbackProxy: onInfoChange: softApInfo=" + softApInfo);
-            }
-
-            Binder.clearCallingIdentity();
-            mExecutor.execute(() -> {
-                mCallback.onInfoChanged(softApInfo);
-            });
-        }
-
-        @Override
-        public void onCapabilityChanged(SoftApCapability capability) {
-            if (mVerboseLoggingEnabled) {
-                Log.v(TAG, "SoftApCallbackProxy: onCapabilityChanged: SoftApCapability="
-                        + capability);
-            }
-
-            Binder.clearCallingIdentity();
-            mExecutor.execute(() -> {
-                mCallback.onCapabilityChanged(capability);
-            });
-        }
-
-        @Override
-        public void onBlockedClientConnecting(@NonNull WifiClient client, int blockedReason) {
-            if (mVerboseLoggingEnabled) {
-                Log.v(TAG, "SoftApCallbackProxy: onBlockedClientConnecting: client=" + client
-                        + " with reason = " + blockedReason);
-            }
-
-            Binder.clearCallingIdentity();
-            mExecutor.execute(() -> {
-                mCallback.onBlockedClientConnecting(client, blockedReason);
-            });
-        }
-    }
-
-    /**
-     * Registers a callback for Soft AP. See {@link SoftApCallback}. Caller will receive the
-     * following callbacks on registration:
-     * <ul>
-     * <li> {@link SoftApCallback#onStateChanged(int, int)}</li>
-     * <li> {@link SoftApCallback#onConnectedClientsChanged(List<WifiClient>)}</li>
-     * <li> {@link SoftApCallback#onInfoChanged(SoftApInfo)}</li>
-     * <li> {@link SoftApCallback#onCapabilityChanged(SoftApCapability)}</li>
-     * </ul>
-     * These will be dispatched on registration to provide the caller with the current state
-     * (and are not an indication of any current change). Note that receiving an immediate
-     * WIFI_AP_STATE_FAILED value for soft AP state indicates that the latest attempt to start
-     * soft AP has failed. Caller can unregister a previously registered callback using
-     * {@link #unregisterSoftApCallback}
-     * <p>
-     * Applications should have the
-     * {@link android.Manifest.permission#NETWORK_SETTINGS NETWORK_SETTINGS} permission. Callers
-     * without the permission will trigger a {@link java.lang.SecurityException}.
-     * <p>
-     *
-     * @param executor The Executor on whose thread to execute the callbacks of the {@code callback}
-     *                 object.
-     * @param callback Callback for soft AP events
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public void registerSoftApCallback(@NonNull @CallbackExecutor Executor executor,
-            @NonNull SoftApCallback callback) {
-        if (executor == null) throw new IllegalArgumentException("executor cannot be null");
-        if (callback == null) throw new IllegalArgumentException("callback cannot be null");
-        Log.v(TAG, "registerSoftApCallback: callback=" + callback + ", executor=" + executor);
-
-        Binder binder = new Binder();
-        try {
-            mService.registerSoftApCallback(
-                    binder, new SoftApCallbackProxy(executor, callback), callback.hashCode());
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Allow callers to unregister a previously registered callback. After calling this method,
-     * applications will no longer receive soft AP events.
-     *
-     * @param callback Callback to unregister for soft AP events
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public void unregisterSoftApCallback(@NonNull SoftApCallback callback) {
-        if (callback == null) throw new IllegalArgumentException("callback cannot be null");
-        Log.v(TAG, "unregisterSoftApCallback: callback=" + callback);
-
-        try {
-            mService.unregisterSoftApCallback(callback.hashCode());
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * LocalOnlyHotspotReservation that contains the {@link SoftApConfiguration} for the active
-     * LocalOnlyHotspot request.
-     * <p>
-     * Applications requesting LocalOnlyHotspot for sharing will receive an instance of the
-     * LocalOnlyHotspotReservation in the
-     * {@link LocalOnlyHotspotCallback#onStarted(LocalOnlyHotspotReservation)} call.  This
-     * reservation contains the relevant {@link SoftApConfiguration}.
-     * When an application is done with the LocalOnlyHotspot, they should call {@link
-     * LocalOnlyHotspotReservation#close()}.  Once this happens, the application will not receive
-     * any further callbacks. If the LocalOnlyHotspot is stopped due to a
-     * user triggered mode change, applications will be notified via the {@link
-     * LocalOnlyHotspotCallback#onStopped()} callback.
-     */
-    public class LocalOnlyHotspotReservation implements AutoCloseable {
-
-        private final CloseGuard mCloseGuard = new CloseGuard();
-        private final SoftApConfiguration mSoftApConfig;
-        private final WifiConfiguration mWifiConfig;
-        private boolean mClosed = false;
-
-        /** @hide */
-        @VisibleForTesting
-        public LocalOnlyHotspotReservation(SoftApConfiguration config) {
-            mSoftApConfig = config;
-            mWifiConfig = config.toWifiConfiguration();
-            mCloseGuard.open("close");
-        }
-
-        /**
-         * Returns the {@link WifiConfiguration} of the current Local Only Hotspot (LOHS).
-         * May be null if hotspot enabled and security type is not
-         * {@code WifiConfiguration.KeyMgmt.None} or {@code WifiConfiguration.KeyMgmt.WPA2_PSK}.
-         *
-         * @deprecated Use {@code WifiManager#getSoftApConfiguration()} to get the
-         * LOHS configuration.
-         */
-        @Deprecated
-        @Nullable
-        public WifiConfiguration getWifiConfiguration() {
-            return mWifiConfig;
-        }
-
-        /**
-         * Returns the {@link SoftApConfiguration} of the current Local Only Hotspot (LOHS).
-         */
-        @NonNull
-        public SoftApConfiguration getSoftApConfiguration() {
-            return mSoftApConfig;
-        }
-
-        @Override
-        public void close() {
-            try {
-                synchronized (mLock) {
-                    if (!mClosed) {
-                        mClosed = true;
-                        stopLocalOnlyHotspot();
-                        mCloseGuard.close();
-                    }
-                }
-            } catch (Exception e) {
-                Log.e(TAG, "Failed to stop Local Only Hotspot.");
-            } finally {
-                Reference.reachabilityFence(this);
-            }
-        }
-
-        @Override
-        protected void finalize() throws Throwable {
-            try {
-                if (mCloseGuard != null) {
-                    mCloseGuard.warnIfOpen();
-                }
-                close();
-            } finally {
-                super.finalize();
-            }
-        }
-    }
-
-    /**
-     * Callback class for applications to receive updates about the LocalOnlyHotspot status.
-     */
-    public static class LocalOnlyHotspotCallback {
-        /** @hide */
-        public static final int REQUEST_REGISTERED = 0;
-
-        public static final int ERROR_NO_CHANNEL = 1;
-        public static final int ERROR_GENERIC = 2;
-        public static final int ERROR_INCOMPATIBLE_MODE = 3;
-        public static final int ERROR_TETHERING_DISALLOWED = 4;
-
-        /** LocalOnlyHotspot start succeeded. */
-        public void onStarted(LocalOnlyHotspotReservation reservation) {};
-
-        /**
-         * LocalOnlyHotspot stopped.
-         * <p>
-         * The LocalOnlyHotspot can be disabled at any time by the user.  When this happens,
-         * applications will be notified that it was stopped. This will not be invoked when an
-         * application calls {@link LocalOnlyHotspotReservation#close()}.
-         */
-        public void onStopped() {};
-
-        /**
-         * LocalOnlyHotspot failed to start.
-         * <p>
-         * Applications can attempt to call
-         * {@link WifiManager#startLocalOnlyHotspot(LocalOnlyHotspotCallback, Handler)} again at
-         * a later time.
-         * <p>
-         * @param reason The reason for failure could be one of: {@link
-         * #ERROR_TETHERING_DISALLOWED}, {@link #ERROR_INCOMPATIBLE_MODE},
-         * {@link #ERROR_NO_CHANNEL}, or {@link #ERROR_GENERIC}.
-         */
-        public void onFailed(int reason) { };
-    }
-
-    /**
-     * Callback proxy for LocalOnlyHotspotCallback objects.
-     */
-    private static class LocalOnlyHotspotCallbackProxy extends ILocalOnlyHotspotCallback.Stub {
-        private final WeakReference<WifiManager> mWifiManager;
-        private final Executor mExecutor;
-        private final LocalOnlyHotspotCallback mCallback;
-
-        /**
-         * Constructs a {@link LocalOnlyHotspotCallbackProxy} using the specified executor.  All
-         * callbacks will run using the given executor.
-         *
-         * @param manager WifiManager
-         * @param executor Executor for delivering callbacks.
-         * @param callback LocalOnlyHotspotCallback to notify the calling application, or null.
-         */
-        LocalOnlyHotspotCallbackProxy(
-                @NonNull WifiManager manager,
-                @NonNull Executor executor,
-                @Nullable LocalOnlyHotspotCallback callback) {
-            mWifiManager = new WeakReference<>(manager);
-            mExecutor = executor;
-            mCallback = callback;
-        }
-
-        @Override
-        public void onHotspotStarted(SoftApConfiguration config) {
-            WifiManager manager = mWifiManager.get();
-            if (manager == null) return;
-
-            if (config == null) {
-                Log.e(TAG, "LocalOnlyHotspotCallbackProxy: config cannot be null.");
-                onHotspotFailed(LocalOnlyHotspotCallback.ERROR_GENERIC);
-                return;
-            }
-            final LocalOnlyHotspotReservation reservation =
-                    manager.new LocalOnlyHotspotReservation(config);
-            if (mCallback == null) return;
-            mExecutor.execute(() -> mCallback.onStarted(reservation));
-        }
-
-        @Override
-        public void onHotspotStopped() {
-            WifiManager manager = mWifiManager.get();
-            if (manager == null) return;
-
-            Log.w(TAG, "LocalOnlyHotspotCallbackProxy: hotspot stopped");
-            if (mCallback == null) return;
-            mExecutor.execute(() -> mCallback.onStopped());
-        }
-
-        @Override
-        public void onHotspotFailed(int reason) {
-            WifiManager manager = mWifiManager.get();
-            if (manager == null) return;
-
-            Log.w(TAG, "LocalOnlyHotspotCallbackProxy: failed to start.  reason: "
-                    + reason);
-            if (mCallback == null) return;
-            mExecutor.execute(() -> mCallback.onFailed(reason));
-        }
-    }
-
-    /**
-     * LocalOnlyHotspotSubscription that is an AutoCloseable object for tracking applications
-     * watching for LocalOnlyHotspot changes.
-     *
-     * @hide
-     */
-    public class LocalOnlyHotspotSubscription implements AutoCloseable {
-        private final CloseGuard mCloseGuard = new CloseGuard();
-
-        /** @hide */
-        @VisibleForTesting
-        public LocalOnlyHotspotSubscription() {
-            mCloseGuard.open("close");
-        }
-
-        @Override
-        public void close() {
-            try {
-                unregisterLocalOnlyHotspotObserver();
-                mCloseGuard.close();
-            } catch (Exception e) {
-                Log.e(TAG, "Failed to unregister LocalOnlyHotspotObserver.");
-            } finally {
-                Reference.reachabilityFence(this);
-            }
-        }
-
-        @Override
-        protected void finalize() throws Throwable {
-            try {
-                if (mCloseGuard != null) {
-                    mCloseGuard.warnIfOpen();
-                }
-                close();
-            } finally {
-                super.finalize();
-            }
-        }
-    }
-
-    /**
-     * Class to notify calling applications that watch for changes in LocalOnlyHotspot of updates.
-     *
-     * @hide
-     */
-    public static class LocalOnlyHotspotObserver {
-        /**
-         * Confirm registration for LocalOnlyHotspotChanges by returning a
-         * LocalOnlyHotspotSubscription.
-         */
-        public void onRegistered(LocalOnlyHotspotSubscription subscription) {};
-
-        /**
-         * LocalOnlyHotspot started with the supplied config.
-         */
-        public void onStarted(SoftApConfiguration config) {};
-
-        /**
-         * LocalOnlyHotspot stopped.
-         */
-        public void onStopped() {};
-    }
-
-    /**
-     * Callback proxy for LocalOnlyHotspotObserver objects.
-     */
-    private static class LocalOnlyHotspotObserverProxy extends ILocalOnlyHotspotCallback.Stub {
-        private final WeakReference<WifiManager> mWifiManager;
-        private final Executor mExecutor;
-        private final LocalOnlyHotspotObserver mObserver;
-
-        /**
-         * Constructs a {@link LocalOnlyHotspotObserverProxy} using the specified looper.
-         * All callbacks will be delivered on the thread of the specified looper.
-         *
-         * @param manager WifiManager
-         * @param executor Executor for delivering callbacks
-         * @param observer LocalOnlyHotspotObserver to notify the calling application.
-         */
-        LocalOnlyHotspotObserverProxy(WifiManager manager, Executor executor,
-                final LocalOnlyHotspotObserver observer) {
-            mWifiManager = new WeakReference<>(manager);
-            mExecutor = executor;
-            mObserver = observer;
-        }
-
-        public void registered() throws RemoteException {
-            WifiManager manager = mWifiManager.get();
-            if (manager == null) return;
-
-            mExecutor.execute(() ->
-                    mObserver.onRegistered(manager.new LocalOnlyHotspotSubscription()));
-        }
-
-        @Override
-        public void onHotspotStarted(SoftApConfiguration config) {
-            WifiManager manager = mWifiManager.get();
-            if (manager == null) return;
-
-            if (config == null) {
-                Log.e(TAG, "LocalOnlyHotspotObserverProxy: config cannot be null.");
-                return;
-            }
-            mExecutor.execute(() -> mObserver.onStarted(config));
-        }
-
-        @Override
-        public void onHotspotStopped() {
-            WifiManager manager = mWifiManager.get();
-            if (manager == null) return;
-
-            mExecutor.execute(() -> mObserver.onStopped());
-        }
-
-        @Override
-        public void onHotspotFailed(int reason) {
-            // do nothing
-        }
-    }
-
-    /**
-     * Callback proxy for ActionListener objects.
-     */
-    private class ActionListenerProxy extends IActionListener.Stub {
-        private final String mActionTag;
-        private final Handler mHandler;
-        private final ActionListener mCallback;
-
-        ActionListenerProxy(String actionTag, Looper looper, ActionListener callback) {
-            mActionTag = actionTag;
-            mHandler = new Handler(looper);
-            mCallback = callback;
-        }
-
-        @Override
-        public void onSuccess() {
-            if (mVerboseLoggingEnabled) {
-                Log.v(TAG, "ActionListenerProxy:" + mActionTag + ": onSuccess");
-            }
-            mHandler.post(() -> {
-                mCallback.onSuccess();
-            });
-        }
-
-        @Override
-        public void onFailure(@ActionListenerFailureReason int reason) {
-            if (mVerboseLoggingEnabled) {
-                Log.v(TAG, "ActionListenerProxy:" + mActionTag + ": onFailure=" + reason);
-            }
-            mHandler.post(() -> {
-                mCallback.onFailure(reason);
-            });
-        }
-    }
-
-    private void connectInternal(@Nullable WifiConfiguration config, int networkId,
-            @Nullable ActionListener listener) {
-        ActionListenerProxy listenerProxy = null;
-        Binder binder = null;
-        if (listener != null) {
-            listenerProxy = new ActionListenerProxy("connect", mLooper, listener);
-            binder = new Binder();
-        }
-        try {
-            mService.connect(config, networkId, binder, listenerProxy,
-                    listener == null ? 0 : listener.hashCode());
-        } catch (RemoteException e) {
-            if (listenerProxy != null) listenerProxy.onFailure(ERROR);
-        } catch (SecurityException e) {
-            if (listenerProxy != null) listenerProxy.onFailure(NOT_AUTHORIZED);
-        }
-    }
-
-    /**
-     * Connect to a network with the given configuration. The network also
-     * gets added to the list of configured networks for the foreground user.
-     *
-     * For a new network, this function is used instead of a
-     * sequence of addNetwork(), enableNetwork(), and reconnect()
-     *
-     * @param config the set of variables that describe the configuration,
-     *            contained in a {@link WifiConfiguration} object.
-     * @param listener for callbacks on success or failure. Can be null.
-     * @throws IllegalStateException if the WifiManager instance needs to be
-     * initialized again
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(anyOf = {
-            android.Manifest.permission.NETWORK_SETTINGS,
-            android.Manifest.permission.NETWORK_SETUP_WIZARD,
-            android.Manifest.permission.NETWORK_STACK
-    })
-    public void connect(@NonNull WifiConfiguration config, @Nullable ActionListener listener) {
-        if (config == null) throw new IllegalArgumentException("config cannot be null");
-        connectInternal(config, WifiConfiguration.INVALID_NETWORK_ID, listener);
-    }
-
-    /**
-     * Connect to a network with the given networkId.
-     *
-     * This function is used instead of a enableNetwork() and reconnect()
-     *
-     * <li> This API will cause reconnect if the credentials of the current active
-     * connection has been changed.</li>
-     * <li> This API will cause reconnect if the current active connection is marked metered.</li>
-     *
-     * @param networkId the ID of the network as returned by {@link #addNetwork} or {@link
-     *        getConfiguredNetworks}.
-     * @param listener for callbacks on success or failure. Can be null.
-     * @throws IllegalStateException if the WifiManager instance needs to be
-     * initialized again
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(anyOf = {
-            android.Manifest.permission.NETWORK_SETTINGS,
-            android.Manifest.permission.NETWORK_SETUP_WIZARD,
-            android.Manifest.permission.NETWORK_STACK
-    })
-    public void connect(int networkId, @Nullable ActionListener listener) {
-        if (networkId < 0) throw new IllegalArgumentException("Network id cannot be negative");
-        connectInternal(null, networkId, listener);
-    }
-
-    /**
-     * Save the given network to the list of configured networks for the
-     * foreground user. If the network already exists, the configuration
-     * is updated. Any new network is enabled by default.
-     *
-     * For a new network, this function is used instead of a
-     * sequence of addNetwork() and enableNetwork().
-     *
-     * For an existing network, it accomplishes the task of updateNetwork()
-     *
-     * <li> This API will cause reconnect if the credentials of the current active
-     * connection has been changed.</li>
-     * <li> This API will cause disconnect if the current active connection is marked metered.</li>
-     *
-     * @param config the set of variables that describe the configuration,
-     *            contained in a {@link WifiConfiguration} object.
-     * @param listener for callbacks on success or failure. Can be null.
-     * @throws IllegalStateException if the WifiManager instance needs to be
-     * initialized again
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(anyOf = {
-            android.Manifest.permission.NETWORK_SETTINGS,
-            android.Manifest.permission.NETWORK_SETUP_WIZARD,
-            android.Manifest.permission.NETWORK_STACK
-    })
-    public void save(@NonNull WifiConfiguration config, @Nullable ActionListener listener) {
-        if (config == null) throw new IllegalArgumentException("config cannot be null");
-        ActionListenerProxy listenerProxy = null;
-        Binder binder = null;
-        if (listener != null) {
-            listenerProxy = new ActionListenerProxy("save", mLooper, listener);
-            binder = new Binder();
-        }
-        try {
-            mService.save(config, binder, listenerProxy,
-                    listener == null ? 0 : listener.hashCode());
-        } catch (RemoteException e) {
-            if (listenerProxy != null) listenerProxy.onFailure(ERROR);
-        } catch (SecurityException e) {
-            if (listenerProxy != null) listenerProxy.onFailure(NOT_AUTHORIZED);
-        }
-    }
-
-    /**
-     * Delete the network from the list of configured networks for the
-     * foreground user.
-     *
-     * This function is used instead of a sequence of removeNetwork()
-     *
-     * @param config the set of variables that describe the configuration,
-     *            contained in a {@link WifiConfiguration} object.
-     * @param listener for callbacks on success or failure. Can be null.
-     * @throws IllegalStateException if the WifiManager instance needs to be
-     * initialized again
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(anyOf = {
-            android.Manifest.permission.NETWORK_SETTINGS,
-            android.Manifest.permission.NETWORK_SETUP_WIZARD,
-            android.Manifest.permission.NETWORK_STACK
-    })
-    public void forget(int netId, @Nullable ActionListener listener) {
-        if (netId < 0) throw new IllegalArgumentException("Network id cannot be negative");
-        ActionListenerProxy listenerProxy = null;
-        Binder binder = null;
-        if (listener != null) {
-            listenerProxy = new ActionListenerProxy("forget", mLooper, listener);
-            binder = new Binder();
-        }
-        try {
-            mService.forget(netId, binder, listenerProxy,
-                    listener == null ? 0 : listener.hashCode());
-        } catch (RemoteException e) {
-            if (listenerProxy != null) listenerProxy.onFailure(ERROR);
-        } catch (SecurityException e) {
-            if (listenerProxy != null) listenerProxy.onFailure(NOT_AUTHORIZED);
-        }
-    }
-
-    /**
-     * Disable network
-     *
-     * @param netId is the network Id
-     * @param listener for callbacks on success or failure. Can be null.
-     * @throws IllegalStateException if the WifiManager instance needs to be
-     * initialized again
-     * @deprecated This API is deprecated. Use {@link #disableNetwork(int)} instead.
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(anyOf = {
-            android.Manifest.permission.NETWORK_SETTINGS,
-            android.Manifest.permission.NETWORK_SETUP_WIZARD,
-            android.Manifest.permission.NETWORK_STACK
-    })
-    @Deprecated
-    public void disable(int netId, @Nullable ActionListener listener) {
-        if (netId < 0) throw new IllegalArgumentException("Network id cannot be negative");
-        // Simple wrapper which forwards the call to disableNetwork. This is a temporary
-        // implementation until we can remove this API completely.
-        boolean status = disableNetwork(netId);
-        if (listener != null) {
-            if (status) {
-                listener.onSuccess();
-            } else {
-                listener.onFailure(ERROR);
-            }
-        }
-    }
-
-    /**
-     * Enable/disable auto-join globally.
-     *
-     * @param allowAutojoin true to allow auto-join, false to disallow auto-join
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public void allowAutojoinGlobal(boolean allowAutojoin) {
-        try {
-            mService.allowAutojoinGlobal(allowAutojoin);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-
-    /**
-     * Sets the user choice for allowing auto-join to a network.
-     * The updated choice will be made available through the updated config supplied by the
-     * CONFIGURED_NETWORKS_CHANGED broadcast.
-     *
-     * @param netId the id of the network to allow/disallow auto-join for.
-     * @param allowAutojoin true to allow auto-join, false to disallow auto-join
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public void allowAutojoin(int netId, boolean allowAutojoin) {
-        try {
-            mService.allowAutojoin(netId, allowAutojoin);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Configure auto-join settings for a Passpoint profile.
-     *
-     * @param fqdn the FQDN (fully qualified domain name) of the passpoint profile.
-     * @param allowAutojoin true to enable auto-join, false to disable auto-join.
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public void allowAutojoinPasspoint(@NonNull String fqdn, boolean allowAutojoin) {
-        try {
-            mService.allowAutojoinPasspoint(fqdn, allowAutojoin);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Configure MAC randomization setting for a Passpoint profile.
-     * MAC randomization is enabled by default.
-     *
-     * @param fqdn the FQDN (fully qualified domain name) of the passpoint profile.
-     * @param enable true to enable MAC randomization, false to disable MAC randomization.
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public void setMacRandomizationSettingPasspointEnabled(@NonNull String fqdn, boolean enable) {
-        try {
-            mService.setMacRandomizationSettingPasspointEnabled(fqdn, enable);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Sets the user's choice of metered override for a Passpoint profile.
-     *
-     * @param fqdn the FQDN (fully qualified domain name) of the passpoint profile.
-     * @param meteredOverride One of three values: {@link WifiConfiguration#METERED_OVERRIDE_NONE},
-     *                        {@link WifiConfiguration#METERED_OVERRIDE_METERED},
-     *                        {@link WifiConfiguration#METERED_OVERRIDE_NOT_METERED}
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public void setPasspointMeteredOverride(@NonNull String fqdn,
-            @WifiConfiguration.MeteredOverride int meteredOverride) {
-        try {
-            mService.setPasspointMeteredOverride(fqdn, meteredOverride);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Temporarily disable a network. Should always trigger with user disconnect network.
-     *
-     * @param network Input can be SSID or FQDN. And caller must ensure that the SSID passed thru
-     *                this API matched the WifiConfiguration.SSID rules, and thus be surrounded by
-     *                quotes.
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(anyOf = {
-            android.Manifest.permission.NETWORK_SETTINGS,
-            android.Manifest.permission.NETWORK_STACK
-    })
-    public void disableEphemeralNetwork(@NonNull String network) {
-        if (TextUtils.isEmpty(network)) {
-            throw new IllegalArgumentException("SSID cannot be null or empty!");
-        }
-        try {
-            mService.disableEphemeralNetwork(network, mContext.getOpPackageName());
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * WPS suport has been deprecated from Client mode and this method will immediately trigger
-     * {@link WpsCallback#onFailed(int)} with a generic error.
-     *
-     * @param config WPS configuration (does not support {@link WpsInfo#LABEL})
-     * @param listener for callbacks on success or failure. Can be null.
-     * @throws IllegalStateException if the WifiManager instance needs to be initialized again
-     * @deprecated This API is deprecated
-     */
-    public void startWps(WpsInfo config, WpsCallback listener) {
-        if (listener != null ) {
-            listener.onFailed(ERROR);
-        }
-    }
-
-    /**
-     * WPS support has been deprecated from Client mode and this method will immediately trigger
-     * {@link WpsCallback#onFailed(int)} with a generic error.
-     *
-     * @param listener for callbacks on success or failure. Can be null.
-     * @throws IllegalStateException if the WifiManager instance needs to be initialized again
-     * @deprecated This API is deprecated
-     */
-    public void cancelWps(WpsCallback listener) {
-        if (listener != null) {
-            listener.onFailed(ERROR);
-        }
-    }
-
-    /**
-     * Allows an application to keep the Wi-Fi radio awake.
-     * Normally the Wi-Fi radio may turn off when the user has not used the device in a while.
-     * Acquiring a WifiLock will keep the radio on until the lock is released.  Multiple
-     * applications may hold WifiLocks, and the radio will only be allowed to turn off when no
-     * WifiLocks are held in any application.
-     * <p>
-     * Before using a WifiLock, consider carefully if your application requires Wi-Fi access, or
-     * could function over a mobile network, if available.  A program that needs to download large
-     * files should hold a WifiLock to ensure that the download will complete, but a program whose
-     * network usage is occasional or low-bandwidth should not hold a WifiLock to avoid adversely
-     * affecting battery life.
-     * <p>
-     * Note that WifiLocks cannot override the user-level "Wi-Fi Enabled" setting, nor Airplane
-     * Mode.  They simply keep the radio from turning off when Wi-Fi is already on but the device
-     * is idle.
-     * <p>
-     * Any application using a WifiLock must request the {@code android.permission.WAKE_LOCK}
-     * permission in an {@code <uses-permission>} element of the application's manifest.
-     */
-    public class WifiLock {
-        private String mTag;
-        private final IBinder mBinder;
-        private int mRefCount;
-        int mLockType;
-        private boolean mRefCounted;
-        private boolean mHeld;
-        private WorkSource mWorkSource;
-
-        private WifiLock(int lockType, String tag) {
-            mTag = tag;
-            mLockType = lockType;
-            mBinder = new Binder();
-            mRefCount = 0;
-            mRefCounted = true;
-            mHeld = false;
-        }
-
-        /**
-         * Locks the Wi-Fi radio on until {@link #release} is called.
-         *
-         * If this WifiLock is reference-counted, each call to {@code acquire} will increment the
-         * reference count, and the radio will remain locked as long as the reference count is
-         * above zero.
-         *
-         * If this WifiLock is not reference-counted, the first call to {@code acquire} will lock
-         * the radio, but subsequent calls will be ignored.  Only one call to {@link #release}
-         * will be required, regardless of the number of times that {@code acquire} is called.
-         */
-        public void acquire() {
-            synchronized (mBinder) {
-                if (mRefCounted ? (++mRefCount == 1) : (!mHeld)) {
-                    try {
-                        mService.acquireWifiLock(mBinder, mLockType, mTag, mWorkSource);
-                        synchronized (WifiManager.this) {
-                            if (mActiveLockCount >= MAX_ACTIVE_LOCKS) {
-                                mService.releaseWifiLock(mBinder);
-                                throw new UnsupportedOperationException(
-                                            "Exceeded maximum number of wifi locks");
-                            }
-                            mActiveLockCount++;
-                        }
-                    } catch (RemoteException e) {
-                        throw e.rethrowFromSystemServer();
-                    }
-                    mHeld = true;
-                }
-            }
-        }
-
-        /**
-         * Unlocks the Wi-Fi radio, allowing it to turn off when the device is idle.
-         *
-         * If this WifiLock is reference-counted, each call to {@code release} will decrement the
-         * reference count, and the radio will be unlocked only when the reference count reaches
-         * zero.  If the reference count goes below zero (that is, if {@code release} is called
-         * a greater number of times than {@link #acquire}), an exception is thrown.
-         *
-         * If this WifiLock is not reference-counted, the first call to {@code release} (after
-         * the radio was locked using {@link #acquire}) will unlock the radio, and subsequent
-         * calls will be ignored.
-         */
-        public void release() {
-            synchronized (mBinder) {
-                if (mRefCounted ? (--mRefCount == 0) : (mHeld)) {
-                    try {
-                        mService.releaseWifiLock(mBinder);
-                        synchronized (WifiManager.this) {
-                            mActiveLockCount--;
-                        }
-                    } catch (RemoteException e) {
-                        throw e.rethrowFromSystemServer();
-                    }
-                    mHeld = false;
-                }
-                if (mRefCount < 0) {
-                    throw new RuntimeException("WifiLock under-locked " + mTag);
-                }
-            }
-        }
-
-        /**
-         * Controls whether this is a reference-counted or non-reference-counted WifiLock.
-         *
-         * Reference-counted WifiLocks keep track of the number of calls to {@link #acquire} and
-         * {@link #release}, and only allow the radio to sleep when every call to {@link #acquire}
-         * has been balanced with a call to {@link #release}.  Non-reference-counted WifiLocks
-         * lock the radio whenever {@link #acquire} is called and it is unlocked, and unlock the
-         * radio whenever {@link #release} is called and it is locked.
-         *
-         * @param refCounted true if this WifiLock should keep a reference count
-         */
-        public void setReferenceCounted(boolean refCounted) {
-            mRefCounted = refCounted;
-        }
-
-        /**
-         * Checks whether this WifiLock is currently held.
-         *
-         * @return true if this WifiLock is held, false otherwise
-         */
-        public boolean isHeld() {
-            synchronized (mBinder) {
-                return mHeld;
-            }
-        }
-
-        public void setWorkSource(WorkSource ws) {
-            synchronized (mBinder) {
-                if (ws != null && ws.isEmpty()) {
-                    ws = null;
-                }
-                boolean changed = true;
-                if (ws == null) {
-                    mWorkSource = null;
-                } else {
-                    ws = ws.withoutNames();
-                    if (mWorkSource == null) {
-                        changed = mWorkSource != null;
-                        mWorkSource = new WorkSource(ws);
-                    } else {
-                        changed = !mWorkSource.equals(ws);
-                        if (changed) {
-                            mWorkSource.set(ws);
-                        }
-                    }
-                }
-                if (changed && mHeld) {
-                    try {
-                        mService.updateWifiLockWorkSource(mBinder, mWorkSource);
-                    } catch (RemoteException e) {
-                        throw e.rethrowFromSystemServer();
-                    }
-                }
-            }
-        }
-
-        public String toString() {
-            String s1, s2, s3;
-            synchronized (mBinder) {
-                s1 = Integer.toHexString(System.identityHashCode(this));
-                s2 = mHeld ? "held; " : "";
-                if (mRefCounted) {
-                    s3 = "refcounted: refcount = " + mRefCount;
-                } else {
-                    s3 = "not refcounted";
-                }
-                return "WifiLock{ " + s1 + "; " + s2 + s3 + " }";
-            }
-        }
-
-        @Override
-        protected void finalize() throws Throwable {
-            super.finalize();
-            synchronized (mBinder) {
-                if (mHeld) {
-                    try {
-                        mService.releaseWifiLock(mBinder);
-                        synchronized (WifiManager.this) {
-                            mActiveLockCount--;
-                        }
-                    } catch (RemoteException e) {
-                        throw e.rethrowFromSystemServer();
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Creates a new WifiLock.
-     *
-     * @param lockType the type of lock to create. See {@link #WIFI_MODE_FULL_HIGH_PERF}
-     * and {@link #WIFI_MODE_FULL_LOW_LATENCY} for descriptions of the types of Wi-Fi locks.
-     * @param tag a tag for the WifiLock to identify it in debugging messages.  This string is
-     *            never shown to the user under normal conditions, but should be descriptive
-     *            enough to identify your application and the specific WifiLock within it, if it
-     *            holds multiple WifiLocks.
-     *
-     * @return a new, unacquired WifiLock with the given tag.
-     *
-     * @see WifiLock
-     */
-    public WifiLock createWifiLock(int lockType, String tag) {
-        return new WifiLock(lockType, tag);
-    }
-
-    /**
-     * Creates a new WifiLock.
-     *
-     * @param tag a tag for the WifiLock to identify it in debugging messages.  This string is
-     *            never shown to the user under normal conditions, but should be descriptive
-     *            enough to identify your application and the specific WifiLock within it, if it
-     *            holds multiple WifiLocks.
-     *
-     * @return a new, unacquired WifiLock with the given tag.
-     *
-     * @see WifiLock
-     *
-     * @deprecated This API is non-functional.
-     */
-    @Deprecated
-    public WifiLock createWifiLock(String tag) {
-        return new WifiLock(WIFI_MODE_FULL, tag);
-    }
-
-    /**
-     * Create a new MulticastLock
-     *
-     * @param tag a tag for the MulticastLock to identify it in debugging
-     *            messages.  This string is never shown to the user under
-     *            normal conditions, but should be descriptive enough to
-     *            identify your application and the specific MulticastLock
-     *            within it, if it holds multiple MulticastLocks.
-     *
-     * @return a new, unacquired MulticastLock with the given tag.
-     *
-     * @see MulticastLock
-     */
-    public MulticastLock createMulticastLock(String tag) {
-        return new MulticastLock(tag);
-    }
-
-    /**
-     * Allows an application to receive Wifi Multicast packets.
-     * Normally the Wifi stack filters out packets not explicitly
-     * addressed to this device.  Acquring a MulticastLock will
-     * cause the stack to receive packets addressed to multicast
-     * addresses.  Processing these extra packets can cause a noticeable
-     * battery drain and should be disabled when not needed.
-     */
-    public class MulticastLock {
-        private String mTag;
-        private final IBinder mBinder;
-        private int mRefCount;
-        private boolean mRefCounted;
-        private boolean mHeld;
-
-        private MulticastLock(String tag) {
-            mTag = tag;
-            mBinder = new Binder();
-            mRefCount = 0;
-            mRefCounted = true;
-            mHeld = false;
-        }
-
-        /**
-         * Locks Wifi Multicast on until {@link #release} is called.
-         *
-         * If this MulticastLock is reference-counted each call to
-         * {@code acquire} will increment the reference count, and the
-         * wifi interface will receive multicast packets as long as the
-         * reference count is above zero.
-         *
-         * If this MulticastLock is not reference-counted, the first call to
-         * {@code acquire} will turn on the multicast packets, but subsequent
-         * calls will be ignored.  Only one call to {@link #release} will
-         * be required, regardless of the number of times that {@code acquire}
-         * is called.
-         *
-         * Note that other applications may also lock Wifi Multicast on.
-         * Only they can relinquish their lock.
-         *
-         * Also note that applications cannot leave Multicast locked on.
-         * When an app exits or crashes, any Multicast locks will be released.
-         */
-        public void acquire() {
-            synchronized (mBinder) {
-                if (mRefCounted ? (++mRefCount == 1) : (!mHeld)) {
-                    try {
-                        mService.acquireMulticastLock(mBinder, mTag);
-                        synchronized (WifiManager.this) {
-                            if (mActiveLockCount >= MAX_ACTIVE_LOCKS) {
-                                mService.releaseMulticastLock(mTag);
-                                throw new UnsupportedOperationException(
-                                        "Exceeded maximum number of wifi locks");
-                            }
-                            mActiveLockCount++;
-                        }
-                    } catch (RemoteException e) {
-                        throw e.rethrowFromSystemServer();
-                    }
-                    mHeld = true;
-                }
-            }
-        }
-
-        /**
-         * Unlocks Wifi Multicast, restoring the filter of packets
-         * not addressed specifically to this device and saving power.
-         *
-         * If this MulticastLock is reference-counted, each call to
-         * {@code release} will decrement the reference count, and the
-         * multicast packets will only stop being received when the reference
-         * count reaches zero.  If the reference count goes below zero (that
-         * is, if {@code release} is called a greater number of times than
-         * {@link #acquire}), an exception is thrown.
-         *
-         * If this MulticastLock is not reference-counted, the first call to
-         * {@code release} (after the radio was multicast locked using
-         * {@link #acquire}) will unlock the multicast, and subsequent calls
-         * will be ignored.
-         *
-         * Note that if any other Wifi Multicast Locks are still outstanding
-         * this {@code release} call will not have an immediate effect.  Only
-         * when all applications have released all their Multicast Locks will
-         * the Multicast filter be turned back on.
-         *
-         * Also note that when an app exits or crashes all of its Multicast
-         * Locks will be automatically released.
-         */
-        public void release() {
-            synchronized (mBinder) {
-                if (mRefCounted ? (--mRefCount == 0) : (mHeld)) {
-                    try {
-                        mService.releaseMulticastLock(mTag);
-                        synchronized (WifiManager.this) {
-                            mActiveLockCount--;
-                        }
-                    } catch (RemoteException e) {
-                        throw e.rethrowFromSystemServer();
-                    }
-                    mHeld = false;
-                }
-                if (mRefCount < 0) {
-                    throw new RuntimeException("MulticastLock under-locked "
-                            + mTag);
-                }
-            }
-        }
-
-        /**
-         * Controls whether this is a reference-counted or non-reference-
-         * counted MulticastLock.
-         *
-         * Reference-counted MulticastLocks keep track of the number of calls
-         * to {@link #acquire} and {@link #release}, and only stop the
-         * reception of multicast packets when every call to {@link #acquire}
-         * has been balanced with a call to {@link #release}.  Non-reference-
-         * counted MulticastLocks allow the reception of multicast packets
-         * whenever {@link #acquire} is called and stop accepting multicast
-         * packets whenever {@link #release} is called.
-         *
-         * @param refCounted true if this MulticastLock should keep a reference
-         * count
-         */
-        public void setReferenceCounted(boolean refCounted) {
-            mRefCounted = refCounted;
-        }
-
-        /**
-         * Checks whether this MulticastLock is currently held.
-         *
-         * @return true if this MulticastLock is held, false otherwise
-         */
-        public boolean isHeld() {
-            synchronized (mBinder) {
-                return mHeld;
-            }
-        }
-
-        public String toString() {
-            String s1, s2, s3;
-            synchronized (mBinder) {
-                s1 = Integer.toHexString(System.identityHashCode(this));
-                s2 = mHeld ? "held; " : "";
-                if (mRefCounted) {
-                    s3 = "refcounted: refcount = " + mRefCount;
-                } else {
-                    s3 = "not refcounted";
-                }
-                return "MulticastLock{ " + s1 + "; " + s2 + s3 + " }";
-            }
-        }
-
-        @Override
-        protected void finalize() throws Throwable {
-            super.finalize();
-            setReferenceCounted(false);
-            release();
-        }
-    }
-
-    /**
-     * Check multicast filter status.
-     *
-     * @return true if multicast packets are allowed.
-     *
-     * @hide pending API council approval
-     */
-    public boolean isMulticastEnabled() {
-        try {
-            return mService.isMulticastEnabled();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Initialize the multicast filtering to 'on'
-     * @hide no intent to publish
-     */
-    @UnsupportedAppUsage
-    public boolean initializeMulticastFiltering() {
-        try {
-            mService.initializeMulticastFiltering();
-            return true;
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Set Wi-Fi verbose logging level from developer settings.
-     *
-     * @param enable true to enable verbose logging, false to disable.
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public void setVerboseLoggingEnabled(boolean enable) {
-        enableVerboseLogging(enable ? 1 : 0);
-    }
-
-    /** @hide */
-    @UnsupportedAppUsage(
-            maxTargetSdk = Build.VERSION_CODES.Q,
-            publicAlternatives = "Use {@code #setVerboseLoggingEnabled(boolean)} instead."
-    )
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public void enableVerboseLogging (int verbose) {
-        try {
-            mService.enableVerboseLogging(verbose);
-        } catch (Exception e) {
-            //ignore any failure here
-            Log.e(TAG, "enableVerboseLogging " + e.toString());
-        }
-    }
-
-    /**
-     * Get the persisted Wi-Fi verbose logging level, set by
-     * {@link #setVerboseLoggingEnabled(boolean)}.
-     * No permissions are required to call this method.
-     *
-     * @return true to indicate that verbose logging is enabled, false to indicate that verbose
-     * logging is disabled.
-     *
-     * @hide
-     */
-    @SystemApi
-    public boolean isVerboseLoggingEnabled() {
-        return getVerboseLoggingLevel() > 0;
-    }
-
-    /** @hide */
-    // TODO(b/145484145): remove once SUW stops calling this via reflection
-    @UnsupportedAppUsage(
-            maxTargetSdk = Build.VERSION_CODES.Q,
-            publicAlternatives = "Use {@code #isVerboseLoggingEnabled()} instead."
-    )
-    public int getVerboseLoggingLevel() {
-        try {
-            return mService.getVerboseLoggingLevel();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Removes all saved Wi-Fi networks, Passpoint configurations, ephemeral networks, Network
-     * Requests, and Network Suggestions.
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public void factoryReset() {
-        try {
-            mService.factoryReset(mContext.getOpPackageName());
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Get {@link Network} object of current wifi network, or null if not connected.
-     * @hide
-     */
-    @Nullable
-    @SystemApi
-    @RequiresPermission(anyOf = {
-            android.Manifest.permission.NETWORK_SETTINGS,
-            android.Manifest.permission.NETWORK_SETUP_WIZARD
-    })
-    public Network getCurrentNetwork() {
-        try {
-            return mService.getCurrentNetwork();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Deprecated
-     * returns false
-     * @hide
-     * @deprecated
-     */
-    public boolean setEnableAutoJoinWhenAssociated(boolean enabled) {
-        return false;
-    }
-
-    /**
-     * Deprecated
-     * returns false
-     * @hide
-     * @deprecated
-     */
-    public boolean getEnableAutoJoinWhenAssociated() {
-        return false;
-    }
-
-    /**
-     * Returns a byte stream representing the data that needs to be backed up to save the
-     * current Wifi state.
-     * This Wifi state can be restored by calling {@link #restoreBackupData(byte[])}.
-     * @hide
-     */
-    @NonNull
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public byte[] retrieveBackupData() {
-        try {
-            return mService.retrieveBackupData();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Restore state from the backed up data.
-     * @param data byte stream in the same format produced by {@link #retrieveBackupData()}
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public void restoreBackupData(@NonNull byte[] data) {
-        try {
-            mService.restoreBackupData(data);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Returns a byte stream representing the data that needs to be backed up to save the
-     * current soft ap config data.
-     *
-     * This soft ap config can be restored by calling {@link #restoreSoftApBackupData(byte[])}
-     * @hide
-     */
-    @NonNull
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public byte[] retrieveSoftApBackupData() {
-        try {
-            return mService.retrieveSoftApBackupData();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Returns soft ap config from the backed up data or null if data is invalid.
-     * @param data byte stream in the same format produced by {@link #retrieveSoftApBackupData()}
-     *
-     * @hide
-     */
-    @Nullable
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public SoftApConfiguration restoreSoftApBackupData(@NonNull byte[] data) {
-        try {
-            return mService.restoreSoftApBackupData(data);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Restore state from the older version of back up data.
-     * The old backup data was essentially a backup of wpa_supplicant.conf
-     * and ipconfig.txt file.
-     * @param supplicantData bytes representing wpa_supplicant.conf
-     * @param ipConfigData bytes representing ipconfig.txt
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public void restoreSupplicantBackupData(
-            @NonNull byte[] supplicantData, @NonNull byte[] ipConfigData) {
-        try {
-            mService.restoreSupplicantBackupData(supplicantData, ipConfigData);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Start subscription provisioning flow
-     *
-     * @param provider {@link OsuProvider} to provision with
-     * @param executor the Executor on which to run the callback.
-     * @param callback {@link ProvisioningCallback} for updates regarding provisioning flow
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(anyOf = {
-            android.Manifest.permission.NETWORK_SETTINGS,
-            android.Manifest.permission.NETWORK_SETUP_WIZARD
-    })
-    public void startSubscriptionProvisioning(@NonNull OsuProvider provider,
-            @NonNull @CallbackExecutor Executor executor, @NonNull ProvisioningCallback callback) {
-        // Verify arguments
-        if (executor == null) {
-            throw new IllegalArgumentException("executor must not be null");
-        }
-        if (callback == null) {
-            throw new IllegalArgumentException("callback must not be null");
-        }
-        try {
-            mService.startSubscriptionProvisioning(provider,
-                    new ProvisioningCallbackProxy(executor, callback));
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Helper class to support OSU Provisioning callbacks
-     */
-    private static class ProvisioningCallbackProxy extends IProvisioningCallback.Stub {
-        private final Executor mExecutor;
-        private final ProvisioningCallback mCallback;
-
-        ProvisioningCallbackProxy(Executor executor, ProvisioningCallback callback) {
-            mExecutor = executor;
-            mCallback = callback;
-        }
-
-        @Override
-        public void onProvisioningStatus(int status) {
-            mExecutor.execute(() -> mCallback.onProvisioningStatus(status));
-        }
-
-        @Override
-        public void onProvisioningFailure(int status) {
-            mExecutor.execute(() -> mCallback.onProvisioningFailure(status));
-        }
-
-        @Override
-        public void onProvisioningComplete() {
-            mExecutor.execute(() -> mCallback.onProvisioningComplete());
-        }
-    }
-
-    /**
-     * Interface for Traffic state callback. Should be extended by applications and set when
-     * calling {@link #registerTrafficStateCallback(Executor, WifiManager.TrafficStateCallback)}.
-     * @hide
-     */
-    @SystemApi
-    public interface TrafficStateCallback {
-        /** @hide */
-        @Retention(RetentionPolicy.SOURCE)
-        @IntDef(prefix = {"DATA_ACTIVITY_"}, value = {
-                DATA_ACTIVITY_NONE,
-                DATA_ACTIVITY_IN,
-                DATA_ACTIVITY_OUT,
-                DATA_ACTIVITY_INOUT})
-        @interface DataActivity {}
-
-        // Lowest bit indicates data reception and the second lowest bit indicates data transmitted
-        /** No data in or out */
-        int DATA_ACTIVITY_NONE         = 0x00;
-        /** Data in, no data out */
-        int DATA_ACTIVITY_IN           = 0x01;
-        /** Data out, no data in */
-        int DATA_ACTIVITY_OUT          = 0x02;
-        /** Data in and out */
-        int DATA_ACTIVITY_INOUT        = 0x03;
-
-        /**
-         * Callback invoked to inform clients about the current traffic state.
-         *
-         * @param state One of the values: {@link #DATA_ACTIVITY_NONE}, {@link #DATA_ACTIVITY_IN},
-         * {@link #DATA_ACTIVITY_OUT} & {@link #DATA_ACTIVITY_INOUT}.
-         */
-        void onStateChanged(@DataActivity int state);
-    }
-
-    /**
-     * Callback proxy for TrafficStateCallback objects.
-     *
-     * @hide
-     */
-    private class TrafficStateCallbackProxy extends ITrafficStateCallback.Stub {
-        private final Executor mExecutor;
-        private final TrafficStateCallback mCallback;
-
-        TrafficStateCallbackProxy(Executor executor, TrafficStateCallback callback) {
-            mExecutor = executor;
-            mCallback = callback;
-        }
-
-        @Override
-        public void onStateChanged(int state) {
-            if (mVerboseLoggingEnabled) {
-                Log.v(TAG, "TrafficStateCallbackProxy: onStateChanged state=" + state);
-            }
-            Binder.clearCallingIdentity();
-            mExecutor.execute(() -> {
-                mCallback.onStateChanged(state);
-            });
-        }
-    }
-
-    /**
-     * Registers a callback for monitoring traffic state. See {@link TrafficStateCallback}. These
-     * callbacks will be invoked periodically by platform to inform clients about the current
-     * traffic state. Caller can unregister a previously registered callback using
-     * {@link #unregisterTrafficStateCallback(TrafficStateCallback)}
-     * <p>
-     * Applications should have the
-     * {@link android.Manifest.permission#NETWORK_SETTINGS NETWORK_SETTINGS} permission. Callers
-     * without the permission will trigger a {@link java.lang.SecurityException}.
-     * <p>
-     *
-     * @param executor The Executor on whose thread to execute the callbacks of the {@code callback}
-     *                 object.
-     * @param callback Callback for traffic state events
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public void registerTrafficStateCallback(@NonNull @CallbackExecutor Executor executor,
-                                             @NonNull TrafficStateCallback callback) {
-        if (executor == null) throw new IllegalArgumentException("executor cannot be null");
-        if (callback == null) throw new IllegalArgumentException("callback cannot be null");
-        Log.v(TAG, "registerTrafficStateCallback: callback=" + callback + ", executor=" + executor);
-
-        Binder binder = new Binder();
-        try {
-            mService.registerTrafficStateCallback(
-                    binder, new TrafficStateCallbackProxy(executor, callback), callback.hashCode());
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Allow callers to unregister a previously registered callback. After calling this method,
-     * applications will no longer receive traffic state notifications.
-     *
-     * @param callback Callback to unregister for traffic state events
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public void unregisterTrafficStateCallback(@NonNull TrafficStateCallback callback) {
-        if (callback == null) throw new IllegalArgumentException("callback cannot be null");
-        Log.v(TAG, "unregisterTrafficStateCallback: callback=" + callback);
-
-        try {
-            mService.unregisterTrafficStateCallback(callback.hashCode());
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Helper method to update the local verbose logging flag based on the verbose logging
-     * level from wifi service.
-     */
-    private void updateVerboseLoggingEnabledFromService() {
-        mVerboseLoggingEnabled = isVerboseLoggingEnabled();
-    }
-
-    /**
-     * @return true if this device supports WPA3-Personal SAE
-     */
-    public boolean isWpa3SaeSupported() {
-        return isFeatureSupported(WIFI_FEATURE_WPA3_SAE);
-    }
-
-    /**
-     * @return true if this device supports WPA3-Enterprise Suite-B-192
-     */
-    public boolean isWpa3SuiteBSupported() {
-        return isFeatureSupported(WIFI_FEATURE_WPA3_SUITE_B);
-    }
-
-    /**
-     * @return true if this device supports Wi-Fi Enhanced Open (OWE)
-     */
-    public boolean isEnhancedOpenSupported() {
-        return isFeatureSupported(WIFI_FEATURE_OWE);
-    }
-
-    /**
-     * Wi-Fi Easy Connect (DPP) introduces standardized mechanisms to simplify the provisioning and
-     * configuration of Wi-Fi devices.
-     * For more details, visit <a href="https://www.wi-fi.org/">https://www.wi-fi.org/</a> and
-     * search for "Easy Connect" or "Device Provisioning Protocol specification".
-     *
-     * @return true if this device supports Wi-Fi Easy-connect (Device Provisioning Protocol)
-     */
-    public boolean isEasyConnectSupported() {
-        return isFeatureSupported(WIFI_FEATURE_DPP);
-    }
-
-    /**
-     * @return true if this device supports WAPI.
-     */
-    public boolean isWapiSupported() {
-        return isFeatureSupported(WIFI_FEATURE_WAPI);
-    }
-
-    /**
-     * Gets the factory Wi-Fi MAC addresses.
-     * @return Array of String representing Wi-Fi MAC addresses sorted lexically or an empty Array
-     * if failed.
-     * @hide
-     */
-    @NonNull
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public String[] getFactoryMacAddresses() {
-        try {
-            return mService.getFactoryMacAddresses();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(prefix = {"DEVICE_MOBILITY_STATE_"}, value = {
-            DEVICE_MOBILITY_STATE_UNKNOWN,
-            DEVICE_MOBILITY_STATE_HIGH_MVMT,
-            DEVICE_MOBILITY_STATE_LOW_MVMT,
-            DEVICE_MOBILITY_STATE_STATIONARY})
-    public @interface DeviceMobilityState {}
-
-    /**
-     * Unknown device mobility state
-     *
-     * @see #setDeviceMobilityState(int)
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int DEVICE_MOBILITY_STATE_UNKNOWN = 0;
-
-    /**
-     * High movement device mobility state.
-     * e.g. on a bike, in a motor vehicle
-     *
-     * @see #setDeviceMobilityState(int)
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int DEVICE_MOBILITY_STATE_HIGH_MVMT = 1;
-
-    /**
-     * Low movement device mobility state.
-     * e.g. walking, running
-     *
-     * @see #setDeviceMobilityState(int)
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int DEVICE_MOBILITY_STATE_LOW_MVMT = 2;
-
-    /**
-     * Stationary device mobility state
-     *
-     * @see #setDeviceMobilityState(int)
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int DEVICE_MOBILITY_STATE_STATIONARY = 3;
-
-    /**
-     * Updates the device mobility state. Wifi uses this information to adjust the interval between
-     * Wifi scans in order to balance power consumption with scan accuracy.
-     * The default mobility state when the device boots is {@link #DEVICE_MOBILITY_STATE_UNKNOWN}.
-     * This API should be called whenever there is a change in the mobility state.
-     * @param state the updated device mobility state
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.WIFI_SET_DEVICE_MOBILITY_STATE)
-    public void setDeviceMobilityState(@DeviceMobilityState int state) {
-        try {
-            mService.setDeviceMobilityState(state);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /* Easy Connect - AKA Device Provisioning Protocol (DPP) */
-
-    /**
-     * Easy Connect Network role: Station.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int EASY_CONNECT_NETWORK_ROLE_STA = 0;
-
-    /**
-     * Easy Connect Network role: Access Point.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int EASY_CONNECT_NETWORK_ROLE_AP = 1;
-
-    /** @hide */
-    @IntDef(prefix = {"EASY_CONNECT_NETWORK_ROLE_"}, value = {
-            EASY_CONNECT_NETWORK_ROLE_STA,
-            EASY_CONNECT_NETWORK_ROLE_AP,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface EasyConnectNetworkRole {
-    }
-
-    /**
-     * Start Easy Connect (DPP) in Configurator-Initiator role. The current device will initiate
-     * Easy Connect bootstrapping with a peer, and configure the peer with the SSID and password of
-     * the specified network using the Easy Connect protocol on an encrypted link.
-     *
-     * @param enrolleeUri         URI of the Enrollee obtained separately (e.g. QR code scanning)
-     * @param selectedNetworkId   Selected network ID to be sent to the peer
-     * @param enrolleeNetworkRole The network role of the enrollee
-     * @param callback            Callback for status updates
-     * @param executor            The Executor on which to run the callback.
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(anyOf = {
-            android.Manifest.permission.NETWORK_SETTINGS,
-            android.Manifest.permission.NETWORK_SETUP_WIZARD})
-    public void startEasyConnectAsConfiguratorInitiator(@NonNull String enrolleeUri,
-            int selectedNetworkId, @EasyConnectNetworkRole int enrolleeNetworkRole,
-            @NonNull @CallbackExecutor Executor executor,
-            @NonNull EasyConnectStatusCallback callback) {
-        Binder binder = new Binder();
-        try {
-            mService.startDppAsConfiguratorInitiator(binder, enrolleeUri, selectedNetworkId,
-                    enrolleeNetworkRole, new EasyConnectCallbackProxy(executor, callback));
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Start Easy Connect (DPP) in Enrollee-Initiator role. The current device will initiate Easy
-     * Connect bootstrapping with a peer, and receive the SSID and password from the peer
-     * configurator.
-     *
-     * @param configuratorUri URI of the Configurator obtained separately (e.g. QR code scanning)
-     * @param callback        Callback for status updates
-     * @param executor        The Executor on which to run the callback.
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(anyOf = {
-            android.Manifest.permission.NETWORK_SETTINGS,
-            android.Manifest.permission.NETWORK_SETUP_WIZARD})
-    public void startEasyConnectAsEnrolleeInitiator(@NonNull String configuratorUri,
-            @NonNull @CallbackExecutor Executor executor,
-            @NonNull EasyConnectStatusCallback callback) {
-        Binder binder = new Binder();
-        try {
-            mService.startDppAsEnrolleeInitiator(binder, configuratorUri,
-                    new EasyConnectCallbackProxy(executor, callback));
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Stop or abort a current Easy Connect (DPP) session. This call, once processed, will
-     * terminate any ongoing transaction, and clean up all associated resources. Caller should not
-     * expect any callbacks once this call is made. However, due to the asynchronous nature of
-     * this call, a callback may be fired if it was already pending in the queue.
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(anyOf = {
-            android.Manifest.permission.NETWORK_SETTINGS,
-            android.Manifest.permission.NETWORK_SETUP_WIZARD})
-    public void stopEasyConnectSession() {
-        try {
-            /* Request lower layers to stop/abort and clear resources */
-            mService.stopDppSession();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Helper class to support Easy Connect (DPP) callbacks
-     *
-     * @hide
-     */
-    private static class EasyConnectCallbackProxy extends IDppCallback.Stub {
-        private final Executor mExecutor;
-        private final EasyConnectStatusCallback mEasyConnectStatusCallback;
-
-        EasyConnectCallbackProxy(Executor executor,
-                EasyConnectStatusCallback easyConnectStatusCallback) {
-            mExecutor = executor;
-            mEasyConnectStatusCallback = easyConnectStatusCallback;
-        }
-
-        @Override
-        public void onSuccessConfigReceived(int newNetworkId) {
-            Log.d(TAG, "Easy Connect onSuccessConfigReceived callback");
-            Binder.clearCallingIdentity();
-            mExecutor.execute(() -> {
-                mEasyConnectStatusCallback.onEnrolleeSuccess(newNetworkId);
-            });
-        }
-
-        @Override
-        public void onSuccess(int status) {
-            Log.d(TAG, "Easy Connect onSuccess callback");
-            Binder.clearCallingIdentity();
-            mExecutor.execute(() -> {
-                mEasyConnectStatusCallback.onConfiguratorSuccess(status);
-            });
-        }
-
-        @Override
-        public void onFailure(int status, String ssid, String channelList,
-                int[] operatingClassArray) {
-            Log.d(TAG, "Easy Connect onFailure callback");
-            Binder.clearCallingIdentity();
-            mExecutor.execute(() -> {
-                SparseArray<int[]> channelListArray = parseDppChannelList(channelList);
-                mEasyConnectStatusCallback.onFailure(status, ssid, channelListArray,
-                        operatingClassArray);
-            });
-        }
-
-        @Override
-        public void onProgress(int status) {
-            Log.d(TAG, "Easy Connect onProgress callback");
-            Binder.clearCallingIdentity();
-            mExecutor.execute(() -> {
-                mEasyConnectStatusCallback.onProgress(status);
-            });
-        }
-    }
-
-    /**
-     * Interface for Wi-Fi usability statistics listener. Should be implemented by applications and
-     * set when calling {@link WifiManager#addOnWifiUsabilityStatsListener(Executor,
-     * OnWifiUsabilityStatsListener)}.
-     *
-     * @hide
-     */
-    @SystemApi
-    public interface OnWifiUsabilityStatsListener {
-        /**
-         * Called when Wi-Fi usability statistics is updated.
-         *
-         * @param seqNum The sequence number of statistics, used to derive the timing of updated
-         *               Wi-Fi usability statistics, set by framework and incremented by one after
-         *               each update.
-         * @param isSameBssidAndFreq The flag to indicate whether the BSSID and the frequency of
-         *                           network stays the same or not relative to the last update of
-         *                           Wi-Fi usability stats.
-         * @param stats The updated Wi-Fi usability statistics.
-         */
-        void onWifiUsabilityStats(int seqNum, boolean isSameBssidAndFreq,
-                @NonNull WifiUsabilityStatsEntry stats);
-    }
-
-    /**
-     * Adds a listener for Wi-Fi usability statistics. See {@link OnWifiUsabilityStatsListener}.
-     * Multiple listeners can be added. Callers will be invoked periodically by framework to
-     * inform clients about the current Wi-Fi usability statistics. Callers can remove a previously
-     * added listener using {@link removeOnWifiUsabilityStatsListener}.
-     *
-     * @param executor The executor on which callback will be invoked.
-     * @param listener Listener for Wifi usability statistics.
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE)
-    public void addOnWifiUsabilityStatsListener(@NonNull @CallbackExecutor Executor executor,
-            @NonNull OnWifiUsabilityStatsListener listener) {
-        if (executor == null) throw new IllegalArgumentException("executor cannot be null");
-        if (listener == null) throw new IllegalArgumentException("listener cannot be null");
-        if (mVerboseLoggingEnabled) {
-            Log.v(TAG, "addOnWifiUsabilityStatsListener: listener=" + listener);
-        }
-        try {
-            mService.addOnWifiUsabilityStatsListener(new Binder(),
-                    new IOnWifiUsabilityStatsListener.Stub() {
-                        @Override
-                        public void onWifiUsabilityStats(int seqNum, boolean isSameBssidAndFreq,
-                                WifiUsabilityStatsEntry stats) {
-                            if (mVerboseLoggingEnabled) {
-                                Log.v(TAG, "OnWifiUsabilityStatsListener: "
-                                        + "onWifiUsabilityStats: seqNum=" + seqNum);
-                            }
-                            Binder.clearCallingIdentity();
-                            executor.execute(() -> listener.onWifiUsabilityStats(
-                                    seqNum, isSameBssidAndFreq, stats));
-                        }
-                    },
-                    listener.hashCode()
-            );
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Allow callers to remove a previously registered listener. After calling this method,
-     * applications will no longer receive Wi-Fi usability statistics.
-     *
-     * @param listener Listener to remove the Wi-Fi usability statistics.
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE)
-    public void removeOnWifiUsabilityStatsListener(@NonNull OnWifiUsabilityStatsListener listener) {
-        if (listener == null) throw new IllegalArgumentException("listener cannot be null");
-        if (mVerboseLoggingEnabled) {
-            Log.v(TAG, "removeOnWifiUsabilityStatsListener: listener=" + listener);
-        }
-        try {
-            mService.removeOnWifiUsabilityStatsListener(listener.hashCode());
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Provide a Wi-Fi usability score information to be recorded (but not acted upon) by the
-     * framework. The Wi-Fi usability score is derived from {@link OnWifiUsabilityStatsListener}
-     * where a score is matched to Wi-Fi usability statistics using the sequence number. The score
-     * is used to quantify whether Wi-Fi is usable in a future time.
-     *
-     * @param seqNum Sequence number of the Wi-Fi usability score.
-     * @param score The Wi-Fi usability score, expected range: [0, 100].
-     * @param predictionHorizonSec Prediction horizon of the Wi-Fi usability score in second,
-     *                             expected range: [0, 30].
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE)
-    public void updateWifiUsabilityScore(int seqNum, int score, int predictionHorizonSec) {
-        try {
-            mService.updateWifiUsabilityScore(seqNum, score, predictionHorizonSec);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Abstract class for scan results callback. Should be extended by applications and set when
-     * calling {@link WifiManager#registerScanResultsCallback(Executor, ScanResultsCallback)}.
-     */
-    public abstract static class ScanResultsCallback {
-        private final ScanResultsCallbackProxy mScanResultsCallbackProxy;
-
-        public ScanResultsCallback() {
-            mScanResultsCallbackProxy = new ScanResultsCallbackProxy();
-        }
-
-        /**
-         * Called when new scan results are available.
-         * Clients should use {@link WifiManager#getScanResults()} to get the scan results.
-         */
-        public abstract void onScanResultsAvailable();
-
-        /*package*/ @NonNull ScanResultsCallbackProxy getProxy() {
-            return mScanResultsCallbackProxy;
-        }
-
-        private static class ScanResultsCallbackProxy extends IScanResultsCallback.Stub {
-            private final Object mLock = new Object();
-            @Nullable @GuardedBy("mLock") private Executor mExecutor;
-            @Nullable @GuardedBy("mLock") private ScanResultsCallback mCallback;
-
-            ScanResultsCallbackProxy() {
-                mCallback = null;
-                mExecutor = null;
-            }
-
-            /*package*/ void initProxy(@NonNull Executor executor,
-                    @NonNull ScanResultsCallback callback) {
-                synchronized (mLock) {
-                    mExecutor = executor;
-                    mCallback = callback;
-                }
-            }
-
-            /*package*/ void cleanUpProxy() {
-                synchronized (mLock) {
-                    mExecutor = null;
-                    mCallback = null;
-                }
-            }
-
-            @Override
-            public void onScanResultsAvailable() {
-                ScanResultsCallback callback;
-                Executor executor;
-                synchronized (mLock) {
-                    executor = mExecutor;
-                    callback = mCallback;
-                }
-                if (callback == null || executor == null) {
-                    return;
-                }
-                Binder.clearCallingIdentity();
-                executor.execute(callback::onScanResultsAvailable);
-            }
-        }
-
-    }
-
-    /**
-     * Register a callback for Scan Results. See {@link ScanResultsCallback}.
-     * Caller will receive the event when scan results are available.
-     * Caller should use {@link WifiManager#getScanResults()} requires
-     * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} to get the scan results.
-     * Caller can remove a previously registered callback using
-     * {@link WifiManager#unregisterScanResultsCallback(ScanResultsCallback)}
-     * Same caller can add multiple listeners.
-     * <p>
-     * Applications should have the
-     * {@link android.Manifest.permission#ACCESS_WIFI_STATE} permission. Callers
-     * without the permission will trigger a {@link java.lang.SecurityException}.
-     * <p>
-     *
-     * @param executor The executor to execute the callback of the {@code callback} object.
-     * @param callback callback for Scan Results events
-     */
-
-    @RequiresPermission(ACCESS_WIFI_STATE)
-    public void registerScanResultsCallback(@NonNull @CallbackExecutor Executor executor,
-            @NonNull ScanResultsCallback callback) {
-        if (executor == null) throw new IllegalArgumentException("executor cannot be null");
-        if (callback == null) throw new IllegalArgumentException("callback cannot be null");
-
-        Log.v(TAG, "registerScanResultsCallback: callback=" + callback
-                + ", executor=" + executor);
-        ScanResultsCallback.ScanResultsCallbackProxy proxy = callback.getProxy();
-        proxy.initProxy(executor, callback);
-        try {
-            mService.registerScanResultsCallback(proxy);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Allow callers to unregister a previously registered callback. After calling this method,
-     * applications will no longer receive Scan Results events.
-     *
-     * @param callback callback to unregister for Scan Results events
-     */
-    @RequiresPermission(ACCESS_WIFI_STATE)
-    public void unregisterScanResultsCallback(@NonNull ScanResultsCallback callback) {
-        if (callback == null) throw new IllegalArgumentException("callback cannot be null");
-        Log.v(TAG, "unregisterScanResultsCallback: Callback=" + callback);
-        ScanResultsCallback.ScanResultsCallbackProxy proxy = callback.getProxy();
-        try {
-            mService.unregisterScanResultsCallback(proxy);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        } finally {
-            proxy.cleanUpProxy();
-        }
-    }
-
-    /**
-     * Interface for suggestion connection status listener.
-     * Should be implemented by applications and set when calling
-     * {@link WifiManager#addSuggestionConnectionStatusListener(
-     * Executor, SuggestionConnectionStatusListener)}.
-     */
-    public interface SuggestionConnectionStatusListener {
-
-        /**
-         * Called when the framework attempted to connect to a suggestion provided by the
-         * registering app, but the connection to the suggestion failed.
-         * @param wifiNetworkSuggestion The suggestion which failed to connect.
-         * @param failureReason the connection failure reason code. One of
-         * {@link #STATUS_SUGGESTION_CONNECTION_FAILURE_ASSOCIATION},
-         * {@link #STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION},
-         * {@link #STATUS_SUGGESTION_CONNECTION_FAILURE_IP_PROVISIONING}
-         * {@link #STATUS_SUGGESTION_CONNECTION_FAILURE_UNKNOWN}
-         */
-        void onConnectionStatus(
-                @NonNull WifiNetworkSuggestion wifiNetworkSuggestion,
-                @SuggestionConnectionStatusCode int failureReason);
-    }
-
-    private class SuggestionConnectionStatusListenerProxy extends
-            ISuggestionConnectionStatusListener.Stub {
-        private final Executor mExecutor;
-        private final SuggestionConnectionStatusListener mListener;
-
-        SuggestionConnectionStatusListenerProxy(@NonNull Executor executor,
-                @NonNull SuggestionConnectionStatusListener listener) {
-            mExecutor = executor;
-            mListener = listener;
-        }
-
-        @Override
-        public void onConnectionStatus(@NonNull WifiNetworkSuggestion wifiNetworkSuggestion,
-                int failureReason) {
-            mExecutor.execute(() ->
-                    mListener.onConnectionStatus(wifiNetworkSuggestion, failureReason));
-        }
-
-    }
-
-    /**
-     * Add a listener for suggestion networks. See {@link SuggestionConnectionStatusListener}.
-     * Caller will receive the event when suggested network have connection failure.
-     * Caller can remove a previously registered listener using
-     * {@link WifiManager#removeSuggestionConnectionStatusListener(
-     * SuggestionConnectionStatusListener)}
-     * Same caller can add multiple listeners to monitor the event.
-     * <p>
-     * Applications should have the
-     * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} and
-     * {@link android.Manifest.permission#ACCESS_WIFI_STATE} permissions.
-     * Callers without the permission will trigger a {@link java.lang.SecurityException}.
-     * <p>
-     *
-     * @param executor The executor to execute the listener of the {@code listener} object.
-     * @param listener listener for suggestion network connection failure.
-     */
-    @RequiresPermission(allOf = {ACCESS_FINE_LOCATION, ACCESS_WIFI_STATE})
-    public void addSuggestionConnectionStatusListener(@NonNull @CallbackExecutor Executor executor,
-            @NonNull SuggestionConnectionStatusListener listener) {
-        if (listener == null) throw new IllegalArgumentException("Listener cannot be null");
-        if (executor == null) throw new IllegalArgumentException("Executor cannot be null");
-        Log.v(TAG, "addSuggestionConnectionStatusListener listener=" + listener
-                + ", executor=" + executor);
-        try {
-            mService.registerSuggestionConnectionStatusListener(new Binder(),
-                    new SuggestionConnectionStatusListenerProxy(executor, listener),
-                    listener.hashCode(), mContext.getOpPackageName(), mContext.getAttributionTag());
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-
-    }
-
-    /**
-     * Allow callers to remove a previously registered listener. After calling this method,
-     * applications will no longer receive suggestion connection events through that listener.
-     *
-     * @param listener listener to remove.
-     */
-    @RequiresPermission(ACCESS_WIFI_STATE)
-    public void removeSuggestionConnectionStatusListener(
-            @NonNull SuggestionConnectionStatusListener listener) {
-        if (listener == null) throw new IllegalArgumentException("Listener cannot be null");
-        Log.v(TAG, "removeSuggestionConnectionStatusListener: listener=" + listener);
-        try {
-            mService.unregisterSuggestionConnectionStatusListener(listener.hashCode(),
-                    mContext.getOpPackageName());
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Parse the list of channels the DPP enrollee reports when it fails to find an AP.
-     *
-     * @param channelList List of channels in the format defined in the DPP specification.
-     * @return A parsed sparse array, where the operating class is the key.
-     * @hide
-     */
-    @VisibleForTesting
-    public static SparseArray<int[]> parseDppChannelList(String channelList) {
-        SparseArray<int[]> channelListArray = new SparseArray<>();
-
-        if (TextUtils.isEmpty(channelList)) {
-            return channelListArray;
-        }
-        StringTokenizer str = new StringTokenizer(channelList, ",");
-        String classStr = null;
-        List<Integer> channelsInClass = new ArrayList<>();
-
-        try {
-            while (str.hasMoreElements()) {
-                String cur = str.nextToken();
-
-                /**
-                 * Example for a channel list:
-                 *
-                 * 81/1,2,3,4,5,6,7,8,9,10,11,115/36,40,44,48,118/52,56,60,64,121/100,104,108,112,
-                 * 116,120,124,128,132,136,140,0/144,124/149,153,157,161,125/165
-                 *
-                 * Detect operating class by the delimiter of '/' and use a string tokenizer with
-                 * ',' as a delimiter.
-                 */
-                int classDelim = cur.indexOf('/');
-                if (classDelim != -1) {
-                    if (classStr != null) {
-                        // Store the last channel array in the sparse array, where the operating
-                        // class is the key (as an integer).
-                        int[] channelsArray = new int[channelsInClass.size()];
-                        for (int i = 0; i < channelsInClass.size(); i++) {
-                            channelsArray[i] = channelsInClass.get(i);
-                        }
-                        channelListArray.append(Integer.parseInt(classStr), channelsArray);
-                        channelsInClass = new ArrayList<>();
-                    }
-
-                    // Init a new operating class and store the first channel
-                    classStr = cur.substring(0, classDelim);
-                    String channelStr = cur.substring(classDelim + 1);
-                    channelsInClass.add(Integer.parseInt(channelStr));
-                } else {
-                    if (classStr == null) {
-                        // Invalid format
-                        Log.e(TAG, "Cannot parse DPP channel list");
-                        return new SparseArray<>();
-                    }
-                    channelsInClass.add(Integer.parseInt(cur));
-                }
-            }
-
-            // Store the last array
-            if (classStr != null) {
-                int[] channelsArray = new int[channelsInClass.size()];
-                for (int i = 0; i < channelsInClass.size(); i++) {
-                    channelsArray[i] = channelsInClass.get(i);
-                }
-                channelListArray.append(Integer.parseInt(classStr), channelsArray);
-            }
-            return channelListArray;
-        } catch (NumberFormatException e) {
-            Log.e(TAG, "Cannot parse DPP channel list");
-            return new SparseArray<>();
-        }
-    }
-
-    /**
-     * Callback interface for framework to receive network status updates and trigger of updating
-     * {@link WifiUsabilityStatsEntry}.
-     *
-     * @hide
-     */
-    @SystemApi
-    public interface ScoreUpdateObserver {
-        /**
-         * Called by applications to indicate network status.
-         *
-         * @param sessionId The ID to indicate current Wi-Fi network connection obtained from
-         *                  {@link WifiConnectedNetworkScorer#onStart(int)}.
-         * @param score The score representing link quality of current Wi-Fi network connection.
-         *              Populated by connected network scorer in applications..
-         */
-        void notifyScoreUpdate(int sessionId, int score);
-
-        /**
-         * Called by applications to trigger an update of {@link WifiUsabilityStatsEntry}.
-         * To receive update applications need to add WifiUsabilityStatsEntry listener. See
-         * {@link addOnWifiUsabilityStatsListener(Executor, OnWifiUsabilityStatsListener)}.
-         *
-         * @param sessionId The ID to indicate current Wi-Fi network connection obtained from
-         *                  {@link WifiConnectedNetworkScorer#onStart(int)}.
-         */
-        void triggerUpdateOfWifiUsabilityStats(int sessionId);
-    }
-
-    /**
-     * Callback proxy for {@link ScoreUpdateObserver} objects.
-     *
-     * @hide
-     */
-    private class ScoreUpdateObserverProxy implements ScoreUpdateObserver {
-        private final IScoreUpdateObserver mScoreUpdateObserver;
-
-        private ScoreUpdateObserverProxy(IScoreUpdateObserver observer) {
-            mScoreUpdateObserver = observer;
-        }
-
-        @Override
-        public void notifyScoreUpdate(int sessionId, int score) {
-            try {
-                mScoreUpdateObserver.notifyScoreUpdate(sessionId, score);
-            } catch (RemoteException e) {
-                throw e.rethrowFromSystemServer();
-            }
-        }
-
-        @Override
-        public void triggerUpdateOfWifiUsabilityStats(int sessionId) {
-            try {
-                mScoreUpdateObserver.triggerUpdateOfWifiUsabilityStats(sessionId);
-            } catch (RemoteException e) {
-                throw e.rethrowFromSystemServer();
-            }
-        }
-    }
-
-    /**
-     * Interface for Wi-Fi connected network scorer. Should be implemented by applications and set
-     * when calling
-     * {@link WifiManager#setWifiConnectedNetworkScorer(Executor, WifiConnectedNetworkScorer)}.
-     *
-     * @hide
-     */
-    @SystemApi
-    public interface WifiConnectedNetworkScorer {
-        /**
-         * Called by framework to indicate the start of a network connection.
-         * @param sessionId The ID to indicate current Wi-Fi network connection.
-         */
-        void onStart(int sessionId);
-
-        /**
-         * Called by framework to indicate the end of a network connection.
-         * @param sessionId The ID to indicate current Wi-Fi network connection obtained from
-         *                  {@link WifiConnectedNetworkScorer#onStart(int)}.
-         */
-        void onStop(int sessionId);
-
-        /**
-         * Framework sets callback for score change events after application sets its scorer.
-         * @param observerImpl The instance for {@link WifiManager#ScoreUpdateObserver}. Should be
-         * implemented and instantiated by framework.
-         */
-        void onSetScoreUpdateObserver(@NonNull ScoreUpdateObserver observerImpl);
-    }
-
-    /**
-     * Callback proxy for {@link WifiConnectedNetworkScorer} objects.
-     *
-     * @hide
-     */
-    private class WifiConnectedNetworkScorerProxy extends IWifiConnectedNetworkScorer.Stub {
-        private Executor mExecutor;
-        private WifiConnectedNetworkScorer mScorer;
-
-        WifiConnectedNetworkScorerProxy(Executor executor, WifiConnectedNetworkScorer scorer) {
-            mExecutor = executor;
-            mScorer = scorer;
-        }
-
-        @Override
-        public void onStart(int sessionId) {
-            if (mVerboseLoggingEnabled) {
-                Log.v(TAG, "WifiConnectedNetworkScorer: " + "onStart: sessionId=" + sessionId);
-            }
-            Binder.clearCallingIdentity();
-            mExecutor.execute(() -> mScorer.onStart(sessionId));
-        }
-
-        @Override
-        public void onStop(int sessionId) {
-            if (mVerboseLoggingEnabled) {
-                Log.v(TAG, "WifiConnectedNetworkScorer: " + "onStop: sessionId=" + sessionId);
-            }
-            Binder.clearCallingIdentity();
-            mExecutor.execute(() -> mScorer.onStop(sessionId));
-        }
-
-        @Override
-        public void onSetScoreUpdateObserver(IScoreUpdateObserver observerImpl) {
-            if (mVerboseLoggingEnabled) {
-                Log.v(TAG, "WifiConnectedNetworkScorer: "
-                        + "onSetScoreUpdateObserver: observerImpl=" + observerImpl);
-            }
-            Binder.clearCallingIdentity();
-            mExecutor.execute(() -> mScorer.onSetScoreUpdateObserver(
-                    new ScoreUpdateObserverProxy(observerImpl)));
-        }
-    }
-
-    /**
-     * Set a callback for Wi-Fi connected network scorer.  See {@link WifiConnectedNetworkScorer}.
-     * Only a single scorer can be set. Caller will be invoked periodically by framework to inform
-     * client about start and stop of Wi-Fi connection. Caller can clear a previously set scorer
-     * using {@link clearWifiConnectedNetworkScorer()}.
-     *
-     * @param executor The executor on which callback will be invoked.
-     * @param scorer Scorer for Wi-Fi network implemented by application.
-     * @return true Scorer is set successfully.
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE)
-    public boolean setWifiConnectedNetworkScorer(@NonNull @CallbackExecutor Executor executor,
-            @NonNull WifiConnectedNetworkScorer scorer) {
-        if (executor == null) throw new IllegalArgumentException("executor cannot be null");
-        if (scorer == null) throw new IllegalArgumentException("scorer cannot be null");
-        if (mVerboseLoggingEnabled) {
-            Log.v(TAG, "setWifiConnectedNetworkScorer: scorer=" + scorer);
-        }
-        try {
-            return mService.setWifiConnectedNetworkScorer(new Binder(),
-                    new WifiConnectedNetworkScorerProxy(executor, scorer));
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Allow caller to clear a previously set scorer. After calling this method,
-     * client will no longer receive information about start and stop of Wi-Fi connection.
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE)
-    public void clearWifiConnectedNetworkScorer() {
-        if (mVerboseLoggingEnabled) {
-            Log.v(TAG, "clearWifiConnectedNetworkScorer");
-        }
-        try {
-            mService.clearWifiConnectedNetworkScorer();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Enable/disable wifi scan throttling from 3rd party apps.
-     *
-     * <p>
-     * The throttling limits for apps are described in
-     * <a href="Wi-Fi Scan Throttling">
-     * https://developer.android.com/guide/topics/connectivity/wifi-scan#wifi-scan-throttling</a>
-     * </p>
-     *
-     * @param enable true to allow scan throttling, false to disallow scan throttling.
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public void setScanThrottleEnabled(boolean enable) {
-        try {
-            mService.setScanThrottleEnabled(enable);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Get the persisted Wi-Fi scan throttle state. Defaults to true, unless changed by the user via
-     * Developer options.
-     *
-     * <p>
-     * The throttling limits for apps are described in
-     * <a href="Wi-Fi Scan Throttling">
-     * https://developer.android.com/guide/topics/connectivity/wifi-scan#wifi-scan-throttling</a>
-     * </p>
-     *
-     * @return true to indicate that scan throttling is enabled, false to indicate that scan
-     * throttling is disabled.
-     */
-    @RequiresPermission(ACCESS_WIFI_STATE)
-    public boolean isScanThrottleEnabled() {
-        try {
-            return mService.isScanThrottleEnabled();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Enable/disable wifi auto wakeup feature.
-     *
-     * <p>
-     * The feature is described in
-     * <a href="Wi-Fi Turn on automatically">
-     * https://source.android.com/devices/tech/connect/wifi-infrastructure
-     * #turn_on_wi-fi_automatically
-     * </a>
-     *
-     * @param enable true to enable, false to disable.
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public void setAutoWakeupEnabled(boolean enable) {
-        try {
-            mService.setAutoWakeupEnabled(enable);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Get the persisted Wi-Fi auto wakeup feature state. Defaults to false, unless changed by the
-     * user via Settings.
-     *
-     * <p>
-     * The feature is described in
-     * <a href="Wi-Fi Turn on automatically">
-     * https://source.android.com/devices/tech/connect/wifi-infrastructure
-     * #turn_on_wi-fi_automatically
-     * </a>
-     *
-     * @return true to indicate that wakeup feature is enabled, false to indicate that wakeup
-     * feature is disabled.
-     */
-    @RequiresPermission(ACCESS_WIFI_STATE)
-    public boolean isAutoWakeupEnabled() {
-        try {
-            return mService.isAutoWakeupEnabled();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-}
diff --git a/wifi/java/android/net/wifi/WifiNetworkAgentSpecifier.java b/wifi/java/android/net/wifi/WifiNetworkAgentSpecifier.java
deleted file mode 100644
index 0d13805..0000000
--- a/wifi/java/android/net/wifi/WifiNetworkAgentSpecifier.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import static com.android.internal.util.Preconditions.checkNotNull;
-import static com.android.internal.util.Preconditions.checkState;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.MacAddress;
-import android.net.MatchAllNetworkSpecifier;
-import android.net.NetworkRequest;
-import android.net.NetworkSpecifier;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.Objects;
-
-/**
- * Network specifier object used by wifi's {@link android.net.NetworkAgent}.
- * @hide
- */
-public final class WifiNetworkAgentSpecifier extends NetworkSpecifier implements Parcelable {
-    /**
-     * Security credentials for the currently connected network.
-     */
-    private final WifiConfiguration mWifiConfiguration;
-
-    public WifiNetworkAgentSpecifier(@NonNull WifiConfiguration wifiConfiguration) {
-        checkNotNull(wifiConfiguration);
-
-        mWifiConfiguration = wifiConfiguration;
-    }
-
-    /**
-     * @hide
-     */
-    public static final @android.annotation.NonNull Creator<WifiNetworkAgentSpecifier> CREATOR =
-            new Creator<WifiNetworkAgentSpecifier>() {
-                @Override
-                public WifiNetworkAgentSpecifier createFromParcel(@NonNull Parcel in) {
-                    WifiConfiguration wifiConfiguration = in.readParcelable(null);
-                    return new WifiNetworkAgentSpecifier(wifiConfiguration);
-                }
-
-                @Override
-                public WifiNetworkAgentSpecifier[] newArray(int size) {
-                    return new WifiNetworkAgentSpecifier[size];
-                }
-            };
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeParcelable(mWifiConfiguration, flags);
-    }
-
-    @Override
-    public boolean canBeSatisfiedBy(@Nullable NetworkSpecifier other) {
-        if (this == other) {
-            return true;
-        }
-        // Any generic requests should be satisifed by a specific wifi network.
-        if (other == null || other instanceof MatchAllNetworkSpecifier) {
-            return true;
-        }
-        if (other instanceof WifiNetworkSpecifier) {
-            return satisfiesNetworkSpecifier((WifiNetworkSpecifier) other);
-        }
-        return equals(other);
-    }
-
-    /**
-     * Match {@link WifiNetworkSpecifier} in app's {@link NetworkRequest} with the
-     * {@link WifiNetworkAgentSpecifier} in wifi platform's {@link android.net.NetworkAgent}.
-     */
-    public boolean satisfiesNetworkSpecifier(@NonNull WifiNetworkSpecifier ns) {
-        // None of these should be null by construction.
-        // {@link WifiNetworkSpecifier.Builder} enforces non-null in {@link WifiNetworkSpecifier}.
-        // {@link WifiNetworkFactory} ensures non-null in {@link WifiNetworkAgentSpecifier}.
-        checkNotNull(ns);
-        checkNotNull(ns.ssidPatternMatcher);
-        checkNotNull(ns.bssidPatternMatcher);
-        checkNotNull(ns.wifiConfiguration.allowedKeyManagement);
-        checkNotNull(this.mWifiConfiguration.SSID);
-        checkNotNull(this.mWifiConfiguration.BSSID);
-        checkNotNull(this.mWifiConfiguration.allowedKeyManagement);
-
-        final String ssidWithQuotes = this.mWifiConfiguration.SSID;
-        checkState(ssidWithQuotes.startsWith("\"") && ssidWithQuotes.endsWith("\""));
-        final String ssidWithoutQuotes = ssidWithQuotes.substring(1, ssidWithQuotes.length() - 1);
-        if (!ns.ssidPatternMatcher.match(ssidWithoutQuotes)) {
-            return false;
-        }
-        final MacAddress bssid = MacAddress.fromString(this.mWifiConfiguration.BSSID);
-        final MacAddress matchBaseAddress = ns.bssidPatternMatcher.first;
-        final MacAddress matchMask = ns.bssidPatternMatcher.second;
-        if (!bssid.matches(matchBaseAddress, matchMask))  {
-            return false;
-        }
-        if (!ns.wifiConfiguration.allowedKeyManagement.equals(
-                this.mWifiConfiguration.allowedKeyManagement)) {
-            return false;
-        }
-        return true;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(
-                mWifiConfiguration.SSID,
-                mWifiConfiguration.BSSID,
-                mWifiConfiguration.allowedKeyManagement);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (!(obj instanceof WifiNetworkAgentSpecifier)) {
-            return false;
-        }
-        WifiNetworkAgentSpecifier lhs = (WifiNetworkAgentSpecifier) obj;
-        return Objects.equals(this.mWifiConfiguration.SSID, lhs.mWifiConfiguration.SSID)
-                && Objects.equals(this.mWifiConfiguration.BSSID, lhs.mWifiConfiguration.BSSID)
-                && Objects.equals(this.mWifiConfiguration.allowedKeyManagement,
-                    lhs.mWifiConfiguration.allowedKeyManagement);
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder("WifiNetworkAgentSpecifier [");
-        sb.append("WifiConfiguration=")
-                .append(", SSID=").append(mWifiConfiguration.SSID)
-                .append(", BSSID=").append(mWifiConfiguration.BSSID)
-                .append("]");
-        return sb.toString();
-    }
-
-    @Override
-    public NetworkSpecifier redact() {
-        return null;
-    }
-}
diff --git a/wifi/java/android/net/wifi/WifiNetworkConnectionStatistics.java b/wifi/java/android/net/wifi/WifiNetworkConnectionStatistics.java
deleted file mode 100644
index 95b2e77..0000000
--- a/wifi/java/android/net/wifi/WifiNetworkConnectionStatistics.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Connection Statistics For a WiFi Network.
- * @hide
- */
-@SystemApi
-public class WifiNetworkConnectionStatistics implements Parcelable {
-    private static final String TAG = "WifiNetworkConnnectionStatistics";
-
-    public int numConnection;
-    public int numUsage;
-
-    public WifiNetworkConnectionStatistics(int connection, int usage) {
-        numConnection = connection;
-        numUsage = usage;
-    }
-
-    public WifiNetworkConnectionStatistics() { }
-
-    @NonNull
-    @Override
-    public String toString() {
-        StringBuilder sbuf = new StringBuilder();
-        sbuf.append("c=").append(numConnection);
-        sbuf.append(" u=").append(numUsage);
-        return sbuf.toString();
-    }
-
-
-    /** copy constructor*/
-    public WifiNetworkConnectionStatistics(WifiNetworkConnectionStatistics source) {
-        numConnection = source.numConnection;
-        numUsage = source.numUsage;
-    }
-
-    /** Implement the Parcelable interface */
-    public int describeContents() {
-        return 0;
-    }
-
-    /** Implement the Parcelable interface */
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(numConnection);
-        dest.writeInt(numUsage);
-    }
-
-    /** Implement the Parcelable interface */
-    public static final @android.annotation.NonNull Creator<WifiNetworkConnectionStatistics> CREATOR =
-        new Creator<WifiNetworkConnectionStatistics>() {
-            public WifiNetworkConnectionStatistics createFromParcel(Parcel in) {
-                int numConnection = in.readInt();
-                int numUsage = in.readInt();
-                WifiNetworkConnectionStatistics stats =
-                        new WifiNetworkConnectionStatistics(numConnection, numUsage);
-                return stats;
-            }
-
-            public WifiNetworkConnectionStatistics[] newArray(int size) {
-                return new WifiNetworkConnectionStatistics[size];
-            }
-        };
-}
diff --git a/wifi/java/android/net/wifi/WifiNetworkSpecifier.java b/wifi/java/android/net/wifi/WifiNetworkSpecifier.java
deleted file mode 100644
index e12bb91..0000000
--- a/wifi/java/android/net/wifi/WifiNetworkSpecifier.java
+++ /dev/null
@@ -1,584 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import static com.android.internal.util.Preconditions.checkNotNull;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.MacAddress;
-import android.net.NetworkRequest;
-import android.net.NetworkSpecifier;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.PatternMatcher;
-import android.text.TextUtils;
-import android.util.Pair;
-
-import java.nio.charset.CharsetEncoder;
-import java.nio.charset.StandardCharsets;
-import java.util.Objects;
-
-/**
- * Network specifier object used to request a local Wi-Fi network. Apps should use the
- * {@link WifiNetworkSpecifier.Builder} class to create an instance.
- */
-public final class WifiNetworkSpecifier extends NetworkSpecifier implements Parcelable {
-    private static final String TAG = "WifiNetworkSpecifier";
-
-    /**
-     * Builder used to create {@link WifiNetworkSpecifier} objects.
-     */
-    public static final class Builder {
-        private static final String MATCH_ALL_SSID_PATTERN_PATH = ".*";
-        private static final String MATCH_EMPTY_SSID_PATTERN_PATH = "";
-        private static final Pair<MacAddress, MacAddress> MATCH_NO_BSSID_PATTERN1 =
-                new Pair<>(MacAddress.BROADCAST_ADDRESS, MacAddress.BROADCAST_ADDRESS);
-        private static final Pair<MacAddress, MacAddress> MATCH_NO_BSSID_PATTERN2 =
-                new Pair<>(WifiManager.ALL_ZEROS_MAC_ADDRESS, MacAddress.BROADCAST_ADDRESS);
-        private static final Pair<MacAddress, MacAddress> MATCH_ALL_BSSID_PATTERN =
-                new Pair<>(WifiManager.ALL_ZEROS_MAC_ADDRESS, WifiManager.ALL_ZEROS_MAC_ADDRESS);
-        private static final MacAddress MATCH_EXACT_BSSID_PATTERN_MASK =
-                MacAddress.BROADCAST_ADDRESS;
-
-        /**
-         * SSID pattern match specified by the app.
-         */
-        private @Nullable PatternMatcher mSsidPatternMatcher;
-        /**
-         * BSSID pattern match specified by the app.
-         * Pair of <BaseAddress, Mask>.
-         */
-        private @Nullable Pair<MacAddress, MacAddress> mBssidPatternMatcher;
-        /**
-         * Whether this is an OWE network or not.
-         */
-        private boolean mIsEnhancedOpen;
-        /**
-         * Pre-shared key for use with WPA-PSK networks.
-         */
-        private @Nullable String mWpa2PskPassphrase;
-        /**
-         * Pre-shared key for use with WPA3-SAE networks.
-         */
-        private @Nullable String mWpa3SaePassphrase;
-        /**
-         * The enterprise configuration details specifying the EAP method,
-         * certificates and other settings associated with the WPA/WPA2-Enterprise networks.
-         */
-        private @Nullable WifiEnterpriseConfig mWpa2EnterpriseConfig;
-        /**
-         * The enterprise configuration details specifying the EAP method,
-         * certificates and other settings associated with the WPA3-Enterprise networks.
-         */
-        private @Nullable WifiEnterpriseConfig mWpa3EnterpriseConfig;
-        /**
-         * This is a network that does not broadcast its SSID, so an
-         * SSID-specific probe request must be used for scans.
-         */
-        private boolean mIsHiddenSSID;
-
-        public Builder() {
-            mSsidPatternMatcher = null;
-            mBssidPatternMatcher = null;
-            mIsEnhancedOpen = false;
-            mWpa2PskPassphrase = null;
-            mWpa3SaePassphrase = null;
-            mWpa2EnterpriseConfig = null;
-            mWpa3EnterpriseConfig = null;
-            mIsHiddenSSID = false;
-        }
-
-        /**
-         * Set the unicode SSID match pattern to use for filtering networks from scan results.
-         * <p>
-         * <li>Overrides any previous value set using {@link #setSsid(String)} or
-         * {@link #setSsidPattern(PatternMatcher)}.</li>
-         *
-         * @param ssidPattern Instance of {@link PatternMatcher} containing the UTF-8 encoded
-         *                    string pattern to use for matching the network's SSID.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         */
-        public @NonNull Builder setSsidPattern(@NonNull PatternMatcher ssidPattern) {
-            checkNotNull(ssidPattern);
-            mSsidPatternMatcher = ssidPattern;
-            return this;
-        }
-
-        /**
-         * Set the unicode SSID for the network.
-         * <p>
-         * <li>Sets the SSID to use for filtering networks from scan results. Will only match
-         * networks whose SSID is identical to the UTF-8 encoding of the specified value.</li>
-         * <li>Overrides any previous value set using {@link #setSsid(String)} or
-         * {@link #setSsidPattern(PatternMatcher)}.</li>
-         *
-         * @param ssid The SSID of the network. It must be valid Unicode.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         * @throws IllegalArgumentException if the SSID is not valid unicode.
-         */
-        public @NonNull Builder setSsid(@NonNull String ssid) {
-            checkNotNull(ssid);
-            final CharsetEncoder unicodeEncoder = StandardCharsets.UTF_8.newEncoder();
-            if (!unicodeEncoder.canEncode(ssid)) {
-                throw new IllegalArgumentException("SSID is not a valid unicode string");
-            }
-            mSsidPatternMatcher = new PatternMatcher(ssid, PatternMatcher.PATTERN_LITERAL);
-            return this;
-        }
-
-        /**
-         * Set the BSSID match pattern to use for filtering networks from scan results.
-         * Will match all networks with BSSID which satisfies the following:
-         * {@code BSSID & mask == baseAddress}.
-         * <p>
-         * <li>Overrides any previous value set using {@link #setBssid(MacAddress)} or
-         * {@link #setBssidPattern(MacAddress, MacAddress)}.</li>
-         *
-         * @param baseAddress Base address for BSSID pattern.
-         * @param mask Mask for BSSID pattern.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         */
-        public @NonNull Builder setBssidPattern(
-                @NonNull MacAddress baseAddress, @NonNull MacAddress mask) {
-            checkNotNull(baseAddress);
-            checkNotNull(mask);
-            mBssidPatternMatcher = Pair.create(baseAddress, mask);
-            return this;
-        }
-
-        /**
-         * Set the BSSID to use for filtering networks from scan results. Will only match network
-         * whose BSSID is identical to the specified value.
-         * <p>
-         * <li>Sets the BSSID to use for filtering networks from scan results. Will only match
-         * networks whose BSSID is identical to specified value.</li>
-         * <li>Overrides any previous value set using {@link #setBssid(MacAddress)} or
-         * {@link #setBssidPattern(MacAddress, MacAddress)}.</li>
-         *
-         * @param bssid BSSID of the network.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         */
-        public @NonNull Builder setBssid(@NonNull MacAddress bssid) {
-            checkNotNull(bssid);
-            mBssidPatternMatcher = Pair.create(bssid, MATCH_EXACT_BSSID_PATTERN_MASK);
-            return this;
-        }
-
-        /**
-         * Specifies whether this represents an Enhanced Open (OWE) network.
-         *
-         * @param isEnhancedOpen {@code true} to indicate that the network uses enhanced open,
-         *                       {@code false} otherwise.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         */
-        public @NonNull Builder setIsEnhancedOpen(boolean isEnhancedOpen) {
-            mIsEnhancedOpen = isEnhancedOpen;
-            return this;
-        }
-
-        /**
-         * Set the ASCII WPA2 passphrase for this network. Needed for authenticating to
-         * WPA2-PSK networks.
-         *
-         * @param passphrase passphrase of the network.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         * @throws IllegalArgumentException if the passphrase is not ASCII encodable.
-         */
-        public @NonNull Builder setWpa2Passphrase(@NonNull String passphrase) {
-            checkNotNull(passphrase);
-            final CharsetEncoder asciiEncoder = StandardCharsets.US_ASCII.newEncoder();
-            if (!asciiEncoder.canEncode(passphrase)) {
-                throw new IllegalArgumentException("passphrase not ASCII encodable");
-            }
-            mWpa2PskPassphrase = passphrase;
-            return this;
-        }
-
-        /**
-         * Set the ASCII WPA3 passphrase for this network. Needed for authenticating to WPA3-SAE
-         * networks.
-         *
-         * @param passphrase passphrase of the network.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         * @throws IllegalArgumentException if the passphrase is not ASCII encodable.
-         */
-        public @NonNull Builder setWpa3Passphrase(@NonNull String passphrase) {
-            checkNotNull(passphrase);
-            final CharsetEncoder asciiEncoder = StandardCharsets.US_ASCII.newEncoder();
-            if (!asciiEncoder.canEncode(passphrase)) {
-                throw new IllegalArgumentException("passphrase not ASCII encodable");
-            }
-            mWpa3SaePassphrase = passphrase;
-            return this;
-        }
-
-        /**
-         * Set the associated enterprise configuration for this network. Needed for authenticating
-         * to WPA2-EAP networks. See {@link WifiEnterpriseConfig} for description.
-         *
-         * @param enterpriseConfig Instance of {@link WifiEnterpriseConfig}.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         */
-        public @NonNull Builder setWpa2EnterpriseConfig(
-                @NonNull WifiEnterpriseConfig enterpriseConfig) {
-            checkNotNull(enterpriseConfig);
-            mWpa2EnterpriseConfig = new WifiEnterpriseConfig(enterpriseConfig);
-            return this;
-        }
-
-        /**
-         * Set the associated enterprise configuration for this network. Needed for authenticating
-         * to WPA3-Enterprise networks (standard and 192-bit security). See
-         * {@link WifiEnterpriseConfig} for description. For 192-bit security networks, both the
-         * client and CA certificates must be provided, and must be of type of either
-         * sha384WithRSAEncryption (OID 1.2.840.113549.1.1.12) or ecdsa-with-SHA384
-         * (OID 1.2.840.10045.4.3.3).
-         *
-         * @param enterpriseConfig Instance of {@link WifiEnterpriseConfig}.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         */
-        public @NonNull Builder setWpa3EnterpriseConfig(
-                @NonNull WifiEnterpriseConfig enterpriseConfig) {
-            checkNotNull(enterpriseConfig);
-            mWpa3EnterpriseConfig = new WifiEnterpriseConfig(enterpriseConfig);
-            return this;
-        }
-
-        /**
-         * Specifies whether this represents a hidden network.
-         * <p>
-         * <li>Setting this disallows the usage of {@link #setSsidPattern(PatternMatcher)} since
-         * hidden networks need to be explicitly probed for.</li>
-         * <li>If not set, defaults to false (i.e not a hidden network).</li>
-         *
-         * @param isHiddenSsid {@code true} to indicate that the network is hidden, {@code false}
-         *                     otherwise.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         */
-        public @NonNull Builder setIsHiddenSsid(boolean isHiddenSsid) {
-            mIsHiddenSSID = isHiddenSsid;
-            return this;
-        }
-
-        private void setSecurityParamsInWifiConfiguration(
-                @NonNull WifiConfiguration configuration) {
-            if (!TextUtils.isEmpty(mWpa2PskPassphrase)) { // WPA-PSK network.
-                configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_PSK);
-                // WifiConfiguration.preSharedKey needs quotes around ASCII password.
-                configuration.preSharedKey = "\"" + mWpa2PskPassphrase + "\"";
-            } else if (!TextUtils.isEmpty(mWpa3SaePassphrase)) { // WPA3-SAE network.
-                configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_SAE);
-                // WifiConfiguration.preSharedKey needs quotes around ASCII password.
-                configuration.preSharedKey = "\"" + mWpa3SaePassphrase + "\"";
-            } else if (mWpa2EnterpriseConfig != null) { // WPA-EAP network
-                configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP);
-                configuration.enterpriseConfig = mWpa2EnterpriseConfig;
-            } else if (mWpa3EnterpriseConfig != null) { // WPA3-Enterprise
-                if (mWpa3EnterpriseConfig.getEapMethod() == WifiEnterpriseConfig.Eap.TLS
-                        && WifiEnterpriseConfig.isSuiteBCipherCert(
-                        mWpa3EnterpriseConfig.getClientCertificate())
-                        && WifiEnterpriseConfig.isSuiteBCipherCert(
-                        mWpa3EnterpriseConfig.getCaCertificate())) {
-                    // WPA3-Enterprise in 192-bit security mode (Suite-B)
-                    configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP_SUITE_B);
-                } else {
-                    // WPA3-Enterprise
-                    configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP);
-                    configuration.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
-                    configuration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
-                    configuration.allowedPairwiseCiphers.set(
-                            WifiConfiguration.PairwiseCipher.GCMP_256);
-                    configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
-                    configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_256);
-                    configuration.requirePmf = true;
-                }
-                configuration.enterpriseConfig = mWpa3EnterpriseConfig;
-            } else if (mIsEnhancedOpen) { // OWE network
-                configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_OWE);
-            } else { // Open network
-                configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_OPEN);
-            }
-        }
-
-        /**
-         * Helper method to build WifiConfiguration object from the builder.
-         * @return Instance of {@link WifiConfiguration}.
-         */
-        private WifiConfiguration buildWifiConfiguration() {
-            final WifiConfiguration wifiConfiguration = new WifiConfiguration();
-            // WifiConfiguration.SSID needs quotes around unicode SSID.
-            if (mSsidPatternMatcher.getType() == PatternMatcher.PATTERN_LITERAL) {
-                wifiConfiguration.SSID = "\"" + mSsidPatternMatcher.getPath() + "\"";
-            }
-            if (mBssidPatternMatcher.second == MATCH_EXACT_BSSID_PATTERN_MASK) {
-                wifiConfiguration.BSSID = mBssidPatternMatcher.first.toString();
-            }
-            setSecurityParamsInWifiConfiguration(wifiConfiguration);
-            wifiConfiguration.hiddenSSID = mIsHiddenSSID;
-            return wifiConfiguration;
-        }
-
-        private boolean hasSetAnyPattern() {
-            return mSsidPatternMatcher != null || mBssidPatternMatcher != null;
-        }
-
-        private void setMatchAnyPatternIfUnset() {
-            if (mSsidPatternMatcher == null) {
-                mSsidPatternMatcher = new PatternMatcher(MATCH_ALL_SSID_PATTERN_PATH,
-                        PatternMatcher.PATTERN_SIMPLE_GLOB);
-            }
-            if (mBssidPatternMatcher == null) {
-                mBssidPatternMatcher = MATCH_ALL_BSSID_PATTERN;
-            }
-        }
-
-        private boolean hasSetMatchNonePattern() {
-            if (mSsidPatternMatcher.getType() != PatternMatcher.PATTERN_PREFIX
-                    && mSsidPatternMatcher.getPath().equals(MATCH_EMPTY_SSID_PATTERN_PATH)) {
-                return true;
-            }
-            if (mBssidPatternMatcher.equals(MATCH_NO_BSSID_PATTERN1)) {
-                return true;
-            }
-            if (mBssidPatternMatcher.equals(MATCH_NO_BSSID_PATTERN2)) {
-                return true;
-            }
-            return false;
-        }
-
-        private boolean hasSetMatchAllPattern() {
-            if ((mSsidPatternMatcher.match(MATCH_EMPTY_SSID_PATTERN_PATH))
-                    && mBssidPatternMatcher.equals(MATCH_ALL_BSSID_PATTERN)) {
-                return true;
-            }
-            return false;
-        }
-
-        private void validateSecurityParams() {
-            int numSecurityTypes = 0;
-            numSecurityTypes += mIsEnhancedOpen ? 1 : 0;
-            numSecurityTypes += !TextUtils.isEmpty(mWpa2PskPassphrase) ? 1 : 0;
-            numSecurityTypes += !TextUtils.isEmpty(mWpa3SaePassphrase) ? 1 : 0;
-            numSecurityTypes += mWpa2EnterpriseConfig != null ? 1 : 0;
-            numSecurityTypes += mWpa3EnterpriseConfig != null ? 1 : 0;
-            if (numSecurityTypes > 1) {
-                throw new IllegalStateException("only one of setIsEnhancedOpen, setWpa2Passphrase,"
-                        + "setWpa3Passphrase, setWpa2EnterpriseConfig or setWpa3EnterpriseConfig"
-                        + " can be invoked for network specifier");
-            }
-        }
-
-        /**
-         * Create a specifier object used to request a local Wi-Fi network. The generated
-         * {@link NetworkSpecifier} should be used in
-         * {@link NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} when building
-         * the {@link NetworkRequest}. These specifiers can only be used to request a local wifi
-         * network (i.e no internet capability). So, the device will not switch it's default route
-         * to wifi if there are other transports (cellular for example) available.
-         *<p>
-         * Note: Apps can set a combination of network match params:
-         * <li> SSID Pattern using {@link #setSsidPattern(PatternMatcher)} OR Specific SSID using
-         * {@link #setSsid(String)}. </li>
-         * AND/OR
-         * <li> BSSID Pattern using {@link #setBssidPattern(MacAddress, MacAddress)} OR Specific
-         * BSSID using {@link #setBssid(MacAddress)} </li>
-         * to trigger connection to a network that matches the set params.
-         * The system will find the set of networks matching the request and present the user
-         * with a system dialog which will allow the user to select a specific Wi-Fi network to
-         * connect to or to deny the request.
-         *</p>
-         *
-         * For example:
-         * To connect to an open network with a SSID prefix of "test" and a BSSID OUI of "10:03:23":
-         *
-         * <pre>{@code
-         * final NetworkSpecifier specifier =
-         *      new Builder()
-         *      .setSsidPattern(new PatternMatcher("test", PatterMatcher.PATTERN_PREFIX))
-         *      .setBssidPattern(MacAddress.fromString("10:03:23:00:00:00"),
-         *                       MacAddress.fromString("ff:ff:ff:00:00:00"))
-         *      .build()
-         * final NetworkRequest request =
-         *      new NetworkRequest.Builder()
-         *      .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
-         *      .removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-         *      .setNetworkSpecifier(specifier)
-         *      .build();
-         * final ConnectivityManager connectivityManager =
-         *      context.getSystemService(Context.CONNECTIVITY_SERVICE);
-         * final NetworkCallback networkCallback = new NetworkCallback() {
-         *      ...
-         *      {@literal @}Override
-         *      void onAvailable(...) {}
-         *      // etc.
-         * };
-         * connectivityManager.requestNetwork(request, networkCallback);
-         * }</pre>
-         *
-         * @return Instance of {@link NetworkSpecifier}.
-         * @throws IllegalStateException on invalid params set.
-         */
-        public @NonNull WifiNetworkSpecifier build() {
-            if (!hasSetAnyPattern()) {
-                throw new IllegalStateException("one of setSsidPattern/setSsid/setBssidPattern/"
-                        + "setBssid should be invoked for specifier");
-            }
-            setMatchAnyPatternIfUnset();
-            if (hasSetMatchNonePattern()) {
-                throw new IllegalStateException("cannot set match-none pattern for specifier");
-            }
-            if (hasSetMatchAllPattern()) {
-                throw new IllegalStateException("cannot set match-all pattern for specifier");
-            }
-            if (mIsHiddenSSID && mSsidPatternMatcher.getType() != PatternMatcher.PATTERN_LITERAL) {
-                throw new IllegalStateException("setSsid should also be invoked when "
-                        + "setIsHiddenSsid is invoked for network specifier");
-            }
-            validateSecurityParams();
-
-            return new WifiNetworkSpecifier(
-                    mSsidPatternMatcher,
-                    mBssidPatternMatcher,
-                    buildWifiConfiguration());
-        }
-    }
-
-    /**
-     * SSID pattern match specified by the app.
-     * @hide
-     */
-    public final PatternMatcher ssidPatternMatcher;
-
-    /**
-     * BSSID pattern match specified by the app.
-     * Pair of <BaseAddress, Mask>.
-     * @hide
-     */
-    public final Pair<MacAddress, MacAddress> bssidPatternMatcher;
-
-    /**
-     * Security credentials for the network.
-     * <p>
-     * Note: {@link WifiConfiguration#SSID} & {@link WifiConfiguration#BSSID} fields from
-     * WifiConfiguration are not used. Instead we use the {@link #ssidPatternMatcher} &
-     * {@link #bssidPatternMatcher} fields embedded directly
-     * within {@link WifiNetworkSpecifier}.
-     * @hide
-     */
-    public final WifiConfiguration wifiConfiguration;
-
-    /** @hide */
-    public WifiNetworkSpecifier() throws IllegalAccessException {
-        throw new IllegalAccessException("Use the builder to create an instance");
-    }
-
-    /** @hide */
-    public WifiNetworkSpecifier(@NonNull PatternMatcher ssidPatternMatcher,
-                                @NonNull Pair<MacAddress, MacAddress> bssidPatternMatcher,
-                                @NonNull WifiConfiguration wifiConfiguration) {
-        checkNotNull(ssidPatternMatcher);
-        checkNotNull(bssidPatternMatcher);
-        checkNotNull(wifiConfiguration);
-
-        this.ssidPatternMatcher = ssidPatternMatcher;
-        this.bssidPatternMatcher = bssidPatternMatcher;
-        this.wifiConfiguration = wifiConfiguration;
-    }
-
-    public static final @NonNull Creator<WifiNetworkSpecifier> CREATOR =
-            new Creator<WifiNetworkSpecifier>() {
-                @Override
-                public WifiNetworkSpecifier createFromParcel(Parcel in) {
-                    PatternMatcher ssidPatternMatcher = in.readParcelable(/* classLoader */null);
-                    MacAddress baseAddress = in.readParcelable(null);
-                    MacAddress mask = in.readParcelable(null);
-                    Pair<MacAddress, MacAddress> bssidPatternMatcher =
-                            Pair.create(baseAddress, mask);
-                    WifiConfiguration wifiConfiguration = in.readParcelable(null);
-                    return new WifiNetworkSpecifier(ssidPatternMatcher, bssidPatternMatcher,
-                            wifiConfiguration);
-                }
-
-                @Override
-                public WifiNetworkSpecifier[] newArray(int size) {
-                    return new WifiNetworkSpecifier[size];
-                }
-            };
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeParcelable(ssidPatternMatcher, flags);
-        dest.writeParcelable(bssidPatternMatcher.first, flags);
-        dest.writeParcelable(bssidPatternMatcher.second, flags);
-        dest.writeParcelable(wifiConfiguration, flags);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(
-                ssidPatternMatcher.getPath(), ssidPatternMatcher.getType(), bssidPatternMatcher,
-                wifiConfiguration.allowedKeyManagement);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (!(obj instanceof WifiNetworkSpecifier)) {
-            return false;
-        }
-        WifiNetworkSpecifier lhs = (WifiNetworkSpecifier) obj;
-        return Objects.equals(this.ssidPatternMatcher.getPath(),
-                    lhs.ssidPatternMatcher.getPath())
-                && Objects.equals(this.ssidPatternMatcher.getType(),
-                    lhs.ssidPatternMatcher.getType())
-                && Objects.equals(this.bssidPatternMatcher,
-                    lhs.bssidPatternMatcher)
-                && Objects.equals(this.wifiConfiguration.allowedKeyManagement,
-                    lhs.wifiConfiguration.allowedKeyManagement);
-    }
-
-    @Override
-    public String toString() {
-        return new StringBuilder()
-                .append("WifiNetworkSpecifier [")
-                .append(", SSID Match pattern=").append(ssidPatternMatcher)
-                .append(", BSSID Match pattern=").append(bssidPatternMatcher)
-                .append(", SSID=").append(wifiConfiguration.SSID)
-                .append(", BSSID=").append(wifiConfiguration.BSSID)
-                .append("]")
-                .toString();
-    }
-
-    /** @hide */
-    @Override
-    public boolean canBeSatisfiedBy(NetworkSpecifier other) {
-        if (other instanceof WifiNetworkAgentSpecifier) {
-            return ((WifiNetworkAgentSpecifier) other).satisfiesNetworkSpecifier(this);
-        }
-        // Specific requests are checked for equality although testing for equality of 2 patterns do
-        // not make much sense!
-        return equals(other);
-    }
-}
diff --git a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
deleted file mode 100644
index d8be1d2..0000000
--- a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
+++ /dev/null
@@ -1,986 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import static com.android.internal.util.Preconditions.checkNotNull;
-
-import android.annotation.IntRange;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
-import android.annotation.SystemApi;
-import android.net.MacAddress;
-import android.net.wifi.hotspot2.PasspointConfiguration;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.telephony.TelephonyManager;
-import android.text.TextUtils;
-
-import java.nio.charset.CharsetEncoder;
-import java.nio.charset.StandardCharsets;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * The Network Suggestion object is used to provide a Wi-Fi network for consideration when
- * auto-connecting to networks. Apps cannot directly create this object, they must use
- * {@link WifiNetworkSuggestion.Builder#build()} to obtain an instance of this object.
- *<p>
- * Apps can provide a list of such networks to the platform using
- * {@link WifiManager#addNetworkSuggestions(List)}.
- */
-public final class WifiNetworkSuggestion implements Parcelable {
-    /**
-     * Builder used to create {@link WifiNetworkSuggestion} objects.
-     */
-    public static final class Builder {
-        private static final int UNASSIGNED_PRIORITY = -1;
-
-        /**
-         * SSID of the network.
-         */
-        private String mSsid;
-        /**
-         * Optional BSSID within the network.
-         */
-        private MacAddress mBssid;
-        /**
-         * Whether this is an OWE network or not.
-         */
-        private boolean mIsEnhancedOpen;
-        /**
-         * Pre-shared key for use with WPA-PSK networks.
-         */
-        private @Nullable String mWpa2PskPassphrase;
-        /**
-         * Pre-shared key for use with WPA3-SAE networks.
-         */
-        private @Nullable String mWpa3SaePassphrase;
-        /**
-         * The enterprise configuration details specifying the EAP method,
-         * certificates and other settings associated with the WPA/WPA2-Enterprise networks.
-         */
-        private @Nullable WifiEnterpriseConfig mWpa2EnterpriseConfig;
-        /**
-         * The enterprise configuration details specifying the EAP method,
-         * certificates and other settings associated with the WPA3-Enterprise networks.
-         */
-        private @Nullable WifiEnterpriseConfig mWpa3EnterpriseConfig;
-        /**
-         * The passpoint config for use with Hotspot 2.0 network
-         */
-        private @Nullable PasspointConfiguration mPasspointConfiguration;
-        /**
-         * This is a network that does not broadcast its SSID, so an
-         * SSID-specific probe request must be used for scans.
-         */
-        private boolean mIsHiddenSSID;
-        /**
-         * Whether app needs to log in to captive portal to obtain Internet access.
-         */
-        private boolean mIsAppInteractionRequired;
-        /**
-         * Whether user needs to log in to captive portal to obtain Internet access.
-         */
-        private boolean mIsUserInteractionRequired;
-        /**
-         * Whether this network is metered or not.
-         */
-        private int mMeteredOverride;
-        /**
-         * Priority of this network among other network suggestions provided by the app.
-         * The lower the number, the higher the priority (i.e value of 0 = highest priority).
-         */
-        private int mPriority;
-
-        /**
-         * The carrier ID identifies the operator who provides this network configuration.
-         *    see {@link TelephonyManager#getSimCarrierId()}
-         */
-        private int mCarrierId;
-
-        /**
-         * Whether this network is shared credential with user to allow user manually connect.
-         */
-        private boolean mIsSharedWithUser;
-
-        /**
-         * Whether the setCredentialSharedWithUser have been called.
-         */
-        private boolean mIsSharedWithUserSet;
-
-        /**
-         * Whether this network is initialized with auto-join enabled (the default) or not.
-         */
-        private boolean mIsInitialAutojoinEnabled;
-
-        /**
-         * Pre-shared key for use with WAPI-PSK networks.
-         */
-        private @Nullable String mWapiPskPassphrase;
-
-        /**
-         * The enterprise configuration details specifying the EAP method,
-         * certificates and other settings associated with the WAPI networks.
-         */
-        private @Nullable WifiEnterpriseConfig mWapiEnterpriseConfig;
-
-        /**
-         * Whether this network will be brought up as untrusted (TRUSTED capability bit removed).
-         */
-        private boolean mIsNetworkUntrusted;
-
-        public Builder() {
-            mSsid = null;
-            mBssid =  null;
-            mIsEnhancedOpen = false;
-            mWpa2PskPassphrase = null;
-            mWpa3SaePassphrase = null;
-            mWpa2EnterpriseConfig = null;
-            mWpa3EnterpriseConfig = null;
-            mPasspointConfiguration = null;
-            mIsHiddenSSID = false;
-            mIsAppInteractionRequired = false;
-            mIsUserInteractionRequired = false;
-            mMeteredOverride = WifiConfiguration.METERED_OVERRIDE_NONE;
-            mIsSharedWithUser = true;
-            mIsSharedWithUserSet = false;
-            mIsInitialAutojoinEnabled = true;
-            mPriority = UNASSIGNED_PRIORITY;
-            mCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID;
-            mWapiPskPassphrase = null;
-            mWapiEnterpriseConfig = null;
-            mIsNetworkUntrusted = false;
-        }
-
-        /**
-         * Set the unicode SSID for the network.
-         * <p>
-         * <li>Overrides any previous value set using {@link #setSsid(String)}.</li>
-         *
-         * @param ssid The SSID of the network. It must be valid Unicode.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         * @throws IllegalArgumentException if the SSID is not valid unicode.
-         */
-        public @NonNull Builder setSsid(@NonNull String ssid) {
-            checkNotNull(ssid);
-            final CharsetEncoder unicodeEncoder = StandardCharsets.UTF_8.newEncoder();
-            if (!unicodeEncoder.canEncode(ssid)) {
-                throw new IllegalArgumentException("SSID is not a valid unicode string");
-            }
-            mSsid = new String(ssid);
-            return this;
-        }
-
-        /**
-         * Set the BSSID to use for filtering networks from scan results. Will only match network
-         * whose BSSID is identical to the specified value.
-         * <p>
-         * <li Sets a specific BSSID for the network suggestion. If set, only the specified BSSID
-         * with the specified SSID will be considered for connection.
-         * <li>If set, only the specified BSSID with the specified SSID will be considered for
-         * connection.</li>
-         * <li>If not set, all BSSIDs with the specified SSID will be considered for connection.
-         * </li>
-         * <li>Overrides any previous value set using {@link #setBssid(MacAddress)}.</li>
-         *
-         * @param bssid BSSID of the network.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         */
-        public @NonNull Builder setBssid(@NonNull MacAddress bssid) {
-            checkNotNull(bssid);
-            mBssid = MacAddress.fromBytes(bssid.toByteArray());
-            return this;
-        }
-
-        /**
-         * Specifies whether this represents an Enhanced Open (OWE) network.
-         *
-         * @param isEnhancedOpen {@code true} to indicate that the network used enhanced open,
-         *                       {@code false} otherwise.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         */
-        public @NonNull Builder setIsEnhancedOpen(boolean isEnhancedOpen) {
-            mIsEnhancedOpen = isEnhancedOpen;
-            return this;
-        }
-
-        /**
-         * Set the ASCII WPA2 passphrase for this network. Needed for authenticating to
-         * WPA2-PSK networks.
-         *
-         * @param passphrase passphrase of the network.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         * @throws IllegalArgumentException if the passphrase is not ASCII encodable.
-         */
-        public @NonNull Builder setWpa2Passphrase(@NonNull String passphrase) {
-            checkNotNull(passphrase);
-            final CharsetEncoder asciiEncoder = StandardCharsets.US_ASCII.newEncoder();
-            if (!asciiEncoder.canEncode(passphrase)) {
-                throw new IllegalArgumentException("passphrase not ASCII encodable");
-            }
-            mWpa2PskPassphrase = passphrase;
-            return this;
-        }
-
-        /**
-         * Set the ASCII WPA3 passphrase for this network. Needed for authenticating to WPA3-SAE
-         * networks.
-         *
-         * @param passphrase passphrase of the network.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         * @throws IllegalArgumentException if the passphrase is not ASCII encodable.
-         */
-        public @NonNull Builder setWpa3Passphrase(@NonNull String passphrase) {
-            checkNotNull(passphrase);
-            final CharsetEncoder asciiEncoder = StandardCharsets.US_ASCII.newEncoder();
-            if (!asciiEncoder.canEncode(passphrase)) {
-                throw new IllegalArgumentException("passphrase not ASCII encodable");
-            }
-            mWpa3SaePassphrase = passphrase;
-            return this;
-        }
-
-        /**
-         * Set the associated enterprise configuration for this network. Needed for authenticating
-         * to WPA2 enterprise networks. See {@link WifiEnterpriseConfig} for description.
-         *
-         * @param enterpriseConfig Instance of {@link WifiEnterpriseConfig}.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         * @throws IllegalArgumentException if configuration CA certificate or
-         *                                  AltSubjectMatch/DomainSuffixMatch is not set.
-         */
-        public @NonNull Builder setWpa2EnterpriseConfig(
-                @NonNull WifiEnterpriseConfig enterpriseConfig) {
-            checkNotNull(enterpriseConfig);
-            if (enterpriseConfig.isInsecure()) {
-                throw new IllegalArgumentException("Enterprise configuration is insecure");
-            }
-            mWpa2EnterpriseConfig = new WifiEnterpriseConfig(enterpriseConfig);
-            return this;
-        }
-
-        /**
-         * Set the associated enterprise configuration for this network. Needed for authenticating
-         * to WPA3-Enterprise networks (standard and 192-bit security). See
-         * {@link WifiEnterpriseConfig} for description. For 192-bit security networks, both the
-         * client and CA certificates must be provided, and must be of type of either
-         * sha384WithRSAEncryption (OID 1.2.840.113549.1.1.12) or ecdsa-with-SHA384
-         * (OID 1.2.840.10045.4.3.3).
-         *
-         * @param enterpriseConfig Instance of {@link WifiEnterpriseConfig}.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         * @throws IllegalArgumentException if configuration CA certificate or
-         *                                  AltSubjectMatch/DomainSuffixMatch is not set.
-         */
-        public @NonNull Builder setWpa3EnterpriseConfig(
-                @NonNull WifiEnterpriseConfig enterpriseConfig) {
-            checkNotNull(enterpriseConfig);
-            if (enterpriseConfig.isInsecure()) {
-                throw new IllegalArgumentException("Enterprise configuration is insecure");
-            }
-            mWpa3EnterpriseConfig = new WifiEnterpriseConfig(enterpriseConfig);
-            return this;
-        }
-
-        /**
-         * Set the associated Passpoint configuration for this network. Needed for authenticating
-         * to Hotspot 2.0 networks. See {@link PasspointConfiguration} for description.
-         *
-         * @param passpointConfig Instance of {@link PasspointConfiguration}.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         * @throws IllegalArgumentException if passpoint configuration is invalid.
-         */
-        public @NonNull Builder setPasspointConfig(
-                @NonNull PasspointConfiguration passpointConfig) {
-            checkNotNull(passpointConfig);
-            if (!passpointConfig.validate()) {
-                throw new IllegalArgumentException("Passpoint configuration is invalid");
-            }
-            mPasspointConfiguration = passpointConfig;
-            return this;
-        }
-
-        /**
-         * Set the carrier ID of the network operator. The carrier ID associates a Suggested
-         * network with a specific carrier (and therefore SIM). The carrier ID must be provided
-         * for any network which uses the SIM-based authentication: e.g. EAP-SIM, EAP-AKA,
-         * EAP-AKA', and EAP-PEAP with SIM-based phase 2 authentication.
-         * @param carrierId see {@link TelephonyManager#getSimCarrierId()}.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         *
-         * @hide
-         */
-        @SystemApi
-        @RequiresPermission(android.Manifest.permission.NETWORK_CARRIER_PROVISIONING)
-        public @NonNull Builder setCarrierId(int carrierId) {
-            mCarrierId = carrierId;
-            return this;
-        }
-
-        /**
-         * Set the ASCII WAPI passphrase for this network. Needed for authenticating to
-         * WAPI-PSK networks.
-         *
-         * @param passphrase passphrase of the network.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         * @throws IllegalArgumentException if the passphrase is not ASCII encodable.
-         *
-         */
-        public @NonNull Builder setWapiPassphrase(@NonNull String passphrase) {
-            checkNotNull(passphrase);
-            final CharsetEncoder asciiEncoder = StandardCharsets.US_ASCII.newEncoder();
-            if (!asciiEncoder.canEncode(passphrase)) {
-                throw new IllegalArgumentException("passphrase not ASCII encodable");
-            }
-            mWapiPskPassphrase = passphrase;
-            return this;
-        }
-
-        /**
-         * Set the associated enterprise configuration for this network. Needed for authenticating
-         * to WAPI-CERT networks. See {@link WifiEnterpriseConfig} for description.
-         *
-         * @param enterpriseConfig Instance of {@link WifiEnterpriseConfig}.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         */
-        public @NonNull Builder setWapiEnterpriseConfig(
-                @NonNull WifiEnterpriseConfig enterpriseConfig) {
-            checkNotNull(enterpriseConfig);
-            mWapiEnterpriseConfig = new WifiEnterpriseConfig(enterpriseConfig);
-            return this;
-        }
-
-        /**
-         * Specifies whether this represents a hidden network.
-         * <p>
-         * <li>If not set, defaults to false (i.e not a hidden network).</li>
-         *
-         * @param isHiddenSsid {@code true} to indicate that the network is hidden, {@code false}
-         *                     otherwise.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         */
-        public @NonNull Builder setIsHiddenSsid(boolean isHiddenSsid) {
-            mIsHiddenSSID = isHiddenSsid;
-            return this;
-        }
-
-        /**
-         * Specifies whether the app needs to log in to a captive portal to obtain Internet access.
-         * <p>
-         * This will dictate if the directed broadcast
-         * {@link WifiManager#ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION} will be sent to the
-         * app after successfully connecting to the network.
-         * Use this for captive portal type networks where the app needs to authenticate the user
-         * before the device can access the network.
-         * <p>
-         * <li>If not set, defaults to false (i.e no app interaction required).</li>
-         *
-         * @param isAppInteractionRequired {@code true} to indicate that app interaction is
-         *                                 required, {@code false} otherwise.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         */
-        public @NonNull Builder setIsAppInteractionRequired(boolean isAppInteractionRequired) {
-            mIsAppInteractionRequired = isAppInteractionRequired;
-            return this;
-        }
-
-        /**
-         * Specifies whether the user needs to log in to a captive portal to obtain Internet access.
-         * <p>
-         * <li>If not set, defaults to false (i.e no user interaction required).</li>
-         *
-         * @param isUserInteractionRequired {@code true} to indicate that user interaction is
-         *                                  required, {@code false} otherwise.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         */
-        public @NonNull Builder setIsUserInteractionRequired(boolean isUserInteractionRequired) {
-            mIsUserInteractionRequired = isUserInteractionRequired;
-            return this;
-        }
-
-        /**
-         * Specify the priority of this network among other network suggestions provided by the same
-         * app (priorities have no impact on suggestions by different apps). The higher the number,
-         * the higher the priority (i.e value of 0 = lowest priority).
-         * <p>
-         * <li>If not set, defaults a lower priority than any assigned priority.</li>
-         *
-         * @param priority Integer number representing the priority among suggestions by the app.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         * @throws IllegalArgumentException if the priority value is negative.
-         */
-        public @NonNull Builder setPriority(@IntRange(from = 0) int priority) {
-            if (priority < 0) {
-                throw new IllegalArgumentException("Invalid priority value " + priority);
-            }
-            mPriority = priority;
-            return this;
-        }
-
-        /**
-         * Specifies whether this network is metered.
-         * <p>
-         * <li>If not set, defaults to detect automatically.</li>
-         *
-         * @param isMetered {@code true} to indicate that the network is metered, {@code false}
-         *                  for not metered.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         */
-        public @NonNull Builder setIsMetered(boolean isMetered) {
-            if (isMetered) {
-                mMeteredOverride = WifiConfiguration.METERED_OVERRIDE_METERED;
-            } else {
-                mMeteredOverride = WifiConfiguration.METERED_OVERRIDE_NOT_METERED;
-            }
-            return this;
-        }
-
-        /**
-         * Specifies whether the network credentials provided with this suggestion can be used by
-         * the user to explicitly (manually) connect to this network. If true this network will
-         * appear in the Wi-Fi Picker (in Settings) and the user will be able to select and connect
-         * to it with the provided credentials. If false, the user will need to enter network
-         * credentials and the resulting configuration will become a user saved network.
-         * <p>
-         * <li>Note: Only valid for secure (non-open) networks.
-         * <li>If not set, defaults to true (i.e. allow user to manually connect) for secure
-         * networks and false for open networks.</li>
-         *
-         * @param isShared {@code true} to indicate that the credentials may be used by the user to
-         *                              manually connect to the network, {@code false} otherwise.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         */
-        public @NonNull Builder setCredentialSharedWithUser(boolean isShared) {
-            mIsSharedWithUser = isShared;
-            mIsSharedWithUserSet = true;
-            return this;
-        }
-
-        /**
-         * Specifies whether the suggestion is created with auto-join enabled or disabled. The
-         * user may modify the auto-join configuration of a suggestion directly once the device
-         * associates to the network.
-         * <p>
-         * If auto-join is initialized as disabled the user may still be able to manually connect
-         * to the network. Therefore, disabling auto-join only makes sense if
-         * {@link #setCredentialSharedWithUser(boolean)} is set to true (the default) which
-         * itself implies a secure (non-open) network.
-         * <p>
-         * If not set, defaults to true (i.e. auto-join is initialized as enabled).
-         *
-         * @param enabled true for initializing with auto-join enabled (the default), false to
-         *                initializing with auto-join disabled.
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         */
-        public @NonNull Builder setIsInitialAutojoinEnabled(boolean enabled) {
-            mIsInitialAutojoinEnabled = enabled;
-            return this;
-        }
-
-        /**
-         * Specifies whether the system will bring up the network (if selected) as untrusted. An
-         * untrusted network has its {@link android.net.NetworkCapabilities#NET_CAPABILITY_TRUSTED}
-         * capability removed. The Wi-Fi network selection process may use this information to
-         * influence priority of the suggested network for Wi-Fi network selection (most likely to
-         * reduce it). The connectivity service may use this information to influence the overall
-         * network configuration of the device.
-         * <p>
-         * <li> An untrusted network's credentials may not be shared with the user using
-         * {@link #setCredentialSharedWithUser(boolean)}.</li>
-         * <li> If not set, defaults to false (i.e. network is trusted).</li>
-         *
-         * @param isUntrusted Boolean indicating whether the network should be brought up untrusted
-         *                    (if true) or trusted (if false).
-         * @return Instance of {@link Builder} to enable chaining of the builder method.
-         */
-        public @NonNull Builder setUntrusted(boolean isUntrusted) {
-            mIsNetworkUntrusted = isUntrusted;
-            return this;
-        }
-
-        private void setSecurityParamsInWifiConfiguration(
-                @NonNull WifiConfiguration configuration) {
-            if (!TextUtils.isEmpty(mWpa2PskPassphrase)) { // WPA-PSK network.
-                configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_PSK);
-                // WifiConfiguration.preSharedKey needs quotes around ASCII password.
-                configuration.preSharedKey = "\"" + mWpa2PskPassphrase + "\"";
-            } else if (!TextUtils.isEmpty(mWpa3SaePassphrase)) { // WPA3-SAE network.
-                configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_SAE);
-                // WifiConfiguration.preSharedKey needs quotes around ASCII password.
-                configuration.preSharedKey = "\"" + mWpa3SaePassphrase + "\"";
-            } else if (mWpa2EnterpriseConfig != null) { // WPA-EAP network
-                configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP);
-                configuration.enterpriseConfig = mWpa2EnterpriseConfig;
-            } else if (mWpa3EnterpriseConfig != null) { // WPA3-Enterprise
-                if (mWpa3EnterpriseConfig.getEapMethod() == WifiEnterpriseConfig.Eap.TLS
-                        && WifiEnterpriseConfig.isSuiteBCipherCert(
-                        mWpa3EnterpriseConfig.getClientCertificate())
-                        && WifiEnterpriseConfig.isSuiteBCipherCert(
-                        mWpa3EnterpriseConfig.getCaCertificate())) {
-                    // WPA3-Enterprise in 192-bit security mode (Suite-B)
-                    configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP_SUITE_B);
-                } else {
-                    // WPA3-Enterprise
-                    configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP);
-                    configuration.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
-                    configuration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
-                    configuration.allowedPairwiseCiphers.set(
-                            WifiConfiguration.PairwiseCipher.GCMP_256);
-                    configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
-                    configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_256);
-                    configuration.requirePmf = true;
-                }
-                configuration.enterpriseConfig = mWpa3EnterpriseConfig;
-            } else if (mIsEnhancedOpen) { // OWE network
-                configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_OWE);
-            } else if (!TextUtils.isEmpty(mWapiPskPassphrase)) { // WAPI-PSK network.
-                configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_WAPI_PSK);
-                // WifiConfiguration.preSharedKey needs quotes around ASCII password.
-                configuration.preSharedKey = "\"" + mWapiPskPassphrase + "\"";
-            } else if (mWapiEnterpriseConfig != null) { // WAPI-CERT network
-                configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_WAPI_CERT);
-                configuration.enterpriseConfig = mWapiEnterpriseConfig;
-            } else { // Open network
-                configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_OPEN);
-            }
-        }
-
-        /**
-         * Helper method to build WifiConfiguration object from the builder.
-         * @return Instance of {@link WifiConfiguration}.
-         */
-        private WifiConfiguration buildWifiConfiguration() {
-            final WifiConfiguration wifiConfiguration = new WifiConfiguration();
-            // WifiConfiguration.SSID needs quotes around unicode SSID.
-            wifiConfiguration.SSID = "\"" + mSsid + "\"";
-            if (mBssid != null) {
-                wifiConfiguration.BSSID = mBssid.toString();
-            }
-
-            setSecurityParamsInWifiConfiguration(wifiConfiguration);
-
-            wifiConfiguration.hiddenSSID = mIsHiddenSSID;
-            wifiConfiguration.priority = mPriority;
-            wifiConfiguration.meteredOverride = mMeteredOverride;
-            wifiConfiguration.carrierId = mCarrierId;
-            wifiConfiguration.trusted = !mIsNetworkUntrusted;
-            return wifiConfiguration;
-        }
-
-        private void validateSecurityParams() {
-            int numSecurityTypes = 0;
-            numSecurityTypes += mIsEnhancedOpen ? 1 : 0;
-            numSecurityTypes += !TextUtils.isEmpty(mWpa2PskPassphrase) ? 1 : 0;
-            numSecurityTypes += !TextUtils.isEmpty(mWpa3SaePassphrase) ? 1 : 0;
-            numSecurityTypes += !TextUtils.isEmpty(mWapiPskPassphrase) ? 1 : 0;
-            numSecurityTypes += mWpa2EnterpriseConfig != null ? 1 : 0;
-            numSecurityTypes += mWpa3EnterpriseConfig != null ? 1 : 0;
-            numSecurityTypes += mWapiEnterpriseConfig != null ? 1 : 0;
-            numSecurityTypes += mPasspointConfiguration != null ? 1 : 0;
-            if (numSecurityTypes > 1) {
-                throw new IllegalStateException("only one of setIsEnhancedOpen, setWpa2Passphrase,"
-                        + " setWpa3Passphrase, setWpa2EnterpriseConfig, setWpa3EnterpriseConfig"
-                        + " setWapiPassphrase, setWapiCertSuite, setIsWapiCertSuiteAuto"
-                        + " or setPasspointConfig can be invoked for network suggestion");
-            }
-        }
-
-        private WifiConfiguration buildWifiConfigurationForPasspoint() {
-            WifiConfiguration wifiConfiguration = new WifiConfiguration();
-            wifiConfiguration.FQDN = mPasspointConfiguration.getHomeSp().getFqdn();
-            wifiConfiguration.setPasspointUniqueId(mPasspointConfiguration.getUniqueId());
-            wifiConfiguration.priority = mPriority;
-            wifiConfiguration.meteredOverride = mMeteredOverride;
-            wifiConfiguration.trusted = !mIsNetworkUntrusted;
-            mPasspointConfiguration.setCarrierId(mCarrierId);
-            mPasspointConfiguration.setMeteredOverride(wifiConfiguration.meteredOverride);
-            return wifiConfiguration;
-        }
-
-        /**
-         * Create a network suggestion object for use in
-         * {@link WifiManager#addNetworkSuggestions(List)}.
-         *
-         *<p class="note">
-         * <b>Note:</b> Apps can set a combination of SSID using {@link #setSsid(String)} and BSSID
-         * using {@link #setBssid(MacAddress)} to provide more fine grained network suggestions to
-         * the platform.
-         * </p>
-         *
-         * For example:
-         * To provide credentials for one open, one WPA2, one WPA3 network with their
-         * corresponding SSID's and one with Passpoint config:
-         *
-         * <pre>{@code
-         * final WifiNetworkSuggestion suggestion1 =
-         *      new Builder()
-         *      .setSsid("test111111")
-         *      .build();
-         * final WifiNetworkSuggestion suggestion2 =
-         *      new Builder()
-         *      .setSsid("test222222")
-         *      .setWpa2Passphrase("test123456")
-         *      .build();
-         * final WifiNetworkSuggestion suggestion3 =
-         *      new Builder()
-         *      .setSsid("test333333")
-         *      .setWpa3Passphrase("test6789")
-         *      .build();
-         * final PasspointConfiguration passpointConfig= new PasspointConfiguration();
-         * // configure passpointConfig to include a valid Passpoint configuration
-         * final WifiNetworkSuggestion suggestion4 =
-         *      new Builder()
-         *      .setPasspointConfig(passpointConfig)
-         *      .build();
-         * final List<WifiNetworkSuggestion> suggestionsList =
-         *      new ArrayList<WifiNetworkSuggestion> { {
-         *          add(suggestion1);
-         *          add(suggestion2);
-         *          add(suggestion3);
-         *          add(suggestion4);
-         *      } };
-         * final WifiManager wifiManager =
-         *      context.getSystemService(Context.WIFI_SERVICE);
-         * wifiManager.addNetworkSuggestions(suggestionsList);
-         * // ...
-         * }</pre>
-         *
-         * @return Instance of {@link WifiNetworkSuggestion}
-         * @throws IllegalStateException on invalid params set
-         * @see WifiNetworkSuggestion
-         */
-        public @NonNull WifiNetworkSuggestion build() {
-            validateSecurityParams();
-            WifiConfiguration wifiConfiguration;
-            if (mPasspointConfiguration != null) {
-                if (mSsid != null) {
-                    throw new IllegalStateException("setSsid should not be invoked for suggestion "
-                            + "with Passpoint configuration");
-                }
-                if (mIsHiddenSSID) {
-                    throw new IllegalStateException("setIsHiddenSsid should not be invoked for "
-                            + "suggestion with Passpoint configuration");
-                }
-                wifiConfiguration = buildWifiConfigurationForPasspoint();
-            } else {
-                if (mSsid == null) {
-                    throw new IllegalStateException("setSsid should be invoked for suggestion");
-                }
-                if (TextUtils.isEmpty(mSsid)) {
-                    throw new IllegalStateException("invalid ssid for suggestion");
-                }
-                if (mBssid != null
-                        && (mBssid.equals(MacAddress.BROADCAST_ADDRESS)
-                        || mBssid.equals(WifiManager.ALL_ZEROS_MAC_ADDRESS))) {
-                    throw new IllegalStateException("invalid bssid for suggestion");
-                }
-                wifiConfiguration = buildWifiConfiguration();
-                if (wifiConfiguration.isOpenNetwork()) {
-                    if (mIsSharedWithUserSet && mIsSharedWithUser) {
-                        throw new IllegalStateException("Open network should not be "
-                                + "setCredentialSharedWithUser to true");
-                    }
-                    mIsSharedWithUser = false;
-                }
-            }
-            if (!mIsSharedWithUser && !mIsInitialAutojoinEnabled) {
-                throw new IllegalStateException("Should have not a network with both "
-                        + "setCredentialSharedWithUser and "
-                        + "setIsAutojoinEnabled set to false");
-            }
-            if (mIsNetworkUntrusted) {
-                if (mIsSharedWithUserSet && mIsSharedWithUser) {
-                    throw new IllegalStateException("Should not be both"
-                            + "setCredentialSharedWithUser and +"
-                            + "setIsNetworkAsUntrusted to true");
-                }
-                mIsSharedWithUser = false;
-            }
-            return new WifiNetworkSuggestion(
-                    wifiConfiguration,
-                    mPasspointConfiguration,
-                    mIsAppInteractionRequired,
-                    mIsUserInteractionRequired,
-                    mIsSharedWithUser,
-                    mIsInitialAutojoinEnabled);
-        }
-    }
-
-    /**
-     * Network configuration for the provided network.
-     * @hide
-     */
-    @NonNull
-    public final WifiConfiguration wifiConfiguration;
-
-    /**
-     * Passpoint configuration for the provided network.
-     * @hide
-     */
-    @Nullable
-    public final PasspointConfiguration passpointConfiguration;
-
-    /**
-     * Whether app needs to log in to captive portal to obtain Internet access.
-     * @hide
-     */
-    public final boolean isAppInteractionRequired;
-
-    /**
-     * Whether user needs to log in to captive portal to obtain Internet access.
-     * @hide
-     */
-    public final boolean isUserInteractionRequired;
-
-    /**
-     * Whether app share credential with the user, allow user use provided credential to
-     * connect network manually.
-     * @hide
-     */
-    public final boolean isUserAllowedToManuallyConnect;
-
-    /**
-     * Whether the suggestion will be initialized as auto-joined or not.
-     * @hide
-     */
-    public final boolean isInitialAutoJoinEnabled;
-
-    /** @hide */
-    public WifiNetworkSuggestion() {
-        this.wifiConfiguration = new WifiConfiguration();
-        this.passpointConfiguration = null;
-        this.isAppInteractionRequired = false;
-        this.isUserInteractionRequired = false;
-        this.isUserAllowedToManuallyConnect = true;
-        this.isInitialAutoJoinEnabled = true;
-    }
-
-    /** @hide */
-    public WifiNetworkSuggestion(@NonNull WifiConfiguration networkConfiguration,
-                                 @Nullable PasspointConfiguration passpointConfiguration,
-                                 boolean isAppInteractionRequired,
-                                 boolean isUserInteractionRequired,
-                                 boolean isUserAllowedToManuallyConnect,
-                                 boolean isInitialAutoJoinEnabled) {
-        checkNotNull(networkConfiguration);
-        this.wifiConfiguration = networkConfiguration;
-        this.passpointConfiguration = passpointConfiguration;
-
-        this.isAppInteractionRequired = isAppInteractionRequired;
-        this.isUserInteractionRequired = isUserInteractionRequired;
-        this.isUserAllowedToManuallyConnect = isUserAllowedToManuallyConnect;
-        this.isInitialAutoJoinEnabled = isInitialAutoJoinEnabled;
-    }
-
-    public static final @NonNull Creator<WifiNetworkSuggestion> CREATOR =
-            new Creator<WifiNetworkSuggestion>() {
-                @Override
-                public WifiNetworkSuggestion createFromParcel(Parcel in) {
-                    return new WifiNetworkSuggestion(
-                            in.readParcelable(null), // wifiConfiguration
-                            in.readParcelable(null), // PasspointConfiguration
-                            in.readBoolean(), // isAppInteractionRequired
-                            in.readBoolean(), // isUserInteractionRequired
-                            in.readBoolean(), // isSharedCredentialWithUser
-                            in.readBoolean()  // isAutojoinEnabled
-                    );
-                }
-
-                @Override
-                public WifiNetworkSuggestion[] newArray(int size) {
-                    return new WifiNetworkSuggestion[size];
-                }
-            };
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeParcelable(wifiConfiguration, flags);
-        dest.writeParcelable(passpointConfiguration, flags);
-        dest.writeBoolean(isAppInteractionRequired);
-        dest.writeBoolean(isUserInteractionRequired);
-        dest.writeBoolean(isUserAllowedToManuallyConnect);
-        dest.writeBoolean(isInitialAutoJoinEnabled);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(wifiConfiguration.SSID, wifiConfiguration.BSSID,
-                wifiConfiguration.allowedKeyManagement, wifiConfiguration.getKey());
-    }
-
-    /**
-     * Equals for network suggestions.
-     */
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (!(obj instanceof WifiNetworkSuggestion)) {
-            return false;
-        }
-        WifiNetworkSuggestion lhs = (WifiNetworkSuggestion) obj;
-        if (this.passpointConfiguration == null ^ lhs.passpointConfiguration == null) {
-            return false;
-        }
-
-        return TextUtils.equals(this.wifiConfiguration.SSID, lhs.wifiConfiguration.SSID)
-                && TextUtils.equals(this.wifiConfiguration.BSSID, lhs.wifiConfiguration.BSSID)
-                && Objects.equals(this.wifiConfiguration.allowedKeyManagement,
-                lhs.wifiConfiguration.allowedKeyManagement)
-                && TextUtils.equals(this.wifiConfiguration.getKey(),
-                lhs.wifiConfiguration.getKey());
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder("WifiNetworkSuggestion[ ")
-                .append("SSID=").append(wifiConfiguration.SSID)
-                .append(", BSSID=").append(wifiConfiguration.BSSID)
-                .append(", FQDN=").append(wifiConfiguration.FQDN)
-                .append(", isAppInteractionRequired=").append(isAppInteractionRequired)
-                .append(", isUserInteractionRequired=").append(isUserInteractionRequired)
-                .append(", isCredentialSharedWithUser=").append(isUserAllowedToManuallyConnect)
-                .append(", isInitialAutoJoinEnabled=").append(isInitialAutoJoinEnabled)
-                .append(", isUnTrusted=").append(!wifiConfiguration.trusted)
-                .append(" ]");
-        return sb.toString();
-    }
-
-    /**
-     * Get the {@link WifiConfiguration} associated with this Suggestion.
-     * @hide
-     */
-    @SystemApi
-    @NonNull
-    public WifiConfiguration getWifiConfiguration() {
-        return wifiConfiguration;
-    }
-
-    /**
-     * Get the BSSID, or null if unset.
-     * @see Builder#setBssid(MacAddress)
-     */
-    @Nullable
-    public MacAddress getBssid() {
-        if (wifiConfiguration.BSSID == null) {
-            return null;
-        }
-        return MacAddress.fromString(wifiConfiguration.BSSID);
-    }
-
-    /** @see Builder#setCredentialSharedWithUser(boolean) */
-    public boolean isCredentialSharedWithUser() {
-        return isUserAllowedToManuallyConnect;
-    }
-
-    /** @see Builder#setIsAppInteractionRequired(boolean) */
-    public boolean isAppInteractionRequired() {
-        return isAppInteractionRequired;
-    }
-
-    /** @see Builder#setIsEnhancedOpen(boolean)  */
-    public boolean isEnhancedOpen() {
-        return wifiConfiguration.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.OWE);
-    }
-
-    /** @see Builder#setIsHiddenSsid(boolean)  */
-    public boolean isHiddenSsid() {
-        return wifiConfiguration.hiddenSSID;
-    }
-
-    /** @see Builder#setIsInitialAutojoinEnabled(boolean)  */
-    public boolean isInitialAutojoinEnabled() {
-        return isInitialAutoJoinEnabled;
-    }
-
-    /** @see Builder#setIsMetered(boolean)  */
-    public boolean isMetered() {
-        return wifiConfiguration.meteredOverride == WifiConfiguration.METERED_OVERRIDE_METERED;
-    }
-
-    /** @see Builder#setIsUserInteractionRequired(boolean)  */
-    public boolean isUserInteractionRequired() {
-        return isUserInteractionRequired;
-    }
-
-    /**
-     * Get the {@link PasspointConfiguration} associated with this Suggestion, or null if this
-     * Suggestion is not for a Passpoint network.
-     */
-    @Nullable
-    public PasspointConfiguration getPasspointConfig() {
-        return passpointConfiguration;
-    }
-
-    /** @see Builder#setPriority(int)  */
-    @IntRange(from = 0)
-    public int getPriority() {
-        return wifiConfiguration.priority;
-    }
-
-    /**
-     * Return the SSID of the network, or null if this is a Passpoint network.
-     * @see Builder#setSsid(String)
-     */
-    @Nullable
-    public String getSsid() {
-        if (wifiConfiguration.SSID == null) {
-            return null;
-        }
-        return WifiInfo.sanitizeSsid(wifiConfiguration.SSID);
-    }
-
-    /** @see Builder#setUntrusted(boolean)  */
-    public boolean isUntrusted() {
-        return !wifiConfiguration.trusted;
-    }
-
-    /**
-     * Get the WifiEnterpriseConfig, or null if unset.
-     * @see Builder#setWapiEnterpriseConfig(WifiEnterpriseConfig)
-     * @see Builder#setWpa2EnterpriseConfig(WifiEnterpriseConfig)
-     * @see Builder#setWpa3EnterpriseConfig(WifiEnterpriseConfig)
-     */
-    @Nullable
-    public WifiEnterpriseConfig getEnterpriseConfig() {
-        if (!wifiConfiguration.isEnterprise()) {
-            return null;
-        }
-        return wifiConfiguration.enterpriseConfig;
-    }
-
-    /**
-     * Get the passphrase, or null if unset.
-     * @see Builder#setWapiPassphrase(String)
-     * @see Builder#setWpa2Passphrase(String)
-     * @see Builder#setWpa3Passphrase(String)
-     */
-    @Nullable
-    public String getPassphrase() {
-        if (wifiConfiguration.preSharedKey == null) {
-            return null;
-        }
-        return WifiInfo.removeDoubleQuotes(wifiConfiguration.preSharedKey);
-    }
-}
diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java
deleted file mode 100644
index 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/non-updatable/java/src/android/net/wifi/SoftApConfToXmlMigrationUtil.java b/wifi/java/src/android/net/wifi/SoftApConfToXmlMigrationUtil.java
similarity index 100%
rename from wifi/non-updatable/java/src/android/net/wifi/SoftApConfToXmlMigrationUtil.java
rename to wifi/java/src/android/net/wifi/SoftApConfToXmlMigrationUtil.java
diff --git a/wifi/non-updatable/java/src/android/net/wifi/WifiMigration.java b/wifi/java/src/android/net/wifi/WifiMigration.java
similarity index 98%
rename from wifi/non-updatable/java/src/android/net/wifi/WifiMigration.java
rename to wifi/java/src/android/net/wifi/WifiMigration.java
index 5792d27..4fabc0b 100755
--- a/wifi/non-updatable/java/src/android/net/wifi/WifiMigration.java
+++ b/wifi/java/src/android/net/wifi/WifiMigration.java
@@ -139,8 +139,8 @@
     /**
      * Load data from legacy shared wifi config store file.
      * <p>
-     * Expected AOSP format is available in the sample files under {@code /frameworks/base/wifi/
-     * java/android/net/wifi/migration_samples}.
+     * Expected AOSP format is available in the sample files under {@code
+     * frameworks/base/wifi/non-updatable/migration_samples/}.
      * </p>
      * <p>
      * Note:
@@ -218,8 +218,8 @@
     /**
      * Load data from legacy user wifi config store file.
      * <p>
-     * Expected AOSP format is available in the sample files under {@code /frameworks/base/wifi/
-     * java/android/net/wifi/migration_samples}.
+     * Expected AOSP format is available in the sample files under {@code
+     * frameworks/base/wifi/non-updatable/migration_samples/}.
      * </p>
      * <p>
      * Note:
diff --git a/wifi/non-updatable/java/src/android/net/wifi/WifiNetworkScoreCache.java b/wifi/java/src/android/net/wifi/WifiNetworkScoreCache.java
similarity index 100%
rename from wifi/non-updatable/java/src/android/net/wifi/WifiNetworkScoreCache.java
rename to wifi/java/src/android/net/wifi/WifiNetworkScoreCache.java
diff --git a/wifi/non-updatable/java/src/android/net/wifi/nl80211/ChannelSettings.java b/wifi/java/src/android/net/wifi/nl80211/ChannelSettings.java
similarity index 100%
rename from wifi/non-updatable/java/src/android/net/wifi/nl80211/ChannelSettings.java
rename to wifi/java/src/android/net/wifi/nl80211/ChannelSettings.java
diff --git a/wifi/non-updatable/java/src/android/net/wifi/nl80211/DeviceWiphyCapabilities.java b/wifi/java/src/android/net/wifi/nl80211/DeviceWiphyCapabilities.java
similarity index 100%
rename from wifi/non-updatable/java/src/android/net/wifi/nl80211/DeviceWiphyCapabilities.java
rename to wifi/java/src/android/net/wifi/nl80211/DeviceWiphyCapabilities.java
diff --git a/wifi/non-updatable/java/src/android/net/wifi/nl80211/HiddenNetwork.java b/wifi/java/src/android/net/wifi/nl80211/HiddenNetwork.java
similarity index 100%
rename from wifi/non-updatable/java/src/android/net/wifi/nl80211/HiddenNetwork.java
rename to wifi/java/src/android/net/wifi/nl80211/HiddenNetwork.java
diff --git a/wifi/non-updatable/java/src/android/net/wifi/nl80211/NativeScanResult.java b/wifi/java/src/android/net/wifi/nl80211/NativeScanResult.java
similarity index 100%
rename from wifi/non-updatable/java/src/android/net/wifi/nl80211/NativeScanResult.java
rename to wifi/java/src/android/net/wifi/nl80211/NativeScanResult.java
diff --git a/wifi/non-updatable/java/src/android/net/wifi/nl80211/NativeWifiClient.java b/wifi/java/src/android/net/wifi/nl80211/NativeWifiClient.java
similarity index 100%
rename from wifi/non-updatable/java/src/android/net/wifi/nl80211/NativeWifiClient.java
rename to wifi/java/src/android/net/wifi/nl80211/NativeWifiClient.java
diff --git a/wifi/non-updatable/java/src/android/net/wifi/nl80211/PnoNetwork.java b/wifi/java/src/android/net/wifi/nl80211/PnoNetwork.java
similarity index 100%
rename from wifi/non-updatable/java/src/android/net/wifi/nl80211/PnoNetwork.java
rename to wifi/java/src/android/net/wifi/nl80211/PnoNetwork.java
diff --git a/wifi/non-updatable/java/src/android/net/wifi/nl80211/PnoSettings.java b/wifi/java/src/android/net/wifi/nl80211/PnoSettings.java
similarity index 100%
rename from wifi/non-updatable/java/src/android/net/wifi/nl80211/PnoSettings.java
rename to wifi/java/src/android/net/wifi/nl80211/PnoSettings.java
diff --git a/wifi/non-updatable/java/src/android/net/wifi/nl80211/RadioChainInfo.java b/wifi/java/src/android/net/wifi/nl80211/RadioChainInfo.java
similarity index 100%
rename from wifi/non-updatable/java/src/android/net/wifi/nl80211/RadioChainInfo.java
rename to wifi/java/src/android/net/wifi/nl80211/RadioChainInfo.java
diff --git a/wifi/non-updatable/java/src/android/net/wifi/nl80211/SingleScanSettings.java b/wifi/java/src/android/net/wifi/nl80211/SingleScanSettings.java
similarity index 100%
rename from wifi/non-updatable/java/src/android/net/wifi/nl80211/SingleScanSettings.java
rename to wifi/java/src/android/net/wifi/nl80211/SingleScanSettings.java
diff --git a/wifi/non-updatable/java/src/android/net/wifi/nl80211/WifiNl80211Manager.java b/wifi/java/src/android/net/wifi/nl80211/WifiNl80211Manager.java
similarity index 100%
rename from wifi/non-updatable/java/src/android/net/wifi/nl80211/WifiNl80211Manager.java
rename to wifi/java/src/android/net/wifi/nl80211/WifiNl80211Manager.java
diff --git a/wifi/java/android/net/wifi/migration_samples/README.txt b/wifi/migration_samples/README.txt
similarity index 100%
rename from wifi/java/android/net/wifi/migration_samples/README.txt
rename to wifi/migration_samples/README.txt
diff --git a/wifi/java/android/net/wifi/migration_samples/Shared_WifiConfigStore.xml b/wifi/migration_samples/Shared_WifiConfigStore.xml
similarity index 100%
rename from wifi/java/android/net/wifi/migration_samples/Shared_WifiConfigStore.xml
rename to wifi/migration_samples/Shared_WifiConfigStore.xml
diff --git a/wifi/java/android/net/wifi/migration_samples/Shared_WifiConfigStoreSoftAp.xml b/wifi/migration_samples/Shared_WifiConfigStoreSoftAp.xml
similarity index 100%
rename from wifi/java/android/net/wifi/migration_samples/Shared_WifiConfigStoreSoftAp.xml
rename to wifi/migration_samples/Shared_WifiConfigStoreSoftAp.xml
diff --git a/wifi/java/android/net/wifi/migration_samples/User_WifiConfigStore.xml b/wifi/migration_samples/User_WifiConfigStore.xml
similarity index 100%
rename from wifi/java/android/net/wifi/migration_samples/User_WifiConfigStore.xml
rename to wifi/migration_samples/User_WifiConfigStore.xml
diff --git a/wifi/java/android/net/wifi/migration_samples/User_WifiConfigStoreNetworkSuggestions.xml b/wifi/migration_samples/User_WifiConfigStoreNetworkSuggestions.xml
similarity index 100%
rename from wifi/java/android/net/wifi/migration_samples/User_WifiConfigStoreNetworkSuggestions.xml
rename to wifi/migration_samples/User_WifiConfigStoreNetworkSuggestions.xml
diff --git a/wifi/non-updatable/tests/Android.bp b/wifi/non-updatable/tests/Android.bp
deleted file mode 100644
index 3f5cacf..0000000
--- a/wifi/non-updatable/tests/Android.bp
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright (C) 2020 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-android_test {
-    name: "FrameworksWifiNonUpdatableApiTests",
-
-    defaults: ["framework-wifi-test-defaults"],
-
-    srcs: ["src/**/*.java"],
-
-    jacoco: {
-        include_filter: ["android.net.wifi.*"],
-        // TODO(b/147521214) need to exclude test classes
-        exclude_filter: [],
-    },
-
-    static_libs: [
-        "androidx.test.rules",
-        "frameworks-base-testutils",
-        "guava",
-        "mockito-target-minus-junit4",
-        "truth-prebuilt",
-    ],
-
-    libs: [
-        "android.test.runner",
-        "android.test.base",
-    ],
-
-    test_suites: [
-        "general-tests",
-    ],
-}
diff --git a/wifi/non-updatable/tests/AndroidManifest.xml b/wifi/non-updatable/tests/AndroidManifest.xml
deleted file mode 100644
index b4b6b2d..0000000
--- a/wifi/non-updatable/tests/AndroidManifest.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2020 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-     package="android.net.wifi.test">
-
-    <application>
-        <uses-library android:name="android.test.runner"/>
-        <activity android:label="WifiTestDummyLabel"
-             android:name="WifiTestDummyName"
-             android:exported="true">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN"/>
-                <category android:name="android.intent.category.LAUNCHER"/>
-            </intent-filter>
-        </activity>
-    </application>
-
-    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
-         android:targetPackage="android.net.wifi.test"
-         android:label="Frameworks Wifi Non-updatable API Tests">
-    </instrumentation>
-
-</manifest>
diff --git a/wifi/non-updatable/tests/AndroidTest.xml b/wifi/non-updatable/tests/AndroidTest.xml
deleted file mode 100644
index 5f3fdd4..0000000
--- a/wifi/non-updatable/tests/AndroidTest.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2020 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<configuration description="Runs Frameworks Wifi Non-updatable API Tests.">
-    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
-        <option name="test-file-name" value="FrameworksWifiNonUpdatableApiTests.apk" />
-    </target_preparer>
-
-    <option name="test-suite-tag" value="apct" />
-    <option name="test-tag" value="FrameworksWifiNonUpdatableApiTests" />
-    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
-        <option name="package" value="android.net.wifi.test" />
-        <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
-        <option name="hidden-api-checks" value="false"/>
-    </test>
-</configuration>
diff --git a/wifi/non-updatable/tests/README.md b/wifi/non-updatable/tests/README.md
deleted file mode 100644
index ad535f4..0000000
--- a/wifi/non-updatable/tests/README.md
+++ /dev/null
@@ -1,32 +0,0 @@
-# Wifi Non-Updatable Framework Unit Tests
-This package contains unit tests for the non-updatable part (i.e. outside the Wifi module) of the
-Android Wifi framework APIs based on the
-[Android Testing Support Library](http://developer.android.com/tools/testing-support-library/index.html).
-The test cases are built using the [JUnit](http://junit.org/) and [Mockito](http://mockito.org/)
-libraries.
-
-## Running Tests
-The easiest way to run tests is simply run
-
-```
-atest android.net.wifi
-```
-
-To pick up changes in framework/base, you will need to:
-1. rebuild the framework library 'make -j32'
-2. sync over the updated library to the device 'adb sync'
-3. restart framework on the device 'adb shell stop' then 'adb shell start'
-
-To enable syncing data to the device for first time after clean reflash:
-1. adb disable-verity
-2. adb reboot
-3. adb remount
-
-## Adding Tests
-Tests can be added by adding classes to the src directory. JUnit4 style test cases can
-be written by simply annotating test methods with `org.junit.Test`.
-
-## Debugging Tests
-If you are trying to debug why tests are not doing what you expected, you can add android log
-statements and use logcat to view them. The beginning and end of every tests is automatically logged
-with the tag `TestRunner`.
diff --git a/wifi/tests/Android.bp b/wifi/tests/Android.bp
index 0e58740..3f5cacf 100644
--- a/wifi/tests/Android.bp
+++ b/wifi/tests/Android.bp
@@ -12,15 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-// Make test APK
-// ============================================================
-
 android_test {
-    name: "FrameworksWifiApiTests",
+    name: "FrameworksWifiNonUpdatableApiTests",
 
     defaults: ["framework-wifi-test-defaults"],
 
-    srcs: ["**/*.java"],
+    srcs: ["src/**/*.java"],
 
     jacoco: {
         include_filter: ["android.net.wifi.*"],
@@ -30,13 +27,9 @@
 
     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",
     ],
 
@@ -46,11 +39,6 @@
     ],
 
     test_suites: [
-        "device-tests",
-        "mts",
+        "general-tests",
     ],
-
-    // 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
index b6c38bc..b4b6b2d 100644
--- a/wifi/tests/AndroidManifest.xml
+++ b/wifi/tests/AndroidManifest.xml
@@ -1,7 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
-
 <!--
-  ~ Copyright (C) 2016 The Android Open Source Project
+  ~ Copyright (C) 2020 The Android Open Source Project
   ~
   ~ Licensed under the Apache License, Version 2.0 (the "License");
   ~ you may not use this file except in compliance with the License.
@@ -17,22 +16,23 @@
   -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.net.wifi.test">
+     package="android.net.wifi.test">
 
     <application>
-        <uses-library android:name="android.test.runner" />
+        <uses-library android:name="android.test.runner"/>
         <activity android:label="WifiTestDummyLabel"
-                  android:name="WifiTestDummyName">
+             android:name="WifiTestDummyName"
+             android:exported="true">
             <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
+                <action android:name="android.intent.action.MAIN"/>
                 <category android:name="android.intent.category.LAUNCHER"/>
             </intent-filter>
         </activity>
     </application>
 
     <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
-        android:targetPackage="android.net.wifi.test"
-        android:label="Frameworks Wifi API Tests">
+         android:targetPackage="android.net.wifi.test"
+         android:label="Frameworks Wifi Non-updatable API Tests">
     </instrumentation>
 
 </manifest>
diff --git a/wifi/tests/AndroidTest.xml b/wifi/tests/AndroidTest.xml
index 34e2e3a..5f3fdd4 100644
--- a/wifi/tests/AndroidTest.xml
+++ b/wifi/tests/AndroidTest.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
+<!-- Copyright (C) 2020 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -13,22 +13,16 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<configuration description="Runs Frameworks Wifi API Tests.">
+<configuration description="Runs Frameworks Wifi Non-updatable API Tests.">
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
-        <option name="test-file-name" value="FrameworksWifiApiTests.apk" />
+        <option name="test-file-name" value="FrameworksWifiNonUpdatableApiTests.apk" />
     </target_preparer>
 
     <option name="test-suite-tag" value="apct" />
-    <option name="test-tag" value="FrameworksWifiApiTests" />
+    <option name="test-tag" value="FrameworksWifiNonUpdatableApiTests" />
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="android.net.wifi.test" />
         <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
         <option name="hidden-api-checks" value="false"/>
     </test>
-
-    <!-- Only run FrameworksWifiApiTests in MTS if the Wifi Mainline module is installed. -->
-    <object type="module_controller"
-            class="com.android.tradefed.testtype.suite.module.MainlineTestModuleController">
-        <option name="mainline-module-package-name" value="com.google.android.wifi" />
-    </object>
 </configuration>
diff --git a/wifi/tests/README.md b/wifi/tests/README.md
index f909404..ad535f4 100644
--- a/wifi/tests/README.md
+++ b/wifi/tests/README.md
@@ -1,5 +1,6 @@
-# Wifi Unit Tests
-This package contains unit tests for the android wifi framework APIs based on the
+# Wifi Non-Updatable Framework Unit Tests
+This package contains unit tests for the non-updatable part (i.e. outside the Wifi module) of the
+Android Wifi framework APIs based on the
 [Android Testing Support Library](http://developer.android.com/tools/testing-support-library/index.html).
 The test cases are built using the [JUnit](http://junit.org/) and [Mockito](http://mockito.org/)
 libraries.
diff --git a/wifi/tests/assets/hsr1/HSR1ProfileWithCACert.base64 b/wifi/tests/assets/hsr1/HSR1ProfileWithCACert.base64
deleted file mode 100644
index 760c839..0000000
--- a/wifi/tests/assets/hsr1/HSR1ProfileWithCACert.base64
+++ /dev/null
@@ -1,86 +0,0 @@
-TUlNRS1WZXJzaW9uOiAxLjAKQ29udGVudC1UeXBlOiBtdWx0aXBhcnQvbWl4ZWQ7IGJvdW5kYXJ5
-PXtib3VuZGFyeX07IGNoYXJzZXQ9VVRGLTgKQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogYmFz
-ZTY0CgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi94LXBhc3Nwb2ludC1w
-cm9maWxlOyBjaGFyc2V0PVVURi04CkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IGJhc2U2NAoK
-UEUxbmJYUlVjbVZsSUhodGJHNXpQU0p6ZVc1amJXdzZaRzFrWkdZeExqSWlQZ29nSUR4V1pYSkVW
-RVErTVM0eVBDOVdaWEpFVkVRKwpDaUFnUEU1dlpHVStDaUFnSUNBOFRtOWtaVTVoYldVK1VHVnlV
-SEp2ZG1sa1pYSlRkV0p6WTNKcGNIUnBiMjQ4TDA1dlpHVk9ZVzFsClBnb2dJQ0FnUEZKVVVISnZj
-R1Z5ZEdsbGN6NEtJQ0FnSUNBZ1BGUjVjR1UrQ2lBZ0lDQWdJQ0FnUEVSRVJrNWhiV1UrZFhKdU9u
-ZG0KWVRwdGJ6cG9iM1J6Y0c5ME1tUnZkREF0Y0dWeWNISnZkbWxrWlhKemRXSnpZM0pwY0hScGIy
-NDZNUzR3UEM5RVJFWk9ZVzFsUGdvZwpJQ0FnSUNBOEwxUjVjR1UrQ2lBZ0lDQThMMUpVVUhKdmNH
-VnlkR2xsY3o0S0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBOFRtOWtaVTVoCmJXVSthVEF3TVR3dlRt
-OWtaVTVoYldVK0NpQWdJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQWdJRHhPYjJSbFRtRnRaVDVJYjIx
-bFUxQTgKTDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEU1
-dlpHVk9ZVzFsUGtaeWFXVnVaR3g1VG1GdApaVHd2VG05a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNB
-OFZtRnNkV1UrUlhoaGJYQnNaU0JPWlhSM2IzSnJQQzlXWVd4MVpUNEtJQ0FnCklDQWdJQ0E4TDA1
-dlpHVStDaUFnSUNBZ0lDQWdQRTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrWlU1aGJXVStSbEZF
-VGp3dlRtOWsKWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0E4Vm1Gc2RXVSthRzkwYzNCdmRDNWxlR0Z0
-Y0d4bExtNWxkRHd2Vm1Gc2RXVStDaUFnSUNBZwpJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJRHhP
-YjJSbFBnb2dJQ0FnSUNBZ0lDQWdQRTV2WkdWT1lXMWxQbEp2WVcxcGJtZERiMjV6CmIzSjBhWFZ0
-VDBrOEwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBqRXhNakl6TXl3ME5EVTFO
-alk4TDFaaGJIVmwKUGdvZ0lDQWdJQ0FnSUR3dlRtOWtaVDRLSUNBZ0lDQWdQQzlPYjJSbFBnb2dJ
-Q0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0E4VG05awpaVTVoYldVK1EzSmxaR1Z1ZEdsaGJEd3ZU
-bTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdQRTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrClpVNWhi
-V1UrVW1WaGJHMDhMMDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQbVY0WVcxd2JH
-VXVZMjl0UEM5V1lXeDEKWlQ0S0lDQWdJQ0FnSUNBOEwwNXZaR1UrQ2lBZ0lDQWdJQ0FnUEU1dlpH
-VStDaUFnSUNBZ0lDQWdJQ0E4VG05a1pVNWhiV1UrVlhObApjbTVoYldWUVlYTnpkMjl5WkR3dlRt
-OWtaVTVoYldVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrWlQ0S0lDQWdJQ0FnSUNBZ0lDQWdQRTV2ClpH
-Vk9ZVzFsUGxWelpYSnVZVzFsUEM5T2IyUmxUbUZ0WlQ0S0lDQWdJQ0FnSUNBZ0lDQWdQRlpoYkhW
-bFBuVnpaWEk4TDFaaGJIVmwKUGdvZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNB
-Z1BFNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lEeE9iMlJsVG1GdApaVDVRWVhOemQyOXlaRHd2VG05
-a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lEeFdZV3gxWlQ1alIwWjZZek5rZG1OdFVUMDhMMVpo
-CmJIVmxQZ29nSUNBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEU1dlpHVStDaUFn
-SUNBZ0lDQWdJQ0FnSUR4T2IyUmwKVG1GdFpUNUZRVkJOWlhSb2IyUThMMDV2WkdWT1lXMWxQZ29n
-SUNBZ0lDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0FnSUNBZwpJQ0E4VG05a1pVNWhiV1Ur
-UlVGUVZIbHdaVHd2VG05a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBqSXhQ
-QzlXCllXeDFaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThU
-bTlrWlQ0S0lDQWdJQ0FnSUNBZ0lDQWcKSUNBOFRtOWtaVTVoYldVK1NXNXVaWEpOWlhSb2IyUThM
-MDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnSUNBZ0lEeFdZV3gxWlQ1TgpVeTFEU0VGUUxWWXlQ
-QzlXWVd4MVpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEM5T2Iy
-UmxQZ29nCklDQWdJQ0FnSUR3dlRtOWtaVDRLSUNBZ0lDQWdJQ0E4VG05a1pUNEtJQ0FnSUNBZ0lD
-QWdJRHhPYjJSbFRtRnRaVDVFYVdkcGRHRnMKUTJWeWRHbG1hV05oZEdVOEwwNXZaR1ZPWVcxbFBn
-b2dJQ0FnSUNBZ0lDQWdQRTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJSbApUbUZ0WlQ1RFpY
-SjBhV1pwWTJGMFpWUjVjR1U4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThWbUZzZFdV
-K2VEVXdPWFl6ClBDOVdZV3gxWlQ0S0lDQWdJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJQ0FnSUNB
-Z0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ0lDQTgKVG05a1pVNWhiV1UrUTJWeWRGTklRVEkxTmta
-cGJtZGxjbkJ5YVc1MFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEZaaApiSFZsUGpG
-bU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaakZt
-TVdZeFpqRm1NV1l4ClpqRm1NV1l4WmpGbU1XWThMMVpoYkhWbFBnb2dJQ0FnSUNBZ0lDQWdQQzlP
-YjJSbFBnb2dJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWcKSUNBZ0lDQThUbTlrWlQ0S0lDQWdJQ0Fn
-SUNBZ0lEeE9iMlJsVG1GdFpUNVRTVTA4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZwpQRTV2
-WkdVK0NpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJSbFRtRnRaVDVKVFZOSlBDOU9iMlJsVG1GdFpUNEtJ
-Q0FnSUNBZ0lDQWdJQ0FnClBGWmhiSFZsUGpFeU16UTFOaW84TDFaaGJIVmxQZ29nSUNBZ0lDQWdJ
-Q0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEU1dlpHVSsKQ2lBZ0lDQWdJQ0FnSUNBZ0lEeE9i
-MlJsVG1GdFpUNUZRVkJVZVhCbFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEZaaApi
-SFZsUGpJelBDOVdZV3gxWlQ0S0lDQWdJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJQ0FnSUNBOEww
-NXZaR1UrQ2lBZ0lDQWdJRHd2ClRtOWtaVDRLSUNBZ0lEd3ZUbTlrWlQ0S0lDQThMMDV2WkdVK0Nq
-d3ZUV2R0ZEZSeVpXVSsKCi0te2JvdW5kYXJ5fQpDb250ZW50LVR5cGU6IGFwcGxpY2F0aW9uL3gt
-eDUwOS1jYS1jZXJ0CkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IGJhc2U2NAoKTFMwdExTMUNS
-VWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVUkxSRU5EUVdoRFowRjNTVUpCWjBsS1FV
-bE1iRVprZDNwTQpWblZ5VFVFd1IwTlRjVWRUU1dJelJGRkZRa04zVlVGTlFrbDRSVVJCVDBKblRs
-WUtRa0ZOVkVJd1ZrSlZRMEpFVVZSRmQwaG9ZMDVOClZGbDNUVlJGZVUxVVJURk5SRVV4VjJoalRr
-MXFXWGROVkVFMVRWUkZNVTFFUlRGWGFrRlRUVkpCZHdwRVoxbEVWbEZSUkVWM1pFWlIKVmtGblVU
-QkZlRTFKU1VKSmFrRk9RbWRyY1docmFVYzVkekJDUVZGRlJrRkJUME5CVVRoQlRVbEpRa05uUzBO
-QlVVVkJDbnB1UVZCVgplakkyVFhOaFpUUjNjelF6WTNwU05ERXZTakpSZEhKVFNWcFZTMjFXVlhO
-V2RXMUVZbGxJY2xCT2RsUllTMU5OV0VGalpYZFBVa1JSCldWZ0tVbkYyU0had2JqaERjMk5DTVN0
-dlIxaGFka2gzZUdvMGVsWXdWMHR2U3pKNlpWaHJZWFV6ZG1ONWJETklTVXQxY0VwbWNUSlUKUlVG
-RFpXWldhbW93ZEFwS1Z5dFlNelZRUjFkd09TOUlOWHBKVlU1V1RsWnFVemRWYlhNNE5FbDJTMmhT
-UWpnMU1USlFRamxWZVVoaApaMWhaVmxnMVIxZHdRV05XY0hsbWNteFNDa1pKT1ZGa2FHZ3JVR0py
-TUhWNWEzUmtZbVl2UTJSbVowaFBiMlZpY2xSMGQxSnNhazB3CmIwUjBXQ3N5UTNZMmFqQjNRa3Mz
-YUVRNGNGQjJaakVyZFhrS1IzcGplbWxuUVZVdk5FdDNOMlZhY1hsa1pqbENLelZTZFhCU0swbGEK
-YVhCWU5ERjRSV2xKY2t0U2QzRnBOVEUzVjFkNldHTnFZVWN5WTA1aVpqUTFNUXA0Y0VnMVVHNVdN
-Mmt4ZEhFd05HcE5SMUZWZWtaMwpTVVJCVVVGQ2J6UkhRVTFJTkhkSVVWbEVWbEl3VDBKQ1dVVkdT
-WGRZTkhaek9FSnBRbU5UWTI5a0NqVnViMXBJVWswNFJUUXJhVTFGClNVZEJNVlZrU1hkUk4wMUVi
-VUZHU1hkWU5IWnpPRUpwUW1OVFkyOWtOVzV2V2toU1RUaEZOQ3RwYjFKaGEwWkVRVk1LVFZKQmQw
-Um4KV1VSV1VWRkVSWGRrUmxGV1FXZFJNRVY0WjJkclFXZDFWVll6UkUxMFZ6WnpkMFJCV1VSV1Vq
-QlVRa0ZWZDBGM1JVSXZla0ZNUW1kTwpWZ3BJVVRoRlFrRk5RMEZSV1hkRVVWbEtTMjlhU1doMlkw
-NUJVVVZNUWxGQlJHZG5SVUpCUm1aUmNVOVVRVGRTZGpkTEsyeDFVVGR3CmJtRnpORUpaZDBoRkNq
-bEhSVkF2ZFc5b2RqWkxUM2t3VkVkUlJtSnlVbFJxUm05TVZrNUNPVUphTVhsdFRVUmFNQzlVU1hk
-SlZXTTMKZDJrM1lUaDBOVzFGY1ZsSU1UVXpkMWNLWVZkdmIybFRhbmxNVEdoMVNUUnpUbkpPUTA5
-MGFYTmtRbkV5Y2pKTlJsaDBObWd3YlVGUgpXVTlRZGpoU09FczNMMlpuVTNoSFJuRjZhSGxPYlcx
-V1RBb3hjVUpLYkdSNE16UlRjSGR6VkVGTVVWWlFZalJvUjNkS2VscG1jakZRClkzQkZVWGcyZUUx
-dVZHdzRlRVZYV2tVelRYTTVPWFZoVlhoaVVYRkpkMUoxQ2t4blFVOXJUa050V1RKdE9EbFdhSHBo
-U0VveGRWWTQKTlVGa1RTOTBSQ3RaYzIxc2JtNXFkRGxNVWtObGFtSkNhWEJxU1VkcVQxaHlaekZL
-VUN0c2VGWUtiWFZOTkhaSUsxQXZiV3h0ZUhOUQpVSG93WkRZMVlpdEZSMjFLV25CdlRHdFBMM1Jr
-VGs1MlExbDZha3B3VkVWWGNFVnpUelpPVFdoTFdXODlDaTB0TFMwdFJVNUVJRU5GClVsUkpSa2xE
-UVZSRkxTMHRMUzBLCi0te2JvdW5kYXJ5fS0tCg==
\ No newline at end of file
diff --git a/wifi/tests/assets/hsr1/HSR1ProfileWithCACert.conf b/wifi/tests/assets/hsr1/HSR1ProfileWithCACert.conf
deleted file mode 100644
index 5b4e4cb..0000000
--- a/wifi/tests/assets/hsr1/HSR1ProfileWithCACert.conf
+++ /dev/null
@@ -1,74 +0,0 @@
-MIME-Version: 1.0
-Content-Type: multipart/mixed; boundary={boundary}; charset=UTF-8
-Content-Transfer-Encoding: base64
-
---{boundary}
-Content-Type: application/x-passpoint-profile; charset=UTF-8
-Content-Transfer-Encoding: base64
-
-PE1nbXRUcmVlIHhtbG5zPSJzeW5jbWw6ZG1kZGYxLjIiPgogIDxWZXJEVEQ+MS4yPC9WZXJEVEQ+
-CiAgPE5vZGU+CiAgICA8Tm9kZU5hbWU+UGVyUHJvdmlkZXJTdWJzY3JpcHRpb248L05vZGVOYW1l
-PgogICAgPFJUUHJvcGVydGllcz4KICAgICAgPFR5cGU+CiAgICAgICAgPERERk5hbWU+dXJuOndm
-YTptbzpob3RzcG90MmRvdDAtcGVycHJvdmlkZXJzdWJzY3JpcHRpb246MS4wPC9EREZOYW1lPgog
-ICAgICA8L1R5cGU+CiAgICA8L1JUUHJvcGVydGllcz4KICAgIDxOb2RlPgogICAgICA8Tm9kZU5h
-bWU+aTAwMTwvTm9kZU5hbWU+CiAgICAgIDxOb2RlPgogICAgICAgIDxOb2RlTmFtZT5Ib21lU1A8
-L05vZGVOYW1lPgogICAgICAgIDxOb2RlPgogICAgICAgICAgPE5vZGVOYW1lPkZyaWVuZGx5TmFt
-ZTwvTm9kZU5hbWU+CiAgICAgICAgICA8VmFsdWU+RXhhbXBsZSBOZXR3b3JrPC9WYWx1ZT4KICAg
-ICAgICA8L05vZGU+CiAgICAgICAgPE5vZGU+CiAgICAgICAgICA8Tm9kZU5hbWU+RlFETjwvTm9k
-ZU5hbWU+CiAgICAgICAgICA8VmFsdWU+aG90c3BvdC5leGFtcGxlLm5ldDwvVmFsdWU+CiAgICAg
-ICAgPC9Ob2RlPgogICAgICAgIDxOb2RlPgogICAgICAgICAgPE5vZGVOYW1lPlJvYW1pbmdDb25z
-b3J0aXVtT0k8L05vZGVOYW1lPgogICAgICAgICAgPFZhbHVlPjExMjIzMyw0NDU1NjY8L1ZhbHVl
-PgogICAgICAgIDwvTm9kZT4KICAgICAgPC9Ob2RlPgogICAgICA8Tm9kZT4KICAgICAgICA8Tm9k
-ZU5hbWU+Q3JlZGVudGlhbDwvTm9kZU5hbWU+CiAgICAgICAgPE5vZGU+CiAgICAgICAgICA8Tm9k
-ZU5hbWU+UmVhbG08L05vZGVOYW1lPgogICAgICAgICAgPFZhbHVlPmV4YW1wbGUuY29tPC9WYWx1
-ZT4KICAgICAgICA8L05vZGU+CiAgICAgICAgPE5vZGU+CiAgICAgICAgICA8Tm9kZU5hbWU+VXNl
-cm5hbWVQYXNzd29yZDwvTm9kZU5hbWU+CiAgICAgICAgICA8Tm9kZT4KICAgICAgICAgICAgPE5v
-ZGVOYW1lPlVzZXJuYW1lPC9Ob2RlTmFtZT4KICAgICAgICAgICAgPFZhbHVlPnVzZXI8L1ZhbHVl
-PgogICAgICAgICAgPC9Ob2RlPgogICAgICAgICAgPE5vZGU+CiAgICAgICAgICAgIDxOb2RlTmFt
-ZT5QYXNzd29yZDwvTm9kZU5hbWU+CiAgICAgICAgICAgIDxWYWx1ZT5jR0Z6YzNkdmNtUT08L1Zh
-bHVlPgogICAgICAgICAgPC9Ob2RlPgogICAgICAgICAgPE5vZGU+CiAgICAgICAgICAgIDxOb2Rl
-TmFtZT5FQVBNZXRob2Q8L05vZGVOYW1lPgogICAgICAgICAgICA8Tm9kZT4KICAgICAgICAgICAg
-ICA8Tm9kZU5hbWU+RUFQVHlwZTwvTm9kZU5hbWU+CiAgICAgICAgICAgICAgPFZhbHVlPjIxPC9W
-YWx1ZT4KICAgICAgICAgICAgPC9Ob2RlPgogICAgICAgICAgICA8Tm9kZT4KICAgICAgICAgICAg
-ICA8Tm9kZU5hbWU+SW5uZXJNZXRob2Q8L05vZGVOYW1lPgogICAgICAgICAgICAgIDxWYWx1ZT5N
-Uy1DSEFQLVYyPC9WYWx1ZT4KICAgICAgICAgICAgPC9Ob2RlPgogICAgICAgICAgPC9Ob2RlPgog
-ICAgICAgIDwvTm9kZT4KICAgICAgICA8Tm9kZT4KICAgICAgICAgIDxOb2RlTmFtZT5EaWdpdGFs
-Q2VydGlmaWNhdGU8L05vZGVOYW1lPgogICAgICAgICAgPE5vZGU+CiAgICAgICAgICAgIDxOb2Rl
-TmFtZT5DZXJ0aWZpY2F0ZVR5cGU8L05vZGVOYW1lPgogICAgICAgICAgICA8VmFsdWU+eDUwOXYz
-PC9WYWx1ZT4KICAgICAgICAgIDwvTm9kZT4KICAgICAgICAgIDxOb2RlPgogICAgICAgICAgICA8
-Tm9kZU5hbWU+Q2VydFNIQTI1NkZpbmdlcnByaW50PC9Ob2RlTmFtZT4KICAgICAgICAgICAgPFZh
-bHVlPjFmMWYxZjFmMWYxZjFmMWYxZjFmMWYxZjFmMWYxZjFmMWYxZjFmMWYxZjFmMWYxZjFmMWYx
-ZjFmMWYxZjFmMWY8L1ZhbHVlPgogICAgICAgICAgPC9Ob2RlPgogICAgICAgIDwvTm9kZT4KICAg
-ICAgICA8Tm9kZT4KICAgICAgICAgIDxOb2RlTmFtZT5TSU08L05vZGVOYW1lPgogICAgICAgICAg
-PE5vZGU+CiAgICAgICAgICAgIDxOb2RlTmFtZT5JTVNJPC9Ob2RlTmFtZT4KICAgICAgICAgICAg
-PFZhbHVlPjEyMzQ1Nio8L1ZhbHVlPgogICAgICAgICAgPC9Ob2RlPgogICAgICAgICAgPE5vZGU+
-CiAgICAgICAgICAgIDxOb2RlTmFtZT5FQVBUeXBlPC9Ob2RlTmFtZT4KICAgICAgICAgICAgPFZh
-bHVlPjIzPC9WYWx1ZT4KICAgICAgICAgIDwvTm9kZT4KICAgICAgICA8L05vZGU+CiAgICAgIDwv
-Tm9kZT4KICAgIDwvTm9kZT4KICA8L05vZGU+CjwvTWdtdFRyZWU+
-
---{boundary}
-Content-Type: application/x-x509-ca-cert
-Content-Transfer-Encoding: base64
-
-LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURLRENDQWhDZ0F3SUJBZ0lKQUlMbEZkd3pM
-VnVyTUEwR0NTcUdTSWIzRFFFQkN3VUFNQkl4RURBT0JnTlYKQkFNVEIwVkJVQ0JEUVRFd0hoY05N
-VFl3TVRFeU1URTFNREUxV2hjTk1qWXdNVEE1TVRFMU1ERTFXakFTTVJBdwpEZ1lEVlFRREV3ZEZR
-VkFnUTBFeE1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBCnpuQVBV
-ejI2TXNhZTR3czQzY3pSNDEvSjJRdHJTSVpVS21WVXNWdW1EYllIclBOdlRYS1NNWEFjZXdPUkRR
-WVgKUnF2SHZwbjhDc2NCMStvR1hadkh3eGo0elYwV0tvSzJ6ZVhrYXUzdmN5bDNISUt1cEpmcTJU
-RUFDZWZWamowdApKVytYMzVQR1dwOS9INXpJVU5WTlZqUzdVbXM4NEl2S2hSQjg1MTJQQjlVeUhh
-Z1hZVlg1R1dwQWNWcHlmcmxSCkZJOVFkaGgrUGJrMHV5a3RkYmYvQ2RmZ0hPb2ViclR0d1Jsak0w
-b0R0WCsyQ3Y2ajB3Qks3aEQ4cFB2ZjErdXkKR3pjemlnQVUvNEt3N2VacXlkZjlCKzVSdXBSK0la
-aXBYNDF4RWlJcktSd3FpNTE3V1d6WGNqYUcyY05iZjQ1MQp4cEg1UG5WM2kxdHEwNGpNR1FVekZ3
-SURBUUFCbzRHQU1INHdIUVlEVlIwT0JCWUVGSXdYNHZzOEJpQmNTY29kCjVub1pIUk04RTQraU1F
-SUdBMVVkSXdRN01EbUFGSXdYNHZzOEJpQmNTY29kNW5vWkhSTThFNCtpb1Jha0ZEQVMKTVJBd0Rn
-WURWUVFERXdkRlFWQWdRMEV4Z2drQWd1VVYzRE10VzZzd0RBWURWUjBUQkFVd0F3RUIvekFMQmdO
-VgpIUThFQkFNQ0FRWXdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBRmZRcU9UQTdSdjdLK2x1UTdw
-bmFzNEJZd0hFCjlHRVAvdW9odjZLT3kwVEdRRmJyUlRqRm9MVk5COUJaMXltTURaMC9USXdJVWM3
-d2k3YTh0NW1FcVlIMTUzd1cKYVdvb2lTanlMTGh1STRzTnJOQ090aXNkQnEycjJNRlh0NmgwbUFR
-WU9QdjhSOEs3L2ZnU3hHRnF6aHlObW1WTAoxcUJKbGR4MzRTcHdzVEFMUVZQYjRoR3dKelpmcjFQ
-Y3BFUXg2eE1uVGw4eEVXWkUzTXM5OXVhVXhiUXFJd1J1CkxnQU9rTkNtWTJtODlWaHphSEoxdVY4
-NUFkTS90RCtZc21sbm5qdDlMUkNlamJCaXBqSUdqT1hyZzFKUCtseFYKbXVNNHZIK1AvbWxteHNQ
-UHowZDY1YitFR21KWnBvTGtPL3RkTk52Q1l6akpwVEVXcEVzTzZOTWhLWW89Ci0tLS0tRU5EIENF
-UlRJRklDQVRFLS0tLS0K
---{boundary}--
diff --git a/wifi/tests/assets/hsr1/HSR1ProfileWithInvalidContentType.base64 b/wifi/tests/assets/hsr1/HSR1ProfileWithInvalidContentType.base64
deleted file mode 100644
index 2775a9f..0000000
--- a/wifi/tests/assets/hsr1/HSR1ProfileWithInvalidContentType.base64
+++ /dev/null
@@ -1,86 +0,0 @@
-TUlNRS1WZXJzaW9uOiAxLjAKQ29udGVudC1UeXBlOiBtdWx0aXBhcnQvbWl4ZWQ7IGJvdW5kYXJ5
-PXtib3VuZGFyeX07IGNoYXJzZXQ9VVRGLTgKQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogYmFz
-ZTY0CgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi9wYXNzcG9pbnQtcHJv
-ZmlsZTsgY2hhcnNldD1VVEYtOApDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBiYXNlNjQKClBF
-MW5iWFJVY21WbElIaHRiRzV6UFNKemVXNWpiV3c2Wkcxa1pHWXhMaklpUGdvZ0lEeFdaWEpFVkVR
-K01TNHlQQzlXWlhKRVZFUSsKQ2lBZ1BFNXZaR1UrQ2lBZ0lDQThUbTlrWlU1aGJXVStVR1Z5VUhK
-dmRtbGtaWEpUZFdKelkzSnBjSFJwYjI0OEwwNXZaR1ZPWVcxbApQZ29nSUNBZ1BGSlVVSEp2Y0dW
-eWRHbGxjejRLSUNBZ0lDQWdQRlI1Y0dVK0NpQWdJQ0FnSUNBZ1BFUkVSazVoYldVK2RYSnVPbmRt
-CllUcHRienBvYjNSemNHOTBNbVJ2ZERBdGNHVnljSEp2ZG1sa1pYSnpkV0p6WTNKcGNIUnBiMjQ2
-TVM0d1BDOUVSRVpPWVcxbFBnb2cKSUNBZ0lDQThMMVI1Y0dVK0NpQWdJQ0E4TDFKVVVISnZjR1Z5
-ZEdsbGN6NEtJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQThUbTlrWlU1aApiV1UrYVRBd01Ud3ZUbTlr
-WlU1aGJXVStDaUFnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUR4T2IyUmxUbUZ0WlQ1SWIyMWxV
-MUE4CkwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZa
-R1ZPWVcxbFBrWnlhV1Z1Wkd4NVRtRnQKWlR3dlRtOWtaVTVoYldVK0NpQWdJQ0FnSUNBZ0lDQThW
-bUZzZFdVK1JYaGhiWEJzWlNCT1pYUjNiM0pyUEM5V1lXeDFaVDRLSUNBZwpJQ0FnSUNBOEwwNXZa
-R1UrQ2lBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0E4VG05a1pVNWhiV1UrUmxGRVRq
-d3ZUbTlrClpVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNBOFZtRnNkV1UrYUc5MGMzQnZkQzVsZUdGdGNH
-eGxMbTVsZER3dlZtRnNkV1UrQ2lBZ0lDQWcKSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUR4T2Iy
-UmxQZ29nSUNBZ0lDQWdJQ0FnUEU1dlpHVk9ZVzFsUGxKdllXMXBibWREYjI1egpiM0owYVhWdFQw
-azhMMDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQakV4TWpJek15dzBORFUxTmpZ
-OEwxWmhiSFZsClBnb2dJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNB
-Z0lDQThUbTlrWlQ0S0lDQWdJQ0FnSUNBOFRtOWsKWlU1aGJXVStRM0psWkdWdWRHbGhiRHd2VG05
-a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0E4VG05awpaVTVoYldV
-K1VtVmhiRzA4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ1BGWmhiSFZsUG1WNFlXMXdiR1V1
-WTI5dFBDOVdZV3gxClpUNEtJQ0FnSUNBZ0lDQThMMDV2WkdVK0NpQWdJQ0FnSUNBZ1BFNXZaR1Ur
-Q2lBZ0lDQWdJQ0FnSUNBOFRtOWtaVTVoYldVK1ZYTmwKY201aGJXVlFZWE56ZDI5eVpEd3ZUbTlr
-WlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0E4VG05a1pUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEU1dgpaR1ZP
-WVcxbFBsVnpaWEp1WVcxbFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQ
-blZ6WlhJOEwxWmhiSFZsClBnb2dJQ0FnSUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdQ
-RTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJSbFRtRnQKWlQ1UVlYTnpkMjl5WkR3dlRtOWta
-VTVoYldVK0NpQWdJQ0FnSUNBZ0lDQWdJRHhXWVd4MVpUNWpSMFo2WXpOa2RtTnRVVDA4TDFaaApi
-SFZsUGdvZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZaR1UrQ2lBZ0lD
-QWdJQ0FnSUNBZ0lEeE9iMlJsClRtRnRaVDVGUVZCTlpYUm9iMlE4TDA1dlpHVk9ZVzFsUGdvZ0lD
-QWdJQ0FnSUNBZ0lDQThUbTlrWlQ0S0lDQWdJQ0FnSUNBZ0lDQWcKSUNBOFRtOWtaVTVoYldVK1JV
-RlFWSGx3WlR3dlRtOWtaVTVoYldVK0NpQWdJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQakl4UEM5
-VwpZV3gxWlQ0S0lDQWdJQ0FnSUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdJQ0E4VG05
-a1pUNEtJQ0FnSUNBZ0lDQWdJQ0FnCklDQThUbTlrWlU1aGJXVStTVzV1WlhKTlpYUm9iMlE4TDA1
-dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ0lDQWdJRHhXWVd4MVpUNU4KVXkxRFNFRlFMVll5UEM5
-V1lXeDFaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJs
-UGdvZwpJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0Fn
-SUR4T2IyUmxUbUZ0WlQ1RWFXZHBkR0ZzClEyVnlkR2xtYVdOaGRHVThMMDV2WkdWT1lXMWxQZ29n
-SUNBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2IyUmwKVG1GdFpUNURaWEow
-YVdacFkyRjBaVlI1Y0dVOEwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWdJQ0E4Vm1Gc2RXVStl
-RFV3T1hZegpQQzlXWVd4MVpUNEtJQ0FnSUNBZ0lDQWdJRHd2VG05a1pUNEtJQ0FnSUNBZ0lDQWdJ
-RHhPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdJQ0E4ClRtOWtaVTVoYldVK1EyVnlkRk5JUVRJMU5rWnBi
-bWRsY25CeWFXNTBQQzlPYjJSbFRtRnRaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BGWmgKYkhWbFBqRm1N
-V1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1X
-WXhaakZtTVdZeApaakZtTVdZeFpqRm1NV1k4TDFaaGJIVmxQZ29nSUNBZ0lDQWdJQ0FnUEM5T2Iy
-UmxQZ29nSUNBZ0lDQWdJRHd2VG05a1pUNEtJQ0FnCklDQWdJQ0E4VG05a1pUNEtJQ0FnSUNBZ0lD
-QWdJRHhPYjJSbFRtRnRaVDVUU1UwOEwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWcKUEU1dlpH
-VStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2IyUmxUbUZ0WlQ1SlRWTkpQQzlPYjJSbFRtRnRaVDRLSUNB
-Z0lDQWdJQ0FnSUNBZwpQRlpoYkhWbFBqRXlNelExTmlvOEwxWmhiSFZsUGdvZ0lDQWdJQ0FnSUNB
-Z1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZaR1UrCkNpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJS
-bFRtRnRaVDVGUVZCVWVYQmxQQzlPYjJSbFRtRnRaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BGWmgKYkhW
-bFBqSXpQQzlXWVd4MVpUNEtJQ0FnSUNBZ0lDQWdJRHd2VG05a1pUNEtJQ0FnSUNBZ0lDQThMMDV2
-WkdVK0NpQWdJQ0FnSUR3dgpUbTlrWlQ0S0lDQWdJRHd2VG05a1pUNEtJQ0E4TDA1dlpHVStDand2
-VFdkdGRGUnlaV1UrCgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi94LXg1
-MDktY2EtY2VydApDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBiYXNlNjQKCkxTMHRMUzFDUlVk
-SlRpQkRSVkpVU1VaSlEwRlVSUzB0TFMwdENrMUpTVVJMUkVORFFXaERaMEYzU1VKQlowbEtRVWxN
-YkVaa2QzcE0KVm5WeVRVRXdSME5UY1VkVFNXSXpSRkZGUWtOM1ZVRk5Ra2w0UlVSQlQwSm5UbFlL
-UWtGTlZFSXdWa0pWUTBKRVVWUkZkMGhvWTA1TgpWRmwzVFZSRmVVMVVSVEZOUkVVeFYyaGpUazFx
-V1hkTlZFRTFUVlJGTVUxRVJURlhha0ZUVFZKQmR3cEVaMWxFVmxGUlJFVjNaRVpSClZrRm5VVEJG
-ZUUxSlNVSkpha0ZPUW1kcmNXaHJhVWM1ZHpCQ1FWRkZSa0ZCVDBOQlVUaEJUVWxKUWtOblMwTkJV
-VVZCQ25wdVFWQlYKZWpJMlRYTmhaVFIzY3pRelkzcFNOREV2U2pKUmRISlRTVnBWUzIxV1ZYTldk
-VzFFWWxsSWNsQk9kbFJZUzFOTldFRmpaWGRQVWtSUgpXVmdLVW5GMlNIWndiamhEYzJOQ01TdHZS
-MWhhZGtoM2VHbzBlbFl3VjB0dlN6SjZaVmhyWVhVemRtTjViRE5JU1V0MWNFcG1jVEpVClJVRkRa
-V1pXYW1vd2RBcEtWeXRZTXpWUVIxZHdPUzlJTlhwSlZVNVdUbFpxVXpkVmJYTTRORWwyUzJoU1Fq
-ZzFNVEpRUWpsVmVVaGgKWjFoWlZsZzFSMWR3UVdOV2NIbG1jbXhTQ2taSk9WRmthR2dyVUdKck1I
-VjVhM1JrWW1ZdlEyUm1aMGhQYjJWaWNsUjBkMUpzYWswdwpiMFIwV0NzeVEzWTJhakIzUWtzM2FF
-UTRjRkIyWmpFcmRYa0tSM3BqZW1sblFWVXZORXQzTjJWYWNYbGtaamxDS3pWU2RYQlNLMGxhCmFY
-QllOREY0UldsSmNrdFNkM0ZwTlRFM1YxZDZXR05xWVVjeVkwNWlaalExTVFwNGNFZzFVRzVXTTJr
-eGRIRXdOR3BOUjFGVmVrWjMKU1VSQlVVRkNielJIUVUxSU5IZElVVmxFVmxJd1QwSkNXVVZHU1hk
-WU5IWnpPRUpwUW1OVFkyOWtDalZ1YjFwSVVrMDRSVFFyYVUxRgpTVWRCTVZWa1NYZFJOMDFFYlVG
-R1NYZFlOSFp6T0VKcFFtTlRZMjlrTlc1dldraFNUVGhGTkN0cGIxSmhhMFpFUVZNS1RWSkJkMFJu
-CldVUldVVkZFUlhka1JsRldRV2RSTUVWNFoyZHJRV2QxVlZZelJFMTBWelp6ZDBSQldVUldVakJV
-UWtGVmQwRjNSVUl2ZWtGTVFtZE8KVmdwSVVUaEZRa0ZOUTBGUldYZEVVVmxLUzI5YVNXaDJZMDVC
-VVVWTVFsRkJSR2RuUlVKQlJtWlJjVTlVUVRkU2RqZExLMngxVVRkdwpibUZ6TkVKWmQwaEZDamxI
-UlZBdmRXOW9kalpMVDNrd1ZFZFJSbUp5VWxScVJtOU1WazVDT1VKYU1YbHRUVVJhTUM5VVNYZEpW
-V00zCmQyazNZVGgwTlcxRmNWbElNVFV6ZDFjS1lWZHZiMmxUYW5sTVRHaDFTVFJ6VG5KT1EwOTBh
-WE5rUW5FeWNqSk5SbGgwTm1nd2JVRlIKV1U5UWRqaFNPRXMzTDJablUzaEhSbkY2YUhsT2JXMVdU
-QW94Y1VKS2JHUjRNelJUY0hkelZFRk1VVlpRWWpSb1IzZEtlbHBtY2pGUQpZM0JGVVhnMmVFMXVW
-R3c0ZUVWWFdrVXpUWE01T1hWaFZYaGlVWEZKZDFKMUNreG5RVTlyVGtOdFdUSnRPRGxXYUhwaFNF
-b3hkVlk0Ck5VRmtUUzkwUkN0WmMyMXNibTVxZERsTVVrTmxhbUpDYVhCcVNVZHFUMWh5WnpGS1VD
-dHNlRllLYlhWTk5IWklLMUF2Yld4dGVITlEKVUhvd1pEWTFZaXRGUjIxS1duQnZUR3RQTDNSa1Rr
-NTJRMWw2YWtwd1ZFVlhjRVZ6VHpaT1RXaExXVzg5Q2kwdExTMHRSVTVFSUVORgpVbFJKUmtsRFFW
-UkZMUzB0TFMwSwotLXtib3VuZGFyeX0tLQo=
\ No newline at end of file
diff --git a/wifi/tests/assets/hsr1/HSR1ProfileWithMissingBoundary.base64 b/wifi/tests/assets/hsr1/HSR1ProfileWithMissingBoundary.base64
deleted file mode 100644
index 7023453..0000000
--- a/wifi/tests/assets/hsr1/HSR1ProfileWithMissingBoundary.base64
+++ /dev/null
@@ -1,86 +0,0 @@
-TUlNRS1WZXJzaW9uOiAxLjAKQ29udGVudC1UeXBlOiBtdWx0aXBhcnQvbWl4ZWQ7IGJvdW5kYXJ5
-PXtib3VuZGFyeX07IGNoYXJzZXQ9VVRGLTgKQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogYmFz
-ZTY0CgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi94LXBhc3Nwb2ludC1w
-cm9maWxlOyBjaGFyc2V0PVVURi04CkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IGJhc2U2NAoK
-UEUxbmJYUlVjbVZsSUhodGJHNXpQU0p6ZVc1amJXdzZaRzFrWkdZeExqSWlQZ29nSUR4V1pYSkVW
-RVErTVM0eVBDOVdaWEpFVkVRKwpDaUFnUEU1dlpHVStDaUFnSUNBOFRtOWtaVTVoYldVK1VHVnlV
-SEp2ZG1sa1pYSlRkV0p6WTNKcGNIUnBiMjQ4TDA1dlpHVk9ZVzFsClBnb2dJQ0FnUEZKVVVISnZj
-R1Z5ZEdsbGN6NEtJQ0FnSUNBZ1BGUjVjR1UrQ2lBZ0lDQWdJQ0FnUEVSRVJrNWhiV1UrZFhKdU9u
-ZG0KWVRwdGJ6cG9iM1J6Y0c5ME1tUnZkREF0Y0dWeWNISnZkbWxrWlhKemRXSnpZM0pwY0hScGIy
-NDZNUzR3UEM5RVJFWk9ZVzFsUGdvZwpJQ0FnSUNBOEwxUjVjR1UrQ2lBZ0lDQThMMUpVVUhKdmNH
-VnlkR2xsY3o0S0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBOFRtOWtaVTVoCmJXVSthVEF3TVR3dlRt
-OWtaVTVoYldVK0NpQWdJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQWdJRHhPYjJSbFRtRnRaVDVJYjIx
-bFUxQTgKTDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEU1
-dlpHVk9ZVzFsUGtaeWFXVnVaR3g1VG1GdApaVHd2VG05a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNB
-OFZtRnNkV1UrUlhoaGJYQnNaU0JPWlhSM2IzSnJQQzlXWVd4MVpUNEtJQ0FnCklDQWdJQ0E4TDA1
-dlpHVStDaUFnSUNBZ0lDQWdQRTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrWlU1aGJXVStSbEZF
-VGp3dlRtOWsKWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0E4Vm1Gc2RXVSthRzkwYzNCdmRDNWxlR0Z0
-Y0d4bExtNWxkRHd2Vm1Gc2RXVStDaUFnSUNBZwpJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJRHhP
-YjJSbFBnb2dJQ0FnSUNBZ0lDQWdQRTV2WkdWT1lXMWxQbEp2WVcxcGJtZERiMjV6CmIzSjBhWFZ0
-VDBrOEwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBqRXhNakl6TXl3ME5EVTFO
-alk4TDFaaGJIVmwKUGdvZ0lDQWdJQ0FnSUR3dlRtOWtaVDRLSUNBZ0lDQWdQQzlPYjJSbFBnb2dJ
-Q0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0E4VG05awpaVTVoYldVK1EzSmxaR1Z1ZEdsaGJEd3ZU
-bTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdQRTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrClpVNWhi
-V1UrVW1WaGJHMDhMMDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQbVY0WVcxd2JH
-VXVZMjl0UEM5V1lXeDEKWlQ0S0lDQWdJQ0FnSUNBOEwwNXZaR1UrQ2lBZ0lDQWdJQ0FnUEU1dlpH
-VStDaUFnSUNBZ0lDQWdJQ0E4VG05a1pVNWhiV1UrVlhObApjbTVoYldWUVlYTnpkMjl5WkR3dlRt
-OWtaVTVoYldVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrWlQ0S0lDQWdJQ0FnSUNBZ0lDQWdQRTV2ClpH
-Vk9ZVzFsUGxWelpYSnVZVzFsUEM5T2IyUmxUbUZ0WlQ0S0lDQWdJQ0FnSUNBZ0lDQWdQRlpoYkhW
-bFBuVnpaWEk4TDFaaGJIVmwKUGdvZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNB
-Z1BFNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lEeE9iMlJsVG1GdApaVDVRWVhOemQyOXlaRHd2VG05
-a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lEeFdZV3gxWlQ1alIwWjZZek5rZG1OdFVUMDhMMVpo
-CmJIVmxQZ29nSUNBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEU1dlpHVStDaUFn
-SUNBZ0lDQWdJQ0FnSUR4T2IyUmwKVG1GdFpUNUZRVkJOWlhSb2IyUThMMDV2WkdWT1lXMWxQZ29n
-SUNBZ0lDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0FnSUNBZwpJQ0E4VG05a1pVNWhiV1Ur
-UlVGUVZIbHdaVHd2VG05a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBqSXhQ
-QzlXCllXeDFaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThU
-bTlrWlQ0S0lDQWdJQ0FnSUNBZ0lDQWcKSUNBOFRtOWtaVTVoYldVK1NXNXVaWEpOWlhSb2IyUThM
-MDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnSUNBZ0lEeFdZV3gxWlQ1TgpVeTFEU0VGUUxWWXlQ
-QzlXWVd4MVpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEM5T2Iy
-UmxQZ29nCklDQWdJQ0FnSUR3dlRtOWtaVDRLSUNBZ0lDQWdJQ0E4VG05a1pUNEtJQ0FnSUNBZ0lD
-QWdJRHhPYjJSbFRtRnRaVDVFYVdkcGRHRnMKUTJWeWRHbG1hV05oZEdVOEwwNXZaR1ZPWVcxbFBn
-b2dJQ0FnSUNBZ0lDQWdQRTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJSbApUbUZ0WlQ1RFpY
-SjBhV1pwWTJGMFpWUjVjR1U4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThWbUZzZFdV
-K2VEVXdPWFl6ClBDOVdZV3gxWlQ0S0lDQWdJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJQ0FnSUNB
-Z0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ0lDQTgKVG05a1pVNWhiV1UrUTJWeWRGTklRVEkxTmta
-cGJtZGxjbkJ5YVc1MFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEZaaApiSFZsUGpG
-bU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaakZt
-TVdZeFpqRm1NV1l4ClpqRm1NV1l4WmpGbU1XWThMMVpoYkhWbFBnb2dJQ0FnSUNBZ0lDQWdQQzlP
-YjJSbFBnb2dJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWcKSUNBZ0lDQThUbTlrWlQ0S0lDQWdJQ0Fn
-SUNBZ0lEeE9iMlJsVG1GdFpUNVRTVTA4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZwpQRTV2
-WkdVK0NpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJSbFRtRnRaVDVKVFZOSlBDOU9iMlJsVG1GdFpUNEtJ
-Q0FnSUNBZ0lDQWdJQ0FnClBGWmhiSFZsUGpFeU16UTFOaW84TDFaaGJIVmxQZ29nSUNBZ0lDQWdJ
-Q0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEU1dlpHVSsKQ2lBZ0lDQWdJQ0FnSUNBZ0lEeE9i
-MlJsVG1GdFpUNUZRVkJVZVhCbFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEZaaApi
-SFZsUGpJelBDOVdZV3gxWlQ0S0lDQWdJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJQ0FnSUNBOEww
-NXZaR1UrQ2lBZ0lDQWdJRHd2ClRtOWtaVDRLSUNBZ0lEd3ZUbTlrWlQ0S0lDQThMMDV2WkdVK0Nq
-d3ZUV2R0ZEZSeVpXVSsKCi0te2JvdW5kYXJ5fQpDb250ZW50LVR5cGU6IGFwcGxpY2F0aW9uL3gt
-eDUwOS1jYS1jZXJ0CkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IGJhc2U2NAoKTFMwdExTMUNS
-VWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVUkxSRU5EUVdoRFowRjNTVUpCWjBsS1FV
-bE1iRVprZDNwTQpWblZ5VFVFd1IwTlRjVWRUU1dJelJGRkZRa04zVlVGTlFrbDRSVVJCVDBKblRs
-WUtRa0ZOVkVJd1ZrSlZRMEpFVVZSRmQwaG9ZMDVOClZGbDNUVlJGZVUxVVJURk5SRVV4VjJoalRr
-MXFXWGROVkVFMVRWUkZNVTFFUlRGWGFrRlRUVkpCZHdwRVoxbEVWbEZSUkVWM1pFWlIKVmtGblVU
-QkZlRTFKU1VKSmFrRk9RbWRyY1docmFVYzVkekJDUVZGRlJrRkJUME5CVVRoQlRVbEpRa05uUzBO
-QlVVVkJDbnB1UVZCVgplakkyVFhOaFpUUjNjelF6WTNwU05ERXZTakpSZEhKVFNWcFZTMjFXVlhO
-V2RXMUVZbGxJY2xCT2RsUllTMU5OV0VGalpYZFBVa1JSCldWZ0tVbkYyU0had2JqaERjMk5DTVN0
-dlIxaGFka2gzZUdvMGVsWXdWMHR2U3pKNlpWaHJZWFV6ZG1ONWJETklTVXQxY0VwbWNUSlUKUlVG
-RFpXWldhbW93ZEFwS1Z5dFlNelZRUjFkd09TOUlOWHBKVlU1V1RsWnFVemRWYlhNNE5FbDJTMmhT
-UWpnMU1USlFRamxWZVVoaApaMWhaVmxnMVIxZHdRV05XY0hsbWNteFNDa1pKT1ZGa2FHZ3JVR0py
-TUhWNWEzUmtZbVl2UTJSbVowaFBiMlZpY2xSMGQxSnNhazB3CmIwUjBXQ3N5UTNZMmFqQjNRa3Mz
-YUVRNGNGQjJaakVyZFhrS1IzcGplbWxuUVZVdk5FdDNOMlZhY1hsa1pqbENLelZTZFhCU0swbGEK
-YVhCWU5ERjRSV2xKY2t0U2QzRnBOVEUzVjFkNldHTnFZVWN5WTA1aVpqUTFNUXA0Y0VnMVVHNVdN
-Mmt4ZEhFd05HcE5SMUZWZWtaMwpTVVJCVVVGQ2J6UkhRVTFJTkhkSVVWbEVWbEl3VDBKQ1dVVkdT
-WGRZTkhaek9FSnBRbU5UWTI5a0NqVnViMXBJVWswNFJUUXJhVTFGClNVZEJNVlZrU1hkUk4wMUVi
-VUZHU1hkWU5IWnpPRUpwUW1OVFkyOWtOVzV2V2toU1RUaEZOQ3RwYjFKaGEwWkVRVk1LVFZKQmQw
-Um4KV1VSV1VWRkVSWGRrUmxGV1FXZFJNRVY0WjJkclFXZDFWVll6UkUxMFZ6WnpkMFJCV1VSV1Vq
-QlVRa0ZWZDBGM1JVSXZla0ZNUW1kTwpWZ3BJVVRoRlFrRk5RMEZSV1hkRVVWbEtTMjlhU1doMlkw
-NUJVVVZNUWxGQlJHZG5SVUpCUm1aUmNVOVVRVGRTZGpkTEsyeDFVVGR3CmJtRnpORUpaZDBoRkNq
-bEhSVkF2ZFc5b2RqWkxUM2t3VkVkUlJtSnlVbFJxUm05TVZrNUNPVUphTVhsdFRVUmFNQzlVU1hk
-SlZXTTMKZDJrM1lUaDBOVzFGY1ZsSU1UVXpkMWNLWVZkdmIybFRhbmxNVEdoMVNUUnpUbkpPUTA5
-MGFYTmtRbkV5Y2pKTlJsaDBObWd3YlVGUgpXVTlRZGpoU09FczNMMlpuVTNoSFJuRjZhSGxPYlcx
-V1RBb3hjVUpLYkdSNE16UlRjSGR6VkVGTVVWWlFZalJvUjNkS2VscG1jakZRClkzQkZVWGcyZUUx
-dVZHdzRlRVZYV2tVelRYTTVPWFZoVlhoaVVYRkpkMUoxQ2t4blFVOXJUa050V1RKdE9EbFdhSHBo
-U0VveGRWWTQKTlVGa1RTOTBSQ3RaYzIxc2JtNXFkRGxNVWtObGFtSkNhWEJxU1VkcVQxaHlaekZL
-VUN0c2VGWUtiWFZOTkhaSUsxQXZiV3h0ZUhOUQpVSG93WkRZMVlpdEZSMjFLV25CdlRHdFBMM1Jr
-VGs1MlExbDZha3B3VkVWWGNFVnpUelpPVFdoTFdXODlDaTB0TFMwdFJVNUVJRU5GClVsUkpSa2xE
-UVZSRkxTMHRMUzBLCg==
\ No newline at end of file
diff --git a/wifi/tests/assets/hsr1/HSR1ProfileWithNonBase64Part.base64 b/wifi/tests/assets/hsr1/HSR1ProfileWithNonBase64Part.base64
deleted file mode 100644
index 5c23f61..0000000
--- a/wifi/tests/assets/hsr1/HSR1ProfileWithNonBase64Part.base64
+++ /dev/null
@@ -1,86 +0,0 @@
-TUlNRS1WZXJzaW9uOiAxLjAKQ29udGVudC1UeXBlOiBtdWx0aXBhcnQvbWl4ZWQ7IGJvdW5kYXJ5
-PXtib3VuZGFyeX07IGNoYXJzZXQ9VVRGLTgKQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogOGJp
-dAoKLS17Ym91bmRhcnl9CkNvbnRlbnQtVHlwZTogYXBwbGljYXRpb24veC1wYXNzcG9pbnQtcHJv
-ZmlsZTsgY2hhcnNldD1VVEYtOApDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBiYXNlNjQKClBF
-MW5iWFJVY21WbElIaHRiRzV6UFNKemVXNWpiV3c2Wkcxa1pHWXhMaklpUGdvZ0lEeFdaWEpFVkVR
-K01TNHlQQzlXWlhKRVZFUSsKQ2lBZ1BFNXZaR1UrQ2lBZ0lDQThUbTlrWlU1aGJXVStVR1Z5VUhK
-dmRtbGtaWEpUZFdKelkzSnBjSFJwYjI0OEwwNXZaR1ZPWVcxbApQZ29nSUNBZ1BGSlVVSEp2Y0dW
-eWRHbGxjejRLSUNBZ0lDQWdQRlI1Y0dVK0NpQWdJQ0FnSUNBZ1BFUkVSazVoYldVK2RYSnVPbmRt
-CllUcHRienBvYjNSemNHOTBNbVJ2ZERBdGNHVnljSEp2ZG1sa1pYSnpkV0p6WTNKcGNIUnBiMjQ2
-TVM0d1BDOUVSRVpPWVcxbFBnb2cKSUNBZ0lDQThMMVI1Y0dVK0NpQWdJQ0E4TDFKVVVISnZjR1Z5
-ZEdsbGN6NEtJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQThUbTlrWlU1aApiV1UrYVRBd01Ud3ZUbTlr
-WlU1aGJXVStDaUFnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUR4T2IyUmxUbUZ0WlQ1SWIyMWxV
-MUE4CkwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZa
-R1ZPWVcxbFBrWnlhV1Z1Wkd4NVRtRnQKWlR3dlRtOWtaVTVoYldVK0NpQWdJQ0FnSUNBZ0lDQThW
-bUZzZFdVK1JYaGhiWEJzWlNCT1pYUjNiM0pyUEM5V1lXeDFaVDRLSUNBZwpJQ0FnSUNBOEwwNXZa
-R1UrQ2lBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0E4VG05a1pVNWhiV1UrUmxGRVRq
-d3ZUbTlrClpVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNBOFZtRnNkV1UrYUc5MGMzQnZkQzVsZUdGdGNH
-eGxMbTVsZER3dlZtRnNkV1UrQ2lBZ0lDQWcKSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUR4T2Iy
-UmxQZ29nSUNBZ0lDQWdJQ0FnUEU1dlpHVk9ZVzFsUGxKdllXMXBibWREYjI1egpiM0owYVhWdFQw
-azhMMDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQakV4TWpJek15dzBORFUxTmpZ
-OEwxWmhiSFZsClBnb2dJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNB
-Z0lDQThUbTlrWlQ0S0lDQWdJQ0FnSUNBOFRtOWsKWlU1aGJXVStRM0psWkdWdWRHbGhiRHd2VG05
-a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0E4VG05awpaVTVoYldV
-K1VtVmhiRzA4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ1BGWmhiSFZsUG1WNFlXMXdiR1V1
-WTI5dFBDOVdZV3gxClpUNEtJQ0FnSUNBZ0lDQThMMDV2WkdVK0NpQWdJQ0FnSUNBZ1BFNXZaR1Ur
-Q2lBZ0lDQWdJQ0FnSUNBOFRtOWtaVTVoYldVK1ZYTmwKY201aGJXVlFZWE56ZDI5eVpEd3ZUbTlr
-WlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0E4VG05a1pUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEU1dgpaR1ZP
-WVcxbFBsVnpaWEp1WVcxbFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQ
-blZ6WlhJOEwxWmhiSFZsClBnb2dJQ0FnSUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdQ
-RTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJSbFRtRnQKWlQ1UVlYTnpkMjl5WkR3dlRtOWta
-VTVoYldVK0NpQWdJQ0FnSUNBZ0lDQWdJRHhXWVd4MVpUNWpSMFo2WXpOa2RtTnRVVDA4TDFaaApi
-SFZsUGdvZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZaR1UrQ2lBZ0lD
-QWdJQ0FnSUNBZ0lEeE9iMlJsClRtRnRaVDVGUVZCTlpYUm9iMlE4TDA1dlpHVk9ZVzFsUGdvZ0lD
-QWdJQ0FnSUNBZ0lDQThUbTlrWlQ0S0lDQWdJQ0FnSUNBZ0lDQWcKSUNBOFRtOWtaVTVoYldVK1JV
-RlFWSGx3WlR3dlRtOWtaVTVoYldVK0NpQWdJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQakl4UEM5
-VwpZV3gxWlQ0S0lDQWdJQ0FnSUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdJQ0E4VG05
-a1pUNEtJQ0FnSUNBZ0lDQWdJQ0FnCklDQThUbTlrWlU1aGJXVStTVzV1WlhKTlpYUm9iMlE4TDA1
-dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ0lDQWdJRHhXWVd4MVpUNU4KVXkxRFNFRlFMVll5UEM5
-V1lXeDFaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJs
-UGdvZwpJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0Fn
-SUR4T2IyUmxUbUZ0WlQ1RWFXZHBkR0ZzClEyVnlkR2xtYVdOaGRHVThMMDV2WkdWT1lXMWxQZ29n
-SUNBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2IyUmwKVG1GdFpUNURaWEow
-YVdacFkyRjBaVlI1Y0dVOEwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWdJQ0E4Vm1Gc2RXVStl
-RFV3T1hZegpQQzlXWVd4MVpUNEtJQ0FnSUNBZ0lDQWdJRHd2VG05a1pUNEtJQ0FnSUNBZ0lDQWdJ
-RHhPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdJQ0E4ClRtOWtaVTVoYldVK1EyVnlkRk5JUVRJMU5rWnBi
-bWRsY25CeWFXNTBQQzlPYjJSbFRtRnRaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BGWmgKYkhWbFBqRm1N
-V1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1X
-WXhaakZtTVdZeApaakZtTVdZeFpqRm1NV1k4TDFaaGJIVmxQZ29nSUNBZ0lDQWdJQ0FnUEM5T2Iy
-UmxQZ29nSUNBZ0lDQWdJRHd2VG05a1pUNEtJQ0FnCklDQWdJQ0E4VG05a1pUNEtJQ0FnSUNBZ0lD
-QWdJRHhPYjJSbFRtRnRaVDVUU1UwOEwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWcKUEU1dlpH
-VStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2IyUmxUbUZ0WlQ1SlRWTkpQQzlPYjJSbFRtRnRaVDRLSUNB
-Z0lDQWdJQ0FnSUNBZwpQRlpoYkhWbFBqRXlNelExTmlvOEwxWmhiSFZsUGdvZ0lDQWdJQ0FnSUNB
-Z1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZaR1UrCkNpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJS
-bFRtRnRaVDVGUVZCVWVYQmxQQzlPYjJSbFRtRnRaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BGWmgKYkhW
-bFBqSXpQQzlXWVd4MVpUNEtJQ0FnSUNBZ0lDQWdJRHd2VG05a1pUNEtJQ0FnSUNBZ0lDQThMMDV2
-WkdVK0NpQWdJQ0FnSUR3dgpUbTlrWlQ0S0lDQWdJRHd2VG05a1pUNEtJQ0E4TDA1dlpHVStDand2
-VFdkdGRGUnlaV1UrCgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi94LXg1
-MDktY2EtY2VydApDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBiYXNlNjQKCkxTMHRMUzFDUlVk
-SlRpQkRSVkpVU1VaSlEwRlVSUzB0TFMwdENrMUpTVVJMUkVORFFXaERaMEYzU1VKQlowbEtRVWxN
-YkVaa2QzcE0KVm5WeVRVRXdSME5UY1VkVFNXSXpSRkZGUWtOM1ZVRk5Ra2w0UlVSQlQwSm5UbFlL
-UWtGTlZFSXdWa0pWUTBKRVVWUkZkMGhvWTA1TgpWRmwzVFZSRmVVMVVSVEZOUkVVeFYyaGpUazFx
-V1hkTlZFRTFUVlJGTVUxRVJURlhha0ZUVFZKQmR3cEVaMWxFVmxGUlJFVjNaRVpSClZrRm5VVEJG
-ZUUxSlNVSkpha0ZPUW1kcmNXaHJhVWM1ZHpCQ1FWRkZSa0ZCVDBOQlVUaEJUVWxKUWtOblMwTkJV
-VVZCQ25wdVFWQlYKZWpJMlRYTmhaVFIzY3pRelkzcFNOREV2U2pKUmRISlRTVnBWUzIxV1ZYTldk
-VzFFWWxsSWNsQk9kbFJZUzFOTldFRmpaWGRQVWtSUgpXVmdLVW5GMlNIWndiamhEYzJOQ01TdHZS
-MWhhZGtoM2VHbzBlbFl3VjB0dlN6SjZaVmhyWVhVemRtTjViRE5JU1V0MWNFcG1jVEpVClJVRkRa
-V1pXYW1vd2RBcEtWeXRZTXpWUVIxZHdPUzlJTlhwSlZVNVdUbFpxVXpkVmJYTTRORWwyUzJoU1Fq
-ZzFNVEpRUWpsVmVVaGgKWjFoWlZsZzFSMWR3UVdOV2NIbG1jbXhTQ2taSk9WRmthR2dyVUdKck1I
-VjVhM1JrWW1ZdlEyUm1aMGhQYjJWaWNsUjBkMUpzYWswdwpiMFIwV0NzeVEzWTJhakIzUWtzM2FF
-UTRjRkIyWmpFcmRYa0tSM3BqZW1sblFWVXZORXQzTjJWYWNYbGtaamxDS3pWU2RYQlNLMGxhCmFY
-QllOREY0UldsSmNrdFNkM0ZwTlRFM1YxZDZXR05xWVVjeVkwNWlaalExTVFwNGNFZzFVRzVXTTJr
-eGRIRXdOR3BOUjFGVmVrWjMKU1VSQlVVRkNielJIUVUxSU5IZElVVmxFVmxJd1QwSkNXVVZHU1hk
-WU5IWnpPRUpwUW1OVFkyOWtDalZ1YjFwSVVrMDRSVFFyYVUxRgpTVWRCTVZWa1NYZFJOMDFFYlVG
-R1NYZFlOSFp6T0VKcFFtTlRZMjlrTlc1dldraFNUVGhGTkN0cGIxSmhhMFpFUVZNS1RWSkJkMFJu
-CldVUldVVkZFUlhka1JsRldRV2RSTUVWNFoyZHJRV2QxVlZZelJFMTBWelp6ZDBSQldVUldVakJV
-UWtGVmQwRjNSVUl2ZWtGTVFtZE8KVmdwSVVUaEZRa0ZOUTBGUldYZEVVVmxLUzI5YVNXaDJZMDVC
-VVVWTVFsRkJSR2RuUlVKQlJtWlJjVTlVUVRkU2RqZExLMngxVVRkdwpibUZ6TkVKWmQwaEZDamxI
-UlZBdmRXOW9kalpMVDNrd1ZFZFJSbUp5VWxScVJtOU1WazVDT1VKYU1YbHRUVVJhTUM5VVNYZEpW
-V00zCmQyazNZVGgwTlcxRmNWbElNVFV6ZDFjS1lWZHZiMmxUYW5sTVRHaDFTVFJ6VG5KT1EwOTBh
-WE5rUW5FeWNqSk5SbGgwTm1nd2JVRlIKV1U5UWRqaFNPRXMzTDJablUzaEhSbkY2YUhsT2JXMVdU
-QW94Y1VKS2JHUjRNelJUY0hkelZFRk1VVlpRWWpSb1IzZEtlbHBtY2pGUQpZM0JGVVhnMmVFMXVW
-R3c0ZUVWWFdrVXpUWE01T1hWaFZYaGlVWEZKZDFKMUNreG5RVTlyVGtOdFdUSnRPRGxXYUhwaFNF
-b3hkVlk0Ck5VRmtUUzkwUkN0WmMyMXNibTVxZERsTVVrTmxhbUpDYVhCcVNVZHFUMWh5WnpGS1VD
-dHNlRllLYlhWTk5IWklLMUF2Yld4dGVITlEKVUhvd1pEWTFZaXRGUjIxS1duQnZUR3RQTDNSa1Rr
-NTJRMWw2YWtwd1ZFVlhjRVZ6VHpaT1RXaExXVzg5Q2kwdExTMHRSVTVFSUVORgpVbFJKUmtsRFFW
-UkZMUzB0TFMwSwotLXtib3VuZGFyeX0tLQo=
\ No newline at end of file
diff --git a/wifi/tests/assets/hsr1/HSR1ProfileWithUpdateIdentifier.base64 b/wifi/tests/assets/hsr1/HSR1ProfileWithUpdateIdentifier.base64
deleted file mode 100644
index bab7607..0000000
--- a/wifi/tests/assets/hsr1/HSR1ProfileWithUpdateIdentifier.base64
+++ /dev/null
@@ -1,88 +0,0 @@
-TUlNRS1WZXJzaW9uOiAxLjAKQ29udGVudC1UeXBlOiBtdWx0aXBhcnQvbWl4ZWQ7IGJvdW5kYXJ5
-PXtib3VuZGFyeX07IGNoYXJzZXQ9VVRGLTgKQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogYmFz
-ZTY0CgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi94LXBhc3Nwb2ludC1w
-cm9maWxlOyBjaGFyc2V0PVVURi04CkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IGJhc2U2NAoK
-UEUxbmJYUlVjbVZsSUhodGJHNXpQU0p6ZVc1amJXdzZaRzFrWkdZeExqSWlQZ29nSUR4V1pYSkVW
-RVErTVM0eVBDOVdaWEpFVkVRKwpDaUFnUEU1dlpHVStDaUFnSUNBOFRtOWtaVTVoYldVK1VHVnlV
-SEp2ZG1sa1pYSlRkV0p6WTNKcGNIUnBiMjQ4TDA1dlpHVk9ZVzFsClBnb2dJQ0FnUEZKVVVISnZj
-R1Z5ZEdsbGN6NEtJQ0FnSUNBZ1BGUjVjR1UrQ2lBZ0lDQWdJQ0FnUEVSRVJrNWhiV1UrZFhKdU9u
-ZG0KWVRwdGJ6cG9iM1J6Y0c5ME1tUnZkREF0Y0dWeWNISnZkbWxrWlhKemRXSnpZM0pwY0hScGIy
-NDZNUzR3UEM5RVJFWk9ZVzFsUGdvZwpJQ0FnSUNBOEwxUjVjR1UrQ2lBZ0lDQThMMUpVVUhKdmNH
-VnlkR2xsY3o0S0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBOFRtOWtaVTVoCmJXVStWWEJrWVhSbFNX
-UmxiblJwWm1sbGNqd3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lEeFdZV3gxWlQ0eE1qTTBQQzlXWVd4
-MVpUNEsKSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBOFRtOWtaVTVoYldV
-K2FUQXdNVHd2VG05a1pVNWhiV1UrQ2lBZwpJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQWdJRHhPYjJS
-bFRtRnRaVDVJYjIxbFUxQThMMDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJRHhPCmIyUmxQZ29nSUNB
-Z0lDQWdJQ0FnUEU1dlpHVk9ZVzFsUGtaeWFXVnVaR3g1VG1GdFpUd3ZUbTlrWlU1aGJXVStDaUFn
-SUNBZ0lDQWcKSUNBOFZtRnNkV1UrUlhoaGJYQnNaU0JPWlhSM2IzSnJQQzlXWVd4MVpUNEtJQ0Fn
-SUNBZ0lDQThMMDV2WkdVK0NpQWdJQ0FnSUNBZwpQRTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThUbTlr
-WlU1aGJXVStSbEZFVGp3dlRtOWtaVTVoYldVK0NpQWdJQ0FnSUNBZ0lDQThWbUZzCmRXVSthRzkw
-YzNCdmRDNWxlR0Z0Y0d4bExtNWxkRHd2Vm1Gc2RXVStDaUFnSUNBZ0lDQWdQQzlPYjJSbFBnb2dJ
-Q0FnSUNBZ0lEeE8KYjJSbFBnb2dJQ0FnSUNBZ0lDQWdQRTV2WkdWT1lXMWxQbEp2WVcxcGJtZERi
-MjV6YjNKMGFYVnRUMGs4TDA1dlpHVk9ZVzFsUGdvZwpJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBqRXhN
-akl6TXl3ME5EVTFOalk4TDFaaGJIVmxQZ29nSUNBZ0lDQWdJRHd2VG05a1pUNEtJQ0FnCklDQWdQ
-QzlPYjJSbFBnb2dJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0E4VG05a1pVNWhiV1UrUTNKbFpH
-VnVkR2xoYkR3dlRtOWsKWlU1aGJXVStDaUFnSUNBZ0lDQWdQRTV2WkdVK0NpQWdJQ0FnSUNBZ0lD
-QThUbTlrWlU1aGJXVStVbVZoYkcwOEwwNXZaR1ZPWVcxbApQZ29nSUNBZ0lDQWdJQ0FnUEZaaGJI
-VmxQbVY0WVcxd2JHVXVZMjl0UEM5V1lXeDFaVDRLSUNBZ0lDQWdJQ0E4TDA1dlpHVStDaUFnCklD
-QWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0E4VG05a1pVNWhiV1UrVlhObGNtNWhiV1ZRWVhO
-emQyOXlaRHd2VG05a1pVNWgKYldVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrWlQ0S0lDQWdJQ0FnSUNB
-Z0lDQWdQRTV2WkdWT1lXMWxQbFZ6WlhKdVlXMWxQQzlPYjJSbApUbUZ0WlQ0S0lDQWdJQ0FnSUNB
-Z0lDQWdQRlpoYkhWbFBuVnpaWEk4TDFaaGJIVmxQZ29nSUNBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29n
-CklDQWdJQ0FnSUNBZ1BFNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lEeE9iMlJsVG1GdFpUNVFZWE56
-ZDI5eVpEd3ZUbTlrWlU1aGJXVSsKQ2lBZ0lDQWdJQ0FnSUNBZ0lEeFdZV3gxWlQ1alIwWjZZek5r
-ZG1OdFVUMDhMMVpoYkhWbFBnb2dJQ0FnSUNBZ0lDQWdQQzlPYjJSbApQZ29nSUNBZ0lDQWdJQ0Fn
-UEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2IyUmxUbUZ0WlQ1RlFWQk5aWFJvYjJROEwwNXZa
-R1ZPCllXMWxQZ29nSUNBZ0lDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0FnSUNBZ0lDQThU
-bTlrWlU1aGJXVStSVUZRVkhsd1pUd3YKVG05a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lDQWdQ
-RlpoYkhWbFBqSXhQQzlXWVd4MVpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEM5TwpiMlJsUGdvZ0lDQWdJ
-Q0FnSUNBZ0lDQThUbTlrWlQ0S0lDQWdJQ0FnSUNBZ0lDQWdJQ0E4VG05a1pVNWhiV1UrU1c1dVpY
-Sk5aWFJvCmIyUThMMDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnSUNBZ0lEeFdZV3gxWlQ1TlV5
-MURTRUZRTFZZeVBDOVdZV3gxWlQ0S0lDQWcKSUNBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lD
-QWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJRHd2VG05a1pUNEtJQ0FnSUNBZwpJQ0E4VG05a1pU
-NEtJQ0FnSUNBZ0lDQWdJRHhPYjJSbFRtRnRaVDVFYVdkcGRHRnNRMlZ5ZEdsbWFXTmhkR1U4TDA1
-dlpHVk9ZVzFsClBnb2dJQ0FnSUNBZ0lDQWdQRTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJS
-bFRtRnRaVDVEWlhKMGFXWnBZMkYwWlZSNWNHVTgKTDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNB
-Z0lDQThWbUZzZFdVK2VEVXdPWFl6UEM5V1lXeDFaVDRLSUNBZ0lDQWdJQ0FnSUR3dgpUbTlrWlQ0
-S0lDQWdJQ0FnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThUbTlrWlU1aGJXVStRMlZ5
-ZEZOSVFUSTFOa1pwCmJtZGxjbkJ5YVc1MFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0Fn
-UEZaaGJIVmxQakZtTVdZeFpqRm1NV1l4WmpGbU1XWXgKWmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4
-WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaakZtTVdZOEwxWmhiSFZsUGdvZwpJQ0Fn
-SUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJQ0FnSUNBOFRtOWta
-VDRLSUNBZ0lDQWdJQ0FnCklEeE9iMlJsVG1GdFpUNVRTVTA4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJ
-Q0FnSUNBZ1BFNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lEeE8KYjJSbFRtRnRaVDVKVFZOSlBDOU9i
-MlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQakV5TXpRMU5pbzhMMVpoYkhWbApQ
-Z29nSUNBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lD
-QWdJQ0FnSUR4T2IyUmxUbUZ0ClpUNUZRVkJVZVhCbFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lD
-QWdJQ0FnUEZaaGJIVmxQakl6UEM5V1lXeDFaVDRLSUNBZ0lDQWcKSUNBZ0lEd3ZUbTlrWlQ0S0lD
-QWdJQ0FnSUNBOEwwNXZaR1UrQ2lBZ0lDQWdJRHd2VG05a1pUNEtJQ0FnSUR3dlRtOWtaVDRLSUNB
-OApMMDV2WkdVK0Nqd3ZUV2R0ZEZSeVpXVSsKCi0te2JvdW5kYXJ5fQpDb250ZW50LVR5cGU6IGFw
-cGxpY2F0aW9uL3gteDUwOS1jYS1jZXJ0CkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IGJhc2U2
-NAoKTFMwdExTMUNSVWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVUkxSRU5EUVdoRFow
-RjNTVUpCWjBsS1FVbE1iRVprZDNwTQpWblZ5VFVFd1IwTlRjVWRUU1dJelJGRkZRa04zVlVGTlFr
-bDRSVVJCVDBKblRsWUtRa0ZOVkVJd1ZrSlZRMEpFVVZSRmQwaG9ZMDVOClZGbDNUVlJGZVUxVVJU
-Rk5SRVV4VjJoalRrMXFXWGROVkVFMVRWUkZNVTFFUlRGWGFrRlRUVkpCZHdwRVoxbEVWbEZSUkVW
-M1pFWlIKVmtGblVUQkZlRTFKU1VKSmFrRk9RbWRyY1docmFVYzVkekJDUVZGRlJrRkJUME5CVVRo
-QlRVbEpRa05uUzBOQlVVVkJDbnB1UVZCVgplakkyVFhOaFpUUjNjelF6WTNwU05ERXZTakpSZEhK
-VFNWcFZTMjFXVlhOV2RXMUVZbGxJY2xCT2RsUllTMU5OV0VGalpYZFBVa1JSCldWZ0tVbkYyU0ha
-d2JqaERjMk5DTVN0dlIxaGFka2gzZUdvMGVsWXdWMHR2U3pKNlpWaHJZWFV6ZG1ONWJETklTVXQx
-Y0VwbWNUSlUKUlVGRFpXWldhbW93ZEFwS1Z5dFlNelZRUjFkd09TOUlOWHBKVlU1V1RsWnFVemRW
-YlhNNE5FbDJTMmhTUWpnMU1USlFRamxWZVVoaApaMWhaVmxnMVIxZHdRV05XY0hsbWNteFNDa1pK
-T1ZGa2FHZ3JVR0pyTUhWNWEzUmtZbVl2UTJSbVowaFBiMlZpY2xSMGQxSnNhazB3CmIwUjBXQ3N5
-UTNZMmFqQjNRa3MzYUVRNGNGQjJaakVyZFhrS1IzcGplbWxuUVZVdk5FdDNOMlZhY1hsa1pqbENL
-elZTZFhCU0swbGEKYVhCWU5ERjRSV2xKY2t0U2QzRnBOVEUzVjFkNldHTnFZVWN5WTA1aVpqUTFN
-UXA0Y0VnMVVHNVdNMmt4ZEhFd05HcE5SMUZWZWtaMwpTVVJCVVVGQ2J6UkhRVTFJTkhkSVVWbEVW
-bEl3VDBKQ1dVVkdTWGRZTkhaek9FSnBRbU5UWTI5a0NqVnViMXBJVWswNFJUUXJhVTFGClNVZEJN
-VlZrU1hkUk4wMUViVUZHU1hkWU5IWnpPRUpwUW1OVFkyOWtOVzV2V2toU1RUaEZOQ3RwYjFKaGEw
-WkVRVk1LVFZKQmQwUm4KV1VSV1VWRkVSWGRrUmxGV1FXZFJNRVY0WjJkclFXZDFWVll6UkUxMFZ6
-WnpkMFJCV1VSV1VqQlVRa0ZWZDBGM1JVSXZla0ZNUW1kTwpWZ3BJVVRoRlFrRk5RMEZSV1hkRVVW
-bEtTMjlhU1doMlkwNUJVVVZNUWxGQlJHZG5SVUpCUm1aUmNVOVVRVGRTZGpkTEsyeDFVVGR3CmJt
-RnpORUpaZDBoRkNqbEhSVkF2ZFc5b2RqWkxUM2t3VkVkUlJtSnlVbFJxUm05TVZrNUNPVUphTVhs
-dFRVUmFNQzlVU1hkSlZXTTMKZDJrM1lUaDBOVzFGY1ZsSU1UVXpkMWNLWVZkdmIybFRhbmxNVEdo
-MVNUUnpUbkpPUTA5MGFYTmtRbkV5Y2pKTlJsaDBObWd3YlVGUgpXVTlRZGpoU09FczNMMlpuVTNo
-SFJuRjZhSGxPYlcxV1RBb3hjVUpLYkdSNE16UlRjSGR6VkVGTVVWWlFZalJvUjNkS2VscG1jakZR
-ClkzQkZVWGcyZUUxdVZHdzRlRVZYV2tVelRYTTVPWFZoVlhoaVVYRkpkMUoxQ2t4blFVOXJUa050
-V1RKdE9EbFdhSHBoU0VveGRWWTQKTlVGa1RTOTBSQ3RaYzIxc2JtNXFkRGxNVWtObGFtSkNhWEJx
-U1VkcVQxaHlaekZLVUN0c2VGWUtiWFZOTkhaSUsxQXZiV3h0ZUhOUQpVSG93WkRZMVlpdEZSMjFL
-V25CdlRHdFBMM1JrVGs1MlExbDZha3B3VkVWWGNFVnpUelpPVFdoTFdXODlDaTB0TFMwdFJVNUVJ
-RU5GClVsUkpSa2xEUVZSRkxTMHRMUzBLCi0te2JvdW5kYXJ5fS0tCg==
\ No newline at end of file
diff --git a/wifi/tests/assets/hsr1/HSR1ProfileWithoutProfile.base64 b/wifi/tests/assets/hsr1/HSR1ProfileWithoutProfile.base64
deleted file mode 100644
index 833c527..0000000
--- a/wifi/tests/assets/hsr1/HSR1ProfileWithoutProfile.base64
+++ /dev/null
@@ -1,31 +0,0 @@
-Q29udGVudC1UeXBlOiBtdWx0aXBhcnQvbWl4ZWQ7IGJvdW5kYXJ5PXtib3VuZGFyeX0KQ29udGVu
-dC1UcmFuc2Zlci1FbmNvZGluZzogYmFzZTY0CgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBh
-cHBsaWNhdGlvbi94LXg1MDktY2EtY2VydApDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBiYXNl
-NjQKCkxTMHRMUzFDUlVkSlRpQkRSVkpVU1VaSlEwRlVSUzB0TFMwdENrMUpTVVJMUkVORFFXaERa
-MEYzU1VKQlowbEtRVWxNYkVaa2QzcE0KVm5WeVRVRXdSME5UY1VkVFNXSXpSRkZGUWtOM1ZVRk5R
-a2w0UlVSQlQwSm5UbFlLUWtGTlZFSXdWa0pWUTBKRVVWUkZkMGhvWTA1TgpWRmwzVFZSRmVVMVVS
-VEZOUkVVeFYyaGpUazFxV1hkTlZFRTFUVlJGTVUxRVJURlhha0ZUVFZKQmR3cEVaMWxFVmxGUlJF
-VjNaRVpSClZrRm5VVEJGZUUxSlNVSkpha0ZPUW1kcmNXaHJhVWM1ZHpCQ1FWRkZSa0ZCVDBOQlVU
-aEJUVWxKUWtOblMwTkJVVVZCQ25wdVFWQlYKZWpJMlRYTmhaVFIzY3pRelkzcFNOREV2U2pKUmRI
-SlRTVnBWUzIxV1ZYTldkVzFFWWxsSWNsQk9kbFJZUzFOTldFRmpaWGRQVWtSUgpXVmdLVW5GMlNI
-WndiamhEYzJOQ01TdHZSMWhhZGtoM2VHbzBlbFl3VjB0dlN6SjZaVmhyWVhVemRtTjViRE5JU1V0
-MWNFcG1jVEpVClJVRkRaV1pXYW1vd2RBcEtWeXRZTXpWUVIxZHdPUzlJTlhwSlZVNVdUbFpxVXpk
-VmJYTTRORWwyUzJoU1FqZzFNVEpRUWpsVmVVaGgKWjFoWlZsZzFSMWR3UVdOV2NIbG1jbXhTQ2ta
-Sk9WRmthR2dyVUdKck1IVjVhM1JrWW1ZdlEyUm1aMGhQYjJWaWNsUjBkMUpzYWswdwpiMFIwV0Nz
-eVEzWTJhakIzUWtzM2FFUTRjRkIyWmpFcmRYa0tSM3BqZW1sblFWVXZORXQzTjJWYWNYbGtaamxD
-S3pWU2RYQlNLMGxhCmFYQllOREY0UldsSmNrdFNkM0ZwTlRFM1YxZDZXR05xWVVjeVkwNWlaalEx
-TVFwNGNFZzFVRzVXTTJreGRIRXdOR3BOUjFGVmVrWjMKU1VSQlVVRkNielJIUVUxSU5IZElVVmxF
-VmxJd1QwSkNXVVZHU1hkWU5IWnpPRUpwUW1OVFkyOWtDalZ1YjFwSVVrMDRSVFFyYVUxRgpTVWRC
-TVZWa1NYZFJOMDFFYlVGR1NYZFlOSFp6T0VKcFFtTlRZMjlrTlc1dldraFNUVGhGTkN0cGIxSmhh
-MFpFUVZNS1RWSkJkMFJuCldVUldVVkZFUlhka1JsRldRV2RSTUVWNFoyZHJRV2QxVlZZelJFMTBW
-elp6ZDBSQldVUldVakJVUWtGVmQwRjNSVUl2ZWtGTVFtZE8KVmdwSVVUaEZRa0ZOUTBGUldYZEVV
-VmxLUzI5YVNXaDJZMDVCVVVWTVFsRkJSR2RuUlVKQlJtWlJjVTlVUVRkU2RqZExLMngxVVRkdwpi
-bUZ6TkVKWmQwaEZDamxIUlZBdmRXOW9kalpMVDNrd1ZFZFJSbUp5VWxScVJtOU1WazVDT1VKYU1Y
-bHRUVVJhTUM5VVNYZEpWV00zCmQyazNZVGgwTlcxRmNWbElNVFV6ZDFjS1lWZHZiMmxUYW5sTVRH
-aDFTVFJ6VG5KT1EwOTBhWE5rUW5FeWNqSk5SbGgwTm1nd2JVRlIKV1U5UWRqaFNPRXMzTDJablUz
-aEhSbkY2YUhsT2JXMVdUQW94Y1VKS2JHUjRNelJUY0hkelZFRk1VVlpRWWpSb1IzZEtlbHBtY2pG
-UQpZM0JGVVhnMmVFMXVWR3c0ZUVWWFdrVXpUWE01T1hWaFZYaGlVWEZKZDFKMUNreG5RVTlyVGtO
-dFdUSnRPRGxXYUhwaFNFb3hkVlk0Ck5VRmtUUzkwUkN0WmMyMXNibTVxZERsTVVrTmxhbUpDYVhC
-cVNVZHFUMWh5WnpGS1VDdHNlRllLYlhWTk5IWklLMUF2Yld4dGVITlEKVUhvd1pEWTFZaXRGUjIx
-S1duQnZUR3RQTDNSa1RrNTJRMWw2YWtwd1ZFVlhjRVZ6VHpaT1RXaExXVzg5Q2kwdExTMHRSVTVF
-SUVORgpVbFJKUmtsRFFWUkZMUzB0TFMwSwotLXtib3VuZGFyeX0tLQo=
diff --git a/wifi/tests/assets/hsr1/README.txt b/wifi/tests/assets/hsr1/README.txt
deleted file mode 100644
index 9f3cdc2..0000000
--- a/wifi/tests/assets/hsr1/README.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-HSR1ProfileWithCACert.conf - unencoded installation file that contains a Passpoint profile and a CA Certificate
-HSR1ProfileWithCACert.base64 - base64 encoded of the data contained in HSR1ProfileWithCAWith.conf
-HSR1ProfileWithNonBase64Part.base64 - base64 encoded installation file that contains a part of non-base64 encoding type
-HSR1ProfileWithMissingBoundary.base64 - base64 encoded installation file with missing end-boundary in the MIME data
-HSR1ProfileWithInvalidContentType.base64 - base64 encoded installation file with that contains a MIME part with an invalid content type
-HSR1ProfileWithUpdateIdentifier.base64 - base64 encoded installation file with that contains an R2 update identifier
diff --git a/wifi/tests/assets/pps/PerProviderSubscription.xml b/wifi/tests/assets/pps/PerProviderSubscription.xml
deleted file mode 100644
index e9afb35..0000000
--- a/wifi/tests/assets/pps/PerProviderSubscription.xml
+++ /dev/null
@@ -1,430 +0,0 @@
-<MgmtTree xmlns="syncml:dmddf1.2">
-  <VerDTD>1.2</VerDTD>
-  <Node>
-    <NodeName>PerProviderSubscription</NodeName>
-    <RTProperties>
-      <Type>
-        <DDFName>urn:wfa:mo:hotspot2dot0-perprovidersubscription:1.0</DDFName>
-      </Type>
-    </RTProperties>
-    <Node>
-      <NodeName>UpdateIdentifier</NodeName>
-      <Value>12</Value>
-    </Node>
-    <Node>
-      <NodeName>i001</NodeName>
-      <Node>
-        <NodeName>Extension</NodeName>
-        <Node>
-          <NodeName>VendorSpecific</NodeName>
-          <Value>Test</Value>
-        </Node>
-        <Node>
-          <NodeName>VendorExtension</NodeName>
-          <Node>
-            <NodeName>VendorAttribute</NodeName>
-            <Value>VendorValue</Value>
-          </Node>
-        </Node>
-        <Node>
-          <NodeName>Android</NodeName>
-          <Node>
-            <NodeName>AAAServerTrustedNames</NodeName>
-            <Node>
-              <NodeName>FQDN</NodeName>
-              <Value>trusted.fqdn.com;another-trusted.fqdn.com</Value>
-            </Node>
-          </Node>
-          <Node>
-            <NodeName>NewSubTree</NodeName>
-            <Node>
-              <NodeName>NewAttribute</NodeName>
-              <Value>NewValue</Value>
-            </Node>
-          </Node>
-        </Node>
-      </Node>
-      <Node>
-        <NodeName>HomeSP</NodeName>
-        <Node>
-          <NodeName>FriendlyName</NodeName>
-          <Value>Century House</Value>
-        </Node>
-        <Node>
-          <NodeName>FQDN</NodeName>
-          <Value>mi6.co.uk</Value>
-        </Node>
-        <Node>
-          <NodeName>RoamingConsortiumOI</NodeName>
-          <Value>112233,445566</Value>
-        </Node>
-        <Node>
-          <NodeName>IconURL</NodeName>
-          <Value>icon.test.com</Value>
-        </Node>
-        <Node>
-          <NodeName>NetworkID</NodeName>
-          <Node>
-            <NodeName>n001</NodeName>
-            <Node>
-              <NodeName>SSID</NodeName>
-              <Value>TestSSID</Value>
-            </Node>
-            <Node>
-              <NodeName>HESSID</NodeName>
-              <Value>12345678</Value>
-            </Node>
-          </Node>
-          <Node>
-            <NodeName>n002</NodeName>
-            <Node>
-              <NodeName>SSID</NodeName>
-              <Value>NullHESSID</Value>
-            </Node>
-          </Node>
-        </Node>
-        <Node>
-          <NodeName>HomeOIList</NodeName>
-          <Node>
-            <NodeName>h001</NodeName>
-            <Node>
-              <NodeName>HomeOI</NodeName>
-              <Value>11223344</Value>
-            </Node>
-            <Node>
-              <NodeName>HomeOIRequired</NodeName>
-              <Value>true</Value>
-            </Node>
-          </Node>
-          <Node>
-            <NodeName>h002</NodeName>
-            <Node>
-              <NodeName>HomeOI</NodeName>
-              <Value>55667788</Value>
-            </Node>
-            <Node>
-              <NodeName>HomeOIRequired</NodeName>
-              <Value>false</Value>
-            </Node>
-          </Node>
-        </Node>
-        <Node>
-          <NodeName>OtherHomePartners</NodeName>
-          <Node>
-            <NodeName>o001</NodeName>
-            <Node>
-              <NodeName>FQDN</NodeName>
-              <Value>other.fqdn.com</Value>
-            </Node>
-          </Node>
-        </Node>
-      </Node>
-      <Node>
-        <NodeName>Credential</NodeName>
-        <Node>
-          <NodeName>CreationDate</NodeName>
-          <Value>2016-01-01T10:00:00Z</Value>
-        </Node>
-        <Node>
-          <NodeName>ExpirationDate</NodeName>
-          <Value>2016-02-01T10:00:00Z</Value>
-        </Node>
-        <Node>
-          <NodeName>Realm</NodeName>
-          <Value>shaken.stirred.com</Value>
-        </Node>
-        <Node>
-          <NodeName>CheckAAAServerCertStatus</NodeName>
-          <Value>true</Value>
-        </Node>
-        <Node>
-          <NodeName>UsernamePassword</NodeName>
-          <Node>
-            <NodeName>Username</NodeName>
-            <Value>james</Value>
-          </Node>
-          <Node>
-            <NodeName>Password</NodeName>
-            <Value>Ym9uZDAwNw==</Value>
-          </Node>
-          <Node>
-            <NodeName>MachineManaged</NodeName>
-            <Value>true</Value>
-          </Node>
-          <Node>
-            <NodeName>SoftTokenApp</NodeName>
-            <Value>TestApp</Value>
-          </Node>
-          <Node>
-            <NodeName>AbleToShare</NodeName>
-            <Value>true</Value>
-          </Node>
-          <Node>
-            <NodeName>EAPMethod</NodeName>
-            <Node>
-              <NodeName>EAPType</NodeName>
-              <Value>21</Value>
-            </Node>
-            <Node>
-              <NodeName>InnerMethod</NodeName>
-              <Value>MS-CHAP-V2</Value>
-            </Node>
-          </Node>
-        </Node>
-        <Node>
-          <NodeName>DigitalCertificate</NodeName>
-          <Node>
-            <NodeName>CertificateType</NodeName>
-            <Value>x509v3</Value>
-          </Node>
-          <Node>
-            <NodeName>CertSHA256Fingerprint</NodeName>
-            <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value>
-          </Node>
-        </Node>
-        <Node>
-          <NodeName>SIM</NodeName>
-          <Node>
-            <NodeName>IMSI</NodeName>
-            <Value>imsi</Value>
-          </Node>
-          <Node>
-            <NodeName>EAPType</NodeName>
-            <Value>24</Value>
-          </Node>
-        </Node>
-      </Node>
-      <Node>
-        <NodeName>Policy</NodeName>
-        <Node>
-          <NodeName>PreferredRoamingPartnerList</NodeName>
-          <Node>
-            <NodeName>p001</NodeName>
-            <Node>
-              <NodeName>FQDN_Match</NodeName>
-              <Value>test1.fqdn.com,exactMatch</Value>
-            </Node>
-            <Node>
-              <NodeName>Priority</NodeName>
-              <Value>127</Value>
-            </Node>
-            <Node>
-              <NodeName>Country</NodeName>
-              <Value>us,fr</Value>
-            </Node>
-          </Node>
-          <Node>
-            <NodeName>p002</NodeName>
-            <Node>
-              <NodeName>FQDN_Match</NodeName>
-              <Value>test2.fqdn.com,includeSubdomains</Value>
-            </Node>
-            <Node>
-              <NodeName>Priority</NodeName>
-              <Value>200</Value>
-            </Node>
-            <Node>
-              <NodeName>Country</NodeName>
-              <Value>*</Value>
-            </Node>
-          </Node>
-        </Node>
-        <Node>
-          <NodeName>MinBackhaulThreshold</NodeName>
-          <Node>
-            <NodeName>m001</NodeName>
-            <Node>
-              <NodeName>NetworkType</NodeName>
-              <Value>home</Value>
-            </Node>
-            <Node>
-              <NodeName>DLBandwidth</NodeName>
-              <Value>23412</Value>
-            </Node>
-            <Node>
-              <NodeName>ULBandwidth</NodeName>
-              <Value>9823</Value>
-            </Node>
-          </Node>
-          <Node>
-            <NodeName>m002</NodeName>
-            <Node>
-              <NodeName>NetworkType</NodeName>
-              <Value>roaming</Value>
-            </Node>
-            <Node>
-              <NodeName>DLBandwidth</NodeName>
-              <Value>9271</Value>
-            </Node>
-            <Node>
-              <NodeName>ULBandwidth</NodeName>
-              <Value>2315</Value>
-            </Node>
-          </Node>
-        </Node>
-        <Node>
-          <NodeName>PolicyUpdate</NodeName>
-          <Node>
-            <NodeName>UpdateInterval</NodeName>
-            <Value>120</Value>
-          </Node>
-          <Node>
-            <NodeName>UpdateMethod</NodeName>
-            <Value>OMA-DM-ClientInitiated</Value>
-          </Node>
-          <Node>
-            <NodeName>Restriction</NodeName>
-            <Value>HomeSP</Value>
-          </Node>
-          <Node>
-            <NodeName>URI</NodeName>
-            <Value>policy.update.com</Value>
-          </Node>
-          <Node>
-            <NodeName>UsernamePassword</NodeName>
-            <Node>
-              <NodeName>Username</NodeName>
-              <Value>updateUser</Value>
-            </Node>
-            <Node>
-              <NodeName>Password</NodeName>
-              <Value>updatePass</Value>
-            </Node>
-          </Node>
-          <Node>
-            <NodeName>TrustRoot</NodeName>
-            <Node>
-              <NodeName>CertURL</NodeName>
-              <Value>update.cert.com</Value>
-            </Node>
-            <Node>
-              <NodeName>CertSHA256Fingerprint</NodeName>
-              <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value>
-            </Node>
-          </Node>
-        </Node>
-        <Node>
-          <NodeName>SPExclusionList</NodeName>
-          <Node>
-            <NodeName>s001</NodeName>
-            <Node>
-              <NodeName>SSID</NodeName>
-              <Value>excludeSSID</Value>
-            </Node>
-          </Node>
-        </Node>
-        <Node>
-          <NodeName>RequiredProtoPortTuple</NodeName>
-          <Node>
-            <NodeName>r001</NodeName>
-            <Node>
-              <NodeName>IPProtocol</NodeName>
-              <Value>12</Value>
-            </Node>
-            <Node>
-              <NodeName>PortNumber</NodeName>
-              <Value>34,92,234</Value>
-            </Node>
-          </Node>
-        </Node>
-        <Node>
-          <NodeName>MaximumBSSLoadValue</NodeName>
-          <Value>23</Value>
-        </Node>
-      </Node>
-      <Node>
-        <NodeName>CredentialPriority</NodeName>
-        <Value>99</Value>
-      </Node>
-      <Node>
-        <NodeName>AAAServerTrustRoot</NodeName>
-        <Node>
-          <NodeName>a001</NodeName>
-          <Node>
-            <NodeName>CertURL</NodeName>
-            <Value>server1.trust.root.com</Value>
-          </Node>
-          <Node>
-            <NodeName>CertSHA256Fingerprint</NodeName>
-            <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value>
-          </Node>
-        </Node>
-      </Node>
-      <Node>
-        <NodeName>SubscriptionUpdate</NodeName>
-        <Node>
-          <NodeName>UpdateInterval</NodeName>
-          <Value>120</Value>
-        </Node>
-        <Node>
-          <NodeName>UpdateMethod</NodeName>
-          <Value>SSP-ClientInitiated</Value>
-        </Node>
-        <Node>
-          <NodeName>Restriction</NodeName>
-          <Value>RoamingPartner</Value>
-        </Node>
-        <Node>
-          <NodeName>URI</NodeName>
-          <Value>subscription.update.com</Value>
-        </Node>
-        <Node>
-          <NodeName>UsernamePassword</NodeName>
-          <Node>
-            <NodeName>Username</NodeName>
-            <Value>subscriptionUser</Value>
-          </Node>
-          <Node>
-            <NodeName>Password</NodeName>
-            <Value>subscriptionPass</Value>
-          </Node>
-        </Node>
-        <Node>
-          <NodeName>TrustRoot</NodeName>
-          <Node>
-            <NodeName>CertURL</NodeName>
-            <Value>subscription.update.cert.com</Value>
-          </Node>
-          <Node>
-            <NodeName>CertSHA256Fingerprint</NodeName>
-            <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value>
-          </Node>
-        </Node>
-      </Node>
-      <Node>
-        <NodeName>SubscriptionParameters</NodeName>
-        <Node>
-          <NodeName>CreationDate</NodeName>
-          <Value>2016-02-01T10:00:00Z</Value>
-        </Node>
-        <Node>
-          <NodeName>ExpirationDate</NodeName>
-          <Value>2016-03-01T10:00:00Z</Value>
-        </Node>
-        <Node>
-          <NodeName>TypeOfSubscription</NodeName>
-          <Value>Gold</Value>
-        </Node>
-        <Node>
-          <NodeName>UsageLimits</NodeName>
-          <Node>
-            <NodeName>DataLimit</NodeName>
-            <Value>921890</Value>
-          </Node>
-          <Node>
-            <NodeName>StartDate</NodeName>
-            <Value>2016-12-01T10:00:00Z</Value>
-          </Node>
-          <Node>
-            <NodeName>TimeLimit</NodeName>
-            <Value>120</Value>
-          </Node>
-          <Node>
-            <NodeName>UsageTimePeriod</NodeName>
-            <Value>99910</Value>
-          </Node>
-        </Node>
-      </Node>
-    </Node>
-  </Node>
-</MgmtTree>
diff --git a/wifi/tests/assets/pps/PerProviderSubscription_DuplicateHomeSP.xml b/wifi/tests/assets/pps/PerProviderSubscription_DuplicateHomeSP.xml
deleted file mode 100644
index e13eb2a..0000000
--- a/wifi/tests/assets/pps/PerProviderSubscription_DuplicateHomeSP.xml
+++ /dev/null
@@ -1,95 +0,0 @@
-<MgmtTree xmlns="syncml:dmddf1.2">
-  <VerDTD>1.2</VerDTD>
-  <Node>
-    <NodeName>PerProviderSubscription</NodeName>
-    <RTProperties>
-      <Type>
-        <DDFName>urn:wfa:mo:hotspot2dot0-perprovidersubscription:1.0</DDFName>
-      </Type>
-    </RTProperties>
-    <Node>
-      <NodeName>i001</NodeName>
-      <Node>
-        <NodeName>HomeSP</NodeName>
-        <Node>
-          <NodeName>FriendlyName</NodeName>
-          <Value>Century House</Value>
-        </Node>
-        <Node>
-          <NodeName>FQDN</NodeName>
-          <Value>mi6.co.uk</Value>
-        </Node>
-        <Node>
-          <NodeName>RoamingConsortiumOI</NodeName>
-          <Value>112233,445566</Value>
-        </Node>
-      </Node>
-      <Node>
-        <NodeName>HomeSP</NodeName>
-        <Node>
-          <NodeName>FriendlyName</NodeName>
-          <Value>Century House</Value>
-        </Node>
-        <Node>
-          <NodeName>FQDN</NodeName>
-          <Value>mi6.co.uk</Value>
-        </Node>
-        <Node>
-          <NodeName>RoamingConsortiumOI</NodeName>
-          <Value>112233,445566</Value>
-        </Node>
-      </Node>
-      <Node>
-        <NodeName>Credential</NodeName>
-        <Node>
-          <NodeName>Realm</NodeName>
-          <Value>shaken.stirred.com</Value>
-        </Node>
-        <Node>
-          <NodeName>UsernamePassword</NodeName>
-          <Node>
-            <NodeName>Username</NodeName>
-            <Value>james</Value>
-          </Node>
-          <Node>
-            <NodeName>Password</NodeName>
-            <Value>Ym9uZDAwNw==</Value>
-          </Node>
-          <Node>
-            <NodeName>EAPMethod</NodeName>
-            <Node>
-              <NodeName>EAPType</NodeName>
-              <Value>21</Value>
-            </Node>
-            <Node>
-              <NodeName>InnerMethod</NodeName>
-              <Value>MS-CHAP-V2</Value>
-            </Node>
-          </Node>
-        </Node>
-        <Node>
-          <NodeName>DigitalCertificate</NodeName>
-          <Node>
-            <NodeName>CertificateType</NodeName>
-            <Value>x509v3</Value>
-          </Node>
-          <Node>
-            <NodeName>CertSHA256FingerPrint</NodeName>
-            <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value>
-          </Node>
-        </Node>
-        <Node>
-          <NodeName>SIM</NodeName>
-          <Node>
-            <NodeName>IMSI</NodeName>
-            <Value>imsi</Value>
-          </Node>
-          <Node>
-            <NodeName>EAPType</NodeName>
-            <Value>24</Value>
-          </Node>
-        </Node>
-      </Node>
-    </Node>
-  </Node>
-</MgmtTree>
diff --git a/wifi/tests/assets/pps/PerProviderSubscription_DuplicateValue.xml b/wifi/tests/assets/pps/PerProviderSubscription_DuplicateValue.xml
deleted file mode 100644
index 8719ffa..0000000
--- a/wifi/tests/assets/pps/PerProviderSubscription_DuplicateValue.xml
+++ /dev/null
@@ -1,81 +0,0 @@
-<MgmtTree xmlns="syncml:dmddf1.2">
-  <VerDTD>1.2</VerDTD>
-  <Node>
-    <NodeName>PerProviderSubscription</NodeName>
-    <RTProperties>
-      <Type>
-        <DDFName>urn:wfa:mo:hotspot2dot0-perprovidersubscription:1.0</DDFName>
-      </Type>
-    </RTProperties>
-    <Node>
-      <NodeName>i001</NodeName>
-      <Node>
-        <NodeName>HomeSP</NodeName>
-        <Node>
-          <NodeName>FriendlyName</NodeName>
-          <Value>Century House</Value>
-          <Value>Century House</Value>
-        </Node>
-        <Node>
-          <NodeName>FQDN</NodeName>
-          <Value>mi6.co.uk</Value>
-        </Node>
-        <Node>
-          <NodeName>RoamingConsortiumOI</NodeName>
-          <Value>112233,445566</Value>
-        </Node>
-      </Node>
-      <Node>
-        <NodeName>Credential</NodeName>
-        <Node>
-          <NodeName>Realm</NodeName>
-          <Value>shaken.stirred.com</Value>
-        </Node>
-        <Node>
-          <NodeName>UsernamePassword</NodeName>
-          <Node>
-            <NodeName>Username</NodeName>
-            <Value>james</Value>
-          </Node>
-          <Node>
-            <NodeName>Password</NodeName>
-            <Value>Ym9uZDAwNw==</Value>
-          </Node>
-          <Node>
-            <NodeName>EAPMethod</NodeName>
-            <Node>
-              <NodeName>EAPType</NodeName>
-              <Value>21</Value>
-            </Node>
-            <Node>
-              <NodeName>InnerMethod</NodeName>
-              <Value>MS-CHAP-V2</Value>
-            </Node>
-          </Node>
-        </Node>
-        <Node>
-          <NodeName>DigitalCertificate</NodeName>
-          <Node>
-            <NodeName>CertificateType</NodeName>
-            <Value>x509v3</Value>
-          </Node>
-          <Node>
-            <NodeName>CertSHA256FingerPrint</NodeName>
-            <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value>
-          </Node>
-        </Node>
-        <Node>
-          <NodeName>SIM</NodeName>
-          <Node>
-            <NodeName>IMSI</NodeName>
-            <Value>imsi</Value>
-          </Node>
-          <Node>
-            <NodeName>EAPType</NodeName>
-            <Value>24</Value>
-          </Node>
-        </Node>
-      </Node>
-    </Node>
-  </Node>
-</MgmtTree>
diff --git a/wifi/tests/assets/pps/PerProviderSubscription_InvalidName.xml b/wifi/tests/assets/pps/PerProviderSubscription_InvalidName.xml
deleted file mode 100644
index c761237..0000000
--- a/wifi/tests/assets/pps/PerProviderSubscription_InvalidName.xml
+++ /dev/null
@@ -1,80 +0,0 @@
-<MgmtTree xmlns="syncml:dmddf1.2">
-  <VerDTD>1.2</VerDTD>
-  <Node>
-    <NodeName>PerProviderSubscription</NodeName>
-    <RTProperties>
-      <Type>
-        <DDFName>urn:wfa:mo:hotspot2dot0-perprovidersubscription:1.0</DDFName>
-      </Type>
-    </RTProperties>
-    <Node>
-      <NodeName>i001</NodeName>
-      <Node>
-        <NodeName>HomeSP</NodeName>
-        <Node>
-          <NodeName>FriendName</NodeName>
-          <Value>Century House</Value>
-        </Node>
-        <Node>
-          <NodeName>FQDN</NodeName>
-          <Value>mi6.co.uk</Value>
-        </Node>
-        <Node>
-          <NodeName>RoamingConsortiumOI</NodeName>
-          <Value>112233,445566</Value>
-        </Node>
-      </Node>
-      <Node>
-        <NodeName>Credential</NodeName>
-        <Node>
-          <NodeName>Realm</NodeName>
-          <Value>shaken.stirred.com</Value>
-        </Node>
-        <Node>
-          <NodeName>UsernamePassword</NodeName>
-          <Node>
-            <NodeName>Username</NodeName>
-            <Value>james</Value>
-          </Node>
-          <Node>
-            <NodeName>Password</NodeName>
-            <Value>Ym9uZDAwNw==</Value>
-          </Node>
-          <Node>
-            <NodeName>EAPMethod</NodeName>
-            <Node>
-              <NodeName>EAPType</NodeName>
-              <Value>21</Value>
-            </Node>
-            <Node>
-              <NodeName>InnerMethod</NodeName>
-              <Value>MS-CHAP-V2</Value>
-            </Node>
-          </Node>
-        </Node>
-        <Node>
-          <NodeName>DigitalCertificate</NodeName>
-          <Node>
-            <NodeName>CertificateType</NodeName>
-            <Value>x509v3</Value>
-          </Node>
-          <Node>
-            <NodeName>CertSHA256FingerPrint</NodeName>
-            <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value>
-          </Node>
-        </Node>
-        <Node>
-          <NodeName>SIM</NodeName>
-          <Node>
-            <NodeName>IMSI</NodeName>
-            <Value>imsi</Value>
-          </Node>
-          <Node>
-            <NodeName>EAPType</NodeName>
-            <Value>24</Value>
-          </Node>
-        </Node>
-      </Node>
-    </Node>
-  </Node>
-</MgmtTree>
diff --git a/wifi/tests/assets/pps/PerProviderSubscription_InvalidNode.xml b/wifi/tests/assets/pps/PerProviderSubscription_InvalidNode.xml
deleted file mode 100644
index 6b807af..0000000
--- a/wifi/tests/assets/pps/PerProviderSubscription_InvalidNode.xml
+++ /dev/null
@@ -1,84 +0,0 @@
-<MgmtTree xmlns="syncml:dmddf1.2">
-  <VerDTD>1.2</VerDTD>
-  <Node>
-    <NodeName>PerProviderSubscription</NodeName>
-    <RTProperties>
-      <Type>
-        <DDFName>urn:wfa:mo:hotspot2dot0-perprovidersubscription:1.0</DDFName>
-      </Type>
-    </RTProperties>
-    <Node>
-      <NodeName>i001</NodeName>
-      <Node>
-        <NodeName>HomeSP</NodeName>
-        <Node>
-          <NodeName>FriendlyName</NodeName>
-          <Value>Century House</Value>
-        </Node>
-        <Node>
-          <NodeName>FQDN</NodeName>
-          <Value>mi6.co.uk</Value>
-          <Node>
-            <NodeName>InvalidNode</NodeName>
-            <Value>Test</Value>
-          </Node>
-        </Node>
-        <Node>
-          <NodeName>RoamingConsortiumOI</NodeName>
-          <Value>112233,445566</Value>
-        </Node>
-      </Node>
-      <Node>
-        <NodeName>Credential</NodeName>
-        <Node>
-          <NodeName>Realm</NodeName>
-          <Value>shaken.stirred.com</Value>
-        </Node>
-        <Node>
-          <NodeName>UsernamePassword</NodeName>
-          <Node>
-            <NodeName>Username</NodeName>
-            <Value>james</Value>
-          </Node>
-          <Node>
-            <NodeName>Password</NodeName>
-            <Value>Ym9uZDAwNw==</Value>
-          </Node>
-          <Node>
-            <NodeName>EAPMethod</NodeName>
-            <Node>
-              <NodeName>EAPType</NodeName>
-              <Value>21</Value>
-            </Node>
-            <Node>
-              <NodeName>InnerMethod</NodeName>
-              <Value>MS-CHAP-V2</Value>
-            </Node>
-          </Node>
-        </Node>
-        <Node>
-          <NodeName>DigitalCertificate</NodeName>
-          <Node>
-            <NodeName>CertificateType</NodeName>
-            <Value>x509v3</Value>
-          </Node>
-          <Node>
-            <NodeName>CertSHA256FingerPrint</NodeName>
-            <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value>
-          </Node>
-        </Node>
-        <Node>
-          <NodeName>SIM</NodeName>
-          <Node>
-            <NodeName>IMSI</NodeName>
-            <Value>imsi</Value>
-          </Node>
-          <Node>
-            <NodeName>EAPType</NodeName>
-            <Value>24</Value>
-          </Node>
-        </Node>
-      </Node>
-    </Node>
-  </Node>
-</MgmtTree>
diff --git a/wifi/tests/assets/pps/PerProviderSubscription_MissingName.xml b/wifi/tests/assets/pps/PerProviderSubscription_MissingName.xml
deleted file mode 100644
index ed06b47..0000000
--- a/wifi/tests/assets/pps/PerProviderSubscription_MissingName.xml
+++ /dev/null
@@ -1,79 +0,0 @@
-<MgmtTree xmlns="syncml:dmddf1.2">
-  <VerDTD>1.2</VerDTD>
-  <Node>
-    <NodeName>PerProviderSubscription</NodeName>
-    <RTProperties>
-      <Type>
-        <DDFName>urn:wfa:mo:hotspot2dot0-perprovidersubscription:1.0</DDFName>
-      </Type>
-    </RTProperties>
-    <Node>
-      <NodeName>i001</NodeName>
-      <Node>
-        <Node>
-          <NodeName>FriendlyName</NodeName>
-          <Value>Century House</Value>
-        </Node>
-        <Node>
-          <NodeName>FQDN</NodeName>
-          <Value>mi6.co.uk</Value>
-        </Node>
-        <Node>
-          <NodeName>RoamingConsortiumOI</NodeName>
-          <Value>112233,445566</Value>
-        </Node>
-      </Node>
-      <Node>
-        <NodeName>Credential</NodeName>
-        <Node>
-          <NodeName>Realm</NodeName>
-          <Value>shaken.stirred.com</Value>
-        </Node>
-        <Node>
-          <NodeName>UsernamePassword</NodeName>
-          <Node>
-            <NodeName>Username</NodeName>
-            <Value>james</Value>
-          </Node>
-          <Node>
-            <NodeName>Password</NodeName>
-            <Value>Ym9uZDAwNw==</Value>
-          </Node>
-          <Node>
-            <NodeName>EAPMethod</NodeName>
-            <Node>
-              <NodeName>EAPType</NodeName>
-              <Value>21</Value>
-            </Node>
-            <Node>
-              <NodeName>InnerMethod</NodeName>
-              <Value>MS-CHAP-V2</Value>
-            </Node>
-          </Node>
-        </Node>
-        <Node>
-          <NodeName>DigitalCertificate</NodeName>
-          <Node>
-            <NodeName>CertificateType</NodeName>
-            <Value>x509v3</Value>
-          </Node>
-          <Node>
-            <NodeName>CertSHA256FingerPrint</NodeName>
-            <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value>
-          </Node>
-        </Node>
-        <Node>
-          <NodeName>SIM</NodeName>
-          <Node>
-            <NodeName>IMSI</NodeName>
-            <Value>imsi</Value>
-          </Node>
-          <Node>
-            <NodeName>EAPType</NodeName>
-            <Value>24</Value>
-          </Node>
-        </Node>
-      </Node>
-    </Node>
-  </Node>
-</MgmtTree>
diff --git a/wifi/tests/assets/pps/PerProviderSubscription_MissingValue.xml b/wifi/tests/assets/pps/PerProviderSubscription_MissingValue.xml
deleted file mode 100644
index f7e35dd..0000000
--- a/wifi/tests/assets/pps/PerProviderSubscription_MissingValue.xml
+++ /dev/null
@@ -1,79 +0,0 @@
-<MgmtTree xmlns="syncml:dmddf1.2">
-  <VerDTD>1.2</VerDTD>
-  <Node>
-    <NodeName>PerProviderSubscription</NodeName>
-    <RTProperties>
-      <Type>
-        <DDFName>urn:wfa:mo:hotspot2dot0-perprovidersubscription:1.0</DDFName>
-      </Type>
-    </RTProperties>
-    <Node>
-      <NodeName>i001</NodeName>
-      <Node>
-        <NodeName>HomeSP</NodeName>
-        <Node>
-          <NodeName>FriendlyName</NodeName>
-        </Node>
-        <Node>
-          <NodeName>FQDN</NodeName>
-          <Value>mi6.co.uk</Value>
-        </Node>
-        <Node>
-          <NodeName>RoamingConsortiumOI</NodeName>
-          <Value>112233,445566</Value>
-        </Node>
-      </Node>
-      <Node>
-        <NodeName>Credential</NodeName>
-        <Node>
-          <NodeName>Realm</NodeName>
-          <Value>shaken.stirred.com</Value>
-        </Node>
-        <Node>
-          <NodeName>UsernamePassword</NodeName>
-          <Node>
-            <NodeName>Username</NodeName>
-            <Value>james</Value>
-          </Node>
-          <Node>
-            <NodeName>Password</NodeName>
-            <Value>Ym9uZDAwNw==</Value>
-          </Node>
-          <Node>
-            <NodeName>EAPMethod</NodeName>
-            <Node>
-              <NodeName>EAPType</NodeName>
-              <Value>21</Value>
-            </Node>
-            <Node>
-              <NodeName>InnerMethod</NodeName>
-              <Value>MS-CHAP-V2</Value>
-            </Node>
-          </Node>
-        </Node>
-        <Node>
-          <NodeName>DigitalCertificate</NodeName>
-          <Node>
-            <NodeName>CertificateType</NodeName>
-            <Value>x509v3</Value>
-          </Node>
-          <Node>
-            <NodeName>CertSHA256FingerPrint</NodeName>
-            <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value>
-          </Node>
-        </Node>
-        <Node>
-          <NodeName>SIM</NodeName>
-          <Node>
-            <NodeName>IMSI</NodeName>
-            <Value>imsi</Value>
-          </Node>
-          <Node>
-            <NodeName>EAPType</NodeName>
-            <Value>24</Value>
-          </Node>
-        </Node>
-      </Node>
-    </Node>
-  </Node>
-</MgmtTree>
diff --git a/wifi/tests/assets/pps/README.txt b/wifi/tests/assets/pps/README.txt
deleted file mode 100644
index 369c0a9..0000000
--- a/wifi/tests/assets/pps/README.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-PerProviderSubscription.xml - valid PPS XML file
-PerProviderSubscription_DuplicateHomeSP.xml - containing multiple HomeSP node
-PerProviderSubscription_DuplicateValue.xml - FriendlyName node contains multiple Value
-PerProviderSubscription_MissingValue.xml - FriendlyName node is missing Value
-PerProviderSubscription_MissingName.xml - HomeSP node is missing NodeName
-PerProviderSubscription_InvalidNode.xml - FQDN node contains both Value and a child node
-PerProviderSubscription_InvalidName.xml - FriendlyName node have a typo in its name
diff --git a/wifi/tests/src/android/net/wifi/EasyConnectStatusCallbackTest.java b/wifi/tests/src/android/net/wifi/EasyConnectStatusCallbackTest.java
deleted file mode 100644
index b101414..0000000
--- a/wifi/tests/src/android/net/wifi/EasyConnectStatusCallbackTest.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import android.util.SparseArray;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Unit tests for {@link android.net.wifi.EasyConnectStatusCallbackTest}.
- */
-@SmallTest
-public class EasyConnectStatusCallbackTest {
-    private EasyConnectStatusCallback mEasyConnectStatusCallback = new EasyConnectStatusCallback() {
-        @Override
-        public void onEnrolleeSuccess(int newNetworkId) {
-
-        }
-
-        @Override
-        public void onConfiguratorSuccess(int code) {
-
-        }
-
-        @Override
-        public void onProgress(int code) {
-
-        }
-
-        @Override
-        public void onFailure(int code) {
-            mOnFailureR1EventReceived = true;
-            mLastCode = code;
-        }
-    };
-    private boolean mOnFailureR1EventReceived;
-    private int mLastCode;
-
-    @Before
-    public void setUp() {
-        mOnFailureR1EventReceived = false;
-        mLastCode = 0;
-    }
-
-    /**
-     * Test that the legacy R1 onFailure is called by default if the R2 onFailure is not overridden
-     * by the app.
-     */
-    @Test
-    public void testR1OnFailureCalled() {
-
-        SparseArray<int[]> channelList = new SparseArray<>();
-        int[] channelArray = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
-
-        channelList.append(81, channelArray);
-        mEasyConnectStatusCallback.onFailure(
-                EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_CANNOT_FIND_NETWORK,
-                "SomeSSID", channelList, new int[] {81});
-
-        assertTrue(mOnFailureR1EventReceived);
-        assertEquals(mLastCode,
-                EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_CANNOT_FIND_NETWORK);
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/FakeKeys.java b/wifi/tests/src/android/net/wifi/FakeKeys.java
deleted file mode 100644
index 8aa6add..0000000
--- a/wifi/tests/src/android/net/wifi/FakeKeys.java
+++ /dev/null
@@ -1,673 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package android.net.wifi;
-
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.nio.charset.StandardCharsets;
-import java.security.KeyFactory;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.PKCS8EncodedKeySpec;
-
-/**
- * A class containing test certificates and private keys.
- */
-public class FakeKeys {
-    private static final String CA_CERT0_STRING = "-----BEGIN CERTIFICATE-----\n" +
-            "MIIDKDCCAhCgAwIBAgIJAILlFdwzLVurMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNV\n" +
-            "BAMTB0VBUCBDQTEwHhcNMTYwMTEyMTE1MDE1WhcNMjYwMTA5MTE1MDE1WjASMRAw\n" +
-            "DgYDVQQDEwdFQVAgQ0ExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA\n" +
-            "znAPUz26Msae4ws43czR41/J2QtrSIZUKmVUsVumDbYHrPNvTXKSMXAcewORDQYX\n" +
-            "RqvHvpn8CscB1+oGXZvHwxj4zV0WKoK2zeXkau3vcyl3HIKupJfq2TEACefVjj0t\n" +
-            "JW+X35PGWp9/H5zIUNVNVjS7Ums84IvKhRB8512PB9UyHagXYVX5GWpAcVpyfrlR\n" +
-            "FI9Qdhh+Pbk0uyktdbf/CdfgHOoebrTtwRljM0oDtX+2Cv6j0wBK7hD8pPvf1+uy\n" +
-            "GzczigAU/4Kw7eZqydf9B+5RupR+IZipX41xEiIrKRwqi517WWzXcjaG2cNbf451\n" +
-            "xpH5PnV3i1tq04jMGQUzFwIDAQABo4GAMH4wHQYDVR0OBBYEFIwX4vs8BiBcScod\n" +
-            "5noZHRM8E4+iMEIGA1UdIwQ7MDmAFIwX4vs8BiBcScod5noZHRM8E4+ioRakFDAS\n" +
-            "MRAwDgYDVQQDEwdFQVAgQ0ExggkAguUV3DMtW6swDAYDVR0TBAUwAwEB/zALBgNV\n" +
-            "HQ8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAFfQqOTA7Rv7K+luQ7pnas4BYwHE\n" +
-            "9GEP/uohv6KOy0TGQFbrRTjFoLVNB9BZ1ymMDZ0/TIwIUc7wi7a8t5mEqYH153wW\n" +
-            "aWooiSjyLLhuI4sNrNCOtisdBq2r2MFXt6h0mAQYOPv8R8K7/fgSxGFqzhyNmmVL\n" +
-            "1qBJldx34SpwsTALQVPb4hGwJzZfr1PcpEQx6xMnTl8xEWZE3Ms99uaUxbQqIwRu\n" +
-            "LgAOkNCmY2m89VhzaHJ1uV85AdM/tD+Ysmlnnjt9LRCejbBipjIGjOXrg1JP+lxV\n" +
-            "muM4vH+P/mlmxsPPz0d65b+EGmJZpoLkO/tdNNvCYzjJpTEWpEsO6NMhKYo=\n" +
-            "-----END CERTIFICATE-----\n";
-    public static final X509Certificate CA_CERT0 = loadCertificate(CA_CERT0_STRING);
-
-    private static final String CA_CERT1_STRING = "-----BEGIN CERTIFICATE-----\n" +
-            "MIIDKDCCAhCgAwIBAgIJAOM5SzKO2pzCMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNV\n" +
-            "BAMTB0VBUCBDQTAwHhcNMTYwMTEyMDAxMDQ3WhcNMjYwMTA5MDAxMDQ3WjASMRAw\n" +
-            "DgYDVQQDEwdFQVAgQ0EwMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA\n" +
-            "89ug+IEKVQXnJGKg5g4uVHg6J/8iRUxR5k2eH5o03hrJNMfN2D+cBe/wCiZcnWbI\n" +
-            "GbGZACWm2nQth2wy9Zgm2LOd3b4ocrHYls3XLq6Qb5Dd7a0JKU7pdGufiNVEkrmF\n" +
-            "EB+N64wgwH4COTvCiN4erp5kyJwkfqAl2xLkZo0C464c9XoyQOXbmYD9A8v10wZu\n" +
-            "jyNsEo7Nr2USyw+qhjWSbFbEirP77Tvx+7pJQJwdtk1V9Tn73T2dGF2WHYejei9S\n" +
-            "mcWpdIUqsu9etYH+zDmtu7I1xlkwiaVsNr2+D+qaCJyOYqrDTKVNK5nmbBPXDWZc\n" +
-            "NoDbTOoqquX7xONpq9M6jQIDAQABo4GAMH4wHQYDVR0OBBYEFAZ3A2S4qJZZwuNY\n" +
-            "wkJ6mAdc0gVdMEIGA1UdIwQ7MDmAFAZ3A2S4qJZZwuNYwkJ6mAdc0gVdoRakFDAS\n" +
-            "MRAwDgYDVQQDEwdFQVAgQ0EwggkA4zlLMo7anMIwDAYDVR0TBAUwAwEB/zALBgNV\n" +
-            "HQ8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAHmdMwEhtys4d0E+t7owBmoVR+lU\n" +
-            "hMCcRtWs8YKX5WIM2kTweT0h/O1xwE1mWmRv/IbDAEb8od4BjAQLhIcolStr2JaO\n" +
-            "9ZzyxjOnNzqeErh/1DHDbb/moPpqfeJ8YiEz7nH/YU56Q8iCPO7TsgS0sNNE7PfN\n" +
-            "IUsBW0yHRgpQ4OxWmiZG2YZWiECRzAC0ecPzo59N5iH4vLQIMTMYquiDeMPQnn1e\n" +
-            "NDGxG8gCtDKIaS6tMg3a28MvWB094pr2ETou8O1C8Ji0Y4hE8QJmSdT7I4+GZjgW\n" +
-            "g94DZ5RiL7sdp3vC48CXOmeT61YBIvhGUsE1rPhXqkpqQ3Z3C4TFF0jXZZc=\n" +
-            "-----END CERTIFICATE-----\n";
-    public static final X509Certificate CA_CERT1 = loadCertificate(CA_CERT1_STRING);
-
-    private static final String CLIENT_CERT_STR = "-----BEGIN CERTIFICATE-----\n" +
-            "MIIE/DCCAuQCAQEwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UEBhMCVVMxCzAJBgNV\n" +
-            "BAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdUZXN0aW5n\n" +
-            "MB4XDTE2MDkzMDIwNTQyOFoXDTE3MDkzMDIwNTQyOFowRDELMAkGA1UEBhMCVVMx\n" +
-            "CzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdU\n" +
-            "ZXN0aW5nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAnpmcbuaeHfnJ\n" +
-            "k+2QNvxmdVFTawyFMNk0USCq5sexscwmxbewG/Rb8YnixwJWS44v2XkSujB67z5C\n" +
-            "s2qudFEhRXKdEuC6idbAuA97KjipHh0AAniWMsyv61fvbgsUC0b0canx3LiDq81p\n" +
-            "y28NNGmAvoazLZUZ4AhBRiwYZY6FKk723gmZoGbEIeG7J1dlXPusc1662rIjz4eU\n" +
-            "zlmmlvqyHfNqnNk8L14Vug6Xh+lOEGN85xhu1YHAEKGrS89kZxs5rum/cZU8KH2V\n" +
-            "v6eKnY03kxjiVLQtnLpm/7VUEoCMGHyruRj+p3my4+DgqMsmsH52RZCBsjyGlpbU\n" +
-            "NOwOTIX6xh+Rqloduz4AnrMYYIiIw2s8g+2zJM7VbcVKx0fGS26BKdrxgrXWfmNE\n" +
-            "nR0/REQ5AxDGw0jfTUvtdTkXAf+K4MDjcNLEZ+MA4rHfAfQWZtUR5BkHCQYxNpJk\n" +
-            "pA0gyk+BpKdC4WdzI14NSWsu5sRCmBCFqH6BTOSEq/V1cNorBxNwLSSTwFFqUDqx\n" +
-            "Y5nQLXygkJf9WHZWtSKeSjtOYgilz7UKzC2s3CsjmIyGFe+SwpuHJnuE4Uc8Z5Cb\n" +
-            "bjNGHPzqL6XnmzZHJp7RF8kBdKdjGC7dCUltzOfICZeKlzOOq+Kw42T/nXjuXvpb\n" +
-            "nkXNxg741Nwd6RecykXJbseFwm3EYxkCAwEAATANBgkqhkiG9w0BAQsFAAOCAgEA\n" +
-            "Ga1mGwI9aXkL2fTPXO9YkAPzoGeX8aeuVYSQaSkNq+5vnogYCyAt3YDHjRG+ewTT\n" +
-            "WbnPA991xRAPac+biJeXWmwvgGj0YuT7e79phAiGkTTnbAjFHGfYnBy/tI/v7btO\n" +
-            "hRNElA5yTJ1m2fVbBEKXzMR83jrT9iyI+YLRN86zUZIaC86xxSbqnrdWN2jOK6MX\n" +
-            "dS8Arp9tPQjC/4gW+2Ilxv68jiYh+5auWHQZVjppWVY//iu4mAbkq1pTwQEhZ8F8\n" +
-            "Zrmh9DHh60hLFcfSuhIAwf/NMzppwdkjy1ruKVrpijhGKGp4OWu8nvOUgHSzxc7F\n" +
-            "PwpVZ5N2Ku4L8MLO6BG2VasRJK7l17TzDXlfLZHJjkuryOFxVaQKt8ZNFgTOaCXS\n" +
-            "E+gpTLksKU7riYckoiP4+H1sn9qcis0e8s4o/uf1UVc8GSdDw61ReGM5oZEDm1u8\n" +
-            "H9x20QU6igLqzyBpqvCKv7JNgU1uB2PAODHH78zJiUfnKd1y+o+J1iWzaGj3EFji\n" +
-            "T8AXksbTP733FeFXfggXju2dyBH+Z1S5BBTEOd1brWgXlHSAZGm97MKZ94r6/tkX\n" +
-            "qfv3fCos0DKz0oV7qBxYS8wiYhzrRVxG6ITAoH8uuUVVQaZF+G4nJ2jEqNbfuKyX\n" +
-            "ATQsVNjNNlDA0J33GobPMjT326wa4YAWMx8PI5PJZ3g=\n" +
-            "-----END CERTIFICATE-----\n";
-    public static final X509Certificate CLIENT_CERT = loadCertificate(CLIENT_CERT_STR);
-
-    private static final byte[] FAKE_RSA_KEY_1 = new byte[] {
-            (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x78, (byte) 0x02, (byte) 0x01,
-            (byte) 0x00, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a,
-            (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01,
-            (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x04, (byte) 0x82,
-            (byte) 0x02, (byte) 0x62, (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x5e,
-            (byte) 0x02, (byte) 0x01, (byte) 0x00, (byte) 0x02, (byte) 0x81, (byte) 0x81,
-            (byte) 0x00, (byte) 0xce, (byte) 0x29, (byte) 0xeb, (byte) 0xf6, (byte) 0x5b,
-            (byte) 0x25, (byte) 0xdc, (byte) 0xa1, (byte) 0xa6, (byte) 0x2c, (byte) 0x66,
-            (byte) 0xcb, (byte) 0x20, (byte) 0x90, (byte) 0x27, (byte) 0x86, (byte) 0x8a,
-            (byte) 0x44, (byte) 0x71, (byte) 0x50, (byte) 0xda, (byte) 0xd3, (byte) 0x02,
-            (byte) 0x77, (byte) 0x55, (byte) 0xe9, (byte) 0xe8, (byte) 0x08, (byte) 0xf3,
-            (byte) 0x36, (byte) 0x9a, (byte) 0xae, (byte) 0xab, (byte) 0x04, (byte) 0x6d,
-            (byte) 0x00, (byte) 0x99, (byte) 0xbf, (byte) 0x7d, (byte) 0x0f, (byte) 0x67,
-            (byte) 0x8b, (byte) 0x1d, (byte) 0xd4, (byte) 0x2b, (byte) 0x7c, (byte) 0xcb,
-            (byte) 0xcd, (byte) 0x33, (byte) 0xc7, (byte) 0x84, (byte) 0x30, (byte) 0xe2,
-            (byte) 0x45, (byte) 0x21, (byte) 0xb3, (byte) 0x75, (byte) 0xf5, (byte) 0x79,
-            (byte) 0x02, (byte) 0xda, (byte) 0x50, (byte) 0xa3, (byte) 0x8b, (byte) 0xce,
-            (byte) 0xc3, (byte) 0x8e, (byte) 0x0f, (byte) 0x25, (byte) 0xeb, (byte) 0x08,
-            (byte) 0x2c, (byte) 0xdd, (byte) 0x1c, (byte) 0xcf, (byte) 0xff, (byte) 0x3b,
-            (byte) 0xde, (byte) 0xb6, (byte) 0xaa, (byte) 0x2a, (byte) 0xa9, (byte) 0xc4,
-            (byte) 0x8a, (byte) 0x24, (byte) 0x24, (byte) 0xe6, (byte) 0x29, (byte) 0x0d,
-            (byte) 0x98, (byte) 0x4c, (byte) 0x32, (byte) 0xa1, (byte) 0x7b, (byte) 0x23,
-            (byte) 0x2b, (byte) 0x42, (byte) 0x30, (byte) 0xee, (byte) 0x78, (byte) 0x08,
-            (byte) 0x47, (byte) 0xad, (byte) 0xf2, (byte) 0x96, (byte) 0xd5, (byte) 0xf1,
-            (byte) 0x62, (byte) 0x42, (byte) 0x2d, (byte) 0x35, (byte) 0x19, (byte) 0xb4,
-            (byte) 0x3c, (byte) 0xc9, (byte) 0xc3, (byte) 0x5f, (byte) 0x03, (byte) 0x16,
-            (byte) 0x3a, (byte) 0x23, (byte) 0xac, (byte) 0xcb, (byte) 0xce, (byte) 0x9e,
-            (byte) 0x51, (byte) 0x2e, (byte) 0x6d, (byte) 0x02, (byte) 0x03, (byte) 0x01,
-            (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x81, (byte) 0x80, (byte) 0x16,
-            (byte) 0x59, (byte) 0xc3, (byte) 0x24, (byte) 0x1d, (byte) 0x33, (byte) 0x98,
-            (byte) 0x9c, (byte) 0xc9, (byte) 0xc8, (byte) 0x2c, (byte) 0x88, (byte) 0xbf,
-            (byte) 0x0a, (byte) 0x01, (byte) 0xce, (byte) 0xfb, (byte) 0x34, (byte) 0x7a,
-            (byte) 0x58, (byte) 0x7a, (byte) 0xb0, (byte) 0xbf, (byte) 0xa6, (byte) 0xb2,
-            (byte) 0x60, (byte) 0xbe, (byte) 0x70, (byte) 0x21, (byte) 0xf5, (byte) 0xfc,
-            (byte) 0x85, (byte) 0x0d, (byte) 0x33, (byte) 0x58, (byte) 0xa1, (byte) 0xe5,
-            (byte) 0x09, (byte) 0x36, (byte) 0x84, (byte) 0xb2, (byte) 0x04, (byte) 0x0a,
-            (byte) 0x02, (byte) 0xd3, (byte) 0x88, (byte) 0x1f, (byte) 0x0c, (byte) 0x2b,
-            (byte) 0x1d, (byte) 0xe9, (byte) 0x3d, (byte) 0xe7, (byte) 0x79, (byte) 0xf9,
-            (byte) 0x32, (byte) 0x5c, (byte) 0x8a, (byte) 0x75, (byte) 0x49, (byte) 0x12,
-            (byte) 0xe4, (byte) 0x05, (byte) 0x26, (byte) 0xd4, (byte) 0x2e, (byte) 0x9e,
-            (byte) 0x1f, (byte) 0xcc, (byte) 0x54, (byte) 0xad, (byte) 0x33, (byte) 0x8d,
-            (byte) 0x99, (byte) 0x00, (byte) 0xdc, (byte) 0xf5, (byte) 0xb4, (byte) 0xa2,
-            (byte) 0x2f, (byte) 0xba, (byte) 0xe5, (byte) 0x62, (byte) 0x30, (byte) 0x6d,
-            (byte) 0xe6, (byte) 0x3d, (byte) 0xeb, (byte) 0x24, (byte) 0xc2, (byte) 0xdc,
-            (byte) 0x5f, (byte) 0xb7, (byte) 0x16, (byte) 0x35, (byte) 0xa3, (byte) 0x98,
-            (byte) 0x98, (byte) 0xa8, (byte) 0xef, (byte) 0xe8, (byte) 0xc4, (byte) 0x96,
-            (byte) 0x6d, (byte) 0x38, (byte) 0xab, (byte) 0x26, (byte) 0x6d, (byte) 0x30,
-            (byte) 0xc2, (byte) 0xa0, (byte) 0x44, (byte) 0xe4, (byte) 0xff, (byte) 0x7e,
-            (byte) 0xbe, (byte) 0x7c, (byte) 0x33, (byte) 0xa5, (byte) 0x10, (byte) 0xad,
-            (byte) 0xd7, (byte) 0x1e, (byte) 0x13, (byte) 0x20, (byte) 0xb3, (byte) 0x1f,
-            (byte) 0x41, (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xf1, (byte) 0x89,
-            (byte) 0x07, (byte) 0x0f, (byte) 0xe8, (byte) 0xcf, (byte) 0xab, (byte) 0x13,
-            (byte) 0x2a, (byte) 0x8f, (byte) 0x88, (byte) 0x80, (byte) 0x11, (byte) 0x9a,
-            (byte) 0x79, (byte) 0xb6, (byte) 0x59, (byte) 0x3a, (byte) 0x50, (byte) 0x6e,
-            (byte) 0x57, (byte) 0x37, (byte) 0xab, (byte) 0x2a, (byte) 0xd2, (byte) 0xaa,
-            (byte) 0xd9, (byte) 0x72, (byte) 0x73, (byte) 0xff, (byte) 0x8b, (byte) 0x47,
-            (byte) 0x76, (byte) 0xdd, (byte) 0xdc, (byte) 0xf5, (byte) 0x97, (byte) 0x44,
-            (byte) 0x3a, (byte) 0x78, (byte) 0xbe, (byte) 0x17, (byte) 0xb4, (byte) 0x22,
-            (byte) 0x6f, (byte) 0xe5, (byte) 0x23, (byte) 0x70, (byte) 0x1d, (byte) 0x10,
-            (byte) 0x5d, (byte) 0xba, (byte) 0x16, (byte) 0x81, (byte) 0xf1, (byte) 0x45,
-            (byte) 0xce, (byte) 0x30, (byte) 0xb4, (byte) 0xab, (byte) 0x80, (byte) 0xe4,
-            (byte) 0x98, (byte) 0x31, (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xda,
-            (byte) 0x82, (byte) 0x9d, (byte) 0x3f, (byte) 0xca, (byte) 0x2f, (byte) 0xe1,
-            (byte) 0xd4, (byte) 0x86, (byte) 0x77, (byte) 0x48, (byte) 0xa6, (byte) 0xab,
-            (byte) 0xab, (byte) 0x1c, (byte) 0x42, (byte) 0x5c, (byte) 0xd5, (byte) 0xc7,
-            (byte) 0x46, (byte) 0x59, (byte) 0x91, (byte) 0x3f, (byte) 0xfc, (byte) 0xcc,
-            (byte) 0xec, (byte) 0xc2, (byte) 0x40, (byte) 0x12, (byte) 0x2c, (byte) 0x8d,
-            (byte) 0x1f, (byte) 0xa2, (byte) 0x18, (byte) 0x88, (byte) 0xee, (byte) 0x82,
-            (byte) 0x4a, (byte) 0x5a, (byte) 0x5e, (byte) 0x88, (byte) 0x20, (byte) 0xe3,
-            (byte) 0x7b, (byte) 0xe0, (byte) 0xd8, (byte) 0x3a, (byte) 0x52, (byte) 0x9a,
-            (byte) 0x26, (byte) 0x6a, (byte) 0x04, (byte) 0xec, (byte) 0xe8, (byte) 0xb9,
-            (byte) 0x48, (byte) 0x40, (byte) 0xe1, (byte) 0xe1, (byte) 0x83, (byte) 0xa6,
-            (byte) 0x67, (byte) 0xa6, (byte) 0xfd, (byte) 0x02, (byte) 0x41, (byte) 0x00,
-            (byte) 0x89, (byte) 0x72, (byte) 0x3e, (byte) 0xb0, (byte) 0x90, (byte) 0xfd,
-            (byte) 0x4c, (byte) 0x0e, (byte) 0xd6, (byte) 0x13, (byte) 0x63, (byte) 0xcb,
-            (byte) 0xed, (byte) 0x38, (byte) 0x88, (byte) 0xb6, (byte) 0x79, (byte) 0xc4,
-            (byte) 0x33, (byte) 0x6c, (byte) 0xf6, (byte) 0xf8, (byte) 0xd8, (byte) 0xd0,
-            (byte) 0xbf, (byte) 0x9d, (byte) 0x35, (byte) 0xac, (byte) 0x69, (byte) 0xd2,
-            (byte) 0x2b, (byte) 0xc1, (byte) 0xf9, (byte) 0x24, (byte) 0x7b, (byte) 0xce,
-            (byte) 0xcd, (byte) 0xcb, (byte) 0xa7, (byte) 0xb2, (byte) 0x7a, (byte) 0x0a,
-            (byte) 0x27, (byte) 0x19, (byte) 0xc9, (byte) 0xaf, (byte) 0x0d, (byte) 0x21,
-            (byte) 0x89, (byte) 0x88, (byte) 0x7c, (byte) 0xad, (byte) 0x9e, (byte) 0x8d,
-            (byte) 0x47, (byte) 0x6d, (byte) 0x3f, (byte) 0xce, (byte) 0x7b, (byte) 0xa1,
-            (byte) 0x74, (byte) 0xf1, (byte) 0xa0, (byte) 0xa1, (byte) 0x02, (byte) 0x41,
-            (byte) 0x00, (byte) 0xd9, (byte) 0xa8, (byte) 0xf5, (byte) 0xfe, (byte) 0xce,
-            (byte) 0xe6, (byte) 0x77, (byte) 0x6b, (byte) 0xfe, (byte) 0x2d, (byte) 0xe0,
-            (byte) 0x1e, (byte) 0xb6, (byte) 0x2e, (byte) 0x12, (byte) 0x4e, (byte) 0x40,
-            (byte) 0xaf, (byte) 0x6a, (byte) 0x7b, (byte) 0x37, (byte) 0x49, (byte) 0x2a,
-            (byte) 0x96, (byte) 0x25, (byte) 0x83, (byte) 0x49, (byte) 0xd4, (byte) 0x0c,
-            (byte) 0xc6, (byte) 0x78, (byte) 0x25, (byte) 0x24, (byte) 0x90, (byte) 0x90,
-            (byte) 0x06, (byte) 0x15, (byte) 0x9e, (byte) 0xfe, (byte) 0xf9, (byte) 0xdf,
-            (byte) 0x5b, (byte) 0xf3, (byte) 0x7e, (byte) 0x38, (byte) 0x70, (byte) 0xeb,
-            (byte) 0x57, (byte) 0xd0, (byte) 0xd9, (byte) 0xa7, (byte) 0x0e, (byte) 0x14,
-            (byte) 0xf7, (byte) 0x95, (byte) 0x68, (byte) 0xd5, (byte) 0xc8, (byte) 0xab,
-            (byte) 0x9d, (byte) 0x3a, (byte) 0x2b, (byte) 0x51, (byte) 0xf9, (byte) 0x02,
-            (byte) 0x41, (byte) 0x00, (byte) 0x96, (byte) 0xdf, (byte) 0xe9, (byte) 0x67,
-            (byte) 0x6c, (byte) 0xdc, (byte) 0x90, (byte) 0x14, (byte) 0xb4, (byte) 0x1d,
-            (byte) 0x22, (byte) 0x33, (byte) 0x4a, (byte) 0x31, (byte) 0xc1, (byte) 0x9d,
-            (byte) 0x2e, (byte) 0xff, (byte) 0x9a, (byte) 0x2a, (byte) 0x95, (byte) 0x4b,
-            (byte) 0x27, (byte) 0x74, (byte) 0xcb, (byte) 0x21, (byte) 0xc3, (byte) 0xd2,
-            (byte) 0x0b, (byte) 0xb2, (byte) 0x46, (byte) 0x87, (byte) 0xf8, (byte) 0x28,
-            (byte) 0x01, (byte) 0x8b, (byte) 0xd8, (byte) 0xb9, (byte) 0x4b, (byte) 0xcd,
-            (byte) 0x9a, (byte) 0x96, (byte) 0x41, (byte) 0x0e, (byte) 0x36, (byte) 0x6d,
-            (byte) 0x40, (byte) 0x42, (byte) 0xbc, (byte) 0xd9, (byte) 0xd3, (byte) 0x7b,
-            (byte) 0xbc, (byte) 0xa7, (byte) 0x92, (byte) 0x90, (byte) 0xdd, (byte) 0xa1,
-            (byte) 0x9c, (byte) 0xce, (byte) 0xa1, (byte) 0x87, (byte) 0x11, (byte) 0x51
-    };
-    public static final PrivateKey RSA_KEY1 = loadPrivateKey("RSA", FAKE_RSA_KEY_1);
-
-    private static final String CA_SUITE_B_RSA3072_CERT_STRING =
-            "-----BEGIN CERTIFICATE-----\n"
-                    + "MIIEnTCCAwWgAwIBAgIUD87Y8fFLzLr1HQ/64aEnjNq2R/4wDQYJKoZIhvcNAQEM\n"
-                    + "BQAwXjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMQwwCgYDVQQHDANNVFYxEDAO\n"
-                    + "BgNVBAoMB0FuZHJvaWQxDjAMBgNVBAsMBVdpLUZpMRIwEAYDVQQDDAl1bml0ZXN0\n"
-                    + "Q0EwHhcNMjAwNzIxMDIxNzU0WhcNMzAwNTMwMDIxNzU0WjBeMQswCQYDVQQGEwJV\n"
-                    + "UzELMAkGA1UECAwCQ0ExDDAKBgNVBAcMA01UVjEQMA4GA1UECgwHQW5kcm9pZDEO\n"
-                    + "MAwGA1UECwwFV2ktRmkxEjAQBgNVBAMMCXVuaXRlc3RDQTCCAaIwDQYJKoZIhvcN\n"
-                    + "AQEBBQADggGPADCCAYoCggGBAMtrsT0otlxh0QS079KpRRbU1PQjCihSoltXnrxF\n"
-                    + "sTWZs2weVEeYVyYU5LaauCDDgISCMtjtfbfylMBeYjpWB5hYzYQOiTzo0anWhMyb\n"
-                    + "Ngb7gpMVZuIl6lwMYRyVRKwHWnTo2EUg1ZzW5rGe5fs/KHj6//hoNFm+3Oju0TQd\n"
-                    + "nraQULpoERPF5B7p85Cssk8uNbviBfZXvtCuJ4N6w7PNceOY/9bbwc1mC+pPZmzV\n"
-                    + "SOAg0vvbIQRzChm63C3jBC3xmxSOOZVrKN4zKDG2s8P0oCNGt0NlgRMrgbPRekzg\n"
-                    + "4avkbA0vTuc2AyriTEYkdea/Mt4EpRg9XuOb43U/GJ/d/vQv2/9fsxhXmsZrn8kr\n"
-                    + "Qo5MMHJFUd96GgHmvYSU3Mf/5r8gF626lvqHioGuTAuHUSnr02ri1WUxZ15LDRgY\n"
-                    + "quMjDCFZfucjJPDAdtiHcFSej/4SLJlN39z8oKKNPn3aL9Gv49oAKs9S8tfDVzMk\n"
-                    + "fDLROQFHFuW715GnnMgEAoOpRwIDAQABo1MwUTAdBgNVHQ4EFgQUeVuGmSVN4ARs\n"
-                    + "mesUMWSJ2qWLbxUwHwYDVR0jBBgwFoAUeVuGmSVN4ARsmesUMWSJ2qWLbxUwDwYD\n"
-                    + "VR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQwFAAOCAYEAit1Lo/hegZpPuT9dlWZJ\n"
-                    + "bC8JvAf95O8lnn6LFb69pgYOHCLgCIlvYXu9rdBUJgZo+V1MzJJljiO6RxWRfKbQ\n"
-                    + "8WBYkoqR1EqriR3Kn8q/SjIZCdFSaznTyU1wQMveBQ6RJWXSUhYVfE9RjyFTp7B4\n"
-                    + "UyH2uCluR/0T06HQNGfH5XpIYQqCk1Zgng5lmEmheLDPoJpa92lKeQFJMC6eYz9g\n"
-                    + "lF1GHxPxkPfbMJ6ZDp5X6Yopu6Q6uEXhVKM/iQVcgzRkx9rid+xTYl+nOKyK/XfC\n"
-                    + "z8P0/TFIoPTW02DLge5wKagdoCpy1B7HdrAXyUjoH4B8MsUkq3kYPFSjPzScuTtV\n"
-                    + "kUuDw5ipCNeXCRnhbYqRDk6PX5GUu2cmN9jtaH3tbgm3fKNOsd/BO1fLIl7qjXlR\n"
-                    + "27HHbC0JXjNvlm2DLp23v4NTxS7WZGYsxyUj5DZrxBxqCsTXu/01w1BrQKWKh9FM\n"
-                    + "aVrlA8omfVODK2CSuw+KhEMHepRv/AUgsLl4L4+RMoa+\n"
-                    + "-----END CERTIFICATE-----\n";
-    public static final X509Certificate CA_SUITE_B_RSA3072_CERT =
-            loadCertificate(CA_SUITE_B_RSA3072_CERT_STRING);
-
-    private static final String CA_SUITE_B_ECDSA_CERT_STRING =
-            "-----BEGIN CERTIFICATE-----\n"
-                    + "MIICTzCCAdSgAwIBAgIUdnLttwNPnQzFufplGOr9bTrGCqMwCgYIKoZIzj0EAwMw\n"
-                    + "XjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMQwwCgYDVQQHDANNVFYxEDAOBgNV\n"
-                    + "BAoMB0FuZHJvaWQxDjAMBgNVBAsMBVdpLUZpMRIwEAYDVQQDDAl1bml0ZXN0Q0Ew\n"
-                    + "HhcNMjAwNzIxMDIyNDA1WhcNMzAwNTMwMDIyNDA1WjBeMQswCQYDVQQGEwJVUzEL\n"
-                    + "MAkGA1UECAwCQ0ExDDAKBgNVBAcMA01UVjEQMA4GA1UECgwHQW5kcm9pZDEOMAwG\n"
-                    + "A1UECwwFV2ktRmkxEjAQBgNVBAMMCXVuaXRlc3RDQTB2MBAGByqGSM49AgEGBSuB\n"
-                    + "BAAiA2IABFmntXwk9icqhDQFUP1xy04WyEpaGW4q6Q+8pujlSl/X3iotPZ++GZfp\n"
-                    + "Mfv3YDHDBl6sELPQ2BEjyPXmpsKjOUdiUe69e88oGEdeqT2xXiQ6uzpTfJD4170i\n"
-                    + "O/TwLrQGKKNTMFEwHQYDVR0OBBYEFCjptsX3g4g5W0L4oEP6N3gfyiZXMB8GA1Ud\n"
-                    + "IwQYMBaAFCjptsX3g4g5W0L4oEP6N3gfyiZXMA8GA1UdEwEB/wQFMAMBAf8wCgYI\n"
-                    + "KoZIzj0EAwMDaQAwZgIxAK61brUYRbLmQKiaEboZgrHtnPAcGo7Yzx3MwHecx3Dm\n"
-                    + "5soIeLVYc8bPYN1pbhXW1gIxALdEe2sh03nBHyQH4adYoZungoCwt8mp/7sJFxou\n"
-                    + "9UnRegyBgGzf74ROWdpZHzh+Pg==\n"
-                    + "-----END CERTIFICATE-----\n";
-    public static final X509Certificate CA_SUITE_B_ECDSA_CERT =
-            loadCertificate(CA_SUITE_B_ECDSA_CERT_STRING);
-
-    private static final String CLIENT_SUITE_B_RSA3072_CERT_STRING =
-            "-----BEGIN CERTIFICATE-----\n"
-                    + "MIIERzCCAq8CFDopjyNgaj+c2TN2k06h7okEWpHJMA0GCSqGSIb3DQEBDAUAMF4x\n"
-                    + "CzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEMMAoGA1UEBwwDTVRWMRAwDgYDVQQK\n"
-                    + "DAdBbmRyb2lkMQ4wDAYDVQQLDAVXaS1GaTESMBAGA1UEAwwJdW5pdGVzdENBMB4X\n"
-                    + "DTIwMDcyMTAyMjkxMVoXDTMwMDUzMDAyMjkxMVowYjELMAkGA1UEBhMCVVMxCzAJ\n"
-                    + "BgNVBAgMAkNBMQwwCgYDVQQHDANNVFYxEDAOBgNVBAoMB0FuZHJvaWQxDjAMBgNV\n"
-                    + "BAsMBVdpLUZpMRYwFAYDVQQDDA11bml0ZXN0Q2xpZW50MIIBojANBgkqhkiG9w0B\n"
-                    + "AQEFAAOCAY8AMIIBigKCAYEAwSK3C5K5udtCKTnE14e8z2cZvwmB4Xe+a8+7QLud\n"
-                    + "Hooc/lQzClgK4MbVUC0D3FE+U32C78SxKoTaRWtvPmNm+UaFT8KkwyUno/dv+2XD\n"
-                    + "pd/zARQ+3FwAfWopAhEyCVSxwsCa+slQ4juRIMIuUC1Mm0NaptZyM3Tj/ICQEfpk\n"
-                    + "o9qVIbiK6eoJMTkY8EWfAn7RTFdfR1OLuO0mVOjgLW9/+upYv6hZ19nAMAxw4QTJ\n"
-                    + "x7lLwALX7B+tDYNEZHDqYL2zyvQWAj2HClere8QYILxkvktgBg2crEJJe4XbDH7L\n"
-                    + "A3rrXmsiqf1ZbfFFEzK9NFqovL+qGh+zIP+588ShJFO9H/RDnDpiTnAFTWXQdTwg\n"
-                    + "szSS0Vw2PB+JqEABAa9DeMvXT1Oy+NY3ItPHyy63nQZVI2rXANw4NhwS0Z6DF+Qs\n"
-                    + "TNrj+GU7e4SG/EGR8SvldjYfQTWFLg1l/UT1hOOkQZwdsaW1zgKyeuiFB2KdMmbA\n"
-                    + "Sq+Ux1L1KICo0IglwWcB/8nnAgMBAAEwDQYJKoZIhvcNAQEMBQADggGBAMYwJkNw\n"
-                    + "BaCviKFmReDTMwWPRy4AMNViEeqAXgERwDEKwM7efjsaj5gctWfKsxX6UdLzkhgg\n"
-                    + "6S/T6PxVWKzJ6l7SoOuTa6tMQOZp+h3R1mdfEQbw8B5cXBxZ+batzAai6Fiy1FKS\n"
-                    + "/ka3INbcGfYuIYghfTrb4/NJKN06ZaQ1bpPwq0e4gN7800T2nbawvSf7r+8ZLcG3\n"
-                    + "6bGCjRMwDSIipNvOwoj3TG315XC7TccX5difQ4sKOY+d2MkVJ3RiO0Ciw2ZbEW8d\n"
-                    + "1FH5vUQJWnBUfSFznosGzLwH3iWfqlP+27jNE+qB2igEwCRFgVAouURx5ou43xuX\n"
-                    + "qf6JkdI3HTJGLIWxkp7gOeln4dEaYzKjYw+P0VqJvKVqQ0IXiLjHgE0J9p0vgyD6\n"
-                    + "HVVcP7U8RgqrbIjL1QgHU4KBhGi+WSUh/mRplUCNvHgcYdcHi/gHpj/j6ubwqIGV\n"
-                    + "z4iSolAHYTmBWcLyE0NgpzE6ntp+53r2KaUJA99l2iGVzbWTwqPSm0XAVw==\n"
-                    + "-----END CERTIFICATE-----\n";
-    public static final X509Certificate CLIENT_SUITE_B_RSA3072_CERT =
-            loadCertificate(CLIENT_SUITE_B_RSA3072_CERT_STRING);
-
-    private static final byte[] CLIENT_SUITE_B_RSA3072_KEY_DATA = new byte[]{
-            (byte) 0x30, (byte) 0x82, (byte) 0x06, (byte) 0xfe, (byte) 0x02, (byte) 0x01,
-            (byte) 0x00, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a,
-            (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01,
-            (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x04, (byte) 0x82,
-            (byte) 0x06, (byte) 0xe8, (byte) 0x30, (byte) 0x82, (byte) 0x06, (byte) 0xe4,
-            (byte) 0x02, (byte) 0x01, (byte) 0x00, (byte) 0x02, (byte) 0x82, (byte) 0x01,
-            (byte) 0x81, (byte) 0x00, (byte) 0xc1, (byte) 0x22, (byte) 0xb7, (byte) 0x0b,
-            (byte) 0x92, (byte) 0xb9, (byte) 0xb9, (byte) 0xdb, (byte) 0x42, (byte) 0x29,
-            (byte) 0x39, (byte) 0xc4, (byte) 0xd7, (byte) 0x87, (byte) 0xbc, (byte) 0xcf,
-            (byte) 0x67, (byte) 0x19, (byte) 0xbf, (byte) 0x09, (byte) 0x81, (byte) 0xe1,
-            (byte) 0x77, (byte) 0xbe, (byte) 0x6b, (byte) 0xcf, (byte) 0xbb, (byte) 0x40,
-            (byte) 0xbb, (byte) 0x9d, (byte) 0x1e, (byte) 0x8a, (byte) 0x1c, (byte) 0xfe,
-            (byte) 0x54, (byte) 0x33, (byte) 0x0a, (byte) 0x58, (byte) 0x0a, (byte) 0xe0,
-            (byte) 0xc6, (byte) 0xd5, (byte) 0x50, (byte) 0x2d, (byte) 0x03, (byte) 0xdc,
-            (byte) 0x51, (byte) 0x3e, (byte) 0x53, (byte) 0x7d, (byte) 0x82, (byte) 0xef,
-            (byte) 0xc4, (byte) 0xb1, (byte) 0x2a, (byte) 0x84, (byte) 0xda, (byte) 0x45,
-            (byte) 0x6b, (byte) 0x6f, (byte) 0x3e, (byte) 0x63, (byte) 0x66, (byte) 0xf9,
-            (byte) 0x46, (byte) 0x85, (byte) 0x4f, (byte) 0xc2, (byte) 0xa4, (byte) 0xc3,
-            (byte) 0x25, (byte) 0x27, (byte) 0xa3, (byte) 0xf7, (byte) 0x6f, (byte) 0xfb,
-            (byte) 0x65, (byte) 0xc3, (byte) 0xa5, (byte) 0xdf, (byte) 0xf3, (byte) 0x01,
-            (byte) 0x14, (byte) 0x3e, (byte) 0xdc, (byte) 0x5c, (byte) 0x00, (byte) 0x7d,
-            (byte) 0x6a, (byte) 0x29, (byte) 0x02, (byte) 0x11, (byte) 0x32, (byte) 0x09,
-            (byte) 0x54, (byte) 0xb1, (byte) 0xc2, (byte) 0xc0, (byte) 0x9a, (byte) 0xfa,
-            (byte) 0xc9, (byte) 0x50, (byte) 0xe2, (byte) 0x3b, (byte) 0x91, (byte) 0x20,
-            (byte) 0xc2, (byte) 0x2e, (byte) 0x50, (byte) 0x2d, (byte) 0x4c, (byte) 0x9b,
-            (byte) 0x43, (byte) 0x5a, (byte) 0xa6, (byte) 0xd6, (byte) 0x72, (byte) 0x33,
-            (byte) 0x74, (byte) 0xe3, (byte) 0xfc, (byte) 0x80, (byte) 0x90, (byte) 0x11,
-            (byte) 0xfa, (byte) 0x64, (byte) 0xa3, (byte) 0xda, (byte) 0x95, (byte) 0x21,
-            (byte) 0xb8, (byte) 0x8a, (byte) 0xe9, (byte) 0xea, (byte) 0x09, (byte) 0x31,
-            (byte) 0x39, (byte) 0x18, (byte) 0xf0, (byte) 0x45, (byte) 0x9f, (byte) 0x02,
-            (byte) 0x7e, (byte) 0xd1, (byte) 0x4c, (byte) 0x57, (byte) 0x5f, (byte) 0x47,
-            (byte) 0x53, (byte) 0x8b, (byte) 0xb8, (byte) 0xed, (byte) 0x26, (byte) 0x54,
-            (byte) 0xe8, (byte) 0xe0, (byte) 0x2d, (byte) 0x6f, (byte) 0x7f, (byte) 0xfa,
-            (byte) 0xea, (byte) 0x58, (byte) 0xbf, (byte) 0xa8, (byte) 0x59, (byte) 0xd7,
-            (byte) 0xd9, (byte) 0xc0, (byte) 0x30, (byte) 0x0c, (byte) 0x70, (byte) 0xe1,
-            (byte) 0x04, (byte) 0xc9, (byte) 0xc7, (byte) 0xb9, (byte) 0x4b, (byte) 0xc0,
-            (byte) 0x02, (byte) 0xd7, (byte) 0xec, (byte) 0x1f, (byte) 0xad, (byte) 0x0d,
-            (byte) 0x83, (byte) 0x44, (byte) 0x64, (byte) 0x70, (byte) 0xea, (byte) 0x60,
-            (byte) 0xbd, (byte) 0xb3, (byte) 0xca, (byte) 0xf4, (byte) 0x16, (byte) 0x02,
-            (byte) 0x3d, (byte) 0x87, (byte) 0x0a, (byte) 0x57, (byte) 0xab, (byte) 0x7b,
-            (byte) 0xc4, (byte) 0x18, (byte) 0x20, (byte) 0xbc, (byte) 0x64, (byte) 0xbe,
-            (byte) 0x4b, (byte) 0x60, (byte) 0x06, (byte) 0x0d, (byte) 0x9c, (byte) 0xac,
-            (byte) 0x42, (byte) 0x49, (byte) 0x7b, (byte) 0x85, (byte) 0xdb, (byte) 0x0c,
-            (byte) 0x7e, (byte) 0xcb, (byte) 0x03, (byte) 0x7a, (byte) 0xeb, (byte) 0x5e,
-            (byte) 0x6b, (byte) 0x22, (byte) 0xa9, (byte) 0xfd, (byte) 0x59, (byte) 0x6d,
-            (byte) 0xf1, (byte) 0x45, (byte) 0x13, (byte) 0x32, (byte) 0xbd, (byte) 0x34,
-            (byte) 0x5a, (byte) 0xa8, (byte) 0xbc, (byte) 0xbf, (byte) 0xaa, (byte) 0x1a,
-            (byte) 0x1f, (byte) 0xb3, (byte) 0x20, (byte) 0xff, (byte) 0xb9, (byte) 0xf3,
-            (byte) 0xc4, (byte) 0xa1, (byte) 0x24, (byte) 0x53, (byte) 0xbd, (byte) 0x1f,
-            (byte) 0xf4, (byte) 0x43, (byte) 0x9c, (byte) 0x3a, (byte) 0x62, (byte) 0x4e,
-            (byte) 0x70, (byte) 0x05, (byte) 0x4d, (byte) 0x65, (byte) 0xd0, (byte) 0x75,
-            (byte) 0x3c, (byte) 0x20, (byte) 0xb3, (byte) 0x34, (byte) 0x92, (byte) 0xd1,
-            (byte) 0x5c, (byte) 0x36, (byte) 0x3c, (byte) 0x1f, (byte) 0x89, (byte) 0xa8,
-            (byte) 0x40, (byte) 0x01, (byte) 0x01, (byte) 0xaf, (byte) 0x43, (byte) 0x78,
-            (byte) 0xcb, (byte) 0xd7, (byte) 0x4f, (byte) 0x53, (byte) 0xb2, (byte) 0xf8,
-            (byte) 0xd6, (byte) 0x37, (byte) 0x22, (byte) 0xd3, (byte) 0xc7, (byte) 0xcb,
-            (byte) 0x2e, (byte) 0xb7, (byte) 0x9d, (byte) 0x06, (byte) 0x55, (byte) 0x23,
-            (byte) 0x6a, (byte) 0xd7, (byte) 0x00, (byte) 0xdc, (byte) 0x38, (byte) 0x36,
-            (byte) 0x1c, (byte) 0x12, (byte) 0xd1, (byte) 0x9e, (byte) 0x83, (byte) 0x17,
-            (byte) 0xe4, (byte) 0x2c, (byte) 0x4c, (byte) 0xda, (byte) 0xe3, (byte) 0xf8,
-            (byte) 0x65, (byte) 0x3b, (byte) 0x7b, (byte) 0x84, (byte) 0x86, (byte) 0xfc,
-            (byte) 0x41, (byte) 0x91, (byte) 0xf1, (byte) 0x2b, (byte) 0xe5, (byte) 0x76,
-            (byte) 0x36, (byte) 0x1f, (byte) 0x41, (byte) 0x35, (byte) 0x85, (byte) 0x2e,
-            (byte) 0x0d, (byte) 0x65, (byte) 0xfd, (byte) 0x44, (byte) 0xf5, (byte) 0x84,
-            (byte) 0xe3, (byte) 0xa4, (byte) 0x41, (byte) 0x9c, (byte) 0x1d, (byte) 0xb1,
-            (byte) 0xa5, (byte) 0xb5, (byte) 0xce, (byte) 0x02, (byte) 0xb2, (byte) 0x7a,
-            (byte) 0xe8, (byte) 0x85, (byte) 0x07, (byte) 0x62, (byte) 0x9d, (byte) 0x32,
-            (byte) 0x66, (byte) 0xc0, (byte) 0x4a, (byte) 0xaf, (byte) 0x94, (byte) 0xc7,
-            (byte) 0x52, (byte) 0xf5, (byte) 0x28, (byte) 0x80, (byte) 0xa8, (byte) 0xd0,
-            (byte) 0x88, (byte) 0x25, (byte) 0xc1, (byte) 0x67, (byte) 0x01, (byte) 0xff,
-            (byte) 0xc9, (byte) 0xe7, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x00,
-            (byte) 0x01, (byte) 0x02, (byte) 0x82, (byte) 0x01, (byte) 0x80, (byte) 0x04,
-            (byte) 0xb1, (byte) 0xcc, (byte) 0x53, (byte) 0x3a, (byte) 0xb0, (byte) 0xcb,
-            (byte) 0x04, (byte) 0xba, (byte) 0x59, (byte) 0xf8, (byte) 0x2e, (byte) 0x81,
-            (byte) 0xb2, (byte) 0xa9, (byte) 0xf3, (byte) 0x3c, (byte) 0xa5, (byte) 0x52,
-            (byte) 0x90, (byte) 0x6f, (byte) 0x98, (byte) 0xc4, (byte) 0x69, (byte) 0x5b,
-            (byte) 0x83, (byte) 0x84, (byte) 0x20, (byte) 0xb1, (byte) 0xae, (byte) 0xc3,
-            (byte) 0x04, (byte) 0x46, (byte) 0x6a, (byte) 0x24, (byte) 0x2f, (byte) 0xcd,
-            (byte) 0x6b, (byte) 0x90, (byte) 0x70, (byte) 0x20, (byte) 0x45, (byte) 0x25,
-            (byte) 0x1a, (byte) 0xc3, (byte) 0x02, (byte) 0x42, (byte) 0xf3, (byte) 0x49,
-            (byte) 0xe2, (byte) 0x3e, (byte) 0x21, (byte) 0x87, (byte) 0xdd, (byte) 0x6a,
-            (byte) 0x94, (byte) 0x2a, (byte) 0x1e, (byte) 0x0f, (byte) 0xdb, (byte) 0x77,
-            (byte) 0x5f, (byte) 0xc1, (byte) 0x2c, (byte) 0x03, (byte) 0xfb, (byte) 0xcf,
-            (byte) 0x91, (byte) 0x82, (byte) 0xa1, (byte) 0xbf, (byte) 0xb0, (byte) 0x73,
-            (byte) 0xfa, (byte) 0xda, (byte) 0xbc, (byte) 0xf8, (byte) 0x9f, (byte) 0x45,
-            (byte) 0xd3, (byte) 0xe8, (byte) 0xbb, (byte) 0x38, (byte) 0xfb, (byte) 0xc2,
-            (byte) 0x2d, (byte) 0x76, (byte) 0x51, (byte) 0x96, (byte) 0x18, (byte) 0x03,
-            (byte) 0x15, (byte) 0xd9, (byte) 0xea, (byte) 0x82, (byte) 0x25, (byte) 0x83,
-            (byte) 0xff, (byte) 0x5c, (byte) 0x85, (byte) 0x06, (byte) 0x09, (byte) 0xb2,
-            (byte) 0x46, (byte) 0x12, (byte) 0x64, (byte) 0x02, (byte) 0x74, (byte) 0x4f,
-            (byte) 0xbc, (byte) 0x9a, (byte) 0x25, (byte) 0x18, (byte) 0x01, (byte) 0x07,
-            (byte) 0x17, (byte) 0x25, (byte) 0x55, (byte) 0x7c, (byte) 0xdc, (byte) 0xe1,
-            (byte) 0xd1, (byte) 0x5a, (byte) 0x2f, (byte) 0x25, (byte) 0xaf, (byte) 0xf6,
-            (byte) 0x8f, (byte) 0xa4, (byte) 0x9a, (byte) 0x5a, (byte) 0x3a, (byte) 0xfe,
-            (byte) 0x2e, (byte) 0x93, (byte) 0x24, (byte) 0xa0, (byte) 0x27, (byte) 0xac,
-            (byte) 0x07, (byte) 0x75, (byte) 0x33, (byte) 0x01, (byte) 0x54, (byte) 0x23,
-            (byte) 0x0f, (byte) 0xe8, (byte) 0x9f, (byte) 0xfa, (byte) 0x36, (byte) 0xe6,
-            (byte) 0x3a, (byte) 0xd5, (byte) 0x78, (byte) 0xb0, (byte) 0xe4, (byte) 0x6a,
-            (byte) 0x16, (byte) 0x50, (byte) 0xbd, (byte) 0x0f, (byte) 0x9f, (byte) 0x32,
-            (byte) 0xa1, (byte) 0x6b, (byte) 0xf5, (byte) 0xa4, (byte) 0x34, (byte) 0x58,
-            (byte) 0xb6, (byte) 0xa4, (byte) 0xb3, (byte) 0xc3, (byte) 0x83, (byte) 0x08,
-            (byte) 0x18, (byte) 0xc7, (byte) 0xef, (byte) 0x95, (byte) 0xe2, (byte) 0x1b,
-            (byte) 0xba, (byte) 0x35, (byte) 0x61, (byte) 0xa3, (byte) 0xb4, (byte) 0x30,
-            (byte) 0xe0, (byte) 0xd1, (byte) 0xc1, (byte) 0xa2, (byte) 0x3a, (byte) 0xc6,
-            (byte) 0xb4, (byte) 0xd2, (byte) 0x80, (byte) 0x5a, (byte) 0xaf, (byte) 0xa4,
-            (byte) 0x54, (byte) 0x3c, (byte) 0x66, (byte) 0x5a, (byte) 0x1c, (byte) 0x4d,
-            (byte) 0xe1, (byte) 0xd9, (byte) 0x98, (byte) 0x44, (byte) 0x01, (byte) 0x1b,
-            (byte) 0x8c, (byte) 0xe9, (byte) 0x80, (byte) 0x54, (byte) 0x83, (byte) 0x3d,
-            (byte) 0x96, (byte) 0x25, (byte) 0x41, (byte) 0x1c, (byte) 0xad, (byte) 0xae,
-            (byte) 0x3b, (byte) 0x7a, (byte) 0xd7, (byte) 0x9d, (byte) 0x10, (byte) 0x7c,
-            (byte) 0xd1, (byte) 0xa7, (byte) 0x96, (byte) 0x39, (byte) 0xa5, (byte) 0x2f,
-            (byte) 0xbe, (byte) 0xc3, (byte) 0x2c, (byte) 0x64, (byte) 0x01, (byte) 0xfe,
-            (byte) 0xa2, (byte) 0xd1, (byte) 0x6a, (byte) 0xcf, (byte) 0x4c, (byte) 0x76,
-            (byte) 0x3b, (byte) 0xc8, (byte) 0x35, (byte) 0x21, (byte) 0xda, (byte) 0x98,
-            (byte) 0xcf, (byte) 0xf9, (byte) 0x29, (byte) 0xff, (byte) 0x30, (byte) 0x59,
-            (byte) 0x36, (byte) 0x53, (byte) 0x0b, (byte) 0xbb, (byte) 0xfa, (byte) 0xba,
-            (byte) 0xc4, (byte) 0x03, (byte) 0x23, (byte) 0xe0, (byte) 0xd3, (byte) 0x33,
-            (byte) 0xff, (byte) 0x32, (byte) 0xdb, (byte) 0x30, (byte) 0x64, (byte) 0xc7,
-            (byte) 0x56, (byte) 0xca, (byte) 0x55, (byte) 0x14, (byte) 0xee, (byte) 0x58,
-            (byte) 0xfe, (byte) 0x96, (byte) 0x7e, (byte) 0x1c, (byte) 0x34, (byte) 0x16,
-            (byte) 0xeb, (byte) 0x76, (byte) 0x26, (byte) 0x48, (byte) 0xe2, (byte) 0xe5,
-            (byte) 0x5c, (byte) 0xd5, (byte) 0x83, (byte) 0x37, (byte) 0xd9, (byte) 0x09,
-            (byte) 0x71, (byte) 0xbc, (byte) 0x54, (byte) 0x25, (byte) 0xca, (byte) 0x2e,
-            (byte) 0xdb, (byte) 0x36, (byte) 0x39, (byte) 0xcc, (byte) 0x3a, (byte) 0x81,
-            (byte) 0x95, (byte) 0x9e, (byte) 0xf4, (byte) 0x01, (byte) 0xa7, (byte) 0xc0,
-            (byte) 0x20, (byte) 0xce, (byte) 0x70, (byte) 0x55, (byte) 0x2c, (byte) 0xe0,
-            (byte) 0x93, (byte) 0x72, (byte) 0xa6, (byte) 0x25, (byte) 0xda, (byte) 0x64,
-            (byte) 0x19, (byte) 0x18, (byte) 0xd2, (byte) 0x31, (byte) 0xe2, (byte) 0x7c,
-            (byte) 0xf2, (byte) 0x30, (byte) 0x9e, (byte) 0x8d, (byte) 0xc6, (byte) 0x14,
-            (byte) 0x8a, (byte) 0x38, (byte) 0xf0, (byte) 0x94, (byte) 0xeb, (byte) 0xf4,
-            (byte) 0x64, (byte) 0x92, (byte) 0x3d, (byte) 0x67, (byte) 0xa6, (byte) 0x2c,
-            (byte) 0x52, (byte) 0xfc, (byte) 0x60, (byte) 0xca, (byte) 0x2a, (byte) 0xcf,
-            (byte) 0x24, (byte) 0xd5, (byte) 0x42, (byte) 0x5f, (byte) 0xc7, (byte) 0x9f,
-            (byte) 0xf3, (byte) 0xb4, (byte) 0xdf, (byte) 0x76, (byte) 0x6e, (byte) 0x53,
-            (byte) 0xa1, (byte) 0x7b, (byte) 0xae, (byte) 0xa5, (byte) 0x84, (byte) 0x1f,
-            (byte) 0xfa, (byte) 0xc0, (byte) 0xb4, (byte) 0x6c, (byte) 0xc9, (byte) 0x02,
-            (byte) 0x81, (byte) 0xc1, (byte) 0x00, (byte) 0xf3, (byte) 0x17, (byte) 0xd9,
-            (byte) 0x48, (byte) 0x17, (byte) 0x87, (byte) 0x84, (byte) 0x16, (byte) 0xea,
-            (byte) 0x2d, (byte) 0x31, (byte) 0x1b, (byte) 0xce, (byte) 0xec, (byte) 0xaf,
-            (byte) 0xdc, (byte) 0x6b, (byte) 0xaf, (byte) 0xc8, (byte) 0xf1, (byte) 0x40,
-            (byte) 0xa7, (byte) 0x4f, (byte) 0xef, (byte) 0x48, (byte) 0x08, (byte) 0x5e,
-            (byte) 0x9a, (byte) 0xd1, (byte) 0xc0, (byte) 0xb1, (byte) 0xfe, (byte) 0xe7,
-            (byte) 0x03, (byte) 0xd5, (byte) 0x96, (byte) 0x01, (byte) 0xe8, (byte) 0x40,
-            (byte) 0xca, (byte) 0x78, (byte) 0xcb, (byte) 0xb3, (byte) 0x28, (byte) 0x1a,
-            (byte) 0xf0, (byte) 0xe5, (byte) 0xf6, (byte) 0x46, (byte) 0xef, (byte) 0xcd,
-            (byte) 0x1a, (byte) 0x0f, (byte) 0x13, (byte) 0x2d, (byte) 0x38, (byte) 0xf8,
-            (byte) 0xf7, (byte) 0x88, (byte) 0x21, (byte) 0x15, (byte) 0xce, (byte) 0x48,
-            (byte) 0xf4, (byte) 0x92, (byte) 0x7e, (byte) 0x9b, (byte) 0x2e, (byte) 0x2f,
-            (byte) 0x22, (byte) 0x3e, (byte) 0x5c, (byte) 0x67, (byte) 0xd7, (byte) 0x58,
-            (byte) 0xf6, (byte) 0xef, (byte) 0x1f, (byte) 0xb4, (byte) 0x04, (byte) 0xc7,
-            (byte) 0xfd, (byte) 0x8c, (byte) 0x4e, (byte) 0x27, (byte) 0x9e, (byte) 0xb9,
-            (byte) 0xef, (byte) 0x0f, (byte) 0xf7, (byte) 0x4a, (byte) 0xc2, (byte) 0xf4,
-            (byte) 0x64, (byte) 0x6b, (byte) 0xe0, (byte) 0xfb, (byte) 0xe3, (byte) 0x45,
-            (byte) 0xd5, (byte) 0x37, (byte) 0xa0, (byte) 0x2a, (byte) 0xc6, (byte) 0xf3,
-            (byte) 0xf6, (byte) 0xcc, (byte) 0xb5, (byte) 0x94, (byte) 0xbf, (byte) 0x56,
-            (byte) 0xa0, (byte) 0x61, (byte) 0x36, (byte) 0x88, (byte) 0x35, (byte) 0xd5,
-            (byte) 0xa5, (byte) 0xad, (byte) 0x20, (byte) 0x48, (byte) 0xda, (byte) 0x70,
-            (byte) 0x35, (byte) 0xd9, (byte) 0x75, (byte) 0x66, (byte) 0xa5, (byte) 0xac,
-            (byte) 0x86, (byte) 0x7a, (byte) 0x75, (byte) 0x49, (byte) 0x88, (byte) 0x40,
-            (byte) 0xce, (byte) 0xb0, (byte) 0x6f, (byte) 0x57, (byte) 0x15, (byte) 0x54,
-            (byte) 0xd3, (byte) 0x2f, (byte) 0x11, (byte) 0x9b, (byte) 0xe3, (byte) 0x87,
-            (byte) 0xc8, (byte) 0x8d, (byte) 0x98, (byte) 0xc6, (byte) 0xe0, (byte) 0xbc,
-            (byte) 0x85, (byte) 0xb9, (byte) 0x04, (byte) 0x43, (byte) 0xa9, (byte) 0x41,
-            (byte) 0xce, (byte) 0x42, (byte) 0x1a, (byte) 0x57, (byte) 0x10, (byte) 0xd8,
-            (byte) 0xe4, (byte) 0x6a, (byte) 0x51, (byte) 0x10, (byte) 0x0a, (byte) 0xec,
-            (byte) 0xe4, (byte) 0x57, (byte) 0xc7, (byte) 0xee, (byte) 0xe9, (byte) 0xd6,
-            (byte) 0xcb, (byte) 0x3e, (byte) 0xba, (byte) 0xfa, (byte) 0xe9, (byte) 0x0e,
-            (byte) 0xed, (byte) 0x87, (byte) 0x04, (byte) 0x9a, (byte) 0x48, (byte) 0xba,
-            (byte) 0xaf, (byte) 0x08, (byte) 0xf5, (byte) 0x02, (byte) 0x81, (byte) 0xc1,
-            (byte) 0x00, (byte) 0xcb, (byte) 0x63, (byte) 0xd6, (byte) 0x54, (byte) 0xb6,
-            (byte) 0xf3, (byte) 0xf3, (byte) 0x8c, (byte) 0xf8, (byte) 0xd0, (byte) 0xd2,
-            (byte) 0x84, (byte) 0xc1, (byte) 0xf5, (byte) 0x12, (byte) 0xe0, (byte) 0x02,
-            (byte) 0x80, (byte) 0x42, (byte) 0x92, (byte) 0x4e, (byte) 0xa4, (byte) 0x5c,
-            (byte) 0xa5, (byte) 0x64, (byte) 0xec, (byte) 0xb7, (byte) 0xdc, (byte) 0xe0,
-            (byte) 0x2d, (byte) 0x5d, (byte) 0xac, (byte) 0x0e, (byte) 0x24, (byte) 0x48,
-            (byte) 0x13, (byte) 0x05, (byte) 0xe8, (byte) 0xff, (byte) 0x96, (byte) 0x93,
-            (byte) 0xba, (byte) 0x3c, (byte) 0x88, (byte) 0xcc, (byte) 0x80, (byte) 0xf9,
-            (byte) 0xdb, (byte) 0xa8, (byte) 0x4d, (byte) 0x86, (byte) 0x47, (byte) 0xc8,
-            (byte) 0xbf, (byte) 0x34, (byte) 0x2d, (byte) 0xda, (byte) 0xb6, (byte) 0x28,
-            (byte) 0xf0, (byte) 0x1e, (byte) 0xd2, (byte) 0x46, (byte) 0x0d, (byte) 0x6f,
-            (byte) 0x36, (byte) 0x8e, (byte) 0x84, (byte) 0xd8, (byte) 0xaf, (byte) 0xf7,
-            (byte) 0x69, (byte) 0x23, (byte) 0x77, (byte) 0xfb, (byte) 0xc5, (byte) 0x04,
-            (byte) 0x08, (byte) 0x18, (byte) 0xac, (byte) 0x85, (byte) 0x80, (byte) 0x87,
-            (byte) 0x1c, (byte) 0xfe, (byte) 0x8e, (byte) 0x5d, (byte) 0x00, (byte) 0x7f,
-            (byte) 0x5b, (byte) 0x33, (byte) 0xf5, (byte) 0xdf, (byte) 0x70, (byte) 0x81,
-            (byte) 0xad, (byte) 0x81, (byte) 0xf4, (byte) 0x5a, (byte) 0x37, (byte) 0x8a,
-            (byte) 0x79, (byte) 0x09, (byte) 0xc5, (byte) 0x55, (byte) 0xab, (byte) 0x58,
-            (byte) 0x7c, (byte) 0x47, (byte) 0xca, (byte) 0xa5, (byte) 0x80, (byte) 0x49,
-            (byte) 0x5f, (byte) 0x71, (byte) 0x83, (byte) 0xfb, (byte) 0x3b, (byte) 0x06,
-            (byte) 0xec, (byte) 0x75, (byte) 0x23, (byte) 0xc4, (byte) 0x32, (byte) 0xc7,
-            (byte) 0x18, (byte) 0xf6, (byte) 0x82, (byte) 0x95, (byte) 0x98, (byte) 0x39,
-            (byte) 0xf7, (byte) 0x92, (byte) 0x31, (byte) 0xc0, (byte) 0x89, (byte) 0xba,
-            (byte) 0xd4, (byte) 0xd4, (byte) 0x58, (byte) 0x4e, (byte) 0x38, (byte) 0x35,
-            (byte) 0x10, (byte) 0xb9, (byte) 0xf1, (byte) 0x27, (byte) 0xdc, (byte) 0xff,
-            (byte) 0xc7, (byte) 0xb2, (byte) 0xba, (byte) 0x1f, (byte) 0x27, (byte) 0xaf,
-            (byte) 0x99, (byte) 0xd5, (byte) 0xb0, (byte) 0x39, (byte) 0xe7, (byte) 0x43,
-            (byte) 0x88, (byte) 0xd3, (byte) 0xce, (byte) 0x38, (byte) 0xc2, (byte) 0x99,
-            (byte) 0x43, (byte) 0xfc, (byte) 0x8a, (byte) 0xe3, (byte) 0x60, (byte) 0x0d,
-            (byte) 0x0a, (byte) 0xb8, (byte) 0xc4, (byte) 0x29, (byte) 0xca, (byte) 0x0d,
-            (byte) 0x30, (byte) 0xaf, (byte) 0xca, (byte) 0xd0, (byte) 0xaa, (byte) 0x67,
-            (byte) 0xb1, (byte) 0xdd, (byte) 0xdb, (byte) 0x7a, (byte) 0x11, (byte) 0xad,
-            (byte) 0xeb, (byte) 0x02, (byte) 0x81, (byte) 0xc0, (byte) 0x71, (byte) 0xb8,
-            (byte) 0xcf, (byte) 0x72, (byte) 0x35, (byte) 0x67, (byte) 0xb5, (byte) 0x38,
-            (byte) 0x8f, (byte) 0x16, (byte) 0xd3, (byte) 0x29, (byte) 0x82, (byte) 0x35,
-            (byte) 0x21, (byte) 0xd4, (byte) 0x49, (byte) 0x20, (byte) 0x74, (byte) 0x2d,
-            (byte) 0xc0, (byte) 0xa4, (byte) 0x44, (byte) 0xf5, (byte) 0xd8, (byte) 0xc9,
-            (byte) 0xe9, (byte) 0x90, (byte) 0x1d, (byte) 0xde, (byte) 0x3a, (byte) 0xa6,
-            (byte) 0xd7, (byte) 0xe5, (byte) 0xe8, (byte) 0x4e, (byte) 0x83, (byte) 0xd7,
-            (byte) 0xe6, (byte) 0x2f, (byte) 0x92, (byte) 0x31, (byte) 0x21, (byte) 0x3f,
-            (byte) 0xfa, (byte) 0xd2, (byte) 0x85, (byte) 0x92, (byte) 0x1f, (byte) 0xff,
-            (byte) 0x61, (byte) 0x00, (byte) 0xf6, (byte) 0xda, (byte) 0x6e, (byte) 0xc6,
-            (byte) 0x7f, (byte) 0x5a, (byte) 0x35, (byte) 0x79, (byte) 0xdc, (byte) 0xdc,
-            (byte) 0xa3, (byte) 0x2e, (byte) 0x9f, (byte) 0x35, (byte) 0xd1, (byte) 0x5c,
-            (byte) 0xda, (byte) 0xb9, (byte) 0xf7, (byte) 0x58, (byte) 0x7d, (byte) 0x4f,
-            (byte) 0xb6, (byte) 0x13, (byte) 0xd7, (byte) 0x2c, (byte) 0x0a, (byte) 0xa8,
-            (byte) 0x4d, (byte) 0xf2, (byte) 0xe4, (byte) 0x67, (byte) 0x4f, (byte) 0x8b,
-            (byte) 0xa6, (byte) 0xca, (byte) 0x1a, (byte) 0xbb, (byte) 0x02, (byte) 0x63,
-            (byte) 0x8f, (byte) 0xb7, (byte) 0x46, (byte) 0xec, (byte) 0x7a, (byte) 0x8a,
-            (byte) 0x09, (byte) 0x0a, (byte) 0x45, (byte) 0x3a, (byte) 0x8d, (byte) 0xa8,
-            (byte) 0x83, (byte) 0x4b, (byte) 0x0a, (byte) 0xdb, (byte) 0x4b, (byte) 0x99,
-            (byte) 0xf3, (byte) 0x69, (byte) 0x95, (byte) 0xf0, (byte) 0xcf, (byte) 0xe9,
-            (byte) 0xf7, (byte) 0x67, (byte) 0xc9, (byte) 0x45, (byte) 0x18, (byte) 0x2f,
-            (byte) 0xf0, (byte) 0x5c, (byte) 0x90, (byte) 0xbd, (byte) 0xa6, (byte) 0x66,
-            (byte) 0x8c, (byte) 0xfe, (byte) 0x60, (byte) 0x5d, (byte) 0x6c, (byte) 0x27,
-            (byte) 0xec, (byte) 0xc1, (byte) 0x84, (byte) 0xb2, (byte) 0xa1, (byte) 0x97,
-            (byte) 0x9e, (byte) 0x16, (byte) 0x29, (byte) 0xa7, (byte) 0xe0, (byte) 0x38,
-            (byte) 0xa2, (byte) 0x36, (byte) 0x05, (byte) 0x5f, (byte) 0xda, (byte) 0x72,
-            (byte) 0x1a, (byte) 0x5f, (byte) 0xa8, (byte) 0x7d, (byte) 0x41, (byte) 0x35,
-            (byte) 0xf6, (byte) 0x4e, (byte) 0x0a, (byte) 0x88, (byte) 0x8e, (byte) 0x00,
-            (byte) 0x98, (byte) 0xa6, (byte) 0xca, (byte) 0xc1, (byte) 0xdf, (byte) 0x72,
-            (byte) 0x6c, (byte) 0xfe, (byte) 0x29, (byte) 0xbe, (byte) 0xa3, (byte) 0x9b,
-            (byte) 0x0b, (byte) 0x5c, (byte) 0x0b, (byte) 0x9d, (byte) 0xa7, (byte) 0x71,
-            (byte) 0xce, (byte) 0x04, (byte) 0xfa, (byte) 0xac, (byte) 0x01, (byte) 0x8d,
-            (byte) 0x52, (byte) 0xa0, (byte) 0x3d, (byte) 0xdd, (byte) 0x02, (byte) 0x81,
-            (byte) 0xc1, (byte) 0x00, (byte) 0xc1, (byte) 0xc0, (byte) 0x2e, (byte) 0xa9,
-            (byte) 0xee, (byte) 0xca, (byte) 0xff, (byte) 0xe4, (byte) 0xf8, (byte) 0x15,
-            (byte) 0xfd, (byte) 0xa5, (byte) 0x68, (byte) 0x1b, (byte) 0x2d, (byte) 0x4a,
-            (byte) 0xe6, (byte) 0x37, (byte) 0x06, (byte) 0xb3, (byte) 0xd7, (byte) 0x64,
-            (byte) 0xad, (byte) 0xb9, (byte) 0x05, (byte) 0x26, (byte) 0x97, (byte) 0x94,
-            (byte) 0x3a, (byte) 0x9e, (byte) 0x1c, (byte) 0xd0, (byte) 0xcd, (byte) 0x7b,
-            (byte) 0xf4, (byte) 0x88, (byte) 0xe2, (byte) 0xa5, (byte) 0x6d, (byte) 0xed,
-            (byte) 0x24, (byte) 0x77, (byte) 0x52, (byte) 0x39, (byte) 0x43, (byte) 0x0f,
-            (byte) 0x4e, (byte) 0x75, (byte) 0xd8, (byte) 0xa3, (byte) 0x59, (byte) 0x5a,
-            (byte) 0xc2, (byte) 0xba, (byte) 0x9a, (byte) 0x5b, (byte) 0x60, (byte) 0x31,
-            (byte) 0x0d, (byte) 0x58, (byte) 0x89, (byte) 0x13, (byte) 0xe8, (byte) 0x95,
-            (byte) 0xdd, (byte) 0xae, (byte) 0xcc, (byte) 0x1f, (byte) 0x73, (byte) 0x48,
-            (byte) 0x55, (byte) 0xd8, (byte) 0xfb, (byte) 0x67, (byte) 0xce, (byte) 0x18,
-            (byte) 0x85, (byte) 0x59, (byte) 0xad, (byte) 0x1f, (byte) 0x93, (byte) 0xe1,
-            (byte) 0xb7, (byte) 0x54, (byte) 0x80, (byte) 0x8e, (byte) 0x5f, (byte) 0xbc,
-            (byte) 0x1c, (byte) 0x96, (byte) 0x66, (byte) 0x2e, (byte) 0x40, (byte) 0x17,
-            (byte) 0x2e, (byte) 0x01, (byte) 0x7a, (byte) 0x7d, (byte) 0xaa, (byte) 0xff,
-            (byte) 0xa3, (byte) 0xd2, (byte) 0xdf, (byte) 0xe2, (byte) 0xf3, (byte) 0x54,
-            (byte) 0x51, (byte) 0xeb, (byte) 0xba, (byte) 0x7c, (byte) 0x2a, (byte) 0x22,
-            (byte) 0xc6, (byte) 0x42, (byte) 0xbc, (byte) 0xa1, (byte) 0x6c, (byte) 0xcf,
-            (byte) 0x73, (byte) 0x2e, (byte) 0x07, (byte) 0xfc, (byte) 0xf5, (byte) 0x67,
-            (byte) 0x25, (byte) 0xd0, (byte) 0xfa, (byte) 0xeb, (byte) 0xb4, (byte) 0xd4,
-            (byte) 0x19, (byte) 0xcc, (byte) 0x64, (byte) 0xa1, (byte) 0x2e, (byte) 0x78,
-            (byte) 0x45, (byte) 0xd9, (byte) 0x7f, (byte) 0x1b, (byte) 0x4c, (byte) 0x10,
-            (byte) 0x31, (byte) 0x44, (byte) 0xe8, (byte) 0xcc, (byte) 0xf9, (byte) 0x1b,
-            (byte) 0x87, (byte) 0x31, (byte) 0xd6, (byte) 0x69, (byte) 0x85, (byte) 0x4a,
-            (byte) 0x49, (byte) 0xf6, (byte) 0xb2, (byte) 0xe0, (byte) 0xb8, (byte) 0x98,
-            (byte) 0x3c, (byte) 0xf6, (byte) 0x78, (byte) 0x46, (byte) 0xc8, (byte) 0x3d,
-            (byte) 0x60, (byte) 0xc1, (byte) 0xaa, (byte) 0x2f, (byte) 0x28, (byte) 0xa1,
-            (byte) 0x14, (byte) 0x6b, (byte) 0x75, (byte) 0x4d, (byte) 0xb1, (byte) 0x3d,
-            (byte) 0x80, (byte) 0x49, (byte) 0x33, (byte) 0xfd, (byte) 0x71, (byte) 0xc0,
-            (byte) 0x13, (byte) 0x1e, (byte) 0x16, (byte) 0x69, (byte) 0x80, (byte) 0xa4,
-            (byte) 0x9c, (byte) 0xd7, (byte) 0x02, (byte) 0x81, (byte) 0xc1, (byte) 0x00,
-            (byte) 0x8c, (byte) 0x33, (byte) 0x2d, (byte) 0xd9, (byte) 0xf3, (byte) 0x42,
-            (byte) 0x4d, (byte) 0xca, (byte) 0x5e, (byte) 0x60, (byte) 0x14, (byte) 0x10,
-            (byte) 0xf6, (byte) 0xf3, (byte) 0x71, (byte) 0x15, (byte) 0x88, (byte) 0x54,
-            (byte) 0x84, (byte) 0x21, (byte) 0x04, (byte) 0xb1, (byte) 0xaf, (byte) 0x02,
-            (byte) 0x11, (byte) 0x7f, (byte) 0x42, (byte) 0x3e, (byte) 0x86, (byte) 0xcb,
-            (byte) 0x6c, (byte) 0xf5, (byte) 0x57, (byte) 0x78, (byte) 0x4a, (byte) 0x03,
-            (byte) 0x9b, (byte) 0x80, (byte) 0xc2, (byte) 0x04, (byte) 0x3a, (byte) 0x6b,
-            (byte) 0xb3, (byte) 0x30, (byte) 0x31, (byte) 0x7e, (byte) 0xc3, (byte) 0x89,
-            (byte) 0x09, (byte) 0x4e, (byte) 0x86, (byte) 0x59, (byte) 0x41, (byte) 0xb5,
-            (byte) 0xae, (byte) 0xd5, (byte) 0xc6, (byte) 0x38, (byte) 0xbc, (byte) 0xd7,
-            (byte) 0xd7, (byte) 0x8e, (byte) 0xa3, (byte) 0x1a, (byte) 0xde, (byte) 0x32,
-            (byte) 0xad, (byte) 0x8d, (byte) 0x15, (byte) 0x81, (byte) 0xfe, (byte) 0xac,
-            (byte) 0xbd, (byte) 0xd0, (byte) 0xca, (byte) 0xbc, (byte) 0xd8, (byte) 0x6a,
-            (byte) 0xe1, (byte) 0xfe, (byte) 0xda, (byte) 0xc4, (byte) 0xd8, (byte) 0x62,
-            (byte) 0x71, (byte) 0x20, (byte) 0xa3, (byte) 0xd3, (byte) 0x06, (byte) 0x11,
-            (byte) 0xa9, (byte) 0x53, (byte) 0x7a, (byte) 0x44, (byte) 0x89, (byte) 0x3d,
-            (byte) 0x28, (byte) 0x5e, (byte) 0x7d, (byte) 0xf0, (byte) 0x60, (byte) 0xeb,
-            (byte) 0xb5, (byte) 0xdf, (byte) 0xed, (byte) 0x4f, (byte) 0x6d, (byte) 0x05,
-            (byte) 0x59, (byte) 0x06, (byte) 0xb0, (byte) 0x62, (byte) 0x50, (byte) 0x1c,
-            (byte) 0xb7, (byte) 0x2c, (byte) 0x44, (byte) 0xa4, (byte) 0x49, (byte) 0xf8,
-            (byte) 0x4f, (byte) 0x4b, (byte) 0xab, (byte) 0x71, (byte) 0x5b, (byte) 0xcb,
-            (byte) 0x31, (byte) 0x10, (byte) 0x41, (byte) 0xe0, (byte) 0x1a, (byte) 0x15,
-            (byte) 0xdc, (byte) 0x4c, (byte) 0x5d, (byte) 0x4f, (byte) 0x62, (byte) 0x83,
-            (byte) 0xa4, (byte) 0x80, (byte) 0x06, (byte) 0x36, (byte) 0xba, (byte) 0xc9,
-            (byte) 0xe2, (byte) 0xa4, (byte) 0x11, (byte) 0x98, (byte) 0x6b, (byte) 0x4c,
-            (byte) 0xe9, (byte) 0x90, (byte) 0x55, (byte) 0x18, (byte) 0xde, (byte) 0xe1,
-            (byte) 0x42, (byte) 0x38, (byte) 0x28, (byte) 0xa3, (byte) 0x54, (byte) 0x56,
-            (byte) 0x31, (byte) 0xaf, (byte) 0x5a, (byte) 0xd6, (byte) 0xf0, (byte) 0x26,
-            (byte) 0xe0, (byte) 0x7a, (byte) 0xd9, (byte) 0x6c, (byte) 0x64, (byte) 0xca,
-            (byte) 0x5d, (byte) 0x6d, (byte) 0x3d, (byte) 0x9a, (byte) 0xfe, (byte) 0x36,
-            (byte) 0x93, (byte) 0x9e, (byte) 0x62, (byte) 0x94, (byte) 0xc6, (byte) 0x07,
-            (byte) 0x83, (byte) 0x96, (byte) 0xd6, (byte) 0x27, (byte) 0xa6, (byte) 0xd8
-    };
-    public static final PrivateKey CLIENT_SUITE_B_RSA3072_KEY =
-            loadPrivateKey("RSA", CLIENT_SUITE_B_RSA3072_KEY_DATA);
-
-    private static final String CLIENT_SUITE_B_ECDSA_CERT_STRING =
-            "-----BEGIN CERTIFICATE-----\n"
-                    + "MIIB9zCCAX4CFDpfSZh3AH07BEfGWuMDa7Ynz6y+MAoGCCqGSM49BAMDMF4xCzAJ\n"
-                    + "BgNVBAYTAlVTMQswCQYDVQQIDAJDQTEMMAoGA1UEBwwDTVRWMRAwDgYDVQQKDAdB\n"
-                    + "bmRyb2lkMQ4wDAYDVQQLDAVXaS1GaTESMBAGA1UEAwwJdW5pdGVzdENBMB4XDTIw\n"
-                    + "MDcyMTAyMjk1MFoXDTMwMDUzMDAyMjk1MFowYjELMAkGA1UEBhMCVVMxCzAJBgNV\n"
-                    + "BAgMAkNBMQwwCgYDVQQHDANNVFYxEDAOBgNVBAoMB0FuZHJvaWQxDjAMBgNVBAsM\n"
-                    + "BVdpLUZpMRYwFAYDVQQDDA11bml0ZXN0Q2xpZW50MHYwEAYHKoZIzj0CAQYFK4EE\n"
-                    + "ACIDYgAEhxhVJ7dcSqrto0X+dgRxtd8BWG8cWmPjBji3MIxDLfpcMDoIB84ae1Ew\n"
-                    + "gJn4YUYHrWsUDiVNihv8j7a/Ol1qcIY2ybH7tbezefLmagqA4vXEUXZXoUyL4ZNC\n"
-                    + "DWcdw6LrMAoGCCqGSM49BAMDA2cAMGQCMH4aP73HrriRUJRguiuRic+X4Cqj/7YQ\n"
-                    + "ueJmP87KF92/thhoQ9OrRo8uJITPmNDswwIwP2Q1AZCSL4BI9dYrqu07Ar+pSkXE\n"
-                    + "R7oOqGdZR+d/MvXcFSrbIaLKEoHXmQamIHLe\n"
-                    + "-----END CERTIFICATE-----\n";
-    public static final X509Certificate CLIENT_SUITE_B_ECDSA_CERT =
-            loadCertificate(CLIENT_SUITE_B_ECDSA_CERT_STRING);
-
-    private static final byte[] CLIENT_SUITE_B_ECC_KEY_DATA = new byte[]{
-            (byte) 0x30, (byte) 0x81, (byte) 0xb6, (byte) 0x02, (byte) 0x01, (byte) 0x00,
-            (byte) 0x30, (byte) 0x10, (byte) 0x06, (byte) 0x07, (byte) 0x2a, (byte) 0x86,
-            (byte) 0x48, (byte) 0xce, (byte) 0x3d, (byte) 0x02, (byte) 0x01, (byte) 0x06,
-            (byte) 0x05, (byte) 0x2b, (byte) 0x81, (byte) 0x04, (byte) 0x00, (byte) 0x22,
-            (byte) 0x04, (byte) 0x81, (byte) 0x9e, (byte) 0x30, (byte) 0x81, (byte) 0x9b,
-            (byte) 0x02, (byte) 0x01, (byte) 0x01, (byte) 0x04, (byte) 0x30, (byte) 0xea,
-            (byte) 0x6c, (byte) 0x4b, (byte) 0x6d, (byte) 0x43, (byte) 0xf9, (byte) 0x6c,
-            (byte) 0x91, (byte) 0xdc, (byte) 0x2d, (byte) 0x6e, (byte) 0x87, (byte) 0x4f,
-            (byte) 0x0a, (byte) 0x0b, (byte) 0x97, (byte) 0x25, (byte) 0x1c, (byte) 0x79,
-            (byte) 0xa2, (byte) 0x07, (byte) 0xdc, (byte) 0x94, (byte) 0xc2, (byte) 0xee,
-            (byte) 0x64, (byte) 0x51, (byte) 0x6d, (byte) 0x4e, (byte) 0x35, (byte) 0x1c,
-            (byte) 0x22, (byte) 0x2f, (byte) 0xc0, (byte) 0xea, (byte) 0x09, (byte) 0x47,
-            (byte) 0x3e, (byte) 0xb9, (byte) 0xb6, (byte) 0xb8, (byte) 0x83, (byte) 0x9e,
-            (byte) 0xed, (byte) 0x59, (byte) 0xe5, (byte) 0xe7, (byte) 0x0f, (byte) 0xa1,
-            (byte) 0x64, (byte) 0x03, (byte) 0x62, (byte) 0x00, (byte) 0x04, (byte) 0x87,
-            (byte) 0x18, (byte) 0x55, (byte) 0x27, (byte) 0xb7, (byte) 0x5c, (byte) 0x4a,
-            (byte) 0xaa, (byte) 0xed, (byte) 0xa3, (byte) 0x45, (byte) 0xfe, (byte) 0x76,
-            (byte) 0x04, (byte) 0x71, (byte) 0xb5, (byte) 0xdf, (byte) 0x01, (byte) 0x58,
-            (byte) 0x6f, (byte) 0x1c, (byte) 0x5a, (byte) 0x63, (byte) 0xe3, (byte) 0x06,
-            (byte) 0x38, (byte) 0xb7, (byte) 0x30, (byte) 0x8c, (byte) 0x43, (byte) 0x2d,
-            (byte) 0xfa, (byte) 0x5c, (byte) 0x30, (byte) 0x3a, (byte) 0x08, (byte) 0x07,
-            (byte) 0xce, (byte) 0x1a, (byte) 0x7b, (byte) 0x51, (byte) 0x30, (byte) 0x80,
-            (byte) 0x99, (byte) 0xf8, (byte) 0x61, (byte) 0x46, (byte) 0x07, (byte) 0xad,
-            (byte) 0x6b, (byte) 0x14, (byte) 0x0e, (byte) 0x25, (byte) 0x4d, (byte) 0x8a,
-            (byte) 0x1b, (byte) 0xfc, (byte) 0x8f, (byte) 0xb6, (byte) 0xbf, (byte) 0x3a,
-            (byte) 0x5d, (byte) 0x6a, (byte) 0x70, (byte) 0x86, (byte) 0x36, (byte) 0xc9,
-            (byte) 0xb1, (byte) 0xfb, (byte) 0xb5, (byte) 0xb7, (byte) 0xb3, (byte) 0x79,
-            (byte) 0xf2, (byte) 0xe6, (byte) 0x6a, (byte) 0x0a, (byte) 0x80, (byte) 0xe2,
-            (byte) 0xf5, (byte) 0xc4, (byte) 0x51, (byte) 0x76, (byte) 0x57, (byte) 0xa1,
-            (byte) 0x4c, (byte) 0x8b, (byte) 0xe1, (byte) 0x93, (byte) 0x42, (byte) 0x0d,
-            (byte) 0x67, (byte) 0x1d, (byte) 0xc3, (byte) 0xa2, (byte) 0xeb
-    };
-    public static final PrivateKey CLIENT_SUITE_B_ECC_KEY =
-            loadPrivateKey("EC", CLIENT_SUITE_B_ECC_KEY_DATA);
-
-    private static X509Certificate loadCertificate(String blob) {
-        try {
-            final CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
-            InputStream stream = new ByteArrayInputStream(blob.getBytes(StandardCharsets.UTF_8));
-
-            return (X509Certificate) certFactory.generateCertificate(stream);
-        } catch (Exception e) {
-            e.printStackTrace();
-            return null;
-        }
-    }
-
-    private static PrivateKey loadPrivateKey(String algorithm, byte[] fakeKey) {
-        try {
-            KeyFactory kf = KeyFactory.getInstance(algorithm);
-            return kf.generatePrivate(new PKCS8EncodedKeySpec(fakeKey));
-        } catch (InvalidKeySpecException | NoSuchAlgorithmException e) {
-            return null;
-        }
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/ParcelUtilTest.java b/wifi/tests/src/android/net/wifi/ParcelUtilTest.java
deleted file mode 100644
index 917b1df..0000000
--- a/wifi/tests/src/android/net/wifi/ParcelUtilTest.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package android.net.wifi;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.security.PrivateKey;
-import java.security.cert.X509Certificate;
-
-/**
- * Unit tests for {@link android.net.wifi.ParcelUtil}.
- */
-@SmallTest
-public class ParcelUtilTest {
-    private Parcel mParcel;
-
-    @Before
-    public void setUp() throws Exception {
-        mParcel = Parcel.obtain();
-    }
-
-    @Test
-    public void readWriteNullPrivateKey() throws Exception {
-        ParcelUtil.writePrivateKey(mParcel, null);
-
-        mParcel.setDataPosition(0);    // Rewind data position back to the beginning for read.
-        PrivateKey readKey = ParcelUtil.readPrivateKey(mParcel);
-        assertNull(readKey);
-    }
-
-    @Test
-    public void readWriteValidPrivateKey() throws Exception {
-        PrivateKey writeKey = FakeKeys.RSA_KEY1;
-        ParcelUtil.writePrivateKey(mParcel, writeKey);
-
-        mParcel.setDataPosition(0);    // Rewind data position back to the beginning for read.
-        PrivateKey readKey = ParcelUtil.readPrivateKey(mParcel);
-        assertNotNull(readKey);
-        assertEquals(writeKey.getAlgorithm(), readKey.getAlgorithm());
-        assertArrayEquals(writeKey.getEncoded(), readKey.getEncoded());
-    }
-
-    @Test
-    public void readWriteNullCertificate() throws Exception {
-        ParcelUtil.writeCertificate(mParcel, null);
-
-        mParcel.setDataPosition(0);    // Rewind data position back to the beginning for read.
-        X509Certificate readCert = ParcelUtil.readCertificate(mParcel);
-        assertNull(readCert);
-    }
-
-    @Test
-    public void readWriteValidCertificate() throws Exception {
-        X509Certificate writeCert = FakeKeys.CA_CERT1;
-        ParcelUtil.writeCertificate(mParcel, writeCert);
-
-        mParcel.setDataPosition(0);    // Rewind data position back to the beginning for read.
-        X509Certificate readCert = ParcelUtil.readCertificate(mParcel);
-        assertNotNull(readCert);
-        assertArrayEquals(writeCert.getEncoded(), readCert.getEncoded());
-    }
-
-    @Test
-    public void readWriteNullCertificates() throws Exception {
-        ParcelUtil.writeCertificates(mParcel, null);
-
-        mParcel.setDataPosition(0);    // Rewind data position back to the beginning for read.
-        X509Certificate[] readCerts = ParcelUtil.readCertificates(mParcel);
-        assertNull(readCerts);
-    }
-
-    @Test
-    public void readWriteValidCertificates() throws Exception {
-        X509Certificate[] writeCerts = new X509Certificate[2];
-        writeCerts[0] = FakeKeys.CA_CERT0;
-        writeCerts[1] = FakeKeys.CA_CERT1;
-        ParcelUtil.writeCertificates(mParcel, writeCerts);
-
-        mParcel.setDataPosition(0);    // Rewind data position back to the beginning for read.
-        X509Certificate[] readCerts = ParcelUtil.readCertificates(mParcel);
-        assertNotNull(readCerts);
-        assertEquals(writeCerts.length, readCerts.length);
-        for (int i = 0; i < writeCerts.length; i++) {
-            assertNotNull(readCerts[i]);
-            assertArrayEquals(writeCerts[i].getEncoded(), readCerts[i].getEncoded());
-        }
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/ScanResultTest.java b/wifi/tests/src/android/net/wifi/ScanResultTest.java
deleted file mode 100644
index f1ec5e8..0000000
--- a/wifi/tests/src/android/net/wifi/ScanResultTest.java
+++ /dev/null
@@ -1,301 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.mockito.Mockito.validateMockitoUsage;
-
-import android.net.wifi.ScanResult.InformationElement;
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.MockitoAnnotations;
-
-/**
- * Unit tests for {@link android.net.wifi.WifiScanner}.
- */
-@SmallTest
-public class ScanResultTest {
-    public static final String TEST_SSID = "\"test_ssid\"";
-    public static final String TEST_BSSID = "04:ac:fe:45:34:10";
-    public static final String TEST_CAPS = "CCMP";
-    public static final int TEST_LEVEL = -56;
-    public static final int TEST_FREQUENCY = 2412;
-    public static final long TEST_TSF = 04660l;
-    public static final @WifiAnnotations.WifiStandard int TEST_WIFI_STANDARD =
-            ScanResult.WIFI_STANDARD_11AC;
-
-    /**
-     * Frequency to channel map. This include some frequencies used outside the US.
-     * Representing it using a vector (instead of map) for simplification.
-     */
-    private static final int[] FREQUENCY_TO_CHANNEL_MAP = {
-            2412, WifiScanner.WIFI_BAND_24_GHZ, 1,
-            2417, WifiScanner.WIFI_BAND_24_GHZ, 2,
-            2422, WifiScanner.WIFI_BAND_24_GHZ, 3,
-            2427, WifiScanner.WIFI_BAND_24_GHZ, 4,
-            2432, WifiScanner.WIFI_BAND_24_GHZ, 5,
-            2437, WifiScanner.WIFI_BAND_24_GHZ, 6,
-            2442, WifiScanner.WIFI_BAND_24_GHZ, 7,
-            2447, WifiScanner.WIFI_BAND_24_GHZ, 8,
-            2452, WifiScanner.WIFI_BAND_24_GHZ, 9,
-            2457, WifiScanner.WIFI_BAND_24_GHZ, 10,
-            2462, WifiScanner.WIFI_BAND_24_GHZ, 11,
-            /* 12, 13 are only legitimate outside the US. */
-            2467, WifiScanner.WIFI_BAND_24_GHZ, 12,
-            2472, WifiScanner.WIFI_BAND_24_GHZ, 13,
-            /* 14 is for Japan, DSSS and CCK only. */
-            2484, WifiScanner.WIFI_BAND_24_GHZ, 14,
-            /* 34 valid in Japan. */
-            5170, WifiScanner.WIFI_BAND_5_GHZ, 34,
-            5180, WifiScanner.WIFI_BAND_5_GHZ, 36,
-            5190, WifiScanner.WIFI_BAND_5_GHZ, 38,
-            5200, WifiScanner.WIFI_BAND_5_GHZ, 40,
-            5210, WifiScanner.WIFI_BAND_5_GHZ, 42,
-            5220, WifiScanner.WIFI_BAND_5_GHZ, 44,
-            5230, WifiScanner.WIFI_BAND_5_GHZ, 46,
-            5240, WifiScanner.WIFI_BAND_5_GHZ, 48,
-            5260, WifiScanner.WIFI_BAND_5_GHZ, 52,
-            5280, WifiScanner.WIFI_BAND_5_GHZ, 56,
-            5300, WifiScanner.WIFI_BAND_5_GHZ, 60,
-            5320, WifiScanner.WIFI_BAND_5_GHZ, 64,
-            5500, WifiScanner.WIFI_BAND_5_GHZ, 100,
-            5520, WifiScanner.WIFI_BAND_5_GHZ, 104,
-            5540, WifiScanner.WIFI_BAND_5_GHZ, 108,
-            5560, WifiScanner.WIFI_BAND_5_GHZ, 112,
-            5580, WifiScanner.WIFI_BAND_5_GHZ, 116,
-            /* 120, 124, 128 valid in Europe/Japan. */
-            5600, WifiScanner.WIFI_BAND_5_GHZ, 120,
-            5620, WifiScanner.WIFI_BAND_5_GHZ, 124,
-            5640, WifiScanner.WIFI_BAND_5_GHZ, 128,
-            /* 132+ valid in US. */
-            5660, WifiScanner.WIFI_BAND_5_GHZ, 132,
-            5680, WifiScanner.WIFI_BAND_5_GHZ, 136,
-            5700, WifiScanner.WIFI_BAND_5_GHZ, 140,
-            /* 144 is supported by a subset of WiFi chips. */
-            5720, WifiScanner.WIFI_BAND_5_GHZ, 144,
-            5745, WifiScanner.WIFI_BAND_5_GHZ, 149,
-            5765, WifiScanner.WIFI_BAND_5_GHZ, 153,
-            5785, WifiScanner.WIFI_BAND_5_GHZ, 157,
-            5805, WifiScanner.WIFI_BAND_5_GHZ, 161,
-            5825, WifiScanner.WIFI_BAND_5_GHZ, 165,
-            5845, WifiScanner.WIFI_BAND_5_GHZ, 169,
-            5865, WifiScanner.WIFI_BAND_5_GHZ, 173,
-            /* Now some 6GHz channels */
-            5955, WifiScanner.WIFI_BAND_6_GHZ, 1,
-            5935, WifiScanner.WIFI_BAND_6_GHZ, 2,
-            5970, WifiScanner.WIFI_BAND_6_GHZ, 4,
-            6110, WifiScanner.WIFI_BAND_6_GHZ, 32
-    };
-
-    /**
-     * Setup before tests.
-     */
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-    }
-
-    /**
-     * Clean up after tests.
-     */
-    @After
-    public void cleanup() {
-        validateMockitoUsage();
-    }
-
-    /**
-     * Verify parcel read/write for ScanResult.
-     */
-    @Test
-    public void verifyScanResultParcelWithoutRadioChainInfo() throws Exception {
-        ScanResult writeScanResult = createScanResult();
-        ScanResult readScanResult = parcelReadWrite(writeScanResult);
-        assertScanResultEquals(writeScanResult, readScanResult);
-    }
-
-    /**
-     * Verify parcel read/write for ScanResult.
-     */
-    @Test
-    public void verifyScanResultParcelWithZeroRadioChainInfo() throws Exception {
-        ScanResult writeScanResult = createScanResult();
-        writeScanResult.radioChainInfos = new ScanResult.RadioChainInfo[0];
-        ScanResult readScanResult = parcelReadWrite(writeScanResult);
-        assertNull(readScanResult.radioChainInfos);
-    }
-
-    /**
-     * Verify parcel read/write for ScanResult.
-     */
-    @Test
-    public void verifyScanResultParcelWithRadioChainInfo() throws Exception {
-        ScanResult writeScanResult = createScanResult();
-        writeScanResult.radioChainInfos = new ScanResult.RadioChainInfo[2];
-        writeScanResult.radioChainInfos[0] = new ScanResult.RadioChainInfo();
-        writeScanResult.radioChainInfos[0].id = 0;
-        writeScanResult.radioChainInfos[0].level = -45;
-        writeScanResult.radioChainInfos[1] = new ScanResult.RadioChainInfo();
-        writeScanResult.radioChainInfos[1].id = 1;
-        writeScanResult.radioChainInfos[1].level = -54;
-        ScanResult readScanResult = parcelReadWrite(writeScanResult);
-        assertScanResultEquals(writeScanResult, readScanResult);
-    }
-
-    /**
-     * Verify copy constructor for ScanResult.
-     */
-    @Test
-    public void verifyScanResultCopyWithoutRadioChainInfo() throws Exception {
-        ScanResult scanResult = createScanResult();
-        ScanResult copyScanResult = new ScanResult(scanResult);
-        assertScanResultEquals(scanResult, copyScanResult);
-    }
-
-    /**
-     * Verify copy constructor for ScanResult.
-     */
-    @Test
-    public void verifyScanResultCopyWithRadioChainInfo() throws Exception {
-        ScanResult scanResult = createScanResult();
-        scanResult.radioChainInfos = new ScanResult.RadioChainInfo[2];
-        scanResult.radioChainInfos[0] = new ScanResult.RadioChainInfo();
-        scanResult.radioChainInfos[0].id = 0;
-        scanResult.radioChainInfos[0].level = -45;
-        scanResult.radioChainInfos[1] = new ScanResult.RadioChainInfo();
-        scanResult.radioChainInfos[1].id = 1;
-        scanResult.radioChainInfos[1].level = -54;
-        ScanResult copyScanResult = new ScanResult(scanResult);
-        assertScanResultEquals(scanResult, copyScanResult);
-    }
-
-    /**
-     * Verify parcel read/write for ScanResult with Information Element
-     */
-    @Test
-    public void verifyScanResultParcelWithInformationElement() throws Exception {
-        ScanResult writeScanResult = createScanResult();
-        writeScanResult.informationElements = new ScanResult.InformationElement[2];
-        writeScanResult.informationElements[0] = new ScanResult.InformationElement();
-        writeScanResult.informationElements[0].id = InformationElement.EID_HT_OPERATION;
-        writeScanResult.informationElements[0].idExt = 0;
-        writeScanResult.informationElements[0].bytes = new byte[]{0x11, 0x22, 0x33};
-        writeScanResult.informationElements[1] = new ScanResult.InformationElement();
-        writeScanResult.informationElements[1].id = InformationElement.EID_EXTENSION_PRESENT;
-        writeScanResult.informationElements[1].idExt = InformationElement.EID_EXT_HE_OPERATION;
-        writeScanResult.informationElements[1].bytes = new byte[]{0x44, 0x55, 0x66};
-        ScanResult readScanResult = new ScanResult(writeScanResult);
-        assertScanResultEquals(writeScanResult, readScanResult);
-    }
-
-    /**
-     * Verify toString for ScanResult.
-     */
-    @Test
-    public void verifyScanResultToStringWithoutRadioChainInfo() throws Exception {
-        ScanResult scanResult = createScanResult();
-        assertEquals("SSID: \"test_ssid\", BSSID: 04:ac:fe:45:34:10, capabilities: CCMP, "
-                + "level: -56, frequency: 2412, timestamp: 2480, "
-                + "distance: 0(cm), distanceSd: 0(cm), "
-                + "passpoint: no, ChannelBandwidth: 0, centerFreq0: 0, centerFreq1: 0, "
-                + "standard: 11ac, "
-                + "80211mcResponder: is not supported, "
-                + "Radio Chain Infos: null", scanResult.toString());
-    }
-
-    /**
-     * Verify toString for ScanResult.
-     */
-    @Test
-    public void verifyScanResultToStringWithRadioChainInfo() throws Exception {
-        ScanResult scanResult = createScanResult();
-        scanResult.radioChainInfos = new ScanResult.RadioChainInfo[2];
-        scanResult.radioChainInfos[0] = new ScanResult.RadioChainInfo();
-        scanResult.radioChainInfos[0].id = 0;
-        scanResult.radioChainInfos[0].level = -45;
-        scanResult.radioChainInfos[1] = new ScanResult.RadioChainInfo();
-        scanResult.radioChainInfos[1].id = 1;
-        scanResult.radioChainInfos[1].level = -54;
-        assertEquals("SSID: \"test_ssid\", BSSID: 04:ac:fe:45:34:10, capabilities: CCMP, "
-                + "level: -56, frequency: 2412, timestamp: 2480, distance: 0(cm), "
-                + "distanceSd: 0(cm), "
-                + "passpoint: no, ChannelBandwidth: 0, centerFreq0: 0, centerFreq1: 0, "
-                + "standard: 11ac, "
-                + "80211mcResponder: is not supported, "
-                + "Radio Chain Infos: [RadioChainInfo: id=0, level=-45, "
-                + "RadioChainInfo: id=1, level=-54]", scanResult.toString());
-    }
-
-    /**
-     * verify frequency to channel conversion for all possible frequencies.
-     */
-    @Test
-    public void convertFrequencyToChannel() throws Exception {
-        for (int i = 0; i < FREQUENCY_TO_CHANNEL_MAP.length; i += 3) {
-            assertEquals(FREQUENCY_TO_CHANNEL_MAP[i + 2],
-                    ScanResult.convertFrequencyMhzToChannel(FREQUENCY_TO_CHANNEL_MAP[i]));
-        }
-    }
-
-    /**
-     * Verify frequency to channel conversion failed for an invalid frequency.
-     */
-    @Test
-    public void convertFrequencyToChannelWithInvalidFreq() throws Exception {
-        assertEquals(-1, ScanResult.convertFrequencyMhzToChannel(8000));
-    }
-
-    /**
-     * Write the provided {@link ScanResult} to a parcel and deserialize it.
-     */
-    private static ScanResult parcelReadWrite(ScanResult writeResult) throws Exception {
-        Parcel parcel = Parcel.obtain();
-        writeResult.writeToParcel(parcel, 0);
-        parcel.setDataPosition(0);    // Rewind data position back to the beginning for read.
-        return ScanResult.CREATOR.createFromParcel(parcel);
-    }
-
-    private static ScanResult createScanResult() {
-        ScanResult result = new ScanResult();
-        result.wifiSsid = WifiSsid.createFromAsciiEncoded(TEST_SSID);
-        result.BSSID = TEST_BSSID;
-        result.capabilities = TEST_CAPS;
-        result.level = TEST_LEVEL;
-        result.frequency = TEST_FREQUENCY;
-        result.timestamp = TEST_TSF;
-        result.setWifiStandard(TEST_WIFI_STANDARD);
-        return result;
-    }
-
-    private static void assertScanResultEquals(ScanResult expected, ScanResult actual) {
-        assertEquals(expected.SSID, actual.SSID);
-        assertEquals(expected.BSSID, actual.BSSID);
-        assertEquals(expected.capabilities, actual.capabilities);
-        assertEquals(expected.level, actual.level);
-        assertEquals(expected.frequency, actual.frequency);
-        assertEquals(expected.timestamp, actual.timestamp);
-        assertEquals(expected.getWifiStandard(), actual.getWifiStandard());
-        assertArrayEquals(expected.radioChainInfos, actual.radioChainInfos);
-        assertArrayEquals(expected.informationElements, actual.informationElements);
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/SoftApCapabilityTest.java b/wifi/tests/src/android/net/wifi/SoftApCapabilityTest.java
deleted file mode 100644
index 73b501a..0000000
--- a/wifi/tests/src/android/net/wifi/SoftApCapabilityTest.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import android.os.Parcel;
-
-import static org.junit.Assert.assertEquals;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-/**
- * Unit tests for {@link android.net.wifi.SoftApCapability}.
- */
-@SmallTest
-public class SoftApCapabilityTest {
-
-    /**
-     * Verifies copy constructor.
-     */
-    @Test
-    public void testCopyOperator() throws Exception {
-        long testSoftApFeature = SoftApCapability.SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT
-                | SoftApCapability.SOFTAP_FEATURE_ACS_OFFLOAD;
-        SoftApCapability capability = new SoftApCapability(testSoftApFeature);
-        capability.setMaxSupportedClients(10);
-
-        SoftApCapability copiedCapability = new SoftApCapability(capability);
-
-        assertEquals(capability, copiedCapability);
-        assertEquals(capability.hashCode(), copiedCapability.hashCode());
-    }
-
-    /**
-     * Verifies parcel serialization/deserialization.
-     */
-    @Test
-    public void testParcelOperation() throws Exception {
-        long testSoftApFeature = SoftApCapability.SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT
-                | SoftApCapability.SOFTAP_FEATURE_ACS_OFFLOAD;
-        SoftApCapability capability = new SoftApCapability(testSoftApFeature);
-        capability.setMaxSupportedClients(10);
-
-        Parcel parcelW = Parcel.obtain();
-        capability.writeToParcel(parcelW, 0);
-        byte[] bytes = parcelW.marshall();
-        parcelW.recycle();
-
-        Parcel parcelR = Parcel.obtain();
-        parcelR.unmarshall(bytes, 0, bytes.length);
-        parcelR.setDataPosition(0);
-        SoftApCapability fromParcel = SoftApCapability.CREATOR.createFromParcel(parcelR);
-
-        assertEquals(capability, fromParcel);
-        assertEquals(capability.hashCode(), fromParcel.hashCode());
-    }
-
-}
diff --git a/wifi/non-updatable/tests/src/android/net/wifi/SoftApConfToXmlMigrationUtilTest.java b/wifi/tests/src/android/net/wifi/SoftApConfToXmlMigrationUtilTest.java
similarity index 100%
rename from wifi/non-updatable/tests/src/android/net/wifi/SoftApConfToXmlMigrationUtilTest.java
rename to wifi/tests/src/android/net/wifi/SoftApConfToXmlMigrationUtilTest.java
diff --git a/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java b/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java
deleted file mode 100644
index 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 311bbc4..0000000
--- a/wifi/tests/src/android/net/wifi/WifiInfoTest.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNotSame;
-import static org.junit.Assert.assertTrue;
-
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-import java.nio.charset.StandardCharsets;
-
-/**
- * Unit tests for {@link android.net.wifi.WifiInfo}.
- */
-@SmallTest
-public class WifiInfoTest {
-    private static final long TEST_TX_SUCCESS = 1;
-    private static final long TEST_TX_RETRIES = 2;
-    private static final long TEST_TX_BAD = 3;
-    private static final long TEST_RX_SUCCESS = 4;
-    private static final String TEST_PACKAGE_NAME = "com.test.example";
-    private static final String TEST_FQDN = "test.com";
-    private static final String TEST_PROVIDER_NAME = "test";
-    private static final int TEST_WIFI_STANDARD = ScanResult.WIFI_STANDARD_11AC;
-    private static final int TEST_MAX_SUPPORTED_TX_LINK_SPEED_MBPS = 866;
-    private static final int TEST_MAX_SUPPORTED_RX_LINK_SPEED_MBPS = 1200;
-    private static final String TEST_SSID = "Test123";
-    private static final String TEST_BSSID = "12:12:12:12:12:12";
-    private static final int TEST_RSSI = -60;
-    private static final int TEST_NETWORK_ID = 5;
-    private static final int TEST_NETWORK_ID2 = 6;
-
-    /**
-     *  Verify parcel write/read with WifiInfo.
-     */
-    @Test
-    public void testWifiInfoParcelWriteRead() throws Exception {
-        WifiInfo writeWifiInfo = new WifiInfo();
-        writeWifiInfo.txSuccess = TEST_TX_SUCCESS;
-        writeWifiInfo.txRetries = TEST_TX_RETRIES;
-        writeWifiInfo.txBad = TEST_TX_BAD;
-        writeWifiInfo.rxSuccess = TEST_RX_SUCCESS;
-        writeWifiInfo.setTrusted(true);
-        writeWifiInfo.setOsuAp(true);
-        writeWifiInfo.setFQDN(TEST_FQDN);
-        writeWifiInfo.setProviderFriendlyName(TEST_PROVIDER_NAME);
-        writeWifiInfo.setRequestingPackageName(TEST_PACKAGE_NAME);
-        writeWifiInfo.setWifiStandard(TEST_WIFI_STANDARD);
-        writeWifiInfo.setMaxSupportedTxLinkSpeedMbps(TEST_MAX_SUPPORTED_TX_LINK_SPEED_MBPS);
-        writeWifiInfo.setMaxSupportedRxLinkSpeedMbps(TEST_MAX_SUPPORTED_RX_LINK_SPEED_MBPS);
-
-        Parcel parcel = Parcel.obtain();
-        writeWifiInfo.writeToParcel(parcel, 0);
-        // Rewind the pointer to the head of the parcel.
-        parcel.setDataPosition(0);
-        WifiInfo readWifiInfo = WifiInfo.CREATOR.createFromParcel(parcel);
-
-        assertNotNull(readWifiInfo);
-        assertEquals(TEST_TX_SUCCESS, readWifiInfo.txSuccess);
-        assertEquals(TEST_TX_RETRIES, readWifiInfo.txRetries);
-        assertEquals(TEST_TX_BAD, readWifiInfo.txBad);
-        assertEquals(TEST_RX_SUCCESS, readWifiInfo.rxSuccess);
-        assertTrue(readWifiInfo.isTrusted());
-        assertTrue(readWifiInfo.isOsuAp());
-        assertTrue(readWifiInfo.isPasspointAp());
-        assertEquals(TEST_PACKAGE_NAME, readWifiInfo.getRequestingPackageName());
-        assertEquals(TEST_FQDN, readWifiInfo.getPasspointFqdn());
-        assertEquals(TEST_PROVIDER_NAME, readWifiInfo.getPasspointProviderFriendlyName());
-        assertEquals(TEST_WIFI_STANDARD, readWifiInfo.getWifiStandard());
-        assertEquals(TEST_MAX_SUPPORTED_TX_LINK_SPEED_MBPS,
-                readWifiInfo.getMaxSupportedTxLinkSpeedMbps());
-        assertEquals(TEST_MAX_SUPPORTED_RX_LINK_SPEED_MBPS,
-                readWifiInfo.getMaxSupportedRxLinkSpeedMbps());
-    }
-
-    /**
-     *  Verify values after reset()
-     */
-    @Test
-    public void testWifiInfoResetValue() throws Exception {
-        WifiInfo wifiInfo = new WifiInfo();
-        wifiInfo.reset();
-        assertEquals(WifiInfo.LINK_SPEED_UNKNOWN, wifiInfo.getMaxSupportedTxLinkSpeedMbps());
-        assertEquals(WifiInfo.LINK_SPEED_UNKNOWN, wifiInfo.getMaxSupportedRxLinkSpeedMbps());
-        assertEquals(WifiInfo.LINK_SPEED_UNKNOWN, wifiInfo.getTxLinkSpeedMbps());
-        assertEquals(WifiInfo.LINK_SPEED_UNKNOWN, wifiInfo.getRxLinkSpeedMbps());
-        assertEquals(WifiInfo.INVALID_RSSI, wifiInfo.getRssi());
-        assertEquals(WifiManager.UNKNOWN_SSID, wifiInfo.getSSID());
-        assertEquals(null, wifiInfo.getBSSID());
-        assertEquals(-1, wifiInfo.getNetworkId());
-    }
-
-    /**
-     * Test that the WifiInfo Builder returns the same values that was set, and that
-     * calling build multiple times returns different instances.
-     */
-    @Test
-    public void testWifiInfoBuilder() throws Exception {
-        WifiInfo.Builder builder = new WifiInfo.Builder()
-                .setSsid(TEST_SSID.getBytes(StandardCharsets.UTF_8))
-                .setBssid(TEST_BSSID)
-                .setRssi(TEST_RSSI)
-                .setNetworkId(TEST_NETWORK_ID);
-
-        WifiInfo info1 = builder.build();
-
-        assertEquals("\"" + TEST_SSID + "\"", info1.getSSID());
-        assertEquals(TEST_BSSID, info1.getBSSID());
-        assertEquals(TEST_RSSI, info1.getRssi());
-        assertEquals(TEST_NETWORK_ID, info1.getNetworkId());
-
-        WifiInfo info2 = builder
-                .setNetworkId(TEST_NETWORK_ID2)
-                .build();
-
-        // different instances
-        assertNotSame(info1, info2);
-
-        // assert that info1 didn't change
-        assertEquals("\"" + TEST_SSID + "\"", info1.getSSID());
-        assertEquals(TEST_BSSID, info1.getBSSID());
-        assertEquals(TEST_RSSI, info1.getRssi());
-        assertEquals(TEST_NETWORK_ID, info1.getNetworkId());
-
-        // assert that info2 changed
-        assertEquals("\"" + TEST_SSID + "\"", info2.getSSID());
-        assertEquals(TEST_BSSID, info2.getBSSID());
-        assertEquals(TEST_RSSI, info2.getRssi());
-        assertEquals(TEST_NETWORK_ID2, info2.getNetworkId());
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
deleted file mode 100644
index 1398bfe..0000000
--- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java
+++ /dev/null
@@ -1,2389 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import static android.net.wifi.WifiConfiguration.METERED_OVERRIDE_METERED;
-import static android.net.wifi.WifiManager.ActionListener;
-import static android.net.wifi.WifiManager.BUSY;
-import static android.net.wifi.WifiManager.ERROR;
-import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_GENERIC;
-import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_INCOMPATIBLE_MODE;
-import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_NO_CHANNEL;
-import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_TETHERING_DISALLOWED;
-import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.REQUEST_REGISTERED;
-import static android.net.wifi.WifiManager.NOT_AUTHORIZED;
-import static android.net.wifi.WifiManager.OnWifiActivityEnergyInfoListener;
-import static android.net.wifi.WifiManager.SAP_START_FAILURE_GENERAL;
-import static android.net.wifi.WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS;
-import static android.net.wifi.WifiManager.STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION;
-import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED;
-import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLING;
-import static android.net.wifi.WifiManager.WIFI_AP_STATE_FAILED;
-import static android.net.wifi.WifiManager.WIFI_FEATURE_DPP;
-import static android.net.wifi.WifiManager.WIFI_FEATURE_OWE;
-import static android.net.wifi.WifiManager.WIFI_FEATURE_P2P;
-import static android.net.wifi.WifiManager.WIFI_FEATURE_PASSPOINT;
-import static android.net.wifi.WifiManager.WIFI_FEATURE_SCANNER;
-import static android.net.wifi.WifiManager.WIFI_FEATURE_WPA3_SAE;
-import static android.net.wifi.WifiManager.WIFI_FEATURE_WPA3_SUITE_B;
-import static android.net.wifi.WifiManager.WpsCallback;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.nullable;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.anyInt;
-import static org.mockito.Mockito.anyList;
-import static org.mockito.Mockito.anyString;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
-
-import android.app.ActivityManager;
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.net.DhcpInfo;
-import android.net.MacAddress;
-import android.net.wifi.WifiManager.LocalOnlyHotspotCallback;
-import android.net.wifi.WifiManager.LocalOnlyHotspotObserver;
-import android.net.wifi.WifiManager.LocalOnlyHotspotReservation;
-import android.net.wifi.WifiManager.LocalOnlyHotspotSubscription;
-import android.net.wifi.WifiManager.NetworkRequestMatchCallback;
-import android.net.wifi.WifiManager.NetworkRequestUserSelectionCallback;
-import android.net.wifi.WifiManager.OnWifiUsabilityStatsListener;
-import android.net.wifi.WifiManager.ScanResultsCallback;
-import android.net.wifi.WifiManager.SoftApCallback;
-import android.net.wifi.WifiManager.SuggestionConnectionStatusListener;
-import android.net.wifi.WifiManager.TrafficStateCallback;
-import android.net.wifi.WifiManager.WifiConnectedNetworkScorer;
-import android.os.Binder;
-import android.os.Build;
-import android.os.Handler;
-import android.os.HandlerExecutor;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.os.connectivity.WifiActivityEnergyInfo;
-import android.os.test.TestLooper;
-import android.util.SparseArray;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.InOrder;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.concurrent.Executor;
-
-/**
- * Unit tests for {@link android.net.wifi.WifiManager}.
- */
-@SmallTest
-public class WifiManagerTest {
-
-    private static final int ERROR_NOT_SET = -1;
-    private static final int ERROR_TEST_REASON = 5;
-    private static final int TEST_UID = 14553;
-    private static final int TEST_NETWORK_ID = 143;
-    private static final String TEST_PACKAGE_NAME = "TestPackage";
-    private static final String TEST_FEATURE_ID = "TestFeature";
-    private static final String TEST_COUNTRY_CODE = "US";
-    private static final String[] TEST_MAC_ADDRESSES = {"da:a1:19:0:0:0"};
-    private static final int TEST_AP_FREQUENCY = 2412;
-    private static final int TEST_AP_BANDWIDTH = SoftApInfo.CHANNEL_WIDTH_20MHZ;
-
-    @Mock Context mContext;
-    @Mock android.net.wifi.IWifiManager mWifiService;
-    @Mock ApplicationInfo mApplicationInfo;
-    @Mock WifiConfiguration mApConfig;
-    @Mock SoftApCallback mSoftApCallback;
-    @Mock TrafficStateCallback mTrafficStateCallback;
-    @Mock NetworkRequestMatchCallback mNetworkRequestMatchCallback;
-    @Mock OnWifiUsabilityStatsListener mOnWifiUsabilityStatsListener;
-    @Mock OnWifiActivityEnergyInfoListener mOnWifiActivityEnergyInfoListener;
-    @Mock SuggestionConnectionStatusListener mListener;
-    @Mock Runnable mRunnable;
-    @Mock Executor mExecutor;
-    @Mock Executor mAnotherExecutor;
-    @Mock ActivityManager mActivityManager;
-    @Mock WifiConnectedNetworkScorer mWifiConnectedNetworkScorer;
-
-    private Handler mHandler;
-    private TestLooper mLooper;
-    private WifiManager mWifiManager;
-    private WifiNetworkSuggestion mWifiNetworkSuggestion;
-    private ScanResultsCallback mScanResultsCallback;
-    private WifiActivityEnergyInfo mWifiActivityEnergyInfo;
-
-    /**
-     * Util function to check public field which used for softap  in WifiConfiguration
-     * same as the value in SoftApConfiguration.
-     *
-     */
-    private boolean compareWifiAndSoftApConfiguration(
-            SoftApConfiguration softApConfig, WifiConfiguration wifiConfig) {
-        if (!Objects.equals(wifiConfig.SSID, softApConfig.getSsid())) {
-            return false;
-        }
-        if (!Objects.equals(wifiConfig.BSSID, softApConfig.getBssid())) {
-            return false;
-        }
-        if (!Objects.equals(wifiConfig.preSharedKey, softApConfig.getPassphrase())) {
-            return false;
-        }
-
-        if (wifiConfig.hiddenSSID != softApConfig.isHiddenSsid()) {
-            return false;
-        }
-        switch (softApConfig.getSecurityType()) {
-            case SoftApConfiguration.SECURITY_TYPE_OPEN:
-                if (wifiConfig.getAuthType() != WifiConfiguration.KeyMgmt.NONE) {
-                    return false;
-                }
-                break;
-            case SoftApConfiguration.SECURITY_TYPE_WPA2_PSK:
-                if (wifiConfig.getAuthType() != WifiConfiguration.KeyMgmt.WPA2_PSK) {
-                    return false;
-                }
-                break;
-            default:
-                return false;
-        }
-        return true;
-    }
-
-    private SoftApConfiguration generatorTestSoftApConfig() {
-        return new SoftApConfiguration.Builder()
-                .setSsid("TestSSID")
-                .setPassphrase("TestPassphrase", SoftApConfiguration.SECURITY_TYPE_WPA2_PSK)
-                .build();
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-        mLooper = new TestLooper();
-        mHandler = spy(new Handler(mLooper.getLooper()));
-        mApplicationInfo.targetSdkVersion = Build.VERSION_CODES.Q;
-        when(mContext.getApplicationInfo()).thenReturn(mApplicationInfo);
-        when(mContext.getOpPackageName()).thenReturn(TEST_PACKAGE_NAME);
-        mWifiManager = new WifiManager(mContext, mWifiService, mLooper.getLooper());
-        verify(mWifiService).getVerboseLoggingLevel();
-        mWifiNetworkSuggestion = new WifiNetworkSuggestion();
-        mScanResultsCallback = new ScanResultsCallback() {
-            @Override
-            public void onScanResultsAvailable() {
-                mRunnable.run();
-            }
-        };
-        mWifiActivityEnergyInfo = new WifiActivityEnergyInfo(0, 0, 0, 0, 0, 0);
-    }
-
-    /**
-     * Check the call to startSoftAp calls WifiService to startSoftAp with the provided
-     * WifiConfiguration.  Verify that the return value is propagated to the caller.
-     */
-    @Test
-    public void testStartSoftApCallsServiceWithWifiConfig() throws Exception {
-        when(mWifiService.startSoftAp(eq(mApConfig))).thenReturn(true);
-        assertTrue(mWifiManager.startSoftAp(mApConfig));
-
-        when(mWifiService.startSoftAp(eq(mApConfig))).thenReturn(false);
-        assertFalse(mWifiManager.startSoftAp(mApConfig));
-    }
-
-    /**
-     * Check the call to startSoftAp calls WifiService to startSoftAp with a null config.  Verify
-     * that the return value is propagated to the caller.
-     */
-    @Test
-    public void testStartSoftApCallsServiceWithNullConfig() throws Exception {
-        when(mWifiService.startSoftAp(eq(null))).thenReturn(true);
-        assertTrue(mWifiManager.startSoftAp(null));
-
-        when(mWifiService.startSoftAp(eq(null))).thenReturn(false);
-        assertFalse(mWifiManager.startSoftAp(null));
-    }
-
-    /**
-     * Check the call to stopSoftAp calls WifiService to stopSoftAp.
-     */
-    @Test
-    public void testStopSoftApCallsService() throws Exception {
-        when(mWifiService.stopSoftAp()).thenReturn(true);
-        assertTrue(mWifiManager.stopSoftAp());
-
-        when(mWifiService.stopSoftAp()).thenReturn(false);
-        assertFalse(mWifiManager.stopSoftAp());
-    }
-
-    /**
-     * Check the call to startSoftAp calls WifiService to startSoftAp with the provided
-     * WifiConfiguration.  Verify that the return value is propagated to the caller.
-     */
-    @Test
-    public void testStartTetheredHotspotCallsServiceWithSoftApConfig() throws Exception {
-        SoftApConfiguration softApConfig = generatorTestSoftApConfig();
-        when(mWifiService.startTetheredHotspot(eq(softApConfig))).thenReturn(true);
-        assertTrue(mWifiManager.startTetheredHotspot(softApConfig));
-
-        when(mWifiService.startTetheredHotspot(eq(softApConfig))).thenReturn(false);
-        assertFalse(mWifiManager.startTetheredHotspot(softApConfig));
-    }
-
-    /**
-     * Check the call to startSoftAp calls WifiService to startSoftAp with a null config.  Verify
-     * that the return value is propagated to the caller.
-     */
-    @Test
-    public void testStartTetheredHotspotCallsServiceWithNullConfig() throws Exception {
-        when(mWifiService.startTetheredHotspot(eq(null))).thenReturn(true);
-        assertTrue(mWifiManager.startTetheredHotspot(null));
-
-        when(mWifiService.startTetheredHotspot(eq(null))).thenReturn(false);
-        assertFalse(mWifiManager.startTetheredHotspot(null));
-    }
-
-    /**
-     * Test creation of a LocalOnlyHotspotReservation and verify that close properly calls
-     * WifiService.stopLocalOnlyHotspot.
-     */
-    @Test
-    public void testCreationAndCloseOfLocalOnlyHotspotReservation() throws Exception {
-        SoftApConfiguration softApConfig = generatorTestSoftApConfig();
-        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(),
-                nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED);
-        mWifiManager.startLocalOnlyHotspot(callback, mHandler);
-
-        callback.onStarted(mWifiManager.new LocalOnlyHotspotReservation(softApConfig));
-
-        assertEquals(softApConfig, callback.mRes.getSoftApConfiguration());
-        WifiConfiguration wifiConfig = callback.mRes.getWifiConfiguration();
-        assertTrue(compareWifiAndSoftApConfiguration(softApConfig, wifiConfig));
-
-        callback.mRes.close();
-        verify(mWifiService).stopLocalOnlyHotspot();
-    }
-
-    /**
-     * Verify stopLOHS is called when try-with-resources is used properly.
-     */
-    @Test
-    public void testLocalOnlyHotspotReservationCallsStopProperlyInTryWithResources()
-            throws Exception {
-        SoftApConfiguration softApConfig = generatorTestSoftApConfig();
-        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(),
-                nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED);
-        mWifiManager.startLocalOnlyHotspot(callback, mHandler);
-
-        callback.onStarted(mWifiManager.new LocalOnlyHotspotReservation(softApConfig));
-
-        try (WifiManager.LocalOnlyHotspotReservation res = callback.mRes) {
-            assertEquals(softApConfig, res.getSoftApConfiguration());
-            WifiConfiguration wifiConfig = callback.mRes.getWifiConfiguration();
-            assertTrue(compareWifiAndSoftApConfiguration(softApConfig, wifiConfig));
-        }
-
-        verify(mWifiService).stopLocalOnlyHotspot();
-    }
-
-    /**
-     * Test creation of a LocalOnlyHotspotSubscription.
-     * TODO: when registrations are tracked, verify removal on close.
-     */
-    @Test
-    public void testCreationOfLocalOnlyHotspotSubscription() throws Exception {
-        try (WifiManager.LocalOnlyHotspotSubscription sub =
-                     mWifiManager.new LocalOnlyHotspotSubscription()) {
-            sub.close();
-        }
-    }
-
-    public class TestLocalOnlyHotspotCallback extends LocalOnlyHotspotCallback {
-        public boolean mOnStartedCalled = false;
-        public boolean mOnStoppedCalled = false;
-        public int mFailureReason = -1;
-        public LocalOnlyHotspotReservation mRes = null;
-        public long mCallingThreadId = -1;
-
-        @Override
-        public void onStarted(LocalOnlyHotspotReservation r) {
-            mRes = r;
-            mOnStartedCalled = true;
-            mCallingThreadId = Thread.currentThread().getId();
-        }
-
-        @Override
-        public void onStopped() {
-            mOnStoppedCalled = true;
-            mCallingThreadId = Thread.currentThread().getId();
-        }
-
-        @Override
-        public void onFailed(int reason) {
-            mFailureReason = reason;
-            mCallingThreadId = Thread.currentThread().getId();
-        }
-    }
-
-    /**
-     * Verify callback is properly plumbed when called.
-     */
-    @Test
-    public void testLocalOnlyHotspotCallback() {
-        SoftApConfiguration softApConfig = generatorTestSoftApConfig();
-        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        assertFalse(callback.mOnStartedCalled);
-        assertFalse(callback.mOnStoppedCalled);
-        assertEquals(ERROR_NOT_SET, callback.mFailureReason);
-        assertEquals(null, callback.mRes);
-
-        // test onStarted
-        WifiManager.LocalOnlyHotspotReservation res =
-                mWifiManager.new LocalOnlyHotspotReservation(softApConfig);
-        callback.onStarted(res);
-        assertEquals(res, callback.mRes);
-        assertTrue(callback.mOnStartedCalled);
-        assertFalse(callback.mOnStoppedCalled);
-        assertEquals(ERROR_NOT_SET, callback.mFailureReason);
-
-        // test onStopped
-        callback.onStopped();
-        assertEquals(res, callback.mRes);
-        assertTrue(callback.mOnStartedCalled);
-        assertTrue(callback.mOnStoppedCalled);
-        assertEquals(ERROR_NOT_SET, callback.mFailureReason);
-
-        // test onFailed
-        callback.onFailed(ERROR_TEST_REASON);
-        assertEquals(res, callback.mRes);
-        assertTrue(callback.mOnStartedCalled);
-        assertTrue(callback.mOnStoppedCalled);
-        assertEquals(ERROR_TEST_REASON, callback.mFailureReason);
-    }
-
-    public class TestLocalOnlyHotspotObserver extends LocalOnlyHotspotObserver {
-        public boolean mOnRegistered = false;
-        public boolean mOnStartedCalled = false;
-        public boolean mOnStoppedCalled = false;
-        public SoftApConfiguration mConfig = null;
-        public LocalOnlyHotspotSubscription mSub = null;
-        public long mCallingThreadId = -1;
-
-        @Override
-        public void onRegistered(LocalOnlyHotspotSubscription sub) {
-            mOnRegistered = true;
-            mSub = sub;
-            mCallingThreadId = Thread.currentThread().getId();
-        }
-
-        @Override
-        public void onStarted(SoftApConfiguration config) {
-            mOnStartedCalled = true;
-            mConfig = config;
-            mCallingThreadId = Thread.currentThread().getId();
-        }
-
-        @Override
-        public void onStopped() {
-            mOnStoppedCalled = true;
-            mCallingThreadId = Thread.currentThread().getId();
-        }
-    }
-
-    /**
-     * Verify observer is properly plumbed when called.
-     */
-    @Test
-    public void testLocalOnlyHotspotObserver() {
-        TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
-        SoftApConfiguration softApConfig = generatorTestSoftApConfig();
-        assertFalse(observer.mOnRegistered);
-        assertFalse(observer.mOnStartedCalled);
-        assertFalse(observer.mOnStoppedCalled);
-        assertEquals(null, observer.mConfig);
-        assertEquals(null, observer.mSub);
-
-        WifiManager.LocalOnlyHotspotSubscription sub =
-                mWifiManager.new LocalOnlyHotspotSubscription();
-        observer.onRegistered(sub);
-        assertTrue(observer.mOnRegistered);
-        assertFalse(observer.mOnStartedCalled);
-        assertFalse(observer.mOnStoppedCalled);
-        assertEquals(null, observer.mConfig);
-        assertEquals(sub, observer.mSub);
-
-        observer.onStarted(softApConfig);
-        assertTrue(observer.mOnRegistered);
-        assertTrue(observer.mOnStartedCalled);
-        assertFalse(observer.mOnStoppedCalled);
-        assertEquals(softApConfig, observer.mConfig);
-        assertEquals(sub, observer.mSub);
-
-        observer.onStopped();
-        assertTrue(observer.mOnRegistered);
-        assertTrue(observer.mOnStartedCalled);
-        assertTrue(observer.mOnStoppedCalled);
-        assertEquals(softApConfig, observer.mConfig);
-        assertEquals(sub, observer.mSub);
-    }
-
-    /**
-     * Verify call to startLocalOnlyHotspot goes to WifiServiceImpl.
-     */
-    @Test
-    public void testStartLocalOnlyHotspot() throws Exception {
-        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        mWifiManager.startLocalOnlyHotspot(callback, mHandler);
-
-        verify(mWifiService).startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class),
-                anyString(), nullable(String.class), eq(null));
-    }
-
-    /**
-     * Verify a SecurityException is thrown for callers without proper permissions for
-     * startLocalOnlyHotspot.
-     */
-    @Test(expected = SecurityException.class)
-    public void testStartLocalOnlyHotspotThrowsSecurityException() throws Exception {
-        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        doThrow(new SecurityException()).when(mWifiService).startLocalOnlyHotspot(
-                any(ILocalOnlyHotspotCallback.class), anyString(), nullable(String.class),
-                eq(null));
-        mWifiManager.startLocalOnlyHotspot(callback, mHandler);
-    }
-
-    /**
-     * Verify an IllegalStateException is thrown for callers that already have a pending request for
-     * startLocalOnlyHotspot.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testStartLocalOnlyHotspotThrowsIllegalStateException() throws Exception {
-        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        doThrow(new IllegalStateException()).when(mWifiService).startLocalOnlyHotspot(
-                any(ILocalOnlyHotspotCallback.class), anyString(), nullable(String.class),
-                eq(null));
-        mWifiManager.startLocalOnlyHotspot(callback, mHandler);
-    }
-
-    /**
-     * Verify that the handler provided by the caller is used for the callbacks.
-     */
-    @Test
-    public void testCorrectLooperIsUsedForHandler() throws Exception {
-        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(),
-                nullable(String.class), eq(null))).thenReturn(ERROR_INCOMPATIBLE_MODE);
-        mWifiManager.startLocalOnlyHotspot(callback, mHandler);
-        mLooper.dispatchAll();
-        assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason);
-        verify(mContext, never()).getMainLooper();
-        verify(mContext, never()).getMainExecutor();
-    }
-
-    /**
-     * Verify that the main looper's thread is used if a handler is not provided by the reqiestomg
-     * application.
-     */
-    @Test
-    public void testMainLooperIsUsedWhenHandlerNotProvided() throws Exception {
-        // record thread from looper.getThread and check ids.
-        TestLooper altLooper = new TestLooper();
-        when(mContext.getMainExecutor()).thenReturn(altLooper.getNewExecutor());
-        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(),
-                nullable(String.class), eq(null))).thenReturn(ERROR_INCOMPATIBLE_MODE);
-        mWifiManager.startLocalOnlyHotspot(callback, null);
-        altLooper.dispatchAll();
-        assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason);
-        assertEquals(altLooper.getLooper().getThread().getId(), callback.mCallingThreadId);
-        verify(mContext).getMainExecutor();
-    }
-
-    /**
-     * Verify the LOHS onStarted callback is triggered when WifiManager receives a HOTSPOT_STARTED
-     * message from WifiServiceImpl.
-     */
-    @Test
-    public void testOnStartedIsCalledWithReservation() throws Exception {
-        SoftApConfiguration softApConfig = generatorTestSoftApConfig();
-        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        TestLooper callbackLooper = new TestLooper();
-        Handler callbackHandler = new Handler(callbackLooper.getLooper());
-        ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback =
-                ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class);
-        when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString(),
-                nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED);
-        mWifiManager.startLocalOnlyHotspot(callback, callbackHandler);
-        callbackLooper.dispatchAll();
-        mLooper.dispatchAll();
-        assertFalse(callback.mOnStartedCalled);
-        assertEquals(null, callback.mRes);
-        // now trigger the callback
-        internalCallback.getValue().onHotspotStarted(softApConfig);
-        mLooper.dispatchAll();
-        callbackLooper.dispatchAll();
-        assertTrue(callback.mOnStartedCalled);
-        assertEquals(softApConfig, callback.mRes.getSoftApConfiguration());
-        WifiConfiguration wifiConfig = callback.mRes.getWifiConfiguration();
-        assertTrue(compareWifiAndSoftApConfiguration(softApConfig, wifiConfig));
-    }
-
-    /**
-     * Verify the LOHS onStarted callback is triggered when WifiManager receives a HOTSPOT_STARTED
-     * message from WifiServiceImpl when softap enabled with SAE security type.
-     */
-    @Test
-    public void testOnStartedIsCalledWithReservationAndSaeSoftApConfig() throws Exception {
-        SoftApConfiguration softApConfig = new SoftApConfiguration.Builder()
-                .setSsid("TestSSID")
-                .setPassphrase("TestPassphrase", SoftApConfiguration.SECURITY_TYPE_WPA3_SAE)
-                .build();
-        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        TestLooper callbackLooper = new TestLooper();
-        Handler callbackHandler = new Handler(callbackLooper.getLooper());
-        ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback =
-                ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class);
-        when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString(),
-                nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED);
-        mWifiManager.startLocalOnlyHotspot(callback, callbackHandler);
-        callbackLooper.dispatchAll();
-        mLooper.dispatchAll();
-        assertFalse(callback.mOnStartedCalled);
-        assertEquals(null, callback.mRes);
-        // now trigger the callback
-        internalCallback.getValue().onHotspotStarted(softApConfig);
-        mLooper.dispatchAll();
-        callbackLooper.dispatchAll();
-        assertTrue(callback.mOnStartedCalled);
-        assertEquals(softApConfig, callback.mRes.getSoftApConfiguration());
-        assertEquals(null, callback.mRes.getWifiConfiguration());
-    }
-
-    /**
-     * Verify onFailed is called if WifiServiceImpl sends a HOTSPOT_STARTED message with a null
-     * config.
-     */
-    @Test
-    public void testOnStartedIsCalledWithNullConfig() throws Exception {
-        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        TestLooper callbackLooper = new TestLooper();
-        Handler callbackHandler = new Handler(callbackLooper.getLooper());
-        ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback =
-                ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class);
-        when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString(),
-                nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED);
-        mWifiManager.startLocalOnlyHotspot(callback, callbackHandler);
-        callbackLooper.dispatchAll();
-        mLooper.dispatchAll();
-        assertFalse(callback.mOnStartedCalled);
-        assertEquals(null, callback.mRes);
-        // now trigger the callback
-        internalCallback.getValue().onHotspotStarted(null);
-        mLooper.dispatchAll();
-        callbackLooper.dispatchAll();
-        assertFalse(callback.mOnStartedCalled);
-        assertEquals(ERROR_GENERIC, callback.mFailureReason);
-    }
-
-    /**
-     * Verify onStopped is called if WifiServiceImpl sends a HOTSPOT_STOPPED message.
-     */
-    @Test
-    public void testOnStoppedIsCalled() throws Exception {
-        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        TestLooper callbackLooper = new TestLooper();
-        Handler callbackHandler = new Handler(callbackLooper.getLooper());
-        ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback =
-                ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class);
-        when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString(),
-                nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED);
-        mWifiManager.startLocalOnlyHotspot(callback, callbackHandler);
-        callbackLooper.dispatchAll();
-        mLooper.dispatchAll();
-        assertFalse(callback.mOnStoppedCalled);
-        // now trigger the callback
-        internalCallback.getValue().onHotspotStopped();
-        mLooper.dispatchAll();
-        callbackLooper.dispatchAll();
-        assertTrue(callback.mOnStoppedCalled);
-    }
-
-    /**
-     * Verify onFailed is called if WifiServiceImpl sends a HOTSPOT_FAILED message.
-     */
-    @Test
-    public void testOnFailedIsCalled() throws Exception {
-        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        TestLooper callbackLooper = new TestLooper();
-        Handler callbackHandler = new Handler(callbackLooper.getLooper());
-        ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback =
-                ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class);
-        when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString(),
-                nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED);
-        mWifiManager.startLocalOnlyHotspot(callback, callbackHandler);
-        callbackLooper.dispatchAll();
-        mLooper.dispatchAll();
-        assertEquals(ERROR_NOT_SET, callback.mFailureReason);
-        // now trigger the callback
-        internalCallback.getValue().onHotspotFailed(ERROR_NO_CHANNEL);
-        mLooper.dispatchAll();
-        callbackLooper.dispatchAll();
-        assertEquals(ERROR_NO_CHANNEL, callback.mFailureReason);
-    }
-
-    /**
-     * Verify callback triggered from startLocalOnlyHotspot with an incompatible mode failure.
-     */
-    @Test
-    public void testLocalOnlyHotspotCallbackFullOnIncompatibleMode() throws Exception {
-        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(),
-                nullable(String.class), eq(null))).thenReturn(ERROR_INCOMPATIBLE_MODE);
-        mWifiManager.startLocalOnlyHotspot(callback, mHandler);
-        mLooper.dispatchAll();
-        assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason);
-        assertFalse(callback.mOnStartedCalled);
-        assertFalse(callback.mOnStoppedCalled);
-        assertEquals(null, callback.mRes);
-    }
-
-    /**
-     * Verify callback triggered from startLocalOnlyHotspot with a tethering disallowed failure.
-     */
-    @Test
-    public void testLocalOnlyHotspotCallbackFullOnTetheringDisallowed() throws Exception {
-        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(),
-                nullable(String.class), eq(null))).thenReturn(ERROR_TETHERING_DISALLOWED);
-        mWifiManager.startLocalOnlyHotspot(callback, mHandler);
-        mLooper.dispatchAll();
-        assertEquals(ERROR_TETHERING_DISALLOWED, callback.mFailureReason);
-        assertFalse(callback.mOnStartedCalled);
-        assertFalse(callback.mOnStoppedCalled);
-        assertEquals(null, callback.mRes);
-    }
-
-    /**
-     * Verify a SecurityException resulting from an application without necessary permissions will
-     * bubble up through the call to start LocalOnlyHotspot and will not trigger other callbacks.
-     */
-    @Test(expected = SecurityException.class)
-    public void testLocalOnlyHotspotCallbackFullOnSecurityException() throws Exception {
-        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        doThrow(new SecurityException()).when(mWifiService).startLocalOnlyHotspot(
-                any(ILocalOnlyHotspotCallback.class), anyString(), nullable(String.class),
-                eq(null));
-        try {
-            mWifiManager.startLocalOnlyHotspot(callback, mHandler);
-        } catch (SecurityException e) {
-            assertEquals(ERROR_NOT_SET, callback.mFailureReason);
-            assertFalse(callback.mOnStartedCalled);
-            assertFalse(callback.mOnStoppedCalled);
-            assertEquals(null, callback.mRes);
-            throw e;
-        }
-
-    }
-
-    /**
-     * Verify the handler passed to startLocalOnlyHotspot is correctly used for callbacks when
-     * SoftApMode fails due to a underlying error.
-     */
-    @Test
-    public void testLocalOnlyHotspotCallbackFullOnNoChannelError() throws Exception {
-        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(),
-                nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED);
-        mWifiManager.startLocalOnlyHotspot(callback, mHandler);
-        mLooper.dispatchAll();
-        //assertEquals(ERROR_NO_CHANNEL, callback.mFailureReason);
-        assertFalse(callback.mOnStartedCalled);
-        assertFalse(callback.mOnStoppedCalled);
-        assertEquals(null, callback.mRes);
-    }
-
-    /**
-     * Verify that the call to cancel a LOHS request does call stopLOHS.
-     */
-    @Test
-    public void testCancelLocalOnlyHotspotRequestCallsStopOnWifiService() throws Exception {
-        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(),
-                nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED);
-        mWifiManager.startLocalOnlyHotspot(callback, mHandler);
-        mWifiManager.cancelLocalOnlyHotspotRequest();
-        verify(mWifiService).stopLocalOnlyHotspot();
-    }
-
-    /**
-     * Verify that we do not crash if cancelLocalOnlyHotspotRequest is called without an existing
-     * callback stored.
-     */
-    @Test
-    public void testCancelLocalOnlyHotspotReturnsWithoutExistingRequest() {
-        mWifiManager.cancelLocalOnlyHotspotRequest();
-    }
-
-    /**
-     * Verify that the callback is not triggered if the LOHS request was already cancelled.
-     */
-    @Test
-    public void testCallbackAfterLocalOnlyHotspotWasCancelled() throws Exception {
-        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(),
-                nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED);
-        mWifiManager.startLocalOnlyHotspot(callback, mHandler);
-        mWifiManager.cancelLocalOnlyHotspotRequest();
-        verify(mWifiService).stopLocalOnlyHotspot();
-        mLooper.dispatchAll();
-        assertEquals(ERROR_NOT_SET, callback.mFailureReason);
-        assertFalse(callback.mOnStartedCalled);
-        assertFalse(callback.mOnStoppedCalled);
-        assertEquals(null, callback.mRes);
-    }
-
-    /**
-     * Verify that calling cancel LOHS request does not crash if an error callback was already
-     * handled.
-     */
-    @Test
-    public void testCancelAfterLocalOnlyHotspotCallbackTriggered() throws Exception {
-        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(),
-                nullable(String.class), eq(null))).thenReturn(ERROR_INCOMPATIBLE_MODE);
-        mWifiManager.startLocalOnlyHotspot(callback, mHandler);
-        mLooper.dispatchAll();
-        assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason);
-        assertFalse(callback.mOnStartedCalled);
-        assertFalse(callback.mOnStoppedCalled);
-        assertEquals(null, callback.mRes);
-        mWifiManager.cancelLocalOnlyHotspotRequest();
-        verify(mWifiService, never()).stopLocalOnlyHotspot();
-    }
-
-    @Test
-    public void testStartLocalOnlyHotspotForwardsCustomConfig() throws Exception {
-        SoftApConfiguration customConfig = new SoftApConfiguration.Builder()
-                .setSsid("customSsid")
-                .build();
-        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        mWifiManager.startLocalOnlyHotspot(customConfig, mExecutor, callback);
-        verify(mWifiService).startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class),
-                anyString(), nullable(String.class), eq(customConfig));
-    }
-
-    /**
-     * Verify the watchLocalOnlyHotspot call goes to WifiServiceImpl.
-     */
-    @Test
-    public void testWatchLocalOnlyHotspot() throws Exception {
-        TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
-
-        mWifiManager.watchLocalOnlyHotspot(observer, mHandler);
-        verify(mWifiService).startWatchLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class));
-    }
-
-    /**
-     * Verify a SecurityException is thrown for callers without proper permissions for
-     * startWatchLocalOnlyHotspot.
-     */
-    @Test(expected = SecurityException.class)
-    public void testStartWatchLocalOnlyHotspotThrowsSecurityException() throws Exception {
-        TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
-        doThrow(new SecurityException()).when(mWifiService)
-                .startWatchLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class));
-        mWifiManager.watchLocalOnlyHotspot(observer, mHandler);
-    }
-
-    /**
-     * Verify an IllegalStateException is thrown for callers that already have a pending request for
-     * watchLocalOnlyHotspot.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testStartWatchLocalOnlyHotspotThrowsIllegalStateException() throws Exception {
-        TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
-        doThrow(new IllegalStateException()).when(mWifiService)
-                .startWatchLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class));
-        mWifiManager.watchLocalOnlyHotspot(observer, mHandler);
-    }
-
-    /**
-     * Verify an IllegalArgumentException is thrown if callback is not provided.
-     */
-    @Test
-    public void registerSoftApCallbackThrowsIllegalArgumentExceptionOnNullArgumentForCallback() {
-        try {
-            mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), null);
-            fail("expected IllegalArgumentException");
-        } catch (IllegalArgumentException expected) {
-        }
-    }
-
-    /**
-     * Verify an IllegalArgumentException is thrown if executor is null.
-     */
-    @Test
-    public void registerSoftApCallbackThrowsIllegalArgumentExceptionOnNullArgumentForExecutor() {
-        try {
-            mWifiManager.registerSoftApCallback(null, mSoftApCallback);
-            fail("expected IllegalArgumentException");
-        } catch (IllegalArgumentException expected) {
-        }
-    }
-
-    /**
-     * Verify an IllegalArgumentException is thrown if callback is not provided.
-     */
-    @Test
-    public void unregisterSoftApCallbackThrowsIllegalArgumentExceptionOnNullArgumentForCallback() {
-        try {
-            mWifiManager.unregisterSoftApCallback(null);
-            fail("expected IllegalArgumentException");
-        } catch (IllegalArgumentException expected) {
-        }
-    }
-
-    /**
-     * Verify the call to registerSoftApCallback goes to WifiServiceImpl.
-     */
-    @Test
-    public void registerSoftApCallbackCallGoesToWifiServiceImpl() throws Exception {
-        mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
-        verify(mWifiService).registerSoftApCallback(any(IBinder.class),
-                any(ISoftApCallback.Stub.class), anyInt());
-    }
-
-    /**
-     * Verify the call to unregisterSoftApCallback goes to WifiServiceImpl.
-     */
-    @Test
-    public void unregisterSoftApCallbackCallGoesToWifiServiceImpl() throws Exception {
-        ArgumentCaptor<Integer> callbackIdentifier = ArgumentCaptor.forClass(Integer.class);
-        mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
-        verify(mWifiService).registerSoftApCallback(any(IBinder.class),
-                any(ISoftApCallback.Stub.class), callbackIdentifier.capture());
-
-        mWifiManager.unregisterSoftApCallback(mSoftApCallback);
-        verify(mWifiService).unregisterSoftApCallback(eq((int) callbackIdentifier.getValue()));
-    }
-
-    /*
-     * Verify client-provided callback is being called through callback proxy
-     */
-    @Test
-    public void softApCallbackProxyCallsOnStateChanged() throws Exception {
-        ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor =
-                ArgumentCaptor.forClass(ISoftApCallback.Stub.class);
-        mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
-        verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(),
-                anyInt());
-
-        callbackCaptor.getValue().onStateChanged(WIFI_AP_STATE_ENABLED, 0);
-        mLooper.dispatchAll();
-        verify(mSoftApCallback).onStateChanged(WIFI_AP_STATE_ENABLED, 0);
-    }
-
-    /*
-     * Verify client-provided callback is being called through callback proxy
-     */
-    @Test
-    public void softApCallbackProxyCallsOnConnectedClientsChanged() throws Exception {
-        ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor =
-                ArgumentCaptor.forClass(ISoftApCallback.Stub.class);
-        mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
-        verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(),
-                anyInt());
-
-        final List<WifiClient> testClients = new ArrayList();
-        callbackCaptor.getValue().onConnectedClientsChanged(testClients);
-        mLooper.dispatchAll();
-        verify(mSoftApCallback).onConnectedClientsChanged(testClients);
-    }
-
-
-    /*
-     * Verify client-provided callback is being called through callback proxy
-     */
-    @Test
-    public void softApCallbackProxyCallsOnSoftApInfoChanged() throws Exception {
-        SoftApInfo testSoftApInfo = new SoftApInfo();
-        testSoftApInfo.setFrequency(TEST_AP_FREQUENCY);
-        testSoftApInfo.setBandwidth(TEST_AP_BANDWIDTH);
-        ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor =
-                ArgumentCaptor.forClass(ISoftApCallback.Stub.class);
-        mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
-        verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(),
-                anyInt());
-
-        callbackCaptor.getValue().onInfoChanged(testSoftApInfo);
-        mLooper.dispatchAll();
-        verify(mSoftApCallback).onInfoChanged(testSoftApInfo);
-    }
-
-
-    /*
-     * Verify client-provided callback is being called through callback proxy
-     */
-    @Test
-    public void softApCallbackProxyCallsOnCapabilityChanged() throws Exception {
-        SoftApCapability testSoftApCapability = new SoftApCapability(0);
-        testSoftApCapability.setMaxSupportedClients(10);
-        ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor =
-                ArgumentCaptor.forClass(ISoftApCallback.Stub.class);
-        mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
-        verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(),
-                anyInt());
-
-        callbackCaptor.getValue().onCapabilityChanged(testSoftApCapability);
-        mLooper.dispatchAll();
-        verify(mSoftApCallback).onCapabilityChanged(testSoftApCapability);
-    }
-
-    /*
-     * Verify client-provided callback is being called through callback proxy
-     */
-    @Test
-    public void softApCallbackProxyCallsOnBlockedClientConnecting() throws Exception {
-        WifiClient testWifiClient = new WifiClient(MacAddress.fromString("22:33:44:55:66:77"));
-        ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor =
-                ArgumentCaptor.forClass(ISoftApCallback.Stub.class);
-        mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
-        verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(),
-                anyInt());
-
-        callbackCaptor.getValue().onBlockedClientConnecting(testWifiClient,
-                WifiManager.SAP_CLIENT_BLOCK_REASON_CODE_NO_MORE_STAS);
-        mLooper.dispatchAll();
-        verify(mSoftApCallback).onBlockedClientConnecting(testWifiClient,
-                WifiManager.SAP_CLIENT_BLOCK_REASON_CODE_NO_MORE_STAS);
-    }
-
-    /*
-     * Verify client-provided callback is being called through callback proxy on multiple events
-     */
-    @Test
-    public void softApCallbackProxyCallsOnMultipleUpdates() throws Exception {
-        SoftApInfo testSoftApInfo = new SoftApInfo();
-        testSoftApInfo.setFrequency(TEST_AP_FREQUENCY);
-        testSoftApInfo.setBandwidth(TEST_AP_BANDWIDTH);
-        SoftApCapability testSoftApCapability = new SoftApCapability(0);
-        testSoftApCapability.setMaxSupportedClients(10);
-        ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor =
-                ArgumentCaptor.forClass(ISoftApCallback.Stub.class);
-        mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
-        verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(),
-                anyInt());
-
-        final List<WifiClient> testClients = new ArrayList();
-        callbackCaptor.getValue().onStateChanged(WIFI_AP_STATE_ENABLING, 0);
-        callbackCaptor.getValue().onConnectedClientsChanged(testClients);
-        callbackCaptor.getValue().onInfoChanged(testSoftApInfo);
-        callbackCaptor.getValue().onStateChanged(WIFI_AP_STATE_FAILED, SAP_START_FAILURE_GENERAL);
-        callbackCaptor.getValue().onCapabilityChanged(testSoftApCapability);
-
-
-        mLooper.dispatchAll();
-        verify(mSoftApCallback).onStateChanged(WIFI_AP_STATE_ENABLING, 0);
-        verify(mSoftApCallback).onConnectedClientsChanged(testClients);
-        verify(mSoftApCallback).onInfoChanged(testSoftApInfo);
-        verify(mSoftApCallback).onStateChanged(WIFI_AP_STATE_FAILED, SAP_START_FAILURE_GENERAL);
-        verify(mSoftApCallback).onCapabilityChanged(testSoftApCapability);
-    }
-
-    /*
-     * Verify client-provided callback is being called on the correct thread
-     */
-    @Test
-    public void softApCallbackIsCalledOnCorrectThread() throws Exception {
-        ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor =
-                ArgumentCaptor.forClass(ISoftApCallback.Stub.class);
-        TestLooper altLooper = new TestLooper();
-        Handler altHandler = new Handler(altLooper.getLooper());
-        mWifiManager.registerSoftApCallback(new HandlerExecutor(altHandler), mSoftApCallback);
-        verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(),
-                anyInt());
-
-        callbackCaptor.getValue().onStateChanged(WIFI_AP_STATE_ENABLED, 0);
-        altLooper.dispatchAll();
-        verify(mSoftApCallback).onStateChanged(WIFI_AP_STATE_ENABLED, 0);
-    }
-
-    /**
-     * Verify that the handler provided by the caller is used for registering soft AP callback.
-     */
-    @Test
-    public void testCorrectLooperIsUsedForSoftApCallbackHandler() throws Exception {
-        mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
-        mLooper.dispatchAll();
-        verify(mWifiService).registerSoftApCallback(any(IBinder.class),
-                any(ISoftApCallback.Stub.class), anyInt());
-        verify(mContext, never()).getMainLooper();
-        verify(mContext, never()).getMainExecutor();
-    }
-
-    /**
-     * Verify that the handler provided by the caller is used for the observer.
-     */
-    @Test
-    public void testCorrectLooperIsUsedForObserverHandler() throws Exception {
-        TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
-        mWifiManager.watchLocalOnlyHotspot(observer, mHandler);
-        mLooper.dispatchAll();
-        assertTrue(observer.mOnRegistered);
-        verify(mContext, never()).getMainLooper();
-        verify(mContext, never()).getMainExecutor();
-    }
-
-    /**
-     * Verify that the main looper's thread is used if a handler is not provided by the requesting
-     * application.
-     */
-    @Test
-    public void testMainLooperIsUsedWhenHandlerNotProvidedForObserver() throws Exception {
-        // record thread from looper.getThread and check ids.
-        TestLooper altLooper = new TestLooper();
-        when(mContext.getMainExecutor()).thenReturn(altLooper.getNewExecutor());
-        TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
-        mWifiManager.watchLocalOnlyHotspot(observer, null);
-        altLooper.dispatchAll();
-        assertTrue(observer.mOnRegistered);
-        assertEquals(altLooper.getLooper().getThread().getId(), observer.mCallingThreadId);
-        verify(mContext).getMainExecutor();
-    }
-
-    /**
-     * Verify the LOHS onRegistered observer callback is triggered when WifiManager receives a
-     * HOTSPOT_OBSERVER_REGISTERED message from WifiServiceImpl.
-     */
-    @Test
-    public void testOnRegisteredIsCalledWithSubscription() throws Exception {
-        TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
-        TestLooper observerLooper = new TestLooper();
-        Handler observerHandler = new Handler(observerLooper.getLooper());
-        assertFalse(observer.mOnRegistered);
-        assertEquals(null, observer.mSub);
-        mWifiManager.watchLocalOnlyHotspot(observer, observerHandler);
-        verify(mWifiService).startWatchLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class));
-        // now trigger the callback
-        observerLooper.dispatchAll();
-        mLooper.dispatchAll();
-        assertTrue(observer.mOnRegistered);
-        assertNotNull(observer.mSub);
-    }
-
-    /**
-     * Verify the LOHS onStarted observer callback is triggered when WifiManager receives a
-     * HOTSPOT_STARTED message from WifiServiceImpl.
-     */
-    @Test
-    public void testObserverOnStartedIsCalledWithWifiConfig() throws Exception {
-        SoftApConfiguration softApConfig = generatorTestSoftApConfig();
-        TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
-        TestLooper observerLooper = new TestLooper();
-        Handler observerHandler = new Handler(observerLooper.getLooper());
-        mWifiManager.watchLocalOnlyHotspot(observer, observerHandler);
-        ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback =
-                ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class);
-        verify(mWifiService).startWatchLocalOnlyHotspot(internalCallback.capture());
-        observerLooper.dispatchAll();
-        mLooper.dispatchAll();
-        assertFalse(observer.mOnStartedCalled);
-        // now trigger the callback
-        internalCallback.getValue().onHotspotStarted(softApConfig);
-        mLooper.dispatchAll();
-        observerLooper.dispatchAll();
-        assertTrue(observer.mOnStartedCalled);
-        assertEquals(softApConfig, observer.mConfig);
-    }
-
-    /**
-     * Verify the LOHS onStarted observer callback is triggered not when WifiManager receives a
-     * HOTSPOT_STARTED message from WifiServiceImpl with a null config.
-     */
-    @Test
-    public void testObserverOnStartedNotCalledWithNullConfig() throws Exception {
-        TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
-        TestLooper observerLooper = new TestLooper();
-        Handler observerHandler = new Handler(observerLooper.getLooper());
-        mWifiManager.watchLocalOnlyHotspot(observer, observerHandler);
-        ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback =
-                ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class);
-        verify(mWifiService).startWatchLocalOnlyHotspot(internalCallback.capture());
-        observerLooper.dispatchAll();
-        mLooper.dispatchAll();
-        assertFalse(observer.mOnStartedCalled);
-        // now trigger the callback
-        internalCallback.getValue().onHotspotStarted(null);
-        mLooper.dispatchAll();
-        observerLooper.dispatchAll();
-        assertFalse(observer.mOnStartedCalled);
-        assertEquals(null, observer.mConfig);
-    }
-
-
-    /**
-     * Verify the LOHS onStopped observer callback is triggered when WifiManager receives a
-     * HOTSPOT_STOPPED message from WifiServiceImpl.
-     */
-    @Test
-    public void testObserverOnStoppedIsCalled() throws Exception {
-        TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
-        TestLooper observerLooper = new TestLooper();
-        Handler observerHandler = new Handler(observerLooper.getLooper());
-        mWifiManager.watchLocalOnlyHotspot(observer, observerHandler);
-        ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback =
-                ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class);
-        verify(mWifiService).startWatchLocalOnlyHotspot(internalCallback.capture());
-        observerLooper.dispatchAll();
-        mLooper.dispatchAll();
-        assertFalse(observer.mOnStoppedCalled);
-        // now trigger the callback
-        internalCallback.getValue().onHotspotStopped();
-        mLooper.dispatchAll();
-        observerLooper.dispatchAll();
-        assertTrue(observer.mOnStoppedCalled);
-    }
-
-    /**
-     * Verify WifiServiceImpl is not called if there is not a registered LOHS observer callback.
-     */
-    @Test
-    public void testUnregisterWifiServiceImplNotCalledWithoutRegisteredObserver() throws Exception {
-        mWifiManager.unregisterLocalOnlyHotspotObserver();
-        verifyZeroInteractions(mWifiService);
-    }
-
-    /**
-     * Verify WifiServiceImpl is called when there is a registered LOHS observer callback.
-     */
-    @Test
-    public void testUnregisterWifiServiceImplCalledWithRegisteredObserver() throws Exception {
-        TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
-        TestLooper observerLooper = new TestLooper();
-        Handler observerHandler = new Handler(observerLooper.getLooper());
-        mWifiManager.watchLocalOnlyHotspot(observer, observerHandler);
-        mWifiManager.unregisterLocalOnlyHotspotObserver();
-        verify(mWifiService).stopWatchLocalOnlyHotspot();
-    }
-
-    /**
-     * Test that calls to get the current WPS config token return null and do not have any
-     * interactions with WifiServiceImpl.
-     */
-    @Test
-    public void testGetCurrentNetworkWpsNfcConfigurationTokenReturnsNull() {
-        assertNull(mWifiManager.getCurrentNetworkWpsNfcConfigurationToken());
-        verifyNoMoreInteractions(mWifiService);
-    }
-
-
-    class WpsCallbackTester extends WpsCallback {
-        public boolean mStarted = false;
-        public boolean mSucceeded = false;
-        public boolean mFailed = false;
-        public int mFailureCode = -1;
-
-        @Override
-        public void onStarted(String pin) {
-            mStarted = true;
-        }
-
-        @Override
-        public void onSucceeded() {
-            mSucceeded = true;
-        }
-
-        @Override
-        public void onFailed(int reason) {
-            mFailed = true;
-            mFailureCode = reason;
-        }
-
-    }
-
-    /**
-     * Verify that a call to start WPS immediately returns a failure.
-     */
-    @Test
-    public void testStartWpsImmediatelyFailsWithCallback() {
-        WpsCallbackTester wpsCallback = new WpsCallbackTester();
-        mWifiManager.startWps(null, wpsCallback);
-        assertTrue(wpsCallback.mFailed);
-        assertEquals(ERROR, wpsCallback.mFailureCode);
-        assertFalse(wpsCallback.mStarted);
-        assertFalse(wpsCallback.mSucceeded);
-        verifyNoMoreInteractions(mWifiService);
-    }
-
-    /**
-     * Verify that a call to start WPS does not go to WifiServiceImpl if we do not have a callback.
-     */
-    @Test
-    public void testStartWpsDoesNotCallWifiServiceImpl() {
-        mWifiManager.startWps(null, null);
-        verifyNoMoreInteractions(mWifiService);
-    }
-
-    /**
-     * Verify that a call to cancel WPS immediately returns a failure.
-     */
-    @Test
-    public void testCancelWpsImmediatelyFailsWithCallback() {
-        WpsCallbackTester wpsCallback = new WpsCallbackTester();
-        mWifiManager.cancelWps(wpsCallback);
-        assertTrue(wpsCallback.mFailed);
-        assertEquals(ERROR, wpsCallback.mFailureCode);
-        assertFalse(wpsCallback.mStarted);
-        assertFalse(wpsCallback.mSucceeded);
-        verifyNoMoreInteractions(mWifiService);
-    }
-
-    /**
-     * Verify that a call to cancel WPS does not go to WifiServiceImpl if we do not have a callback.
-     */
-    @Test
-    public void testCancelWpsDoesNotCallWifiServiceImpl() {
-        mWifiManager.cancelWps(null);
-        verifyNoMoreInteractions(mWifiService);
-    }
-
-    /**
-     * Verify that a successful call properly returns true.
-     */
-    @Test
-    public void testSetWifiApConfigurationSuccessReturnsTrue() throws Exception {
-        WifiConfiguration apConfig = new WifiConfiguration();
-
-        when(mWifiService.setWifiApConfiguration(eq(apConfig), eq(TEST_PACKAGE_NAME)))
-                .thenReturn(true);
-        assertTrue(mWifiManager.setWifiApConfiguration(apConfig));
-    }
-
-    /**
-     * Verify that a failed call properly returns false.
-     */
-    @Test
-    public void testSetWifiApConfigurationFailureReturnsFalse() throws Exception {
-        WifiConfiguration apConfig = new WifiConfiguration();
-
-        when(mWifiService.setWifiApConfiguration(eq(apConfig), eq(TEST_PACKAGE_NAME)))
-                .thenReturn(false);
-        assertFalse(mWifiManager.setWifiApConfiguration(apConfig));
-    }
-
-    /**
-     * Verify Exceptions are rethrown when underlying calls to WifiService throw exceptions.
-     */
-    @Test
-    public void testSetWifiApConfigurationRethrowsException() throws Exception {
-        doThrow(new SecurityException()).when(mWifiService).setWifiApConfiguration(any(), any());
-
-        try {
-            mWifiManager.setWifiApConfiguration(new WifiConfiguration());
-            fail("setWifiApConfiguration should rethrow Exceptions from WifiService");
-        } catch (SecurityException e) { }
-    }
-
-    /**
-     * Verify that a successful call properly returns true.
-     */
-    @Test
-    public void testSetSoftApConfigurationSuccessReturnsTrue() throws Exception {
-        SoftApConfiguration apConfig = generatorTestSoftApConfig();
-
-        when(mWifiService.setSoftApConfiguration(eq(apConfig), eq(TEST_PACKAGE_NAME)))
-                .thenReturn(true);
-        assertTrue(mWifiManager.setSoftApConfiguration(apConfig));
-    }
-
-    /**
-     * Verify that a failed call properly returns false.
-     */
-    @Test
-    public void testSetSoftApConfigurationFailureReturnsFalse() throws Exception {
-        SoftApConfiguration apConfig = generatorTestSoftApConfig();
-
-        when(mWifiService.setSoftApConfiguration(eq(apConfig), eq(TEST_PACKAGE_NAME)))
-                .thenReturn(false);
-        assertFalse(mWifiManager.setSoftApConfiguration(apConfig));
-    }
-
-    /**
-     * Verify Exceptions are rethrown when underlying calls to WifiService throw exceptions.
-     */
-    @Test
-    public void testSetSoftApConfigurationRethrowsException() throws Exception {
-        doThrow(new SecurityException()).when(mWifiService).setSoftApConfiguration(any(), any());
-
-        try {
-            mWifiManager.setSoftApConfiguration(generatorTestSoftApConfig());
-            fail("setWifiApConfiguration should rethrow Exceptions from WifiService");
-        } catch (SecurityException e) { }
-    }
-
-    /**
-     * Check the call to startScan calls WifiService.
-     */
-    @Test
-    public void testStartScan() throws Exception {
-        when(mWifiService.startScan(eq(TEST_PACKAGE_NAME), nullable(String.class))).thenReturn(
-                true);
-        assertTrue(mWifiManager.startScan());
-
-        when(mWifiService.startScan(eq(TEST_PACKAGE_NAME), nullable(String.class))).thenReturn(
-                false);
-        assertFalse(mWifiManager.startScan());
-    }
-
-    /**
-     * Verify main looper is used when handler is not provided.
-     */
-    @Test
-    public void registerTrafficStateCallbackUsesMainLooperOnNullArgumentForHandler()
-            throws Exception {
-        ArgumentCaptor<ITrafficStateCallback.Stub> callbackCaptor =
-                ArgumentCaptor.forClass(ITrafficStateCallback.Stub.class);
-        mWifiManager.registerTrafficStateCallback(
-                new HandlerExecutor(new Handler(mLooper.getLooper())), mTrafficStateCallback);
-        verify(mWifiService).registerTrafficStateCallback(
-                any(IBinder.class), callbackCaptor.capture(), anyInt());
-
-        assertEquals(0, mLooper.dispatchAll());
-        callbackCaptor.getValue().onStateChanged(TrafficStateCallback.DATA_ACTIVITY_INOUT);
-        assertEquals(1, mLooper.dispatchAll());
-        verify(mTrafficStateCallback).onStateChanged(TrafficStateCallback.DATA_ACTIVITY_INOUT);
-    }
-
-    /**
-     * Verify the call to unregisterTrafficStateCallback goes to WifiServiceImpl.
-     */
-    @Test
-    public void unregisterTrafficStateCallbackCallGoesToWifiServiceImpl() throws Exception {
-        ArgumentCaptor<Integer> callbackIdentifier = ArgumentCaptor.forClass(Integer.class);
-        mWifiManager.registerTrafficStateCallback(new HandlerExecutor(mHandler),
-                mTrafficStateCallback);
-        verify(mWifiService).registerTrafficStateCallback(any(IBinder.class),
-                any(ITrafficStateCallback.Stub.class), callbackIdentifier.capture());
-
-        mWifiManager.unregisterTrafficStateCallback(mTrafficStateCallback);
-        verify(mWifiService).unregisterTrafficStateCallback(
-                eq((int) callbackIdentifier.getValue()));
-    }
-
-    /*
-     * Verify client-provided callback is being called through callback proxy on multiple events
-     */
-    @Test
-    public void trafficStateCallbackProxyCallsOnMultipleUpdates() throws Exception {
-        ArgumentCaptor<ITrafficStateCallback.Stub> callbackCaptor =
-                ArgumentCaptor.forClass(ITrafficStateCallback.Stub.class);
-        mWifiManager.registerTrafficStateCallback(new HandlerExecutor(mHandler),
-                mTrafficStateCallback);
-        verify(mWifiService).registerTrafficStateCallback(
-                any(IBinder.class), callbackCaptor.capture(), anyInt());
-
-        InOrder inOrder = inOrder(mTrafficStateCallback);
-
-        callbackCaptor.getValue().onStateChanged(TrafficStateCallback.DATA_ACTIVITY_IN);
-        callbackCaptor.getValue().onStateChanged(TrafficStateCallback.DATA_ACTIVITY_INOUT);
-        callbackCaptor.getValue().onStateChanged(TrafficStateCallback.DATA_ACTIVITY_OUT);
-
-        mLooper.dispatchAll();
-        inOrder.verify(mTrafficStateCallback).onStateChanged(
-                TrafficStateCallback.DATA_ACTIVITY_IN);
-        inOrder.verify(mTrafficStateCallback).onStateChanged(
-                TrafficStateCallback.DATA_ACTIVITY_INOUT);
-        inOrder.verify(mTrafficStateCallback).onStateChanged(
-                TrafficStateCallback.DATA_ACTIVITY_OUT);
-    }
-
-    /**
-     * Verify client-provided callback is being called on the correct thread
-     */
-    @Test
-    public void trafficStateCallbackIsCalledOnCorrectThread() throws Exception {
-        ArgumentCaptor<ITrafficStateCallback.Stub> callbackCaptor =
-                ArgumentCaptor.forClass(ITrafficStateCallback.Stub.class);
-        TestLooper altLooper = new TestLooper();
-        Handler altHandler = new Handler(altLooper.getLooper());
-        mWifiManager.registerTrafficStateCallback(new HandlerExecutor(altHandler),
-                mTrafficStateCallback);
-        verify(mContext, never()).getMainLooper();
-        verify(mContext, never()).getMainExecutor();
-        verify(mWifiService).registerTrafficStateCallback(
-                any(IBinder.class), callbackCaptor.capture(), anyInt());
-
-        assertEquals(0, altLooper.dispatchAll());
-        callbackCaptor.getValue().onStateChanged(TrafficStateCallback.DATA_ACTIVITY_INOUT);
-        assertEquals(1, altLooper.dispatchAll());
-        verify(mTrafficStateCallback).onStateChanged(TrafficStateCallback.DATA_ACTIVITY_INOUT);
-    }
-
-    /**
-     * Verify the call to registerNetworkRequestMatchCallback goes to WifiServiceImpl.
-     */
-    @Test
-    public void registerNetworkRequestMatchCallbackCallGoesToWifiServiceImpl()
-            throws Exception {
-        ArgumentCaptor<INetworkRequestMatchCallback.Stub> callbackCaptor =
-                ArgumentCaptor.forClass(INetworkRequestMatchCallback.Stub.class);
-        mWifiManager.registerNetworkRequestMatchCallback(
-                new HandlerExecutor(new Handler(mLooper.getLooper())),
-                mNetworkRequestMatchCallback);
-        verify(mWifiService).registerNetworkRequestMatchCallback(
-                any(IBinder.class), callbackCaptor.capture(), anyInt());
-
-        INetworkRequestUserSelectionCallback iUserSelectionCallback =
-                mock(INetworkRequestUserSelectionCallback.class);
-
-        assertEquals(0, mLooper.dispatchAll());
-
-        callbackCaptor.getValue().onAbort();
-        assertEquals(1, mLooper.dispatchAll());
-        verify(mNetworkRequestMatchCallback).onAbort();
-
-        callbackCaptor.getValue().onMatch(new ArrayList<ScanResult>());
-        assertEquals(1, mLooper.dispatchAll());
-        verify(mNetworkRequestMatchCallback).onMatch(anyList());
-
-        callbackCaptor.getValue().onUserSelectionConnectSuccess(new WifiConfiguration());
-        assertEquals(1, mLooper.dispatchAll());
-        verify(mNetworkRequestMatchCallback).onUserSelectionConnectSuccess(
-                any(WifiConfiguration.class));
-
-        callbackCaptor.getValue().onUserSelectionConnectFailure(new WifiConfiguration());
-        assertEquals(1, mLooper.dispatchAll());
-        verify(mNetworkRequestMatchCallback).onUserSelectionConnectFailure(
-                any(WifiConfiguration.class));
-    }
-
-    /**
-     * Verify the call to unregisterNetworkRequestMatchCallback goes to WifiServiceImpl.
-     */
-    @Test
-    public void unregisterNetworkRequestMatchCallbackCallGoesToWifiServiceImpl() throws Exception {
-        ArgumentCaptor<Integer> callbackIdentifier = ArgumentCaptor.forClass(Integer.class);
-        mWifiManager.registerNetworkRequestMatchCallback(new HandlerExecutor(mHandler),
-                mNetworkRequestMatchCallback);
-        verify(mWifiService).registerNetworkRequestMatchCallback(
-                any(IBinder.class), any(INetworkRequestMatchCallback.class),
-                callbackIdentifier.capture());
-
-        mWifiManager.unregisterNetworkRequestMatchCallback(mNetworkRequestMatchCallback);
-        verify(mWifiService).unregisterNetworkRequestMatchCallback(
-                eq((int) callbackIdentifier.getValue()));
-    }
-
-    /**
-     * Verify the call to NetworkRequestUserSelectionCallback goes to
-     * WifiServiceImpl.
-     */
-    @Test
-    public void networkRequestUserSelectionCallbackCallGoesToWifiServiceImpl()
-            throws Exception {
-        ArgumentCaptor<INetworkRequestMatchCallback.Stub> callbackCaptor =
-                ArgumentCaptor.forClass(INetworkRequestMatchCallback.Stub.class);
-        mWifiManager.registerNetworkRequestMatchCallback(
-                new HandlerExecutor(new Handler(mLooper.getLooper())),
-                mNetworkRequestMatchCallback);
-        verify(mWifiService).registerNetworkRequestMatchCallback(
-                any(IBinder.class), callbackCaptor.capture(), anyInt());
-
-        INetworkRequestUserSelectionCallback iUserSelectionCallback =
-                mock(INetworkRequestUserSelectionCallback.class);
-        ArgumentCaptor<NetworkRequestUserSelectionCallback> userSelectionCallbackCaptor =
-                ArgumentCaptor.forClass(NetworkRequestUserSelectionCallback.class);
-        callbackCaptor.getValue().onUserSelectionCallbackRegistration(
-                iUserSelectionCallback);
-        assertEquals(1, mLooper.dispatchAll());
-        verify(mNetworkRequestMatchCallback).onUserSelectionCallbackRegistration(
-                userSelectionCallbackCaptor.capture());
-
-        WifiConfiguration selected = new WifiConfiguration();
-        userSelectionCallbackCaptor.getValue().select(selected);
-        verify(iUserSelectionCallback).select(selected);
-
-        userSelectionCallbackCaptor.getValue().reject();
-        verify(iUserSelectionCallback).reject();
-    }
-
-    /**
-     * Check the call to getAllMatchingWifiConfigs calls getAllMatchingFqdnsForScanResults and
-     * getWifiConfigsForPasspointProfiles of WifiService in order.
-     */
-    @Test
-    public void testGetAllMatchingWifiConfigs() throws Exception {
-        Map<String, List<ScanResult>> passpointProfiles = new HashMap<>();
-        passpointProfiles.put("www.test.com_987a69bca26", new ArrayList<>());
-        when(mWifiService.getAllMatchingPasspointProfilesForScanResults(
-                any(List.class))).thenReturn(passpointProfiles);
-        InOrder inOrder = inOrder(mWifiService);
-
-        mWifiManager.getAllMatchingWifiConfigs(new ArrayList<>());
-
-        inOrder.verify(mWifiService).getAllMatchingPasspointProfilesForScanResults(any(List.class));
-        inOrder.verify(mWifiService).getWifiConfigsForPasspointProfiles(any(List.class));
-    }
-
-    /**
-     * Check the call to getMatchingOsuProviders calls getMatchingOsuProviders of WifiService
-     * with the provided a list of ScanResult.
-     */
-    @Test
-    public void testGetMatchingOsuProviders() throws Exception {
-        mWifiManager.getMatchingOsuProviders(new ArrayList<>());
-
-        verify(mWifiService).getMatchingOsuProviders(any(List.class));
-    }
-
-    /**
-     * Verify calls to {@link WifiManager#addNetworkSuggestions(List)},
-     * {@link WifiManager#getNetworkSuggestions()} and
-     * {@link WifiManager#removeNetworkSuggestions(List)}.
-     */
-    @Test
-    public void addGetRemoveNetworkSuggestions() throws Exception {
-        List<WifiNetworkSuggestion> testList = new ArrayList<>();
-        when(mWifiService.addNetworkSuggestions(any(List.class), anyString(),
-                nullable(String.class))).thenReturn(STATUS_NETWORK_SUGGESTIONS_SUCCESS);
-        when(mWifiService.removeNetworkSuggestions(any(List.class), anyString())).thenReturn(
-                STATUS_NETWORK_SUGGESTIONS_SUCCESS);
-        when(mWifiService.getNetworkSuggestions(anyString()))
-                .thenReturn(testList);
-
-        assertEquals(STATUS_NETWORK_SUGGESTIONS_SUCCESS,
-                mWifiManager.addNetworkSuggestions(testList));
-        verify(mWifiService).addNetworkSuggestions(anyList(), eq(TEST_PACKAGE_NAME),
-                nullable(String.class));
-
-        assertEquals(testList, mWifiManager.getNetworkSuggestions());
-        verify(mWifiService).getNetworkSuggestions(eq(TEST_PACKAGE_NAME));
-
-        assertEquals(STATUS_NETWORK_SUGGESTIONS_SUCCESS,
-                mWifiManager.removeNetworkSuggestions(new ArrayList<>()));
-        verify(mWifiService).removeNetworkSuggestions(anyList(), eq(TEST_PACKAGE_NAME));
-    }
-
-    /**
-     * Verify call to {@link WifiManager#getMaxNumberOfNetworkSuggestionsPerApp()}.
-     */
-    @Test
-    public void getMaxNumberOfNetworkSuggestionsPerApp() {
-        when(mContext.getSystemServiceName(ActivityManager.class))
-                .thenReturn(Context.ACTIVITY_SERVICE);
-        when(mContext.getSystemService(Context.ACTIVITY_SERVICE))
-                .thenReturn(mActivityManager);
-        when(mActivityManager.isLowRamDevice()).thenReturn(true);
-        assertEquals(256, mWifiManager.getMaxNumberOfNetworkSuggestionsPerApp());
-
-        when(mActivityManager.isLowRamDevice()).thenReturn(false);
-        assertEquals(1024, mWifiManager.getMaxNumberOfNetworkSuggestionsPerApp());
-    }
-
-    /**
-     * Verify getting the factory MAC address.
-     */
-    @Test
-    public void testGetFactoryMacAddress() throws Exception {
-        when(mWifiService.getFactoryMacAddresses()).thenReturn(TEST_MAC_ADDRESSES);
-        assertArrayEquals(TEST_MAC_ADDRESSES, mWifiManager.getFactoryMacAddresses());
-        verify(mWifiService).getFactoryMacAddresses();
-    }
-
-    /**
-     * Verify the call to addOnWifiUsabilityStatsListener goes to WifiServiceImpl.
-     */
-    @Test
-    public void addOnWifiUsabilityStatsListeneroesToWifiServiceImpl() throws Exception {
-        mExecutor = new SynchronousExecutor();
-        mWifiManager.addOnWifiUsabilityStatsListener(mExecutor, mOnWifiUsabilityStatsListener);
-        verify(mWifiService).addOnWifiUsabilityStatsListener(any(IBinder.class),
-                any(IOnWifiUsabilityStatsListener.Stub.class), anyInt());
-    }
-
-    /**
-     * Verify the call to removeOnWifiUsabilityStatsListener goes to WifiServiceImpl.
-     */
-    @Test
-    public void removeOnWifiUsabilityListenerGoesToWifiServiceImpl() throws Exception {
-        ArgumentCaptor<Integer> listenerIdentifier = ArgumentCaptor.forClass(Integer.class);
-        mExecutor = new SynchronousExecutor();
-        mWifiManager.addOnWifiUsabilityStatsListener(mExecutor, mOnWifiUsabilityStatsListener);
-        verify(mWifiService).addOnWifiUsabilityStatsListener(any(IBinder.class),
-                any(IOnWifiUsabilityStatsListener.Stub.class), listenerIdentifier.capture());
-
-        mWifiManager.removeOnWifiUsabilityStatsListener(mOnWifiUsabilityStatsListener);
-        verify(mWifiService).removeOnWifiUsabilityStatsListener(
-                eq((int) listenerIdentifier.getValue()));
-    }
-
-    /**
-     * Test behavior of isEnhancedOpenSupported
-     */
-    @Test
-    public void testIsEnhancedOpenSupported() throws Exception {
-        when(mWifiService.getSupportedFeatures())
-                .thenReturn(new Long(WIFI_FEATURE_OWE));
-        assertTrue(mWifiManager.isEnhancedOpenSupported());
-        when(mWifiService.getSupportedFeatures())
-                .thenReturn(new Long(~WIFI_FEATURE_OWE));
-        assertFalse(mWifiManager.isEnhancedOpenSupported());
-    }
-
-    /**
-     * Test behavior of isWpa3SaeSupported
-     */
-    @Test
-    public void testIsWpa3SaeSupported() throws Exception {
-        when(mWifiService.getSupportedFeatures())
-                .thenReturn(new Long(WIFI_FEATURE_WPA3_SAE));
-        assertTrue(mWifiManager.isWpa3SaeSupported());
-        when(mWifiService.getSupportedFeatures())
-                .thenReturn(new Long(~WIFI_FEATURE_WPA3_SAE));
-        assertFalse(mWifiManager.isWpa3SaeSupported());
-    }
-
-    /**
-     * Test behavior of isWpa3SuiteBSupported
-     */
-    @Test
-    public void testIsWpa3SuiteBSupported() throws Exception {
-        when(mWifiService.getSupportedFeatures())
-                .thenReturn(new Long(WIFI_FEATURE_WPA3_SUITE_B));
-        assertTrue(mWifiManager.isWpa3SuiteBSupported());
-        when(mWifiService.getSupportedFeatures())
-                .thenReturn(new Long(~WIFI_FEATURE_WPA3_SUITE_B));
-        assertFalse(mWifiManager.isWpa3SuiteBSupported());
-    }
-
-    /**
-     * Test behavior of isEasyConnectSupported
-     */
-    @Test
-    public void testIsEasyConnectSupported() throws Exception {
-        when(mWifiService.getSupportedFeatures())
-                .thenReturn(new Long(WIFI_FEATURE_DPP));
-        assertTrue(mWifiManager.isEasyConnectSupported());
-        when(mWifiService.getSupportedFeatures())
-                .thenReturn(new Long(~WIFI_FEATURE_DPP));
-        assertFalse(mWifiManager.isEasyConnectSupported());
-    }
-
-    /**
-     * Test behavior of {@link WifiManager#addNetwork(WifiConfiguration)}
-     */
-    @Test
-    public void testAddNetwork() throws Exception {
-        WifiConfiguration configuration = new WifiConfiguration();
-        when(mWifiService.addOrUpdateNetwork(any(), anyString()))
-                .thenReturn(TEST_NETWORK_ID);
-
-        assertEquals(mWifiManager.addNetwork(configuration), TEST_NETWORK_ID);
-        verify(mWifiService).addOrUpdateNetwork(configuration, mContext.getOpPackageName());
-
-        // send a null config
-        assertEquals(mWifiManager.addNetwork(null), -1);
-    }
-
-    /**
-     * Test behavior of {@link WifiManager#addNetwork(WifiConfiguration)}
-     */
-    @Test
-    public void testUpdateNetwork() throws Exception {
-        WifiConfiguration configuration = new WifiConfiguration();
-        when(mWifiService.addOrUpdateNetwork(any(), anyString()))
-                .thenReturn(TEST_NETWORK_ID);
-
-        configuration.networkId = TEST_NETWORK_ID;
-        assertEquals(mWifiManager.updateNetwork(configuration), TEST_NETWORK_ID);
-        verify(mWifiService).addOrUpdateNetwork(configuration, mContext.getOpPackageName());
-
-        // config with invalid network ID
-        configuration.networkId = -1;
-        assertEquals(mWifiManager.updateNetwork(configuration), -1);
-
-        // send a null config
-        assertEquals(mWifiManager.updateNetwork(null), -1);
-    }
-
-    /**
-     * Test behavior of {@link WifiManager#enableNetwork(int, boolean)}
-     */
-    @Test
-    public void testEnableNetwork() throws Exception {
-        when(mWifiService.enableNetwork(anyInt(), anyBoolean(), anyString()))
-                .thenReturn(true);
-        assertTrue(mWifiManager.enableNetwork(TEST_NETWORK_ID, true));
-        verify(mWifiService).enableNetwork(TEST_NETWORK_ID, true, mContext.getOpPackageName());
-    }
-
-    /**
-     * Test behavior of {@link WifiManager#disableNetwork(int)}
-     */
-    @Test
-    public void testDisableNetwork() throws Exception {
-        when(mWifiService.disableNetwork(anyInt(), anyString()))
-                .thenReturn(true);
-        assertTrue(mWifiManager.disableNetwork(TEST_NETWORK_ID));
-        verify(mWifiService).disableNetwork(TEST_NETWORK_ID, mContext.getOpPackageName());
-    }
-
-    /**
-     * Test behavior of {@link WifiManager#allowAutojoin(int, boolean)}
-     * @throws Exception
-     */
-    @Test
-    public void testAllowAutojoin() throws Exception {
-        mWifiManager.allowAutojoin(1, true);
-        verify(mWifiService).allowAutojoin(1, true);
-    }
-
-    /**
-     * Test behavior of {@link WifiManager#allowAutojoinPasspoint(String, boolean)}
-     * @throws Exception
-     */
-    @Test
-    public void testAllowAutojoinPasspoint() throws Exception {
-        final String fqdn = "FullyQualifiedDomainName";
-        mWifiManager.allowAutojoinPasspoint(fqdn, true);
-        verify(mWifiService).allowAutojoinPasspoint(fqdn, true);
-    }
-
-    /**
-     * Test behavior of
-     * {@link WifiManager#setMacRandomizationSettingPasspointEnabled(String, boolean)}
-     */
-    @Test
-    public void testSetMacRandomizationSettingPasspointEnabled() throws Exception {
-        final String fqdn = "FullyQualifiedDomainName";
-        mWifiManager.setMacRandomizationSettingPasspointEnabled(fqdn, true);
-        verify(mWifiService).setMacRandomizationSettingPasspointEnabled(fqdn, true);
-    }
-
-    /**
-     * Test behavior of
-     * {@link WifiManager#setMacRandomizationSettingPasspointEnabled(String, boolean)}
-     */
-    @Test
-    public void testSetPasspointMeteredOverride() throws Exception {
-        final String fqdn = "FullyQualifiedDomainName";
-        mWifiManager.setPasspointMeteredOverride(fqdn, METERED_OVERRIDE_METERED);
-        verify(mWifiService).setPasspointMeteredOverride(fqdn, METERED_OVERRIDE_METERED);
-    }
-
-    /**
-     * Test behavior of {@link WifiManager#disconnect()}
-     */
-    @Test
-    public void testDisconnect() throws Exception {
-        when(mWifiService.disconnect(anyString())).thenReturn(true);
-        assertTrue(mWifiManager.disconnect());
-        verify(mWifiService).disconnect(mContext.getOpPackageName());
-    }
-
-    /**
-     * Test behavior of {@link WifiManager#reconnect()}
-     */
-    @Test
-    public void testReconnect() throws Exception {
-        when(mWifiService.reconnect(anyString())).thenReturn(true);
-        assertTrue(mWifiManager.reconnect());
-        verify(mWifiService).reconnect(mContext.getOpPackageName());
-    }
-
-    /**
-     * Test behavior of {@link WifiManager#reassociate()}
-     */
-    @Test
-    public void testReassociate() throws Exception {
-        when(mWifiService.reassociate(anyString())).thenReturn(true);
-        assertTrue(mWifiManager.reassociate());
-        verify(mWifiService).reassociate(mContext.getOpPackageName());
-    }
-
-    /**
-     * Test behavior of {@link WifiManager#getSupportedFeatures()}
-     */
-    @Test
-    public void testGetSupportedFeatures() throws Exception {
-        long supportedFeatures =
-                WIFI_FEATURE_SCANNER
-                        | WIFI_FEATURE_PASSPOINT
-                        | WIFI_FEATURE_P2P;
-        when(mWifiService.getSupportedFeatures())
-                .thenReturn(Long.valueOf(supportedFeatures));
-
-        assertTrue(mWifiManager.isWifiScannerSupported());
-        assertTrue(mWifiManager.isPasspointSupported());
-        assertTrue(mWifiManager.isP2pSupported());
-        assertFalse(mWifiManager.isPortableHotspotSupported());
-        assertFalse(mWifiManager.isDeviceToDeviceRttSupported());
-        assertFalse(mWifiManager.isDeviceToApRttSupported());
-        assertFalse(mWifiManager.isPreferredNetworkOffloadSupported());
-        assertFalse(mWifiManager.isAdditionalStaSupported());
-        assertFalse(mWifiManager.isTdlsSupported());
-        assertFalse(mWifiManager.isOffChannelTdlsSupported());
-        assertFalse(mWifiManager.isEnhancedPowerReportingSupported());
-    }
-
-    /**
-     * Tests that passing a null Executor to {@link WifiManager#getWifiActivityEnergyInfoAsync}
-     * throws an exception.
-     */
-    @Test(expected = NullPointerException.class)
-    public void testGetWifiActivityInfoNullExecutor() throws Exception {
-        mWifiManager.getWifiActivityEnergyInfoAsync(null, mOnWifiActivityEnergyInfoListener);
-    }
-
-    /**
-     * Tests that passing a null listener to {@link WifiManager#getWifiActivityEnergyInfoAsync}
-     * throws an exception.
-     */
-    @Test(expected = NullPointerException.class)
-    public void testGetWifiActivityInfoNullListener() throws Exception {
-        mWifiManager.getWifiActivityEnergyInfoAsync(mExecutor, null);
-    }
-
-    /** Tests that the listener runs on the correct Executor. */
-    @Test
-    public void testGetWifiActivityInfoRunsOnCorrectExecutor() throws Exception {
-        mWifiManager.getWifiActivityEnergyInfoAsync(mExecutor, mOnWifiActivityEnergyInfoListener);
-        ArgumentCaptor<IOnWifiActivityEnergyInfoListener> listenerCaptor =
-                ArgumentCaptor.forClass(IOnWifiActivityEnergyInfoListener.class);
-        verify(mWifiService).getWifiActivityEnergyInfoAsync(listenerCaptor.capture());
-        IOnWifiActivityEnergyInfoListener listener = listenerCaptor.getValue();
-        listener.onWifiActivityEnergyInfo(mWifiActivityEnergyInfo);
-        verify(mExecutor).execute(any());
-
-        // ensure that the executor is only triggered once
-        listener.onWifiActivityEnergyInfo(mWifiActivityEnergyInfo);
-        verify(mExecutor).execute(any());
-    }
-
-    /** Tests that the correct listener runs. */
-    @Test
-    public void testGetWifiActivityInfoRunsCorrectListener() throws Exception {
-        int[] flag = {0};
-        mWifiManager.getWifiActivityEnergyInfoAsync(
-                new SynchronousExecutor(), info -> flag[0]++);
-        ArgumentCaptor<IOnWifiActivityEnergyInfoListener> listenerCaptor =
-                ArgumentCaptor.forClass(IOnWifiActivityEnergyInfoListener.class);
-        verify(mWifiService).getWifiActivityEnergyInfoAsync(listenerCaptor.capture());
-        IOnWifiActivityEnergyInfoListener listener = listenerCaptor.getValue();
-        listener.onWifiActivityEnergyInfo(mWifiActivityEnergyInfo);
-        assertEquals(1, flag[0]);
-
-        // ensure that the listener is only triggered once
-        listener.onWifiActivityEnergyInfo(mWifiActivityEnergyInfo);
-        assertEquals(1, flag[0]);
-    }
-
-    /**
-     * Test behavior of {@link WifiManager#getConnectionInfo()}
-     */
-    @Test
-    public void testGetConnectionInfo() throws Exception {
-        WifiInfo wifiInfo = new WifiInfo();
-        when(mWifiService.getConnectionInfo(anyString(), nullable(String.class))).thenReturn(
-                wifiInfo);
-
-        assertEquals(wifiInfo, mWifiManager.getConnectionInfo());
-    }
-
-    /**
-     * Test behavior of {@link WifiManager#is5GHzBandSupported()}
-     */
-    @Test
-    public void testIs5GHzBandSupported() throws Exception {
-        when(mWifiService.is5GHzBandSupported()).thenReturn(true);
-        assertTrue(mWifiManager.is5GHzBandSupported());
-        verify(mWifiService).is5GHzBandSupported();
-    }
-
-    /**
-     * Test behavior of {@link WifiManager#is6GHzBandSupported()}
-     */
-    @Test
-    public void testIs6GHzBandSupported() throws Exception {
-        when(mWifiService.is6GHzBandSupported()).thenReturn(true);
-        assertTrue(mWifiManager.is6GHzBandSupported());
-        verify(mWifiService).is6GHzBandSupported();
-    }
-
-    /**
-     * Test behavior of {@link WifiManager#isWifiStandardSupported()}
-     */
-    @Test
-    public void testIsWifiStandardSupported() throws Exception {
-        int standard = ScanResult.WIFI_STANDARD_11AX;
-        when(mWifiService.isWifiStandardSupported(standard)).thenReturn(true);
-        assertTrue(mWifiManager.isWifiStandardSupported(standard));
-        verify(mWifiService).isWifiStandardSupported(standard);
-    }
-
-    /**
-     * Test behavior of {@link WifiManager#getDhcpInfo()}
-     */
-    @Test
-    public void testGetDhcpInfo() throws Exception {
-        DhcpInfo dhcpInfo = new DhcpInfo();
-
-        when(mWifiService.getDhcpInfo()).thenReturn(dhcpInfo);
-        assertEquals(dhcpInfo, mWifiManager.getDhcpInfo());
-        verify(mWifiService).getDhcpInfo();
-    }
-
-    /**
-     * Test behavior of {@link WifiManager#setWifiEnabled(boolean)}
-     */
-    @Test
-    public void testSetWifiEnabled() throws Exception {
-        when(mWifiService.setWifiEnabled(anyString(), anyBoolean())).thenReturn(true);
-        assertTrue(mWifiManager.setWifiEnabled(true));
-        verify(mWifiService).setWifiEnabled(mContext.getOpPackageName(), true);
-        assertTrue(mWifiManager.setWifiEnabled(false));
-        verify(mWifiService).setWifiEnabled(mContext.getOpPackageName(), false);
-    }
-
-    /**
-     * Test behavior of {@link WifiManager#connect(int, ActionListener)}
-     */
-    @Test
-    public void testConnectWithListener() throws Exception {
-        ActionListener externalListener = mock(ActionListener.class);
-        mWifiManager.connect(TEST_NETWORK_ID, externalListener);
-
-        ArgumentCaptor<IActionListener> binderListenerCaptor =
-                ArgumentCaptor.forClass(IActionListener.class);
-        verify(mWifiService).connect(eq(null), eq(TEST_NETWORK_ID), any(Binder.class),
-                binderListenerCaptor.capture(), anyInt());
-        assertNotNull(binderListenerCaptor.getValue());
-
-        // Trigger on success.
-        binderListenerCaptor.getValue().onSuccess();
-        mLooper.dispatchAll();
-        verify(externalListener).onSuccess();
-
-        // Trigger on failure.
-        binderListenerCaptor.getValue().onFailure(BUSY);
-        mLooper.dispatchAll();
-        verify(externalListener).onFailure(BUSY);
-    }
-
-    /**
-     * Test behavior of {@link WifiManager#connect(int, ActionListener)}
-     */
-    @Test
-    public void testConnectWithListenerHandleSecurityException() throws Exception {
-        doThrow(new SecurityException()).when(mWifiService)
-                .connect(eq(null), anyInt(), any(IBinder.class),
-                        any(IActionListener.class), anyInt());
-        ActionListener externalListener = mock(ActionListener.class);
-        mWifiManager.connect(TEST_NETWORK_ID, externalListener);
-
-        mLooper.dispatchAll();
-        verify(externalListener).onFailure(NOT_AUTHORIZED);
-    }
-
-    /**
-     * Test behavior of {@link WifiManager#connect(int, ActionListener)}
-     */
-    @Test
-    public void testConnectWithListenerHandleRemoteException() throws Exception {
-        doThrow(new RemoteException()).when(mWifiService)
-                .connect(eq(null), anyInt(), any(IBinder.class),
-                        any(IActionListener.class), anyInt());
-        ActionListener externalListener = mock(ActionListener.class);
-        mWifiManager.connect(TEST_NETWORK_ID, externalListener);
-
-        mLooper.dispatchAll();
-        verify(externalListener).onFailure(ERROR);
-    }
-
-    /**
-     * Test behavior of {@link WifiManager#connect(int, ActionListener)}
-     */
-    @Test
-    public void testConnectWithoutListener() throws Exception {
-        WifiConfiguration configuration = new WifiConfiguration();
-        mWifiManager.connect(configuration, null);
-
-        verify(mWifiService).connect(configuration, WifiConfiguration.INVALID_NETWORK_ID, null,
-                null, 0);
-    }
-
-    /**
-     * Verify an IllegalArgumentException is thrown if callback is not provided.
-     */
-    @Test(expected = IllegalArgumentException.class)
-    public void testRegisterScanResultsCallbackWithNullCallback() throws Exception {
-        mWifiManager.registerScanResultsCallback(mExecutor, null);
-    }
-
-    /**
-     * Verify an IllegalArgumentException is thrown if executor is not provided.
-     */
-    @Test(expected = IllegalArgumentException.class)
-    public void testRegisterCallbackWithNullExecutor() throws Exception {
-        mWifiManager.registerScanResultsCallback(null, mScanResultsCallback);
-    }
-
-    /**
-     * Verify client provided callback is being called to the right callback.
-     */
-    @Test
-    public void testAddScanResultsCallbackAndReceiveEvent() throws Exception {
-        ArgumentCaptor<IScanResultsCallback.Stub> callbackCaptor =
-                ArgumentCaptor.forClass(IScanResultsCallback.Stub.class);
-        mWifiManager.registerScanResultsCallback(new SynchronousExecutor(), mScanResultsCallback);
-        verify(mWifiService).registerScanResultsCallback(callbackCaptor.capture());
-        callbackCaptor.getValue().onScanResultsAvailable();
-        verify(mRunnable).run();
-    }
-
-    /**
-     * Verify client provided callback is being called to the right executor.
-     */
-    @Test
-    public void testRegisterScanResultsCallbackWithTheTargetExecutor() throws Exception {
-        ArgumentCaptor<IScanResultsCallback.Stub> callbackCaptor =
-                ArgumentCaptor.forClass(IScanResultsCallback.Stub.class);
-        mWifiManager.registerScanResultsCallback(mExecutor, mScanResultsCallback);
-        verify(mWifiService).registerScanResultsCallback(callbackCaptor.capture());
-        mWifiManager.registerScanResultsCallback(mAnotherExecutor, mScanResultsCallback);
-        callbackCaptor.getValue().onScanResultsAvailable();
-        verify(mExecutor, never()).execute(any(Runnable.class));
-        verify(mAnotherExecutor).execute(any(Runnable.class));
-    }
-
-    /**
-     * Verify client register unregister then register again, to ensure callback still works.
-     */
-    @Test
-    public void testRegisterUnregisterThenRegisterAgainWithScanResultCallback() throws Exception {
-        ArgumentCaptor<IScanResultsCallback.Stub> callbackCaptor =
-                ArgumentCaptor.forClass(IScanResultsCallback.Stub.class);
-        mWifiManager.registerScanResultsCallback(new SynchronousExecutor(), mScanResultsCallback);
-        verify(mWifiService).registerScanResultsCallback(callbackCaptor.capture());
-        mWifiManager.unregisterScanResultsCallback(mScanResultsCallback);
-        callbackCaptor.getValue().onScanResultsAvailable();
-        verify(mRunnable, never()).run();
-        mWifiManager.registerScanResultsCallback(new SynchronousExecutor(), mScanResultsCallback);
-        callbackCaptor.getValue().onScanResultsAvailable();
-        verify(mRunnable).run();
-    }
-
-    /**
-     * Verify client unregisterScanResultsCallback.
-     */
-    @Test
-    public void testUnregisterScanResultsCallback() throws Exception {
-        mWifiManager.unregisterScanResultsCallback(mScanResultsCallback);
-        verify(mWifiService).unregisterScanResultsCallback(any());
-    }
-
-    /**
-     * Verify client unregisterScanResultsCallback with null callback will cause an exception.
-     */
-    @Test(expected = IllegalArgumentException.class)
-    public void testUnregisterScanResultsCallbackWithNullCallback() throws Exception {
-        mWifiManager.unregisterScanResultsCallback(null);
-    }
-
-    /**
-     * Verify an IllegalArgumentException is thrown if executor not provided.
-     */
-    @Test(expected = IllegalArgumentException.class)
-    public void testAddSuggestionConnectionStatusListenerWithNullExecutor() {
-        mWifiManager.addSuggestionConnectionStatusListener(null, mListener);
-    }
-
-    /**
-     * Verify an IllegalArgumentException is thrown if listener is not provided.
-     */
-    @Test(expected = IllegalArgumentException.class)
-    public void testAddSuggestionConnectionStatusListenerWithNullListener() {
-        mWifiManager.addSuggestionConnectionStatusListener(mExecutor, null);
-    }
-
-    /**
-     * Verify client provided listener is being called to the right listener.
-     */
-    @Test
-    public void testAddSuggestionConnectionStatusListenerAndReceiveEvent() throws Exception {
-        int errorCode = STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION;
-        ArgumentCaptor<ISuggestionConnectionStatusListener.Stub> callbackCaptor =
-                ArgumentCaptor.forClass(ISuggestionConnectionStatusListener.Stub.class);
-        Executor executor = new SynchronousExecutor();
-        mWifiManager.addSuggestionConnectionStatusListener(executor, mListener);
-        verify(mWifiService).registerSuggestionConnectionStatusListener(any(IBinder.class),
-                callbackCaptor.capture(), anyInt(), anyString(), nullable(String.class));
-        callbackCaptor.getValue().onConnectionStatus(mWifiNetworkSuggestion, errorCode);
-        verify(mListener).onConnectionStatus(any(WifiNetworkSuggestion.class), eq(errorCode));
-    }
-
-    /**
-     * Verify client provided listener is being called to the right executor.
-     */
-    @Test
-    public void testAddSuggestionConnectionStatusListenerWithTheTargetExecutor() throws Exception {
-        int errorCode = STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION;
-        ArgumentCaptor<ISuggestionConnectionStatusListener.Stub> callbackCaptor =
-                ArgumentCaptor.forClass(ISuggestionConnectionStatusListener.Stub.class);
-        mWifiManager.addSuggestionConnectionStatusListener(mExecutor, mListener);
-        verify(mWifiService).registerSuggestionConnectionStatusListener(any(IBinder.class),
-                callbackCaptor.capture(), anyInt(), anyString(), nullable(String.class));
-        callbackCaptor.getValue().onConnectionStatus(any(WifiNetworkSuggestion.class), errorCode);
-        verify(mExecutor).execute(any(Runnable.class));
-    }
-
-    /**
-     * Verify an IllegalArgumentException is thrown if listener is not provided.
-     */
-    @Test(expected = IllegalArgumentException.class)
-    public void testRemoveSuggestionConnectionListenerWithNullListener() {
-        mWifiManager.removeSuggestionConnectionStatusListener(null);
-    }
-
-    /**
-     * Verify removeSuggestionConnectionListener.
-     */
-    @Test
-    public void testRemoveSuggestionConnectionListener() throws Exception {
-        mWifiManager.removeSuggestionConnectionStatusListener(mListener);
-        verify(mWifiService).unregisterSuggestionConnectionStatusListener(anyInt(), anyString());
-    }
-
-    /** Test {@link WifiManager#calculateSignalLevel(int)} */
-    @Test
-    public void testCalculateSignalLevel() throws Exception {
-        when(mWifiService.calculateSignalLevel(anyInt())).thenReturn(3);
-        int actual = mWifiManager.calculateSignalLevel(-60);
-        verify(mWifiService).calculateSignalLevel(-60);
-        assertEquals(3, actual);
-    }
-
-    /** Test {@link WifiManager#getMaxSignalLevel()} */
-    @Test
-    public void testGetMaxSignalLevel() throws Exception {
-        when(mWifiService.calculateSignalLevel(anyInt())).thenReturn(4);
-        int actual = mWifiManager.getMaxSignalLevel();
-        verify(mWifiService).calculateSignalLevel(Integer.MAX_VALUE);
-        assertEquals(4, actual);
-    }
-
-    /*
-     * Test behavior of isWapiSupported
-     * @throws Exception
-     */
-    @Test
-    public void testIsWapiSupported() throws Exception {
-        when(mWifiService.getSupportedFeatures())
-                .thenReturn(new Long(WifiManager.WIFI_FEATURE_WAPI));
-        assertTrue(mWifiManager.isWapiSupported());
-        when(mWifiService.getSupportedFeatures())
-                .thenReturn(new Long(~WifiManager.WIFI_FEATURE_WAPI));
-        assertFalse(mWifiManager.isWapiSupported());
-    }
-
-    /*
-     * Test that DPP channel list is parsed correctly
-     */
-    @Test
-    public void testparseDppChannelList() throws Exception {
-        String channelList = "81/1,2,3,4,5,6,7,8,9,10,11,115/36,40,44,48";
-        SparseArray<int[]> expectedResult = new SparseArray<>();
-        expectedResult.append(81, new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11});
-        expectedResult.append(115, new int[]{36, 40, 44, 48});
-
-        SparseArray<int[]> result = WifiManager.parseDppChannelList(channelList);
-        assertEquals(expectedResult.size(), result.size());
-
-        int index = 0;
-        int key;
-
-        // Compare the two primitive int arrays
-        do {
-            try {
-                key = result.keyAt(index);
-            } catch (java.lang.ArrayIndexOutOfBoundsException e) {
-                break;
-            }
-            int[] expected = expectedResult.get(key);
-            int[] output = result.get(key);
-            assertEquals(expected.length, output.length);
-            for (int i = 0; i < output.length; i++) {
-                assertEquals(expected[i], output[i]);
-            }
-            index++;
-        } while (true);
-    }
-
-    /*
-     * Test that DPP channel list parser gracefully fails for invalid input
-     */
-    @Test
-    public void testparseDppChannelListWithInvalidFormats() throws Exception {
-        String channelList = "1,2,3,4,5,6,7,8,9,10,11,36,40,44,48";
-        SparseArray<int[]> result = WifiManager.parseDppChannelList(channelList);
-        assertEquals(result.size(), 0);
-
-        channelList = "ajgalskgjalskjg3-09683dh";
-        result = WifiManager.parseDppChannelList(channelList);
-        assertEquals(result.size(), 0);
-
-        channelList = "13/abc,46////";
-        result = WifiManager.parseDppChannelList(channelList);
-        assertEquals(result.size(), 0);
-
-        channelList = "11/4,5,13/";
-        result = WifiManager.parseDppChannelList(channelList);
-        assertEquals(result.size(), 0);
-
-        channelList = "/24,6";
-        result = WifiManager.parseDppChannelList(channelList);
-        assertEquals(result.size(), 0);
-    }
-
-    /**
-     * Test getWifiConfigsForMatchedNetworkSuggestions for given scanResults.
-     */
-    @Test
-    public void testGetWifiConfigsForMatchedNetworkSuggestions() throws Exception {
-        List<WifiConfiguration> testResults = new ArrayList<>();
-        testResults.add(new WifiConfiguration());
-
-        when(mWifiService.getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(any(List.class)))
-                .thenReturn(testResults);
-        assertEquals(testResults, mWifiManager
-                .getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(new ArrayList<>()));
-    }
-
-    /**
-     * Verify the call to setWifiConnectedNetworkScorer goes to WifiServiceImpl.
-     */
-    @Test
-    public void setWifiConnectedNetworkScorerGoesToWifiServiceImpl() throws Exception {
-        mExecutor = new SynchronousExecutor();
-        mWifiManager.setWifiConnectedNetworkScorer(mExecutor, mWifiConnectedNetworkScorer);
-        verify(mWifiService).setWifiConnectedNetworkScorer(any(IBinder.class),
-                any(IWifiConnectedNetworkScorer.Stub.class));
-    }
-
-    /**
-     * Verify the call to clearWifiConnectedNetworkScorer goes to WifiServiceImpl.
-     */
-    @Test
-    public void clearWifiConnectedNetworkScorerGoesToWifiServiceImpl() throws Exception {
-        mExecutor = new SynchronousExecutor();
-        mWifiManager.setWifiConnectedNetworkScorer(mExecutor, mWifiConnectedNetworkScorer);
-        verify(mWifiService).setWifiConnectedNetworkScorer(any(IBinder.class),
-                any(IWifiConnectedNetworkScorer.Stub.class));
-
-        mWifiManager.clearWifiConnectedNetworkScorer();
-        verify(mWifiService).clearWifiConnectedNetworkScorer();
-    }
-
-    /**
-     * Verify that Wi-Fi connected scorer receives score update observer after registeration.
-     */
-    @Test
-    public void verifyScorerReceiveScoreUpdateObserverAfterRegistration() throws Exception {
-        mExecutor = new SynchronousExecutor();
-        mWifiManager.setWifiConnectedNetworkScorer(mExecutor, mWifiConnectedNetworkScorer);
-        ArgumentCaptor<IWifiConnectedNetworkScorer.Stub> scorerCaptor =
-                ArgumentCaptor.forClass(IWifiConnectedNetworkScorer.Stub.class);
-        verify(mWifiService).setWifiConnectedNetworkScorer(any(IBinder.class),
-                scorerCaptor.capture());
-        scorerCaptor.getValue().onSetScoreUpdateObserver(any());
-        mLooper.dispatchAll();
-        verify(mWifiConnectedNetworkScorer).onSetScoreUpdateObserver(any());
-    }
-
-    /**
-     * Verify that Wi-Fi connected scorer receives session ID when onStart/onStop methods
-     * are called.
-     */
-    @Test
-    public void verifyScorerReceiveSessionIdWhenStartStopIsCalled() throws Exception {
-        mExecutor = new SynchronousExecutor();
-        mWifiManager.setWifiConnectedNetworkScorer(mExecutor, mWifiConnectedNetworkScorer);
-        ArgumentCaptor<IWifiConnectedNetworkScorer.Stub> callbackCaptor =
-                ArgumentCaptor.forClass(IWifiConnectedNetworkScorer.Stub.class);
-        verify(mWifiService).setWifiConnectedNetworkScorer(any(IBinder.class),
-                callbackCaptor.capture());
-        callbackCaptor.getValue().onStart(0);
-        callbackCaptor.getValue().onStop(10);
-        mLooper.dispatchAll();
-        verify(mWifiConnectedNetworkScorer).onStart(0);
-        verify(mWifiConnectedNetworkScorer).onStop(10);
-    }
-
-    @Test
-    public void testScanThrottle() throws Exception {
-        mWifiManager.setScanThrottleEnabled(true);
-        verify(mWifiService).setScanThrottleEnabled(true);
-
-        when(mWifiService.isScanThrottleEnabled()).thenReturn(false);
-        assertFalse(mWifiManager.isScanThrottleEnabled());
-        verify(mWifiService).isScanThrottleEnabled();
-    }
-
-    @Test
-    public void testAutoWakeup() throws Exception {
-        mWifiManager.setAutoWakeupEnabled(true);
-        verify(mWifiService).setAutoWakeupEnabled(true);
-
-        when(mWifiService.isAutoWakeupEnabled()).thenReturn(false);
-        assertFalse(mWifiManager.isAutoWakeupEnabled());
-        verify(mWifiService).isAutoWakeupEnabled();
-    }
-
-
-    @Test
-    public void testScanAvailable() throws Exception {
-        mWifiManager.setScanAlwaysAvailable(true);
-        verify(mWifiService).setScanAlwaysAvailable(true);
-
-        when(mWifiService.isScanAlwaysAvailable()).thenReturn(false);
-        assertFalse(mWifiManager.isScanAlwaysAvailable());
-        verify(mWifiService).isScanAlwaysAvailable();
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkAgentSpecifierTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkAgentSpecifierTest.java
deleted file mode 100644
index d479aac..0000000
--- a/wifi/tests/src/android/net/wifi/WifiNetworkAgentSpecifierTest.java
+++ /dev/null
@@ -1,395 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import android.net.MacAddress;
-import android.net.MatchAllNetworkSpecifier;
-import android.os.Parcel;
-import android.os.PatternMatcher;
-import android.util.Pair;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-/**
- * Unit tests for {@link android.net.wifi.WifiNetworkAgentSpecifier}.
- */
-@SmallTest
-public class WifiNetworkAgentSpecifierTest {
-    private static final String TEST_SSID = "Test123";
-    private static final String TEST_SSID_PATTERN = "Test";
-    private static final String TEST_SSID_1 = "456test";
-    private static final String TEST_BSSID = "12:12:12:aa:0b:c0";
-    private static final String TEST_BSSID_OUI_BASE_ADDRESS = "12:12:12:00:00:00";
-    private static final String TEST_BSSID_OUI_MASK = "ff:ff:ff:00:00:00";
-    private static final String TEST_BSSID_1 = "aa:cc:12:aa:0b:c0";
-    private static final String TEST_PRESHARED_KEY = "\"Test123\"";
-
-    /**
-     * Validate that parcel marshalling/unmarshalling works
-     */
-    @Test
-    public void testWifiNetworkAgentSpecifierParcel() {
-        WifiNetworkAgentSpecifier specifier = createDefaultNetworkAgentSpecifier();
-
-        Parcel parcelW = Parcel.obtain();
-        specifier.writeToParcel(parcelW, 0);
-        byte[] bytes = parcelW.marshall();
-        parcelW.recycle();
-
-        Parcel parcelR = Parcel.obtain();
-        parcelR.unmarshall(bytes, 0, bytes.length);
-        parcelR.setDataPosition(0);
-        WifiNetworkAgentSpecifier parcelSpecifier =
-                WifiNetworkAgentSpecifier.CREATOR.createFromParcel(parcelR);
-
-        assertEquals(specifier, parcelSpecifier);
-    }
-
-    /**
-     * Validate NetworkAgentSpecifier equals with itself.
-     * a) Create network agent specifier 1 for WPA_PSK network
-     * b) Create network agent specifier 2 with the same params as specifier 1.
-     * c) Ensure that the specifier 2 equals specifier 1.
-     */
-    @Test
-    public void testWifiNetworkAgentSpecifierEqualsSame() {
-        WifiNetworkAgentSpecifier specifier1 = createDefaultNetworkAgentSpecifier();
-        WifiNetworkAgentSpecifier specifier2 = createDefaultNetworkAgentSpecifier();
-
-        assertTrue(specifier2.equals(specifier1));
-    }
-
-    /**
-     * Validate NetworkAgentSpecifier equals between instances of {@link WifiNetworkAgentSpecifier}.
-     * a) Create network agent specifier 1 for WPA_PSK network
-     * b) Create network agent specifier 2 with different key mgmt params.
-     * c) Ensure that the specifier 2 does not equal specifier 1.
-     */
-    @Test
-    public void testWifiNetworkAgentSpecifierDoesNotEqualsWhenKeyMgmtDifferent() {
-        WifiConfiguration wifiConfiguration1 = createDefaultWifiConfiguration();
-        WifiNetworkAgentSpecifier specifier1 =
-                new WifiNetworkAgentSpecifier(
-                        wifiConfiguration1);
-
-        WifiConfiguration wifiConfiguration2 = new WifiConfiguration(wifiConfiguration1);
-        wifiConfiguration2.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
-        WifiNetworkAgentSpecifier specifier2 =
-                new WifiNetworkAgentSpecifier(
-                        wifiConfiguration2);
-
-        assertFalse(specifier2.equals(specifier1));
-    }
-
-    /**
-     * Validate NetworkAgentSpecifier equals between instances of {@link WifiNetworkAgentSpecifier}.
-     * a) Create network agent specifier 1 for WPA_PSK network
-     * b) Create network agent specifier 2 with different SSID.
-     * c) Ensure that the specifier 2 does not equal specifier 1.
-     */
-    @Test
-    public void testWifiNetworkAgentSpecifierDoesNotSatisifyWhenSsidDifferent() {
-        WifiConfiguration wifiConfiguration1 = createDefaultWifiConfiguration();
-        WifiNetworkAgentSpecifier specifier1 =
-                new WifiNetworkAgentSpecifier(
-                        wifiConfiguration1);
-
-        WifiConfiguration wifiConfiguration2 = new WifiConfiguration(wifiConfiguration1);
-        wifiConfiguration2.SSID = TEST_SSID_1;
-        WifiNetworkAgentSpecifier specifier2 =
-                new WifiNetworkAgentSpecifier(
-                        wifiConfiguration2);
-
-        assertFalse(specifier2.equals(specifier1));
-    }
-
-    /**
-     * Validate NetworkAgentSpecifier equals between instances of {@link WifiNetworkAgentSpecifier}.
-     * a) Create network agent specifier 1 for WPA_PSK network
-     * b) Create network agent specifier 2 with different BSSID.
-     * c) Ensure that the specifier 2 does not equal specifier 1.
-     */
-    @Test
-    public void testWifiNetworkAgentSpecifierDoesNotSatisifyWhenBssidDifferent() {
-        WifiConfiguration wifiConfiguration1 = createDefaultWifiConfiguration();
-        WifiNetworkAgentSpecifier specifier1 =
-                new WifiNetworkAgentSpecifier(
-                        wifiConfiguration1);
-
-        WifiConfiguration wifiConfiguration2 = new WifiConfiguration(wifiConfiguration1);
-        wifiConfiguration2.BSSID = TEST_BSSID_1;
-        WifiNetworkAgentSpecifier specifier2 =
-                new WifiNetworkAgentSpecifier(
-                        wifiConfiguration2);
-
-        assertFalse(specifier2.equals(specifier1));
-    }
-
-    /**
-     * Validate NetworkAgentSpecifier matching.
-     * a) Create a network agent specifier for WPA_PSK network
-     * b) Ensure that the specifier matches {@code null} and {@link MatchAllNetworkSpecifier}
-     * specifiers.
-     */
-    @Test
-    public void testWifiNetworkAgentSpecifierSatisifiesNullAndAllMatch() {
-        WifiNetworkAgentSpecifier specifier = createDefaultNetworkAgentSpecifier();
-
-        assertTrue(specifier.canBeSatisfiedBy(null));
-        assertTrue(specifier.canBeSatisfiedBy(new MatchAllNetworkSpecifier()));
-    }
-
-    /**
-     * Validate NetworkAgentSpecifier matching with itself.
-     * a) Create network agent specifier 1 for WPA_PSK network
-     * b) Create network agent specifier 2 with the same params as specifier 1.
-     * c) Ensure that the agent specifier is satisfied by itself.
-     */
-    @Test
-    public void testWifiNetworkAgentSpecifierDoesSatisifySame() {
-        WifiNetworkAgentSpecifier specifier1 = createDefaultNetworkAgentSpecifier();
-        WifiNetworkAgentSpecifier specifier2 = createDefaultNetworkAgentSpecifier();
-
-        assertTrue(specifier2.canBeSatisfiedBy(specifier1));
-    }
-
-    /**
-     * Validate {@link WifiNetworkAgentSpecifier} with {@link WifiNetworkSpecifier} matching.
-     * a) Create network agent specifier for WPA_PSK network
-     * b) Create network specifier with matching SSID pattern.
-     * c) Ensure that the agent specifier is satisfied by specifier.
-     */
-    @Test
-    public void
-            testWifiNetworkAgentSpecifierSatisfiesNetworkSpecifierWithSsidPattern() {
-        WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier = createDefaultNetworkAgentSpecifier();
-
-        PatternMatcher ssidPattern =
-                new PatternMatcher(TEST_SSID_PATTERN, PatternMatcher.PATTERN_PREFIX);
-        Pair<MacAddress, MacAddress> bssidPattern =
-                Pair.create(WifiManager.ALL_ZEROS_MAC_ADDRESS, WifiManager.ALL_ZEROS_MAC_ADDRESS);
-        WifiConfiguration wificonfigurationNetworkSpecifier = new WifiConfiguration();
-        wificonfigurationNetworkSpecifier.allowedKeyManagement
-                .set(WifiConfiguration.KeyMgmt.WPA_PSK);
-        WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
-                ssidPattern,
-                bssidPattern,
-                wificonfigurationNetworkSpecifier);
-
-        assertTrue(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier));
-        assertTrue(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier));
-    }
-
-    /**
-     * Validate {@link WifiNetworkAgentSpecifier} with {@link WifiNetworkSpecifier} matching.
-     * a) Create network agent specifier for WPA_PSK network
-     * b) Create network specifier with matching BSSID pattern.
-     * c) Ensure that the agent specifier is satisfied by specifier.
-     */
-    @Test
-    public void
-            testWifiNetworkAgentSpecifierSatisfiesNetworkSpecifierWithBssidPattern() {
-        WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier = createDefaultNetworkAgentSpecifier();
-
-        PatternMatcher ssidPattern =
-                new PatternMatcher(".*", PatternMatcher.PATTERN_SIMPLE_GLOB);
-        Pair<MacAddress, MacAddress> bssidPattern =
-                Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
-                        MacAddress.fromString(TEST_BSSID_OUI_MASK));
-        WifiConfiguration wificonfigurationNetworkSpecifier = new WifiConfiguration();
-        wificonfigurationNetworkSpecifier.allowedKeyManagement
-                .set(WifiConfiguration.KeyMgmt.WPA_PSK);
-        WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
-                ssidPattern,
-                bssidPattern,
-                wificonfigurationNetworkSpecifier);
-
-        assertTrue(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier));
-        assertTrue(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier));
-    }
-
-    /**
-     * Validate {@link WifiNetworkAgentSpecifier} with {@link WifiNetworkSpecifier} matching.
-     * a) Create network agent specifier for WPA_PSK network
-     * b) Create network specifier with matching SSID & BSSID pattern.
-     * c) Ensure that the agent specifier is satisfied by specifier.
-     */
-    @Test
-    public void
-            testWifiNetworkAgentSpecifierSatisfiesNetworkSpecifierWithSsidAndBssidPattern() {
-        WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier = createDefaultNetworkAgentSpecifier();
-
-        PatternMatcher ssidPattern =
-                new PatternMatcher(TEST_SSID_PATTERN, PatternMatcher.PATTERN_PREFIX);
-        Pair<MacAddress, MacAddress> bssidPattern =
-                Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
-                        MacAddress.fromString(TEST_BSSID_OUI_MASK));
-        WifiConfiguration wificonfigurationNetworkSpecifier = new WifiConfiguration();
-        wificonfigurationNetworkSpecifier.allowedKeyManagement
-                .set(WifiConfiguration.KeyMgmt.WPA_PSK);
-        WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
-                ssidPattern,
-                bssidPattern,
-                wificonfigurationNetworkSpecifier);
-
-        assertTrue(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier));
-        assertTrue(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier));
-    }
-
-    /**
-     * Validate {@link WifiNetworkAgentSpecifier} with {@link WifiNetworkSpecifier} matching.
-     * a) Create network agent specifier for WPA_PSK network
-     * b) Create network specifier with non-matching SSID pattern.
-     * c) Ensure that the agent specifier is not satisfied by specifier.
-     */
-    @Test
-    public void
-            testWifiNetworkAgentSpecifierDoesNotSatisfyNetworkSpecifierWithSsidPattern() {
-        WifiConfiguration wifiConfigurationNetworkAgent = createDefaultWifiConfiguration();
-        wifiConfigurationNetworkAgent.SSID = "\"" + TEST_SSID_1 + "\"";
-        WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier =
-                new WifiNetworkAgentSpecifier(
-                        wifiConfigurationNetworkAgent);
-
-        PatternMatcher ssidPattern =
-                new PatternMatcher(TEST_SSID_PATTERN, PatternMatcher.PATTERN_PREFIX);
-        Pair<MacAddress, MacAddress> bssidPattern =
-                Pair.create(WifiManager.ALL_ZEROS_MAC_ADDRESS, WifiManager.ALL_ZEROS_MAC_ADDRESS);
-        WifiConfiguration wificonfigurationNetworkSpecifier = new WifiConfiguration();
-        wificonfigurationNetworkSpecifier.allowedKeyManagement
-                .set(WifiConfiguration.KeyMgmt.WPA_PSK);
-        WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
-                ssidPattern,
-                bssidPattern,
-                wificonfigurationNetworkSpecifier);
-
-        assertFalse(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier));
-        assertFalse(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier));
-    }
-
-    /**
-     * Validate {@link WifiNetworkAgentSpecifier} with {@link WifiNetworkSpecifier} matching.
-     * a) Create network agent specifier for WPA_PSK network
-     * b) Create network specifier with non-matching BSSID pattern.
-     * c) Ensure that the agent specifier is not satisfied by specifier.
-     */
-    @Test
-    public void
-            testWifiNetworkAgentSpecifierDoesNotSatisfyNetworkSpecifierWithBssidPattern() {
-        WifiConfiguration wifiConfigurationNetworkAgent = createDefaultWifiConfiguration();
-        wifiConfigurationNetworkAgent.BSSID = TEST_BSSID_1;
-        WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier =
-                new WifiNetworkAgentSpecifier(
-                        wifiConfigurationNetworkAgent);
-
-        PatternMatcher ssidPattern =
-                new PatternMatcher(".*", PatternMatcher.PATTERN_SIMPLE_GLOB);
-        Pair<MacAddress, MacAddress> bssidPattern =
-                Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
-                        MacAddress.fromString(TEST_BSSID_OUI_MASK));
-        WifiConfiguration wificonfigurationNetworkSpecifier = new WifiConfiguration();
-        wificonfigurationNetworkSpecifier.allowedKeyManagement
-                .set(WifiConfiguration.KeyMgmt.WPA_PSK);
-        WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
-                ssidPattern,
-                bssidPattern,
-                wificonfigurationNetworkSpecifier);
-
-        assertFalse(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier));
-        assertFalse(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier));
-    }
-
-    /**
-     * Validate {@link WifiNetworkAgentSpecifier} with {@link WifiNetworkSpecifier} matching.
-     * a) Create network agent specifier for WPA_PSK network
-     * b) Create network specifier with non-matching SSID and BSSID pattern.
-     * c) Ensure that the agent specifier is not satisfied by specifier.
-     */
-    @Test
-    public void
-            testWifiNetworkAgentSpecifierDoesNotSatisfyNetworkSpecifierWithSsidAndBssidPattern() {
-        WifiConfiguration wifiConfigurationNetworkAgent = createDefaultWifiConfiguration();
-        wifiConfigurationNetworkAgent.BSSID = TEST_BSSID_1;
-        WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier =
-                new WifiNetworkAgentSpecifier(
-                        wifiConfigurationNetworkAgent);
-
-        PatternMatcher ssidPattern =
-                new PatternMatcher(TEST_SSID_PATTERN, PatternMatcher.PATTERN_PREFIX);
-        Pair<MacAddress, MacAddress> bssidPattern =
-                Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
-                        MacAddress.fromString(TEST_BSSID_OUI_MASK));
-        WifiConfiguration wificonfigurationNetworkSpecifier = new WifiConfiguration();
-        wificonfigurationNetworkSpecifier.allowedKeyManagement
-                .set(WifiConfiguration.KeyMgmt.WPA_PSK);
-        WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
-                ssidPattern,
-                bssidPattern,
-                wificonfigurationNetworkSpecifier);
-
-        assertFalse(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier));
-        assertFalse(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier));
-    }
-
-    /**
-     * Validate {@link WifiNetworkAgentSpecifier} with {@link WifiNetworkSpecifier} matching.
-     * a) Create network agent specifier for WPA_PSK network
-     * b) Create network specifier with matching SSID and BSSID pattern, but different key mgmt.
-     * c) Ensure that the agent specifier is not satisfied by specifier.
-     */
-    @Test
-    public void
-            testWifiNetworkAgentSpecifierDoesNotSatisfyNetworkSpecifierWithDifferentKeyMgmt() {
-        WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier = createDefaultNetworkAgentSpecifier();
-
-        PatternMatcher ssidPattern =
-                new PatternMatcher(TEST_SSID_PATTERN, PatternMatcher.PATTERN_PREFIX);
-        Pair<MacAddress, MacAddress> bssidPattern =
-                Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
-                        MacAddress.fromString(TEST_BSSID_OUI_MASK));
-        WifiConfiguration wificonfigurationNetworkSpecifier = new WifiConfiguration();
-        wificonfigurationNetworkSpecifier.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
-        WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
-                ssidPattern,
-                bssidPattern,
-                wificonfigurationNetworkSpecifier);
-
-        assertFalse(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier));
-        assertFalse(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier));
-    }
-
-
-    private WifiConfiguration createDefaultWifiConfiguration() {
-        WifiConfiguration wifiConfiguration = new WifiConfiguration();
-        wifiConfiguration.SSID = "\"" + TEST_SSID + "\"";
-        wifiConfiguration.BSSID = TEST_BSSID;
-        wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
-        wifiConfiguration.preSharedKey = TEST_PRESHARED_KEY;
-        return wifiConfiguration;
-    }
-
-    private WifiNetworkAgentSpecifier createDefaultNetworkAgentSpecifier() {
-        return new WifiNetworkAgentSpecifier(createDefaultWifiConfiguration());
-    }
-
-}
diff --git a/wifi/non-updatable/tests/src/android/net/wifi/WifiNetworkScoreCacheTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkScoreCacheTest.java
similarity index 100%
rename from wifi/non-updatable/tests/src/android/net/wifi/WifiNetworkScoreCacheTest.java
rename to wifi/tests/src/android/net/wifi/WifiNetworkScoreCacheTest.java
diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java
deleted file mode 100644
index 6f47f3d..0000000
--- a/wifi/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java
+++ /dev/null
@@ -1,617 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import static android.os.PatternMatcher.PATTERN_LITERAL;
-import static android.os.PatternMatcher.PATTERN_PREFIX;
-import static android.os.PatternMatcher.PATTERN_SIMPLE_GLOB;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import android.net.MacAddress;
-import android.net.MatchAllNetworkSpecifier;
-import android.net.NetworkSpecifier;
-import android.os.Parcel;
-import android.os.PatternMatcher;
-import android.util.Pair;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-import java.security.cert.X509Certificate;
-
-/**
- * Unit tests for {@link android.net.wifi.WifiNetworkSpecifier}.
- */
-@SmallTest
-public class WifiNetworkSpecifierTest {
-    private static final String TEST_SSID = "Test123";
-    private static final String TEST_BSSID_OUI_BASE_ADDRESS = "12:12:12:00:00:00";
-    private static final String TEST_BSSID_OUI_MASK = "ff:ff:ff:00:00:00";
-    private static final String TEST_BSSID = "12:12:12:12:12:12";
-    private static final String TEST_PRESHARED_KEY = "\"Test123\"";
-    private static final String TEST_DOMAIN_SUFFIX_MATCH = "domainSuffixMatch";
-
-    /**
-     * Validate correctness of WifiNetworkSpecifier object created by
-     * {@link WifiNetworkSpecifier.Builder#build()} for open network with SSID pattern.
-     */
-    @Test
-    public void testWifiNetworkSpecifierBuilderForOpenNetworkWithSsidPattern() {
-        NetworkSpecifier specifier = new WifiNetworkSpecifier.Builder()
-                .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_PREFIX))
-                .build();
-
-        assertTrue(specifier instanceof WifiNetworkSpecifier);
-        WifiNetworkSpecifier wifiNetworkSpecifier = (WifiNetworkSpecifier) specifier;
-
-        assertEquals(TEST_SSID, wifiNetworkSpecifier.ssidPatternMatcher.getPath());
-        assertEquals(PATTERN_PREFIX, wifiNetworkSpecifier.ssidPatternMatcher.getType());
-        assertEquals(WifiManager.ALL_ZEROS_MAC_ADDRESS,
-                wifiNetworkSpecifier.bssidPatternMatcher.first);
-        assertEquals(WifiManager.ALL_ZEROS_MAC_ADDRESS,
-                wifiNetworkSpecifier.bssidPatternMatcher.second);
-        assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement
-                .get(WifiConfiguration.KeyMgmt.NONE));
-    }
-
-    /**
-     * Validate correctness of WifiNetworkSpecifier object created by
-     * {@link WifiNetworkSpecifier.Builder#build()} for WPA_PSK network with BSSID
-     * pattern.
-     */
-    @Test
-    public void testWifiNetworkSpecifierBuilderForWpa2PskNetworkWithBssidPattern() {
-        NetworkSpecifier specifier = new WifiNetworkSpecifier.Builder()
-                .setBssidPattern(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
-                        MacAddress.fromString(TEST_BSSID_OUI_MASK))
-                .setWpa2Passphrase(TEST_PRESHARED_KEY)
-                .build();
-
-        assertTrue(specifier instanceof WifiNetworkSpecifier);
-        WifiNetworkSpecifier wifiNetworkSpecifier = (WifiNetworkSpecifier) specifier;
-
-        assertEquals(".*", wifiNetworkSpecifier.ssidPatternMatcher.getPath());
-        assertEquals(PATTERN_SIMPLE_GLOB, wifiNetworkSpecifier.ssidPatternMatcher.getType());
-        assertEquals(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
-                wifiNetworkSpecifier.bssidPatternMatcher.first);
-        assertEquals(MacAddress.fromString(TEST_BSSID_OUI_MASK),
-                wifiNetworkSpecifier.bssidPatternMatcher.second);
-        assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement
-                .get(WifiConfiguration.KeyMgmt.WPA_PSK));
-        assertEquals("\"" + TEST_PRESHARED_KEY + "\"",
-                wifiNetworkSpecifier.wifiConfiguration.preSharedKey);
-    }
-
-    /**
-     * Validate correctness of WifiNetworkSpecifier object created by
-     * {@link WifiNetworkSpecifier.Builder#build()} for WPA_EAP network with
-     * SSID and BSSID pattern.
-     */
-    @Test
-    public void testWifiNetworkSpecifierBuilderForWpa2EapHiddenNetworkWithSsidAndBssid() {
-        WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
-        enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
-        enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.GTC);
-
-        NetworkSpecifier specifier = new WifiNetworkSpecifier.Builder()
-                .setSsid(TEST_SSID)
-                .setBssid(MacAddress.fromString(TEST_BSSID))
-                .setWpa2EnterpriseConfig(enterpriseConfig)
-                .setIsHiddenSsid(true)
-                .build();
-
-        assertTrue(specifier instanceof WifiNetworkSpecifier);
-        WifiNetworkSpecifier wifiNetworkSpecifier = (WifiNetworkSpecifier) specifier;
-
-        assertEquals(TEST_SSID, wifiNetworkSpecifier.ssidPatternMatcher.getPath());
-        assertEquals(PATTERN_LITERAL, wifiNetworkSpecifier.ssidPatternMatcher.getType());
-        assertEquals(MacAddress.fromString(TEST_BSSID),
-                wifiNetworkSpecifier.bssidPatternMatcher.first);
-        assertEquals(MacAddress.BROADCAST_ADDRESS,
-                wifiNetworkSpecifier.bssidPatternMatcher.second);
-        assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement
-                .get(WifiConfiguration.KeyMgmt.WPA_EAP));
-        assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement
-                .get(WifiConfiguration.KeyMgmt.IEEE8021X));
-        assertTrue(wifiNetworkSpecifier.wifiConfiguration.hiddenSSID);
-        assertEquals(enterpriseConfig.getEapMethod(),
-                wifiNetworkSpecifier.wifiConfiguration.enterpriseConfig.getEapMethod());
-        assertEquals(enterpriseConfig.getPhase2Method(),
-                wifiNetworkSpecifier.wifiConfiguration.enterpriseConfig.getPhase2Method());
-    }
-
-    /**
-     * Validate correctness of WifiNetworkSuggestion object created by
-     * {@link WifiNetworkSuggestion.Builder#build()} for WPA3-Enterprise network.
-     */
-    @Test
-    public void testWifiNetworkSuggestionBuilderForWpa3EapNetwork() {
-        WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
-        enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
-        enterpriseConfig.setCaCertificate(FakeKeys.CA_CERT0);
-        enterpriseConfig.setDomainSuffixMatch(TEST_DOMAIN_SUFFIX_MATCH);
-
-        NetworkSpecifier specifier = new WifiNetworkSpecifier.Builder()
-                .setSsid(TEST_SSID)
-                .setWpa3EnterpriseConfig(enterpriseConfig)
-                .build();
-
-        assertTrue(specifier instanceof WifiNetworkSpecifier);
-        WifiNetworkSpecifier wifiNetworkSpecifier = (WifiNetworkSpecifier) specifier;
-
-        assertEquals("\"" + TEST_SSID + "\"", wifiNetworkSpecifier.wifiConfiguration.SSID);
-        assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement
-                .get(WifiConfiguration.KeyMgmt.IEEE8021X));
-        assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement
-                .get(WifiConfiguration.KeyMgmt.WPA_EAP));
-        assertFalse(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement
-                .get(WifiConfiguration.KeyMgmt.SUITE_B_192));
-        assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedGroupCiphers
-                .get(WifiConfiguration.GroupCipher.CCMP));
-        assertTrue(wifiNetworkSpecifier.wifiConfiguration.requirePmf);
-        assertNull(wifiNetworkSpecifier.wifiConfiguration.preSharedKey);
-        assertNotNull(wifiNetworkSpecifier.wifiConfiguration.enterpriseConfig);
-    }
-
-    /**
-     * Validate correctness of WifiNetworkSuggestion object created by
-     * {@link WifiNetworkSuggestion.Builder#build()} for WPA3-Enterprise 192-bit RSA SuiteB network.
-     */
-    @Test
-    public void testWifiNetworkSuggestionBuilderForWpa3SuiteBRsaEapNetwork() {
-        WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
-        enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
-        enterpriseConfig.setCaCertificate(FakeKeys.CA_SUITE_B_RSA3072_CERT);
-        enterpriseConfig.setClientKeyEntryWithCertificateChain(FakeKeys.CLIENT_SUITE_B_RSA3072_KEY,
-                new X509Certificate[] {FakeKeys.CLIENT_SUITE_B_RSA3072_CERT});
-
-        enterpriseConfig.setDomainSuffixMatch(TEST_DOMAIN_SUFFIX_MATCH);
-
-        NetworkSpecifier specifier = new WifiNetworkSpecifier.Builder()
-                .setSsid(TEST_SSID)
-                .setWpa3EnterpriseConfig(enterpriseConfig)
-                .build();
-
-        assertTrue(specifier instanceof WifiNetworkSpecifier);
-        WifiNetworkSpecifier wifiNetworkSpecifier = (WifiNetworkSpecifier) specifier;
-
-        assertEquals("\"" + TEST_SSID + "\"", wifiNetworkSpecifier.wifiConfiguration.SSID);
-        assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement
-                .get(WifiConfiguration.KeyMgmt.SUITE_B_192));
-        assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedGroupCiphers
-                .get(WifiConfiguration.GroupCipher.GCMP_256));
-        assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedGroupManagementCiphers
-                .get(WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256));
-        assertTrue(wifiNetworkSpecifier.wifiConfiguration.requirePmf);
-        assertNull(wifiNetworkSpecifier.wifiConfiguration.preSharedKey);
-        assertNotNull(wifiNetworkSpecifier.wifiConfiguration.enterpriseConfig);
-    }
-
-    /**
-     * Validate correctness of WifiNetworkSuggestion object created by
-     * {@link WifiNetworkSuggestion.Builder#build()} for WPA3-Enterprise 192-bit ECC SuiteB network.
-     */
-    @Test
-    public void testWifiNetworkSuggestionBuilderForWpa3SuiteBEccEapNetwork() {
-        WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
-        enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
-        enterpriseConfig.setCaCertificate(FakeKeys.CA_SUITE_B_ECDSA_CERT);
-        enterpriseConfig.setClientKeyEntryWithCertificateChain(FakeKeys.CLIENT_SUITE_B_ECC_KEY,
-                new X509Certificate[] {FakeKeys.CLIENT_SUITE_B_ECDSA_CERT});
-
-        enterpriseConfig.setDomainSuffixMatch(TEST_DOMAIN_SUFFIX_MATCH);
-
-        NetworkSpecifier specifier = new WifiNetworkSpecifier.Builder()
-                .setSsid(TEST_SSID)
-                .setWpa3EnterpriseConfig(enterpriseConfig)
-                .build();
-
-        assertTrue(specifier instanceof WifiNetworkSpecifier);
-        WifiNetworkSpecifier wifiNetworkSpecifier = (WifiNetworkSpecifier) specifier;
-
-        assertEquals("\"" + TEST_SSID + "\"", wifiNetworkSpecifier.wifiConfiguration.SSID);
-        assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement
-                .get(WifiConfiguration.KeyMgmt.SUITE_B_192));
-        assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedGroupCiphers
-                .get(WifiConfiguration.GroupCipher.GCMP_256));
-        assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedGroupManagementCiphers
-                .get(WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256));
-        assertTrue(wifiNetworkSpecifier.wifiConfiguration.requirePmf);
-        assertNull(wifiNetworkSpecifier.wifiConfiguration.preSharedKey);
-        assertNotNull(wifiNetworkSpecifier.wifiConfiguration.enterpriseConfig);
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSpecifier.Builder#setSsid(String)} throws an exception
-     * when the string is not Unicode.
-     */
-    @Test(expected = IllegalArgumentException.class)
-    public void testWifiNetworkSpecifierBuilderSetSsidWithNonUnicodeString() {
-        new WifiNetworkSpecifier.Builder()
-                .setSsid("\ud800")
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSpecifier.Builder#setWpa2Passphrase(String)} throws an exception
-     * when the string is not ASCII encodable.
-     */
-    @Test(expected = IllegalArgumentException.class)
-    public void testWifiNetworkSpecifierSetWpa2PasphraseWithNonAsciiString() {
-        new WifiNetworkSpecifier.Builder()
-                .setSsid(TEST_SSID)
-                .setWpa2Passphrase("salvē")
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
-     * when neither SSID nor BSSID patterns were set.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testWifiNetworkSpecifierBuilderWithNoSsidAndBssidPattern() {
-        new WifiNetworkSpecifier.Builder().build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
-     * when match-all SSID pattern is set.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testWifiNetworkSpecifierBuilderWithMatchAllSsidPattern1() {
-        new WifiNetworkSpecifier.Builder()
-                .setSsidPattern(new PatternMatcher(".*", PATTERN_SIMPLE_GLOB))
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
-     * when match-all SSID pattern is set.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testWifiNetworkSpecifierBuilderWithMatchAllSsidPattern2() {
-        new WifiNetworkSpecifier.Builder()
-                .setSsidPattern(new PatternMatcher(".*", PatternMatcher.PATTERN_ADVANCED_GLOB))
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
-     * when match-all SSID pattern is set.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testWifiNetworkSpecifierBuilderWithMatchAllSsidPattern3() {
-        new WifiNetworkSpecifier.Builder()
-                .setSsidPattern(new PatternMatcher("", PATTERN_PREFIX))
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
-     * when match-all BSSID pattern is set.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testWifiNetworkSpecifierBuilderWithMatchAllBssidPattern() {
-        new WifiNetworkSpecifier.Builder()
-                .setBssidPattern(WifiManager.ALL_ZEROS_MAC_ADDRESS,
-                        WifiManager.ALL_ZEROS_MAC_ADDRESS)
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
-     * when match-none SSID pattern is set.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testWifiNetworkSpecifierBuilderWithMatchNoneSsidPattern1() {
-        new WifiNetworkSpecifier.Builder()
-                .setSsidPattern(new PatternMatcher("", PatternMatcher.PATTERN_LITERAL))
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
-     * when match-none SSID pattern is set.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testWifiNetworkSpecifierBuilderWithMatchNoneSsidPattern2() {
-        new WifiNetworkSpecifier.Builder()
-                .setSsid("")
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
-     * when match-none BSSID pattern is set.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testWifiNetworkSpecifierBuilderWithMatchNoneBssidPattern1() {
-        new WifiNetworkSpecifier.Builder()
-                .setBssidPattern(MacAddress.BROADCAST_ADDRESS, MacAddress.BROADCAST_ADDRESS)
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
-     * when match-none BSSID pattern is set.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testWifiNetworkSpecifierBuilderWithMatchNoneBssidPattern2() {
-        new WifiNetworkSpecifier.Builder()
-                .setBssid(MacAddress.BROADCAST_ADDRESS)
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
-     * when match-none BSSID pattern is set.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testWifiNetworkSpecifierBuilderWithMatchNoneBssidPattern3() {
-        new WifiNetworkSpecifier.Builder()
-                .setBssid(WifiManager.ALL_ZEROS_MAC_ADDRESS)
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
-     * when SSID pattern is set for hidden network.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testWifiNetworkSpecifierBuilderWithBssidMatchPatternForHiddenNetwork() {
-        new WifiNetworkSpecifier.Builder()
-                .setBssidPattern(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
-                        MacAddress.fromString(TEST_BSSID_OUI_MASK))
-                .setIsHiddenSsid(true)
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
-     * when both {@link WifiNetworkSpecifier.Builder#setWpa2Passphrase(String)} and
-     * {@link WifiNetworkSpecifier.Builder#setWpa2EnterpriseConfig(WifiEnterpriseConfig)} are
-     * invoked.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testWifiNetworkSpecifierBuilderWithBothWpa2PasphraseAndEnterpriseConfig() {
-        new WifiNetworkSpecifier.Builder()
-                .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_LITERAL))
-                .setWpa2Passphrase(TEST_PRESHARED_KEY)
-                .setWpa2EnterpriseConfig(new WifiEnterpriseConfig())
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
-     * when SSID pattern is set for hidden network.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testWifiNetworkSpecifierBuilderWithSsidMatchPatternForHiddenNetwork() {
-        new WifiNetworkSpecifier.Builder()
-                .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_PREFIX))
-                .setIsHiddenSsid(true)
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
-     * when both {@link WifiNetworkSpecifier.Builder#setWpa2Passphrase(String)} and
-     * {@link WifiNetworkSpecifier.Builder#setWpa3Passphrase(String)} are invoked.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testWifiNetworkSpecifierBuilderWithBothWpa2PasphraseAndWpa3Passphrase() {
-        new WifiNetworkSpecifier.Builder()
-                .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_LITERAL))
-                .setWpa2Passphrase(TEST_PRESHARED_KEY)
-                .setWpa3Passphrase(TEST_PRESHARED_KEY)
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
-     * when both {@link WifiNetworkSpecifier.Builder#setWpa3Passphrase(String)} and
-     * {@link WifiNetworkSpecifier.Builder#setWpa3EnterpriseConfig(WifiEnterpriseConfig)} are
-     * invoked.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testWifiNetworkSpecifierBuilderWithBothWpa3PasphraseAndEnterprise() {
-        new WifiNetworkSpecifier.Builder()
-                .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_LITERAL))
-                .setWpa3Passphrase(TEST_PRESHARED_KEY)
-                .setWpa3EnterpriseConfig(new WifiEnterpriseConfig())
-                .build();
-    }
-
-    /**
-     * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
-     * when both {@link WifiNetworkSpecifier.Builder#setWpa3Passphrase(String)} and
-     * {@link WifiNetworkSpecifier.Builder#setIsEnhancedOpen(boolean)} are invoked.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testWifiNetworkSpecifierBuilderWithBothWpa3PasphraseAndEnhancedOpen() {
-        new WifiNetworkSpecifier.Builder()
-                .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_LITERAL))
-                .setWpa3Passphrase(TEST_PRESHARED_KEY)
-                .setIsEnhancedOpen(true)
-                .build();
-    }
-
-    /**
-     * Validate that parcel marshalling/unmarshalling works
-     */
-    @Test
-    public void testWifiNetworkSpecifierParcel() {
-        WifiConfiguration wifiConfiguration = new WifiConfiguration();
-        wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
-        wifiConfiguration.preSharedKey = TEST_PRESHARED_KEY;
-        WifiNetworkSpecifier specifier =
-                new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
-                        Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
-                                MacAddress.fromString(TEST_BSSID_OUI_MASK)),
-                        wifiConfiguration);
-
-        Parcel parcelW = Parcel.obtain();
-        specifier.writeToParcel(parcelW, 0);
-        byte[] bytes = parcelW.marshall();
-        parcelW.recycle();
-
-        Parcel parcelR = Parcel.obtain();
-        parcelR.unmarshall(bytes, 0, bytes.length);
-        parcelR.setDataPosition(0);
-        WifiNetworkSpecifier parcelSpecifier =
-                WifiNetworkSpecifier.CREATOR.createFromParcel(parcelR);
-
-        assertEquals(specifier, parcelSpecifier);
-    }
-
-    /**
-     * Validate NetworkSpecifier matching.
-     * a) Create a network specifier for WPA_PSK network
-     * b) Ensure that the specifier does not match {@code null} and {@link MatchAllNetworkSpecifier}
-     * specifiers.
-     */
-    @Test
-    public void testWifiNetworkSpecifierDoesNotSatisfyNullAndAllMatch() {
-        WifiConfiguration wifiConfiguration = new WifiConfiguration();
-        wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
-        wifiConfiguration.preSharedKey = TEST_PRESHARED_KEY;
-        WifiNetworkSpecifier specifier =
-                new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
-                        Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
-                                MacAddress.fromString(TEST_BSSID_OUI_MASK)),
-                        wifiConfiguration);
-
-        assertFalse(specifier.canBeSatisfiedBy(null));
-        assertFalse(specifier.canBeSatisfiedBy(new MatchAllNetworkSpecifier()));
-    }
-
-    /**
-     * Validate NetworkSpecifier matching.
-     * a) Create network specifier 1 for WPA_PSK network
-     * b) Create network specifier 2 with the same params as specifier 1.
-     * c) Ensure that the specifier 2 is satisfied by specifier 1.
-     */
-    @Test
-    public void testWifiNetworkSpecifierSatisfiesSame() {
-        WifiConfiguration wifiConfiguration = new WifiConfiguration();
-        wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
-        wifiConfiguration.preSharedKey = TEST_PRESHARED_KEY;
-
-        WifiNetworkSpecifier specifier1 =
-                new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
-                        Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
-                                MacAddress.fromString(TEST_BSSID_OUI_MASK)),
-                        wifiConfiguration);
-
-        WifiNetworkSpecifier specifier2 =
-                new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
-                        Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
-                                MacAddress.fromString(TEST_BSSID_OUI_MASK)),
-                        wifiConfiguration);
-
-        assertTrue(specifier2.canBeSatisfiedBy(specifier1));
-    }
-
-    /**
-     * Validate NetworkSpecifier matching.
-     * a) Create network specifier 1 for WPA_PSK network
-     * b) Create network specifier 2 with different key mgmt params.
-     * c) Ensure that the specifier 2 is not satisfied by specifier 1.
-     */
-    @Test
-    public void testWifiNetworkSpecifierDoesNotSatisfyWhenKeyMgmtDifferent() {
-        WifiConfiguration wifiConfiguration1 = new WifiConfiguration();
-        wifiConfiguration1.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
-        wifiConfiguration1.preSharedKey = TEST_PRESHARED_KEY;
-
-        WifiNetworkSpecifier specifier1 =
-                new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
-                        Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
-                                MacAddress.fromString(TEST_BSSID_OUI_MASK)),
-                        wifiConfiguration1);
-
-        WifiConfiguration wifiConfiguration2 = new WifiConfiguration();
-        wifiConfiguration2.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
-        WifiNetworkSpecifier specifier2 =
-                new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
-                        Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
-                                MacAddress.fromString(TEST_BSSID_OUI_MASK)),
-                        wifiConfiguration2);
-
-        assertFalse(specifier2.canBeSatisfiedBy(specifier1));
-    }
-
-    /**
-     * Validate NetworkSpecifier matching.
-     * a) Create network specifier 1 for WPA_PSK network
-     * b) Create network specifier 2 with different SSID pattern.
-     * c) Ensure that the specifier 2 is not satisfied by specifier 1.
-     */
-    @Test
-    public void testWifiNetworkSpecifierDoesNotSatisfyWhenSsidDifferent() {
-        WifiConfiguration wifiConfiguration = new WifiConfiguration();
-        wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
-        wifiConfiguration.preSharedKey = TEST_PRESHARED_KEY;
-
-        WifiNetworkSpecifier specifier1 =
-                new WifiNetworkSpecifier(new PatternMatcher("", PATTERN_LITERAL),
-                        Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
-                                MacAddress.fromString(TEST_BSSID_OUI_MASK)),
-                        wifiConfiguration);
-
-        WifiNetworkSpecifier specifier2 =
-                new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
-                        Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
-                                MacAddress.fromString(TEST_BSSID_OUI_MASK)),
-                        wifiConfiguration);
-
-        assertFalse(specifier2.canBeSatisfiedBy(specifier1));
-    }
-
-    /**
-     * Validate NetworkSpecifier matching.
-     * a) Create network specifier 1 for WPA_PSK network
-     * b) Create network specifier 2 with different BSSID pattern.
-     * c) Ensure that the specifier 2 is not satisfied by specifier 1.
-     */
-    @Test
-    public void testWifiNetworkSpecifierDoesNotSatisfyWhenBssidDifferent() {
-        WifiConfiguration wifiConfiguration = new WifiConfiguration();
-        wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
-        wifiConfiguration.preSharedKey = TEST_PRESHARED_KEY;
-
-        WifiNetworkSpecifier specifier1 =
-                new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
-                        Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
-                                MacAddress.fromString(TEST_BSSID_OUI_MASK)),
-                        wifiConfiguration);
-
-        WifiNetworkSpecifier specifier2 =
-                new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
-                        Pair.create(WifiManager.ALL_ZEROS_MAC_ADDRESS,
-                                WifiManager.ALL_ZEROS_MAC_ADDRESS),
-                        wifiConfiguration);
-
-        assertFalse(specifier2.canBeSatisfiedBy(specifier1));
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java
deleted file mode 100644
index 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/non-updatable/tests/src/android/net/wifi/nl80211/DeviceWiphyCapabilitiesTest.java b/wifi/tests/src/android/net/wifi/nl80211/DeviceWiphyCapabilitiesTest.java
similarity index 100%
rename from wifi/non-updatable/tests/src/android/net/wifi/nl80211/DeviceWiphyCapabilitiesTest.java
rename to wifi/tests/src/android/net/wifi/nl80211/DeviceWiphyCapabilitiesTest.java
diff --git a/wifi/non-updatable/tests/src/android/net/wifi/nl80211/NativeScanResultTest.java b/wifi/tests/src/android/net/wifi/nl80211/NativeScanResultTest.java
similarity index 100%
rename from wifi/non-updatable/tests/src/android/net/wifi/nl80211/NativeScanResultTest.java
rename to wifi/tests/src/android/net/wifi/nl80211/NativeScanResultTest.java
diff --git a/wifi/non-updatable/tests/src/android/net/wifi/nl80211/PnoSettingsTest.java b/wifi/tests/src/android/net/wifi/nl80211/PnoSettingsTest.java
similarity index 100%
rename from wifi/non-updatable/tests/src/android/net/wifi/nl80211/PnoSettingsTest.java
rename to wifi/tests/src/android/net/wifi/nl80211/PnoSettingsTest.java
diff --git a/wifi/non-updatable/tests/src/android/net/wifi/nl80211/SingleScanSettingsTest.java b/wifi/tests/src/android/net/wifi/nl80211/SingleScanSettingsTest.java
similarity index 100%
rename from wifi/non-updatable/tests/src/android/net/wifi/nl80211/SingleScanSettingsTest.java
rename to wifi/tests/src/android/net/wifi/nl80211/SingleScanSettingsTest.java
diff --git a/wifi/non-updatable/tests/src/android/net/wifi/nl80211/WifiNl80211ManagerTest.java b/wifi/tests/src/android/net/wifi/nl80211/WifiNl80211ManagerTest.java
similarity index 100%
rename from wifi/non-updatable/tests/src/android/net/wifi/nl80211/WifiNl80211ManagerTest.java
rename to wifi/tests/src/android/net/wifi/nl80211/WifiNl80211ManagerTest.java
diff --git a/wifi/tests/src/android/net/wifi/p2p/WifiP2pConfigTest.java b/wifi/tests/src/android/net/wifi/p2p/WifiP2pConfigTest.java
deleted file mode 100644
index 6199325..0000000
--- a/wifi/tests/src/android/net/wifi/p2p/WifiP2pConfigTest.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-/**
- * Unit test harness for {@link android.net.wifi.p2p.WifiP2pConfig}
- */
-@SmallTest
-public class WifiP2pConfigTest {
-
-    private static final String DEVICE_ADDRESS = "aa:bb:cc:dd:ee:ff";
-    /**
-     * Check network name setter
-     */
-    @Test
-    public void testBuilderInvalidNetworkName() throws Exception {
-        WifiP2pConfig.Builder b = new WifiP2pConfig.Builder();
-
-        // sunny case
-        try {
-            b.setNetworkName("DIRECT-ab-Hello");
-        } catch (IllegalArgumentException e) {
-            fail("Unexpected IllegalArgumentException");
-        }
-
-        // sunny case, no trailing string
-        try {
-            b.setNetworkName("DIRECT-WR");
-        } catch (IllegalArgumentException e) {
-            fail("Unexpected IllegalArgumentException");
-        }
-
-        // sunny case with maximum bytes for the network name
-        try {
-            b.setNetworkName("DIRECT-abcdefghijklmnopqrstuvwxy");
-        } catch (IllegalArgumentException e) {
-            fail("Unexpected IllegalArgumentException");
-        }
-
-        // less than 9 characters.
-        try {
-            b.setNetworkName("DIRECT-z");
-            fail("expected IllegalArgumentException");
-        } catch (IllegalArgumentException e) { }
-
-        // not starts with DIRECT-xy.
-        try {
-            b.setNetworkName("ABCDEFGHIJK");
-            fail("expected IllegalArgumentException");
-        } catch (IllegalArgumentException e) { }
-
-        // not starts with uppercase DIRECT-xy
-        try {
-            b.setNetworkName("direct-ab");
-            fail("expected IllegalArgumentException");
-        } catch (IllegalArgumentException e) { }
-
-        // x and y are not selected from upper case letters, lower case letters or
-        // numbers.
-        try {
-            b.setNetworkName("direct-a?");
-            fail("expected IllegalArgumentException");
-        } catch (IllegalArgumentException e) { }
-
-        // over maximum bytes
-        try {
-            b.setNetworkName("DIRECT-abcdefghijklmnopqrstuvwxyz");
-            fail("expected IllegalArgumentException");
-        } catch (IllegalArgumentException e) { }
-    }
-
-    /**
-     * Check passphrase setter
-     */
-    @Test
-    public void testBuilderInvalidPassphrase() throws Exception {
-        WifiP2pConfig.Builder b = new WifiP2pConfig.Builder();
-
-        // sunny case
-        try {
-            b.setPassphrase("abcd1234");
-        } catch (IllegalArgumentException e) {
-            fail("Unexpected IllegalArgumentException");
-        }
-
-        // null string.
-        try {
-            b.setPassphrase(null);
-            fail("should throw IllegalArgumentException");
-        } catch (IllegalArgumentException e) {
-            // expected exception.
-        }
-
-        // less than 8 characters.
-        try {
-            b.setPassphrase("12abcde");
-            fail("should throw IllegalArgumentException");
-        } catch (IllegalArgumentException e) {
-            // expected exception.
-        }
-
-        // more than 63 characters.
-        try {
-            b.setPassphrase(
-                    "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890+/");
-            fail("should throw IllegalArgumentException");
-        } catch (IllegalArgumentException e) {
-            // expected exception.
-        }
-    }
-
-    @Test
-    /*
-     * Verify WifiP2pConfig basic operations
-     */
-    public void testWifiP2pConfig() throws Exception {
-        WifiP2pConfig config = new WifiP2pConfig();
-        config.deviceAddress = DEVICE_ADDRESS;
-
-        WifiP2pConfig copiedConfig = new WifiP2pConfig(config);
-        // no equals operator, use toString for comparison.
-        assertEquals(config.toString(), copiedConfig.toString());
-
-        Parcel parcelW = Parcel.obtain();
-        config.writeToParcel(parcelW, 0);
-        byte[] bytes = parcelW.marshall();
-        parcelW.recycle();
-
-        Parcel parcelR = Parcel.obtain();
-        parcelR.unmarshall(bytes, 0, bytes.length);
-        parcelR.setDataPosition(0);
-        WifiP2pConfig configFromParcel = WifiP2pConfig.CREATOR.createFromParcel(parcelR);
-
-        // no equals operator, use toString for comparison.
-        assertEquals(config.toString(), configFromParcel.toString());
-
-    }
-
-    @Test
-    /*
-     * Verify WifiP2pConfig invalidate API
-     */
-    public void testInvalidate() throws Exception {
-        WifiP2pConfig config = new WifiP2pConfig();
-        config.deviceAddress = DEVICE_ADDRESS;
-        config.invalidate();
-        assertEquals("", config.deviceAddress);
-    }
-
-}
diff --git a/wifi/tests/src/android/net/wifi/p2p/WifiP2pDeviceListTest.java b/wifi/tests/src/android/net/wifi/p2p/WifiP2pDeviceListTest.java
deleted file mode 100644
index 22936bd..0000000
--- a/wifi/tests/src/android/net/wifi/p2p/WifiP2pDeviceListTest.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p;
-
-import static org.junit.Assert.assertEquals;
-
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-/**
- * Unit test harness for {@link android.net.wifi.p2p.WifiP2pDeviceList}
- */
-@SmallTest
-public class WifiP2pDeviceListTest {
-
-    private static final WifiP2pDevice TEST_DEVICE_1 = new WifiP2pDevice("aa:bb:cc:dd:ee:ff");
-    private static final WifiP2pDevice TEST_DEVICE_2 = new WifiP2pDevice("aa:bb:cc:dd:ee:f1");
-    private static final WifiP2pDevice TEST_DEVICE_3 = new WifiP2pDevice("11:22:33:44:55:66");
-    private static final WifiP2pDevice TEST_DEVICE_4 = new WifiP2pDevice("a0:b0:c0:d0:e0:f0");
-
-    /**
-     * Verify basic operations.
-     */
-    @Test
-    public void testListOperations() throws Exception {
-        WifiP2pDeviceList list = new WifiP2pDeviceList();
-        list.update(TEST_DEVICE_1);
-        list.update(TEST_DEVICE_2);
-        list.update(TEST_DEVICE_3);
-        assertEquals(3, list.getDeviceList().size());
-
-        assertEquals(TEST_DEVICE_1, list.get(TEST_DEVICE_1.deviceAddress));
-        assertEquals(null, list.get(TEST_DEVICE_4.deviceAddress));
-
-        list.remove(TEST_DEVICE_2.deviceAddress);
-        assertEquals(null, list.get(TEST_DEVICE_2.deviceAddress));
-
-        list.remove(TEST_DEVICE_3);
-        assertEquals(null, list.get(TEST_DEVICE_3.deviceAddress));
-
-        assertEquals(1, list.getDeviceList().size());
-
-        list.clear();
-        assertEquals(0, list.getDeviceList().size());
-
-        Parcel parcelW = Parcel.obtain();
-        list.writeToParcel(parcelW, 0);
-        byte[] bytes = parcelW.marshall();
-        parcelW.recycle();
-
-        Parcel parcelR = Parcel.obtain();
-        parcelR.unmarshall(bytes, 0, bytes.length);
-        parcelR.setDataPosition(0);
-        WifiP2pDeviceList fromParcel = WifiP2pDeviceList.CREATOR.createFromParcel(parcelR);
-
-        assertEquals(list.toString(), fromParcel.toString());
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/p2p/WifiP2pDeviceTest.java b/wifi/tests/src/android/net/wifi/p2p/WifiP2pDeviceTest.java
deleted file mode 100644
index 6edc287..0000000
--- a/wifi/tests/src/android/net/wifi/p2p/WifiP2pDeviceTest.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-/**
- * Unit test harness for {@link android.net.wifi.p2p.WifiP2pDevice}
- */
-@SmallTest
-public class WifiP2pDeviceTest {
-
-    /**
-     * Compare two p2p devices.
-     *
-     * @param devA is the first device to be compared
-     * @param devB is the second device to be compared
-     */
-    private void compareWifiP2pDevices(WifiP2pDevice devA, WifiP2pDevice devB) {
-        assertEquals(devA.deviceName, devB.deviceName);
-        assertEquals(devA.deviceAddress, devB.deviceAddress);
-        assertEquals(devA.primaryDeviceType, devB.primaryDeviceType);
-        assertEquals(devA.secondaryDeviceType, devB.secondaryDeviceType);
-        assertEquals(devA.wpsConfigMethodsSupported, devB.wpsConfigMethodsSupported);
-        assertEquals(devA.deviceCapability, devB.deviceCapability);
-        assertEquals(devA.groupCapability, devB.groupCapability);
-        assertEquals(devA.status, devB.status);
-        if (devA.wfdInfo != null) {
-            assertEquals(devA.wfdInfo.isEnabled(), devB.wfdInfo.isEnabled());
-            assertEquals(devA.wfdInfo.getDeviceInfoHex(), devB.wfdInfo.getDeviceInfoHex());
-            assertEquals(devA.wfdInfo.getControlPort(), devB.wfdInfo.getControlPort());
-            assertEquals(devA.wfdInfo.getMaxThroughput(), devB.wfdInfo.getMaxThroughput());
-        } else {
-            assertEquals(devA.wfdInfo, devB.wfdInfo);
-        }
-    }
-
-    /**
-     * Check equals and hashCode consistency
-     */
-    @Test
-    public void testEqualsWithHashCode() throws Exception {
-        WifiP2pDevice dev_a = new WifiP2pDevice();
-        dev_a.deviceAddress = new String("02:90:4c:a0:92:54");
-        WifiP2pDevice dev_b = new WifiP2pDevice();
-        dev_b.deviceAddress = new String("02:90:4c:a0:92:54");
-
-        assertTrue(dev_a.equals(dev_b));
-        assertEquals(dev_a.hashCode(), dev_b.hashCode());
-    }
-
-    /**
-     * Check the copy constructor with default values.
-     */
-    @Test
-    public void testCopyConstructorWithDefaultValues() throws Exception {
-        WifiP2pDevice device = new WifiP2pDevice();
-        WifiP2pDevice copy = new WifiP2pDevice(device);
-        compareWifiP2pDevices(device, copy);
-    }
-
-    /**
-     * Check the copy constructor with updated values.
-     */
-    @Test
-    public void testCopyConstructorWithUpdatedValues() throws Exception {
-        WifiP2pDevice device = new WifiP2pDevice();
-        device.deviceName = "deviceName";
-        device.deviceAddress = "11:22:33:44:55:66";
-        device.primaryDeviceType = "primaryDeviceType";
-        device.secondaryDeviceType = "secondaryDeviceType";
-        device.wpsConfigMethodsSupported = 0x0008;
-        device.deviceCapability = 1;
-        device.groupCapability = 1;
-        device.status = WifiP2pDevice.CONNECTED;
-        device.wfdInfo = new WifiP2pWfdInfo();
-        WifiP2pDevice copy = new WifiP2pDevice(device);
-        compareWifiP2pDevices(device, copy);
-    }
-
-    /**
-     * Check the copy constructor when the wfdInfo of the source object is null.
-     */
-    @Test
-    public void testCopyConstructorWithNullWfdInfo() throws Exception {
-        WifiP2pDevice device = new WifiP2pDevice();
-        device.deviceName = "deviceName";
-        device.deviceAddress = "11:22:33:44:55:66";
-        device.primaryDeviceType = "primaryDeviceType";
-        device.secondaryDeviceType = "secondaryDeviceType";
-        device.wpsConfigMethodsSupported = 0x0008;
-        device.deviceCapability = 1;
-        device.groupCapability = 1;
-        device.status = WifiP2pDevice.CONNECTED;
-        device.wfdInfo = null;
-        WifiP2pDevice copy = new WifiP2pDevice(device);
-        compareWifiP2pDevices(device, copy);
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/p2p/WifiP2pGroupListTest.java b/wifi/tests/src/android/net/wifi/p2p/WifiP2pGroupListTest.java
deleted file mode 100644
index 2402f5b..0000000
--- a/wifi/tests/src/android/net/wifi/p2p/WifiP2pGroupListTest.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Unit test harness for {@link android.net.wifi.p2p.WifiP2pGroupList}
- */
-@SmallTest
-public class WifiP2pGroupListTest {
-
-    private static final WifiP2pDevice TEST_GROUP_OWNER_1 = new WifiP2pDevice("aa:bb:cc:dd:ee:f0");
-    private static final WifiP2pDevice TEST_GROUP_OWNER_2 = new WifiP2pDevice("aa:bb:cc:dd:ee:f1");
-    private static final WifiP2pDevice TEST_GROUP_OWNER_3 = new WifiP2pDevice("aa:bb:cc:dd:ee:f2");
-    private static final WifiP2pDevice TEST_GROUP_OWNER_OTHER =
-            new WifiP2pDevice("aa:bb:cc:dd:ee:f3");
-
-    private WifiP2pGroup mTestGroup1;
-    private WifiP2pGroup mTestGroup2;
-    private WifiP2pGroup mTestGroup3;
-    private WifiP2pGroup mTestGroup4;
-
-    private WifiP2pGroup createGroup(
-            int networkId, String networkName,
-            String passphrase, boolean isGo,
-            WifiP2pDevice goDev) {
-        WifiP2pGroup group = new WifiP2pGroup();
-        group.setNetworkId(networkId);
-        group.setNetworkName(networkName);
-        group.setPassphrase(passphrase);
-        group.setIsGroupOwner(isGo);
-        group.setOwner(goDev);
-        return group;
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        mTestGroup1 = createGroup(0, "testGroup1", "12345678", false, TEST_GROUP_OWNER_1);
-        mTestGroup2 = createGroup(1, "testGroup2", "12345678", true, TEST_GROUP_OWNER_2);
-        mTestGroup3 = createGroup(2, "testGroup3", "12345678", false, TEST_GROUP_OWNER_3);
-        mTestGroup4 = createGroup(3, "testGroup4", "12345678", false, TEST_GROUP_OWNER_1);
-    }
-
-    /**
-     * Verify basic operations.
-     */
-    @Test
-    public void testListOperations() throws Exception {
-        WifiP2pGroupList list = new WifiP2pGroupList();
-        list.add(mTestGroup1);
-        list.add(mTestGroup2);
-        list.add(mTestGroup3);
-        list.add(mTestGroup4);
-        assertEquals(4, list.getGroupList().size());
-
-        // in list
-        assertEquals(mTestGroup2.getNetworkId(),
-                list.getNetworkId(TEST_GROUP_OWNER_2.deviceAddress));
-        assertEquals(TEST_GROUP_OWNER_2.deviceAddress,
-                list.getOwnerAddr(mTestGroup2.getNetworkId()));
-        // not in list
-        assertEquals(-1, list.getNetworkId(TEST_GROUP_OWNER_OTHER.deviceAddress));
-        // if there are groups with the same GO, return the first one found.
-        assertEquals(mTestGroup1.getNetworkId(),
-                list.getNetworkId(TEST_GROUP_OWNER_1.deviceAddress));
-        // identify groups with the same GO, but different network names.
-        assertEquals(mTestGroup4.getNetworkId(),
-                list.getNetworkId(TEST_GROUP_OWNER_1.deviceAddress, "testGroup4"));
-
-        list.remove(mTestGroup3.getNetworkId());
-        assertEquals(-1, list.getNetworkId(TEST_GROUP_OWNER_3.deviceAddress));
-        assertFalse(list.contains(mTestGroup3.getNetworkId()));
-
-        assertEquals(3, list.getGroupList().size());
-
-        Parcel parcelW = Parcel.obtain();
-        list.writeToParcel(parcelW, 0);
-        byte[] bytes = parcelW.marshall();
-        parcelW.recycle();
-
-        Parcel parcelR = Parcel.obtain();
-        parcelR.unmarshall(bytes, 0, bytes.length);
-        parcelR.setDataPosition(0);
-        WifiP2pGroupList fromParcel = WifiP2pGroupList.CREATOR.createFromParcel(parcelR);
-
-        assertEquals(list.toString(), fromParcel.toString());
-
-        list.clear();
-        assertEquals(0, list.getGroupList().size());
-
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/p2p/WifiP2pGroupTest.java b/wifi/tests/src/android/net/wifi/p2p/WifiP2pGroupTest.java
deleted file mode 100644
index 9473e42..0000000
--- a/wifi/tests/src/android/net/wifi/p2p/WifiP2pGroupTest.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-/**
- * Unit test harness for {@link android.net.wifi.p2p.WifiP2pGroup}
- */
-@SmallTest
-public class WifiP2pGroupTest {
-
-    private static final String INTERFACE = "p2p-p2p0-3";
-    private static final int NETWORK_ID = 9;
-    private static final String NETWORK_NAME = "DIRECT-xy-Hello";
-    private static final String PASSPHRASE = "HelloWorld";
-    private static final WifiP2pDevice GROUP_OWNER = new WifiP2pDevice("de:ad:be:ef:00:01");
-    private static final int FREQUENCY = 5300;
-    private static final WifiP2pDevice CLIENT_1 = new WifiP2pDevice("aa:bb:cc:dd:ee:01");
-    private static final WifiP2pDevice CLIENT_2 = new WifiP2pDevice("aa:bb:cc:dd:ee:02");
-
-    /**
-     * Verify setter/getter functions.
-     */
-    @Test
-    public void testSetterGetter() throws Exception {
-        WifiP2pGroup group = new WifiP2pGroup();
-
-        group.setInterface(INTERFACE);
-        group.setNetworkId(NETWORK_ID);
-        group.setNetworkName(NETWORK_NAME);
-        group.setPassphrase(PASSPHRASE);
-        group.setIsGroupOwner(false);
-        group.setOwner(GROUP_OWNER);
-        group.setFrequency(FREQUENCY);
-        group.addClient(CLIENT_1.deviceAddress);
-        group.addClient(CLIENT_2);
-
-        assertEquals(INTERFACE, group.getInterface());
-        assertEquals(NETWORK_ID, group.getNetworkId());
-        assertEquals(NETWORK_NAME, group.getNetworkName());
-        assertEquals(PASSPHRASE, group.getPassphrase());
-        assertFalse(group.isGroupOwner());
-        assertEquals(GROUP_OWNER, group.getOwner());
-        assertEquals(FREQUENCY, group.getFrequency());
-
-        assertFalse(group.isClientListEmpty());
-        assertTrue(group.contains(CLIENT_1));
-
-        assertEquals(2, group.getClientList().size());
-
-        group.removeClient(CLIENT_1);
-        group.removeClient(CLIENT_2.deviceAddress);
-        assertFalse(group.contains(CLIENT_1));
-        assertTrue(group.isClientListEmpty());
-
-        Parcel parcelW = Parcel.obtain();
-        group.writeToParcel(parcelW, 0);
-        byte[] bytes = parcelW.marshall();
-        parcelW.recycle();
-
-        Parcel parcelR = Parcel.obtain();
-        parcelR.unmarshall(bytes, 0, bytes.length);
-        parcelR.setDataPosition(0);
-        WifiP2pGroup fromParcel = WifiP2pGroup.CREATOR.createFromParcel(parcelR);
-
-        assertEquals(group.toString(), fromParcel.toString());
-
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/p2p/WifiP2pInfoTest.java b/wifi/tests/src/android/net/wifi/p2p/WifiP2pInfoTest.java
deleted file mode 100644
index e207ca1..0000000
--- a/wifi/tests/src/android/net/wifi/p2p/WifiP2pInfoTest.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p;
-
-import static org.junit.Assert.assertEquals;
-
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.net.InetAddress;
-
-/**
- * Unit test harness for {@link android.net.wifi.p2p.WifiP2pInfo}
- */
-@SmallTest
-public class WifiP2pInfoTest {
-
-    private InetAddress mGroupOnwerIpv4Address;
-
-    @Before
-    public void setUp() throws Exception {
-        byte[] ipv4 = {(byte) 192, (byte) 168, (byte) 49, (byte) 1};
-        mGroupOnwerIpv4Address = InetAddress.getByAddress(ipv4);
-    }
-
-    /**
-     * Verifies copy constructor.
-     */
-    @Test
-    public void testCopyOperator() throws Exception {
-        WifiP2pInfo info = new WifiP2pInfo();
-        info.groupFormed = true;
-        info.isGroupOwner = true;
-        info.groupOwnerAddress = mGroupOnwerIpv4Address;
-
-        WifiP2pInfo copiedInfo = new WifiP2pInfo(info);
-
-        // no equals operator, use toString for data comparison.
-        assertEquals(info.toString(), copiedInfo.toString());
-    }
-
-    /**
-     * Verifies parcel serialization/deserialization.
-     */
-    @Test
-    public void testParcelOperation() throws Exception {
-        WifiP2pInfo info = new WifiP2pInfo();
-        info.groupFormed = true;
-        info.isGroupOwner = true;
-        info.groupOwnerAddress = mGroupOnwerIpv4Address;
-
-        Parcel parcelW = Parcel.obtain();
-        info.writeToParcel(parcelW, 0);
-        byte[] bytes = parcelW.marshall();
-        parcelW.recycle();
-
-        Parcel parcelR = Parcel.obtain();
-        parcelR.unmarshall(bytes, 0, bytes.length);
-        parcelR.setDataPosition(0);
-        WifiP2pInfo fromParcel = WifiP2pInfo.CREATOR.createFromParcel(parcelR);
-
-        // no equals operator, use toString for data comparison.
-        assertEquals(info.toString(), fromParcel.toString());
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/p2p/WifiP2pManagerTest.java b/wifi/tests/src/android/net/wifi/p2p/WifiP2pManagerTest.java
deleted file mode 100644
index 9e8dca4..0000000
--- a/wifi/tests/src/android/net/wifi/p2p/WifiP2pManagerTest.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.verify;
-
-import android.content.Context;
-import android.os.test.TestLooper;
-
-import androidx.test.filters.SmallTest;
-
-import libcore.junit.util.ResourceLeakageDetector;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-/**
- * Unit test harness for WifiP2pManager.
- */
-@SmallTest
-public class WifiP2pManagerTest {
-    private WifiP2pManager mDut;
-    private TestLooper mTestLooper;
-
-    @Mock
-    public Context mContextMock;
-    @Mock
-    IWifiP2pManager mP2pServiceMock;
-
-    @Rule
-    public ResourceLeakageDetector.LeakageDetectorRule leakageDetectorRule =
-            ResourceLeakageDetector.getRule();
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-
-        mDut = new WifiP2pManager(mP2pServiceMock);
-        mTestLooper = new TestLooper();
-    }
-
-    /**
-     * Validate that on finalize we close the channel and flag a resource leakage.
-     */
-    @Test
-    public void testChannelFinalize() throws Exception {
-        try (WifiP2pManager.Channel channel = new WifiP2pManager.Channel(mContextMock,
-                mTestLooper.getLooper(), null, null, mDut)) {
-            leakageDetectorRule.assertUnreleasedResourceCount(channel, 1);
-        }
-    }
-
-    /**
-     * Validate that when close is called on a channel it frees up resources (i.e. don't
-     * get flagged again on finalize).
-     */
-    @Test
-    public void testChannelClose() throws Exception {
-        WifiP2pManager.Channel channel = new WifiP2pManager.Channel(mContextMock,
-                mTestLooper.getLooper(), null, null, mDut);
-
-        channel.close();
-        verify(mP2pServiceMock).close(any());
-
-        leakageDetectorRule.assertUnreleasedResourceCount(channel, 0);
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/p2p/WifiP2pProvDiscEventTest.java b/wifi/tests/src/android/net/wifi/p2p/WifiP2pProvDiscEventTest.java
deleted file mode 100644
index e3b10a7..0000000
--- a/wifi/tests/src/android/net/wifi/p2p/WifiP2pProvDiscEventTest.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-/**
- * Unit test harness for {@link android.net.wifi.p2p.WifiP2pProvDiscEvent}
- */
-@SmallTest
-public class WifiP2pProvDiscEventTest {
-
-    private static final String DEVICE_ADDRESS = "aa:bb:cc:dd:ee:ff";
-    private static final String EVENT_PBC_REQ_STRING = "P2P-PROV-DISC-PBC-REQ";
-    private static final String EVENT_PBC_RSP_STRING = "P2P-PROV-DISC-PBC-RESP";
-    private static final String EVENT_ENTER_PIN_STRING = "P2P-PROV-DISC-ENTER-PIN";
-    private static final String EVENT_SHOW_PIN_STRING = "P2P-PROV-DISC-SHOW-PIN";
-    private static final String TEST_PIN = "44490607";
-
-    /**
-     * Test parsing PBC request event.
-     */
-    @Test
-    public void testPbcReqEvent() throws Exception {
-        WifiP2pProvDiscEvent event =
-                new WifiP2pProvDiscEvent(EVENT_PBC_REQ_STRING + " " + DEVICE_ADDRESS);
-        assertEquals(WifiP2pProvDiscEvent.PBC_REQ, event.event);
-        assertEquals(DEVICE_ADDRESS, event.device.deviceAddress);
-    }
-
-
-    /**
-     * Test parsing PBC response event.
-     */
-    @Test
-    public void testPbcRespEvent() throws Exception {
-        WifiP2pProvDiscEvent event =
-                new WifiP2pProvDiscEvent(EVENT_PBC_RSP_STRING + " " + DEVICE_ADDRESS);
-        assertEquals(WifiP2pProvDiscEvent.PBC_RSP, event.event);
-        assertEquals(DEVICE_ADDRESS, event.device.deviceAddress);
-    }
-
-    /**
-     * Test parsing ENTER-PIN event.
-     */
-    @Test
-    public void testEnterPinEvent() throws Exception {
-        WifiP2pProvDiscEvent event =
-                new WifiP2pProvDiscEvent(EVENT_ENTER_PIN_STRING + " " + DEVICE_ADDRESS);
-        assertEquals(WifiP2pProvDiscEvent.ENTER_PIN, event.event);
-        assertEquals(DEVICE_ADDRESS, event.device.deviceAddress);
-    }
-
-    /**
-     * Test parsing SHOW-PIN event.
-     */
-    @Test
-    public void testShowPinEvent() throws Exception {
-        WifiP2pProvDiscEvent event =
-                new WifiP2pProvDiscEvent(
-                        EVENT_SHOW_PIN_STRING + " " + DEVICE_ADDRESS + " " + TEST_PIN);
-        assertEquals(WifiP2pProvDiscEvent.SHOW_PIN, event.event);
-        assertEquals(DEVICE_ADDRESS, event.device.deviceAddress);
-        assertEquals(TEST_PIN, event.pin);
-    }
-
-    /**
-     * Test parsing malformed input.
-     */
-    @Test
-    public void testMalformedInput() throws Exception {
-        try {
-            WifiP2pProvDiscEvent event = new WifiP2pProvDiscEvent("OneToken");
-            fail("Should throw IllegalArgumentException exception.");
-        } catch (IllegalArgumentException ex) {
-            // expected exception.
-        }
-    }
-
-    /**
-     * Test parsing malformed event.
-     */
-    @Test
-    public void testMalformedEvent() throws Exception {
-        try {
-            WifiP2pProvDiscEvent event = new WifiP2pProvDiscEvent("XXX " + DEVICE_ADDRESS);
-            fail("Should throw IllegalArgumentException exception.");
-        } catch (IllegalArgumentException ex) {
-            // expected exception.
-        }
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/p2p/WifiP2pWfdInfoTest.java b/wifi/tests/src/android/net/wifi/p2p/WifiP2pWfdInfoTest.java
deleted file mode 100644
index 2a9b36b..0000000
--- a/wifi/tests/src/android/net/wifi/p2p/WifiP2pWfdInfoTest.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Unit test harness for {@link android.net.wifi.p2p.WifiP2pWfdInfo}
- */
-@SmallTest
-public class WifiP2pWfdInfoTest {
-
-    private static final int TEST_CTRL_PORT = 9999;
-    private static final int TEST_MAX_TPUT = 1024;
-
-    private WifiP2pWfdInfo mSourceInfo = new WifiP2pWfdInfo(
-            0,
-            TEST_CTRL_PORT,
-            TEST_MAX_TPUT);
-
-    @Before
-    public void setUp() {
-        // initialize device info flags.
-        mSourceInfo.setDeviceType(WifiP2pWfdInfo.DEVICE_TYPE_WFD_SOURCE);
-        mSourceInfo.setSessionAvailable(true);
-        mSourceInfo.setContentProtectionSupported(true);
-    }
-
-    /**
-     * Verifies setters/getters.
-     */
-    @Test
-    public void testSettersGetters() throws Exception {
-        WifiP2pWfdInfo info = new WifiP2pWfdInfo();
-
-        info.setEnabled(true);
-        assertTrue(info.isEnabled());
-
-        info.setDeviceType(WifiP2pWfdInfo.DEVICE_TYPE_WFD_SOURCE);
-        assertEquals(WifiP2pWfdInfo.DEVICE_TYPE_WFD_SOURCE, info.getDeviceType());
-
-        info.setSessionAvailable(true);
-        assertTrue(info.isSessionAvailable());
-
-        info.setContentProtectionSupported(true);
-        assertTrue(info.isContentProtectionSupported());
-
-        info.setControlPort(TEST_CTRL_PORT);
-        assertEquals(TEST_CTRL_PORT, info.getControlPort());
-
-        info.setMaxThroughput(TEST_MAX_TPUT);
-        assertEquals(TEST_MAX_TPUT, info.getMaxThroughput());
-
-        assertEquals("0110270f0400", info.getDeviceInfoHex());
-    }
-
-    /**
-     * Verifies copy constructor.
-     */
-    @Test
-    public void testCopyOperator() throws Exception {
-        WifiP2pWfdInfo copiedInfo = new WifiP2pWfdInfo(mSourceInfo);
-
-        // no equals operator, use toString for data comparison.
-        assertEquals(mSourceInfo.toString(), copiedInfo.toString());
-    }
-
-    /**
-     * Verifies parcel serialization/deserialization.
-     */
-    @Test
-    public void testParcelOperation() throws Exception {
-        Parcel parcelW = Parcel.obtain();
-        mSourceInfo.writeToParcel(parcelW, 0);
-        byte[] bytes = parcelW.marshall();
-        parcelW.recycle();
-
-        Parcel parcelR = Parcel.obtain();
-        parcelR.unmarshall(bytes, 0, bytes.length);
-        parcelR.setDataPosition(0);
-        WifiP2pWfdInfo fromParcel = WifiP2pWfdInfo.CREATOR.createFromParcel(parcelR);
-
-        // no equals operator, use toString for data comparison.
-        assertEquals(mSourceInfo.toString(), fromParcel.toString());
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfoTest.java b/wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfoTest.java
deleted file mode 100644
index e1cffee..0000000
--- a/wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfoTest.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p.nsd;
-
-import static org.junit.Assert.fail;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Unit test harness for {@link android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceInfo}
- */
-@SmallTest
-public class WifiP2pDnsSdServiceInfoTest {
-
-    private static final String INSTANCE_NAME = "MyPrinter";
-    private static final String SERVICE_TYPE = "_ipp._tcp";
-    private static final String TXTRECORD_PROP_AVAILABLE = "available";
-    private static final String TXTRECORD_PROP_AVAILABLE_VISABLE = "visable";
-
-    private Map<String, String> mTxtMap = new HashMap<>();
-
-    @Before
-    public void setUp() throws Exception {
-        mTxtMap.put(TXTRECORD_PROP_AVAILABLE, TXTRECORD_PROP_AVAILABLE_VISABLE);
-    }
-
-    /**
-     * Verify newInstance API
-     */
-    @Test
-    public void testNewInstance() throws Exception {
-        WifiP2pDnsSdServiceInfo info = null;
-
-        // the least arguments
-        info = WifiP2pDnsSdServiceInfo.newInstance(
-                INSTANCE_NAME,
-                SERVICE_TYPE,
-                null);
-
-        // all arguments are given.
-        info = WifiP2pDnsSdServiceInfo.newInstance(
-                INSTANCE_NAME,
-                SERVICE_TYPE,
-                mTxtMap);
-
-        // failure case due to no instance name.
-        try {
-            info = WifiP2pDnsSdServiceInfo.newInstance(
-                    null,
-                    SERVICE_TYPE,
-                    null);
-            fail("should throw IllegalArgumentException");
-        } catch (IllegalArgumentException ex) {
-            // expected exception.
-        }
-
-        // failure case due to no service type.
-        try {
-            info = WifiP2pDnsSdServiceInfo.newInstance(
-                    INSTANCE_NAME,
-                    null,
-                    null);
-            fail("should throw IllegalArgumentException");
-        } catch (IllegalArgumentException ex) {
-            // expected exception.
-        }
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceRequestTest.java b/wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceRequestTest.java
deleted file mode 100644
index 7d46a5f..0000000
--- a/wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceRequestTest.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p.nsd;
-
-import static org.junit.Assert.fail;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-/**
- * Unit test harness for {@link android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceRequest}
- */
-@SmallTest
-public class WifiP2pDnsSdServiceRequestTest {
-
-    private static final String SERVICE_NAME = "MyPrinter";
-    private static final String SERVICE_TYPE = "_ipp._tcp";
-
-    @Test
-    public void testNewInstance() throws Exception {
-        WifiP2pDnsSdServiceRequest request = null;
-
-        // default new instance
-        request = WifiP2pDnsSdServiceRequest.newInstance();
-
-        // set service type
-        request = WifiP2pDnsSdServiceRequest.newInstance(SERVICE_TYPE);
-
-        // set service type
-        request = WifiP2pDnsSdServiceRequest.newInstance(SERVICE_NAME, SERVICE_TYPE);
-
-        // failure case due to null service type
-        try {
-            request = WifiP2pDnsSdServiceRequest.newInstance(null);
-            fail("should throw IllegalArgumentException");
-        } catch (IllegalArgumentException ex) {
-            // expected exception.
-        }
-
-        // failure case due to null service name
-        try {
-            request = WifiP2pDnsSdServiceRequest.newInstance(SERVICE_NAME, null);
-            fail("should throw IllegalArgumentException");
-        } catch (IllegalArgumentException ex) {
-            // expected exception.
-        }
-
-        // failure case due to null service type
-        try {
-            request = WifiP2pDnsSdServiceRequest.newInstance(null, SERVICE_TYPE);
-            fail("should throw IllegalArgumentException");
-        } catch (IllegalArgumentException ex) {
-            // expected exception.
-        }
-
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceInfoTest.java b/wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceInfoTest.java
deleted file mode 100644
index 49ead11..0000000
--- a/wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceInfoTest.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p.nsd;
-
-import static org.junit.Assert.fail;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Unit test harness for {@link android.net.wifi.p2p.nsd.WifiP2pUpnpServiceInfo}
- */
-@SmallTest
-public class WifiP2pUpnpServiceInfoTest {
-
-    private static final String UUID = "6859dede-8574-59ab-9332-123456789012";
-    private static final String DEVICE = "aa:bb:cc:dd:ee:ff";
-
-    private List<String> mServiceList = new ArrayList<>();
-
-    @Before
-    public void setUp() throws Exception {
-        mServiceList.add("urn:schemas-upnp-org:service:ContentDirectory:1");
-    }
-
-    /**
-     * Verify newInstance API
-     */
-    @Test
-    public void testNewInstance() throws Exception {
-        WifiP2pUpnpServiceInfo info = null;
-
-        // the least arguments
-        info = WifiP2pUpnpServiceInfo.newInstance(
-                UUID, DEVICE, null);
-
-        // all arguments are given.
-        info = WifiP2pUpnpServiceInfo.newInstance(
-                UUID, DEVICE, mServiceList);
-
-        // failure case due to no UUID.
-        try {
-            info = WifiP2pUpnpServiceInfo.newInstance(
-                    null, DEVICE, null);
-            fail("should throw IllegalArgumentException");
-        } catch (IllegalArgumentException ex) {
-            // expected exception.
-        }
-
-        // failure case due to no device.
-        try {
-            info = WifiP2pUpnpServiceInfo.newInstance(
-                    UUID,
-                    null,
-                    null);
-            fail("should throw IllegalArgumentException");
-        } catch (IllegalArgumentException ex) {
-            // expected exception.
-        }
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceRequestTest.java b/wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceRequestTest.java
deleted file mode 100644
index 79930dc..0000000
--- a/wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceRequestTest.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p.nsd;
-
-import static org.junit.Assert.fail;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-/**
- * Unit test harness for {@link android.net.wifi.p2p.nsd.WifiP2pUpnpServiceRequest}
- */
-@SmallTest
-public class WifiP2pUpnpServiceRequestTest {
-
-    @Test
-    public void testNewInstance() throws Exception {
-        WifiP2pUpnpServiceRequest request = null;
-
-        // Create a service discovery request to search all UPnP services.
-        request = WifiP2pUpnpServiceRequest.newInstance();
-
-        // Create a service discovery request to search specified UPnP services.
-        request = WifiP2pUpnpServiceRequest.newInstance("ssdp:all");
-
-        // failure case due to null target string
-        try {
-            request = WifiP2pUpnpServiceRequest.newInstance(null);
-            fail("should throw IllegalArgumentException");
-        } catch (IllegalArgumentException ex) {
-            // expected exception.
-        }
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/rtt/CivicLocationTest.java b/wifi/tests/src/android/net/wifi/rtt/CivicLocationTest.java
deleted file mode 100644
index f746fb7..0000000
--- a/wifi/tests/src/android/net/wifi/rtt/CivicLocationTest.java
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.rtt;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertNull;
-import static junit.framework.Assert.assertTrue;
-
-import android.location.Address;
-import android.os.Parcel;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/**
- * Tests for {@link CivicLocation}.
- */
-@RunWith(JUnit4.class)
-public class CivicLocationTest {
-    private static final String sUsCountryCode = "US";
-
-    private static final byte[] sEmptyBuffer = {};
-
-    private static final byte[] sTestCivicLocationBuffer = {
-            (byte) 17,
-            (byte) 3,
-            (byte) 'a',
-            (byte) 'b',
-            (byte) 'c',
-            (byte) 4,
-            (byte) 4,
-            (byte) 'd',
-            (byte) 'e',
-            (byte) 'f',
-            (byte) 'g',
-            (byte) 12,
-            (byte) 1,
-            (byte) 'h'
-    };
-
-    private static final byte[] sTestCivicLocationBufferWithAddress = {
-            (byte) CivicLocationKeys.HNO,
-            (byte) 2,
-            (byte) '1',
-            (byte) '5',
-            (byte) CivicLocationKeys.PRIMARY_ROAD_NAME,
-            (byte) 4,
-            (byte) 'A',
-            (byte) 'l',
-            (byte) 't',
-            (byte) 'o',
-            (byte) CivicLocationKeys.STREET_NAME_POST_MODIFIER,
-            (byte) 4,
-            (byte) 'R',
-            (byte) 'o',
-            (byte) 'a',
-            (byte) 'd',
-            (byte) CivicLocationKeys.CITY,
-            (byte) 8,
-            (byte) 'M',
-            (byte) 't',
-            (byte) 'n',
-            (byte) ' ',
-            (byte) 'V',
-            (byte) 'i',
-            (byte) 'e',
-            (byte) 'w',
-            (byte) CivicLocationKeys.STATE,
-            (byte) 2,
-            (byte) 'C',
-            (byte) 'A',
-            (byte) CivicLocationKeys.POSTAL_CODE,
-            (byte) 5,
-            (byte) '9',
-            (byte) '4',
-            (byte) '0',
-            (byte) '4',
-            (byte) '3'
-    };
-
-    /**
-     * Test inValid for null CountryCode.
-     */
-    @Test
-    public void testCivicLocationNullCountryCode() {
-        CivicLocation civicLocation = new CivicLocation(sTestCivicLocationBuffer, null);
-
-        boolean valid = civicLocation.isValid();
-
-        assertFalse(valid);
-    }
-
-    /**
-     * Test inValid for CountryCode too short.
-     */
-    @Test
-    public void testCivicLocationCountryCodeTooShort() {
-        CivicLocation civicLocation = new CivicLocation(sTestCivicLocationBuffer, "X");
-
-        boolean valid = civicLocation.isValid();
-
-        assertFalse(valid);
-    }
-
-    /**
-     * Test inValid for CountryCode too long.
-     */
-    @Test
-    public void testCivicLocationCountryCodeTooLong() {
-        CivicLocation civicLocation = new CivicLocation(sTestCivicLocationBuffer, "XYZ");
-
-        boolean valid = civicLocation.isValid();
-
-        assertFalse(valid);
-    }
-
-    /**
-     * Test inValid for null CivicLocation Buffer
-     */
-    @Test
-    public void testCivicLocationNullBuffer() {
-        CivicLocation civicLocation = new CivicLocation(null, sUsCountryCode);
-
-        boolean valid = civicLocation.isValid();
-
-        assertFalse(valid);
-    }
-
-    /**
-     * Test inValid for Empty CivicLocation Buffer.
-     */
-    @Test
-    public void testCivicLocationEmptyBuffer() {
-        CivicLocation civicLocation = new CivicLocation(sEmptyBuffer, sUsCountryCode);
-
-        boolean valid = civicLocation.isValid();
-
-        assertFalse(valid);
-    }
-
-    /**
-     * Test for valid CivicLocationBuffer and Country Code.
-     */
-    @Test
-    public void testCivicLocationValid() {
-        CivicLocation civicLocation = new CivicLocation(sTestCivicLocationBuffer, sUsCountryCode);
-
-        boolean valid = civicLocation.isValid();
-
-        assertTrue(valid);
-    }
-
-    /**
-     * Test toString Representation
-     */
-    @Test
-    public void testCivicLocationToString() {
-        CivicLocation civicLocation = new CivicLocation(sTestCivicLocationBuffer, sUsCountryCode);
-
-        String str = civicLocation.toString();
-
-        assertEquals("{4=defg, 12=h, 17=abc}", str);
-    }
-
-    /**
-     * Test the toString
-     */
-    @Test
-    public void testCivicLocationgetElementValue() {
-        CivicLocation civicLocation = new CivicLocation(sTestCivicLocationBuffer, sUsCountryCode);
-
-        String value1 = civicLocation.getCivicElementValue(4);
-        String value2 = civicLocation.getCivicElementValue(17);
-        String value3 = civicLocation.getCivicElementValue(12);
-        String value4 = civicLocation.getCivicElementValue(156); // not in test data
-        String value5 = civicLocation.getCivicElementValue(276); // greater than key index
-
-        assertEquals("defg", value1);
-        assertEquals("abc", value2);
-        assertEquals("h", value3);
-        assertNull(value4);
-        assertNull(value5);
-    }
-
-    /* Test toAddress representation */
-    @Test
-    public void testCivicLocationToAddress() {
-        CivicLocation civicLocation =
-                new CivicLocation(sTestCivicLocationBufferWithAddress, sUsCountryCode);
-
-        Address address = civicLocation.toAddress();
-
-        assertEquals("", address.getAddressLine(0));
-        assertEquals("15 Alto", address.getAddressLine(1));
-        assertEquals("Mtn View", address.getAddressLine(2));
-        assertEquals("CA 94043", address.getAddressLine(3));
-        assertEquals("US", address.getAddressLine(4));
-    }
-
-    /**
-     * Test toString Representation
-     */
-    @Test
-    public void testCivicLocationToString2() {
-        CivicLocation civicLocation =
-                new CivicLocation(sTestCivicLocationBufferWithAddress, sUsCountryCode);
-
-        String str = civicLocation.toString();
-
-        assertEquals("{1=CA, 3=Mtn View, 19=15, 24=94043, 34=Alto, 39=Road}", str);
-    }
-
-    /** Test object is Parcellable */
-    @Test
-    public void testCivicLocationParcelable() {
-        CivicLocation civicLocation =
-                new CivicLocation(sTestCivicLocationBufferWithAddress, sUsCountryCode);
-
-        Parcel parcel = Parcel.obtain();
-        civicLocation.writeToParcel(parcel, 0);
-        parcel.setDataPosition(0);
-        CivicLocation civicLocationFromParcel =
-                CivicLocation.CREATOR.createFromParcel(parcel);
-
-        assertEquals(civicLocationFromParcel, civicLocation);
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/rtt/ResponderLocationTest.java b/wifi/tests/src/android/net/wifi/rtt/ResponderLocationTest.java
deleted file mode 100644
index 271339c..0000000
--- a/wifi/tests/src/android/net/wifi/rtt/ResponderLocationTest.java
+++ /dev/null
@@ -1,589 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.rtt;
-
-import android.location.Address;
-import android.location.Location;
-import android.net.MacAddress;
-import android.os.Parcel;
-import android.util.SparseArray;
-import android.webkit.MimeTypeMap;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-import java.util.List;
-
-/**
- * Tests for {@link ResponderLocation}.
- */
-@RunWith(JUnit4.class)
-public class ResponderLocationTest {
-    private static final double LATLNG_TOLERANCE_DEGREES = 0.000_000_05D; // 5E-8 = 6mm of meridian
-    private static final double ALT_TOLERANCE_METERS = 0.01;
-    private static final double HEIGHT_TOLERANCE_METERS = 0.01;
-    private static final int INDEX_ELEMENT_TYPE = 2;
-    private static final int INDEX_SUBELEMENT_TYPE = 0;
-    private static final int INDEX_SUBELEMENT_LENGTH = 1;
-
-    /* Test Buffers */
-
-    private static final byte[] sTestLciIeHeader = {
-            (byte) 0x01, (byte) 0x00, (byte) 0x08 // LCI Information Element (IE)
-    };
-
-    private static final byte[] sTestLciShortBuffer = {
-        (byte) 0x00
-    };
-
-    private static final byte[] sTestLciSE = {
-            (byte) 0x00, // Subelement LCI
-            (byte) 16,   // Subelement LCI length always = 16
-            (byte) 0x52,
-            (byte) 0x83,
-            (byte) 0x4d,
-            (byte) 0x12,
-            (byte) 0xef,
-            (byte) 0xd2,
-            (byte) 0xb0,
-            (byte) 0x8b,
-            (byte) 0x9b,
-            (byte) 0x4b,
-            (byte) 0xf1,
-            (byte) 0xcc,
-            (byte) 0x2c,
-            (byte) 0x00,
-            (byte) 0x00,
-            (byte) 0x41
-    };
-
-    private static final byte[] sTestZHeightSE = {
-            (byte) 0x04, // Subelement Z
-            (byte) 6, // Length always 6
-            (byte) 0x00, // LSB STA Floor Info (2 bytes)
-            (byte) 0x01, // MSB
-            (byte) 0xcd, // LSB Height(m) (3 bytes)
-            (byte) 0x2c,
-            (byte) 0x00, // MSB Height(m)
-            (byte) 0x0e, // STA Height Uncertainty
-    };
-
-    private static final byte[] sTestUsageSE1 = {
-            (byte) 0x06, // Subelement Usage Rights
-            (byte) 1, // Length 1 (with no retention limit)
-            (byte) 0x01, // Retransmit ok, No expiration, no extra info available
-    };
-
-    private static final byte[] sTestUsageSE2 = {
-            (byte) 0x06, // Subelement Usage Rights
-            (byte) 3,    // Length 3 (including retention limit)
-            (byte) 0x06, // Retransmit not ok, Expiration, extra info available
-            (byte) 0x00, // LSB expiration time  (0x8000 = 32768 hrs)
-            (byte) 0x80  // MSB expiration time
-    };
-
-    private static final byte[] sTestBssidListSE = {
-            (byte) 0x07, // Subelement BSSID list
-            (byte) 13, // length dependent on number of BSSIDs in list
-            (byte) 0x00, // List is explicit; no expansion of list required
-            (byte) 0x01, // BSSID #1 (MSB)
-            (byte) 0x02,
-            (byte) 0x03,
-            (byte) 0x04,
-            (byte) 0x05,
-            (byte) 0x06, // (LSB)
-            (byte) 0xf1, // BSSID #2 (MSB)
-            (byte) 0xf2,
-            (byte) 0xf3,
-            (byte) 0xf4,
-            (byte) 0xf5,
-            (byte) 0xf6 // (LSB)
-    };
-
-    private static final byte[] sTestLcrBufferHeader = {
-            (byte) 0x01, (byte) 0x00, (byte) 0x0b,
-    };
-
-    private static final byte[] sEmptyBuffer = {};
-
-    private static final byte[] sTestCivicLocationSEWithAddress = {
-            (byte) 0, // Civic Location Subelement
-            (byte) 39, // Length of subelement value
-            (byte) 'U', // CountryCodeChar1
-            (byte) 'S', // CountryCodeChar2
-            (byte) CivicLocationKeys.HNO,
-            (byte) 2,
-            (byte) '1',
-            (byte) '5',
-            (byte) CivicLocationKeys.PRIMARY_ROAD_NAME,
-            (byte) 4,
-            (byte) 'A',
-            (byte) 'l',
-            (byte) 't',
-            (byte) 'o',
-            (byte) CivicLocationKeys.STREET_NAME_POST_MODIFIER,
-            (byte) 4,
-            (byte) 'R',
-            (byte) 'o',
-            (byte) 'a',
-            (byte) 'd',
-            (byte) CivicLocationKeys.CITY,
-            (byte) 8,
-            (byte) 'M',
-            (byte) 't',
-            (byte) 'n',
-            (byte) ' ',
-            (byte) 'V',
-            (byte) 'i',
-            (byte) 'e',
-            (byte) 'w',
-            (byte) CivicLocationKeys.STATE,
-            (byte) 2,
-            (byte) 'C',
-            (byte) 'A',
-            (byte) CivicLocationKeys.POSTAL_CODE,
-            (byte) 5,
-            (byte) '9',
-            (byte) '4',
-            (byte) '0',
-            (byte) '4',
-            (byte) '3'
-    };
-
-    // Buffer representing: "https://map.com/mall.jpg"
-    private static final byte[] sTestMapUrlSE = {
-            (byte) 5, // Map URL Subelement
-            (byte) 25,
-            (byte) 0, // MAP_TYPE_URL_DEFINED
-            (byte) 'h',
-            (byte) 't',
-            (byte) 't',
-            (byte) 'p',
-            (byte) 's',
-            (byte) ':',
-            (byte) '/',
-            (byte) '/',
-            (byte) 'm',
-            (byte) 'a',
-            (byte) 'p',
-            (byte) '.',
-            (byte) 'c',
-            (byte) 'o',
-            (byte) 'm',
-            (byte) '/',
-            (byte) 'm',
-            (byte) 'a',
-            (byte) 'l',
-            (byte) 'l',
-            (byte) '.',
-            (byte) 'j',
-            (byte) 'p',
-            (byte) 'g'
-    };
-
-    /**
-     * Test if the lci and lcr buffers are null.
-     */
-    @Test
-    public void testIfLciOrLcrIsNull() {
-        ResponderLocation responderLocation = new ResponderLocation(null, null);
-
-        boolean valid = responderLocation.isValid();
-        boolean lciValid = responderLocation.isLciSubelementValid();
-        boolean zValid = responderLocation.isZaxisSubelementValid();
-
-        assertFalse(valid);
-        assertFalse(lciValid);
-        assertFalse(zValid);
-    }
-
-    /**
-     * Test if the lci and lcr buffers are empty.
-     */
-    @Test
-    public void testIfLciOrLcrIsEmpty() {
-        ResponderLocation responderLocation = new ResponderLocation(sEmptyBuffer, sEmptyBuffer);
-
-        boolean valid = responderLocation.isValid();
-        boolean lciValid = responderLocation.isLciSubelementValid();
-        boolean zValid = responderLocation.isZaxisSubelementValid();
-
-        assertFalse(valid);
-        assertFalse(lciValid);
-        assertFalse(zValid);
-    }
-
-    /**
-     * Test if the lci subelement only has one byte
-     */
-    @Test
-    public void testIfLciShortBuffer() {
-        byte[] testLciBuffer = concatenateArrays(sTestLciIeHeader, sTestLciShortBuffer);
-        ResponderLocation responderLocation =
-                new ResponderLocation(testLciBuffer, sTestLcrBufferHeader);
-
-        boolean valid = responderLocation.isValid();
-        boolean lciValid = responderLocation.isLciSubelementValid();
-        boolean zValid = responderLocation.isZaxisSubelementValid();
-
-        assertFalse(valid);
-        assertFalse(lciValid);
-        assertFalse(zValid);
-    }
-
-    /**
-     * Test that the example buffer contains a valid LCI Subelement.
-     */
-    @Test
-    public void testLciValidSubelement() {
-        byte[] testLciBuffer = concatenateArrays(sTestLciIeHeader, sTestLciSE);
-        ResponderLocation responderLocation =
-                new ResponderLocation(testLciBuffer, sTestLcrBufferHeader);
-
-        boolean valid = responderLocation.isValid();
-        boolean lciValid = responderLocation.isLciSubelementValid();
-        boolean zValid = responderLocation.isZaxisSubelementValid();
-        Location location = responderLocation.toLocation();
-
-        assertTrue(valid);
-        assertTrue(lciValid);
-        assertFalse(zValid);
-        assertEquals(0.0009765625D, responderLocation.getLatitudeUncertainty());
-        assertEquals(-33.8570095D, responderLocation.getLatitude(),
-                LATLNG_TOLERANCE_DEGREES);
-        assertEquals(0.0009765625D, responderLocation.getLongitudeUncertainty());
-        assertEquals(151.2152005D, responderLocation.getLongitude(),
-                LATLNG_TOLERANCE_DEGREES);
-        assertEquals(1, responderLocation.getAltitudeType());
-        assertEquals(64.0, responderLocation.getAltitudeUncertainty());
-        assertEquals(11.2, responderLocation.getAltitude(), ALT_TOLERANCE_METERS);
-        assertEquals(1, responderLocation.getDatum()); // WGS84
-        assertEquals(false, responderLocation.getRegisteredLocationAgreementIndication());
-        assertEquals(false, responderLocation.getRegisteredLocationDseIndication());
-        assertEquals(false, responderLocation.getDependentStationIndication());
-        assertEquals(1, responderLocation.getLciVersion());
-
-        // Testing Location Object
-        assertEquals(-33.8570095D, location.getLatitude(),
-                LATLNG_TOLERANCE_DEGREES);
-        assertEquals(151.2152005D, location.getLongitude(),
-                LATLNG_TOLERANCE_DEGREES);
-        assertEquals((0.0009765625D + 0.0009765625D) / 2, location.getAccuracy(),
-                LATLNG_TOLERANCE_DEGREES);
-        assertEquals(11.2, location.getAltitude(), ALT_TOLERANCE_METERS);
-        assertEquals(64.0, location.getVerticalAccuracyMeters(), ALT_TOLERANCE_METERS);
-    }
-
-    /**
-     * Test for an invalid LCI element.
-     */
-    @Test
-    public void testLciInvalidElement() {
-        byte[] testBuffer = concatenateArrays(sTestLciIeHeader, sTestLciSE);
-        testBuffer[INDEX_ELEMENT_TYPE] = (byte) 0xFF;
-        ResponderLocation responderLocation =
-                new ResponderLocation(testBuffer, sTestLcrBufferHeader);
-
-        boolean valid = responderLocation.isValid();
-        boolean lciValid = responderLocation.isLciSubelementValid();
-        boolean zValid = responderLocation.isZaxisSubelementValid();
-
-        assertFalse(valid);
-        assertFalse(lciValid);
-        assertFalse(zValid);
-    }
-
-    /**
-     * Test for an invalid subelement type.
-     */
-    @Test
-    public void testSkipLciSubElementUnusedOrUnknown() {
-        byte[] testLciBuffer = concatenateArrays(sTestLciIeHeader, sTestLciSE);
-        // Corrupt the subelement type to an unknown type.
-        testLciBuffer[sTestLciIeHeader.length + INDEX_SUBELEMENT_TYPE] = (byte) 0x77;
-        ResponderLocation responderLocation =
-                new ResponderLocation(testLciBuffer, sTestLcrBufferHeader);
-
-        boolean valid = responderLocation.isValid();
-        boolean lciValid = responderLocation.isLciSubelementValid();
-        boolean zValid = responderLocation.isZaxisSubelementValid();
-
-        assertFalse(valid);
-        assertFalse(lciValid);
-        assertFalse(zValid);
-    }
-
-    /**
-     * Test for a subelement LCI length too small.
-     */
-    @Test
-    public void testInvalidLciSubElementLengthTooSmall() {
-        byte[] testLciBuffer = concatenateArrays(sTestLciIeHeader, sTestLciSE);
-        // Corrupt the length making it too small.
-        testLciBuffer[sTestLciIeHeader.length + INDEX_SUBELEMENT_LENGTH] = (byte) 0x01;
-        ResponderLocation responderLocation =
-                new ResponderLocation(testLciBuffer, sTestLcrBufferHeader);
-
-        boolean valid = responderLocation.isValid();
-        boolean lciValid = responderLocation.isLciSubelementValid();
-        boolean zValid = responderLocation.isZaxisSubelementValid();
-
-        assertFalse(valid);
-        assertFalse(lciValid);
-        assertFalse(zValid);
-    }
-
-    /**
-     * Test for a subelement LCI length too big.
-     */
-    @Test
-    public void testInvalidLciSubElementLengthTooBig() {
-        byte[] testLciBuffer = concatenateArrays(sTestLciIeHeader, sTestLciSE);
-        // Corrupt the length making it too big.
-        testLciBuffer[sTestLciIeHeader.length + INDEX_SUBELEMENT_TYPE] = (byte) 0x11;
-        ResponderLocation responderLocation =
-                new ResponderLocation(testLciBuffer, sTestLcrBufferHeader);
-
-        boolean valid = responderLocation.isValid();
-        boolean lciValid = responderLocation.isLciSubelementValid();
-        boolean zValid = responderLocation.isZaxisSubelementValid();
-
-        assertFalse(valid);
-        assertFalse(lciValid);
-        assertFalse(zValid);
-    }
-
-    /**
-     * Test for a valid Z (Height) subelement following an LCI subelement.
-     */
-    @Test
-    public void testLciValidZBufferSEAfterLci() {
-        byte[] testBufferTmp = concatenateArrays(sTestLciIeHeader, sTestLciSE);
-        byte[] testBuffer = concatenateArrays(testBufferTmp, sTestZHeightSE);
-        ResponderLocation responderLocation =
-                new ResponderLocation(testBuffer, sTestLcrBufferHeader);
-
-        boolean isValid = responderLocation.isValid();
-        boolean isZValid = responderLocation.isZaxisSubelementValid();
-        boolean isLciValid = responderLocation.isLciSubelementValid();
-        double staFloorNumber = responderLocation.getFloorNumber();
-        double staHeightAboveFloorMeters = responderLocation.getHeightAboveFloorMeters();
-        double staHeightAboveFloorUncertaintyMeters =
-                responderLocation.getHeightAboveFloorUncertaintyMeters();
-
-        assertTrue(isValid);
-        assertTrue(isZValid);
-        assertTrue(isLciValid);
-        assertEquals(4.0, staFloorNumber);
-        assertEquals(2.8, staHeightAboveFloorMeters, HEIGHT_TOLERANCE_METERS);
-        assertEquals(0.125, staHeightAboveFloorUncertaintyMeters);
-    }
-
-    /**
-     * Test for a valid Usage Policy that is unrestrictive
-     */
-    @Test
-    public void testLciOpenUsagePolicy() {
-        byte[] testBufferTmp = concatenateArrays(sTestLciIeHeader, sTestLciSE);
-        byte[] testBuffer = concatenateArrays(testBufferTmp, sTestUsageSE1);
-        ResponderLocation responderLocation =
-                new ResponderLocation(testBuffer, sTestLcrBufferHeader);
-
-        boolean valid = responderLocation.isValid();
-        boolean retransmit = responderLocation.getRetransmitPolicyIndication();
-        boolean expiration = responderLocation.getRetentionExpiresIndication();
-        boolean extraInfo = responderLocation.getExtraInfoOnAssociationIndication();
-
-        assertTrue(valid);
-        assertTrue(retransmit);
-        assertFalse(expiration);
-        assertFalse(extraInfo);
-    }
-
-    /**
-     * Test for a valid Usage Policy that is restrictive
-     */
-    @Test
-    public void testLciRestrictiveUsagePolicy() {
-        byte[] testBufferTmp = concatenateArrays(sTestLciIeHeader, sTestLciSE);
-        byte[] testBuffer = concatenateArrays(testBufferTmp, sTestUsageSE2);
-        ResponderLocation responderLocation =
-                new ResponderLocation(testBuffer, sTestLcrBufferHeader);
-
-        boolean valid = responderLocation.isValid();
-        boolean retransmit = responderLocation.getRetransmitPolicyIndication();
-        boolean expiration = responderLocation.getRetentionExpiresIndication();
-        boolean extraInfo = responderLocation.getExtraInfoOnAssociationIndication();
-
-        assertFalse(valid);
-        assertFalse(retransmit);
-        assertTrue(expiration);
-        assertTrue(extraInfo);
-    }
-
-    /**
-     * Test for a valid BSSID element following an LCI subelement.
-     */
-    @Test
-    public void testLciBssidListSEAfterLci() {
-        byte[] testBufferTmp = concatenateArrays(sTestLciIeHeader, sTestLciSE);
-        byte[] testBuffer = concatenateArrays(testBufferTmp, sTestBssidListSE);
-        ResponderLocation responderLocation =
-                new ResponderLocation(testBuffer, sTestLcrBufferHeader);
-
-        boolean valid = responderLocation.isValid();
-        List<MacAddress> bssidList = responderLocation.getColocatedBssids();
-
-        assertTrue(valid);
-        assertEquals(2, bssidList.size());
-        MacAddress macAddress1 = bssidList.get(0);
-        assertEquals("01:02:03:04:05:06", macAddress1.toString());
-        MacAddress macAddress2 = bssidList.get(1);
-        assertEquals("f1:f2:f3:f4:f5:f6", macAddress2.toString());
-    }
-
-    /**
-     * Test for a valid BSSID element before and LCI element
-     */
-    @Test
-    public void testLciBssidListSEBeforeLci() {
-        byte[] testBufferTmp = concatenateArrays(sTestLciIeHeader, sTestBssidListSE);
-        byte[] testBuffer = concatenateArrays(testBufferTmp, sTestLciSE);
-        ResponderLocation responderLocation =
-                new ResponderLocation(testBuffer, sTestLcrBufferHeader);
-
-        boolean valid = responderLocation.isValid();
-        List<MacAddress> bssidList = responderLocation.getColocatedBssids();
-
-        assertTrue(valid);
-        assertEquals(2, bssidList.size());
-        MacAddress macAddress1 = bssidList.get(0);
-        assertEquals("01:02:03:04:05:06", macAddress1.toString());
-        MacAddress macAddress2 = bssidList.get(1);
-        assertEquals("f1:f2:f3:f4:f5:f6", macAddress2.toString());
-    }
-
-    /**
-     * Test that a valid address can be extracted from a valid lcr buffer with Civic Location.
-     */
-    @Test
-    public void testLcrTestCivicLocationAddress() {
-        byte[] testLciBuffer = concatenateArrays(sTestLciIeHeader, sTestLciSE);
-        byte[] testLcrBuffer =
-                concatenateArrays(sTestLcrBufferHeader, sTestCivicLocationSEWithAddress);
-        ResponderLocation responderLocation = new ResponderLocation(testLciBuffer, testLcrBuffer);
-
-        boolean valid = responderLocation.isValid();
-        String countryCode = responderLocation.getCivicLocationCountryCode();
-        Address address = responderLocation.toCivicLocationAddress();
-
-        assertTrue(valid);
-        assertEquals("US", countryCode);
-        assertEquals("", address.getAddressLine(0));
-        assertEquals("15 Alto", address.getAddressLine(1));
-        assertEquals("Mtn View", address.getAddressLine(2));
-        assertEquals("CA 94043", address.getAddressLine(3));
-        assertEquals("US", address.getAddressLine(4));
-    }
-
-    /**
-     * Test that a Civic Location sparseArray can be extracted from a valid lcr buffer.
-     */
-    @Test
-    public void testLcrTestCivicLocationSparseArray() {
-        byte[] testLciBuffer = concatenateArrays(sTestLciIeHeader, sTestLciSE);
-        byte[] testLcrBuffer =
-                concatenateArrays(sTestLcrBufferHeader, sTestCivicLocationSEWithAddress);
-        ResponderLocation responderLocation = new ResponderLocation(testLciBuffer, testLcrBuffer);
-
-        boolean valid = responderLocation.isValid();
-        SparseArray<String> civicLocationSparseArray = responderLocation
-                .toCivicLocationSparseArray();
-
-        assertTrue(valid);
-        assertEquals("15", civicLocationSparseArray.get(CivicLocationKeys.HNO));
-        assertEquals("Alto",
-                civicLocationSparseArray.get(CivicLocationKeys.PRIMARY_ROAD_NAME));
-        assertEquals("Road",
-                civicLocationSparseArray.get(CivicLocationKeys.STREET_NAME_POST_MODIFIER));
-        assertEquals("Mtn View", civicLocationSparseArray.get(CivicLocationKeys.CITY));
-        assertEquals("94043", civicLocationSparseArray.get(CivicLocationKeys.POSTAL_CODE));
-    }
-
-    /**
-     * Test that a URL can be extracted from a valid lcr buffer with a map image subelement.
-     */
-    @Test
-    public void testLcrCheckMapUriIsValid() {
-        byte[] testLciBuffer = concatenateArrays(sTestLciIeHeader, sTestLciSE);
-        byte[] testLcrBuffer = concatenateArrays(sTestLcrBufferHeader, sTestMapUrlSE);
-        ResponderLocation responderLocation = new ResponderLocation(testLciBuffer, testLcrBuffer);
-
-        boolean valid = responderLocation.isValid();
-        String mapImageMimeType = responderLocation.getMapImageMimeType();
-        String urlString = "";
-        if (responderLocation.getMapImageUri() != null) {
-            urlString = responderLocation.getMapImageUri().toString();
-        }
-
-        assertTrue(valid);
-        MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton();
-        assertEquals(mimeTypeMap.getMimeTypeFromExtension("jpg"), mapImageMimeType);
-        assertEquals("https://map.com/mall.jpg", urlString);
-    }
-
-    /**
-     * Test the object is parcelable
-     */
-    @Test
-    public void testResponderLocationParcelable() {
-        byte[] testLciBuffer = concatenateArrays(sTestLciIeHeader, sTestLciSE);
-        ResponderLocation responderLocation =
-                new ResponderLocation(testLciBuffer, sTestLcrBufferHeader);
-
-        Parcel parcel = Parcel.obtain();
-        responderLocation.writeToParcel(parcel, 0);
-        parcel.setDataPosition(0);
-        ResponderLocation responderLocationFromParcel =
-                ResponderLocation.CREATOR.createFromParcel(parcel);
-
-        assertEquals(responderLocationFromParcel, responderLocation);
-    }
-
-    /* Helper Method */
-
-    /**
-     * Concatenate two arrays.
-     *
-     * @param a first array
-     * @param b second array
-     * @return a third array which is the concatenation of the two array params
-     */
-    private byte[] concatenateArrays(byte[] a, byte[] b) {
-        int aLen = a.length;
-        int bLen = b.length;
-        byte[] c = new byte[aLen + bLen];
-        System.arraycopy(a, 0, c, 0, aLen);
-        System.arraycopy(b, 0, c, aLen, bLen);
-        return c;
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/rtt/WifiRttManagerTest.java b/wifi/tests/src/android/net/wifi/rtt/WifiRttManagerTest.java
deleted file mode 100644
index e6eae416..0000000
--- a/wifi/tests/src/android/net/wifi/rtt/WifiRttManagerTest.java
+++ /dev/null
@@ -1,395 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.rtt;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.net.MacAddress;
-import android.net.wifi.ScanResult;
-import android.net.wifi.aware.PeerHandle;
-import android.os.IBinder;
-import android.os.Parcel;
-import android.os.test.TestLooper;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.Executor;
-
-/**
- * Unit test harness for WifiRttManager class.
- */
-@SmallTest
-public class WifiRttManagerTest {
-    private WifiRttManager mDut;
-    private TestLooper mMockLooper;
-    private Executor mMockLooperExecutor;
-
-    private final String packageName = "some.package.name.for.rtt.app";
-    private final String featureId = "some.feature.id.in.rtt.app";
-
-    @Mock
-    public Context mockContext;
-
-    @Mock
-    public IWifiRttManager mockRttService;
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-
-        mDut = new WifiRttManager(mockContext, mockRttService);
-        mMockLooper = new TestLooper();
-        mMockLooperExecutor = mMockLooper.getNewExecutor();
-
-        when(mockContext.getOpPackageName()).thenReturn(packageName);
-        when(mockContext.getAttributionTag()).thenReturn(featureId);
-    }
-
-    /**
-     * Validate ranging call flow with successful results.
-     */
-    @Test
-    public void testRangeSuccess() throws Exception {
-        RangingRequest request = new RangingRequest.Builder().build();
-        List<RangingResult> results = new ArrayList<>();
-        results.add(
-                new RangingResult(RangingResult.STATUS_SUCCESS, MacAddress.BROADCAST_ADDRESS, 15, 5,
-                        10, 8, 5, null, null, null, 666));
-        RangingResultCallback callbackMock = mock(RangingResultCallback.class);
-        ArgumentCaptor<IRttCallback> callbackCaptor = ArgumentCaptor.forClass(IRttCallback.class);
-
-        // verify ranging request passed to service
-        mDut.startRanging(request, mMockLooperExecutor, callbackMock);
-        verify(mockRttService).startRanging(any(IBinder.class), eq(packageName), eq(featureId),
-                eq(null),  eq(request), callbackCaptor.capture());
-
-        // service calls back with success
-        callbackCaptor.getValue().onRangingResults(results);
-        mMockLooper.dispatchAll();
-        verify(callbackMock).onRangingResults(results);
-
-        verifyNoMoreInteractions(mockRttService, callbackMock);
-    }
-
-    /**
-     * Validate ranging call flow which failed.
-     */
-    @Test
-    public void testRangeFail() throws Exception {
-        int failureCode = RangingResultCallback.STATUS_CODE_FAIL;
-
-        RangingRequest request = new RangingRequest.Builder().build();
-        RangingResultCallback callbackMock = mock(RangingResultCallback.class);
-        ArgumentCaptor<IRttCallback> callbackCaptor = ArgumentCaptor.forClass(IRttCallback.class);
-
-        // verify ranging request passed to service
-        mDut.startRanging(request, mMockLooperExecutor, callbackMock);
-        verify(mockRttService).startRanging(any(IBinder.class), eq(packageName), eq(featureId),
-                eq(null), eq(request), callbackCaptor.capture());
-
-        // service calls back with failure code
-        callbackCaptor.getValue().onRangingFailure(failureCode);
-        mMockLooper.dispatchAll();
-        verify(callbackMock).onRangingFailure(failureCode);
-
-        verifyNoMoreInteractions(mockRttService, callbackMock);
-    }
-
-    /**
-     * Validate that RangingRequest parcel works (produces same object on write/read).
-     */
-    @Test
-    public void testRangingRequestParcel() {
-        // Note: not validating parcel code of ScanResult (assumed to work)
-        ScanResult scanResult1 = new ScanResult();
-        scanResult1.BSSID = "00:01:02:03:04:05";
-        ScanResult scanResult2 = new ScanResult();
-        scanResult2.BSSID = "06:07:08:09:0A:0B";
-        ScanResult scanResult3 = new ScanResult();
-        scanResult3.BSSID = "AA:BB:CC:DD:EE:FF";
-        List<ScanResult> scanResults2and3 = new ArrayList<>(2);
-        scanResults2and3.add(scanResult2);
-        scanResults2and3.add(scanResult3);
-        MacAddress mac1 = MacAddress.fromString("00:01:02:03:04:05");
-        PeerHandle peerHandle1 = new PeerHandle(12);
-
-        RangingRequest.Builder builder = new RangingRequest.Builder();
-        builder.addAccessPoint(scanResult1);
-        builder.addAccessPoints(scanResults2and3);
-        builder.addWifiAwarePeer(mac1);
-        builder.addWifiAwarePeer(peerHandle1);
-        RangingRequest request = builder.build();
-
-        Parcel parcelW = Parcel.obtain();
-        request.writeToParcel(parcelW, 0);
-        byte[] bytes = parcelW.marshall();
-        parcelW.recycle();
-
-        Parcel parcelR = Parcel.obtain();
-        parcelR.unmarshall(bytes, 0, bytes.length);
-        parcelR.setDataPosition(0);
-        RangingRequest rereadRequest = RangingRequest.CREATOR.createFromParcel(parcelR);
-
-        assertEquals(request, rereadRequest);
-    }
-
-    /**
-     * Validate that can request as many range operation as the upper limit on number of requests.
-     */
-    @Test
-    public void testRangingRequestAtLimit() {
-        ScanResult scanResult = new ScanResult();
-        scanResult.BSSID = "AA:BB:CC:DD:EE:FF";
-        List<ScanResult> scanResultList = new ArrayList<>();
-        for (int i = 0; i < RangingRequest.getMaxPeers() - 3; ++i) {
-            scanResultList.add(scanResult);
-        }
-        MacAddress mac1 = MacAddress.fromString("00:01:02:03:04:05");
-
-        // create request
-        RangingRequest.Builder builder = new RangingRequest.Builder();
-        builder.addAccessPoint(scanResult);
-        builder.addAccessPoints(scanResultList);
-        builder.addAccessPoint(scanResult);
-        builder.addWifiAwarePeer(mac1);
-        RangingRequest request = builder.build();
-
-        // verify request
-        request.enforceValidity(true);
-    }
-
-    /**
-     * Validate that limit on number of requests is applied.
-     */
-    @Test(expected = IllegalArgumentException.class)
-    public void testRangingRequestPastLimit() {
-        ScanResult scanResult = new ScanResult();
-        scanResult.BSSID = "00:01:02:03:04:05";
-        List<ScanResult> scanResultList = new ArrayList<>();
-        for (int i = 0; i < RangingRequest.getMaxPeers() - 2; ++i) {
-            scanResultList.add(scanResult);
-        }
-        MacAddress mac1 = MacAddress.fromString("00:01:02:03:04:05");
-
-        // create request
-        RangingRequest.Builder builder = new RangingRequest.Builder();
-        builder.addAccessPoint(scanResult);
-        builder.addAccessPoints(scanResultList);
-        builder.addAccessPoint(scanResult);
-        builder.addWifiAwarePeer(mac1);
-        RangingRequest request = builder.build();
-
-        // verify request
-        request.enforceValidity(true);
-    }
-
-    /**
-     * Validate that Aware requests are invalid on devices which do not support Aware
-     */
-    @Test(expected = IllegalArgumentException.class)
-    public void testRangingRequestWithAwareWithNoAwareSupport() {
-        // create request
-        RangingRequest.Builder builder = new RangingRequest.Builder();
-        builder.addWifiAwarePeer(new PeerHandle(10));
-        RangingRequest request = builder.build();
-
-        // verify request
-        request.enforceValidity(false);
-    }
-
-    /**
-     * Validate that RangingResults parcel works (produces same object on write/read).
-     */
-    @Test
-    public void testRangingResultsParcel() {
-        int status = RangingResult.STATUS_SUCCESS;
-        final MacAddress mac = MacAddress.fromString("00:01:02:03:04:05");
-        PeerHandle peerHandle = new PeerHandle(10);
-        int distanceCm = 105;
-        int distanceStdDevCm = 10;
-        int rssi = 5;
-        int numAttemptedMeasurements = 8;
-        int numSuccessfulMeasurements = 3;
-        long timestamp = System.currentTimeMillis();
-        byte[] lci = { 0x5, 0x6, 0x7 };
-        byte[] lcr = { 0x1, 0x2, 0x3, 0xA, 0xB, 0xC };
-
-        // RangingResults constructed with a MAC address
-        RangingResult result = new RangingResult(status, mac, distanceCm, distanceStdDevCm, rssi,
-                numAttemptedMeasurements, numSuccessfulMeasurements, lci, lcr, null, timestamp);
-
-        Parcel parcelW = Parcel.obtain();
-        result.writeToParcel(parcelW, 0);
-        byte[] bytes = parcelW.marshall();
-        parcelW.recycle();
-
-        Parcel parcelR = Parcel.obtain();
-        parcelR.unmarshall(bytes, 0, bytes.length);
-        parcelR.setDataPosition(0);
-        RangingResult rereadResult = RangingResult.CREATOR.createFromParcel(parcelR);
-
-        assertEquals(result, rereadResult);
-
-        // RangingResults constructed with a PeerHandle
-        result = new RangingResult(status, peerHandle, distanceCm, distanceStdDevCm, rssi,
-                numAttemptedMeasurements, numSuccessfulMeasurements, null, null, null, timestamp);
-
-        parcelW = Parcel.obtain();
-        result.writeToParcel(parcelW, 0);
-        bytes = parcelW.marshall();
-        parcelW.recycle();
-
-        parcelR = Parcel.obtain();
-        parcelR.unmarshall(bytes, 0, bytes.length);
-        parcelR.setDataPosition(0);
-        rereadResult = RangingResult.CREATOR.createFromParcel(parcelR);
-
-        assertEquals(result, rereadResult);
-    }
-
-    /**
-     * Validate that RangingResults tests equal even if LCI/LCR is empty (length == 0) and null.
-     */
-    @Test
-    public void testRangingResultsEqualityLciLcr() {
-        int status = RangingResult.STATUS_SUCCESS;
-        final MacAddress mac = MacAddress.fromString("00:01:02:03:04:05");
-        PeerHandle peerHandle = new PeerHandle(10);
-        int distanceCm = 105;
-        int distanceStdDevCm = 10;
-        int rssi = 5;
-        int numAttemptedMeasurements = 10;
-        int numSuccessfulMeasurements = 3;
-        long timestamp = System.currentTimeMillis();
-        byte[] lci = { };
-        byte[] lcr = { };
-
-        RangingResult rr1 = new RangingResult(status, mac, distanceCm, distanceStdDevCm, rssi,
-                numAttemptedMeasurements, numSuccessfulMeasurements, lci, lcr, null, timestamp);
-        RangingResult rr2 = new RangingResult(status, mac, distanceCm, distanceStdDevCm, rssi,
-                numAttemptedMeasurements, numSuccessfulMeasurements, null, null, null, timestamp);
-
-        assertEquals(rr1, rr2);
-    }
-
-    /**
-     * Validate that ResponderConfig parcel works (produces same object on write/read).
-     */
-    @Test
-    public void testResponderConfigParcel() {
-        // ResponderConfig constructed with a MAC address
-        ResponderConfig config = new ResponderConfig(MacAddress.fromString("00:01:02:03:04:05"),
-                ResponderConfig.RESPONDER_AP, true, ResponderConfig.CHANNEL_WIDTH_80MHZ, 2134, 2345,
-                2555, ResponderConfig.PREAMBLE_LEGACY);
-
-        Parcel parcelW = Parcel.obtain();
-        config.writeToParcel(parcelW, 0);
-        byte[] bytes = parcelW.marshall();
-        parcelW.recycle();
-
-        Parcel parcelR = Parcel.obtain();
-        parcelR.unmarshall(bytes, 0, bytes.length);
-        parcelR.setDataPosition(0);
-        ResponderConfig rereadConfig = ResponderConfig.CREATOR.createFromParcel(parcelR);
-
-        assertEquals(config, rereadConfig);
-
-        // ResponderConfig constructed with a PeerHandle
-        config = new ResponderConfig(new PeerHandle(10), ResponderConfig.RESPONDER_AWARE, false,
-                ResponderConfig.CHANNEL_WIDTH_80MHZ_PLUS_MHZ, 5555, 6666, 7777,
-                ResponderConfig.PREAMBLE_VHT);
-
-        parcelW = Parcel.obtain();
-        config.writeToParcel(parcelW, 0);
-        bytes = parcelW.marshall();
-        parcelW.recycle();
-
-        parcelR = Parcel.obtain();
-        parcelR.unmarshall(bytes, 0, bytes.length);
-        parcelR.setDataPosition(0);
-        rereadConfig = ResponderConfig.CREATOR.createFromParcel(parcelR);
-
-        assertEquals(config, rereadConfig);
-    }
-
-    /**
-     * Validate preamble selection from ScanResults.
-     */
-    @Test
-    public void testResponderPreambleSelection() {
-        ScanResult.InformationElement htCap = new ScanResult.InformationElement();
-        htCap.id = ScanResult.InformationElement.EID_HT_CAPABILITIES;
-
-        ScanResult.InformationElement vhtCap = new ScanResult.InformationElement();
-        vhtCap.id = ScanResult.InformationElement.EID_VHT_CAPABILITIES;
-
-        ScanResult.InformationElement vsa = new ScanResult.InformationElement();
-        vsa.id = ScanResult.InformationElement.EID_VSA;
-
-        // no IE
-        ScanResult scan = new ScanResult();
-        scan.BSSID = "00:01:02:03:04:05";
-        scan.informationElements = null;
-        scan.channelWidth = ResponderConfig.CHANNEL_WIDTH_80MHZ;
-
-        ResponderConfig config = ResponderConfig.fromScanResult(scan);
-
-        assertEquals(ResponderConfig.PREAMBLE_VHT, config.preamble);
-
-        // IE with HT & VHT
-        scan.channelWidth = ResponderConfig.CHANNEL_WIDTH_40MHZ;
-
-        scan.informationElements = new ScanResult.InformationElement[2];
-        scan.informationElements[0] = htCap;
-        scan.informationElements[1] = vhtCap;
-
-        config = ResponderConfig.fromScanResult(scan);
-
-        assertEquals(ResponderConfig.PREAMBLE_VHT, config.preamble);
-
-        // IE with some entries but no HT or VHT
-        scan.informationElements[0] = vsa;
-        scan.informationElements[1] = vsa;
-
-        config = ResponderConfig.fromScanResult(scan);
-
-        assertEquals(ResponderConfig.PREAMBLE_LEGACY, config.preamble);
-
-        // IE with HT
-        scan.informationElements[0] = vsa;
-        scan.informationElements[1] = htCap;
-
-        config = ResponderConfig.fromScanResult(scan);
-
-        assertEquals(ResponderConfig.PREAMBLE_HT, config.preamble);
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/util/HexEncodingTest.java b/wifi/tests/src/android/net/wifi/util/HexEncodingTest.java
deleted file mode 100644
index 0d75138..0000000
--- a/wifi/tests/src/android/net/wifi/util/HexEncodingTest.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.util;
-
-import static android.net.wifi.util.HexEncoding.decode;
-import static android.net.wifi.util.HexEncoding.encode;
-import static android.net.wifi.util.HexEncoding.encodeToString;
-
-import junit.framework.TestCase;
-
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.Locale;
-
-/** Copied from {@link libcore.libcore.util.HexEncodingTest}. */
-public class HexEncodingTest extends TestCase {
-
-    public void testEncodeByte() {
-        Object[][] testCases = new Object[][]{
-                {0x01, "01"},
-                {0x09, "09"},
-                {0x0A, "0A"},
-                {0x0F, "0F"},
-                {0x10, "10"},
-                {0x1F, "1F"},
-                {0x20, "20"},
-                {0x7F, "7F"},
-                {0x80, "80"},
-                {0xFF, "FF"},
-        };
-        for (Object[] testCase : testCases) {
-            Number toEncode = (Number) testCase[0];
-            String expected = (String) testCase[1];
-
-            String actualUpper = encodeToString(toEncode.byteValue(), true /* upperCase */);
-            assertEquals(upper(expected), actualUpper);
-
-            String actualLower = encodeToString(toEncode.byteValue(), false /* upperCase */);
-            assertEquals(lower(expected), actualLower);
-        }
-    }
-
-    public void testEncodeBytes() {
-        Object[][] testCases = new Object[][]{
-                {"avocados".getBytes(StandardCharsets.UTF_8), "61766F6361646F73"},
-        };
-
-        for (Object[] testCase : testCases) {
-            byte[] bytes = (byte[]) testCase[0];
-            String encodedLower = lower((String) testCase[1]);
-            String encodedUpper = upper((String) testCase[1]);
-
-            assertArraysEqual(encodedUpper.toCharArray(), encode(bytes));
-            assertArraysEqual(encodedUpper.toCharArray(), encode(bytes, true /* upperCase */));
-            assertArraysEqual(encodedLower.toCharArray(), encode(bytes, false /* upperCase */));
-
-            assertArraysEqual(bytes, decode(encode(bytes), false /* allowSingleChar */));
-
-            // Make sure we can handle lower case hex encodings as well.
-            assertArraysEqual(bytes,
-                    decode(encodedLower.toCharArray(), false /* allowSingleChar */));
-        }
-    }
-
-    public void testDecode_allow4Bit() {
-        assertArraysEqual(new byte[]{6}, decode("6".toCharArray(), true));
-        assertArraysEqual(new byte[]{6, 0x76}, decode("676".toCharArray(), true));
-    }
-
-    public void testDecode_disallow4Bit() {
-        try {
-            decode("676".toCharArray(), false /* allowSingleChar */);
-            fail();
-        } catch (IllegalArgumentException expected) {
-        }
-    }
-
-    public void testDecode_invalid() {
-        try {
-            decode("DEADBARD".toCharArray(), false /* allowSingleChar */);
-            fail();
-        } catch (IllegalArgumentException expected) {
-        }
-
-        // This demonstrates a difference in behaviour from apache commons : apache
-        // commons uses Character.isDigit and would successfully decode a string with
-        // arabic and devanagari characters.
-        try {
-            decode("६१٧٥٥F6361646F73".toCharArray(), false /* allowSingleChar */);
-            fail();
-        } catch (IllegalArgumentException expected) {
-        }
-
-        try {
-            decode("#%6361646F73".toCharArray(), false /* allowSingleChar */);
-            fail();
-        } catch (IllegalArgumentException expected) {
-        }
-    }
-
-    private static void assertArraysEqual(char[] lhs, char[] rhs) {
-        assertEquals(new String(lhs), new String(rhs));
-    }
-
-    private static void assertArraysEqual(byte[] lhs, byte[] rhs) {
-        assertEquals(Arrays.toString(lhs), Arrays.toString(rhs));
-    }
-
-    private static String lower(String string) {
-        return string.toLowerCase(Locale.ROOT);
-    }
-
-    private static String upper(String string) {
-        return string.toUpperCase(Locale.ROOT);
-    }
-}
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
