summaryrefslogtreecommitdiff
path: root/wifi/java
diff options
context:
space:
mode:
Diffstat (limited to 'wifi/java')
-rw-r--r--wifi/java/android/net/wifi/IActionListener.aidl27
-rw-r--r--wifi/java/android/net/wifi/ILocalOnlyHotspotCallback.aidl30
-rw-r--r--wifi/java/android/net/wifi/IScanResultsListener.aidl27
-rw-r--r--wifi/java/android/net/wifi/ITxPacketCountListener.aidl27
-rw-r--r--wifi/java/android/net/wifi/IWifiManager.aidl24
-rw-r--r--wifi/java/android/net/wifi/RssiPacketCountInfo.java75
-rw-r--r--wifi/java/android/net/wifi/WifiConfiguration.java20
-rw-r--r--wifi/java/android/net/wifi/WifiInfo.java66
-rw-r--r--wifi/java/android/net/wifi/WifiManager.java765
-rw-r--r--wifi/java/android/net/wifi/WifiNetworkSpecifier.java3
-rw-r--r--wifi/java/android/net/wifi/WifiNetworkSuggestion.java132
-rw-r--r--wifi/java/android/net/wifi/WifiScanner.java69
-rw-r--r--wifi/java/android/net/wifi/WifiUsabilityStatsEntry.java2
-rw-r--r--wifi/java/android/net/wifi/hotspot2/ConfigParser.java6
-rw-r--r--wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java18
-rw-r--r--wifi/java/com/android/server/wifi/BaseWifiService.java65
16 files changed, 784 insertions, 572 deletions
diff --git a/wifi/java/android/net/wifi/IActionListener.aidl b/wifi/java/android/net/wifi/IActionListener.aidl
new file mode 100644
index 000000000000..faa0901cb087
--- /dev/null
+++ b/wifi/java/android/net/wifi/IActionListener.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi;
+
+/**
+ * Interface for generic wifi callbacks.
+ * @hide
+ */
+oneway interface IActionListener
+{
+ void onSuccess();
+ void onFailure(int reason);
+}
diff --git a/wifi/java/android/net/wifi/ILocalOnlyHotspotCallback.aidl b/wifi/java/android/net/wifi/ILocalOnlyHotspotCallback.aidl
new file mode 100644
index 000000000000..b83b594c8cb9
--- /dev/null
+++ b/wifi/java/android/net/wifi/ILocalOnlyHotspotCallback.aidl
@@ -0,0 +1,30 @@
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi;
+
+import android.net.wifi.WifiConfiguration;
+
+/**
+ * Communicates LOHS status back to the application process.
+ *
+ * @hide
+ */
+oneway interface ILocalOnlyHotspotCallback {
+ void onHotspotStarted(in WifiConfiguration config);
+ void onHotspotStopped();
+ void onHotspotFailed(int reason);
+}
diff --git a/wifi/java/android/net/wifi/IScanResultsListener.aidl b/wifi/java/android/net/wifi/IScanResultsListener.aidl
new file mode 100644
index 000000000000..bec74a620380
--- /dev/null
+++ b/wifi/java/android/net/wifi/IScanResultsListener.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi;
+
+/**
+ * Interface for Wi-Fi scan result available callback.
+ *
+ * @hide
+ */
+oneway interface IScanResultsListener
+{
+ void onScanResultsAvailable();
+}
diff --git a/wifi/java/android/net/wifi/ITxPacketCountListener.aidl b/wifi/java/android/net/wifi/ITxPacketCountListener.aidl
new file mode 100644
index 000000000000..8606ab5afa9c
--- /dev/null
+++ b/wifi/java/android/net/wifi/ITxPacketCountListener.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi;
+
+/**
+ * Interface for tx packet counter callback.
+ * @hide
+ */
+oneway interface ITxPacketCountListener
+{
+ void onSuccess(int count);
+ void onFailure(int reason);
+}
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index df9a1d55af20..5ab6678afe78 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -24,10 +24,14 @@ import android.net.wifi.hotspot2.IProvisioningCallback;
import android.net.DhcpInfo;
import android.net.Network;
+import android.net.wifi.IActionListener;
import android.net.wifi.IDppCallback;
+import android.net.wifi.ILocalOnlyHotspotCallback;
import android.net.wifi.INetworkRequestMatchCallback;
+import android.net.wifi.IScanResultsListener;
import android.net.wifi.ISoftApCallback;
import android.net.wifi.ITrafficStateCallback;
+import android.net.wifi.ITxPacketCountListener;
import android.net.wifi.IOnWifiUsabilityStatsListener;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiActivityEnergyInfo;
@@ -107,8 +111,6 @@ interface IWifiManager
int getWifiEnabledState();
- void setCountryCode(String country);
-
String getCountryCode();
boolean isDualBandSupported();
@@ -139,11 +141,11 @@ interface IWifiManager
boolean stopSoftAp();
- int startLocalOnlyHotspot(in Messenger messenger, in IBinder binder, String packageName);
+ int startLocalOnlyHotspot(in ILocalOnlyHotspotCallback callback, String packageName);
void stopLocalOnlyHotspot();
- void startWatchLocalOnlyHotspot(in Messenger messenger, in IBinder binder);
+ void startWatchLocalOnlyHotspot(in ILocalOnlyHotspotCallback callback);
void stopWatchLocalOnlyHotspot();
@@ -157,8 +159,6 @@ interface IWifiManager
void notifyUserOfApBandConversion(String packageName);
- Messenger getWifiServiceMessenger(String packageName);
-
void enableTdls(String remoteIPAddress, boolean enable);
void enableTdlsWithMacAddress(String remoteMacAddress, boolean enable);
@@ -250,5 +250,17 @@ interface IWifiManager
void updateWifiUsabilityScore(int seqNum, int score, int predictionHorizonSec);
+ oneway void connect(in WifiConfiguration config, int netId, in IBinder binder, in IActionListener listener, int callbackIdentifier);
+
+ oneway void save(in WifiConfiguration config, in IBinder binder, in IActionListener listener, int callbackIdentifier);
+
+ oneway void forget(int netId, in IBinder binder, in IActionListener listener, int callbackIdentifier);
+
+ oneway void getTxPacketCount(String packageName, in IBinder binder, in ITxPacketCountListener listener, int callbackIdentifier);
+
+ void registerScanResultsListener(in IBinder binder, in IScanResultsListener Listener, int listenerIdentifier);
+
+ void unregisterScanResultsListener(int listenerIdentifier);
+
int getSoftApWifiGeneration();
}
diff --git a/wifi/java/android/net/wifi/RssiPacketCountInfo.java b/wifi/java/android/net/wifi/RssiPacketCountInfo.java
deleted file mode 100644
index 4301165308d1..000000000000
--- a/wifi/java/android/net/wifi/RssiPacketCountInfo.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Bundle of RSSI and packet count information, for WiFi watchdog
- *
- * @see WifiWatchdogStateMachine
- *
- * @hide
- */
-public class RssiPacketCountInfo implements Parcelable {
-
- public int rssi;
-
- public int txgood;
-
- public int txbad;
-
- public int rxgood;
-
- public RssiPacketCountInfo() {
- rssi = txgood = txbad = rxgood = 0;
- }
-
- private RssiPacketCountInfo(Parcel in) {
- rssi = in.readInt();
- txgood = in.readInt();
- txbad = in.readInt();
- rxgood = in.readInt();
- }
-
- @Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeInt(rssi);
- out.writeInt(txgood);
- out.writeInt(txbad);
- out.writeInt(rxgood);
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- public static final @android.annotation.NonNull Parcelable.Creator<RssiPacketCountInfo> CREATOR =
- new Parcelable.Creator<RssiPacketCountInfo>() {
- @Override
- public RssiPacketCountInfo createFromParcel(Parcel in) {
- return new RssiPacketCountInfo(in);
- }
-
- @Override
- public RssiPacketCountInfo[] newArray(int size) {
- return new RssiPacketCountInfo[size];
- }
- };
-}
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 258c5813f960..b51622c065fb 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -1113,26 +1113,6 @@ public class WifiConfiguration implements Parcelable {
}
/**
- * @hide
- * Returns Randomized MAC address to use with the network.
- * If it is not set/valid, creates a new randomized address.
- * If it can't generate a valid mac, returns the default MAC.
- */
- public @NonNull MacAddress getOrCreateRandomizedMacAddress() {
- int randomMacGenerationCount = 0;
- while (!isValidMacAddressForRandomization(mRandomizedMacAddress)
- && randomMacGenerationCount < MAXIMUM_RANDOM_MAC_GENERATION_RETRY) {
- mRandomizedMacAddress = MacAddress.createRandomUnicastAddress();
- randomMacGenerationCount++;
- }
-
- if (!isValidMacAddressForRandomization(mRandomizedMacAddress)) {
- mRandomizedMacAddress = MacAddress.fromString(WifiInfo.DEFAULT_MAC_ADDRESS);
- }
- return mRandomizedMacAddress;
- }
-
- /**
* Returns MAC address set to be the local randomized MAC address.
* Depending on user preference, the device may or may not use the returned MAC address for
* connections to this network.
diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java
index 0127c630baa9..7eadd3b3d9e9 100644
--- a/wifi/java/android/net/wifi/WifiInfo.java
+++ b/wifi/java/android/net/wifi/WifiInfo.java
@@ -16,6 +16,7 @@
package android.net.wifi;
+import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.Nullable;
import android.annotation.SystemApi;
@@ -27,6 +28,8 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
@@ -34,7 +37,7 @@ import java.util.EnumMap;
import java.util.Locale;
/**
- * Describes the state of any Wifi connection that is active or
+ * Describes the state of any Wi-Fi connection that is active or
* is in the process of being set up.
*/
public class WifiInfo implements Parcelable {
@@ -96,6 +99,47 @@ public class WifiInfo implements Parcelable {
private int mRssi;
/**
+ * Wi-Fi unknown technology
+ */
+ public static final int WIFI_TECHNOLOGY_UNKNOWN = 0;
+
+ /**
+ * Wi-Fi 802.11a/b/g
+ */
+ public static final int WIFI_TECHNOLOGY_LEGACY = 1;
+
+ /**
+ * Wi-Fi 802.11n
+ */
+ public static final int WIFI_TECHNOLOGY_11N = 4;
+
+ /**
+ * Wi-Fi 802.11ac
+ */
+ public static final int WIFI_TECHNOLOGY_11AC = 5;
+
+ /**
+ * Wi-Fi 802.11ax
+ */
+ public static final int WIFI_TECHNOLOGY_11AX = 6;
+
+ /** @hide */
+ @IntDef(prefix = { "WIFI_TECHNOLOGY_" }, value = {
+ WIFI_TECHNOLOGY_UNKNOWN,
+ WIFI_TECHNOLOGY_LEGACY,
+ WIFI_TECHNOLOGY_11N,
+ WIFI_TECHNOLOGY_11AC,
+ WIFI_TECHNOLOGY_11AX
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface WifiTechnology{}
+
+ /**
+ * Wi-Fi technology for the connection
+ */
+ private @WifiTechnology int mWifiTechnology;
+
+ /**
* The unit in which links speeds are expressed.
*/
public static final String LINK_SPEED_UNITS = "Mbps";
@@ -301,6 +345,7 @@ public class WifiInfo implements Parcelable {
txSuccessRate = source.txSuccessRate;
rxSuccessRate = source.rxSuccessRate;
score = source.score;
+ mWifiTechnology = source.mWifiTechnology;
}
}
@@ -389,6 +434,22 @@ public class WifiInfo implements Parcelable {
}
/**
+ * Sets the Wi-Fi technology
+ * @hide
+ */
+ public void setWifiTechnology(@WifiTechnology int wifiTechnology) {
+ mWifiTechnology = wifiTechnology;
+ }
+
+ /**
+ * Get connection Wi-Fi technology
+ * @return the connection Wi-Fi technology
+ */
+ public @WifiTechnology int getWifiTechnology() {
+ return mWifiTechnology;
+ }
+
+ /**
* Returns the current link speed in {@link #LINK_SPEED_UNITS}.
* @return the link speed or {@link #LINK_SPEED_UNKNOWN} if link speed is unknown.
* @see #LINK_SPEED_UNITS
@@ -727,6 +788,7 @@ public class WifiInfo implements Parcelable {
.append(", Wifi Generation: ").append(mWifiGeneration)
.append(", TWT support: ").append(mTwtSupport)
.append(", Eight Max VHT Spatial streams support: ").append(mVhtMax8SpatialStreamsSupport)
+ .append(", Wi-Fi technology: ").append(mWifiTechnology)
.append(", RSSI: ").append(mRssi)
.append(", Link speed: ").append(mLinkSpeed).append(LINK_SPEED_UNITS)
.append(", Tx Link speed: ").append(mTxLinkSpeed).append(LINK_SPEED_UNITS)
@@ -785,6 +847,7 @@ public class WifiInfo implements Parcelable {
dest.writeInt(mWifiGeneration);
dest.writeInt(mVhtMax8SpatialStreamsSupport ? 1 : 0);
dest.writeInt(mTwtSupport ? 1 : 0);
+ dest.writeInt(mWifiTechnology);
}
/** Implement the Parcelable interface {@hide} */
@@ -829,6 +892,7 @@ public class WifiInfo implements Parcelable {
info.mWifiGeneration = in.readInt();
info.mVhtMax8SpatialStreamsSupport = in.readInt() != 0;
info.mTwtSupport = in.readInt() != 0;
+ info.mWifiTechnology = in.readInt();
return info;
}
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 026c6a8ec7d6..6d382eef6808 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -38,6 +38,7 @@ import android.net.DhcpInfo;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
+import android.net.NetworkStack;
import android.net.wifi.hotspot2.IProvisioningCallback;
import android.net.wifi.hotspot2.OsuProvider;
import android.net.wifi.hotspot2.PasspointConfiguration;
@@ -45,23 +46,19 @@ import android.net.wifi.hotspot2.ProvisioningCallback;
import android.os.Binder;
import android.os.Build;
import android.os.Handler;
+import android.os.HandlerExecutor;
import android.os.IBinder;
import android.os.Looper;
-import android.os.Message;
-import android.os.Messenger;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.WorkSource;
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
-import android.util.SparseArray;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
-import com.android.internal.util.AsyncChannel;
-import com.android.internal.util.Protocol;
import com.android.server.net.NetworkPinner;
import dalvik.system.CloseGuard;
@@ -75,7 +72,6 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
/**
@@ -566,7 +562,9 @@ public class WifiManager {
*
* @hide
*/
- public static final String EXTRA_WIFI_AP_INTERFACE_NAME = "wifi_ap_interface_name";
+ @SystemApi
+ public static final String EXTRA_WIFI_AP_INTERFACE_NAME =
+ "android.net.wifi.extra.WIFI_AP_INTERFACE_NAME";
/**
* The intended ip mode for this softap.
* @see #IFACE_IP_MODE_TETHERED
@@ -574,7 +572,8 @@ public class WifiManager {
*
* @hide
*/
- public static final String EXTRA_WIFI_AP_MODE = "wifi_ap_mode";
+ @SystemApi
+ public static final String EXTRA_WIFI_AP_MODE = "android.net.wifi.extra.WIFI_AP_MODE";
/** @hide */
@IntDef(flag = false, prefix = { "WIFI_AP_STATE_" }, value = {
@@ -680,6 +679,7 @@ public class WifiManager {
*
* @hide
*/
+ @SystemApi
public static final int IFACE_IP_MODE_UNSPECIFIED = -1;
/**
@@ -689,6 +689,7 @@ public class WifiManager {
*
* @hide
*/
+ @SystemApi
public static final int IFACE_IP_MODE_CONFIGURATION_ERROR = 0;
/**
@@ -698,6 +699,7 @@ public class WifiManager {
*
* @hide
*/
+ @SystemApi
public static final int IFACE_IP_MODE_TETHERED = 1;
/**
@@ -707,6 +709,7 @@ public class WifiManager {
*
* @hide
*/
+ @SystemApi
public static final int IFACE_IP_MODE_LOCAL_ONLY = 2;
/**
@@ -1204,26 +1207,9 @@ public class WifiManager {
IWifiManager mService;
private final int mTargetSdkVersion;
- private static final int INVALID_KEY = 0;
- private int mListenerKey = 1;
- private final SparseArray mListenerMap = new SparseArray();
- private final Object mListenerMapLock = new Object();
-
- private AsyncChannel mAsyncChannel;
- private CountDownLatch mConnected;
private Looper mLooper;
private boolean mVerboseLoggingEnabled = false;
- /* LocalOnlyHotspot callback message types */
- /** @hide */
- public static final int HOTSPOT_STARTED = 0;
- /** @hide */
- public static final int HOTSPOT_STOPPED = 1;
- /** @hide */
- public static final int HOTSPOT_FAILED = 2;
- /** @hide */
- public static final int HOTSPOT_OBSERVER_REGISTERED = 3;
-
private final Object mLock = new Object(); // lock guarding access to the following vars
@GuardedBy("mLock")
private LocalOnlyHotspotCallbackProxy mLOHSCallbackProxy;
@@ -1991,12 +1977,13 @@ public class WifiManager {
}
/**
- * Remove the Passpoint configuration identified by its FQDN (Fully Qualified Domain Name).
+ * Remove the Passpoint configuration identified by its FQDN (Fully Qualified Domain Name) added
+ * by the caller.
*
- * @param fqdn The FQDN of the Passpoint configuration to be removed
+ * @param fqdn The FQDN of the Passpoint configuration added by the caller to be removed
* @throws IllegalArgumentException if no configuration is associated with the given FQDN or
* Passpoint is not enabled on the device.
- * @deprecated This is no longer supported.
+ * @deprecated This will be non-functional in a future release.
*/
@Deprecated
@RequiresPermission(anyOf = {
@@ -2020,12 +2007,12 @@ public class WifiManager {
}
/**
- * Return the list of installed Passpoint configurations.
+ * Return the list of installed Passpoint configurations added by the caller.
*
* An empty list will be returned when no configurations are installed.
*
- * @return A list of {@link PasspointConfiguration}
- * @deprecated This is no longer supported.
+ * @return A list of {@link PasspointConfiguration} added by the caller
+ * @deprecated This will be non-functional in a future release.
*/
@Deprecated
@RequiresPermission(anyOf = {
@@ -2658,25 +2645,6 @@ public class WifiManager {
}
/**
- * Set the country code.
- * @param countryCode country code in ISO 3166 format.
- *
- * @hide
- */
- public void setCountryCode(@NonNull String country) {
- try {
- IWifiManager iWifiManager = getIWifiManager();
- if (iWifiManager == null) {
- if (TextUtils.isEmpty(country)) return;
- throw new RemoteException("Wifi service is not running");
- }
- iWifiManager.setCountryCode(country);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
* get the country code.
* @return the country code in ISO 3166 format.
*
@@ -2801,8 +2769,23 @@ public class WifiManager {
*
* @hide for CTS test only
*/
- public void getTxPacketCount(TxPacketCountListener listener) {
- getChannel().sendMessage(RSSI_PKTCNT_FETCH, 0, putListener(listener));
+ public void getTxPacketCount(@NonNull TxPacketCountListener listener) {
+ if (listener == null) throw new IllegalArgumentException("listener cannot be null");
+ Binder binder = new Binder();
+ TxPacketCountListenerProxy listenerProxy =
+ new TxPacketCountListenerProxy(mLooper, listener);
+ try {
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) {
+ throw new RemoteException("Wifi service is not running");
+ }
+ iWifiManager.getTxPacketCount(mContext.getOpPackageName(), binder, listenerProxy,
+ listener.hashCode());
+ } catch (RemoteException e) {
+ listenerProxy.onFailure(ERROR);
+ } catch (SecurityException e) {
+ listenerProxy.onFailure(NOT_AUTHORIZED);
+ }
}
/**
@@ -2843,16 +2826,21 @@ public class WifiManager {
/**
* Call allowing ConnectivityService to update WifiService with interface mode changes.
*
- * The possible modes include: {@link #IFACE_IP_MODE_TETHERED},
- * {@link #IFACE_IP_MODE_LOCAL_ONLY},
- * {@link #IFACE_IP_MODE_CONFIGURATION_ERROR}
- *
- * @param ifaceName String name of the updated interface
- * @param mode int representing the new mode
+ * @param ifaceName String name of the updated interface, or null to represent all interfaces
+ * @param mode int representing the new mode, one of:
+ * {@link #IFACE_IP_MODE_TETHERED},
+ * {@link #IFACE_IP_MODE_LOCAL_ONLY},
+ * {@link #IFACE_IP_MODE_CONFIGURATION_ERROR},
+ * {@link #IFACE_IP_MODE_UNSPECIFIED}
*
* @hide
*/
- public void updateInterfaceIpState(String ifaceName, int mode) {
+ @SystemApi
+ @RequiresPermission(anyOf = {
+ android.Manifest.permission.NETWORK_STACK,
+ NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK
+ })
+ public void updateInterfaceIpState(@Nullable String ifaceName, @IfaceIpMode int mode) {
try {
IWifiManager iWifiManager = getIWifiManager();
if (iWifiManager == null) {
@@ -2875,6 +2863,11 @@ public class WifiManager {
*
* @hide
*/
+ @SystemApi
+ @RequiresPermission(anyOf = {
+ android.Manifest.permission.NETWORK_STACK,
+ NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK
+ })
public boolean startSoftAp(@Nullable WifiConfiguration wifiConfig) {
try {
IWifiManager iWifiManager = getIWifiManager();
@@ -2892,6 +2885,11 @@ public class WifiManager {
*
* @hide
*/
+ @SystemApi
+ @RequiresPermission(anyOf = {
+ android.Manifest.permission.NETWORK_STACK,
+ NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK
+ })
public boolean stopSoftAp() {
try {
IWifiManager iWifiManager = getIWifiManager();
@@ -2902,6 +2900,13 @@ public class WifiManager {
}
}
+ private Executor executorForHandler(@Nullable Handler handler) {
+ if (handler == null) {
+ return mContext.getMainExecutor();
+ }
+ return new HandlerExecutor(handler);
+ }
+
/**
* Request a local only hotspot that an application can use to communicate between co-located
* devices connected to the created WiFi hotspot. The network created by this method will not
@@ -2959,21 +2964,20 @@ public class WifiManager {
*/
public void startLocalOnlyHotspot(LocalOnlyHotspotCallback callback,
@Nullable Handler handler) {
+ Executor executor = executorForHandler(handler);
synchronized (mLock) {
- Looper looper = (handler == null) ? mContext.getMainLooper() : handler.getLooper();
LocalOnlyHotspotCallbackProxy proxy =
- new LocalOnlyHotspotCallbackProxy(this, looper, callback);
+ new LocalOnlyHotspotCallbackProxy(this, executor, callback);
try {
IWifiManager iWifiManager = getIWifiManager();
if (iWifiManager == null) {
throw new RemoteException("Wifi service is not running");
}
String packageName = mContext.getOpPackageName();
- int returnCode = iWifiManager.startLocalOnlyHotspot(
- proxy.getMessenger(), new Binder(), packageName);
+ int returnCode = iWifiManager.startLocalOnlyHotspot(proxy, packageName);
if (returnCode != LocalOnlyHotspotCallback.REQUEST_REGISTERED) {
// Send message to the proxy to make sure we call back on the correct thread
- proxy.notifyFailed(returnCode);
+ proxy.onHotspotFailed(returnCode);
return;
}
mLOHSCallbackProxy = proxy;
@@ -3051,16 +3055,16 @@ public class WifiManager {
*/
public void watchLocalOnlyHotspot(LocalOnlyHotspotObserver observer,
@Nullable Handler handler) {
+ Executor executor = executorForHandler(handler);
synchronized (mLock) {
- Looper looper = (handler == null) ? mContext.getMainLooper() : handler.getLooper();
- mLOHSObserverProxy = new LocalOnlyHotspotObserverProxy(this, looper, observer);
+ mLOHSObserverProxy =
+ new LocalOnlyHotspotObserverProxy(this, executor, observer);
try {
IWifiManager iWifiManager = getIWifiManager();
if (iWifiManager == null) {
throw new RemoteException("Wifi service is not running");
}
- iWifiManager.startWatchLocalOnlyHotspot(
- mLOHSObserverProxy.getMessenger(), new Binder());
+ iWifiManager.startWatchLocalOnlyHotspot(mLOHSObserverProxy);
mLOHSObserverProxy.registered();
} catch (RemoteException e) {
mLOHSObserverProxy = null;
@@ -3237,76 +3241,6 @@ public class WifiManager {
}
}
- /* TODO: deprecate synchronous API and open up the following API */
-
- private static final int BASE = Protocol.BASE_WIFI_MANAGER;
-
- /* Commands to WifiService */
- /** @hide */
- public static final int CONNECT_NETWORK = BASE + 1;
- /** @hide */
- public static final int CONNECT_NETWORK_FAILED = BASE + 2;
- /** @hide */
- public static final int CONNECT_NETWORK_SUCCEEDED = BASE + 3;
-
- /** @hide */
- public static final int FORGET_NETWORK = BASE + 4;
- /** @hide */
- public static final int FORGET_NETWORK_FAILED = BASE + 5;
- /** @hide */
- public static final int FORGET_NETWORK_SUCCEEDED = BASE + 6;
-
- /** @hide */
- public static final int SAVE_NETWORK = BASE + 7;
- /** @hide */
- public static final int SAVE_NETWORK_FAILED = BASE + 8;
- /** @hide */
- public static final int SAVE_NETWORK_SUCCEEDED = BASE + 9;
-
- /** @hide
- * @deprecated This is deprecated
- */
- public static final int START_WPS = BASE + 10;
- /** @hide
- * @deprecated This is deprecated
- */
- public static final int START_WPS_SUCCEEDED = BASE + 11;
- /** @hide
- * @deprecated This is deprecated
- */
- public static final int WPS_FAILED = BASE + 12;
- /** @hide
- * @deprecated This is deprecated
- */
- public static final int WPS_COMPLETED = BASE + 13;
-
- /** @hide
- * @deprecated This is deprecated
- */
- public static final int CANCEL_WPS = BASE + 14;
- /** @hide
- * @deprecated This is deprecated
- */
- public static final int CANCEL_WPS_FAILED = BASE + 15;
- /** @hide
- * @deprecated This is deprecated
- */
- public static final int CANCEL_WPS_SUCCEDED = BASE + 16;
-
- /** @hide */
- public static final int DISABLE_NETWORK = BASE + 17;
- /** @hide */
- public static final int DISABLE_NETWORK_FAILED = BASE + 18;
- /** @hide */
- public static final int DISABLE_NETWORK_SUCCEEDED = BASE + 19;
-
- /** @hide */
- public static final int RSSI_PKTCNT_FETCH = BASE + 20;
- /** @hide */
- public static final int RSSI_PKTCNT_FETCH_SUCCEEDED = BASE + 21;
- /** @hide */
- public static final int RSSI_PKTCNT_FETCH_FAILED = BASE + 22;
-
/**
* Passed with {@link ActionListener#onFailure}.
* Indicates that the operation failed due to an internal error.
@@ -3329,6 +3263,11 @@ public class WifiManager {
*/
public static final int BUSY = 2;
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({ERROR, IN_PROGRESS, BUSY})
+ public @interface ActionListenerFailureReason {}
+
/* WPS specific errors */
/** WPS overlap detected
* @deprecated This is deprecated
@@ -3373,20 +3312,13 @@ public class WifiManager {
public interface ActionListener {
/**
* The operation succeeded.
- * This is called when the scan request has been validated and ready
- * to sent to driver.
*/
- public void onSuccess();
+ void onSuccess();
/**
* The operation failed.
- * This is called when the scan request failed.
- * @param reason The reason for failure could be one of the following:
- * {@link #REASON_INVALID_REQUEST}} is specified when scan request parameters are invalid.
- * {@link #REASON_NOT_AUTHORIZED} is specified when requesting app doesn't have the required
- * permission to request a scan.
- * {@link #REASON_UNSPECIFIED} is specified when driver reports a scan failure.
+ * @param reason The reason for failure depends on the operation.
*/
- public void onFailure(int reason);
+ void onFailure(@ActionListenerFailureReason int reason);
}
/** Interface for callback invocation on a start WPS action
@@ -3431,6 +3363,41 @@ public class WifiManager {
}
/**
+ * Callback proxy for TxPacketCountListener objects.
+ *
+ * @hide
+ */
+ private class TxPacketCountListenerProxy extends ITxPacketCountListener.Stub {
+ private final Handler mHandler;
+ private final TxPacketCountListener mCallback;
+
+ TxPacketCountListenerProxy(Looper looper, TxPacketCountListener callback) {
+ mHandler = new Handler(looper);
+ mCallback = callback;
+ }
+
+ @Override
+ public void onSuccess(int count) {
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "TxPacketCounterProxy: onSuccess: count=" + count);
+ }
+ mHandler.post(() -> {
+ mCallback.onSuccess(count);
+ });
+ }
+
+ @Override
+ public void onFailure(int reason) {
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "TxPacketCounterProxy: onFailure: reason=" + reason);
+ }
+ mHandler.post(() -> {
+ mCallback.onFailure(reason);
+ });
+ }
+ }
+
+ /**
* Base class for soft AP callback. Should be extended by applications and set when calling
* {@link WifiManager#registerSoftApCallback(SoftApCallback, Handler)}.
*
@@ -3687,82 +3654,58 @@ public class WifiManager {
/**
* Callback proxy for LocalOnlyHotspotCallback objects.
*/
- private static class LocalOnlyHotspotCallbackProxy {
- private final Handler mHandler;
+ private static class LocalOnlyHotspotCallbackProxy extends ILocalOnlyHotspotCallback.Stub {
private final WeakReference<WifiManager> mWifiManager;
- private final Looper mLooper;
- private final Messenger mMessenger;
+ private final Executor mExecutor;
+ private final LocalOnlyHotspotCallback mCallback;
/**
- * Constructs a {@link LocalOnlyHotspotCallback} using the specified looper. All callbacks
- * will be delivered on the thread of the specified looper.
+ * Constructs a {@link LocalOnlyHotspotCallbackProxy} using the specified executor. All
+ * callbacks will run using the given executor.
*
* @param manager WifiManager
- * @param looper Looper for delivering callbacks
+ * @param executor Executor for delivering callbacks.
* @param callback LocalOnlyHotspotCallback to notify the calling application.
*/
- LocalOnlyHotspotCallbackProxy(WifiManager manager, Looper looper,
- final LocalOnlyHotspotCallback callback) {
+ LocalOnlyHotspotCallbackProxy(WifiManager manager, Executor executor,
+ LocalOnlyHotspotCallback callback) {
mWifiManager = new WeakReference<>(manager);
- mLooper = looper;
-
- mHandler = new Handler(looper) {
- @Override
- public void handleMessage(Message msg) {
- Log.d(TAG, "LocalOnlyHotspotCallbackProxy: handle message what: "
- + msg.what + " msg: " + msg);
-
- WifiManager manager = mWifiManager.get();
- if (manager == null) {
- Log.w(TAG, "LocalOnlyHotspotCallbackProxy: handle message post GC");
- return;
- }
+ mExecutor = executor;
+ mCallback = callback;
+ }
- switch (msg.what) {
- case HOTSPOT_STARTED:
- WifiConfiguration config = (WifiConfiguration) msg.obj;
- if (config == null) {
- Log.e(TAG, "LocalOnlyHotspotCallbackProxy: config cannot be null.");
- callback.onFailed(LocalOnlyHotspotCallback.ERROR_GENERIC);
- return;
- }
- callback.onStarted(manager.new LocalOnlyHotspotReservation(config));
- break;
- case HOTSPOT_STOPPED:
- Log.w(TAG, "LocalOnlyHotspotCallbackProxy: hotspot stopped");
- callback.onStopped();
- break;
- case HOTSPOT_FAILED:
- int reasonCode = msg.arg1;
- Log.w(TAG, "LocalOnlyHotspotCallbackProxy: failed to start. reason: "
- + reasonCode);
- callback.onFailed(reasonCode);
- Log.w(TAG, "done with the callback...");
- break;
- default:
- Log.e(TAG, "LocalOnlyHotspotCallbackProxy unhandled message. type: "
- + msg.what);
- }
- }
- };
- mMessenger = new Messenger(mHandler);
+ @Override
+ public void onHotspotStarted(WifiConfiguration config) {
+ WifiManager manager = mWifiManager.get();
+ if (manager == null) return;
+
+ if (config == null) {
+ Log.e(TAG, "LocalOnlyHotspotCallbackProxy: config cannot be null.");
+ onHotspotFailed(LocalOnlyHotspotCallback.ERROR_GENERIC);
+ return;
+ }
+ final LocalOnlyHotspotReservation reservation =
+ manager.new LocalOnlyHotspotReservation(config);
+ mExecutor.execute(() -> mCallback.onStarted(reservation));
}
- public Messenger getMessenger() {
- return mMessenger;
+ @Override
+ public void onHotspotStopped() {
+ WifiManager manager = mWifiManager.get();
+ if (manager == null) return;
+
+ Log.w(TAG, "LocalOnlyHotspotCallbackProxy: hotspot stopped");
+ mExecutor.execute(() -> mCallback.onStopped());
}
- /**
- * Helper method allowing the the incoming application call to move the onFailed callback
- * over to the desired callback thread.
- *
- * @param reason int representing the error type
- */
- public void notifyFailed(int reason) throws RemoteException {
- Message msg = Message.obtain();
- msg.what = HOTSPOT_FAILED;
- msg.arg1 = reason;
- mMessenger.send(msg);
+ @Override
+ public void onHotspotFailed(int reason) {
+ WifiManager manager = mWifiManager.get();
+ if (manager == null) return;
+
+ Log.w(TAG, "LocalOnlyHotspotCallbackProxy: failed to start. reason: "
+ + reason);
+ mExecutor.execute(() -> mCallback.onFailed(reason));
}
}
@@ -3830,191 +3773,115 @@ public class WifiManager {
/**
* Callback proxy for LocalOnlyHotspotObserver objects.
*/
- private static class LocalOnlyHotspotObserverProxy {
- private final Handler mHandler;
+ private static class LocalOnlyHotspotObserverProxy extends ILocalOnlyHotspotCallback.Stub {
private final WeakReference<WifiManager> mWifiManager;
- private final Looper mLooper;
- private final Messenger mMessenger;
+ private final Executor mExecutor;
+ private final LocalOnlyHotspotObserver mObserver;
/**
* Constructs a {@link LocalOnlyHotspotObserverProxy} using the specified looper.
* All callbacks will be delivered on the thread of the specified looper.
*
* @param manager WifiManager
- * @param looper Looper for delivering callbacks
+ * @param executor Executor for delivering callbacks
* @param observer LocalOnlyHotspotObserver to notify the calling application.
*/
- LocalOnlyHotspotObserverProxy(WifiManager manager, Looper looper,
+ LocalOnlyHotspotObserverProxy(WifiManager manager, Executor executor,
final LocalOnlyHotspotObserver observer) {
mWifiManager = new WeakReference<>(manager);
- mLooper = looper;
-
- mHandler = new Handler(looper) {
- @Override
- public void handleMessage(Message msg) {
- Log.d(TAG, "LocalOnlyHotspotObserverProxy: handle message what: "
- + msg.what + " msg: " + msg);
-
- WifiManager manager = mWifiManager.get();
- if (manager == null) {
- Log.w(TAG, "LocalOnlyHotspotObserverProxy: handle message post GC");
- return;
- }
-
- switch (msg.what) {
- case HOTSPOT_OBSERVER_REGISTERED:
- observer.onRegistered(manager.new LocalOnlyHotspotSubscription());
- break;
- case HOTSPOT_STARTED:
- WifiConfiguration config = (WifiConfiguration) msg.obj;
- if (config == null) {
- Log.e(TAG, "LocalOnlyHotspotObserverProxy: config cannot be null.");
- return;
- }
- observer.onStarted(config);
- break;
- case HOTSPOT_STOPPED:
- observer.onStopped();
- break;
- default:
- Log.e(TAG, "LocalOnlyHotspotObserverProxy unhandled message. type: "
- + msg.what);
- }
- }
- };
- mMessenger = new Messenger(mHandler);
- }
-
- public Messenger getMessenger() {
- return mMessenger;
+ mExecutor = executor;
+ mObserver = observer;
}
public void registered() throws RemoteException {
- Message msg = Message.obtain();
- msg.what = HOTSPOT_OBSERVER_REGISTERED;
- mMessenger.send(msg);
- }
- }
+ WifiManager manager = mWifiManager.get();
+ if (manager == null) return;
- // Ensure that multiple ServiceHandler threads do not interleave message dispatch.
- private static final Object sServiceHandlerDispatchLock = new Object();
-
- private class ServiceHandler extends Handler {
- ServiceHandler(Looper looper) {
- super(looper);
+ mExecutor.execute(() ->
+ mObserver.onRegistered(manager.new LocalOnlyHotspotSubscription()));
}
@Override
- public void handleMessage(Message message) {
- synchronized (sServiceHandlerDispatchLock) {
- dispatchMessageToListeners(message);
+ public void onHotspotStarted(WifiConfiguration config) {
+ WifiManager manager = mWifiManager.get();
+ if (manager == null) return;
+
+ if (config == null) {
+ Log.e(TAG, "LocalOnlyHotspotObserverProxy: config cannot be null.");
+ return;
}
+ mExecutor.execute(() -> mObserver.onStarted(config));
}
- private void dispatchMessageToListeners(Message message) {
- Object listener = removeListener(message.arg2);
- switch (message.what) {
- case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
- if (message.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
- mAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
- } else {
- Log.e(TAG, "Failed to set up channel connection");
- // This will cause all further async API calls on the WifiManager
- // to fail and throw an exception
- mAsyncChannel = null;
- }
- mConnected.countDown();
- break;
- case AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED:
- // Ignore
- break;
- case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
- Log.e(TAG, "Channel connection lost");
- // This will cause all further async API calls on the WifiManager
- // to fail and throw an exception
- mAsyncChannel = null;
- getLooper().quit();
- break;
- /* ActionListeners grouped together */
- case WifiManager.CONNECT_NETWORK_FAILED:
- case WifiManager.FORGET_NETWORK_FAILED:
- case WifiManager.SAVE_NETWORK_FAILED:
- case WifiManager.DISABLE_NETWORK_FAILED:
- if (listener != null) {
- ((ActionListener) listener).onFailure(message.arg1);
- }
- break;
- /* ActionListeners grouped together */
- case WifiManager.CONNECT_NETWORK_SUCCEEDED:
- case WifiManager.FORGET_NETWORK_SUCCEEDED:
- case WifiManager.SAVE_NETWORK_SUCCEEDED:
- case WifiManager.DISABLE_NETWORK_SUCCEEDED:
- if (listener != null) {
- ((ActionListener) listener).onSuccess();
- }
- break;
- case WifiManager.RSSI_PKTCNT_FETCH_SUCCEEDED:
- if (listener != null) {
- RssiPacketCountInfo info = (RssiPacketCountInfo) message.obj;
- if (info != null)
- ((TxPacketCountListener) listener).onSuccess(info.txgood + info.txbad);
- else
- ((TxPacketCountListener) listener).onFailure(ERROR);
- }
- break;
- case WifiManager.RSSI_PKTCNT_FETCH_FAILED:
- if (listener != null) {
- ((TxPacketCountListener) listener).onFailure(message.arg1);
- }
- break;
- default:
- //ignore
- break;
- }
+ @Override
+ public void onHotspotStopped() {
+ WifiManager manager = mWifiManager.get();
+ if (manager == null) return;
+
+ mExecutor.execute(() -> mObserver.onStopped());
}
- }
- private int putListener(Object listener) {
- if (listener == null) return INVALID_KEY;
- int key;
- synchronized (mListenerMapLock) {
- do {
- key = mListenerKey++;
- } while (key == INVALID_KEY);
- mListenerMap.put(key, listener);
+ @Override
+ public void onHotspotFailed(int reason) {
+ // do nothing
}
- return key;
}
- private Object removeListener(int key) {
- if (key == INVALID_KEY) return null;
- synchronized (mListenerMapLock) {
- Object listener = mListenerMap.get(key);
- mListenerMap.remove(key);
- return listener;
+ /**
+ * Callback proxy for ActionListener objects.
+ */
+ private class ActionListenerProxy extends IActionListener.Stub {
+ private final String mActionTag;
+ private final Handler mHandler;
+ private final ActionListener mCallback;
+
+ ActionListenerProxy(String actionTag, Looper looper, ActionListener callback) {
+ mActionTag = actionTag;
+ mHandler = new Handler(looper);
+ mCallback = callback;
}
- }
- private synchronized AsyncChannel getChannel() {
- if (mAsyncChannel == null) {
- Messenger messenger = getWifiServiceMessenger();
- if (messenger == null) {
- throw new IllegalStateException(
- "getWifiServiceMessenger() returned null! This is invalid.");
+ @Override
+ public void onSuccess() {
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "ActionListenerProxy:" + mActionTag + ": onSuccess");
}
+ mHandler.post(() -> {
+ mCallback.onSuccess();
+ });
+ }
- mAsyncChannel = new AsyncChannel();
- mConnected = new CountDownLatch(1);
+ @Override
+ public void onFailure(@ActionListenerFailureReason int reason) {
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "ActionListenerProxy:" + mActionTag + ": onFailure=" + reason);
+ }
+ mHandler.post(() -> {
+ mCallback.onFailure(reason);
+ });
+ }
+ }
- Handler handler = new ServiceHandler(mLooper);
- mAsyncChannel.connect(mContext, handler, messenger);
- try {
- mConnected.await();
- } catch (InterruptedException e) {
- Log.e(TAG, "interrupted wait at init");
+ private void connectInternal(@Nullable WifiConfiguration config, int networkId,
+ @Nullable ActionListener listener) {
+ ActionListenerProxy listenerProxy = null;
+ Binder binder = null;
+ if (listener != null) {
+ listenerProxy = new ActionListenerProxy("connect", mLooper, listener);
+ binder = new Binder();
+ }
+ try {
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) {
+ throw new RemoteException("Wifi service is not running");
}
+ iWifiManager.connect(config, networkId, binder, listenerProxy,
+ listener == null ? 0 : listener.hashCode());
+ } catch (RemoteException e) {
+ if (listenerProxy != null) listenerProxy.onFailure(ERROR);
+ } catch (SecurityException e) {
+ if (listenerProxy != null) listenerProxy.onFailure(NOT_AUTHORIZED);
}
- return mAsyncChannel;
}
/**
@@ -4040,10 +3907,7 @@ public class WifiManager {
})
public void connect(@NonNull WifiConfiguration config, @Nullable ActionListener listener) {
if (config == null) throw new IllegalArgumentException("config cannot be null");
- // Use INVALID_NETWORK_ID for arg1 when passing a config object
- // arg1 is used to pass network id when the network already exists
- getChannel().sendMessage(CONNECT_NETWORK, WifiConfiguration.INVALID_NETWORK_ID,
- putListener(listener), config);
+ connectInternal(config, WifiConfiguration.INVALID_NETWORK_ID, listener);
}
/**
@@ -4066,7 +3930,7 @@ public class WifiManager {
})
public void connect(int networkId, @Nullable ActionListener listener) {
if (networkId < 0) throw new IllegalArgumentException("Network id cannot be negative");
- getChannel().sendMessage(CONNECT_NETWORK, networkId, putListener(listener));
+ connectInternal(null, networkId, listener);
}
/**
@@ -4097,7 +3961,24 @@ public class WifiManager {
})
public void save(@NonNull WifiConfiguration config, @Nullable ActionListener listener) {
if (config == null) throw new IllegalArgumentException("config cannot be null");
- getChannel().sendMessage(SAVE_NETWORK, 0, putListener(listener), config);
+ ActionListenerProxy listenerProxy = null;
+ Binder binder = null;
+ if (listener != null) {
+ listenerProxy = new ActionListenerProxy("save", mLooper, listener);
+ binder = new Binder();
+ }
+ try {
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) {
+ throw new RemoteException("Wifi service is not running");
+ }
+ iWifiManager.save(config, binder, listenerProxy,
+ listener == null ? 0 : listener.hashCode());
+ } catch (RemoteException e) {
+ if (listenerProxy != null) listenerProxy.onFailure(ERROR);
+ } catch (SecurityException e) {
+ if (listenerProxy != null) listenerProxy.onFailure(NOT_AUTHORIZED);
+ }
}
/**
@@ -4121,7 +4002,24 @@ public class WifiManager {
})
public void forget(int netId, @Nullable ActionListener listener) {
if (netId < 0) throw new IllegalArgumentException("Network id cannot be negative");
- getChannel().sendMessage(FORGET_NETWORK, netId, putListener(listener));
+ ActionListenerProxy listenerProxy = null;
+ Binder binder = null;
+ if (listener != null) {
+ listenerProxy = new ActionListenerProxy("forget", mLooper, listener);
+ binder = new Binder();
+ }
+ try {
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) {
+ throw new RemoteException("Wifi service is not running");
+ }
+ iWifiManager.forget(netId, binder, listenerProxy,
+ listener == null ? 0 : listener.hashCode());
+ } catch (RemoteException e) {
+ if (listenerProxy != null) listenerProxy.onFailure(ERROR);
+ } catch (SecurityException e) {
+ if (listenerProxy != null) listenerProxy.onFailure(NOT_AUTHORIZED);
+ }
}
/**
@@ -4131,6 +4029,7 @@ public class WifiManager {
* @param listener for callbacks on success or failure. Can be null.
* @throws IllegalStateException if the WifiManager instance needs to be
* initialized again
+ * @deprecated This API is deprecated. Use {@link #disableNetwork(int)} instead.
* @hide
*/
@SystemApi
@@ -4139,9 +4038,19 @@ public class WifiManager {
android.Manifest.permission.NETWORK_SETUP_WIZARD,
android.Manifest.permission.NETWORK_STACK
})
+ @Deprecated
public void disable(int netId, @Nullable ActionListener listener) {
if (netId < 0) throw new IllegalArgumentException("Network id cannot be negative");
- getChannel().sendMessage(DISABLE_NETWORK, netId, putListener(listener));
+ // Simple wrapper which forwards the call to disableNetwork. This is a temporary
+ // implementation until we can remove this API completely.
+ boolean status = disableNetwork(netId);
+ if (listener != null) {
+ if (status) {
+ listener.onSuccess();
+ } else {
+ listener.onFailure(ERROR);
+ }
+ }
}
/**
@@ -4197,24 +4106,6 @@ public class WifiManager {
}
/**
- * Get a reference to WifiService handler. This is used by a client to establish
- * an AsyncChannel communication with WifiService
- *
- * @return Messenger pointing to the WifiService handler
- */
- @UnsupportedAppUsage
- private Messenger getWifiServiceMessenger() {
- try {
- IWifiManager iWifiManager = getIWifiManager();
- if (iWifiManager == null) return null;
- return iWifiManager.getWifiServiceMessenger(mContext.getOpPackageName());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
-
- /**
* Allows an application to keep the Wi-Fi radio awake.
* Normally the Wi-Fi radio may turn off when the user has not used the device in a while.
* Acquiring a WifiLock will keep the radio on until the lock is released. Multiple
@@ -4674,16 +4565,6 @@ public class WifiManager {
}
}
- protected void finalize() throws Throwable {
- try {
- if (mAsyncChannel != null) {
- mAsyncChannel.disconnect();
- }
- } finally {
- super.finalize();
- }
- }
-
/**
* Set wifi verbose log. Called from developer settings.
* @hide
@@ -5643,4 +5524,90 @@ public class WifiManager {
throw e.rethrowFromSystemServer();
}
}
+
+ /**
+ * Base class for scan results listener. Should be implemented by applications and set when
+ * calling {@link WifiManager#addScanResultsListener(Executor, ScanResultsListener)}.
+ */
+ public interface ScanResultsListener {
+
+ /**
+ * Called when new scan results available.
+ * Caller should use {@link WifiManager#getScanResults()} to get the scan results.
+ */
+ void onScanResultsAvailable();
+ }
+
+ private class ScanResultsListenerProxy extends IScanResultsListener.Stub {
+ private final Executor mExecutor;
+ private final ScanResultsListener mListener;
+
+ ScanResultsListenerProxy(Executor executor, ScanResultsListener listener) {
+ mExecutor = executor;
+ mListener = listener;
+ }
+
+ @Override
+ public void onScanResultsAvailable() {
+ mExecutor.execute(mListener::onScanResultsAvailable);
+ }
+ }
+
+ /**
+ * Add a listener for Scan Results. See {@link ScanResultsListener}.
+ * Caller will receive the event when scan results are available.
+ * Caller should use {@link WifiManager#getScanResults()} to get the scan results.
+ * Caller can remove a previously registered listener using
+ * {@link WifiManager#removeScanResultsListener(ScanResultsListener)}
+ * <p>
+ * Applications should have the
+ * {@link android.Manifest.permission#ACCESS_WIFI_STATE} permission. Callers
+ * without the permission will trigger a {@link java.lang.SecurityException}.
+ * <p>
+ *
+ * @param executor The executor to execute the listener of the {@code listener} object.
+ * @param listener listener for Scan Results events
+ */
+
+ @RequiresPermission(ACCESS_WIFI_STATE)
+ public void addScanResultsListener(@NonNull @CallbackExecutor Executor executor,
+ @NonNull ScanResultsListener listener) {
+ if (listener == null) throw new IllegalArgumentException("listener cannot be null");
+ if (executor == null) throw new IllegalArgumentException("executor cannot be null");
+ Log.v(TAG, "addScanResultsListener: listener=" + listener + ", executor=" + executor);
+ try {
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) {
+ throw new RemoteException("Wifi service is not running");
+ }
+ iWifiManager.registerScanResultsListener(
+ new Binder(),
+ new ScanResultsListenerProxy(executor, listener),
+ mContext.getOpPackageName().hashCode());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Allow callers to remove a previously added listener. After calling this method,
+ * applications will no longer receive Scan Results events.
+ *
+ * @param listener listener to remove for Scan Results events
+ */
+ @RequiresPermission(ACCESS_WIFI_STATE)
+ public void removeScanResultsListener(@NonNull ScanResultsListener listener) {
+ if (listener == null) throw new IllegalArgumentException("listener cannot be null");
+ Log.v(TAG, "removeScanResultsListener: listener=" + listener);
+
+ try {
+ IWifiManager iWifiManager = getIWifiManager();
+ if (iWifiManager == null) {
+ throw new RemoteException("Wifi service is not running");
+ }
+ iWifiManager.unregisterScanResultsListener(mContext.getOpPackageName().hashCode());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
}
diff --git a/wifi/java/android/net/wifi/WifiNetworkSpecifier.java b/wifi/java/android/net/wifi/WifiNetworkSpecifier.java
index 6c2d7ff882d3..ba9dd37398a1 100644
--- a/wifi/java/android/net/wifi/WifiNetworkSpecifier.java
+++ b/wifi/java/android/net/wifi/WifiNetworkSpecifier.java
@@ -157,7 +157,8 @@ public final class WifiNetworkSpecifier extends NetworkSpecifier implements Parc
*/
public @NonNull Builder setBssidPattern(
@NonNull MacAddress baseAddress, @NonNull MacAddress mask) {
- checkNotNull(baseAddress, mask);
+ checkNotNull(baseAddress);
+ checkNotNull(mask);
mBssidPatternMatcher = Pair.create(baseAddress, mask);
return this;
}
diff --git a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
index 426201732359..9b529cee58b3 100644
--- a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
+++ b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
@@ -23,6 +23,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityThread;
import android.net.MacAddress;
+import android.net.wifi.hotspot2.PasspointConfiguration;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.Process;
@@ -80,6 +81,10 @@ public final class WifiNetworkSuggestion implements Parcelable {
*/
private @Nullable WifiEnterpriseConfig mWpa3EnterpriseConfig;
/**
+ * The passpoint config for use with Hotspot 2.0 network
+ */
+ private @Nullable PasspointConfiguration mPasspointConfiguration;
+ /**
* This is a network that does not broadcast its SSID, so an
* SSID-specific probe request must be used for scans.
*/
@@ -110,6 +115,7 @@ public final class WifiNetworkSuggestion implements Parcelable {
mWpa3SaePassphrase = null;
mWpa2EnterpriseConfig = null;
mWpa3EnterpriseConfig = null;
+ mPasspointConfiguration = null;
mIsHiddenSSID = false;
mIsAppInteractionRequired = false;
mIsUserInteractionRequired = false;
@@ -234,6 +240,24 @@ public final class WifiNetworkSuggestion implements Parcelable {
}
/**
+ * Set the associated Passpoint configuration for this network. Needed for authenticating
+ * to Hotspot 2.0 networks. See {@link PasspointConfiguration} for description.
+ *
+ * @param passpointConfig Instance of {@link PasspointConfiguration}.
+ * @return Instance of {@link Builder} to enable chaining of the builder method.
+ * @throws IllegalArgumentException if passpoint configuration is invalid.
+ */
+ public @NonNull Builder setPasspointConfig(
+ @NonNull PasspointConfiguration passpointConfig) {
+ checkNotNull(passpointConfig);
+ if (!passpointConfig.validate()) {
+ throw new IllegalArgumentException("Passpoint configuration is invalid");
+ }
+ mPasspointConfiguration = passpointConfig;
+ return this;
+ }
+
+ /**
* Specifies whether this represents a hidden network.
* <p>
* <li>If not set, defaults to false (i.e not a hidden network).</li>
@@ -366,13 +390,24 @@ public final class WifiNetworkSuggestion implements Parcelable {
numSecurityTypes += !TextUtils.isEmpty(mWpa3SaePassphrase) ? 1 : 0;
numSecurityTypes += mWpa2EnterpriseConfig != null ? 1 : 0;
numSecurityTypes += mWpa3EnterpriseConfig != null ? 1 : 0;
+ numSecurityTypes += mPasspointConfiguration != null ? 1 : 0;
if (numSecurityTypes > 1) {
throw new IllegalStateException("only one of setIsEnhancedOpen, setWpa2Passphrase,"
- + "setWpa3Passphrase, setWpa2EnterpriseConfig or setWpa3EnterpriseConfig"
- + " can be invoked for network specifier");
+ + "setWpa3Passphrase, setWpa2EnterpriseConfig, setWpa3EnterpriseConfig"
+ + "or setPasspointConfig can be invoked for network suggestion");
}
}
+ private WifiConfiguration buildWifiConfigurationForPasspoint() {
+ WifiConfiguration wifiConfiguration = new WifiConfiguration();
+ wifiConfiguration.FQDN = mPasspointConfiguration.getHomeSp().getFqdn();
+ wifiConfiguration.priority = mPriority;
+ wifiConfiguration.meteredOverride =
+ mIsMetered ? WifiConfiguration.METERED_OVERRIDE_METERED
+ : WifiConfiguration.METERED_OVERRIDE_NONE;
+ return wifiConfiguration;
+ }
+
/**
* Create a network suggestion object for use in
* {@link WifiManager#addNetworkSuggestions(List)}.
@@ -384,29 +419,36 @@ public final class WifiNetworkSuggestion implements Parcelable {
* </p>
*
* For example:
- * To provide credentials for one open, one WPA2 and one WPA3 network with their
- * corresponding SSID's:
+ * To provide credentials for one open, one WPA2, one WPA3 network with their
+ * corresponding SSID's and one with Passpoint config:
*
* <pre>{@code
* final WifiNetworkSuggestion suggestion1 =
* new Builder()
* .setSsid("test111111")
- * .build()
+ * .build();
* final WifiNetworkSuggestion suggestion2 =
* new Builder()
* .setSsid("test222222")
* .setWpa2Passphrase("test123456")
- * .build()
+ * .build();
* final WifiNetworkSuggestion suggestion3 =
* new Builder()
* .setSsid("test333333")
* .setWpa3Passphrase("test6789")
- * .build()
+ * .build();
+ * final PasspointConfiguration passpointConfig= new PasspointConfiguration();
+ * // configure passpointConfig to include a valid Passpoint configuration
+ * final WifiNetworkSuggestion suggestion4 =
+ * new Builder()
+ * .setPasspointConfig(passpointConfig)
+ * .build();
* final List<WifiNetworkSuggestion> suggestionsList =
* new ArrayList<WifiNetworkSuggestion> { {
* add(suggestion1);
* add(suggestion2);
* add(suggestion3);
+ * add(suggestion4);
* } };
* final WifiManager wifiManager =
* context.getSystemService(Context.WIFI_SERVICE);
@@ -419,21 +461,37 @@ public final class WifiNetworkSuggestion implements Parcelable {
* @see WifiNetworkSuggestion
*/
public @NonNull WifiNetworkSuggestion build() {
- if (mSsid == null) {
- throw new IllegalStateException("setSsid should be invoked for suggestion");
- }
- if (TextUtils.isEmpty(mSsid)) {
- throw new IllegalStateException("invalid ssid for suggestion");
- }
- if (mBssid != null
- && (mBssid.equals(MacAddress.BROADCAST_ADDRESS)
- || mBssid.equals(MacAddress.ALL_ZEROS_ADDRESS))) {
- throw new IllegalStateException("invalid bssid for suggestion");
- }
validateSecurityParams();
+ WifiConfiguration wifiConfiguration;
+ if (mPasspointConfiguration != null) {
+ if (mSsid != null) {
+ throw new IllegalStateException("setSsid should not be invoked for suggestion "
+ + "with Passpoint configuration");
+ }
+ if (mIsHiddenSSID) {
+ throw new IllegalStateException("setIsHiddenSsid should not be invoked for "
+ + "suggestion with Passpoint configuration");
+ }
+ wifiConfiguration = buildWifiConfigurationForPasspoint();
+
+ } else {
+ if (mSsid == null) {
+ throw new IllegalStateException("setSsid should be invoked for suggestion");
+ }
+ if (TextUtils.isEmpty(mSsid)) {
+ throw new IllegalStateException("invalid ssid for suggestion");
+ }
+ if (mBssid != null
+ && (mBssid.equals(MacAddress.BROADCAST_ADDRESS)
+ || mBssid.equals(MacAddress.ALL_ZEROS_ADDRESS))) {
+ throw new IllegalStateException("invalid bssid for suggestion");
+ }
+ wifiConfiguration = buildWifiConfiguration();
+ }
return new WifiNetworkSuggestion(
- buildWifiConfiguration(),
+ wifiConfiguration,
+ mPasspointConfiguration,
mIsAppInteractionRequired,
mIsUserInteractionRequired,
Process.myUid(),
@@ -448,6 +506,12 @@ public final class WifiNetworkSuggestion implements Parcelable {
public final WifiConfiguration wifiConfiguration;
/**
+ * Passpoint configuration for the provided network.
+ * @hide
+ */
+ public final PasspointConfiguration passpointConfiguration;
+
+ /**
* Whether app needs to log in to captive portal to obtain Internet access.
* @hide
*/
@@ -474,6 +538,7 @@ public final class WifiNetworkSuggestion implements Parcelable {
/** @hide */
public WifiNetworkSuggestion() {
this.wifiConfiguration = null;
+ this.passpointConfiguration = null;
this.isAppInteractionRequired = false;
this.isUserInteractionRequired = false;
this.suggestorUid = -1;
@@ -481,14 +546,16 @@ public final class WifiNetworkSuggestion implements Parcelable {
}
/** @hide */
- public WifiNetworkSuggestion(@NonNull WifiConfiguration wifiConfiguration,
+ public WifiNetworkSuggestion(@NonNull WifiConfiguration networkConfiguration,
+ @Nullable PasspointConfiguration passpointConfiguration,
boolean isAppInteractionRequired,
boolean isUserInteractionRequired,
int suggestorUid, @NonNull String suggestorPackageName) {
- checkNotNull(wifiConfiguration);
+ checkNotNull(networkConfiguration);
checkNotNull(suggestorPackageName);
+ this.wifiConfiguration = networkConfiguration;
+ this.passpointConfiguration = passpointConfiguration;
- this.wifiConfiguration = wifiConfiguration;
this.isAppInteractionRequired = isAppInteractionRequired;
this.isUserInteractionRequired = isUserInteractionRequired;
this.suggestorUid = suggestorUid;
@@ -501,6 +568,7 @@ public final class WifiNetworkSuggestion implements Parcelable {
public WifiNetworkSuggestion createFromParcel(Parcel in) {
return new WifiNetworkSuggestion(
in.readParcelable(null), // wifiConfiguration
+ in.readParcelable(null), // PasspointConfiguration
in.readBoolean(), // isAppInteractionRequired
in.readBoolean(), // isUserInteractionRequired
in.readInt(), // suggestorUid
@@ -522,6 +590,7 @@ public final class WifiNetworkSuggestion implements Parcelable {
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeParcelable(wifiConfiguration, flags);
+ dest.writeParcelable(passpointConfiguration, flags);
dest.writeBoolean(isAppInteractionRequired);
dest.writeBoolean(isUserInteractionRequired);
dest.writeInt(suggestorUid);
@@ -531,7 +600,8 @@ public final class WifiNetworkSuggestion implements Parcelable {
@Override
public int hashCode() {
return Objects.hash(wifiConfiguration.SSID, wifiConfiguration.BSSID,
- wifiConfiguration.allowedKeyManagement, suggestorUid, suggestorPackageName);
+ wifiConfiguration.allowedKeyManagement, wifiConfiguration.FQDN,
+ suggestorUid, suggestorPackageName);
}
/**
@@ -546,12 +616,17 @@ public final class WifiNetworkSuggestion implements Parcelable {
return false;
}
WifiNetworkSuggestion lhs = (WifiNetworkSuggestion) obj;
- return Objects.equals(this.wifiConfiguration.SSID, lhs.wifiConfiguration.SSID)
- && Objects.equals(this.wifiConfiguration.BSSID, lhs.wifiConfiguration.BSSID)
+ if (this.passpointConfiguration == null ^ lhs.passpointConfiguration == null) {
+ return false;
+ }
+
+ return TextUtils.equals(this.wifiConfiguration.SSID, lhs.wifiConfiguration.SSID)
+ && TextUtils.equals(this.wifiConfiguration.BSSID, lhs.wifiConfiguration.BSSID)
&& Objects.equals(this.wifiConfiguration.allowedKeyManagement,
- lhs.wifiConfiguration.allowedKeyManagement)
- && suggestorUid == lhs.suggestorUid
- && TextUtils.equals(suggestorPackageName, lhs.suggestorPackageName);
+ lhs.wifiConfiguration.allowedKeyManagement)
+ && TextUtils.equals(this.wifiConfiguration.FQDN, lhs.wifiConfiguration.FQDN)
+ && this.suggestorUid == lhs.suggestorUid
+ && TextUtils.equals(this.suggestorPackageName, lhs.suggestorPackageName);
}
@Override
@@ -559,6 +634,7 @@ public final class WifiNetworkSuggestion implements Parcelable {
StringBuilder sb = new StringBuilder("WifiNetworkSuggestion [")
.append(", SSID=").append(wifiConfiguration.SSID)
.append(", BSSID=").append(wifiConfiguration.BSSID)
+ .append(", FQDN=").append(wifiConfiguration.FQDN)
.append(", isAppInteractionRequired=").append(isAppInteractionRequired)
.append(", isUserInteractionRequired=").append(isUserInteractionRequired)
.append(", suggestorUid=").append(suggestorUid)
diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java
index 075531ce158e..68948cbbe7a9 100644
--- a/wifi/java/android/net/wifi/WifiScanner.java
+++ b/wifi/java/android/net/wifi/WifiScanner.java
@@ -17,6 +17,7 @@
package android.net.wifi;
import android.Manifest;
+import android.annotation.NonNull;
import android.annotation.RequiresPermission;
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
@@ -58,13 +59,23 @@ public class WifiScanner {
/** 5 GHz band excluding DFS channels */
public static final int WIFI_BAND_5_GHZ = 2; /* 5 GHz band without DFS channels */
/** DFS channels from 5 GHz band only */
- public static final int WIFI_BAND_5_GHZ_DFS_ONLY = 4; /* 5 GHz band with DFS channels */
+ public static final int WIFI_BAND_5_GHZ_DFS_ONLY = 4; /* 5 GHz band DFS channels */
+ /**
+ * 2.4Ghz band + DFS channels from 5 GHz band only
+ * @hide
+ */
+ public static final int WIFI_BAND_24_GHZ_WITH_5GHZ_DFS = 5;
/** 5 GHz band including DFS channels */
public static final int WIFI_BAND_5_GHZ_WITH_DFS = 6; /* 5 GHz band with DFS channels */
/** Both 2.4 GHz band and 5 GHz band; no DFS channels */
public static final int WIFI_BAND_BOTH = 3; /* both bands without DFS channels */
/** Both 2.4 GHz band and 5 GHz band; with DFS channels */
public static final int WIFI_BAND_BOTH_WITH_DFS = 7; /* both bands with DFS channels */
+ /**
+ * Max band value
+ * @hide
+ */
+ public static final int WIFI_BAND_MAX = 8;
/** Minimum supported scanning period */
public static final int MIN_SCAN_PERIOD_MS = 1000; /* minimum supported period */
@@ -375,19 +386,27 @@ public class WifiScanner {
*/
private int mBandScanned;
/** all scan results discovered in this scan, sorted by timestamp in ascending order */
- private ScanResult mResults[];
+ private final List<ScanResult> mResults;
- ScanData() {}
+ ScanData() {
+ mResults = new ArrayList<>();
+ }
public ScanData(int id, int flags, ScanResult[] results) {
mId = id;
mFlags = flags;
- mResults = results;
+ mResults = new ArrayList<>(Arrays.asList(results));
}
/** {@hide} */
public ScanData(int id, int flags, int bucketsScanned, int bandScanned,
ScanResult[] results) {
+ this(id, flags, bucketsScanned, bandScanned, new ArrayList<>(Arrays.asList(results)));
+ }
+
+ /** {@hide} */
+ public ScanData(int id, int flags, int bucketsScanned, int bandScanned,
+ List<ScanResult> results) {
mId = id;
mFlags = flags;
mBucketsScanned = bucketsScanned;
@@ -400,11 +419,9 @@ public class WifiScanner {
mFlags = s.mFlags;
mBucketsScanned = s.mBucketsScanned;
mBandScanned = s.mBandScanned;
- mResults = new ScanResult[s.mResults.length];
- for (int i = 0; i < s.mResults.length; i++) {
- ScanResult result = s.mResults[i];
- ScanResult newResult = new ScanResult(result);
- mResults[i] = newResult;
+ mResults = new ArrayList<>();
+ for (ScanResult scanResult : s.mResults) {
+ mResults.add(new ScanResult(scanResult));
}
}
@@ -427,7 +444,14 @@ public class WifiScanner {
}
public ScanResult[] getResults() {
- return mResults;
+ return mResults.toArray(new ScanResult[0]);
+ }
+
+ /** {@hide} */
+ public void addResults(@NonNull ScanResult[] newResults) {
+ for (ScanResult result : newResults) {
+ mResults.add(new ScanResult(result));
+ }
}
/** Implement the Parcelable interface {@hide} */
@@ -437,19 +461,11 @@ public class WifiScanner {
/** Implement the Parcelable interface {@hide} */
public void writeToParcel(Parcel dest, int flags) {
- if (mResults != null) {
- dest.writeInt(mId);
- dest.writeInt(mFlags);
- dest.writeInt(mBucketsScanned);
- dest.writeInt(mBandScanned);
- dest.writeInt(mResults.length);
- for (int i = 0; i < mResults.length; i++) {
- ScanResult result = mResults[i];
- result.writeToParcel(dest, flags);
- }
- } else {
- dest.writeInt(0);
- }
+ dest.writeInt(mId);
+ dest.writeInt(mFlags);
+ dest.writeInt(mBucketsScanned);
+ dest.writeInt(mBandScanned);
+ dest.writeParcelableList(mResults, 0);
}
/** Implement the Parcelable interface {@hide} */
@@ -460,11 +476,8 @@ public class WifiScanner {
int flags = in.readInt();
int bucketsScanned = in.readInt();
int bandScanned = in.readInt();
- int n = in.readInt();
- ScanResult results[] = new ScanResult[n];
- for (int i = 0; i < n; i++) {
- results[i] = ScanResult.CREATOR.createFromParcel(in);
- }
+ List<ScanResult> results = new ArrayList<>();
+ in.readParcelableList(results, ScanResult.class.getClassLoader());
return new ScanData(id, flags, bucketsScanned, bandScanned, results);
}
diff --git a/wifi/java/android/net/wifi/WifiUsabilityStatsEntry.java b/wifi/java/android/net/wifi/WifiUsabilityStatsEntry.java
index e59516485112..8f3635fd2f04 100644
--- a/wifi/java/android/net/wifi/WifiUsabilityStatsEntry.java
+++ b/wifi/java/android/net/wifi/WifiUsabilityStatsEntry.java
@@ -20,8 +20,8 @@ import android.annotation.IntDef;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
-import android.telephony.TelephonyManager.NetworkType;
+import android.telephony.Annotation.NetworkType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
diff --git a/wifi/java/android/net/wifi/hotspot2/ConfigParser.java b/wifi/java/android/net/wifi/hotspot2/ConfigParser.java
index e8e873199e17..bb01365d6722 100644
--- a/wifi/java/android/net/wifi/hotspot2/ConfigParser.java
+++ b/wifi/java/android/net/wifi/hotspot2/ConfigParser.java
@@ -182,6 +182,12 @@ public final class ConfigParser {
throw new IOException("Passpoint profile missing credential");
}
+ // Don't allow the installer to make changes to the update identifier. This is an
+ // indicator of an R2 (or newer) network.
+ if (config.getUpdateIdentifier() != Integer.MIN_VALUE) {
+ config.setUpdateIdentifier(Integer.MIN_VALUE);
+ }
+
// Parse CA (Certificate Authority) certificate.
byte[] caCertData = mimeParts.get(TYPE_CA_CERT);
if (caCertData != null) {
diff --git a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
index 557b7c9b05e9..e9aa076798e1 100644
--- a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
+++ b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
@@ -65,6 +65,7 @@ public final class PasspointConfiguration implements Parcelable {
* Configurations under HomeSp subtree.
*/
private HomeSp mHomeSp = null;
+
/**
* Set the Home SP (Service Provider) information.
*
@@ -248,7 +249,10 @@ public final class PasspointConfiguration implements Parcelable {
mSubscriptionExpirationTimeInMillis = subscriptionExpirationTimeInMillis;
}
/**
- * @hide
+ * Utility method to get the time this subscription will expire. It is in the format of number
+ * of milliseconds since January 1, 1970, 00:00:00 GMT.
+ *
+ * @return The time this subscription will expire, or Long.MIN_VALUE to indicate unset value
*/
public long getSubscriptionExpirationTimeInMillis() {
return mSubscriptionExpirationTimeInMillis;
@@ -521,6 +525,8 @@ public final class PasspointConfiguration implements Parcelable {
.append("\n");
builder.append("UsageLimitDataLimit: ").append(mUsageLimitDataLimit).append("\n");
builder.append("UsageLimitTimeLimit: ").append(mUsageLimitTimeLimitInMinutes).append("\n");
+ builder.append("Provisioned by a subscription server: ")
+ .append(isOsuProvisioned() ? "Yes" : "No").append("\n");
if (mHomeSp != null) {
builder.append("HomeSP Begin ---\n");
builder.append(mHomeSp);
@@ -728,4 +734,14 @@ public final class PasspointConfiguration implements Parcelable {
}
return true;
}
+
+ /**
+ * Indicates if the Passpoint Configuration was provisioned by a subscription (OSU) server,
+ * which means that it's an R2 (or R3) profile.
+ *
+ * @return true if the Passpoint Configuration was provisioned by a subscription server.
+ */
+ public boolean isOsuProvisioned() {
+ return getUpdateIdentifier() != Integer.MIN_VALUE;
+ }
}
diff --git a/wifi/java/com/android/server/wifi/BaseWifiService.java b/wifi/java/com/android/server/wifi/BaseWifiService.java
index 03eb169f60b9..300f1a28416b 100644
--- a/wifi/java/com/android/server/wifi/BaseWifiService.java
+++ b/wifi/java/com/android/server/wifi/BaseWifiService.java
@@ -21,11 +21,15 @@ package com.android.server.wifi;
import android.content.pm.ParceledListSlice;
import android.net.DhcpInfo;
import android.net.Network;
+import android.net.wifi.IActionListener;
import android.net.wifi.IDppCallback;
+import android.net.wifi.ILocalOnlyHotspotCallback;
import android.net.wifi.INetworkRequestMatchCallback;
import android.net.wifi.IOnWifiUsabilityStatsListener;
+import android.net.wifi.IScanResultsListener;
import android.net.wifi.ISoftApCallback;
import android.net.wifi.ITrafficStateCallback;
+import android.net.wifi.ITxPacketCountListener;
import android.net.wifi.IWifiManager;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiActivityEnergyInfo;
@@ -205,11 +209,6 @@ public class BaseWifiService extends IWifiManager.Stub {
}
@Override
- public void setCountryCode(String country) {
- throw new UnsupportedOperationException();
- }
-
- @Override
public String getCountryCode() {
throw new UnsupportedOperationException();
}
@@ -284,22 +283,34 @@ public class BaseWifiService extends IWifiManager.Stub {
throw new UnsupportedOperationException();
}
- @Override
+ /** @deprecated replaced by {@link #startLocalOnlyHotspot(ILocalOnlyHotspotCallback, String)} */
+ @Deprecated
public int startLocalOnlyHotspot(Messenger messenger, IBinder binder, String packageName) {
throw new UnsupportedOperationException();
}
@Override
- public void stopLocalOnlyHotspot() {
+ public int startLocalOnlyHotspot(ILocalOnlyHotspotCallback callback, String packageName) {
throw new UnsupportedOperationException();
}
@Override
+ public void stopLocalOnlyHotspot() {
+ throw new UnsupportedOperationException();
+ }
+
+ /** @deprecated replaced by {@link #startWatchLocalOnlyHotspot(ILocalOnlyHotspotCallback)} */
+ @Deprecated
public void startWatchLocalOnlyHotspot(Messenger messenger, IBinder binder) {
throw new UnsupportedOperationException();
}
@Override
+ public void startWatchLocalOnlyHotspot(ILocalOnlyHotspotCallback callback) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
public void stopWatchLocalOnlyHotspot() {
throw new UnsupportedOperationException();
}
@@ -325,11 +336,6 @@ public class BaseWifiService extends IWifiManager.Stub {
}
@Override
- public Messenger getWifiServiceMessenger(String packageName) {
- throw new UnsupportedOperationException();
- }
-
- @Override
public void enableTdls(String remoteIPAddress, boolean enable) {
throw new UnsupportedOperationException();
}
@@ -494,6 +500,41 @@ public class BaseWifiService extends IWifiManager.Stub {
}
@Override
+ public void connect(WifiConfiguration config, int netId, IBinder binder,
+ IActionListener callback, int callbackIdentifier) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void save(WifiConfiguration config, IBinder binder, IActionListener callback,
+ int callbackIdentifier) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void forget(int netId, IBinder binder, IActionListener callback,
+ int callbackIdentifier) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void getTxPacketCount(String packageName, IBinder binder,
+ ITxPacketCountListener callback, int callbackIdentifier) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void registerScanResultsListener(
+ IBinder binder, IScanResultsListener listener, int listenerIdentifier) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void unregisterScanResultsListener(int listenerIdentifier) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
public boolean isWifiCoverageExtendFeatureEnabled() {
throw new UnsupportedOperationException();
}