Merge "Expose Wifi P2P @hide APIs as @SystemApi"
diff --git a/api/current.txt b/api/current.txt
index 61013e8..8b1df00 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -30526,6 +30526,9 @@
     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 public int groupOwnerIntent;
     field public android.net.wifi.WpsInfo wps;
@@ -30546,6 +30549,7 @@
     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 boolean wpsDisplaySupported();
@@ -30582,6 +30586,7 @@
     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();
@@ -30706,6 +30711,28 @@
     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 isSessionAvailable();
+    method public boolean isWfdEnabled();
+    method public void setControlPort(int);
+    method public boolean setDeviceType(int);
+    method public void setMaxThroughput(int);
+    method public void setSessionAvailable(boolean);
+    method public void setWfdEnabled(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 {
diff --git a/api/system-current.txt b/api/system-current.txt
index d91ecd4..fd6afea 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -57,6 +57,7 @@
     field public static final String CHANGE_DEVICE_IDLE_TEMP_WHITELIST = "android.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST";
     field public static final String CLEAR_APP_USER_DATA = "android.permission.CLEAR_APP_USER_DATA";
     field public static final String CONFIGURE_DISPLAY_BRIGHTNESS = "android.permission.CONFIGURE_DISPLAY_BRIGHTNESS";
+    field public static final String CONFIGURE_WIFI_DISPLAY = "android.permission.CONFIGURE_WIFI_DISPLAY";
     field public static final String CONNECTIVITY_INTERNAL = "android.permission.CONNECTIVITY_INTERNAL";
     field public static final String CONNECTIVITY_USE_RESTRICTED_NETWORKS = "android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS";
     field public static final String CONTROL_DISPLAY_COLOR_TRANSFORMS = "android.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS";
@@ -125,8 +126,10 @@
     field public static final String NETWORK_CARRIER_PROVISIONING = "android.permission.NETWORK_CARRIER_PROVISIONING";
     field public static final String NETWORK_MANAGED_PROVISIONING = "android.permission.NETWORK_MANAGED_PROVISIONING";
     field public static final String NETWORK_SCAN = "android.permission.NETWORK_SCAN";
+    field public static final String NETWORK_SETTINGS = "android.permission.NETWORK_SETTINGS";
     field public static final String NETWORK_SETUP_WIZARD = "android.permission.NETWORK_SETUP_WIZARD";
     field public static final String NETWORK_SIGNAL_STRENGTH_WAKEUP = "android.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP";
+    field public static final String NETWORK_STACK = "android.permission.NETWORK_STACK";
     field public static final String NOTIFICATION_DURING_SETUP = "android.permission.NOTIFICATION_DURING_SETUP";
     field public static final String NOTIFY_TV_INPUTS = "android.permission.NOTIFY_TV_INPUTS";
     field public static final String OBSERVE_APP_USAGE = "android.permission.OBSERVE_APP_USAGE";
@@ -4123,8 +4126,8 @@
     method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void getLatestTetheringEntitlementResult(int, boolean, @NonNull java.util.concurrent.Executor, @NonNull android.net.ConnectivityManager.OnTetheringEntitlementResultListener);
     method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public boolean isTetheringSupported();
     method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void registerTetheringEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.ConnectivityManager.OnTetheringEventCallback);
-    method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD, "android.permission.NETWORK_STACK"}) public void setAirplaneMode(boolean);
-    method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, "android.permission.NETWORK_STACK"}) public boolean shouldAvoidBadWifi();
+    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void setAirplaneMode(boolean);
+    method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public boolean shouldAvoidBadWifi();
     method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public void startCaptivePortalApp(@NonNull android.net.Network, @NonNull android.os.Bundle);
     method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void startTethering(int, boolean, android.net.ConnectivityManager.OnStartTetheringCallback);
     method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void startTethering(int, boolean, android.net.ConnectivityManager.OnStartTetheringCallback, android.os.Handler);
@@ -4832,14 +4835,14 @@
 
   public class WifiManager {
     method @RequiresPermission("android.permission.WIFI_UPDATE_USABILITY_STATS_SCORE") public void addOnWifiUsabilityStatsListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.OnWifiUsabilityStatsListener);
