[WIFICOND] Formalize the wificond AIDL interface
The wificond daemon provides an interface for the framework to interact with the operating system when managing Wi-Fi. Since wificond is outside the mainline module, the AIDL interface has to be formalized as an API surface. Bug: 140062898 Test: atest android.net.wifi Test: atest com.android.server.wifi.aware Test: (CTS) atest android.net.wifi.cts Test: scan, association, SoftAP operations manually tested, kill wificond Change-Id: Iee0fef6a454fdd84b1d0c59516d4746ddc2a4ce5
This commit is contained in:
@@ -6208,6 +6208,130 @@ package android.net.wifi.rtt {
|
||||
|
||||
}
|
||||
|
||||
package android.net.wifi.wificond {
|
||||
|
||||
public final class NativeScanResult implements android.os.Parcelable {
|
||||
method public int describeContents();
|
||||
method @NonNull public byte[] getBssid();
|
||||
method @NonNull public java.util.BitSet getCapabilities();
|
||||
method public int getFrequencyMhz();
|
||||
method @NonNull public byte[] getInformationElements();
|
||||
method @NonNull public java.util.List<android.net.wifi.wificond.RadioChainInfo> getRadioChainInfos();
|
||||
method public int getSignalMbm();
|
||||
method @NonNull public byte[] getSsid();
|
||||
method public long getTsf();
|
||||
method public boolean isAssociated();
|
||||
method public void writeToParcel(@NonNull android.os.Parcel, int);
|
||||
field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.wificond.NativeScanResult> CREATOR;
|
||||
}
|
||||
|
||||
public final class NativeWifiClient implements android.os.Parcelable {
|
||||
method public int describeContents();
|
||||
method public void writeToParcel(@NonNull android.os.Parcel, int);
|
||||
field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.wificond.NativeWifiClient> CREATOR;
|
||||
field @NonNull public final byte[] macAddress;
|
||||
}
|
||||
|
||||
public final class PnoNetwork implements android.os.Parcelable {
|
||||
ctor public PnoNetwork();
|
||||
method public int describeContents();
|
||||
method @NonNull public int[] getFrequenciesMhz();
|
||||
method @NonNull public byte[] getSsid();
|
||||
method public boolean isHidden();
|
||||
method public void setFrequenciesMhz(@NonNull int[]);
|
||||
method public void setHidden(boolean);
|
||||
method public void setSsid(@NonNull byte[]);
|
||||
method public void writeToParcel(@NonNull android.os.Parcel, int);
|
||||
field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.wificond.PnoNetwork> CREATOR;
|
||||
}
|
||||
|
||||
public final class PnoSettings implements android.os.Parcelable {
|
||||
ctor public PnoSettings();
|
||||
method public int describeContents();
|
||||
method public int getIntervalMillis();
|
||||
method public int getMin2gRssiDbm();
|
||||
method public int getMin5gRssiDbm();
|
||||
method public int getMin6gRssiDbm();
|
||||
method @NonNull public java.util.List<android.net.wifi.wificond.PnoNetwork> getPnoNetworks();
|
||||
method public void setIntervalMillis(int);
|
||||
method public void setMin2gRssiDbm(int);
|
||||
method public void setMin5gRssiDbm(int);
|
||||
method public void setMin6gRssiDbm(int);
|
||||
method public void setPnoNetworks(@NonNull java.util.List<android.net.wifi.wificond.PnoNetwork>);
|
||||
method public void writeToParcel(@NonNull android.os.Parcel, int);
|
||||
field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.wificond.PnoSettings> CREATOR;
|
||||
}
|
||||
|
||||
public final class RadioChainInfo implements android.os.Parcelable {
|
||||
method public int describeContents();
|
||||
method public int getChainId();
|
||||
method public int getLevelDbm();
|
||||
method public void writeToParcel(@NonNull android.os.Parcel, int);
|
||||
field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.wificond.RadioChainInfo> CREATOR;
|
||||
}
|
||||
|
||||
public class WifiCondManager {
|
||||
method public void abortScan(@NonNull String);
|
||||
method public void enableVerboseLogging(boolean);
|
||||
method @NonNull public int[] getChannelsMhzForBand(int);
|
||||
method @NonNull public java.util.List<android.net.wifi.wificond.NativeScanResult> getScanResults(@NonNull String, int);
|
||||
method @Nullable public android.net.wifi.wificond.WifiCondManager.TxPacketCounters getTxPacketCounters(@NonNull String);
|
||||
method public boolean initialize(@NonNull Runnable);
|
||||
method public boolean registerApCallback(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.wificond.WifiCondManager.SoftApCallback);
|
||||
method public void sendMgmtFrame(@NonNull String, @NonNull byte[], int, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.wificond.WifiCondManager.SendMgmtFrameCallback);
|
||||
method public boolean setupInterfaceForClientMode(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.wificond.WifiCondManager.ScanEventCallback, @NonNull android.net.wifi.wificond.WifiCondManager.ScanEventCallback);
|
||||
method public boolean setupInterfaceForSoftApMode(@NonNull String);
|
||||
method @Nullable public android.net.wifi.wificond.WifiCondManager.SignalPollResult signalPoll(@NonNull String);
|
||||
method public boolean startPnoScan(@NonNull String, @NonNull android.net.wifi.wificond.PnoSettings, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.wificond.WifiCondManager.PnoScanRequestCallback);
|
||||
method public boolean startScan(@NonNull String, int, @Nullable java.util.Set<java.lang.Integer>, @Nullable java.util.List<byte[]>);
|
||||
method public boolean stopPnoScan(@NonNull String);
|
||||
method public boolean tearDownClientInterface(@NonNull String);
|
||||
method public boolean tearDownInterfaces();
|
||||
method public boolean tearDownSoftApInterface(@NonNull String);
|
||||
field public static final int SCAN_TYPE_PNO_SCAN = 1; // 0x1
|
||||
field public static final int SCAN_TYPE_SINGLE_SCAN = 0; // 0x0
|
||||
field public static final int SEND_MGMT_FRAME_ERROR_ALREADY_STARTED = 5; // 0x5
|
||||
field public static final int SEND_MGMT_FRAME_ERROR_MCS_UNSUPPORTED = 2; // 0x2
|
||||
field public static final int SEND_MGMT_FRAME_ERROR_NO_ACK = 3; // 0x3
|
||||
field public static final int SEND_MGMT_FRAME_ERROR_TIMEOUT = 4; // 0x4
|
||||
field public static final int SEND_MGMT_FRAME_ERROR_UNKNOWN = 1; // 0x1
|
||||
}
|
||||
|
||||
public static interface WifiCondManager.PnoScanRequestCallback {
|
||||
method public void onPnoRequestFailed();
|
||||
method public void onPnoRequestSucceeded();
|
||||
}
|
||||
|
||||
public static interface WifiCondManager.ScanEventCallback {
|
||||
method public void onScanFailed();
|
||||
method public void onScanResultReady();
|
||||
}
|
||||
|
||||
public static interface WifiCondManager.SendMgmtFrameCallback {
|
||||
method public void onAck(int);
|
||||
method public void onFailure(int);
|
||||
}
|
||||
|
||||
public static class WifiCondManager.SignalPollResult {
|
||||
field public final int associationFrequencyMHz;
|
||||
field public final int currentRssiDbm;
|
||||
field public final int rxBitrateMbps;
|
||||
field public final int txBitrateMbps;
|
||||
}
|
||||
|
||||
public static interface WifiCondManager.SoftApCallback {
|
||||
method public void onConnectedClientsChanged(@NonNull android.net.wifi.wificond.NativeWifiClient, boolean);
|
||||
method public void onFailure();
|
||||
method public void onSoftApChannelSwitched(int, int);
|
||||
}
|
||||
|
||||
public static class WifiCondManager.TxPacketCounters {
|
||||
field public final int txPacketFailed;
|
||||
field public final int txPacketSucceeded;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
package android.nfc {
|
||||
|
||||
public final class NfcAdapter {
|
||||
|
||||
@@ -24,6 +24,11 @@ ExecutorRegistration: android.net.wifi.p2p.WifiP2pManager#setWfdInfo(android.net
|
||||
ExecutorRegistration: android.net.wifi.p2p.WifiP2pManager#setWifiP2pChannels(android.net.wifi.p2p.WifiP2pManager.Channel, int, int, android.net.wifi.p2p.WifiP2pManager.ActionListener):
|
||||
Registration methods should have overload that accepts delivery Executor: `setWifiP2pChannels`
|
||||
|
||||
HeavyBitSet: android.net.wifi.wificond.NativeScanResult#getCapabilities():
|
||||
Type must not be heavy BitSet (method android.net.wifi.wificond.NativeScanResult.getCapabilities())
|
||||
PairedRegistration: android.net.wifi.wificond.WifiCondManager#registerApCallback(String, java.util.concurrent.Executor, android.net.wifi.wificond.WifiCondManager.SoftApCallback):
|
||||
Found registerApCallback but not unregisterApCallback in android.net.wifi.wificond.WifiCondManager
|
||||
|
||||
|
||||
GenericException: android.app.prediction.AppPredictor#finalize():
|
||||
|
||||
|
||||
@@ -120,8 +120,8 @@ import android.net.lowpan.ILowpanManager;
|
||||
import android.net.lowpan.LowpanManager;
|
||||
import android.net.nsd.INsdManager;
|
||||
import android.net.nsd.NsdManager;
|
||||
import android.net.wifi.WifiCondManager;
|
||||
import android.net.wifi.WifiFrameworkInitializer;
|
||||
import android.net.wifi.wificond.WifiCondManager;
|
||||
import android.nfc.NfcManager;
|
||||
import android.os.BatteryManager;
|
||||
import android.os.BatteryStats;
|
||||
|
||||
@@ -32,7 +32,6 @@ filegroup {
|
||||
// framework-wifi.jar. This is not a good idea, should move WifiNetworkScoreCache
|
||||
// to a separate package.
|
||||
"java/android/net/wifi/WifiNetworkScoreCache.java",
|
||||
"java/android/net/wifi/WifiCondManager.java",
|
||||
"java/android/net/wifi/wificond/*.java",
|
||||
":libwificond_ipc_aidl",
|
||||
],
|
||||
|
||||
@@ -16,15 +16,12 @@
|
||||
|
||||
package android.net.wifi;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.SystemApi;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
@@ -85,26 +82,12 @@ public final class SoftApInfo implements Parcelable {
|
||||
*/
|
||||
public static final int CHANNEL_WIDTH_160MHZ = 6;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@IntDef(prefix = { "CHANNEL_WIDTH_" }, value = {
|
||||
CHANNEL_WIDTH_INVALID,
|
||||
CHANNEL_WIDTH_20MHZ_NOHT,
|
||||
CHANNEL_WIDTH_20MHZ,
|
||||
CHANNEL_WIDTH_40MHZ,
|
||||
CHANNEL_WIDTH_80MHZ,
|
||||
CHANNEL_WIDTH_80MHZ_PLUS_MHZ,
|
||||
CHANNEL_WIDTH_160MHZ,
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface Bandwidth {}
|
||||
|
||||
|
||||
/** The frequency which AP resides on. */
|
||||
private int mFrequency = 0;
|
||||
|
||||
@Bandwidth
|
||||
@WifiAnnotations.Bandwidth
|
||||
private int mBandwidth = CHANNEL_WIDTH_INVALID;
|
||||
|
||||
/**
|
||||
@@ -127,9 +110,9 @@ public final class SoftApInfo implements Parcelable {
|
||||
*
|
||||
* @return One of {@link #CHANNEL_WIDTH_20MHZ}, {@link #CHANNEL_WIDTH_40MHZ},
|
||||
* {@link #CHANNEL_WIDTH_80MHZ}, {@link #CHANNEL_WIDTH_160MHZ},
|
||||
* {@link #CHANNEL_WIDTH_80MHZ_PLUS_MHZ} or {@link #CHANNEL_WIDTH_UNKNOWN}.
|
||||
* {@link #CHANNEL_WIDTH_80MHZ_PLUS_MHZ} or {@link #CHANNEL_WIDTH_INVALID}.
|
||||
*/
|
||||
@Bandwidth
|
||||
@WifiAnnotations.Bandwidth
|
||||
public int getBandwidth() {
|
||||
return mBandwidth;
|
||||
}
|
||||
@@ -138,7 +121,7 @@ public final class SoftApInfo implements Parcelable {
|
||||
* Set AP Channel bandwidth.
|
||||
* @hide
|
||||
*/
|
||||
public void setBandwidth(@Bandwidth int bandwidth) {
|
||||
public void setBandwidth(@WifiAnnotations.Bandwidth int bandwidth) {
|
||||
mBandwidth = bandwidth;
|
||||
}
|
||||
|
||||
|
||||
@@ -48,4 +48,16 @@ public final class WifiAnnotations {
|
||||
WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY,
|
||||
WifiScanner.WIFI_BAND_6_GHZ})
|
||||
public @interface WifiBandBasic {}
|
||||
|
||||
@IntDef(prefix = { "CHANNEL_WIDTH_" }, value = {
|
||||
SoftApInfo.CHANNEL_WIDTH_INVALID,
|
||||
SoftApInfo.CHANNEL_WIDTH_20MHZ_NOHT,
|
||||
SoftApInfo.CHANNEL_WIDTH_20MHZ,
|
||||
SoftApInfo.CHANNEL_WIDTH_40MHZ,
|
||||
SoftApInfo.CHANNEL_WIDTH_80MHZ,
|
||||
SoftApInfo.CHANNEL_WIDTH_80MHZ_PLUS_MHZ,
|
||||
SoftApInfo.CHANNEL_WIDTH_160MHZ,
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface Bandwidth {}
|
||||
}
|
||||
|
||||
@@ -16,46 +16,163 @@
|
||||
|
||||
package android.net.wifi.wificond;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.SystemApi;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.BitSet;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* ScanResult from wificond
|
||||
* Raw scan result data from the wificond daemon.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public class NativeScanResult implements Parcelable {
|
||||
@SystemApi
|
||||
public final class NativeScanResult implements Parcelable {
|
||||
private static final int CAPABILITY_SIZE = 16;
|
||||
|
||||
/** @hide */
|
||||
@VisibleForTesting
|
||||
public byte[] ssid;
|
||||
/** @hide */
|
||||
@VisibleForTesting
|
||||
public byte[] bssid;
|
||||
/** @hide */
|
||||
@VisibleForTesting
|
||||
public byte[] infoElement;
|
||||
/** @hide */
|
||||
@VisibleForTesting
|
||||
public int frequency;
|
||||
/** @hide */
|
||||
@VisibleForTesting
|
||||
public int signalMbm;
|
||||
/** @hide */
|
||||
@VisibleForTesting
|
||||
public long tsf;
|
||||
/** @hide */
|
||||
@VisibleForTesting
|
||||
public BitSet capability;
|
||||
/** @hide */
|
||||
@VisibleForTesting
|
||||
public boolean associated;
|
||||
/** @hide */
|
||||
@VisibleForTesting
|
||||
public List<RadioChainInfo> radioChainInfos;
|
||||
|
||||
/** public constructor */
|
||||
public NativeScanResult() { }
|
||||
|
||||
/** copy constructor */
|
||||
public NativeScanResult(NativeScanResult source) {
|
||||
ssid = source.ssid.clone();
|
||||
bssid = source.bssid.clone();
|
||||
infoElement = source.infoElement.clone();
|
||||
frequency = source.frequency;
|
||||
signalMbm = source.signalMbm;
|
||||
tsf = source.tsf;
|
||||
capability = (BitSet) source.capability.clone();
|
||||
associated = source.associated;
|
||||
/**
|
||||
* Returns the SSID raw byte array of the AP represented by this scan result.
|
||||
*
|
||||
* @return A byte array.
|
||||
*/
|
||||
@NonNull public byte[] getSsid() {
|
||||
return ssid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns raw bytes representing the MAC address (BSSID) of the AP represented by this scan
|
||||
* result.
|
||||
*
|
||||
* @return a byte array, possibly null or containing the incorrect number of bytes for a MAC
|
||||
* address.
|
||||
*/
|
||||
@NonNull public byte[] getBssid() {
|
||||
return bssid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw bytes of the information element advertised by the AP represented by this
|
||||
* scan result.
|
||||
*
|
||||
* @return A byte array, possibly null or containing an invalid TLV configuration.
|
||||
*/
|
||||
@NonNull public byte[] getInformationElements() {
|
||||
return infoElement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the frequency (in MHz) on which the AP represented by this scan result was observed.
|
||||
*
|
||||
* @return The frequency in MHz.
|
||||
*/
|
||||
public int getFrequencyMhz() {
|
||||
return frequency;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the signal strength of probe response/beacon in (100 * dBm).
|
||||
*
|
||||
* @return Signal strenght in (100 * dBm).
|
||||
*/
|
||||
public int getSignalMbm() {
|
||||
return signalMbm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the TSF (Timing Synchronization Function) of the received probe response/beacon.
|
||||
* @return
|
||||
*/
|
||||
public long getTsf() {
|
||||
return tsf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a boolean indicating whether or not we're associated to the AP represented by this
|
||||
* scan result.
|
||||
*
|
||||
* @return A boolean indicating association.
|
||||
*/
|
||||
public boolean isAssociated() {
|
||||
return associated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the capabilities of the AP repseresented by this scan result as advertised in the
|
||||
* received probe response or beacon.
|
||||
*
|
||||
* This is a bit mask describing the capabilities of a BSS. See IEEE Std 802.11: 8.4.1.4:
|
||||
* Bit 0 - ESS
|
||||
* Bit 1 - IBSS
|
||||
* Bit 2 - CF Pollable
|
||||
* Bit 3 - CF-Poll Request
|
||||
* Bit 4 - Privacy
|
||||
* Bit 5 - Short Preamble
|
||||
* Bit 6 - PBCC
|
||||
* Bit 7 - Channel Agility
|
||||
* Bit 8 - Spectrum Mgmt
|
||||
* Bit 9 - QoS
|
||||
* Bit 10 - Short Slot Time
|
||||
* Bit 11 - APSD
|
||||
* Bit 12 - Radio Measurement
|
||||
* Bit 13 - DSSS-OFDM
|
||||
* Bit 14 - Delayed Block Ack
|
||||
* Bit 15 - Immediate Block Ack
|
||||
*
|
||||
* @return a bit mask of capabilities.
|
||||
*/
|
||||
@NonNull public BitSet getCapabilities() {
|
||||
return capability;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns details of the signal received on each radio chain for the AP represented by this
|
||||
* scan result in a list of {@link RadioChainInfo} elements.
|
||||
*
|
||||
* @return A list of {@link RadioChainInfo} - possibly empty in case of error.
|
||||
*/
|
||||
@NonNull public List<RadioChainInfo> getRadioChainInfos() {
|
||||
return radioChainInfos;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public NativeScanResult() { }
|
||||
|
||||
/** implement Parcelable interface */
|
||||
@Override
|
||||
public int describeContents() {
|
||||
@@ -64,7 +181,7 @@ public class NativeScanResult implements Parcelable {
|
||||
|
||||
/** implement Parcelable interface */
|
||||
@Override
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
public void writeToParcel(@NonNull Parcel out, int flags) {
|
||||
out.writeByteArray(ssid);
|
||||
out.writeByteArray(bssid);
|
||||
out.writeByteArray(infoElement);
|
||||
@@ -83,14 +200,23 @@ public class NativeScanResult implements Parcelable {
|
||||
}
|
||||
|
||||
/** implement Parcelable interface */
|
||||
public static final Parcelable.Creator<NativeScanResult> CREATOR =
|
||||
@NonNull public static final Parcelable.Creator<NativeScanResult> CREATOR =
|
||||
new Parcelable.Creator<NativeScanResult>() {
|
||||
@Override
|
||||
public NativeScanResult createFromParcel(Parcel in) {
|
||||
NativeScanResult result = new NativeScanResult();
|
||||
result.ssid = in.createByteArray();
|
||||
if (result.ssid == null) {
|
||||
result.ssid = new byte[0];
|
||||
}
|
||||
result.bssid = in.createByteArray();
|
||||
if (result.bssid == null) {
|
||||
result.bssid = new byte[0];
|
||||
}
|
||||
result.infoElement = in.createByteArray();
|
||||
if (result.infoElement == null) {
|
||||
result.infoElement = new byte[0];
|
||||
}
|
||||
result.frequency = in.readInt();
|
||||
result.signalMbm = in.readInt();
|
||||
result.tsf = in.readLong();
|
||||
|
||||
@@ -16,21 +16,32 @@
|
||||
|
||||
package android.net.wifi.wificond;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.SystemApi;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* NativeWifiClient for wificond
|
||||
* Structure providing information about clients (STAs) associated with a SoftAp.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public class NativeWifiClient implements Parcelable {
|
||||
public byte[] macAddress;
|
||||
@SystemApi
|
||||
public final class NativeWifiClient implements Parcelable {
|
||||
/**
|
||||
* The raw bytes of the MAC address of the client (STA) represented by this object.
|
||||
*/
|
||||
@NonNull public final byte[] macAddress;
|
||||
|
||||
/** public constructor */
|
||||
public NativeWifiClient() { }
|
||||
/**
|
||||
* public constructor
|
||||
* @hide
|
||||
*/
|
||||
public NativeWifiClient(@NonNull byte[] macAddress) {
|
||||
this.macAddress = macAddress;
|
||||
}
|
||||
|
||||
/** override comparator */
|
||||
@Override
|
||||
@@ -60,18 +71,20 @@ public class NativeWifiClient implements Parcelable {
|
||||
* |flag| is ignored.
|
||||
*/
|
||||
@Override
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
public void writeToParcel(@NonNull Parcel out, int flags) {
|
||||
out.writeByteArray(macAddress);
|
||||
}
|
||||
|
||||
/** implement Parcelable interface */
|
||||
public static final Parcelable.Creator<NativeWifiClient> CREATOR =
|
||||
@NonNull public static final Parcelable.Creator<NativeWifiClient> CREATOR =
|
||||
new Parcelable.Creator<NativeWifiClient>() {
|
||||
@Override
|
||||
public NativeWifiClient createFromParcel(Parcel in) {
|
||||
NativeWifiClient result = new NativeWifiClient();
|
||||
result.macAddress = in.createByteArray();
|
||||
return result;
|
||||
byte[] macAddress = in.createByteArray();
|
||||
if (macAddress == null) {
|
||||
macAddress = new byte[0];
|
||||
}
|
||||
return new NativeWifiClient(macAddress);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package android.net.wifi.wificond;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.SystemApi;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
@@ -23,17 +25,85 @@ import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* PnoNetwork for wificond
|
||||
* Configuration for a PNO (preferred network offload) network used in {@link PnoSettings}. A PNO
|
||||
* network allows configuration of a specific network to search for.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public class PnoNetwork implements Parcelable {
|
||||
@SystemApi
|
||||
public final class PnoNetwork implements Parcelable {
|
||||
private boolean mIsHidden;
|
||||
private byte[] mSsid;
|
||||
private int[] mFrequencies;
|
||||
|
||||
public boolean isHidden;
|
||||
public byte[] ssid;
|
||||
public int[] frequencies;
|
||||
/**
|
||||
* Indicates whether the PNO network configuration is for a hidden SSID - i.e. a network which
|
||||
* does not broadcast its SSID and must be queried explicitly.
|
||||
*
|
||||
* @return True if the configuration is for a hidden network, false otherwise.
|
||||
*/
|
||||
public boolean isHidden() {
|
||||
return mIsHidden;
|
||||
}
|
||||
|
||||
/** public constructor */
|
||||
/**
|
||||
* Configure whether the PNO network configuration is for a hidden SSID - i.e. a network which
|
||||
* does not broadcast its SSID and must be queried explicitly.
|
||||
*
|
||||
* @param isHidden True if the configuration is for a hidden network, false otherwise.
|
||||
*/
|
||||
public void setHidden(boolean isHidden) {
|
||||
mIsHidden = isHidden;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the raw bytes for the SSID of the PNO network being scanned for.
|
||||
*
|
||||
* @return A byte array.
|
||||
*/
|
||||
@NonNull public byte[] getSsid() {
|
||||
return mSsid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the raw bytes for the SSID of the PNO network being scanned for.
|
||||
*
|
||||
* @param ssid A byte array.
|
||||
*/
|
||||
public void setSsid(@NonNull byte[] ssid) {
|
||||
if (ssid == null) {
|
||||
throw new IllegalArgumentException("null argument");
|
||||
}
|
||||
this.mSsid = ssid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the frequencies (in MHz) on which to PNO scan for the current network is being searched
|
||||
* for. A null return (i.e. no frequencies configured) indicates that the network is search for
|
||||
* on all supported frequencies.
|
||||
*
|
||||
* @return A array of frequencies (in MHz), a null indicates no configured frequencies.
|
||||
*/
|
||||
@NonNull public int[] getFrequenciesMhz() {
|
||||
return mFrequencies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the frequencies (in MHz) on which to PNO scan for the current network is being searched
|
||||
* for. A null configuration (i.e. no frequencies configured) indicates that the network is
|
||||
* search for on all supported frequencies.
|
||||
*
|
||||
* @param frequenciesMhz an array of frequencies (in MHz), null indicating no configured
|
||||
* frequencies.
|
||||
*/
|
||||
public void setFrequenciesMhz(@NonNull int[] frequenciesMhz) {
|
||||
if (frequenciesMhz == null) {
|
||||
throw new IllegalArgumentException("null argument");
|
||||
}
|
||||
this.mFrequencies = frequenciesMhz;
|
||||
}
|
||||
|
||||
/** Construct an uninitialized PnoNetwork object */
|
||||
public PnoNetwork() { }
|
||||
|
||||
/** override comparator */
|
||||
@@ -44,18 +114,18 @@ public class PnoNetwork implements Parcelable {
|
||||
return false;
|
||||
}
|
||||
PnoNetwork network = (PnoNetwork) rhs;
|
||||
return Arrays.equals(ssid, network.ssid)
|
||||
&& Arrays.equals(frequencies, network.frequencies)
|
||||
&& isHidden == network.isHidden;
|
||||
return Arrays.equals(mSsid, network.mSsid)
|
||||
&& Arrays.equals(mFrequencies, network.mFrequencies)
|
||||
&& mIsHidden == network.mIsHidden;
|
||||
}
|
||||
|
||||
/** override hash code */
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(
|
||||
isHidden,
|
||||
Arrays.hashCode(ssid),
|
||||
Arrays.hashCode(frequencies));
|
||||
mIsHidden,
|
||||
Arrays.hashCode(mSsid),
|
||||
Arrays.hashCode(mFrequencies));
|
||||
}
|
||||
|
||||
/** implement Parcelable interface */
|
||||
@@ -69,21 +139,27 @@ public class PnoNetwork implements Parcelable {
|
||||
* |flag| is ignored.
|
||||
*/
|
||||
@Override
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
out.writeInt(isHidden ? 1 : 0);
|
||||
out.writeByteArray(ssid);
|
||||
out.writeIntArray(frequencies);
|
||||
public void writeToParcel(@NonNull Parcel out, int flags) {
|
||||
out.writeInt(mIsHidden ? 1 : 0);
|
||||
out.writeByteArray(mSsid);
|
||||
out.writeIntArray(mFrequencies);
|
||||
}
|
||||
|
||||
/** implement Parcelable interface */
|
||||
public static final Parcelable.Creator<PnoNetwork> CREATOR =
|
||||
@NonNull public static final Parcelable.Creator<PnoNetwork> CREATOR =
|
||||
new Parcelable.Creator<PnoNetwork>() {
|
||||
@Override
|
||||
public PnoNetwork createFromParcel(Parcel in) {
|
||||
PnoNetwork result = new PnoNetwork();
|
||||
result.isHidden = in.readInt() != 0 ? true : false;
|
||||
result.ssid = in.createByteArray();
|
||||
result.frequencies = in.createIntArray();
|
||||
result.mIsHidden = in.readInt() != 0 ? true : false;
|
||||
result.mSsid = in.createByteArray();
|
||||
if (result.mSsid == null) {
|
||||
result.mSsid = new byte[0];
|
||||
}
|
||||
result.mFrequencies = in.createIntArray();
|
||||
if (result.mFrequencies == null) {
|
||||
result.mFrequencies = new int[0];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,27 +16,130 @@
|
||||
|
||||
package android.net.wifi.wificond;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.SystemApi;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* PnoSettings for wificond
|
||||
* Configuration for a PNO (preferred network offload). A mechanism by which scans are offloaded
|
||||
* from the host device to the Wi-Fi chip.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public class PnoSettings implements Parcelable {
|
||||
public int intervalMs;
|
||||
public int min2gRssi;
|
||||
public int min5gRssi;
|
||||
public int min6gRssi;
|
||||
public ArrayList<PnoNetwork> pnoNetworks;
|
||||
@SystemApi
|
||||
public final class PnoSettings implements Parcelable {
|
||||
private int mIntervalMs;
|
||||
private int mMin2gRssi;
|
||||
private int mMin5gRssi;
|
||||
private int mMin6gRssi;
|
||||
private List<PnoNetwork> mPnoNetworks;
|
||||
|
||||
/** public constructor */
|
||||
/** Construct an uninitialized PnoSettings object */
|
||||
public PnoSettings() { }
|
||||
|
||||
/**
|
||||
* Get the requested PNO scan interval in milliseconds.
|
||||
*
|
||||
* @return An interval in milliseconds.
|
||||
*/
|
||||
public int getIntervalMillis() {
|
||||
return mIntervalMs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the requested PNO scan interval in milliseconds.
|
||||
*
|
||||
* @param intervalMs An interval in milliseconds.
|
||||
*/
|
||||
public void setIntervalMillis(int intervalMs) {
|
||||
this.mIntervalMs = intervalMs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the requested minimum RSSI threshold (in dBm) for APs to report in scan results in the
|
||||
* 2.4GHz band.
|
||||
*
|
||||
* @return An RSSI value in dBm.
|
||||
*/
|
||||
public int getMin2gRssiDbm() {
|
||||
return mMin2gRssi;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the requested minimum RSSI threshold (in dBm) for APs to report in scan scan results in
|
||||
* the 2.4GHz band.
|
||||
*
|
||||
* @param min2gRssiDbm An RSSI value in dBm.
|
||||
*/
|
||||
public void setMin2gRssiDbm(int min2gRssiDbm) {
|
||||
this.mMin2gRssi = min2gRssiDbm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the requested minimum RSSI threshold (in dBm) for APs to report in scan results in the
|
||||
* 5GHz band.
|
||||
*
|
||||
* @return An RSSI value in dBm.
|
||||
*/
|
||||
public int getMin5gRssiDbm() {
|
||||
return mMin5gRssi;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the requested minimum RSSI threshold (in dBm) for APs to report in scan scan results in
|
||||
* the 5GHz band.
|
||||
*
|
||||
* @param min5gRssiDbm An RSSI value in dBm.
|
||||
*/
|
||||
public void setMin5gRssiDbm(int min5gRssiDbm) {
|
||||
this.mMin5gRssi = min5gRssiDbm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the requested minimum RSSI threshold (in dBm) for APs to report in scan results in the
|
||||
* 6GHz band.
|
||||
*
|
||||
* @return An RSSI value in dBm.
|
||||
*/
|
||||
public int getMin6gRssiDbm() {
|
||||
return mMin6gRssi;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the requested minimum RSSI threshold (in dBm) for APs to report in scan scan results in
|
||||
* the 6GHz band.
|
||||
*
|
||||
* @param min6gRssiDbm An RSSI value in dBm.
|
||||
*/
|
||||
public void setMin6gRssiDbm(int min6gRssiDbm) {
|
||||
this.mMin6gRssi = min6gRssiDbm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the configured list of specific networks to search for in a PNO scan.
|
||||
*
|
||||
* @return A list of {@link PnoNetwork} objects, possibly empty if non configured.
|
||||
*/
|
||||
@NonNull public List<PnoNetwork> getPnoNetworks() {
|
||||
return mPnoNetworks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the list of specified networks to scan for in a PNO scan. The networks (APs) are
|
||||
* specified using {@link PnoNetwork}s. An empty list indicates that all networks are scanned
|
||||
* for.
|
||||
*
|
||||
* @param pnoNetworks A (possibly empty) list of {@link PnoNetwork} objects.
|
||||
*/
|
||||
public void setPnoNetworks(@NonNull List<PnoNetwork> pnoNetworks) {
|
||||
this.mPnoNetworks = pnoNetworks;
|
||||
}
|
||||
|
||||
/** override comparator */
|
||||
@Override
|
||||
public boolean equals(Object rhs) {
|
||||
@@ -48,17 +151,17 @@ public class PnoSettings implements Parcelable {
|
||||
if (settings == null) {
|
||||
return false;
|
||||
}
|
||||
return intervalMs == settings.intervalMs
|
||||
&& min2gRssi == settings.min2gRssi
|
||||
&& min5gRssi == settings.min5gRssi
|
||||
&& min6gRssi == settings.min6gRssi
|
||||
&& pnoNetworks.equals(settings.pnoNetworks);
|
||||
return mIntervalMs == settings.mIntervalMs
|
||||
&& mMin2gRssi == settings.mMin2gRssi
|
||||
&& mMin5gRssi == settings.mMin5gRssi
|
||||
&& mMin6gRssi == settings.mMin6gRssi
|
||||
&& mPnoNetworks.equals(settings.mPnoNetworks);
|
||||
}
|
||||
|
||||
/** override hash code */
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(intervalMs, min2gRssi, min5gRssi, min6gRssi, pnoNetworks);
|
||||
return Objects.hash(mIntervalMs, mMin2gRssi, mMin5gRssi, mMin6gRssi, mPnoNetworks);
|
||||
}
|
||||
|
||||
/** implement Parcelable interface */
|
||||
@@ -72,27 +175,27 @@ public class PnoSettings implements Parcelable {
|
||||
* |flag| is ignored.
|
||||
**/
|
||||
@Override
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
out.writeInt(intervalMs);
|
||||
out.writeInt(min2gRssi);
|
||||
out.writeInt(min5gRssi);
|
||||
out.writeInt(min6gRssi);
|
||||
out.writeTypedList(pnoNetworks);
|
||||
public void writeToParcel(@NonNull Parcel out, int flags) {
|
||||
out.writeInt(mIntervalMs);
|
||||
out.writeInt(mMin2gRssi);
|
||||
out.writeInt(mMin5gRssi);
|
||||
out.writeInt(mMin6gRssi);
|
||||
out.writeTypedList(mPnoNetworks);
|
||||
}
|
||||
|
||||
/** implement Parcelable interface */
|
||||
public static final Parcelable.Creator<PnoSettings> CREATOR =
|
||||
@NonNull public static final Parcelable.Creator<PnoSettings> CREATOR =
|
||||
new Parcelable.Creator<PnoSettings>() {
|
||||
@Override
|
||||
public PnoSettings createFromParcel(Parcel in) {
|
||||
PnoSettings result = new PnoSettings();
|
||||
result.intervalMs = in.readInt();
|
||||
result.min2gRssi = in.readInt();
|
||||
result.min5gRssi = in.readInt();
|
||||
result.min6gRssi = in.readInt();
|
||||
result.mIntervalMs = in.readInt();
|
||||
result.mMin2gRssi = in.readInt();
|
||||
result.mMin5gRssi = in.readInt();
|
||||
result.mMin6gRssi = in.readInt();
|
||||
|
||||
result.pnoNetworks = new ArrayList<PnoNetwork>();
|
||||
in.readTypedList(result.pnoNetworks, PnoNetwork.CREATOR);
|
||||
result.mPnoNetworks = new ArrayList<>();
|
||||
in.readTypedList(result.mPnoNetworks, PnoNetwork.CREATOR);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -16,26 +16,52 @@
|
||||
|
||||
package android.net.wifi.wificond;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.SystemApi;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* RadioChainInfo for wificond
|
||||
* A class representing the radio chains of the Wi-Fi modems. Use to provide raw information about
|
||||
* signals received on different radio chains.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public class RadioChainInfo implements Parcelable {
|
||||
@SystemApi
|
||||
public final class RadioChainInfo implements Parcelable {
|
||||
private static final String TAG = "RadioChainInfo";
|
||||
|
||||
/** @hide */
|
||||
@VisibleForTesting
|
||||
public int chainId;
|
||||
/** @hide */
|
||||
@VisibleForTesting
|
||||
public int level;
|
||||
|
||||
/**
|
||||
* Return an identifier for this radio chain. This is an arbitrary ID which is consistent for
|
||||
* the same device.
|
||||
*
|
||||
* @return The radio chain ID.
|
||||
*/
|
||||
public int getChainId() {
|
||||
return chainId;
|
||||
}
|
||||
|
||||
/** public constructor */
|
||||
public RadioChainInfo() { }
|
||||
/**
|
||||
* Returns the detected signal level on this radio chain in dBm (aka RSSI).
|
||||
*
|
||||
* @return A signal level in dBm.
|
||||
*/
|
||||
public int getLevelDbm() {
|
||||
return level;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public RadioChainInfo(int chainId, int level) {
|
||||
this.chainId = chainId;
|
||||
this.level = level;
|
||||
@@ -73,23 +99,20 @@ public class RadioChainInfo implements Parcelable {
|
||||
* |flags| is ignored.
|
||||
*/
|
||||
@Override
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
public void writeToParcel(@NonNull Parcel out, int flags) {
|
||||
out.writeInt(chainId);
|
||||
out.writeInt(level);
|
||||
}
|
||||
|
||||
/** implement Parcelable interface */
|
||||
public static final Parcelable.Creator<RadioChainInfo> CREATOR =
|
||||
@NonNull public static final Parcelable.Creator<RadioChainInfo> CREATOR =
|
||||
new Parcelable.Creator<RadioChainInfo>() {
|
||||
/**
|
||||
* Caller is responsible for providing a valid parcel.
|
||||
*/
|
||||
@Override
|
||||
public RadioChainInfo createFromParcel(Parcel in) {
|
||||
RadioChainInfo result = new RadioChainInfo();
|
||||
result.chainId = in.readInt();
|
||||
result.level = in.readInt();
|
||||
return result;
|
||||
return new RadioChainInfo(in.readInt(), in.readInt());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -14,18 +14,27 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.net.wifi;
|
||||
package android.net.wifi.wificond;
|
||||
|
||||
import android.annotation.CallbackExecutor;
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.SystemApi;
|
||||
import android.annotation.SystemService;
|
||||
import android.app.AlarmManager;
|
||||
import android.content.Context;
|
||||
import android.net.wifi.wificond.ChannelSettings;
|
||||
import android.net.wifi.wificond.HiddenNetwork;
|
||||
import android.net.wifi.wificond.NativeScanResult;
|
||||
import android.net.wifi.wificond.NativeWifiClient;
|
||||
import android.net.wifi.wificond.PnoSettings;
|
||||
import android.net.wifi.wificond.SingleScanSettings;
|
||||
import android.net.wifi.IApInterface;
|
||||
import android.net.wifi.IApInterfaceEventCallback;
|
||||
import android.net.wifi.IClientInterface;
|
||||
import android.net.wifi.IPnoScanEvent;
|
||||
import android.net.wifi.IScanEvent;
|
||||
import android.net.wifi.ISendMgmtFrameEvent;
|
||||
import android.net.wifi.IWifiScannerImpl;
|
||||
import android.net.wifi.IWificond;
|
||||
import android.net.wifi.SoftApInfo;
|
||||
import android.net.wifi.WifiAnnotations;
|
||||
import android.net.wifi.WifiScanner;
|
||||
import android.os.Binder;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
@@ -44,37 +53,48 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* This class provides methods for WifiNative to send control commands to wificond.
|
||||
* NOTE: This class should only be used from WifiNative.
|
||||
* This class encapsulates the interface the wificond daemon presents to the Wi-Fi framework. The
|
||||
* interface is only for use by the Wi-Fi framework and access is protected by SELinux permissions.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public class WifiCondManager implements IBinder.DeathRecipient {
|
||||
@SystemApi
|
||||
@SystemService(Context.WIFI_COND_SERVICE)
|
||||
public class WifiCondManager {
|
||||
private static final String TAG = "WifiCondManager";
|
||||
private boolean mVerboseLoggingEnabled = false;
|
||||
|
||||
/**
|
||||
* The {@link #sendMgmtFrame(String, byte[], SendMgmtFrameCallback, int) sendMgmtFrame()}
|
||||
* The {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)}
|
||||
* timeout, in milliseconds, after which
|
||||
* {@link SendMgmtFrameCallback#onFailure(int)} will be called with reason
|
||||
* {@link #SEND_MGMT_FRAME_ERROR_TIMEOUT}.
|
||||
*/
|
||||
public static final int SEND_MGMT_FRAME_TIMEOUT_MS = 1000;
|
||||
private static final int SEND_MGMT_FRAME_TIMEOUT_MS = 1000;
|
||||
|
||||
private static final String TIMEOUT_ALARM_TAG = TAG + " Send Management Frame Timeout";
|
||||
|
||||
/** @hide */
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(prefix = {"SCAN_TYPE_"},
|
||||
value = {SCAN_TYPE_SINGLE_SCAN,
|
||||
SCAN_TYPE_PNO_SCAN})
|
||||
public @interface ScanResultType {}
|
||||
|
||||
/** Get scan results for a single scan */
|
||||
/**
|
||||
* Specifies a scan type: single scan initiated by the framework. Can be used in
|
||||
* {@link #getScanResults(String, int)} to specify the type of scan result to fetch.
|
||||
*/
|
||||
public static final int SCAN_TYPE_SINGLE_SCAN = 0;
|
||||
|
||||
/** Get scan results for Pno Scan */
|
||||
/**
|
||||
* Specifies a scan type: PNO scan. Can be used in {@link #getScanResults(String, int)} to
|
||||
* specify the type of scan result to fetch.
|
||||
*/
|
||||
public static final int SCAN_TYPE_PNO_SCAN = 1;
|
||||
|
||||
private AlarmManager mAlarmManager;
|
||||
@@ -95,11 +115,12 @@ public class WifiCondManager implements IBinder.DeathRecipient {
|
||||
private AtomicBoolean mSendMgmtFrameInProgress = new AtomicBoolean(false);
|
||||
|
||||
/**
|
||||
* Interface for a callback to be used to handle scan results.
|
||||
* Interface used when waiting for scans to be completed (with results).
|
||||
*/
|
||||
public interface ScanEventCallback {
|
||||
/**
|
||||
* Called when scan results are available.
|
||||
* Called when scan results are available. Scans results should then be obtained from
|
||||
* {@link #getScanResults(String, int)}.
|
||||
*/
|
||||
void onScanResultReady();
|
||||
|
||||
@@ -110,11 +131,14 @@ public class WifiCondManager implements IBinder.DeathRecipient {
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface for a callback to provide information about PNO scan request.
|
||||
* Interface for a callback to provide information about PNO scan request requested with
|
||||
* {@link #startPnoScan(String, PnoSettings, Executor, PnoScanRequestCallback)}. Note that the
|
||||
* callback are for the status of the request - not the scan itself. The results of the scan
|
||||
* are returned with {@link ScanEventCallback}.
|
||||
*/
|
||||
public interface PnoScanRequestCallback {
|
||||
/**
|
||||
* Called when the PNO scan is requested.
|
||||
* Called when a PNO scan request has been successfully submitted.
|
||||
*/
|
||||
void onPnoRequestSucceeded();
|
||||
|
||||
@@ -125,73 +149,116 @@ public class WifiCondManager implements IBinder.DeathRecipient {
|
||||
}
|
||||
|
||||
private class ScanEventHandler extends IScanEvent.Stub {
|
||||
private Executor mExecutor;
|
||||
private ScanEventCallback mCallback;
|
||||
|
||||
ScanEventHandler(@NonNull ScanEventCallback callback) {
|
||||
ScanEventHandler(@NonNull Executor executor, @NonNull ScanEventCallback callback) {
|
||||
mExecutor = executor;
|
||||
mCallback = callback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void OnScanResultReady() {
|
||||
Log.d(TAG, "Scan result ready event");
|
||||
mCallback.onScanResultReady();
|
||||
Binder.clearCallingIdentity();
|
||||
mExecutor.execute(() -> mCallback.onScanResultReady());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void OnScanFailed() {
|
||||
Log.d(TAG, "Scan failed event");
|
||||
mCallback.onScanFailed();
|
||||
Binder.clearCallingIdentity();
|
||||
mExecutor.execute(() -> mCallback.onScanFailed());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Result of a signal poll.
|
||||
* Result of a signal poll requested using {@link #signalPoll(String)}.
|
||||
*/
|
||||
public static class SignalPollResult {
|
||||
// RSSI value in dBM.
|
||||
public int currentRssi;
|
||||
//Transmission bit rate in Mbps.
|
||||
public int txBitrate;
|
||||
// Association frequency in MHz.
|
||||
public int associationFrequency;
|
||||
//Last received packet bit rate in Mbps.
|
||||
public int rxBitrate;
|
||||
/** @hide */
|
||||
public SignalPollResult(int currentRssiDbm, int txBitrateMbps, int rxBitrateMbps,
|
||||
int associationFrequencyMHz) {
|
||||
this.currentRssiDbm = currentRssiDbm;
|
||||
this.txBitrateMbps = txBitrateMbps;
|
||||
this.rxBitrateMbps = rxBitrateMbps;
|
||||
this.associationFrequencyMHz = associationFrequencyMHz;
|
||||
}
|
||||
|
||||
/**
|
||||
* RSSI value in dBM.
|
||||
*/
|
||||
public final int currentRssiDbm;
|
||||
|
||||
/**
|
||||
* Transmission bit rate in Mbps.
|
||||
*/
|
||||
public final int txBitrateMbps;
|
||||
|
||||
/**
|
||||
* Last received packet bit rate in Mbps.
|
||||
*/
|
||||
public final int rxBitrateMbps;
|
||||
|
||||
/**
|
||||
* Association frequency in MHz.
|
||||
*/
|
||||
public final int associationFrequencyMHz;
|
||||
}
|
||||
|
||||
/**
|
||||
* WiFi interface transimission counters.
|
||||
* Transmission counters obtained using {@link #getTxPacketCounters(String)}.
|
||||
*/
|
||||
public static class TxPacketCounters {
|
||||
// Number of successfully transmitted packets.
|
||||
public int txSucceeded;
|
||||
// Number of tramsmission failures.
|
||||
public int txFailed;
|
||||
/** @hide */
|
||||
public TxPacketCounters(int txPacketSucceeded, int txPacketFailed) {
|
||||
this.txPacketSucceeded = txPacketSucceeded;
|
||||
this.txPacketFailed = txPacketFailed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Number of successfully transmitted packets.
|
||||
*/
|
||||
public final int txPacketSucceeded;
|
||||
|
||||
/**
|
||||
* Number of packet transmission failures.
|
||||
*/
|
||||
public final int txPacketFailed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callbacks for SoftAp interface.
|
||||
* Callbacks for SoftAp interface registered using
|
||||
* {@link #registerApCallback(String, Executor, SoftApCallback)}.
|
||||
*/
|
||||
public interface SoftApListener {
|
||||
public interface SoftApCallback {
|
||||
/**
|
||||
* Invoked when there is some fatal failure in the lower layers.
|
||||
* Invoked when there is a fatal failure and the SoftAp is shutdown.
|
||||
*/
|
||||
void onFailure();
|
||||
|
||||
/**
|
||||
* Invoked when the associated stations changes.
|
||||
* Invoked when there is a change in the associated station (STA).
|
||||
* @param client Information about the client whose status has changed.
|
||||
* @param isConnected Indication as to whether the client is connected (true), or
|
||||
* disconnected (false).
|
||||
*/
|
||||
void onConnectedClientsChanged(NativeWifiClient client, boolean isConnected);
|
||||
void onConnectedClientsChanged(@NonNull NativeWifiClient client, boolean isConnected);
|
||||
|
||||
/**
|
||||
* Invoked when the channel switch event happens.
|
||||
* Invoked when a channel switch event happens - i.e. the SoftAp is moved to a different
|
||||
* channel. Also called on initial registration.
|
||||
* @param frequencyMhz The new frequency of the SoftAp. A value of 0 is invalid and is an
|
||||
* indication that the SoftAp is not enabled.
|
||||
* @param bandwidth The new bandwidth of the SoftAp.
|
||||
*/
|
||||
void onSoftApChannelSwitched(int frequency, int bandwidth);
|
||||
void onSoftApChannelSwitched(int frequencyMhz, @WifiAnnotations.Bandwidth int bandwidth);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback to notify the results of a
|
||||
* {@link #sendMgmtFrame(String, byte[], SendMgmtFrameCallback, int) sendMgmtFrame()} call.
|
||||
* Note: no callbacks will be triggered if the iface dies while sending a frame.
|
||||
* {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)} call.
|
||||
* Note: no callbacks will be triggered if the interface dies while sending a frame.
|
||||
*/
|
||||
public interface SendMgmtFrameCallback {
|
||||
/**
|
||||
@@ -211,6 +278,7 @@ public class WifiCondManager implements IBinder.DeathRecipient {
|
||||
void onFailure(@SendMgmtFrameError int reason);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(prefix = {"SEND_MGMT_FRAME_ERROR_"},
|
||||
value = {SEND_MGMT_FRAME_ERROR_UNKNOWN,
|
||||
@@ -224,43 +292,44 @@ public class WifiCondManager implements IBinder.DeathRecipient {
|
||||
|
||||
/**
|
||||
* Unknown error occurred during call to
|
||||
* {@link #sendMgmtFrame(String, byte[], SendMgmtFrameCallback, int) sendMgmtFrame()}.
|
||||
* {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)}.
|
||||
*/
|
||||
public static final int SEND_MGMT_FRAME_ERROR_UNKNOWN = 1;
|
||||
|
||||
/**
|
||||
* Specifying the MCS rate in
|
||||
* {@link #sendMgmtFrame(String, byte[], SendMgmtFrameCallback, int) sendMgmtFrame()} is not
|
||||
* {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)} is not
|
||||
* supported by this device.
|
||||
*/
|
||||
public static final int SEND_MGMT_FRAME_ERROR_MCS_UNSUPPORTED = 2;
|
||||
|
||||
/**
|
||||
* Driver reported that no ACK was received for the frame transmitted using
|
||||
* {@link #sendMgmtFrame(String, byte[], SendMgmtFrameCallback, int) sendMgmtFrame()}.
|
||||
* {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)}.
|
||||
*/
|
||||
public static final int SEND_MGMT_FRAME_ERROR_NO_ACK = 3;
|
||||
|
||||
/**
|
||||
* Error code for when the driver fails to report on the status of the frame sent by
|
||||
* {@link #sendMgmtFrame(String, byte[], SendMgmtFrameCallback, int) sendMgmtFrame()}
|
||||
* {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)}
|
||||
* after {@link #SEND_MGMT_FRAME_TIMEOUT_MS} milliseconds.
|
||||
*/
|
||||
public static final int SEND_MGMT_FRAME_ERROR_TIMEOUT = 4;
|
||||
|
||||
/**
|
||||
* An existing call to
|
||||
* {@link #sendMgmtFrame(String, byte[], SendMgmtFrameCallback, int) sendMgmtFrame()}
|
||||
* {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)}
|
||||
* is in progress. Another frame cannot be sent until the first call completes.
|
||||
*/
|
||||
public static final int SEND_MGMT_FRAME_ERROR_ALREADY_STARTED = 5;
|
||||
|
||||
|
||||
/** @hide */
|
||||
public WifiCondManager(Context context) {
|
||||
mAlarmManager = (AlarmManager) context.getSystemService(AlarmManager.class);
|
||||
mAlarmManager = context.getSystemService(AlarmManager.class);
|
||||
mEventHandler = new Handler(context.getMainLooper());
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
@VisibleForTesting
|
||||
public WifiCondManager(Context context, IWificond wificond) {
|
||||
this(context);
|
||||
@@ -268,22 +337,26 @@ public class WifiCondManager implements IBinder.DeathRecipient {
|
||||
}
|
||||
|
||||
private class PnoScanEventHandler extends IPnoScanEvent.Stub {
|
||||
private Executor mExecutor;
|
||||
private ScanEventCallback mCallback;
|
||||
|
||||
PnoScanEventHandler(@NonNull ScanEventCallback callback) {
|
||||
PnoScanEventHandler(@NonNull Executor executor, @NonNull ScanEventCallback callback) {
|
||||
mExecutor = executor;
|
||||
mCallback = callback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void OnPnoNetworkFound() {
|
||||
Log.d(TAG, "Pno scan result event");
|
||||
mCallback.onScanResultReady();
|
||||
Binder.clearCallingIdentity();
|
||||
mExecutor.execute(() -> mCallback.onScanResultReady());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void OnPnoScanFailed() {
|
||||
Log.d(TAG, "Pno Scan failed event");
|
||||
mCallback.onScanFailed();
|
||||
Binder.clearCallingIdentity();
|
||||
mExecutor.execute(() -> mCallback.onScanFailed());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -291,9 +364,11 @@ public class WifiCondManager implements IBinder.DeathRecipient {
|
||||
* Listener for AP Interface events.
|
||||
*/
|
||||
private class ApInterfaceEventCallback extends IApInterfaceEventCallback.Stub {
|
||||
private SoftApListener mSoftApListener;
|
||||
private Executor mExecutor;
|
||||
private SoftApCallback mSoftApListener;
|
||||
|
||||
ApInterfaceEventCallback(SoftApListener listener) {
|
||||
ApInterfaceEventCallback(Executor executor, SoftApCallback listener) {
|
||||
mExecutor = executor;
|
||||
mSoftApListener = listener;
|
||||
}
|
||||
|
||||
@@ -304,12 +379,36 @@ public class WifiCondManager implements IBinder.DeathRecipient {
|
||||
+ client.macAddress + " isConnected: " + isConnected);
|
||||
}
|
||||
|
||||
mSoftApListener.onConnectedClientsChanged(client, isConnected);
|
||||
Binder.clearCallingIdentity();
|
||||
mExecutor.execute(() -> mSoftApListener.onConnectedClientsChanged(client, isConnected));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSoftApChannelSwitched(int frequency, int bandwidth) {
|
||||
mSoftApListener.onSoftApChannelSwitched(frequency, bandwidth);
|
||||
Binder.clearCallingIdentity();
|
||||
mExecutor.execute(() -> mSoftApListener.onSoftApChannelSwitched(frequency,
|
||||
toFrameworkBandwidth(bandwidth)));
|
||||
}
|
||||
|
||||
private @WifiAnnotations.Bandwidth int toFrameworkBandwidth(int bandwidth) {
|
||||
switch(bandwidth) {
|
||||
case IApInterfaceEventCallback.BANDWIDTH_INVALID:
|
||||
return SoftApInfo.CHANNEL_WIDTH_INVALID;
|
||||
case IApInterfaceEventCallback.BANDWIDTH_20_NOHT:
|
||||
return SoftApInfo.CHANNEL_WIDTH_20MHZ_NOHT;
|
||||
case IApInterfaceEventCallback.BANDWIDTH_20:
|
||||
return SoftApInfo.CHANNEL_WIDTH_20MHZ;
|
||||
case IApInterfaceEventCallback.BANDWIDTH_40:
|
||||
return SoftApInfo.CHANNEL_WIDTH_40MHZ;
|
||||
case IApInterfaceEventCallback.BANDWIDTH_80:
|
||||
return SoftApInfo.CHANNEL_WIDTH_80MHZ;
|
||||
case IApInterfaceEventCallback.BANDWIDTH_80P80:
|
||||
return SoftApInfo.CHANNEL_WIDTH_80MHZ_PLUS_MHZ;
|
||||
case IApInterfaceEventCallback.BANDWIDTH_160:
|
||||
return SoftApInfo.CHANNEL_WIDTH_160MHZ;
|
||||
default:
|
||||
return SoftApInfo.CHANNEL_WIDTH_INVALID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -317,6 +416,7 @@ public class WifiCondManager implements IBinder.DeathRecipient {
|
||||
* Callback triggered by wificond.
|
||||
*/
|
||||
private class SendMgmtFrameEvent extends ISendMgmtFrameEvent.Stub {
|
||||
private Executor mExecutor;
|
||||
private SendMgmtFrameCallback mCallback;
|
||||
private AlarmManager.OnAlarmListener mTimeoutCallback;
|
||||
/**
|
||||
@@ -332,14 +432,16 @@ public class WifiCondManager implements IBinder.DeathRecipient {
|
||||
r.run();
|
||||
}
|
||||
|
||||
SendMgmtFrameEvent(@NonNull SendMgmtFrameCallback callback) {
|
||||
SendMgmtFrameEvent(@NonNull Executor executor, @NonNull SendMgmtFrameCallback callback) {
|
||||
mExecutor = executor;
|
||||
mCallback = callback;
|
||||
// called in main thread
|
||||
mTimeoutCallback = () -> runIfFirstCall(() -> {
|
||||
if (mVerboseLoggingEnabled) {
|
||||
Log.e(TAG, "Timed out waiting for ACK");
|
||||
}
|
||||
mCallback.onFailure(SEND_MGMT_FRAME_ERROR_TIMEOUT);
|
||||
Binder.clearCallingIdentity();
|
||||
mExecutor.execute(() -> mCallback.onFailure(SEND_MGMT_FRAME_ERROR_TIMEOUT));
|
||||
});
|
||||
mWasCalled = false;
|
||||
|
||||
@@ -354,7 +456,8 @@ public class WifiCondManager implements IBinder.DeathRecipient {
|
||||
// post to main thread
|
||||
mEventHandler.post(() -> runIfFirstCall(() -> {
|
||||
mAlarmManager.cancel(mTimeoutCallback);
|
||||
mCallback.onAck(elapsedTimeMs);
|
||||
Binder.clearCallingIdentity();
|
||||
mExecutor.execute(() -> mCallback.onAck(elapsedTimeMs));
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -364,7 +467,8 @@ public class WifiCondManager implements IBinder.DeathRecipient {
|
||||
// post to main thread
|
||||
mEventHandler.post(() -> runIfFirstCall(() -> {
|
||||
mAlarmManager.cancel(mTimeoutCallback);
|
||||
mCallback.onFailure(reason);
|
||||
Binder.clearCallingIdentity();
|
||||
mExecutor.execute(() -> mCallback.onFailure(reason));
|
||||
}));
|
||||
}
|
||||
}
|
||||
@@ -372,8 +476,9 @@ public class WifiCondManager implements IBinder.DeathRecipient {
|
||||
/**
|
||||
* Called by the binder subsystem upon remote object death.
|
||||
* Invoke all the register death handlers and clear state.
|
||||
* @hide
|
||||
*/
|
||||
@Override
|
||||
@VisibleForTesting
|
||||
public void binderDied() {
|
||||
mEventHandler.post(() -> {
|
||||
Log.e(TAG, "Wificond died!");
|
||||
@@ -387,17 +492,22 @@ public class WifiCondManager implements IBinder.DeathRecipient {
|
||||
});
|
||||
}
|
||||
|
||||
/** Enable or disable verbose logging of WificondControl.
|
||||
* @param enable True to enable verbose logging. False to disable verbose logging.
|
||||
/**
|
||||
* Enable or disable verbose logging of the WifiCondManager module.
|
||||
* @param enable True to enable verbose logging. False to disable verbose logging.
|
||||
*/
|
||||
public void enableVerboseLogging(boolean enable) {
|
||||
mVerboseLoggingEnabled = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes wificond & registers a death notification for wificond.
|
||||
* This method clears any existing state in wificond daemon.
|
||||
* Initializes WifiCondManager & registers a death notification for the WifiCondManager which
|
||||
* acts as a proxy for the wificond daemon (i.e. the death listener will be called when and if
|
||||
* the wificond daemon dies).
|
||||
*
|
||||
* Note: This method clears any existing state in wificond daemon.
|
||||
*
|
||||
* @param deathEventHandler A {@link Runnable} to be called whenever the wificond daemon dies.
|
||||
* @return Returns true on success.
|
||||
*/
|
||||
public boolean initialize(@NonNull Runnable deathEventHandler) {
|
||||
@@ -428,7 +538,7 @@ public class WifiCondManager implements IBinder.DeathRecipient {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
mWificond.asBinder().linkToDeath(this, 0);
|
||||
mWificond.asBinder().linkToDeath(() -> binderDied(), 0);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Failed to register death notification for wificond");
|
||||
// The remote has already died.
|
||||
@@ -438,16 +548,27 @@ public class WifiCondManager implements IBinder.DeathRecipient {
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup interface for client mode via wificond.
|
||||
* @return true on success.
|
||||
*/
|
||||
* Set up an interface for client (STA) mode.
|
||||
*
|
||||
* @param ifaceName Name of the interface to configure.
|
||||
* @param executor The Executor on which to execute the callbacks.
|
||||
* @param scanCallback A callback for framework initiated scans.
|
||||
* @param pnoScanCallback A callback for PNO (offloaded) scans.
|
||||
* @return true on success.
|
||||
*/
|
||||
public boolean setupInterfaceForClientMode(@NonNull String ifaceName,
|
||||
@NonNull @CallbackExecutor Executor executor,
|
||||
@NonNull ScanEventCallback scanCallback, @NonNull ScanEventCallback pnoScanCallback) {
|
||||
Log.d(TAG, "Setting up interface for client mode");
|
||||
if (!retrieveWificondAndRegisterForDeath()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (scanCallback == null || pnoScanCallback == null || executor == null) {
|
||||
Log.e(TAG, "setupInterfaceForClientMode invoked with null callbacks");
|
||||
return false;
|
||||
}
|
||||
|
||||
IClientInterface clientInterface = null;
|
||||
try {
|
||||
clientInterface = mWificond.createClientInterface(ifaceName);
|
||||
@@ -472,10 +593,11 @@ public class WifiCondManager implements IBinder.DeathRecipient {
|
||||
}
|
||||
mWificondScanners.put(ifaceName, wificondScanner);
|
||||
Binder.allowBlocking(wificondScanner.asBinder());
|
||||
ScanEventHandler scanEventHandler = new ScanEventHandler(scanCallback);
|
||||
ScanEventHandler scanEventHandler = new ScanEventHandler(executor, scanCallback);
|
||||
mScanEventHandlers.put(ifaceName, scanEventHandler);
|
||||
wificondScanner.subscribeScanEvents(scanEventHandler);
|
||||
PnoScanEventHandler pnoScanEventHandler = new PnoScanEventHandler(pnoScanCallback);
|
||||
PnoScanEventHandler pnoScanEventHandler = new PnoScanEventHandler(executor,
|
||||
pnoScanCallback);
|
||||
mPnoScanEventHandlers.put(ifaceName, pnoScanEventHandler);
|
||||
wificondScanner.subscribePnoScanEvents(pnoScanEventHandler);
|
||||
} catch (RemoteException e) {
|
||||
@@ -486,8 +608,10 @@ public class WifiCondManager implements IBinder.DeathRecipient {
|
||||
}
|
||||
|
||||
/**
|
||||
* Teardown a specific STA interface configured in wificond.
|
||||
* Tear down a specific client (STA) interface, initially configured using
|
||||
* {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)}.
|
||||
*
|
||||
* @param ifaceName Name of the interface to tear down.
|
||||
* @return Returns true on success.
|
||||
*/
|
||||
public boolean tearDownClientInterface(@NonNull String ifaceName) {
|
||||
@@ -531,9 +655,11 @@ public class WifiCondManager implements IBinder.DeathRecipient {
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup interface for softAp mode via wificond.
|
||||
* @return true on success.
|
||||
*/
|
||||
* Set up interface as a Soft AP.
|
||||
*
|
||||
* @param ifaceName Name of the interface to configure.
|
||||
* @return true on success.
|
||||
*/
|
||||
public boolean setupInterfaceForSoftApMode(@NonNull String ifaceName) {
|
||||
Log.d(TAG, "Setting up interface for soft ap mode");
|
||||
if (!retrieveWificondAndRegisterForDeath()) {
|
||||
@@ -560,8 +686,10 @@ public class WifiCondManager implements IBinder.DeathRecipient {
|
||||
}
|
||||
|
||||
/**
|
||||
* Teardown a specific AP interface configured in wificond.
|
||||
* Tear down a Soft AP interface initially configured using
|
||||
* {@link #setupInterfaceForSoftApMode(String)}.
|
||||
*
|
||||
* @param ifaceName Name of the interface to tear down.
|
||||
* @return Returns true on success.
|
||||
*/
|
||||
public boolean tearDownSoftApInterface(@NonNull String ifaceName) {
|
||||
@@ -592,7 +720,8 @@ public class WifiCondManager implements IBinder.DeathRecipient {
|
||||
}
|
||||
|
||||
/**
|
||||
* Teardown all interfaces configured in wificond.
|
||||
* Tear down all interfaces, whether clients (STA) or Soft AP.
|
||||
*
|
||||
* @return Returns true on success.
|
||||
*/
|
||||
public boolean tearDownInterfaces() {
|
||||
@@ -624,12 +753,13 @@ public class WifiCondManager implements IBinder.DeathRecipient {
|
||||
}
|
||||
|
||||
/**
|
||||
* Request signal polling to wificond.
|
||||
* @param ifaceName Name of the interface.
|
||||
* Returns an SignalPollResult object.
|
||||
* Returns null on failure.
|
||||
* Request signal polling.
|
||||
*
|
||||
* @param ifaceName Name of the interface on which to poll.
|
||||
* @return A {@link SignalPollResult} object containing interface statistics, or a null on
|
||||
* error.
|
||||
*/
|
||||
public SignalPollResult signalPoll(@NonNull String ifaceName) {
|
||||
@Nullable public SignalPollResult signalPoll(@NonNull String ifaceName) {
|
||||
IClientInterface iface = getClientInterface(ifaceName);
|
||||
if (iface == null) {
|
||||
Log.e(TAG, "No valid wificond client interface handler");
|
||||
@@ -647,21 +777,16 @@ public class WifiCondManager implements IBinder.DeathRecipient {
|
||||
Log.e(TAG, "Failed to do signal polling due to remote exception");
|
||||
return null;
|
||||
}
|
||||
SignalPollResult pollResult = new SignalPollResult();
|
||||
pollResult.currentRssi = resultArray[0];
|
||||
pollResult.txBitrate = resultArray[1];
|
||||
pollResult.associationFrequency = resultArray[2];
|
||||
pollResult.rxBitrate = resultArray[3];
|
||||
return pollResult;
|
||||
return new SignalPollResult(resultArray[0], resultArray[1], resultArray[3], resultArray[2]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch TX packet counters on current connection from wificond.
|
||||
* Get current transmit (Tx) packet counters of the specified interface.
|
||||
*
|
||||
* @param ifaceName Name of the interface.
|
||||
* Returns an TxPacketCounters object.
|
||||
* Returns null on failure.
|
||||
* @return {@link TxPacketCounters} of the current interface or null on error.
|
||||
*/
|
||||
public TxPacketCounters getTxPacketCounters(@NonNull String ifaceName) {
|
||||
@Nullable public TxPacketCounters getTxPacketCounters(@NonNull String ifaceName) {
|
||||
IClientInterface iface = getClientInterface(ifaceName);
|
||||
if (iface == null) {
|
||||
Log.e(TAG, "No valid wificond client interface handler");
|
||||
@@ -679,10 +804,7 @@ public class WifiCondManager implements IBinder.DeathRecipient {
|
||||
Log.e(TAG, "Failed to do signal polling due to remote exception");
|
||||
return null;
|
||||
}
|
||||
TxPacketCounters counters = new TxPacketCounters();
|
||||
counters.txSucceeded = resultArray[0];
|
||||
counters.txFailed = resultArray[1];
|
||||
return counters;
|
||||
return new TxPacketCounters(resultArray[0], resultArray[1]);
|
||||
}
|
||||
|
||||
/** Helper function to look up the scanner impl handle using name */
|
||||
@@ -691,10 +813,16 @@ public class WifiCondManager implements IBinder.DeathRecipient {
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the latest scan result from kernel via wificond.
|
||||
* @param ifaceName Name of the interface.
|
||||
* @return Returns an array of native scan results or an empty array on failure.
|
||||
*/
|
||||
* Fetch the latest scan results of the indicated type for the specified interface. Note that
|
||||
* this method fetches the latest results - it does not initiate a scan. Initiating a scan can
|
||||
* be done using {@link #startScan(String, int, Set, List)} or
|
||||
* {@link #startPnoScan(String, PnoSettings, Executor, PnoScanRequestCallback)}.
|
||||
*
|
||||
* @param ifaceName Name of the interface.
|
||||
* @param scanType The type of scan result to be returned, can be
|
||||
* {@link #SCAN_TYPE_SINGLE_SCAN} or {@link #SCAN_TYPE_PNO_SCAN}.
|
||||
* @return Returns an array of {@link NativeScanResult} or an empty array on failure.
|
||||
*/
|
||||
@NonNull public List<NativeScanResult> getScanResults(@NonNull String ifaceName,
|
||||
@ScanResultType int scanType) {
|
||||
IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName);
|
||||
@@ -739,15 +867,23 @@ public class WifiCondManager implements IBinder.DeathRecipient {
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a scan using wificond for the given parameters.
|
||||
* @param ifaceName Name of the interface.
|
||||
* @param scanType Type of scan to perform.
|
||||
* Start a scan using the specified parameters. A scan is an asynchronous operation. The
|
||||
* result of the operation is returned in the {@link ScanEventCallback} registered when
|
||||
* setting up an interface using
|
||||
* {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)}.
|
||||
* The latest scans can be obtained using {@link #getScanResults(String, int)} and using a
|
||||
* {@link #SCAN_TYPE_SINGLE_SCAN} for the {@code scanType}.
|
||||
*
|
||||
* @param ifaceName Name of the interface on which to initiate the scan.
|
||||
* @param scanType Type of scan to perform, can be any of
|
||||
* {@link WifiScanner#SCAN_TYPE_HIGH_ACCURACY}, {@link WifiScanner#SCAN_TYPE_LOW_POWER}, or
|
||||
* {@link WifiScanner#SCAN_TYPE_LOW_LATENCY}.
|
||||
* @param freqs list of frequencies to scan for, if null scan all supported channels.
|
||||
* @param hiddenNetworkSSIDs List of hidden networks to be scanned for.
|
||||
* @return Returns true on success.
|
||||
*/
|
||||
public boolean scan(@NonNull String ifaceName, @WifiAnnotations.ScanType int scanType,
|
||||
Set<Integer> freqs, List<byte[]> hiddenNetworkSSIDs) {
|
||||
public boolean startScan(@NonNull String ifaceName, @WifiAnnotations.ScanType int scanType,
|
||||
@Nullable Set<Integer> freqs, @Nullable List<byte[]> hiddenNetworkSSIDs) {
|
||||
IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName);
|
||||
if (scannerImpl == null) {
|
||||
Log.e(TAG, "No valid wificond scanner interface handler");
|
||||
@@ -792,25 +928,40 @@ public class WifiCondManager implements IBinder.DeathRecipient {
|
||||
}
|
||||
|
||||
/**
|
||||
* Start PNO scan.
|
||||
* @param ifaceName Name of the interface.
|
||||
* @param pnoSettings Pno scan configuration.
|
||||
* Request a PNO (Preferred Network Offload). The offload request and the scans are asynchronous
|
||||
* operations. The result of the request are returned in the {@code callback} parameter which
|
||||
* is an {@link PnoScanRequestCallback}. The scan results are are return in the
|
||||
* {@link ScanEventCallback} which is registered when setting up an interface using
|
||||
* {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)}.
|
||||
* The latest PNO scans can be obtained using {@link #getScanResults(String, int)} with the
|
||||
* {@code scanType} set to {@link #SCAN_TYPE_PNO_SCAN}.
|
||||
*
|
||||
* @param ifaceName Name of the interface on which to request a PNO.
|
||||
* @param pnoSettings PNO scan configuration.
|
||||
* @param executor The Executor on which to execute the callback.
|
||||
* @param callback Callback for the results of the offload request.
|
||||
* @return true on success.
|
||||
*/
|
||||
public boolean startPnoScan(@NonNull String ifaceName, PnoSettings pnoSettings,
|
||||
PnoScanRequestCallback callback) {
|
||||
public boolean startPnoScan(@NonNull String ifaceName, @NonNull PnoSettings pnoSettings,
|
||||
@NonNull @CallbackExecutor Executor executor,
|
||||
@NonNull PnoScanRequestCallback callback) {
|
||||
IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName);
|
||||
if (scannerImpl == null) {
|
||||
Log.e(TAG, "No valid wificond scanner interface handler");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (callback == null || executor == null) {
|
||||
Log.e(TAG, "startPnoScan called with a null callback");
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
boolean success = scannerImpl.startPnoScan(pnoSettings);
|
||||
if (success) {
|
||||
callback.onPnoRequestSucceeded();
|
||||
executor.execute(callback::onPnoRequestSucceeded);
|
||||
} else {
|
||||
callback.onPnoRequestFailed();
|
||||
executor.execute(callback::onPnoRequestFailed);
|
||||
}
|
||||
return success;
|
||||
} catch (RemoteException e1) {
|
||||
@@ -820,8 +971,10 @@ public class WifiCondManager implements IBinder.DeathRecipient {
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop PNO scan.
|
||||
* @param ifaceName Name of the interface.
|
||||
* Stop PNO scan configured with
|
||||
* {@link #startPnoScan(String, PnoSettings, Executor, PnoScanRequestCallback)}.
|
||||
*
|
||||
* @param ifaceName Name of the interface on which the PNO scan was configured.
|
||||
* @return true on success.
|
||||
*/
|
||||
public boolean stopPnoScan(@NonNull String ifaceName) {
|
||||
@@ -839,8 +992,9 @@ public class WifiCondManager implements IBinder.DeathRecipient {
|
||||
}
|
||||
|
||||
/**
|
||||
* Abort ongoing single scan.
|
||||
* @param ifaceName Name of the interface.
|
||||
* Abort ongoing single scan started with {@link #startScan(String, int, Set, List)}.
|
||||
*
|
||||
* @param ifaceName Name of the interface on which the scan was started.
|
||||
*/
|
||||
public void abortScan(@NonNull String ifaceName) {
|
||||
IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName);
|
||||
@@ -856,7 +1010,7 @@ public class WifiCondManager implements IBinder.DeathRecipient {
|
||||
}
|
||||
|
||||
/**
|
||||
* Query the list of valid frequencies for the provided band.
|
||||
* Query the list of valid frequencies (in MHz) for the provided band.
|
||||
* The result depends on the on the country code that has been set.
|
||||
*
|
||||
* @param band as specified by one of the WifiScanner.WIFI_BAND_* constants.
|
||||
@@ -865,31 +1019,39 @@ public class WifiCondManager implements IBinder.DeathRecipient {
|
||||
* WifiScanner.WIFI_BAND_5_GHZ
|
||||
* WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY
|
||||
* WifiScanner.WIFI_BAND_6_GHZ
|
||||
* @return frequencies vector of valid frequencies (MHz), or null for error.
|
||||
* @return frequencies vector of valid frequencies (MHz), or an empty array for error.
|
||||
* @throws IllegalArgumentException if band is not recognized.
|
||||
*/
|
||||
public int [] getChannelsForBand(@WifiAnnotations.WifiBandBasic int band) {
|
||||
public @NonNull int[] getChannelsMhzForBand(@WifiAnnotations.WifiBandBasic int band) {
|
||||
if (mWificond == null) {
|
||||
Log.e(TAG, "No valid wificond scanner interface handler");
|
||||
return null;
|
||||
return new int[0];
|
||||
}
|
||||
int[] result = null;
|
||||
try {
|
||||
switch (band) {
|
||||
case WifiScanner.WIFI_BAND_24_GHZ:
|
||||
return mWificond.getAvailable2gChannels();
|
||||
result = mWificond.getAvailable2gChannels();
|
||||
break;
|
||||
case WifiScanner.WIFI_BAND_5_GHZ:
|
||||
return mWificond.getAvailable5gNonDFSChannels();
|
||||
result = mWificond.getAvailable5gNonDFSChannels();
|
||||
break;
|
||||
case WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY:
|
||||
return mWificond.getAvailableDFSChannels();
|
||||
result = mWificond.getAvailableDFSChannels();
|
||||
break;
|
||||
case WifiScanner.WIFI_BAND_6_GHZ:
|
||||
return mWificond.getAvailable6gChannels();
|
||||
result = mWificond.getAvailable6gChannels();
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("unsupported band " + band);
|
||||
}
|
||||
} catch (RemoteException e1) {
|
||||
Log.e(TAG, "Failed to request getChannelsForBand due to remote exception");
|
||||
}
|
||||
return null;
|
||||
if (result == null) {
|
||||
result = new int[0];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Helper function to look up the interface handle using name */
|
||||
@@ -898,22 +1060,33 @@ public class WifiCondManager implements IBinder.DeathRecipient {
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the provided listener for SoftAp events.
|
||||
* Register the provided callback handler for SoftAp events. Note that the Soft AP itself is
|
||||
* configured using {@link #setupInterfaceForSoftApMode(String)}.
|
||||
*
|
||||
* @param ifaceName Name of the interface.
|
||||
* @param listener Callback for AP events.
|
||||
* @param ifaceName Name of the interface on which to register the callback.
|
||||
* @param executor The Executor on which to execute the callbacks.
|
||||
* @param callback Callback for AP events.
|
||||
* @return true on success, false otherwise.
|
||||
*/
|
||||
public boolean registerApListener(@NonNull String ifaceName, SoftApListener listener) {
|
||||
public boolean registerApCallback(@NonNull String ifaceName,
|
||||
@NonNull @CallbackExecutor Executor executor,
|
||||
@NonNull SoftApCallback callback) {
|
||||
IApInterface iface = getApInterface(ifaceName);
|
||||
if (iface == null) {
|
||||
Log.e(TAG, "No valid ap interface handler");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (callback == null || executor == null) {
|
||||
Log.e(TAG, "registerApCallback called with a null callback");
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
IApInterfaceEventCallback callback = new ApInterfaceEventCallback(listener);
|
||||
mApInterfaceListeners.put(ifaceName, callback);
|
||||
boolean success = iface.registerCallback(callback);
|
||||
IApInterfaceEventCallback wificondCallback = new ApInterfaceEventCallback(executor,
|
||||
callback);
|
||||
mApInterfaceListeners.put(ifaceName, wificondCallback);
|
||||
boolean success = iface.registerCallback(wificondCallback);
|
||||
if (!success) {
|
||||
Log.e(TAG, "Failed to register ap callback.");
|
||||
return false;
|
||||
@@ -926,19 +1099,28 @@ public class WifiCondManager implements IBinder.DeathRecipient {
|
||||
}
|
||||
|
||||
/**
|
||||
* See {@link #sendMgmtFrame(String, byte[], SendMgmtFrameCallback, int)}
|
||||
* Send a management frame on the specified interface at the specified rate. Useful for probing
|
||||
* the link with arbitrary frames.
|
||||
*
|
||||
* @param ifaceName The interface on which to send the frame.
|
||||
* @param frame The raw byte array of the management frame to tramit.
|
||||
* @param mcs The MCS (modulation and coding scheme), i.e. rate, at which to transmit the
|
||||
* frame. Specified per IEEE 802.11.
|
||||
* @param executor The Executor on which to execute the callbacks.
|
||||
* @param callback A {@link SendMgmtFrameCallback} callback for results of the operation.
|
||||
*/
|
||||
public void sendMgmtFrame(@NonNull String ifaceName, @NonNull byte[] frame,
|
||||
@NonNull SendMgmtFrameCallback callback, int mcs) {
|
||||
public void sendMgmtFrame(@NonNull String ifaceName, @NonNull byte[] frame, int mcs,
|
||||
@NonNull @CallbackExecutor Executor executor,
|
||||
@NonNull SendMgmtFrameCallback callback) {
|
||||
|
||||
if (callback == null) {
|
||||
if (callback == null || executor == null) {
|
||||
Log.e(TAG, "callback cannot be null!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (frame == null) {
|
||||
Log.e(TAG, "frame cannot be null!");
|
||||
callback.onFailure(SEND_MGMT_FRAME_ERROR_UNKNOWN);
|
||||
executor.execute(() -> callback.onFailure(SEND_MGMT_FRAME_ERROR_UNKNOWN));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -946,17 +1128,17 @@ public class WifiCondManager implements IBinder.DeathRecipient {
|
||||
IClientInterface clientInterface = getClientInterface(ifaceName);
|
||||
if (clientInterface == null) {
|
||||
Log.e(TAG, "No valid wificond client interface handler");
|
||||
callback.onFailure(SEND_MGMT_FRAME_ERROR_UNKNOWN);
|
||||
executor.execute(() -> callback.onFailure(SEND_MGMT_FRAME_ERROR_UNKNOWN));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mSendMgmtFrameInProgress.compareAndSet(false, true)) {
|
||||
Log.e(TAG, "An existing management frame transmission is in progress!");
|
||||
callback.onFailure(SEND_MGMT_FRAME_ERROR_ALREADY_STARTED);
|
||||
executor.execute(() -> callback.onFailure(SEND_MGMT_FRAME_ERROR_ALREADY_STARTED));
|
||||
return;
|
||||
}
|
||||
|
||||
SendMgmtFrameEvent sendMgmtFrameEvent = new SendMgmtFrameEvent(callback);
|
||||
SendMgmtFrameEvent sendMgmtFrameEvent = new SendMgmtFrameEvent(executor, callback);
|
||||
try {
|
||||
clientInterface.SendMgmtFrame(frame, sendMgmtFrameEvent, mcs);
|
||||
} catch (RemoteException e) {
|
||||
@@ -30,7 +30,7 @@ import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link android.net.wifi.wificond.PnoSettingsResult}.
|
||||
* Unit tests for {@link android.net.wifi.wificond.PnoSettings}.
|
||||
*/
|
||||
@SmallTest
|
||||
public class PnoSettingsTest {
|
||||
@@ -52,14 +52,14 @@ public class PnoSettingsTest {
|
||||
@Before
|
||||
public void setUp() {
|
||||
mPnoNetwork1 = new PnoNetwork();
|
||||
mPnoNetwork1.ssid = TEST_SSID_1;
|
||||
mPnoNetwork1.isHidden = true;
|
||||
mPnoNetwork1.frequencies = TEST_FREQUENCIES_1;
|
||||
mPnoNetwork1.setSsid(TEST_SSID_1);
|
||||
mPnoNetwork1.setHidden(true);
|
||||
mPnoNetwork1.setFrequenciesMhz(TEST_FREQUENCIES_1);
|
||||
|
||||
mPnoNetwork2 = new PnoNetwork();
|
||||
mPnoNetwork2.ssid = TEST_SSID_2;
|
||||
mPnoNetwork2.isHidden = false;
|
||||
mPnoNetwork2.frequencies = TEST_FREQUENCIES_2;
|
||||
mPnoNetwork2.setSsid(TEST_SSID_2);
|
||||
mPnoNetwork2.setHidden(false);
|
||||
mPnoNetwork2.setFrequenciesMhz(TEST_FREQUENCIES_2);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -69,10 +69,10 @@ public class PnoSettingsTest {
|
||||
@Test
|
||||
public void canSerializeAndDeserialize() {
|
||||
PnoSettings pnoSettings = new PnoSettings();
|
||||
pnoSettings.intervalMs = TEST_INTERVAL_MS;
|
||||
pnoSettings.min2gRssi = TEST_MIN_2G_RSSI;
|
||||
pnoSettings.min5gRssi = TEST_MIN_5G_RSSI;
|
||||
pnoSettings.pnoNetworks = new ArrayList<>(Arrays.asList(mPnoNetwork1, mPnoNetwork2));
|
||||
pnoSettings.setIntervalMillis(TEST_INTERVAL_MS);
|
||||
pnoSettings.setMin2gRssiDbm(TEST_MIN_2G_RSSI);
|
||||
pnoSettings.setMin5gRssiDbm(TEST_MIN_5G_RSSI);
|
||||
pnoSettings.setPnoNetworks(new ArrayList<>(Arrays.asList(mPnoNetwork1, mPnoNetwork2)));
|
||||
|
||||
Parcel parcel = Parcel.obtain();
|
||||
pnoSettings.writeToParcel(parcel, 0);
|
||||
@@ -90,16 +90,16 @@ public class PnoSettingsTest {
|
||||
@Test
|
||||
public void testAsHashMapKey() {
|
||||
PnoSettings pnoSettings1 = new PnoSettings();
|
||||
pnoSettings1.intervalMs = TEST_INTERVAL_MS;
|
||||
pnoSettings1.min2gRssi = TEST_MIN_2G_RSSI;
|
||||
pnoSettings1.min5gRssi = TEST_MIN_5G_RSSI;
|
||||
pnoSettings1.pnoNetworks = new ArrayList<>(Arrays.asList(mPnoNetwork1, mPnoNetwork2));
|
||||
pnoSettings1.setIntervalMillis(TEST_INTERVAL_MS);
|
||||
pnoSettings1.setMin2gRssiDbm(TEST_MIN_2G_RSSI);
|
||||
pnoSettings1.setMin5gRssiDbm(TEST_MIN_5G_RSSI);
|
||||
pnoSettings1.setPnoNetworks(new ArrayList<>(Arrays.asList(mPnoNetwork1, mPnoNetwork2)));
|
||||
|
||||
PnoSettings pnoSettings2 = new PnoSettings();
|
||||
pnoSettings2.intervalMs = TEST_INTERVAL_MS;
|
||||
pnoSettings2.min2gRssi = TEST_MIN_2G_RSSI;
|
||||
pnoSettings2.min5gRssi = TEST_MIN_5G_RSSI;
|
||||
pnoSettings2.pnoNetworks = new ArrayList<>(Arrays.asList(mPnoNetwork1, mPnoNetwork2));
|
||||
pnoSettings2.setIntervalMillis(TEST_INTERVAL_MS);
|
||||
pnoSettings2.setMin2gRssiDbm(TEST_MIN_2G_RSSI);
|
||||
pnoSettings2.setMin5gRssiDbm(TEST_MIN_5G_RSSI);
|
||||
pnoSettings2.setPnoNetworks(new ArrayList<>(Arrays.asList(mPnoNetwork1, mPnoNetwork2)));
|
||||
|
||||
assertEquals(pnoSettings1, pnoSettings2);
|
||||
assertEquals(pnoSettings1.hashCode(), pnoSettings2.hashCode());
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.net.wifi;
|
||||
package android.net.wifi.wificond;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
@@ -38,13 +38,18 @@ import static org.mockito.Mockito.when;
|
||||
import android.app.AlarmManager;
|
||||
import android.app.test.TestAlarmManager;
|
||||
import android.content.Context;
|
||||
import android.net.wifi.IApInterface;
|
||||
import android.net.wifi.IApInterfaceEventCallback;
|
||||
import android.net.wifi.IClientInterface;
|
||||
import android.net.wifi.IPnoScanEvent;
|
||||
import android.net.wifi.IScanEvent;
|
||||
import android.net.wifi.ISendMgmtFrameEvent;
|
||||
import android.net.wifi.IWifiScannerImpl;
|
||||
import android.net.wifi.IWificond;
|
||||
import android.net.wifi.SoftApInfo;
|
||||
import android.net.wifi.WifiConfiguration;
|
||||
import android.net.wifi.WifiScanner;
|
||||
import android.net.wifi.util.HexEncoding;
|
||||
import android.net.wifi.wificond.ChannelSettings;
|
||||
import android.net.wifi.wificond.HiddenNetwork;
|
||||
import android.net.wifi.wificond.NativeWifiClient;
|
||||
import android.net.wifi.wificond.PnoNetwork;
|
||||
import android.net.wifi.wificond.PnoSettings;
|
||||
import android.net.wifi.wificond.SingleScanSettings;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
@@ -67,7 +72,6 @@ import java.nio.charset.CharsetDecoder;
|
||||
import java.nio.charset.CharsetEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@@ -88,7 +92,7 @@ public class WifiCondManagerTest {
|
||||
@Mock
|
||||
private IApInterface mApInterface;
|
||||
@Mock
|
||||
private WifiCondManager.SoftApListener mSoftApListener;
|
||||
private WifiCondManager.SoftApCallback mSoftApListener;
|
||||
@Mock
|
||||
private WifiCondManager.SendMgmtFrameCallback mSendMgmtFrameCallback;
|
||||
@Mock
|
||||
@@ -122,6 +126,7 @@ public class WifiCondManagerTest {
|
||||
private static final String TEST_QUOTED_SSID_2 = "\"testSsid2\"";
|
||||
private static final int[] TEST_FREQUENCIES_1 = {};
|
||||
private static final int[] TEST_FREQUENCIES_2 = {2500, 5124};
|
||||
private static final byte[] TEST_RAW_MAC_BYTES = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05};
|
||||
|
||||
private static final List<byte[]> SCAN_HIDDEN_NETWORK_SSID_LIST =
|
||||
new ArrayList<byte[]>() {{
|
||||
@@ -131,22 +136,23 @@ public class WifiCondManagerTest {
|
||||
LocalNativeUtil.decodeSsid(TEST_QUOTED_SSID_2)));
|
||||
}};
|
||||
|
||||
private static final PnoSettings TEST_PNO_SETTINGS =
|
||||
new PnoSettings() {{
|
||||
intervalMs = 6000;
|
||||
pnoNetworks = new ArrayList<>();
|
||||
PnoNetwork network = new PnoNetwork();
|
||||
network.ssid = LocalNativeUtil.byteArrayFromArrayList(
|
||||
LocalNativeUtil.decodeSsid(TEST_QUOTED_SSID_1));
|
||||
network.isHidden = true;
|
||||
network.frequencies = TEST_FREQUENCIES_1;
|
||||
pnoNetworks.add(network);
|
||||
network.ssid = LocalNativeUtil.byteArrayFromArrayList(
|
||||
LocalNativeUtil.decodeSsid(TEST_QUOTED_SSID_2));
|
||||
network.isHidden = false;
|
||||
network.frequencies = TEST_FREQUENCIES_2;
|
||||
pnoNetworks.add(network);
|
||||
}};
|
||||
private static final PnoSettings TEST_PNO_SETTINGS = new PnoSettings();
|
||||
static {
|
||||
TEST_PNO_SETTINGS.setIntervalMillis(6000);
|
||||
List<PnoNetwork> initPnoNetworks = new ArrayList<>();
|
||||
PnoNetwork network = new PnoNetwork();
|
||||
network.setSsid(LocalNativeUtil.byteArrayFromArrayList(
|
||||
LocalNativeUtil.decodeSsid(TEST_QUOTED_SSID_1)));
|
||||
network.setHidden(true);
|
||||
network.setFrequenciesMhz(TEST_FREQUENCIES_1);
|
||||
initPnoNetworks.add(network);
|
||||
network.setSsid(LocalNativeUtil.byteArrayFromArrayList(
|
||||
LocalNativeUtil.decodeSsid(TEST_QUOTED_SSID_2)));
|
||||
network.setHidden(false);
|
||||
network.setFrequenciesMhz(TEST_FREQUENCIES_2);
|
||||
initPnoNetworks.add(network);
|
||||
TEST_PNO_SETTINGS.setPnoNetworks(initPnoNetworks);
|
||||
}
|
||||
|
||||
private static final int TEST_MCS_RATE = 5;
|
||||
private static final int TEST_SEND_MGMT_FRAME_ELAPSED_TIME_MS = 100;
|
||||
@@ -180,8 +186,9 @@ public class WifiCondManagerTest {
|
||||
when(mClientInterface.getWifiScannerImpl()).thenReturn(mWifiScannerImpl);
|
||||
when(mClientInterface.getInterfaceName()).thenReturn(TEST_INTERFACE_NAME);
|
||||
mWificondControl = new WifiCondManager(mContext, mWificond);
|
||||
assertEquals(true, mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME,
|
||||
mNormalScanCallback, mPnoScanCallback));
|
||||
assertEquals(true,
|
||||
mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, Runnable::run,
|
||||
mNormalScanCallback, mPnoScanCallback));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -264,7 +271,7 @@ public class WifiCondManagerTest {
|
||||
assertNull(mWificondControl.signalPoll(TEST_INTERFACE_NAME));
|
||||
verify(mClientInterface, never()).signalPoll();
|
||||
|
||||
assertFalse(mWificondControl.scan(
|
||||
assertFalse(mWificondControl.startScan(
|
||||
TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_LOW_LATENCY,
|
||||
SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST));
|
||||
verify(mWifiScannerImpl, never()).scan(any());
|
||||
@@ -348,8 +355,8 @@ public class WifiCondManagerTest {
|
||||
public void testTeardownSoftApInterfaceClearsHandles() throws Exception {
|
||||
testTeardownSoftApInterface();
|
||||
|
||||
assertFalse(mWificondControl.registerApListener(
|
||||
TEST_INTERFACE_NAME, mSoftApListener));
|
||||
assertFalse(mWificondControl.registerApCallback(
|
||||
TEST_INTERFACE_NAME, Runnable::run, mSoftApListener));
|
||||
verify(mApInterface, never()).registerCallback(any());
|
||||
}
|
||||
|
||||
@@ -417,8 +424,8 @@ public class WifiCondManagerTest {
|
||||
public void testSignalPoll() throws Exception {
|
||||
when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface);
|
||||
|
||||
mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, mNormalScanCallback,
|
||||
mPnoScanCallback);
|
||||
mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, Runnable::run,
|
||||
mNormalScanCallback, mPnoScanCallback);
|
||||
mWificondControl.signalPoll(TEST_INTERFACE_NAME);
|
||||
verify(mClientInterface).signalPoll();
|
||||
}
|
||||
@@ -432,7 +439,7 @@ public class WifiCondManagerTest {
|
||||
|
||||
// Configure client interface.
|
||||
assertEquals(true, mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME,
|
||||
mNormalScanCallback, mPnoScanCallback));
|
||||
Runnable::run, mNormalScanCallback, mPnoScanCallback));
|
||||
|
||||
// Tear down interfaces.
|
||||
assertTrue(mWificondControl.tearDownInterfaces());
|
||||
@@ -448,8 +455,8 @@ public class WifiCondManagerTest {
|
||||
public void testGetTxPacketCounters() throws Exception {
|
||||
when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface);
|
||||
|
||||
mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, mNormalScanCallback,
|
||||
mPnoScanCallback);
|
||||
mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, Runnable::run,
|
||||
mNormalScanCallback, mPnoScanCallback);
|
||||
mWificondControl.getTxPacketCounters(TEST_INTERFACE_NAME);
|
||||
verify(mClientInterface).getPacketCounters();
|
||||
}
|
||||
@@ -464,7 +471,7 @@ public class WifiCondManagerTest {
|
||||
|
||||
// Configure client interface.
|
||||
assertEquals(true, mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME,
|
||||
mNormalScanCallback, mPnoScanCallback));
|
||||
Runnable::run, mNormalScanCallback, mPnoScanCallback));
|
||||
|
||||
// Tear down interfaces.
|
||||
assertTrue(mWificondControl.tearDownInterfaces());
|
||||
@@ -483,7 +490,7 @@ public class WifiCondManagerTest {
|
||||
|
||||
// Configure client interface.
|
||||
assertEquals(true, mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME,
|
||||
mNormalScanCallback, mPnoScanCallback));
|
||||
Runnable::run, mNormalScanCallback, mPnoScanCallback));
|
||||
|
||||
// Tear down interfaces.
|
||||
assertTrue(mWificondControl.tearDownInterfaces());
|
||||
@@ -500,7 +507,7 @@ public class WifiCondManagerTest {
|
||||
@Test
|
||||
public void testScan() throws Exception {
|
||||
when(mWifiScannerImpl.scan(any(SingleScanSettings.class))).thenReturn(true);
|
||||
assertTrue(mWificondControl.scan(
|
||||
assertTrue(mWificondControl.startScan(
|
||||
TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_LOW_POWER,
|
||||
SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST));
|
||||
verify(mWifiScannerImpl).scan(argThat(new ScanMatcher(
|
||||
@@ -520,7 +527,7 @@ public class WifiCondManagerTest {
|
||||
assertEquals(hiddenSsidWithDup.get(0),
|
||||
hiddenSsidWithDup.get(hiddenSsidWithDup.size() - 1));
|
||||
// Pass the List with duplicate elements into scan()
|
||||
assertTrue(mWificondControl.scan(
|
||||
assertTrue(mWificondControl.startScan(
|
||||
TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_LOW_POWER,
|
||||
SCAN_FREQ_SET, hiddenSsidWithDup));
|
||||
// But the argument passed down should have the duplicate removed.
|
||||
@@ -535,7 +542,7 @@ public class WifiCondManagerTest {
|
||||
@Test
|
||||
public void testScanNullParameters() throws Exception {
|
||||
when(mWifiScannerImpl.scan(any(SingleScanSettings.class))).thenReturn(true);
|
||||
assertTrue(mWificondControl.scan(
|
||||
assertTrue(mWificondControl.startScan(
|
||||
TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_HIGH_ACCURACY, null, null));
|
||||
verify(mWifiScannerImpl).scan(argThat(new ScanMatcher(
|
||||
IWifiScannerImpl.SCAN_TYPE_HIGH_ACCURACY, null, null)));
|
||||
@@ -547,7 +554,7 @@ public class WifiCondManagerTest {
|
||||
@Test
|
||||
public void testScanFailure() throws Exception {
|
||||
when(mWifiScannerImpl.scan(any(SingleScanSettings.class))).thenReturn(false);
|
||||
assertFalse(mWificondControl.scan(
|
||||
assertFalse(mWificondControl.startScan(
|
||||
TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_LOW_LATENCY,
|
||||
SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST));
|
||||
verify(mWifiScannerImpl).scan(any(SingleScanSettings.class));
|
||||
@@ -558,7 +565,7 @@ public class WifiCondManagerTest {
|
||||
*/
|
||||
@Test
|
||||
public void testScanFailureDueToInvalidType() throws Exception {
|
||||
assertFalse(mWificondControl.scan(
|
||||
assertFalse(mWificondControl.startScan(
|
||||
TEST_INTERFACE_NAME, 100,
|
||||
SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST));
|
||||
verify(mWifiScannerImpl, never()).scan(any(SingleScanSettings.class));
|
||||
@@ -570,9 +577,10 @@ public class WifiCondManagerTest {
|
||||
@Test
|
||||
public void testStartPnoScan() throws Exception {
|
||||
when(mWifiScannerImpl.startPnoScan(any(PnoSettings.class))).thenReturn(true);
|
||||
assertTrue(mWificondControl.startPnoScan(TEST_INTERFACE_NAME, TEST_PNO_SETTINGS,
|
||||
mPnoScanRequestCallback));
|
||||
verify(mWifiScannerImpl).startPnoScan(argThat(new PnoScanMatcher(TEST_PNO_SETTINGS)));
|
||||
assertTrue(
|
||||
mWificondControl.startPnoScan(TEST_INTERFACE_NAME, TEST_PNO_SETTINGS, Runnable::run,
|
||||
mPnoScanRequestCallback));
|
||||
verify(mWifiScannerImpl).startPnoScan(eq(TEST_PNO_SETTINGS));
|
||||
verify(mPnoScanRequestCallback).onPnoRequestSucceeded();
|
||||
}
|
||||
|
||||
@@ -665,8 +673,9 @@ public class WifiCondManagerTest {
|
||||
public void testStartPnoScanForMetrics() throws Exception {
|
||||
when(mWifiScannerImpl.startPnoScan(any(PnoSettings.class))).thenReturn(false);
|
||||
|
||||
assertFalse(mWificondControl.startPnoScan(TEST_INTERFACE_NAME, TEST_PNO_SETTINGS,
|
||||
mPnoScanRequestCallback));
|
||||
assertFalse(
|
||||
mWificondControl.startPnoScan(TEST_INTERFACE_NAME, TEST_PNO_SETTINGS, Runnable::run,
|
||||
mPnoScanRequestCallback));
|
||||
verify(mPnoScanRequestCallback).onPnoRequestFailed();
|
||||
}
|
||||
|
||||
@@ -695,11 +704,11 @@ public class WifiCondManagerTest {
|
||||
final ArgumentCaptor<IApInterfaceEventCallback> apInterfaceCallbackCaptor =
|
||||
ArgumentCaptor.forClass(IApInterfaceEventCallback.class);
|
||||
|
||||
assertTrue(mWificondControl.registerApListener(
|
||||
TEST_INTERFACE_NAME, mSoftApListener));
|
||||
assertTrue(mWificondControl.registerApCallback(
|
||||
TEST_INTERFACE_NAME, Runnable::run, mSoftApListener));
|
||||
verify(mApInterface).registerCallback(apInterfaceCallbackCaptor.capture());
|
||||
|
||||
final NativeWifiClient testClient = new NativeWifiClient();
|
||||
final NativeWifiClient testClient = new NativeWifiClient(TEST_RAW_MAC_BYTES);
|
||||
apInterfaceCallbackCaptor.getValue().onConnectedClientsChanged(testClient, true);
|
||||
verify(mSoftApListener).onConnectedClientsChanged(eq(testClient), eq(true));
|
||||
|
||||
@@ -707,7 +716,8 @@ public class WifiCondManagerTest {
|
||||
int channelBandwidth = IApInterfaceEventCallback.BANDWIDTH_20;
|
||||
apInterfaceCallbackCaptor.getValue().onSoftApChannelSwitched(channelFrequency,
|
||||
channelBandwidth);
|
||||
verify(mSoftApListener).onSoftApChannelSwitched(eq(channelFrequency), eq(channelBandwidth));
|
||||
verify(mSoftApListener).onSoftApChannelSwitched(eq(channelFrequency),
|
||||
eq(SoftApInfo.CHANNEL_WIDTH_20MHZ));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -739,7 +749,7 @@ public class WifiCondManagerTest {
|
||||
verify(deathHandler).run();
|
||||
|
||||
// The handles should be cleared after death.
|
||||
assertNull(mWificondControl.getChannelsForBand(WifiScanner.WIFI_BAND_5_GHZ));
|
||||
assertEquals(0, mWificondControl.getChannelsMhzForBand(WifiScanner.WIFI_BAND_5_GHZ).length);
|
||||
verify(mWificond, never()).getAvailable5gNonDFSChannels();
|
||||
}
|
||||
|
||||
@@ -748,7 +758,8 @@ public class WifiCondManagerTest {
|
||||
*/
|
||||
@Test
|
||||
public void testSendMgmtFrameNullCallback() throws Exception {
|
||||
mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, null, TEST_MCS_RATE);
|
||||
mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE,
|
||||
Runnable::run, null);
|
||||
|
||||
verify(mClientInterface, never()).SendMgmtFrame(any(), any(), anyInt());
|
||||
}
|
||||
@@ -758,8 +769,8 @@ public class WifiCondManagerTest {
|
||||
*/
|
||||
@Test
|
||||
public void testSendMgmtFrameNullFrame() throws Exception {
|
||||
mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, null,
|
||||
mSendMgmtFrameCallback, TEST_MCS_RATE);
|
||||
mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, null, TEST_MCS_RATE, Runnable::run,
|
||||
mSendMgmtFrameCallback);
|
||||
|
||||
verify(mClientInterface, never()).SendMgmtFrame(any(), any(), anyInt());
|
||||
verify(mSendMgmtFrameCallback).onFailure(anyInt());
|
||||
@@ -770,8 +781,8 @@ public class WifiCondManagerTest {
|
||||
*/
|
||||
@Test
|
||||
public void testSendMgmtFrameInvalidInterfaceName() throws Exception {
|
||||
mWificondControl.sendMgmtFrame(TEST_INVALID_INTERFACE_NAME, TEST_PROBE_FRAME,
|
||||
mSendMgmtFrameCallback, TEST_MCS_RATE);
|
||||
mWificondControl.sendMgmtFrame(TEST_INVALID_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE,
|
||||
Runnable::run, mSendMgmtFrameCallback);
|
||||
|
||||
verify(mClientInterface, never()).SendMgmtFrame(any(), any(), anyInt());
|
||||
verify(mSendMgmtFrameCallback).onFailure(anyInt());
|
||||
@@ -787,13 +798,15 @@ public class WifiCondManagerTest {
|
||||
WifiCondManager.SendMgmtFrameCallback cb2 = mock(
|
||||
WifiCondManager.SendMgmtFrameCallback.class);
|
||||
|
||||
mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, cb1, TEST_MCS_RATE);
|
||||
mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE,
|
||||
Runnable::run, cb1);
|
||||
verify(cb1, never()).onFailure(anyInt());
|
||||
verify(mClientInterface, times(1))
|
||||
.SendMgmtFrame(AdditionalMatchers.aryEq(TEST_PROBE_FRAME),
|
||||
any(), eq(TEST_MCS_RATE));
|
||||
|
||||
mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, cb2, TEST_MCS_RATE);
|
||||
mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE,
|
||||
Runnable::run, cb2);
|
||||
verify(cb2).onFailure(WifiCondManager.SEND_MGMT_FRAME_ERROR_ALREADY_STARTED);
|
||||
// verify SendMgmtFrame() still was only called once i.e. not called again
|
||||
verify(mClientInterface, times(1))
|
||||
@@ -820,8 +833,8 @@ public class WifiCondManagerTest {
|
||||
doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(),
|
||||
alarmListenerCaptor.capture(), handlerCaptor.capture());
|
||||
|
||||
mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME,
|
||||
cb, TEST_MCS_RATE);
|
||||
mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE,
|
||||
Runnable::run, cb);
|
||||
mLooper.dispatchAll();
|
||||
|
||||
verify(cb).onFailure(anyInt());
|
||||
@@ -854,7 +867,8 @@ public class WifiCondManagerTest {
|
||||
final ArgumentCaptor<Handler> handlerCaptor = ArgumentCaptor.forClass(Handler.class);
|
||||
doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(),
|
||||
alarmListenerCaptor.capture(), handlerCaptor.capture());
|
||||
mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, cb, TEST_MCS_RATE);
|
||||
mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE,
|
||||
Runnable::run, cb);
|
||||
|
||||
sendMgmtFrameEventCaptor.getValue().OnAck(TEST_SEND_MGMT_FRAME_ELAPSED_TIME_MS);
|
||||
mLooper.dispatchAll();
|
||||
@@ -887,7 +901,8 @@ public class WifiCondManagerTest {
|
||||
final ArgumentCaptor<Handler> handlerCaptor = ArgumentCaptor.forClass(Handler.class);
|
||||
doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(),
|
||||
alarmListenerCaptor.capture(), handlerCaptor.capture());
|
||||
mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, cb, TEST_MCS_RATE);
|
||||
mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE,
|
||||
Runnable::run, cb);
|
||||
|
||||
sendMgmtFrameEventCaptor.getValue().OnFailure(
|
||||
WifiCondManager.SEND_MGMT_FRAME_ERROR_UNKNOWN);
|
||||
@@ -921,7 +936,8 @@ public class WifiCondManagerTest {
|
||||
final ArgumentCaptor<Handler> handlerCaptor = ArgumentCaptor.forClass(Handler.class);
|
||||
doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(),
|
||||
alarmListenerCaptor.capture(), handlerCaptor.capture());
|
||||
mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, cb, TEST_MCS_RATE);
|
||||
mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE,
|
||||
Runnable::run, cb);
|
||||
|
||||
handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm());
|
||||
mLooper.dispatchAll();
|
||||
@@ -987,8 +1003,8 @@ public class WifiCondManagerTest {
|
||||
final ArgumentCaptor<Handler> handlerCaptor = ArgumentCaptor.forClass(Handler.class);
|
||||
doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(),
|
||||
alarmListenerCaptor.capture(), handlerCaptor.capture());
|
||||
mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME,
|
||||
mSendMgmtFrameCallback, TEST_MCS_RATE);
|
||||
mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE,
|
||||
Runnable::run, mSendMgmtFrameCallback);
|
||||
|
||||
// AlarmManager should post the onAlarm() callback onto the handler, but since we are
|
||||
// triggering onAlarm() ourselves during the test, manually post onto handler
|
||||
@@ -1015,8 +1031,8 @@ public class WifiCondManagerTest {
|
||||
final ArgumentCaptor<Handler> handlerCaptor = ArgumentCaptor.forClass(Handler.class);
|
||||
doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(),
|
||||
alarmListenerCaptor.capture(), handlerCaptor.capture());
|
||||
mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME,
|
||||
mSendMgmtFrameCallback, TEST_MCS_RATE);
|
||||
mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE,
|
||||
Runnable::run, mSendMgmtFrameCallback);
|
||||
|
||||
// AlarmManager should post the onAlarm() callback onto the handler, but since we are
|
||||
// triggering onAlarm() ourselves during the test, manually post onto handler
|
||||
@@ -1086,56 +1102,6 @@ public class WifiCondManagerTest {
|
||||
}
|
||||
}
|
||||
|
||||
// Create a ArgumentMatcher which captures a PnoSettings parameter and checks if it
|
||||
// matches the WifiNative.PnoSettings;
|
||||
private class PnoScanMatcher implements ArgumentMatcher<PnoSettings> {
|
||||
private final PnoSettings mExpectedPnoSettings;
|
||||
|
||||
PnoScanMatcher(PnoSettings expectedPnoSettings) {
|
||||
this.mExpectedPnoSettings = expectedPnoSettings;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(PnoSettings settings) {
|
||||
if (mExpectedPnoSettings == null) {
|
||||
return false;
|
||||
}
|
||||
if (settings.intervalMs != mExpectedPnoSettings.intervalMs
|
||||
|| settings.min2gRssi != mExpectedPnoSettings.min2gRssi
|
||||
|| settings.min5gRssi != mExpectedPnoSettings.min5gRssi
|
||||
|| settings.min6gRssi != mExpectedPnoSettings.min6gRssi) {
|
||||
return false;
|
||||
}
|
||||
if (settings.pnoNetworks == null || mExpectedPnoSettings.pnoNetworks == null) {
|
||||
return false;
|
||||
}
|
||||
if (settings.pnoNetworks.size() != mExpectedPnoSettings.pnoNetworks.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < settings.pnoNetworks.size(); i++) {
|
||||
if (!Arrays.equals(settings.pnoNetworks.get(i).ssid,
|
||||
mExpectedPnoSettings.pnoNetworks.get(i).ssid)) {
|
||||
return false;
|
||||
}
|
||||
if (settings.pnoNetworks.get(i).isHidden != mExpectedPnoSettings.pnoNetworks.get(
|
||||
i).isHidden) {
|
||||
return false;
|
||||
}
|
||||
if (!Arrays.equals(settings.pnoNetworks.get(i).frequencies,
|
||||
mExpectedPnoSettings.pnoNetworks.get(i).frequencies)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PnoScanMatcher{" + "mExpectedPnoSettings=" + mExpectedPnoSettings + '}';
|
||||
}
|
||||
}
|
||||
|
||||
private static class LocalNativeUtil {
|
||||
private static final int SSID_BYTES_MAX_LEN = 32;
|
||||
|
||||
Reference in New Issue
Block a user