From 975173096197db89632b550e1a4d765bfd3e5bfc Mon Sep 17 00:00:00 2001 From: David Su Date: Tue, 5 Nov 2019 13:50:44 -0800 Subject: [PATCH 1/3] SettingsLib: Rename WifiManager.LINK_CONFIGURATION_CHANGED_ACTION Rename WifiManager.LINK_CONFIGURATION_CHANGED_ACTION to WifiManager.ACTION_LINK_CONFIGURATION_CHANGED to conform to API guidelines. Bug: 143970861 Test: make RunSettingsLibRoboTests -j40 Change-Id: Ib2ad30259276405586000d0d34322d5fa5e25a84 --- .../deviceinfo/AbstractImsStatusPreferenceController.java | 2 +- .../deviceinfo/AbstractIpAddressPreferenceController.java | 2 +- .../AbstractWifiMacAddressPreferenceController.java | 2 +- .../src/com/android/settingslib/wifi/WifiTracker.java | 4 ++-- .../src/com/android/settingslib/wifi/WifiTrackerTest.java | 4 ++-- .../deviceinfo/IpAddressPreferenceControllerTest.java | 2 +- .../deviceinfo/WifiMacAddressPreferenceControllerTest.java | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractImsStatusPreferenceController.java b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractImsStatusPreferenceController.java index a5f403690dab1..4c3e605e3a948 100644 --- a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractImsStatusPreferenceController.java +++ b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractImsStatusPreferenceController.java @@ -44,7 +44,7 @@ public abstract class AbstractImsStatusPreferenceController private static final String[] CONNECTIVITY_INTENTS = { BluetoothAdapter.ACTION_STATE_CHANGED, ConnectivityManager.CONNECTIVITY_ACTION, - WifiManager.LINK_CONFIGURATION_CHANGED_ACTION, + WifiManager.ACTION_LINK_CONFIGURATION_CHANGED, WifiManager.NETWORK_STATE_CHANGED_ACTION, }; diff --git a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractIpAddressPreferenceController.java b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractIpAddressPreferenceController.java index 24da72ea611a5..3bb3a0c412a54 100644 --- a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractIpAddressPreferenceController.java +++ b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractIpAddressPreferenceController.java @@ -42,7 +42,7 @@ public abstract class AbstractIpAddressPreferenceController private static final String[] CONNECTIVITY_INTENTS = { ConnectivityManager.CONNECTIVITY_ACTION, - WifiManager.LINK_CONFIGURATION_CHANGED_ACTION, + WifiManager.ACTION_LINK_CONFIGURATION_CHANGED, WifiManager.NETWORK_STATE_CHANGED_ACTION, }; diff --git a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractWifiMacAddressPreferenceController.java b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractWifiMacAddressPreferenceController.java index 097c028714a1e..b5f275b463f42 100644 --- a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractWifiMacAddressPreferenceController.java +++ b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractWifiMacAddressPreferenceController.java @@ -44,7 +44,7 @@ public abstract class AbstractWifiMacAddressPreferenceController private static final String[] CONNECTIVITY_INTENTS = { ConnectivityManager.CONNECTIVITY_ACTION, - WifiManager.LINK_CONFIGURATION_CHANGED_ACTION, + WifiManager.ACTION_LINK_CONFIGURATION_CHANGED, WifiManager.NETWORK_STATE_CHANGED_ACTION, }; diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java index d3bab5f41f39c..97fddc0e3e798 100644 --- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java @@ -180,7 +180,7 @@ public class WifiTracker implements LifecycleObserver, OnStart, OnStop, OnDestro filter.addAction(WifiManager.NETWORK_IDS_CHANGED_ACTION); filter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION); filter.addAction(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION); - filter.addAction(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION); + filter.addAction(WifiManager.ACTION_LINK_CONFIGURATION_CHANGED); filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); filter.addAction(WifiManager.RSSI_CHANGED_ACTION); @@ -866,7 +866,7 @@ public class WifiTracker implements LifecycleObserver, OnStart, OnStop, OnDestro fetchScansAndConfigsAndUpdateAccessPoints(); } else if (WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION.equals(action) - || WifiManager.LINK_CONFIGURATION_CHANGED_ACTION.equals(action)) { + || WifiManager.ACTION_LINK_CONFIGURATION_CHANGED.equals(action)) { fetchScansAndConfigsAndUpdateAccessPoints(); } else if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action)) { // TODO(sghuman): Refactor these methods so they cannot result in duplicate diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java index 7fac81211dc1b..942ee4f7404cb 100644 --- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java +++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java @@ -902,7 +902,7 @@ public class WifiTrackerTest { tracker.mReceiver.onReceive( mContext, new Intent(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION)); tracker.mReceiver.onReceive( - mContext, new Intent(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION)); + mContext, new Intent(WifiManager.ACTION_LINK_CONFIGURATION_CHANGED)); verify(mockWifiListener, never()).onAccessPointsChanged(); @@ -920,7 +920,7 @@ public class WifiTrackerTest { tracker.mReceiver.onReceive( mContext, new Intent(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION)); tracker.mReceiver.onReceive( - mContext, new Intent(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION)); + mContext, new Intent(WifiManager.ACTION_LINK_CONFIGURATION_CHANGED)); verify(mockWifiListener, never()).onAccessPointsChanged(); diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/IpAddressPreferenceControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/IpAddressPreferenceControllerTest.java index 76a26d9179695..a83d7e099e514 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/IpAddressPreferenceControllerTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/IpAddressPreferenceControllerTest.java @@ -63,7 +63,7 @@ public class IpAddressPreferenceControllerTest { new ConcreteIpAddressPreferenceController(mContext, mLifecycle); final List expectedIntents = Arrays.asList( ConnectivityManager.CONNECTIVITY_ACTION, - WifiManager.LINK_CONFIGURATION_CHANGED_ACTION, + WifiManager.ACTION_LINK_CONFIGURATION_CHANGED, WifiManager.NETWORK_STATE_CHANGED_ACTION); diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/WifiMacAddressPreferenceControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/WifiMacAddressPreferenceControllerTest.java index 7c2f0a8aaa714..40b9b13ef55fb 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/WifiMacAddressPreferenceControllerTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/WifiMacAddressPreferenceControllerTest.java @@ -84,7 +84,7 @@ public class WifiMacAddressPreferenceControllerTest { public void testHasIntentFilters() { final List expectedIntents = Arrays.asList( ConnectivityManager.CONNECTIVITY_ACTION, - WifiManager.LINK_CONFIGURATION_CHANGED_ACTION, + WifiManager.ACTION_LINK_CONFIGURATION_CHANGED, WifiManager.NETWORK_STATE_CHANGED_ACTION); From f07dd9ac85d6f13b0662ca2e4cf2b9bb69325199 Mon Sep 17 00:00:00 2001 From: David Su Date: Tue, 5 Nov 2019 13:51:16 -0800 Subject: [PATCH 2/3] SystemUI: Clean up WifiManager APIs Promoting WifiManager#registerSoftApCallback() and WifiManager#registerTrafficStateCallback() to @SystemApi. Changed method signatures to conform to API guidelines. Bug: 143970861 Test: atest HotspotControllerImplTest Change-Id: I1950173be3a62fc1cf8b745f97a503c386a11972 --- .../android/systemui/statusbar/policy/WifiSignalController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java index a441f660ecb72..5a4332105e579 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java @@ -128,7 +128,7 @@ public class WifiSignalController extends } public void handleBootCompleted() { - mWifiManager.registerTrafficStateCallback(new WifiTrafficStateCallback(), null); + mWifiManager.registerTrafficStateCallback(new WifiTrafficStateCallback()); } /** From f7ef955d9061aab091af1dd0873c4a35fa470e19 Mon Sep 17 00:00:00 2001 From: David Su Date: Tue, 5 Nov 2019 13:44:12 -0800 Subject: [PATCH 3/3] WifiManager/Scanner: Expose @hide APIs as @SystemApi Expose @hide APIs in WifiManager/WifiScanner as @SystemApi so that they can be referenced by external callers (mostly Settings). Bug: 143970861 Test: atest FrameworksWifiApiTests Change-Id: I956290e2a3aca3f4946da52d7e271082824dd06c --- api/system-current.txt | 57 ++- api/system-lint-baseline.txt | 4 +- wifi/java/android/net/wifi/WifiManager.java | 365 ++++++++++++------ wifi/java/android/net/wifi/WifiScanner.java | 5 +- .../src/android/net/wifi/WifiManagerTest.java | 48 ++- 5 files changed, 341 insertions(+), 138 deletions(-) diff --git a/api/system-current.txt b/api/system-current.txt index fd6afea8a91b4..412e0959570c1 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -4839,21 +4839,38 @@ package android.net.wifi { 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 enableVerboseLogging(int); + method @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL) 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>>> getAllMatchingWifiConfigs(@NonNull java.util.List); + method @Nullable @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL) public String getCountryCode(); + method @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) 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> getMatchingOsuProviders(@Nullable java.util.List); method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.Map getMatchingPasspointConfigsForOsuProviders(@NonNull java.util.Set); 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 getPrivilegedConfiguredNetworks(); + method public int getVerboseLoggingLevel(); 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(); method public boolean isApMacRandomizationSupported(); method public boolean isConnectedMacRandomizationSupported(); method @Deprecated public boolean isDeviceToDeviceRttSupported(); + method public boolean isDualBandSupported(); + method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public boolean isDualModeSupported(); method public boolean isPortableHotspotSupported(); method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public boolean isWifiApEnabled(); method public boolean isWifiScannerSupported(); - method @RequiresPermission(android.Manifest.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 registerNetworkRequestMatchCallback(@NonNull android.net.wifi.WifiManager.NetworkRequestMatchCallback); + 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 android.net.wifi.WifiManager.SoftApCallback); + 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 android.net.wifi.WifiManager.TrafficStateCallback); + method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void registerTrafficStateCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.TrafficStateCallback); method @RequiresPermission("android.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 @Deprecated @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 @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); @@ -4865,8 +4882,15 @@ package android.net.wifi { 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(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.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 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 @@ -4878,8 +4902,11 @@ package android.net.wifi { 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_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"; @@ -4892,6 +4919,8 @@ package android.net.wifi { 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_START_FAILURE_GENERAL = 0; // 0x0 + field public static final int SAP_START_FAILURE_NO_CHANNEL = 1; // 0x1 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 @@ -4908,14 +4937,35 @@ package android.net.wifi { method public void onSuccess(); } + public static interface WifiManager.NetworkRequestMatchCallback { + method public default void onAbort(); + method public default void onMatch(@NonNull java.util.List); + 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.OnWifiUsabilityStatsListener { method public void onWifiUsabilityStats(int, boolean, @NonNull android.net.wifi.WifiUsabilityStatsEntry); } public static interface WifiManager.SoftApCallback { - method public void onConnectedClientsChanged(@NonNull java.util.List); + method public default void onConnectedClientsChanged(@NonNull java.util.List); method public default void onInfoChanged(@NonNull android.net.wifi.SoftApInfo); - method public void onStateChanged(int, int); + 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 class WifiNetworkConnectionStatistics implements android.os.Parcelable { @@ -4938,6 +4988,7 @@ package android.net.wifi { method @Deprecated public void configureWifiChange(android.net.wifi.WifiScanner.WifiChangeSettings); method @NonNull @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public java.util.List getAvailableChannels(int); method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public boolean getScanResults(); + method @NonNull @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public java.util.List getSingleScanResults(); method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void startBackgroundScan(android.net.wifi.WifiScanner.ScanSettings, android.net.wifi.WifiScanner.ScanListener); method @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); diff --git a/api/system-lint-baseline.txt b/api/system-lint-baseline.txt index 6c659c880b34a..7eb54434f5563 100644 --- a/api/system-lint-baseline.txt +++ b/api/system-lint-baseline.txt @@ -1,6 +1,8 @@ // Baseline format: 1.0 ActionValue: android.location.Location#EXTRA_NO_GPS_LOCATION: +ActionValue: android.net.wifi.WifiManager#ACTION_LINK_CONFIGURATION_CHANGED: + Inconsistent action value; expected `android.net.wifi.action.LINK_CONFIGURATION_CHANGED`, was `android.net.wifi.LINK_CONFIGURATION_CHANGED` ArrayReturn: android.view.contentcapture.ViewNode#getAutofillOptions(): @@ -347,7 +349,7 @@ SamShouldBeLast: android.telephony.TelephonyManager#requestNetworkScan(android.t SamShouldBeLast: android.telephony.TelephonyManager#setPreferredOpportunisticDataSubscription(int, boolean, java.util.concurrent.Executor, java.util.function.Consumer): SamShouldBeLast: android.telephony.TelephonyManager#updateAvailableNetworks(java.util.List, java.util.concurrent.Executor, java.util.function.Consumer): - + SamShouldBeLast: android.view.View#postDelayed(Runnable, long): SamShouldBeLast: android.view.View#postOnAnimationDelayed(Runnable, long): diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index a61a5afc310e8..8482b069616de 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -380,14 +380,6 @@ public class WifiManager { * @hide */ public static final String EXTRA_DELAY = "android.net.wifi.extra.DELAY"; - /** - * String representation of an URL. - * - * Retrieve with {@link android.content.Intent#getStringExtra(String)}. - * - * @hide - */ - public static final String EXTRA_URL = "android.net.wifi.extra.URL"; /** * Broadcast intent action indicating a Passpoint subscription remediation frame has been @@ -420,30 +412,41 @@ public class WifiManager { "android.net.wifi.extra.SUBSCRIPTION_REMEDIATION_METHOD"; /** - * Activity Action: lunch OSU (Online Sign Up) view. + * 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. * - *

Note: The broadcast is only delivered to registered receivers - no manifest registered - * components will be launched. - * * @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 OSU server. + * 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. @@ -656,6 +659,7 @@ public class WifiManager { * * @hide */ + @SystemApi public static final int SAP_START_FAILURE_GENERAL= 0; /** @@ -664,6 +668,7 @@ public class WifiManager { * * @hide */ + @SystemApi public static final int SAP_START_FAILURE_NO_CHANNEL = 1; /** @hide */ @@ -917,7 +922,7 @@ public class WifiManager { * The RSSI (signal strength) has changed. * * Receiver Required Permission: android.Manifest.permission.ACCESS_WIFI_STATE - * @see {@link #EXTRA_NEW_RSSI} + * @see #EXTRA_NEW_RSSI */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String RSSI_CHANGED_ACTION = "android.net.wifi.RSSI_CHANGED"; @@ -927,21 +932,37 @@ public class WifiManager { public static final String EXTRA_NEW_RSSI = "newRssi"; /** - * Broadcast intent action indicating that the link configuration - * changed on wifi. + * @see #ACTION_LINK_CONFIGURATION_CHANGED * @hide */ @UnsupportedAppUsage public static final String LINK_CONFIGURATION_CHANGED_ACTION = - "android.net.wifi.LINK_CONFIGURATION_CHANGED"; + "android.net.wifi.LINK_CONFIGURATION_CHANGED"; + + /** + * Broadcast intent action indicating that the link configuration changed on wifi. + *
Included Extras: + *
{@link #EXTRA_LINK_PROPERTIES}: {@link android.net.LinkProperties} object associated + * with the Wi-Fi network. + *
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. Retrieve with - * {@link android.content.Intent#getParcelableExtra(String)}. + * Wi-Fi network. + * Included in the {@link #ACTION_LINK_CONFIGURATION_CHANGED} broadcast. + * + * Retrieve with {@link android.content.Intent#getParcelableExtra(String)}. * @hide */ - public static final String EXTRA_LINK_PROPERTIES = "linkProperties"; + @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 @@ -981,24 +1002,26 @@ public class WifiManager { public static final String ACTION_PICK_WIFI_NETWORK = "android.net.wifi.PICK_WIFI_NETWORK"; /** - * Activity Action: Show UI to get user approval to enable WiFi. + * Activity Action: Receiver should show UI to get user approval to enable WiFi. *

Input: {@link android.content.Intent#EXTRA_PACKAGE_NAME} string extra with * the name of the app requesting the action. *

Output: Nothing. - * + *

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: Show UI to get user approval to disable WiFi. + * Activity Action: Receiver should show UI to get user approval to disable WiFi. *

Input: {@link android.content.Intent#EXTRA_PACKAGE_NAME} string extra with * the name of the app requesting the action. *

Output: Nothing. - * + *

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"; @@ -1115,11 +1138,15 @@ public class WifiManager { private static final int MAX_RSSI = -55; /** - * Number of RSSI levels used in the framework to initiate - * {@link #RSSI_CHANGED_ACTION} broadcast + * 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 + // TODO(b/140781184): need to support custom number of RSSI levels, as well as levels that are + // not evenly spaced public static final int RSSI_LEVELS = 5; /** @@ -1147,7 +1174,8 @@ public class WifiManager { /** @hide */ public static final boolean DEFAULT_POOR_NETWORK_AVOIDANCE_ENABLED = false; - /* Maximum number of active locks we allow. + /** + * 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. */ @@ -1487,40 +1515,43 @@ public class WifiManager { * {@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. */ - void select(@NonNull WifiConfiguration wifiConfiguration); + default void select(@NonNull WifiConfiguration wifiConfiguration) {} /** * User rejected the app's request. */ - void reject(); + default void reject() {} } /** * Interface for network request callback. Should be implemented by applications and passed when - * calling {@link #registerNetworkRequestMatchCallback(NetworkRequestMatchCallback, Handler)}. + * 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 paased in this method is to be invoked by the UI component after the service sends + * 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. */ - void onUserSelectionCallbackRegistration( - @NonNull NetworkRequestUserSelectionCallback userSelectionCallback); + default void onUserSelectionCallbackRegistration( + @NonNull NetworkRequestUserSelectionCallback userSelectionCallback) {} /** * Invoked when the active network request is aborted, either because @@ -1529,7 +1560,7 @@ public class WifiManager { * 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. */ - void onAbort(); + default void onAbort() {} /** * Invoked when a network request initiated by an app matches some networks in scan results. @@ -1539,7 +1570,7 @@ public class WifiManager { * @param scanResults List of {@link ScanResult} objects corresponding to the networks * matching the request. */ - void onMatch(@NonNull List scanResults); + default void onMatch(@NonNull List scanResults) {} /** * Invoked on a successful connection with the network that the user selected @@ -1548,7 +1579,7 @@ public class WifiManager { * @param wifiConfiguration WifiConfiguration object corresponding to the network that the * user selected. */ - void onUserSelectionConnectSuccess(@NonNull WifiConfiguration wifiConfiguration); + default void onUserSelectionConnectSuccess(@NonNull WifiConfiguration wifiConfiguration) {} /** * Invoked on failure to establish connection with the network that the user selected @@ -1557,7 +1588,7 @@ public class WifiManager { * @param wifiConfiguration WifiConfiguration object corresponding to the network * user selected. */ - void onUserSelectionConnectFailure(@NonNull WifiConfiguration wifiConfiguration); + default void onUserSelectionConnectFailure(@NonNull WifiConfiguration wifiConfiguration) {} } /** @@ -1606,11 +1637,11 @@ public class WifiManager { * @hide */ private class NetworkRequestMatchCallbackProxy extends INetworkRequestMatchCallback.Stub { - private final Handler mHandler; + private final Executor mExecutor; private final NetworkRequestMatchCallback mCallback; - NetworkRequestMatchCallbackProxy(Looper looper, NetworkRequestMatchCallback callback) { - mHandler = new Handler(looper); + NetworkRequestMatchCallbackProxy(Executor executor, NetworkRequestMatchCallback callback) { + mExecutor = executor; mCallback = callback; } @@ -1621,7 +1652,8 @@ public class WifiManager { Log.v(TAG, "NetworkRequestMatchCallbackProxy: " + "onUserSelectionCallbackRegistration callback: " + userSelectionCallback); } - mHandler.post(() -> { + Binder.clearCallingIdentity(); + mExecutor.execute(() -> { mCallback.onUserSelectionCallbackRegistration( new NetworkRequestUserSelectionCallbackProxy(userSelectionCallback)); }); @@ -1632,7 +1664,8 @@ public class WifiManager { if (mVerboseLoggingEnabled) { Log.v(TAG, "NetworkRequestMatchCallbackProxy: onAbort"); } - mHandler.post(() -> { + Binder.clearCallingIdentity(); + mExecutor.execute(() -> { mCallback.onAbort(); }); } @@ -1643,7 +1676,8 @@ public class WifiManager { Log.v(TAG, "NetworkRequestMatchCallbackProxy: onMatch scanResults: " + scanResults); } - mHandler.post(() -> { + Binder.clearCallingIdentity(); + mExecutor.execute(() -> { mCallback.onMatch(scanResults); }); } @@ -1654,7 +1688,8 @@ public class WifiManager { Log.v(TAG, "NetworkRequestMatchCallbackProxy: onUserSelectionConnectSuccess " + " wificonfiguration: " + wifiConfiguration); } - mHandler.post(() -> { + Binder.clearCallingIdentity(); + mExecutor.execute(() -> { mCallback.onUserSelectionConnectSuccess(wifiConfiguration); }); } @@ -1665,12 +1700,25 @@ public class WifiManager { Log.v(TAG, "NetworkRequestMatchCallbackProxy: onUserSelectionConnectFailure" + " wificonfiguration: " + wifiConfiguration); } - mHandler.post(() -> { + Binder.clearCallingIdentity(); + mExecutor.execute(() -> { mCallback.onUserSelectionConnectFailure(wifiConfiguration); }); } } + /** + * Same as {@link #registerNetworkRequestMatchCallback(Executor, NetworkRequestMatchCallback)}, + * except that the callback will be executed on the application's main thread. + * @param callback Callback for network match events to register. + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) + public void registerNetworkRequestMatchCallback(@NonNull NetworkRequestMatchCallback callback) { + registerNetworkRequestMatchCallback(mContext.getMainExecutor(), callback); + } + /** * Registers a callback for NetworkRequest matches. See {@link NetworkRequestMatchCallback}. * Caller can unregister a previously registered callback using @@ -1681,19 +1729,20 @@ public class WifiManager { * without the permission will trigger a {@link java.lang.SecurityException}. *

* - * @param callback Callback for network match events - * @param handler The Handler on whose thread to execute the callbacks of the {@code callback} - * object. If null, then the application's main thread will be used. + * @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 NetworkRequestMatchCallback callback, - @Nullable Handler handler) { + 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 - + ", handler=" + handler); + + ", executor=" + executor); - Looper looper = (handler == null) ? mContext.getMainLooper() : handler.getLooper(); Binder binder = new Binder(); try { IWifiManager iWifiManager = getIWifiManager(); @@ -1701,7 +1750,7 @@ public class WifiManager { throw new RemoteException("Wifi service is not running"); } iWifiManager.registerNetworkRequestMatchCallback( - binder, new NetworkRequestMatchCallbackProxy(looper, callback), + binder, new NetworkRequestMatchCallbackProxy(executor, callback), callback.hashCode()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -1716,9 +1765,10 @@ public class WifiManager { * without the permission will trigger a {@link java.lang.SecurityException}. *

* - * @param callback Callback for network match events + * @param callback Callback for network match events to unregister. * @hide */ + @SystemApi @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void unregisterNetworkRequestMatchCallback( @NonNull NetworkRequestMatchCallback callback) { @@ -2561,29 +2611,30 @@ public class WifiManager { } /** - * get the country code. - * @return the country code in ISO 3166 format. - * - * @hide - */ - @UnsupportedAppUsage + * Get the country code. + * @return the country code in ISO 3166 format, or null if there is no country code configured. + * @hide + */ + @Nullable + @SystemApi + @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL) public String getCountryCode() { try { IWifiManager iWifiManager = getIWifiManager(); if (iWifiManager == null) return null; - String country = iWifiManager.getCountryCode(); - return country; + return iWifiManager.getCountryCode(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** - * Check if the chipset supports dual frequency band (2.4 GHz and 5 GHz) + * Check if the chipset supports dual frequency band (2.4 GHz and 5 GHz). + * No permissions are required to call this method. * @return {@code true} if supported, {@code false} otherwise. * @hide */ - @UnsupportedAppUsage + @SystemApi public boolean isDualBandSupported() { try { IWifiManager iWifiManager = getIWifiManager(); @@ -2595,10 +2646,20 @@ public class WifiManager { } /** - * Check if the chipset requires conversion of 5GHz Only apBand to ANY. - * @return {@code true} if required, {@code false} otherwise. + * Check if the device is dual mode capable i.e. supports concurrent STA + Soft AP. + * + * If the device is dual mode capable, it may require conversion of the user's Soft AP band + * selection {@link WifiConfiguration#apBand} from {@link WifiConfiguration#AP_BAND_5GHZ} to + * {@link WifiConfiguration#AP_BAND_ANY}, since if the device is connected to a 5GHz DFS + * channel as a STA, it may be unable to honor a request to start Soft AP on the same DFS + * channel. + * + * @return {@code true} if dual mode STA + AP is supported by this device, {@code false} + * otherwise. * @hide */ + @SystemApi + @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public boolean isDualModeSupported() { try { IWifiManager iWifiManager = getIWifiManager(); @@ -2685,6 +2746,7 @@ public class WifiManager { * * @hide for CTS test only */ + // TODO(b/144036594): add @TestApi public void getTxPacketCount(@NonNull TxPacketCountListener listener) { if (listener == null) throw new IllegalArgumentException("listener cannot be null"); Binder binder = new Binder(); @@ -3134,10 +3196,12 @@ public class WifiManager { } /** - * Method that triggers a notification to the user about a conversion to their saved AP config. + * Method that triggers a notification to the user about a band conversion + * (e.g. 5 GHz to 2.4 GHz) to their saved AP config. * * @hide */ + // TODO(b/144218444): move the notification to Settings instead of making this @SystemApi @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void notifyUserOfApBandConversion() { Log.d(TAG, "apBand was converted, notify the user"); @@ -3371,22 +3435,21 @@ public class WifiManager { /** * Called when soft AP state changes. * - * @param state new new AP state. One of {@link #WIFI_AP_STATE_DISABLED}, + * @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} */ - void onStateChanged(@WifiApState int state, - @SapStartFailure int failureReason); + default void onStateChanged(@WifiApState int state, @SapStartFailure int failureReason) {} /** * Called when the connected clients to soft AP changes. * * @param clients the currently connected clients */ - void onConnectedClientsChanged(@NonNull List clients); + default void onConnectedClientsChanged(@NonNull List clients) {} /** * Called when information of softap changes. @@ -3451,32 +3514,43 @@ public class WifiManager { } } + /** + * Same as {@link #registerSoftApCallback(Executor, SoftApCallback)}, + * except that the callback will be executed on the application's main thread. + * @param callback Callback for soft AP events + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) + public void registerSoftApCallback(@NonNull SoftApCallback callback) { + registerSoftApCallback(mContext.getMainExecutor(), callback); + } + /** * Registers a callback for Soft AP. See {@link SoftApCallback}. Caller will receive the current * soft AP state and number of connected devices immediately after a successful call to this API * via callback. 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} + * previously registered callback using {@link #unregisterSoftApCallback} *

* Applications should have the * {@link android.Manifest.permission#NETWORK_SETTINGS NETWORK_SETTINGS} permission. Callers * without the permission will trigger a {@link java.lang.SecurityException}. *

* - * @param executor The executor to execute the callbacks of the {@code executor} - * object. If null, then the application's main executor will be used. + * @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(@Nullable @CallbackExecutor Executor executor, - @NonNull SoftApCallback callback) { + 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); - executor = (executor == null) ? mContext.getMainExecutor() : executor; Binder binder = new Binder(); try { IWifiManager iWifiManager = getIWifiManager(); @@ -3498,6 +3572,7 @@ public class WifiManager { * * @hide */ + @SystemApi @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void unregisterSoftApCallback(@NonNull SoftApCallback callback) { if (callback == null) throw new IllegalArgumentException("callback cannot be null"); @@ -4042,23 +4117,27 @@ public class WifiManager { } /** - * Disable ephemeral Network + * Disable an ephemeral network. + * + * @param ssid in the format of WifiConfiguration's SSID. * - * @param SSID, in the format of WifiConfiguration's SSID. * @hide */ + @SystemApi @RequiresPermission(anyOf = { android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK }) - public void disableEphemeralNetwork(String SSID) { - if (TextUtils.isEmpty(SSID)) throw new IllegalArgumentException("SSID cannot be null"); + public void disableEphemeralNetwork(@NonNull String ssid) { + if (TextUtils.isEmpty(ssid)) { + throw new IllegalArgumentException("SSID cannot be null or empty!"); + } try { IWifiManager iWifiManager = getIWifiManager(); if (iWifiManager == null) { throw new RemoteException("Wifi service is not running"); } - iWifiManager.disableEphemeralNetwork(SSID, mContext.getOpPackageName()); + iWifiManager.disableEphemeralNetwork(ssid, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4554,11 +4633,15 @@ public class WifiManager { } /** - * Set wifi verbose log. Called from developer settings. + * Set Wi-Fi verbose logging level from developer settings. + * + * @param verbose the verbose logging level to set. 0 will disable verbose logging, a positive + * integer will enable verbose logging. + * * @hide */ + @SystemApi @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) - @UnsupportedAppUsage public void enableVerboseLogging (int verbose) { try { IWifiManager iWifiManager = getIWifiManager(); @@ -4574,11 +4657,15 @@ public class WifiManager { } /** - * Get the WiFi verbose logging level.This is used by settings - * to decide what to show within the picker. + * Get the persisted WiFi verbose logging level, set by {@link #enableVerboseLogging(int)}. + * No permissions are required to call this method. + * + * @return 0 to indicate that verbose logging is disabled, a positive integer to indicate that + * verbose logging is enabled. + * * @hide */ - @UnsupportedAppUsage + @SystemApi public int getVerboseLoggingLevel() { try { IWifiManager iWifiManager = getIWifiManager(); @@ -4590,10 +4677,13 @@ public class WifiManager { } /** - * Removes all saved wifi networks. + * Removes all saved Wi-Fi networks, Passpoint configurations, ephemeral networks, Network + * Requests, and Network Suggestions. * * @hide */ + @SystemApi + @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL) public void factoryReset() { try { IWifiManager iWifiManager = getIWifiManager(); @@ -4607,11 +4697,12 @@ public class WifiManager { } /** - * Get Network object of current wifi network - * @return Get Network object of current wifi network + * Get {@link Network} object of current wifi network, or null if not connected. * @hide */ - @UnsupportedAppUsage + @Nullable + @SystemApi + @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public Network getCurrentNetwork() { try { IWifiManager iWifiManager = getIWifiManager(); @@ -4660,13 +4751,18 @@ public class WifiManager { } /** - * Retrieve the data to be backed to save the current state. + * 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 { IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) return null; + if (iWifiManager == null) return new byte[0]; return iWifiManager.retrieveBackupData(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -4675,9 +4771,12 @@ public class WifiManager { /** * Restore state from the backed up data. + * @param data byte stream in the same format produced by {@link #retrieveBackupData()} * @hide */ - public void restoreBackupData(byte[] data) { + @SystemApi + @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) + public void restoreBackupData(@NonNull byte[] data) { try { IWifiManager iWifiManager = getIWifiManager(); if (iWifiManager == null) { @@ -4694,11 +4793,16 @@ public class WifiManager { * 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 * @deprecated this is no longer supported. * @hide */ @Deprecated - public void restoreSupplicantBackupData(byte[] supplicantData, byte[] ipConfigData) { + @SystemApi + @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) + public void restoreSupplicantBackupData( + @NonNull byte[] supplicantData, @NonNull byte[] ipConfigData) { try { IWifiManager iWifiManager = getIWifiManager(); if (iWifiManager == null) { @@ -4774,22 +4878,29 @@ public class WifiManager { } /** - * Base class for Traffic state callback. Should be extended by applications and set when - * calling {@link WifiManager#registerTrafficStateCallback(TrafficStateCallback, Handler)}. + * Interface for Traffic state callback. Should be extended by applications and set when + * calling {@link #registerTrafficStateCallback(Executor, WifiManager.TrafficStateCallback)}. * @hide */ + @SystemApi public interface TrafficStateCallback { - /** - * Lowest bit indicates data reception and the second lowest - * bit indicates data transmitted - */ /** @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; - /** @hide */ + /** Data in, no data out */ int DATA_ACTIVITY_IN = 0x01; - /** @hide */ + /** Data out, no data in */ int DATA_ACTIVITY_OUT = 0x02; - /** @hide */ + /** Data in and out */ int DATA_ACTIVITY_INOUT = 0x03; /** @@ -4797,9 +4908,8 @@ public class WifiManager { * * @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); + void onStateChanged(@DataActivity int state); } /** @@ -4808,11 +4918,11 @@ public class WifiManager { * @hide */ private class TrafficStateCallbackProxy extends ITrafficStateCallback.Stub { - private final Handler mHandler; + private final Executor mExecutor; private final TrafficStateCallback mCallback; - TrafficStateCallbackProxy(Looper looper, TrafficStateCallback callback) { - mHandler = new Handler(looper); + TrafficStateCallbackProxy(Executor executor, TrafficStateCallback callback) { + mExecutor = executor; mCallback = callback; } @@ -4821,12 +4931,25 @@ public class WifiManager { if (mVerboseLoggingEnabled) { Log.v(TAG, "TrafficStateCallbackProxy: onStateChanged state=" + state); } - mHandler.post(() -> { + Binder.clearCallingIdentity(); + mExecutor.execute(() -> { mCallback.onStateChanged(state); }); } } + /** + * Same as {@link #registerTrafficStateCallback(Executor, TrafficStateCallback)}, + * except that the callback will be executed on the application's main thread. + * @param callback Callback for traffic state events + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) + public void registerTrafficStateCallback(@NonNull TrafficStateCallback callback) { + registerTrafficStateCallback(mContext.getMainExecutor(), callback); + } + /** * Registers a callback for monitoring traffic state. See {@link TrafficStateCallback}. These * callbacks will be invoked periodically by platform to inform clients about the current @@ -4838,18 +4961,19 @@ public class WifiManager { * without the permission will trigger a {@link java.lang.SecurityException}. *

* + * @param executor The Executor on whose thread to execute the callbacks of the {@code callback} + * object. * @param callback Callback for traffic state events - * @param handler The Handler on whose thread to execute the callbacks of the {@code callback} - * object. If null, then the application's main thread will be used. * @hide */ + @SystemApi @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) - public void registerTrafficStateCallback(@NonNull TrafficStateCallback callback, - @Nullable Handler handler) { + 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 + ", handler=" + handler); + Log.v(TAG, "registerTrafficStateCallback: callback=" + callback + ", executor=" + executor); - Looper looper = (handler == null) ? mContext.getMainLooper() : handler.getLooper(); Binder binder = new Binder(); try { IWifiManager iWifiManager = getIWifiManager(); @@ -4857,7 +4981,7 @@ public class WifiManager { throw new RemoteException("Wifi service is not running"); } iWifiManager.registerTrafficStateCallback( - binder, new TrafficStateCallbackProxy(looper, callback), callback.hashCode()); + binder, new TrafficStateCallbackProxy(executor, callback), callback.hashCode()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4870,6 +4994,7 @@ public class WifiManager { * @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"); @@ -4933,11 +5058,13 @@ public class WifiManager { * if failed. * @hide */ + @NonNull + @SystemApi @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public String[] getFactoryMacAddresses() { try { IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) return null; + if (iWifiManager == null) return new String[0]; return iWifiManager.getFactoryMacAddresses(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java index 7e14451332fb9..0d36718f07f1c 100644 --- a/wifi/java/android/net/wifi/WifiScanner.java +++ b/wifi/java/android/net/wifi/WifiScanner.java @@ -960,6 +960,9 @@ public class WifiScanner { * Retrieve the most recent scan results from a single scan request. * {@hide} */ + @NonNull + @SystemApi + @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public List getSingleScanResults() { validateChannel(); Bundle scanParams = new Bundle(); @@ -973,7 +976,7 @@ public class WifiScanner { OperationResult result = (OperationResult) reply.obj; Log.e(TAG, "Error retrieving SingleScan results reason: " + result.reason + " description: " + result.description); - return new ArrayList(); + return new ArrayList<>(); } private void startPnoScan(ScanSettings scanSettings, PnoSettings pnoSettings, int key) { diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index 6305277269642..06ebc1b3f6dab 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -708,6 +708,18 @@ public class WifiManagerTest { } } + /** + * 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. */ @@ -724,9 +736,10 @@ public class WifiManagerTest { * Verify main looper is used when handler is not provided. */ @Test - public void registerSoftApCallbackUsesMainLooperOnNullArgumentForHandler() { - when(mContext.getMainLooper()).thenReturn(mLooper.getLooper()); - mWifiManager.registerSoftApCallback(null, mSoftApCallback); + public void registerSoftApCallbackUsesMainExecutorOnNoExecutorProvided() { + when(mContext.getMainExecutor()).thenReturn( + new HandlerExecutor(new Handler(mLooper.getLooper()))); + mWifiManager.registerSoftApCallback(mSoftApCallback); verify(mContext).getMainExecutor(); } @@ -1147,10 +1160,11 @@ public class WifiManagerTest { @Test public void registerTrafficStateCallbackUsesMainLooperOnNullArgumentForHandler() throws Exception { - when(mContext.getMainLooper()).thenReturn(mLooper.getLooper()); + when(mContext.getMainExecutor()).thenReturn( + new HandlerExecutor(new Handler(mLooper.getLooper()))); ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(ITrafficStateCallback.Stub.class); - mWifiManager.registerTrafficStateCallback(mTrafficStateCallback, null); + mWifiManager.registerTrafficStateCallback(mTrafficStateCallback); verify(mWifiService).registerTrafficStateCallback( any(IBinder.class), callbackCaptor.capture(), anyInt()); @@ -1166,7 +1180,8 @@ public class WifiManagerTest { @Test public void unregisterTrafficStateCallbackCallGoesToWifiServiceImpl() throws Exception { ArgumentCaptor callbackIdentifier = ArgumentCaptor.forClass(Integer.class); - mWifiManager.registerTrafficStateCallback(mTrafficStateCallback, mHandler); + mWifiManager.registerTrafficStateCallback(new HandlerExecutor(mHandler), + mTrafficStateCallback); verify(mWifiService).registerTrafficStateCallback(any(IBinder.class), any(ITrafficStateCallback.Stub.class), callbackIdentifier.capture()); @@ -1182,7 +1197,8 @@ public class WifiManagerTest { public void trafficStateCallbackProxyCallsOnMultipleUpdates() throws Exception { ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(ITrafficStateCallback.Stub.class); - mWifiManager.registerTrafficStateCallback(mTrafficStateCallback, mHandler); + mWifiManager.registerTrafficStateCallback(new HandlerExecutor(mHandler), + mTrafficStateCallback); verify(mWifiService).registerTrafficStateCallback( any(IBinder.class), callbackCaptor.capture(), anyInt()); @@ -1201,7 +1217,7 @@ public class WifiManagerTest { TrafficStateCallback.DATA_ACTIVITY_OUT); } - /* + /** * Verify client-provided callback is being called on the correct thread */ @Test @@ -1210,7 +1226,8 @@ public class WifiManagerTest { ArgumentCaptor.forClass(ITrafficStateCallback.Stub.class); TestLooper altLooper = new TestLooper(); Handler altHandler = new Handler(altLooper.getLooper()); - mWifiManager.registerTrafficStateCallback(mTrafficStateCallback, altHandler); + mWifiManager.registerTrafficStateCallback(new HandlerExecutor(altHandler), + mTrafficStateCallback); verify(mContext, never()).getMainLooper(); verify(mContext, never()).getMainExecutor(); verify(mWifiService).registerTrafficStateCallback( @@ -1228,10 +1245,11 @@ public class WifiManagerTest { @Test public void registerNetworkRequestMatchCallbackCallGoesToWifiServiceImpl() throws Exception { - when(mContext.getMainLooper()).thenReturn(mLooper.getLooper()); + when(mContext.getMainExecutor()).thenReturn( + new HandlerExecutor(new Handler(mLooper.getLooper()))); ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(INetworkRequestMatchCallback.Stub.class); - mWifiManager.registerNetworkRequestMatchCallback(mNetworkRequestMatchCallback, null); + mWifiManager.registerNetworkRequestMatchCallback(mNetworkRequestMatchCallback); verify(mWifiService).registerNetworkRequestMatchCallback( any(IBinder.class), callbackCaptor.capture(), anyInt()); @@ -1265,7 +1283,8 @@ public class WifiManagerTest { @Test public void unregisterNetworkRequestMatchCallbackCallGoesToWifiServiceImpl() throws Exception { ArgumentCaptor callbackIdentifier = ArgumentCaptor.forClass(Integer.class); - mWifiManager.registerNetworkRequestMatchCallback(mNetworkRequestMatchCallback, mHandler); + mWifiManager.registerNetworkRequestMatchCallback(new HandlerExecutor(mHandler), + mNetworkRequestMatchCallback); verify(mWifiService).registerNetworkRequestMatchCallback( any(IBinder.class), any(INetworkRequestMatchCallback.class), callbackIdentifier.capture()); @@ -1282,10 +1301,11 @@ public class WifiManagerTest { @Test public void networkRequestUserSelectionCallbackCallGoesToWifiServiceImpl() throws Exception { - when(mContext.getMainLooper()).thenReturn(mLooper.getLooper()); + when(mContext.getMainExecutor()).thenReturn( + new HandlerExecutor(new Handler(mLooper.getLooper()))); ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(INetworkRequestMatchCallback.Stub.class); - mWifiManager.registerNetworkRequestMatchCallback(mNetworkRequestMatchCallback, null); + mWifiManager.registerNetworkRequestMatchCallback(mNetworkRequestMatchCallback); verify(mWifiService).registerNetworkRequestMatchCallback( any(IBinder.class), callbackCaptor.capture(), anyInt());