492 lines
18 KiB
Java
492 lines
18 KiB
Java
/*
|
|
* Copyright (C) 2016 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package android.net.wifi.aware;
|
|
|
|
import android.annotation.FlaggedApi;
|
|
import android.annotation.NonNull;
|
|
import android.annotation.RequiresApi;
|
|
import android.annotation.SystemApi;
|
|
import android.net.wifi.OuiKeyedData;
|
|
import android.net.wifi.ParcelUtil;
|
|
import android.os.Build;
|
|
import android.os.Parcel;
|
|
import android.os.Parcelable;
|
|
|
|
import com.android.modules.utils.build.SdkLevel;
|
|
import com.android.wifi.flags.Flags;
|
|
|
|
import java.util.Arrays;
|
|
import java.util.Collections;
|
|
import java.util.List;
|
|
import java.util.Objects;
|
|
|
|
/**
|
|
* Defines a request object to configure a Wi-Fi Aware network. Built using
|
|
* {@link ConfigRequest.Builder}. Configuration is requested using
|
|
* {@link WifiAwareManager#attach(AttachCallback, android.os.Handler)}.
|
|
* Note that the actual achieved configuration may be different from the
|
|
* requested configuration - since different applications may request different
|
|
* configurations.
|
|
*
|
|
* @hide
|
|
*/
|
|
@FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
|
|
@SystemApi
|
|
public final class ConfigRequest implements Parcelable {
|
|
/**
|
|
* Lower range of possible cluster ID.
|
|
* @hide
|
|
*/
|
|
public static final int CLUSTER_ID_MIN = 0;
|
|
|
|
/**
|
|
* Upper range of possible cluster ID.
|
|
* @hide
|
|
*/
|
|
public static final int CLUSTER_ID_MAX = 0xFFFF;
|
|
|
|
/**
|
|
* Indices for configuration variables which are specified per band.
|
|
* @hide
|
|
*/
|
|
public static final int NAN_BAND_24GHZ = 0;
|
|
|
|
/** @hide */
|
|
public static final int NAN_BAND_5GHZ = 1;
|
|
|
|
/** @hide */
|
|
public static final int NAN_BAND_6GHZ = 2;
|
|
|
|
/**
|
|
* Magic values for Discovery Window (DW) interval configuration
|
|
* @hide
|
|
*/
|
|
public static final int DW_INTERVAL_NOT_INIT = -1;
|
|
|
|
/** @hide */
|
|
public static final int DW_DISABLE = 0; // only valid for 5GHz
|
|
|
|
/**
|
|
* Indicates whether 5G band support is requested.
|
|
* @hide
|
|
*/
|
|
public final boolean mSupport5gBand;
|
|
|
|
/**
|
|
* Indicates whether 6G band support is requested.
|
|
* @hide
|
|
*/
|
|
public final boolean mSupport6gBand;
|
|
|
|
/**
|
|
* Specifies the desired master preference.
|
|
* @hide
|
|
*/
|
|
public int mMasterPreference;
|
|
|
|
/**
|
|
* Specifies the desired lower range of the cluster ID. Must be lower than
|
|
* {@link ConfigRequest#mClusterHigh}.
|
|
* @hide
|
|
*/
|
|
public final int mClusterLow;
|
|
|
|
/**
|
|
* Specifies the desired higher range of the cluster ID. Must be higher than
|
|
* {@link ConfigRequest#mClusterLow}.
|
|
* @hide
|
|
*/
|
|
public final int mClusterHigh;
|
|
|
|
/**
|
|
* Specifies the discovery window interval for the device on NAN_BAND_*.
|
|
* @hide
|
|
*/
|
|
public final int mDiscoveryWindowInterval[];
|
|
|
|
/**
|
|
* List of {@link OuiKeyedData} providing vendor-specific configuration data.
|
|
*/
|
|
private final List<OuiKeyedData> mVendorData;
|
|
|
|
private ConfigRequest(boolean support5gBand, boolean support6gBand, int masterPreference,
|
|
int clusterLow, int clusterHigh, int[] discoveryWindowInterval,
|
|
@NonNull List<OuiKeyedData> vendorData) {
|
|
mSupport5gBand = support5gBand;
|
|
mSupport6gBand = support6gBand;
|
|
mMasterPreference = masterPreference;
|
|
mClusterLow = clusterLow;
|
|
mClusterHigh = clusterHigh;
|
|
mDiscoveryWindowInterval = discoveryWindowInterval;
|
|
mVendorData = vendorData;
|
|
}
|
|
|
|
@FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
|
|
@Override
|
|
public String toString() {
|
|
return "ConfigRequest [mSupport5gBand=" + mSupport5gBand
|
|
+ ", mSupport6gBand=" + mSupport6gBand
|
|
+ ", mMasterPreference=" + mMasterPreference
|
|
+ ", mClusterLow=" + mClusterLow
|
|
+ ", mClusterHigh=" + mClusterHigh
|
|
+ ", mDiscoveryWindowInterval=" + Arrays.toString(mDiscoveryWindowInterval)
|
|
+ ", mVendorData=" + mVendorData
|
|
+ "]";
|
|
}
|
|
|
|
@FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
|
|
@Override
|
|
public int describeContents() {
|
|
return 0;
|
|
}
|
|
|
|
@FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
|
|
@Override
|
|
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
|
dest.writeInt(mSupport5gBand ? 1 : 0);
|
|
dest.writeInt(mSupport6gBand ? 1 : 0);
|
|
dest.writeInt(mMasterPreference);
|
|
dest.writeInt(mClusterLow);
|
|
dest.writeInt(mClusterHigh);
|
|
dest.writeIntArray(mDiscoveryWindowInterval);
|
|
dest.writeList(mVendorData);
|
|
}
|
|
|
|
@FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
|
|
public static final @android.annotation.NonNull Creator<ConfigRequest> CREATOR = new Creator<ConfigRequest>() {
|
|
@Override
|
|
public ConfigRequest[] newArray(int size) {
|
|
return new ConfigRequest[size];
|
|
}
|
|
|
|
@Override
|
|
public ConfigRequest createFromParcel(Parcel in) {
|
|
boolean support5gBand = in.readInt() != 0;
|
|
boolean support6gBand = in.readInt() != 0;
|
|
int masterPreference = in.readInt();
|
|
int clusterLow = in.readInt();
|
|
int clusterHigh = in.readInt();
|
|
int discoveryWindowInterval[] = in.createIntArray();
|
|
List<OuiKeyedData> vendorData = ParcelUtil.readOuiKeyedDataList(in);
|
|
|
|
return new ConfigRequest(support5gBand, support6gBand, masterPreference, clusterLow,
|
|
clusterHigh, discoveryWindowInterval, vendorData);
|
|
}
|
|
};
|
|
|
|
@FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
|
|
@Override
|
|
public boolean equals(Object o) {
|
|
if (this == o) {
|
|
return true;
|
|
}
|
|
|
|
if (!(o instanceof ConfigRequest)) {
|
|
return false;
|
|
}
|
|
|
|
ConfigRequest lhs = (ConfigRequest) o;
|
|
|
|
return mSupport5gBand == lhs.mSupport5gBand
|
|
&& mSupport6gBand == lhs.mSupport6gBand
|
|
&& mMasterPreference == lhs.mMasterPreference
|
|
&& mClusterLow == lhs.mClusterLow && mClusterHigh == lhs.mClusterHigh
|
|
&& Arrays.equals(mDiscoveryWindowInterval, lhs.mDiscoveryWindowInterval)
|
|
&& Objects.equals(mVendorData, lhs.mVendorData);
|
|
}
|
|
|
|
@FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
|
|
@Override
|
|
public int hashCode() {
|
|
int result = 17;
|
|
|
|
result = 31 * result + (mSupport5gBand ? 1 : 0);
|
|
result = 31 * result + (mSupport6gBand ? 1 : 0);
|
|
result = 31 * result + mMasterPreference;
|
|
result = 31 * result + mClusterLow;
|
|
result = 31 * result + mClusterHigh;
|
|
result = 31 * result + Arrays.hashCode(mDiscoveryWindowInterval);
|
|
result = 31 * result + mVendorData.hashCode();
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Verifies that the contents of the ConfigRequest are valid. Otherwise
|
|
* throws an IllegalArgumentException.
|
|
* @hide
|
|
*/
|
|
public void validate() throws IllegalArgumentException {
|
|
if (mMasterPreference < 0) {
|
|
throw new IllegalArgumentException(
|
|
"Master Preference specification must be non-negative");
|
|
}
|
|
if (mMasterPreference == 1 || mMasterPreference == 255 || mMasterPreference > 255) {
|
|
throw new IllegalArgumentException("Master Preference specification must not "
|
|
+ "exceed 255 or use 1 or 255 (reserved values)");
|
|
}
|
|
if (mClusterLow < CLUSTER_ID_MIN) {
|
|
throw new IllegalArgumentException("Cluster specification must be non-negative");
|
|
}
|
|
if (mClusterLow > CLUSTER_ID_MAX) {
|
|
throw new IllegalArgumentException("Cluster specification must not exceed 0xFFFF");
|
|
}
|
|
if (mClusterHigh < CLUSTER_ID_MIN) {
|
|
throw new IllegalArgumentException("Cluster specification must be non-negative");
|
|
}
|
|
if (mClusterHigh > CLUSTER_ID_MAX) {
|
|
throw new IllegalArgumentException("Cluster specification must not exceed 0xFFFF");
|
|
}
|
|
if (mClusterLow > mClusterHigh) {
|
|
throw new IllegalArgumentException(
|
|
"Invalid argument combination - must have Cluster Low <= Cluster High");
|
|
}
|
|
if (mDiscoveryWindowInterval.length != 3) {
|
|
throw new IllegalArgumentException(
|
|
"Invalid discovery window interval: must have 3 elements (2.4 & 5 & 6");
|
|
}
|
|
if (mDiscoveryWindowInterval[NAN_BAND_24GHZ] != DW_INTERVAL_NOT_INIT &&
|
|
(mDiscoveryWindowInterval[NAN_BAND_24GHZ] < 1 // valid for 2.4GHz: [1-5]
|
|
|| mDiscoveryWindowInterval[NAN_BAND_24GHZ] > 5)) {
|
|
throw new IllegalArgumentException(
|
|
"Invalid discovery window interval for 2.4GHz: valid is UNSET or [1,5]");
|
|
}
|
|
if (mDiscoveryWindowInterval[NAN_BAND_5GHZ] != DW_INTERVAL_NOT_INIT &&
|
|
(mDiscoveryWindowInterval[NAN_BAND_5GHZ] < 0 // valid for 5GHz: [0-5]
|
|
|| mDiscoveryWindowInterval[NAN_BAND_5GHZ] > 5)) {
|
|
throw new IllegalArgumentException(
|
|
"Invalid discovery window interval for 5GHz: valid is UNSET or [0,5]");
|
|
}
|
|
if (mDiscoveryWindowInterval[NAN_BAND_6GHZ] != DW_INTERVAL_NOT_INIT
|
|
&& (mDiscoveryWindowInterval[NAN_BAND_6GHZ] < 0 // valid for 6GHz: [0-5]
|
|
|| mDiscoveryWindowInterval[NAN_BAND_6GHZ] > 5)) {
|
|
throw new IllegalArgumentException(
|
|
"Invalid discovery window interval for 6GHz: valid is UNSET or [0,5]");
|
|
}
|
|
if (mVendorData == null) {
|
|
throw new IllegalArgumentException("Vendor data list must be non-null");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get the vendor-provided configuration data, if it exists. See {@link
|
|
* Builder#setVendorData(List)}
|
|
*
|
|
* @return Vendor configuration data, or empty list if it does not exist.
|
|
* @hide
|
|
*/
|
|
@RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
|
|
@FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
|
|
@SystemApi
|
|
@NonNull
|
|
public List<OuiKeyedData> getVendorData() {
|
|
if (!SdkLevel.isAtLeastV()) {
|
|
throw new UnsupportedOperationException();
|
|
}
|
|
return mVendorData != null ? mVendorData : Collections.emptyList();
|
|
}
|
|
|
|
/**
|
|
* Builder used to build {@link ConfigRequest} objects.
|
|
*/
|
|
@FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
|
|
public static final class Builder {
|
|
private boolean mSupport5gBand = true;
|
|
private boolean mSupport6gBand = false;
|
|
private int mMasterPreference = 0;
|
|
private int mClusterLow = CLUSTER_ID_MIN;
|
|
private int mClusterHigh = CLUSTER_ID_MAX;
|
|
private int[] mDiscoveryWindowInterval = {DW_INTERVAL_NOT_INIT, DW_INTERVAL_NOT_INIT,
|
|
DW_INTERVAL_NOT_INIT};
|
|
private List<OuiKeyedData> mVendorData = Collections.emptyList();
|
|
|
|
/**
|
|
* Specify whether 5G band support is required in this request. Disabled by default.
|
|
*
|
|
* @param support5gBand Support for 5G band is required.
|
|
*
|
|
* @return The builder to facilitate chaining
|
|
* {@code builder.setXXX(..).setXXX(..)}.
|
|
* @hide
|
|
*/
|
|
public Builder setSupport5gBand(boolean support5gBand) {
|
|
mSupport5gBand = support5gBand;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Specify whether 6G band support is required in this request. Disabled by default.
|
|
*
|
|
* @param support6gBand Support for 6G band is required.
|
|
*
|
|
* @return The builder to facilitate chaining
|
|
* {@code builder.setXXX(..).setXXX(..)}.
|
|
* @hide
|
|
*/
|
|
public Builder setSupport6gBand(boolean support6gBand) {
|
|
mSupport6gBand = support6gBand;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Specify the Master Preference requested. The permitted range is 0 (the default) to
|
|
* 255 with 1 and 255 excluded (reserved).
|
|
*
|
|
* @param masterPreference The requested master preference
|
|
*
|
|
* @return The builder to facilitate chaining
|
|
* {@code builder.setXXX(..).setXXX(..)}.
|
|
* @hide
|
|
*/
|
|
public Builder setMasterPreference(int masterPreference) {
|
|
if (masterPreference < 0) {
|
|
throw new IllegalArgumentException(
|
|
"Master Preference specification must be non-negative");
|
|
}
|
|
if (masterPreference == 1 || masterPreference == 255 || masterPreference > 255) {
|
|
throw new IllegalArgumentException("Master Preference specification must not "
|
|
+ "exceed 255 or use 1 or 255 (reserved values)");
|
|
}
|
|
|
|
mMasterPreference = masterPreference;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* The Cluster ID is generated randomly for new Aware networks. Specify
|
|
* the lower range of the cluster ID. The upper range is specified using
|
|
* the {@link ConfigRequest.Builder#setClusterHigh(int)}. The permitted
|
|
* range is 0 (the default) to the value specified by
|
|
* {@link ConfigRequest.Builder#setClusterHigh(int)}. Equality of Low and High is
|
|
* permitted which restricts the Cluster ID to the specified value.
|
|
*
|
|
* @param clusterLow The lower range of the generated cluster ID.
|
|
*
|
|
* @return The builder to facilitate chaining
|
|
* {@code builder.setClusterLow(..).setClusterHigh(..)}.
|
|
* @hide
|
|
*/
|
|
public Builder setClusterLow(int clusterLow) {
|
|
if (clusterLow < CLUSTER_ID_MIN) {
|
|
throw new IllegalArgumentException("Cluster specification must be non-negative");
|
|
}
|
|
if (clusterLow > CLUSTER_ID_MAX) {
|
|
throw new IllegalArgumentException("Cluster specification must not exceed 0xFFFF");
|
|
}
|
|
|
|
mClusterLow = clusterLow;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* The Cluster ID is generated randomly for new Aware networks. Specify
|
|
* the lower upper of the cluster ID. The lower range is specified using
|
|
* the {@link ConfigRequest.Builder#setClusterLow(int)}. The permitted
|
|
* range is the value specified by
|
|
* {@link ConfigRequest.Builder#setClusterLow(int)} to 0xFFFF (the default). Equality of
|
|
* Low and High is permitted which restricts the Cluster ID to the specified value.
|
|
*
|
|
* @param clusterHigh The upper range of the generated cluster ID.
|
|
*
|
|
* @return The builder to facilitate chaining
|
|
* {@code builder.setClusterLow(..).setClusterHigh(..)}.
|
|
* @hide
|
|
*/
|
|
public Builder setClusterHigh(int clusterHigh) {
|
|
if (clusterHigh < CLUSTER_ID_MIN) {
|
|
throw new IllegalArgumentException("Cluster specification must be non-negative");
|
|
}
|
|
if (clusterHigh > CLUSTER_ID_MAX) {
|
|
throw new IllegalArgumentException("Cluster specification must not exceed 0xFFFF");
|
|
}
|
|
|
|
mClusterHigh = clusterHigh;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* The discovery window interval specifies the discovery windows in which the device will be
|
|
* awake. The configuration enables trading off latency vs. power (higher interval means
|
|
* higher discovery latency but lower power).
|
|
*
|
|
* @param band Either {@link #NAN_BAND_24GHZ} or {@link #NAN_BAND_5GHZ} or
|
|
* {@link #NAN_BAND_6GHZ}.
|
|
* @param interval A value of 1, 2, 3, 4, or 5 indicating an interval of 2^(interval-1). For
|
|
* the 5GHz band a value of 0 indicates that the device will not be awake
|
|
* for any discovery windows.
|
|
*
|
|
* @return The builder itself to facilitate chaining operations
|
|
* {@code builder.setDiscoveryWindowInterval(...).setMasterPreference(...)}.
|
|
* @hide
|
|
*/
|
|
public Builder setDiscoveryWindowInterval(int band, int interval) {
|
|
if (band != NAN_BAND_24GHZ && band != NAN_BAND_5GHZ && band != NAN_BAND_6GHZ) {
|
|
throw new IllegalArgumentException("Invalid band value");
|
|
}
|
|
if ((band == NAN_BAND_24GHZ && (interval < 1 || interval > 5))
|
|
|| (band == NAN_BAND_5GHZ && (interval < 0 || interval > 5))
|
|
|| (band == NAN_BAND_6GHZ && (interval < 0 || interval > 5))) {
|
|
throw new IllegalArgumentException(
|
|
"Invalid interval value: 2.4 GHz [1,5] or 5GHz/6GHz [0,5]");
|
|
}
|
|
|
|
mDiscoveryWindowInterval[band] = interval;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set additional vendor-provided configuration data.
|
|
*
|
|
* @param vendorData List of {@link android.net.wifi.OuiKeyedData} containing the
|
|
* vendor-provided configuration data. Note that multiple elements with
|
|
* the same OUI are allowed.
|
|
* @return Builder for chaining.
|
|
* @hide
|
|
*/
|
|
@RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
|
|
@FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
|
|
@SystemApi
|
|
@NonNull
|
|
public Builder setVendorData(@NonNull List<OuiKeyedData> vendorData) {
|
|
if (!SdkLevel.isAtLeastV()) {
|
|
throw new UnsupportedOperationException();
|
|
}
|
|
if (vendorData == null) {
|
|
throw new IllegalArgumentException("setVendorData received a null value");
|
|
}
|
|
mVendorData = vendorData;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Build {@link ConfigRequest} given the current requests made on the
|
|
* builder.
|
|
*/
|
|
@FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
|
|
@NonNull
|
|
public ConfigRequest build() {
|
|
if (mClusterLow > mClusterHigh) {
|
|
throw new IllegalArgumentException(
|
|
"Invalid argument combination - must have Cluster Low <= Cluster High");
|
|
}
|
|
|
|
return new ConfigRequest(mSupport5gBand, mSupport6gBand, mMasterPreference, mClusterLow,
|
|
mClusterHigh, mDiscoveryWindowInterval, mVendorData);
|
|
}
|
|
}
|
|
}
|