-    method @RequiresPermission("android.permission.NETWORK_SETTINGS") public void allowAutojoin(int, boolean);
-    method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD, "android.permission.NETWORK_STACK"}) public void connect(@NonNull android.net.wifi.WifiConfiguration, @Nullable android.net.wifi.WifiManager.ActionListener);
-    method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD, "android.permission.NETWORK_STACK"}) public void connect(int, @Nullable android.net.wifi.WifiManager.ActionListener);
-    method @Deprecated @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD, "android.permission.NETWORK_STACK"}) public void disable(int, @Nullable android.net.wifi.WifiManager.ActionListener);
-    method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD, "android.permission.NETWORK_STACK"}) public void forget(int, @Nullable android.net.wifi.WifiManager.ActionListener);
-    method @NonNull @RequiresPermission(anyOf={"android.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 @NonNull @RequiresPermission(anyOf={"android.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.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 @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void allowAutojoin(int, boolean);
+    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_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 @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 @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 @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public android.net.wifi.WifiConfiguration getWifiApConfiguration();
     method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public int getWifiApState();
@@ -4849,20 +4852,20 @@
     method public boolean isPortableHotspotSupported();
     method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public boolean isWifiApEnabled();
     method public boolean isWifiScannerSupported();
-    method @RequiresPermission("android.permission.NETWORK_SETTINGS") public void registerSoftApCallback(@Nullable java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.SoftApCallback);
+    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void registerSoftApCallback(@Nullable java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.SoftApCallback);
     method @RequiresPermission("android.permission.WIFI_UPDATE_USABILITY_STATS_SCORE") public void removeOnWifiUsabilityStatsListener(@NonNull android.net.wifi.WifiManager.OnWifiUsabilityStatsListener);
-    method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD, "android.permission.NETWORK_STACK"}) public void save(@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 save(@NonNull android.net.wifi.WifiConfiguration, @Nullable android.net.wifi.WifiManager.ActionListener);
     method @RequiresPermission("android.permission.WIFI_SET_DEVICE_MOBILITY_STATE") public void setDeviceMobilityState(int);
     method @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE) public boolean setWifiApConfiguration(android.net.wifi.WifiConfiguration);
