1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.net.wifi;
18 
19 import android.annotation.LongDef;
20 import android.annotation.NonNull;
21 import android.annotation.Nullable;
22 import android.annotation.SystemApi;
23 import android.os.Parcel;
24 import android.os.Parcelable;
25 
26 import java.lang.annotation.Retention;
27 import java.lang.annotation.RetentionPolicy;
28 import java.util.Objects;
29 
30 /**
31  * A class representing capability of the SoftAp.
32  * {@see WifiManager}
33  *
34  * @hide
35  */
36 @SystemApi
37 public final class SoftApCapability implements Parcelable {
38 
39     /**
40      * Support for automatic channel selection in driver (ACS).
41      * Driver will auto select best channel based on interference to optimize performance.
42      *
43      * flag when {@link R.bool.config_wifi_softap_acs_supported)} is true.
44      *
45      * <p>
46      * Use {@link WifiManager.SoftApCallback#onInfoChanged(SoftApInfo)} and
47      * {@link SoftApInfo#getFrequency} and {@link SoftApInfo#getBandwidth} to get
48      * driver channel selection result.
49      */
50     public static final long SOFTAP_FEATURE_ACS_OFFLOAD = 1 << 0;
51 
52     /**
53      * Support for client force disconnect.
54      * flag when {@link R.bool.config_wifi_sofap_client_force_disconnect_supported)} is true
55      *
56      * <p>
57      * Several Soft AP client control features, e.g. specifying the maximum number of
58      * Soft AP clients, only work when this feature support is present.
59      * Check feature support before invoking
60      * {@link SoftApConfiguration.Builder#setMaxNumberOfClients(int)}
61      */
62     public static final long SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT = 1 << 1;
63 
64 
65     /**
66      * Support for WPA3 Simultaneous Authentication of Equals (WPA3-SAE).
67      *
68      * flag when {@link config_wifi_softap_sae_supported)} is true.
69      */
70     public static final long SOFTAP_FEATURE_WPA3_SAE = 1 << 2;
71 
72     /** @hide */
73     @Retention(RetentionPolicy.SOURCE)
74     @LongDef(flag = true, prefix = { "SOFTAP_FEATURE_" }, value = {
75             SOFTAP_FEATURE_ACS_OFFLOAD,
76             SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT,
77             SOFTAP_FEATURE_WPA3_SAE,
78     })
79     public @interface HotspotFeatures {}
80 
81     private @HotspotFeatures long mSupportedFeatures = 0;
82 
83     private int mMaximumSupportedClientNumber;
84 
85     /**
86      * Get the maximum supported client numbers which AP resides on.
87      */
getMaxSupportedClients()88     public int getMaxSupportedClients() {
89         return mMaximumSupportedClientNumber;
90     }
91 
92     /**
93      * Set the maximum supported client numbers which AP resides on.
94      *
95      * @param maxClient maximum supported client numbers for the softap.
96      * @hide
97      */
setMaxSupportedClients(int maxClient)98     public void setMaxSupportedClients(int maxClient) {
99         mMaximumSupportedClientNumber = maxClient;
100     }
101 
102     /**
103      * Returns true when all of the queried features are supported, otherwise false.
104      *
105      * @param features One or combination of the following features:
106      * {@link #SOFTAP_FEATURE_ACS_OFFLOAD}, {@link #SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT} or
107      * {@link #SOFTAP_FEATURE_WPA3_SAE}.
108      */
areFeaturesSupported(@otspotFeatures long features)109     public boolean areFeaturesSupported(@HotspotFeatures long features) {
110         return (mSupportedFeatures & features) == features;
111     }
112 
113     /**
114      * @hide
115      */
SoftApCapability(@ullable SoftApCapability source)116     public SoftApCapability(@Nullable SoftApCapability source) {
117         if (source != null) {
118             mSupportedFeatures = source.mSupportedFeatures;
119             mMaximumSupportedClientNumber = source.mMaximumSupportedClientNumber;
120         }
121     }
122 
123     /**
124      * Constructor with combination of the feature.
125      * Zero to no supported feature.
126      *
127      * @param features One or combination of the following features:
128      * {@link #SOFTAP_FEATURE_ACS_OFFLOAD}, {@link #SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT} or
129      * {@link #SOFTAP_FEATURE_WPA3_SAE}.
130      * @hide
131      */
SoftApCapability(@otspotFeatures long features)132     public SoftApCapability(@HotspotFeatures long features) {
133         mSupportedFeatures = features;
134     }
135 
136     @Override
137     /** Implement the Parcelable interface. */
describeContents()138     public int describeContents() {
139         return 0;
140     }
141 
142     @Override
143     /** Implement the Parcelable interface */
writeToParcel(@onNull Parcel dest, int flags)144     public void writeToParcel(@NonNull Parcel dest, int flags) {
145         dest.writeLong(mSupportedFeatures);
146         dest.writeInt(mMaximumSupportedClientNumber);
147     }
148 
149     @NonNull
150     /** Implement the Parcelable interface */
151     public static final Creator<SoftApCapability> CREATOR = new Creator<SoftApCapability>() {
152         public SoftApCapability createFromParcel(Parcel in) {
153             long supportedFeatures = in.readLong();
154             SoftApCapability capability = new SoftApCapability(supportedFeatures);
155             capability.mMaximumSupportedClientNumber = in.readInt();
156             return capability;
157         }
158 
159         public SoftApCapability[] newArray(int size) {
160             return new SoftApCapability[size];
161         }
162     };
163 
164     @NonNull
165     @Override
toString()166     public String toString() {
167         StringBuilder sbuf = new StringBuilder();
168         sbuf.append("SupportedFeatures=").append(mSupportedFeatures);
169         sbuf.append("MaximumSupportedClientNumber=").append(mMaximumSupportedClientNumber);
170         return sbuf.toString();
171     }
172 
173     @Override
equals(@onNull Object o)174     public boolean equals(@NonNull Object o) {
175         if (this == o) return true;
176         if (!(o instanceof SoftApCapability)) return false;
177         SoftApCapability capability = (SoftApCapability) o;
178         return mSupportedFeatures == capability.mSupportedFeatures
179                 && mMaximumSupportedClientNumber == capability.mMaximumSupportedClientNumber;
180     }
181 
182     @Override
hashCode()183     public int hashCode() {
184         return Objects.hash(mSupportedFeatures, mMaximumSupportedClientNumber);
185     }
186 }
187