-    method @RequiresPermission(anyOf={"android.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.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.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(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.permission.NETWORK_STACK", android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public boolean startSoftAp(@Nullable android.net.wifi.WifiConfiguration);
-    method @RequiresPermission(anyOf={"android.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.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void stopEasyConnectSession();
-    method @RequiresPermission(anyOf={"android.permission.NETWORK_STACK", android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public boolean stopSoftAp();
-    method @RequiresPermission(anyOf={"android.permission.NETWORK_STACK", android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void updateInterfaceIpState(@Nullable String, int);
+    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public boolean startSoftAp(@Nullable android.net.wifi.WifiConfiguration);
+    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_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(anyOf={android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void updateInterfaceIpState(@Nullable String, int);
     method @RequiresPermission("android.permission.WIFI_UPDATE_USABILITY_STATS_SCORE") public void updateWifiUsabilityScore(int, int, int);
     field public static final int CHANGE_REASON_ADDED = 0; // 0x0
     field public static final int CHANGE_REASON_CONFIG_CHANGE = 2; // 0x2
@@ -5154,6 +5157,36 @@
 
 }
 
+package android.net.wifi.p2p {
+
+  public final class WifiP2pGroupList implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public java.util.Collection<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(android.Manifest.permission.NETWORK_SETTINGS) public void listen(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, boolean, @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(allOf={android.Manifest.permission.CONNECTIVITY_INTERNAL, 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);
+    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 {
diff --git a/api/system-lint-baseline.txt b/api/system-lint-baseline.txt
index 21526d0..6c659c8 100644
--- a/api/system-lint-baseline.txt
+++ b/api/system-lint-baseline.txt
@@ -7,6 +7,22 @@
     
 
 
+ExecutorRegistration: android.net.wifi.p2p.WifiP2pManager#deletePersistentGroup(android.net.wifi.p2p.WifiP2pManager.Channel, int, android.net.wifi.p2p.WifiP2pManager.ActionListener):
+    Registration methods should have overload that accepts delivery Executor: `deletePersistentGroup`
+ExecutorRegistration: android.net.wifi.p2p.WifiP2pManager#factoryReset(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener):
+    Registration methods should have overload that accepts delivery Executor: `factoryReset`
+ExecutorRegistration: android.net.wifi.p2p.WifiP2pManager#listen(android.net.wifi.p2p.WifiP2pManager.Channel, boolean, android.net.wifi.p2p.WifiP2pManager.ActionListener):
+    Registration methods should have overload that accepts delivery Executor: `listen`
+ExecutorRegistration: android.net.wifi.p2p.WifiP2pManager#requestPersistentGroupInfo(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.PersistentGroupInfoListener):
+    Registration methods should have overload that accepts delivery Executor: `requestPersistentGroupInfo`
+ExecutorRegistration: android.net.wifi.p2p.WifiP2pManager#setDeviceName(android.net.wifi.p2p.WifiP2pManager.Channel, String, android.net.wifi.p2p.WifiP2pManager.ActionListener):
+    Registration methods should have overload that accepts delivery Executor: `setDeviceName`
+ExecutorRegistration: android.net.wifi.p2p.WifiP2pManager#setWfdInfo(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pWfdInfo, android.net.wifi.p2p.WifiP2pManager.ActionListener):
+    Registration methods should have overload that accepts delivery Executor: `setWfdInfo`
+ExecutorRegistration: android.net.wifi.p2p.WifiP2pManager#setWifiP2pChannels(android.net.wifi.p2p.WifiP2pManager.Channel, int, int, android.net.wifi.p2p.WifiP2pManager.ActionListener):
+    Registration methods should have overload that accepts delivery Executor: `setWifiP2pChannels`
+
+
 GenericException: android.app.prediction.AppPredictor#finalize():
     
 GenericException: android.hardware.location.ContextHubClient#finalize():
@@ -17,8 +33,7 @@
     
 
 
-InterfaceConstant: android.service.storage.ExternalStorageService#SERVICE_INTERFACE:
-    
+
 
 
 KotlinKeyword: android.app.Notification#when:
@@ -198,9 +213,9 @@
 SamShouldBeLast: android.app.AlarmManager#setWindow(int, long, long, String, android.app.AlarmManager.OnAlarmListener, android.os.Handler):
     
 SamShouldBeLast: android.app.WallpaperInfo#dump(android.util.Printer, String):
-    
+
 SamShouldBeLast: android.app.admin.DevicePolicyManager#installSystemUpdate(android.content.ComponentName, android.net.Uri, java.util.concurrent.Executor, android.app.admin.DevicePolicyManager.InstallSystemUpdateCallback):
-    
+
 SamShouldBeLast: android.content.Context#bindIsolatedService(android.content.Intent, int, String, java.util.concurrent.Executor, android.content.ServiceConnection):
     
 SamShouldBeLast: android.content.Context#bindService(android.content.Intent, int, java.util.concurrent.Executor, android.content.ServiceConnection):
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 545538b..e6cea79 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -375,7 +375,7 @@
     <protected-broadcast android:name="android.net.wifi.p2p.THIS_DEVICE_CHANGED" />
     <protected-broadcast android:name="android.net.wifi.p2p.PEERS_CHANGED" />
     <protected-broadcast android:name="android.net.wifi.p2p.CONNECTION_STATE_CHANGE" />
-    <protected-broadcast android:name="android.net.wifi.p2p.PERSISTENT_GROUPS_CHANGED" />
+    <protected-broadcast android:name="android.net.wifi.p2p.action.WIFI_P2P_PERSISTENT_GROUPS_CHANGED" />
     <protected-broadcast android:name="android.net.conn.TETHER_STATE_CHANGED" />
     <protected-broadcast android:name="android.net.conn.INET_CONDITION_ACTION" />
     <protected-broadcast android:name="android.net.conn.NETWORK_CONDITIONS_MEASURED" />
@@ -1615,6 +1615,7 @@
 
     <!-- Allows network stack services (Connectivity and Wifi) to coordinate
          <p>Not for use by third-party or privileged applications.
+         @SystemApi
          @hide This should only be used by Connectivity and Wifi Services.
     -->
     <permission android:name="android.permission.NETWORK_STACK"
@@ -1622,6 +1623,7 @@
 
     <!-- Allows Settings and SystemUI to call methods in Networking services
          <p>Not for use by third-party or privileged applications.
+         @SystemApi
          @hide This should only be used by Settings and SystemUI.
     -->
     <permission android:name="android.permission.NETWORK_SETTINGS"
@@ -3583,7 +3585,8 @@
         android:protectionLevel="signature" />
 
     <!-- Allows an application to configure and connect to Wifi displays
-         @hide -->
+         @hide
+         @SystemApi -->
     <permission android:name="android.permission.CONFIGURE_WIFI_DISPLAY"
         android:protectionLevel="signature" />
 
diff --git a/services/core/java/com/android/server/display/WifiDisplayController.java b/services/core/java/com/android/server/display/WifiDisplayController.java
index d9d46b8..283a78b 100644
--- a/services/core/java/com/android/server/display/WifiDisplayController.java
+++ b/services/core/java/com/android/server/display/WifiDisplayController.java
@@ -16,8 +16,6 @@
 
 package com.android.server.display;
 
-import com.android.internal.util.DumpUtils;
-
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -36,16 +34,18 @@
 import android.net.wifi.p2p.WifiP2pDeviceList;
 import android.net.wifi.p2p.WifiP2pGroup;
 import android.net.wifi.p2p.WifiP2pManager;
-import android.net.wifi.p2p.WifiP2pWfdInfo;
 import android.net.wifi.p2p.WifiP2pManager.ActionListener;
 import android.net.wifi.p2p.WifiP2pManager.Channel;
 import android.net.wifi.p2p.WifiP2pManager.GroupInfoListener;
 import android.net.wifi.p2p.WifiP2pManager.PeerListListener;
+import android.net.wifi.p2p.WifiP2pWfdInfo;
 import android.os.Handler;
 import android.provider.Settings;
 import android.util.Slog;
 import android.view.Surface;
 
+import com.android.internal.util.DumpUtils;
+
 import java.io.PrintWriter;
 import java.net.Inet4Address;
 import java.net.InetAddress;
@@ -292,11 +292,11 @@
 
                 WifiP2pWfdInfo wfdInfo = new WifiP2pWfdInfo();
                 wfdInfo.setWfdEnabled(true);
-                wfdInfo.setDeviceType(WifiP2pWfdInfo.WFD_SOURCE);
+                wfdInfo.setDeviceType(WifiP2pWfdInfo.DEVICE_TYPE_WFD_SOURCE);
                 wfdInfo.setSessionAvailable(true);
                 wfdInfo.setControlPort(DEFAULT_CONTROL_PORT);
                 wfdInfo.setMaxThroughput(MAX_THROUGHPUT);
-                mWifiP2pManager.setWFDInfo(mWifiP2pChannel, wfdInfo, new ActionListener() {
+                mWifiP2pManager.setWfdInfo(mWifiP2pChannel, wfdInfo, new ActionListener() {
                     @Override
                     public void onSuccess() {
                         if (DEBUG) {
@@ -324,7 +324,7 @@
             if (mWfdEnabled || mWfdEnabling) {
                 WifiP2pWfdInfo wfdInfo = new WifiP2pWfdInfo();
                 wfdInfo.setWfdEnabled(false);
-                mWifiP2pManager.setWFDInfo(mWifiP2pChannel, wfdInfo, new ActionListener() {
+                mWifiP2pManager.setWfdInfo(mWifiP2pChannel, wfdInfo, new ActionListener() {
                     @Override
                     public void onSuccess() {
                         if (DEBUG) {
@@ -508,7 +508,8 @@
                 Slog.d(TAG, "updateDesiredDevice: new information "
                         + describeWifiP2pDevice(device));
             }
-            mDesiredDevice.update(device);
+            mDesiredDevice.updateSupplicantDetails(device);
+            mDesiredDevice.status = device.status;
             if (mAdvertisedDisplay != null
                     && mAdvertisedDisplay.getDeviceAddress().equals(address)) {
                 readvertiseDisplay(createWifiDisplay(mDesiredDevice));
@@ -694,7 +695,7 @@
             config.wps = wps;
             config.deviceAddress = mConnectingDevice.deviceAddress;
             // Helps with STA & P2P concurrency
-            config.groupOwnerIntent = WifiP2pConfig.MIN_GROUP_OWNER_INTENT;
+            config.groupOwnerIntent = WifiP2pConfig.GROUP_OWNER_INTENT_MIN;
 
             WifiDisplay display = createWifiDisplay(mConnectingDevice);
             advertiseDisplay(display, null, 0, 0, 0);
@@ -824,6 +825,10 @@
         requestPeers();
     }
 
+    private static boolean contains(WifiP2pGroup group, WifiP2pDevice device) {
+        return group.getOwner().equals(device) || group.getClientList().contains(device);
+    }
+
     private void handleConnectionChanged(NetworkInfo networkInfo) {
         mNetworkInfo = networkInfo;
         if (mWfdEnabled && networkInfo.isConnected()) {
@@ -835,7 +840,7 @@
                             Slog.d(TAG, "Received group info: " + describeWifiP2pGroup(info));
                         }
 
-                        if (mConnectingDevice != null && !info.contains(mConnectingDevice)) {
+                        if (mConnectingDevice != null && !contains(info, mConnectingDevice)) {
                             Slog.i(TAG, "Aborting connection to Wifi display because "
                                     + "the current P2P group does not contain the device "
                                     + "we expected to find: " + mConnectingDevice.deviceName
@@ -844,7 +849,7 @@
                             return;
                         }
 
-                        if (mDesiredDevice != null && !info.contains(mDesiredDevice)) {
+                        if (mDesiredDevice != null && !contains(info, mDesiredDevice)) {
                             disconnect();
                             return;
                         }
@@ -1038,14 +1043,15 @@
     }
 
     private static boolean isWifiDisplay(WifiP2pDevice device) {
-        return device.wfdInfo != null
-                && device.wfdInfo.isWfdEnabled()
-                && isPrimarySinkDeviceType(device.wfdInfo.getDeviceType());
+        WifiP2pWfdInfo wfdInfo = device.getWfdInfo();
+        return wfdInfo != null
+                && wfdInfo.isWfdEnabled()
+                && isPrimarySinkDeviceType(wfdInfo.getDeviceType());
     }
 
     private static boolean isPrimarySinkDeviceType(int deviceType) {
-        return deviceType == WifiP2pWfdInfo.PRIMARY_SINK
-                || deviceType == WifiP2pWfdInfo.SOURCE_OR_PRIMARY_SINK;
+        return deviceType == WifiP2pWfdInfo.DEVICE_TYPE_PRIMARY_SINK
+                || deviceType == WifiP2pWfdInfo.DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK;
     }
 
     private static String describeWifiP2pDevice(WifiP2pDevice device) {
@@ -1058,7 +1064,7 @@
 
     private static WifiDisplay createWifiDisplay(WifiP2pDevice device) {
         return new WifiDisplay(device.deviceAddress, device.deviceName, null,
-                true, device.wfdInfo.isSessionAvailable(), false);
+                true, device.getWfdInfo().isSessionAvailable(), false);
     }
 
     private final BroadcastReceiver mWifiP2pReceiver = new BroadcastReceiver() {
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java
index c3cfb02..767055f 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java
@@ -66,12 +66,6 @@
     public int groupOwnerBand = GROUP_OWNER_BAND_AUTO;
 
     /** @hide */
-    public static final int MAX_GROUP_OWNER_INTENT   =   15;
-    /** @hide */
-    @UnsupportedAppUsage
-    public static final int MIN_GROUP_OWNER_INTENT   =   0;
-
-    /** @hide */
     @IntDef(flag = false, prefix = { "GROUP_OWNER_BAND_" }, value = {
         GROUP_OWNER_BAND_AUTO,
         GROUP_OWNER_BAND_2GHZ,
@@ -94,13 +88,35 @@
     public static final int GROUP_OWNER_BAND_5GHZ = 2;
 
     /**
-     * This is an integer value between 0 and 15 where 0 indicates the least
-     * inclination to be a group owner and 15 indicates the highest inclination
-     * to be a group owner.
-     *
-     * A value of -1 indicates the system can choose an appropriate value.
+     * The least inclination to be a group owner, to be filled in the field
+     * {@link #groupOwnerIntent}.
      */
-    public int groupOwnerIntent = -1;
+    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}.
+     */
+    public int groupOwnerIntent = GROUP_OWNER_INTENT_AUTO;
 
     /** @hide */
     @UnsupportedAppUsage
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java b/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java
index c5318a9..13b2520 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java
@@ -16,6 +16,8 @@
 
 package android.net.wifi.p2p;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.UnsupportedAppUsage;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -237,6 +239,12 @@
         }
     }
 
+    /** 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;
@@ -278,14 +286,15 @@
     }
 
     /**
-     * Update device details. This will be throw an exception if the device address
-     * does not match.
+     * Update device details. This will throw an exception if the device address does not match.
+     *
      * @param device to be updated
-     * @throws IllegalArgumentException if the device is null or device address does not match
+     * @throws IllegalArgumentException if the device is null or the device address does not match
+     *
      * @hide
      */
     @UnsupportedAppUsage
-    public void update(WifiP2pDevice device) {
+    public void update(@NonNull WifiP2pDevice device) {
         updateSupplicantDetails(device);
         status = device.status;
     }
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java b/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java
index 4866bd4..f9d1266 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java
@@ -16,6 +16,7 @@
 
 package android.net.wifi.p2p;
 
+import android.annotation.Nullable;
 import android.annotation.UnsupportedAppUsage;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -36,15 +37,21 @@
  */
 public class WifiP2pGroup implements Parcelable {
 
-    /** The temporary network id.
-     * {@hide} */
+    /**
+     * The temporary network id.
+     *
+     * @hide
+     */
     @UnsupportedAppUsage
     public static final int TEMPORARY_NET_ID = -1;
 
-    /** The persistent network id.
+    /**
+     * The persistent network id.
      * If a matching persistent profile is found, use it.
      * Otherwise, create a new persistent profile.
-     * {@hide} */
+     *
+     * @hide
+     */
     public static final int PERSISTENT_NET_ID = -2;
 
     /** The network name */
@@ -64,7 +71,7 @@
 
     private String mInterface;
 
-    /** The network id in the wpa_supplicant */
+    /** The network ID in wpa_supplicant */
     private int mNetId;
 
     /** The frequency (in MHz) used by this group */
@@ -225,10 +232,13 @@
         return mClients.size() == 0;
     }
 
-    /** @hide Returns {@code true} if the device is part of the group */
-    public boolean contains(WifiP2pDevice device) {
-        if (mOwner.equals(device) || mClients.contains(device)) return true;
-        return false;
+    /**
+     * 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 */
@@ -261,8 +271,7 @@
         return mInterface;
     }
 
-    /** @hide */
-    @UnsupportedAppUsage
+    /** The network ID of the P2P group in wpa_supplicant. */
     public int getNetworkId() {
         return mNetId;
     }
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.java b/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.java
index 62524d9..10fd09a 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.java
@@ -15,14 +15,16 @@
  */
 package android.net.wifi.p2p;
 
-import java.util.Collection;
-import java.util.Map;
-
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
 import android.annotation.UnsupportedAppUsage;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.LruCache;
 
+import java.util.Collection;
+import java.util.Map;
+
 
 /**
  * A class representing a Wi-Fi P2p group list
@@ -30,7 +32,8 @@
  * {@see WifiP2pManager}
  * @hide
  */
-public class WifiP2pGroupList implements Parcelable {
+@SystemApi
+public final class WifiP2pGroupList implements Parcelable {
 
     private static final int CREDENTIAL_MAX_NUM             =   32;
 
@@ -40,6 +43,7 @@
 
     private boolean isClearCalled = false;
 
+    /** @hide */
     public interface GroupDeleteListener {
         public void onDeleteGroup(int netId);
     }
@@ -71,11 +75,9 @@
     }
 
     /**
-     * Return the list of p2p group.
-     *
-     * @return the list of p2p group.
+     * Get the list of P2P groups.
      */
-    @UnsupportedAppUsage
+    @NonNull
     public Collection<WifiP2pGroup> getGroupList() {
         return mGroups.snapshot().values();
     }
@@ -206,6 +208,7 @@
         return false;
     }
 
+    @Override
     public String toString() {
         StringBuffer sbuf = new StringBuffer();
 
@@ -217,12 +220,14 @@
     }
 
     /** Implement the Parcelable interface */
+    @Override
     public int describeContents() {
         return 0;
     }
 
     /** Implement the Parcelable interface */
-    public void writeToParcel(Parcel dest, int flags) {
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
         final Collection<WifiP2pGroup> groups = mGroups.snapshot().values();
         dest.writeInt(groups.size());
         for(WifiP2pGroup group : groups) {
@@ -231,7 +236,7 @@
     }
 
     /** Implement the Parcelable interface */
-    public static final @android.annotation.NonNull Creator<WifiP2pGroupList> CREATOR =
+    public static final @NonNull Creator<WifiP2pGroupList> CREATOR =
         new Creator<WifiP2pGroupList>() {
             public WifiP2pGroupList createFromParcel(Parcel in) {
                 WifiP2pGroupList grpList = new WifiP2pGroupList();
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
index 3178519..1c20679 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
@@ -22,6 +22,7 @@
 import android.annotation.RequiresPermission;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
+import android.annotation.SystemApi;
 import android.annotation.SystemService;
 import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
@@ -327,8 +328,9 @@
      * Broadcast intent action indicating that remembered persistent groups have changed.
      * @hide
      */
-    public static final String WIFI_P2P_PERSISTENT_GROUPS_CHANGED_ACTION =
-        "android.net.wifi.p2p.PERSISTENT_GROUPS_CHANGED";
+    @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.
@@ -756,13 +758,18 @@
     }
 
 
-    /** Interface for callback invocation when stored group info list is available {@hide}*/
+    /**
+     * 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
          */
-        public void onPersistentGroupInfoAvailable(WifiP2pGroupList groups);
+        void onPersistentGroupInfoAvailable(@NonNull WifiP2pGroupList groups);
     }
 
     /**
@@ -1202,7 +1209,7 @@
         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
@@ -1347,20 +1354,36 @@
      *
      * @hide
      */
+    @SystemApi
     @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public void listen(Channel c, boolean enable, ActionListener listener) {
+    public void listen(@NonNull Channel c, boolean enable, @Nullable ActionListener listener) {
         checkChannel(c);
         c.mAsyncChannel.sendMessage(enable ? START_LISTEN : STOP_LISTEN,
                 0, c.putListener(listener));
     }
 
-    /** @hide */
-    @UnsupportedAppUsage
-    public void setWifiP2pChannels(Channel c, int lc, int oc, ActionListener 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", lc);
-        p2pChannels.putInt("oc", oc);
+        p2pChannels.putInt("lc", listeningChannel);
+        p2pChannels.putInt("oc", operatingChannel);
         c.mAsyncChannel.sendMessage(SET_CHANNEL, 0, c.putListener(listener), p2pChannels);
     }
 
@@ -1618,23 +1641,47 @@
 
     /**
      * Set p2p device name.
-     * @hide
+     *
      * @param c is the channel created at {@link #initialize}
      * @param listener for callback when group info is available. Can be null.
+     *
+     * @hide
      */
-    @UnsupportedAppUsage
-    public void setDeviceName(Channel c, String devName, ActionListener listener) {
+    @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
-    public void setWFDInfo(
-            Channel c, WifiP2pWfdInfo wfdInfo,
-            ActionListener listener) {
+    @RequiresPermission(android.Manifest.permission.CONFIGURE_WIFI_DISPLAY)
+    public void setWFDInfo(@NonNull Channel c, @NonNull WifiP2pWfdInfo wfdInfo,
+            @Nullable ActionListener listener) {
         checkChannel(c);
         try {
             mService.checkConfigureWifiDisplayPermission();
@@ -1658,12 +1705,19 @@
      *  a network id can be obtained by {@link WifiP2pGroup#getNetworkId()}.
      *
      * @param c is the channel created at {@link #initialize}
-     * @param netId he network id of the p2p group.
+     * @param netId the network id of the p2p group.
      * @param listener for callbacks on success or failure. Can be null.
+     *
      * @hide
      */
-    @UnsupportedAppUsage
-    public void deletePersistentGroup(Channel c, int netId, ActionListener listener) {
+    @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));
     }
@@ -1673,23 +1727,68 @@
      *
      * @param c is the channel created at {@link #initialize}
      * @param listener for callback when persistent group info list is available. Can be null.
+     *
      * @hide
      */
-    @UnsupportedAppUsage
-    public void requestPersistentGroupInfo(Channel c, PersistentGroupInfoListener listener) {
+    @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;
-    /** @hide */
+    /**
+     * Device acts as a Miracast source.
+     * @hide
+     */
+    @SystemApi
     public static final int MIRACAST_SOURCE   = 1;
-    /** @hide */
+    /**
+     * Device acts as a Miracast sink.
+     * @hide
+     */
+    @SystemApi
     public static final int MIRACAST_SINK     = 2;
-    /** Internal use only @hide */
-    @UnsupportedAppUsage
-    public void setMiracastMode(int mode) {
+
+    /**
+     * 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(allOf = {
+            android.Manifest.permission.CONNECTIVITY_INTERNAL,
+            android.Manifest.permission.CONFIGURE_WIFI_DISPLAY})
+    public void setMiracastMode(@MiracastMode int mode) {
         try {
             mService.setMiracastMode(mode);
         } catch (RemoteException e) {
@@ -1778,8 +1877,10 @@
      *
      * @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);
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java b/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java
index 3caa280..48b0703 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java
@@ -16,49 +16,68 @@
 
 package android.net.wifi.p2p;
 
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.UnsupportedAppUsage;
-import android.os.Build;
-import android.os.Parcelable;
 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
- * @hide
+ * A class representing Wifi Display information for a device.
+ *
+ * See Wifi Display technical specification v1.0.0, section 5.1.2.
  */
-public class WifiP2pWfdInfo implements Parcelable {
-
-    private static final String TAG = "WifiP2pWfdInfo";
+public final class WifiP2pWfdInfo implements Parcelable {
 
     private boolean mWfdEnabled;
 
+    /** Device information bitmap */
     private int mDeviceInfo;
 
-    public static final int WFD_SOURCE              = 0;
-    public static final int PRIMARY_SINK            = 1;
-    public static final int SECONDARY_SINK          = 2;
-    public static final int SOURCE_OR_PRIMARY_SINK  = 3;
+    /** @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 {}
 
-    /* Device information bitmap */
-    /** One of {@link #WFD_SOURCE}, {@link #PRIMARY_SINK}, {@link #SECONDARY_SINK}
-     * or {@link #SOURCE_OR_PRIMARY_SINK}
+    /** 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}.
      */
-    private static final int DEVICE_TYPE                            = 0x3;
-    private static final int COUPLED_SINK_SUPPORT_AT_SOURCE         = 0x4;
-    private static final int COUPLED_SINK_SUPPORT_AT_SINK           = 0x8;
-    private static final int SESSION_AVAILABLE                      = 0x30;
-    private static final int SESSION_AVAILABLE_BIT1                 = 0x10;
-    private static final int SESSION_AVAILABLE_BIT2                 = 0x20;
+    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;
 
     private int mCtrlPort;
 
     private int mMaxThroughput;
 
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
-    public WifiP2pWfdInfo() {
-    }
+    /** Default constructor. */
+    public WifiP2pWfdInfo() {}
 
+    /** @hide */
     @UnsupportedAppUsage
     public WifiP2pWfdInfo(int devInfo, int ctrlPort, int maxTput) {
         mWfdEnabled = true;
@@ -67,24 +86,40 @@
         mMaxThroughput = maxTput;
     }
 
-    @UnsupportedAppUsage
+    /** Returns true is Wifi Display is enabled, false otherwise. */
     public boolean isWfdEnabled() {
         return mWfdEnabled;
     }
 
-    @UnsupportedAppUsage
+    /**
+     * Sets whether Wifi Display should be enabled.
+     *
+     * @param enabled true to enable Wifi Display, false to disable
+     */
     public void setWfdEnabled(boolean enabled) {
         mWfdEnabled = enabled;
     }
 
-    @UnsupportedAppUsage
+    /**
+     * 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);
+        return mDeviceInfo & DEVICE_TYPE;
     }
 
-    @UnsupportedAppUsage
-    public boolean setDeviceType(int deviceType) {
-        if (deviceType >= WFD_SOURCE && deviceType <= SOURCE_OR_PRIMARY_SINK) {
+    /**
+     * 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;
@@ -92,35 +127,16 @@
         return false;
     }
 
-    public boolean isCoupledSinkSupportedAtSource() {
-        return (mDeviceInfo & COUPLED_SINK_SUPPORT_AT_SINK) != 0;
-    }
-
-    public void setCoupledSinkSupportAtSource(boolean enabled) {
-        if (enabled ) {
-            mDeviceInfo |= COUPLED_SINK_SUPPORT_AT_SINK;
-        } else {
-            mDeviceInfo &= ~COUPLED_SINK_SUPPORT_AT_SINK;
-        }
-    }
-
-    public boolean isCoupledSinkSupportedAtSink() {
-        return (mDeviceInfo & COUPLED_SINK_SUPPORT_AT_SINK) != 0;
-    }
-
-    public void setCoupledSinkSupportAtSink(boolean enabled) {
-        if (enabled ) {
-            mDeviceInfo |= COUPLED_SINK_SUPPORT_AT_SINK;
-        } else {
-            mDeviceInfo &= ~COUPLED_SINK_SUPPORT_AT_SINK;
-        }
-    }
-
+    /** Returns true if a session is available, false otherwise. */
     public boolean isSessionAvailable() {
         return (mDeviceInfo & SESSION_AVAILABLE) != 0;
     }
 
-    @UnsupportedAppUsage
+    /**
+     * 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;
@@ -130,29 +146,33 @@
         }
     }
 
+    /** Returns the TCP port at which the WFD Device listens for RTSP messages. */
     public int getControlPort() {
         return mCtrlPort;
     }
 
-    @UnsupportedAppUsage
+    /** Sets the TCP port at which the WFD Device listens for RTSP messages. */
     public void setControlPort(int port) {
         mCtrlPort = port;
     }
 
-    @UnsupportedAppUsage
+    /** Sets the maximum average throughput capability of the WFD Device, in megabits/second. */
     public void setMaxThroughput(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(mWfdEnabled);
@@ -167,9 +187,8 @@
         return 0;
     }
 
-    /** copy constructor */
-    @UnsupportedAppUsage
-    public WifiP2pWfdInfo(WifiP2pWfdInfo source) {
+    /** Copy constructor. */
+    public WifiP2pWfdInfo(@Nullable WifiP2pWfdInfo source) {
         if (source != null) {
             mWfdEnabled = source.mWfdEnabled;
             mDeviceInfo = source.mDeviceInfo;
@@ -179,14 +198,15 @@
     }
 
     /** Implement the Parcelable interface */
-    public void writeToParcel(Parcel dest, int flags) {
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
         dest.writeInt(mWfdEnabled ? 1 : 0);
         dest.writeInt(mDeviceInfo);
         dest.writeInt(mCtrlPort);
         dest.writeInt(mMaxThroughput);
     }
 
-    public void readFromParcel(Parcel in) {
+    private void readFromParcel(Parcel in) {
         mWfdEnabled = (in.readInt() == 1);
         mDeviceInfo = in.readInt();
         mCtrlPort = in.readInt();
@@ -194,8 +214,7 @@
     }
 
     /** Implement the Parcelable interface */
-    @UnsupportedAppUsage
-    public static final @android.annotation.NonNull Creator<WifiP2pWfdInfo> CREATOR =
+    public static final @NonNull Creator<WifiP2pWfdInfo> CREATOR =
         new Creator<WifiP2pWfdInfo>() {
             public WifiP2pWfdInfo createFromParcel(Parcel in) {
                 WifiP2pWfdInfo device = new WifiP2pWfdInfo();
diff --git a/wifi/tests/src/android/net/wifi/p2p/WifiP2pWfdInfoTest.java b/wifi/tests/src/android/net/wifi/p2p/WifiP2pWfdInfoTest.java
index d2f1168..cea73ef 100644
--- a/wifi/tests/src/android/net/wifi/p2p/WifiP2pWfdInfoTest.java
+++ b/wifi/tests/src/android/net/wifi/p2p/WifiP2pWfdInfoTest.java
@@ -43,7 +43,7 @@
     @Before
     public void setUp() {
         // initialize device info flags.
-        mSourceInfo.setDeviceType(WifiP2pWfdInfo.WFD_SOURCE);
+        mSourceInfo.setDeviceType(WifiP2pWfdInfo.DEVICE_TYPE_WFD_SOURCE);
         mSourceInfo.setSessionAvailable(true);
     }
 
@@ -57,14 +57,8 @@
         info.setWfdEnabled(true);
         assertTrue(info.isWfdEnabled());
 
-        info.setDeviceType(WifiP2pWfdInfo.WFD_SOURCE);
-        assertEquals(WifiP2pWfdInfo.WFD_SOURCE, info.getDeviceType());
-
-        info.setCoupledSinkSupportAtSource(true);
-        assertTrue(info.isCoupledSinkSupportedAtSource());
-
-        info.setCoupledSinkSupportAtSink(true);
-        assertTrue(info.isCoupledSinkSupportedAtSink());
+        info.setDeviceType(WifiP2pWfdInfo.DEVICE_TYPE_WFD_SOURCE);
+        assertEquals(WifiP2pWfdInfo.DEVICE_TYPE_WFD_SOURCE, info.getDeviceType());
 
         info.setSessionAvailable(true);
         assertTrue(info.isSessionAvailable());
@@ -75,7 +69,7 @@
         info.setMaxThroughput(TEST_MAX_TPUT);
         assertEquals(TEST_MAX_TPUT, info.getMaxThroughput());
 
-        assertEquals("0018270f0400", info.getDeviceInfoHex());
+        assertEquals("0010270f0400", info.getDeviceInfoHex());
     }
 
     /**