• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012 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.p2p;
18 
19 import android.annotation.IntDef;
20 import android.annotation.IntRange;
21 import android.annotation.NonNull;
22 import android.annotation.Nullable;
23 import android.compat.annotation.UnsupportedAppUsage;
24 import android.os.Build;
25 import android.os.Parcel;
26 import android.os.Parcelable;
27 
28 import androidx.annotation.RequiresApi;
29 
30 import com.android.modules.utils.build.SdkLevel;
31 
32 import java.lang.annotation.Retention;
33 import java.lang.annotation.RetentionPolicy;
34 import java.util.Locale;
35 
36 /**
37  * A class representing Wifi Display information for a device.
38  *
39  * See Wifi Display technical specification v1.0.0, section 5.1.2.
40  * See Wifi Display technical specification v2.0.0, section 5.1.12 for Wifi Display R2.
41  */
42 public final class WifiP2pWfdInfo implements Parcelable {
43 
44     private boolean mEnabled;
45 
46     /** Device information bitmap */
47     private int mDeviceInfo;
48 
49     /** R2 Device information bitmap */
50     private int mR2DeviceInfo = -1;
51 
52     /** @hide */
53     @Retention(RetentionPolicy.SOURCE)
54     @IntDef(prefix = { "DEVICE_TYPE_" }, value = {
55             DEVICE_TYPE_WFD_SOURCE,
56             DEVICE_TYPE_PRIMARY_SINK,
57             DEVICE_TYPE_SECONDARY_SINK,
58             DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK})
59     public @interface DeviceType {}
60 
61     /** The device is a Wifi Display Source. */
62     public static final int DEVICE_TYPE_WFD_SOURCE = 0;
63     /** The device is a primary sink. */
64     public static final int DEVICE_TYPE_PRIMARY_SINK = 1;
65     /** The device is a secondary sink. This type is only supported by R1. */
66     public static final int DEVICE_TYPE_SECONDARY_SINK = 2;
67     /** The device is dual-role capable i.e. either a WFD source or a primary sink. */
68     public static final int DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK = 3;
69 
70     /** @hide */
71     @Retention(RetentionPolicy.SOURCE)
72     @IntDef(prefix = { "PREFERRED_CONNECTIVITY_" }, value = {
73             PREFERRED_CONNECTIVITY_P2P,
74             PREFERRED_CONNECTIVITY_TDLS})
75     public @interface PreferredConnectivity {}
76 
77     /** Wifi Display (WFD) preferred connectivity is Wifi Direct (P2P). */
78     public static final int PREFERRED_CONNECTIVITY_P2P = 0;
79     /** Wifi Display (WFD) preferred connectivity is TDLS. */
80     public static final int PREFERRED_CONNECTIVITY_TDLS = 1;
81 
82     /** @hide */
83     @Retention(RetentionPolicy.SOURCE)
84     @IntDef(flag = true, prefix = {"DEVICE_INFO_"}, value = {
85             DEVICE_INFO_DEVICE_TYPE_MASK,
86             DEVICE_INFO_COUPLED_SINK_SUPPORT_AT_SOURCE,
87             DEVICE_INFO_COUPLED_SINK_SUPPORT_AT_SINK,
88             DEVICE_INFO_SESSION_AVAILABLE_MASK,
89             DEVICE_INFO_WFD_SERVICE_DISCOVERY_SUPPORT,
90             DEVICE_INFO_PREFERRED_CONNECTIVITY_MASK,
91             DEVICE_INFO_CONTENT_PROTECTION_SUPPORT,
92             DEVICE_INFO_TIME_SYNCHRONIZATION_SUPPORT,
93             DEVICE_INFO_AUDIO_UNSUPPORTED_AT_PRIMARY_SINK,
94             DEVICE_INFO_AUDIO_ONLY_SUPPORT_AT_SOURCE,
95             DEVICE_INFO_TDLS_PERSISTENT_GROUP,
96             DEVICE_INFO_TDLS_PERSISTENT_GROUP_REINVOKE})
97     public @interface DeviceInfoMask {}
98 
99     /** @hide */
100     @Retention(RetentionPolicy.SOURCE)
101     @IntDef(flag = true, prefix = {"DEVICE_INFO_"}, value = {DEVICE_INFO_DEVICE_TYPE_MASK})
102     public @interface R2DeviceInfoMask {}
103 
104     /**
105      * {@link #getDeviceInfo()} & {@link #DEVICE_INFO_DEVICE_TYPE_MASK} is one of
106      * {@link #DEVICE_TYPE_WFD_SOURCE}, {@link #DEVICE_TYPE_PRIMARY_SINK},
107      * {@link #DEVICE_TYPE_SECONDARY_SINK} or {@link #DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK}.
108      *
109      * The bit definition is listed in 5.1.2 WFD Device Information Subelement and
110      * 5.1.12 WFD R2 Device Information Subelement in Wifi Display Technical Specification.
111      */
112     public static final int DEVICE_INFO_DEVICE_TYPE_MASK = 1 << 1 | 1 << 0;
113     /**
114      * Bit field for {@link #getDeviceInfo()}, indicates that coupled sink is supported at source.
115      *
116      * The bit definition is listed in 5.1.2 WFD Device Information Subelement in
117      * Wifi Display Technical Specification.
118      */
119     public static final int DEVICE_INFO_COUPLED_SINK_SUPPORT_AT_SOURCE = 1 << 2;
120     /**
121      * Bit field for {@link #getDeviceInfo()}, indicates that coupled sink is supporeted at sink.
122      *
123      * The bit definition is listed in 5.1.2 WFD Device Information Subelement in
124      * Wifi Display Technical Specification.
125      */
126     public static final int DEVICE_INFO_COUPLED_SINK_SUPPORT_AT_SINK = 1 << 3;
127     private static final int SESSION_AVAILABLE_BIT1 = 1 << 4;
128     private static final int SESSION_AVAILABLE_BIT2 = 1 << 5;
129     /**
130      * Bit field for {@link #getDeviceInfo()}, indicates that Wifi Display session is available.
131      *
132      * The bit definition is listed in 5.1.2 WFD Device Information Subelement in
133      * Wifi Display Technical Specification.
134      */
135     public static final int DEVICE_INFO_SESSION_AVAILABLE_MASK =
136             SESSION_AVAILABLE_BIT2 | SESSION_AVAILABLE_BIT1;
137     /**
138      * Bit field for {@link #getDeviceInfo()}, indicates that Wifi Display discovery is supported.
139      *
140      * The bit definition is listed in 5.1.2 WFD Device Information Subelement in
141      * Wifi Display Technical Specification.
142      */
143     public static final int DEVICE_INFO_WFD_SERVICE_DISCOVERY_SUPPORT = 1 << 6;
144     /**
145      * Bit field for {@link #getDeviceInfo()}, indicate the preferred connectifity for Wifi Display.
146      *
147      * The bit definition is listed in 5.1.2 WFD Device Information Subelement in
148      * Wifi Display Technical Specification.
149      * The value is one of {@link #PREFERRED_CONNECTIVITY_P2P} or
150      * {@link #PREFERRED_CONNECTIVITY_TDLS}.
151      */
152     public static final int DEVICE_INFO_PREFERRED_CONNECTIVITY_MASK = 1 << 7;
153     /**
154      * Bit field for {@link #getDeviceInfo()}, indicate the support of Content Protection
155      * using the HDCP system 2.0/2.1.
156      *
157      * The bit definition is listed in 5.1.2 WFD Device Information Subelement in
158      * Wifi Display Technical Specification.
159      */
160     public static final int DEVICE_INFO_CONTENT_PROTECTION_SUPPORT = 1 << 8;
161     /**
162      * Bit field for {@link #getDeviceInfo()}, indicate time synchronization
163      * using 802.1AS is supported.
164      *
165      * The bit definition is listed in 5.1.2 WFD Device Information Subelement in
166      * Wifi Display Technical Specification.
167      */
168     public static final int DEVICE_INFO_TIME_SYNCHRONIZATION_SUPPORT = 1 << 9;
169     /**
170      * Bit field for {@link #getDeviceInfo()}, indicate audio is not supported at primary sink.
171      *
172      * The bit definition is listed in 5.1.2 WFD Device Information Subelement in
173      * Wifi Display Technical Specification.
174      */
175     public static final int DEVICE_INFO_AUDIO_UNSUPPORTED_AT_PRIMARY_SINK = 1 << 10;
176     /**
177      * Bit field for {@link #getDeviceInfo()}, indicate audo is only supported at source.
178      *
179      * The bit definition is listed in 5.1.2 WFD Device Information Subelement in
180      * Wifi Display Technical Specification.
181      */
182     public static final int DEVICE_INFO_AUDIO_ONLY_SUPPORT_AT_SOURCE = 1 << 11;
183     /** Bit field for {@link #getDeviceInfo()}, indicate that TDLS persistent group is intended.
184      *
185      * The bit definition is listed in 5.1.2 WFD Device Information Subelement in
186      * Wifi Display Technical Specification.
187      */
188     public static final int DEVICE_INFO_TDLS_PERSISTENT_GROUP = 1 << 12;
189     /** Bit field for {@link #getDeviceInfo()}, indicate that the request is for
190      * re-invocation of TDLS persistent group.
191      *
192      * The bit definition is listed in 5.1.2 WFD Device Information Subelement in
193      * Wifi Display Technical Specification.
194      */
195     public static final int DEVICE_INFO_TDLS_PERSISTENT_GROUP_REINVOKE = 1 << 13;
196 
197     private int mCtrlPort;
198 
199     private int mMaxThroughput;
200 
201     /** Default constructor. */
WifiP2pWfdInfo()202     public WifiP2pWfdInfo() {}
203 
204     /** @hide */
205     @UnsupportedAppUsage
WifiP2pWfdInfo(int devInfo, int ctrlPort, int maxTput)206     public WifiP2pWfdInfo(int devInfo, int ctrlPort, int maxTput) {
207         mEnabled = true;
208         mDeviceInfo = devInfo;
209         mCtrlPort = ctrlPort;
210         mMaxThroughput = maxTput;
211         mR2DeviceInfo = -1;
212     }
213 
214     /**
215      * Return R1 raw device info, See
216      * Wifi Display technical specification v1.0.0, section 5.1.2.
217      * Access bit fields by DEVICE_INFO_* constants.
218      */
219     @DeviceInfoMask
getDeviceInfo()220     public int getDeviceInfo() {
221         return mDeviceInfo;
222     }
223 
224     /**
225      * Set Wifi Display R2 raw device info, see
226      * Wifi Display technical specification v2.0.0, section 5.1.12.
227      * Access bit fields by {@link #DEVICE_INFO_DEVICE_TYPE_MASK}.
228      *
229      * @param r2DeviceInfo the raw data of R2 device info.
230      * @hide
231      */
setR2DeviceInfo(int r2DeviceInfo)232     public void setR2DeviceInfo(int r2DeviceInfo) {
233         mR2DeviceInfo = r2DeviceInfo;
234     }
235 
236     /**
237      * Return R2 raw device info, See
238      * Wifi Display technical specification v2.0.0, section 5.1.12.
239      * Access bit fields by {@link #DEVICE_INFO_DEVICE_TYPE_MASK}.
240      */
241     @R2DeviceInfoMask
getR2DeviceInfo()242     public int getR2DeviceInfo() {
243         return mR2DeviceInfo;
244     }
245 
246     /** Returns true is Wifi Display is enabled, false otherwise. */
isEnabled()247     public boolean isEnabled() {
248         return mEnabled;
249     }
250 
251     /** Returns true is Wifi Display R2 is enabled, false otherwise. */
isR2Supported()252     public boolean isR2Supported() {
253         return mR2DeviceInfo >= 0;
254     }
255 
256     /**
257      * Sets whether Wifi Display should be enabled.
258      *
259      * @param enabled true to enable Wifi Display, false to disable
260      */
setEnabled(boolean enabled)261     public void setEnabled(boolean enabled) {
262         mEnabled = enabled;
263     }
264 
265     /**
266      * Sets the type of the Wifi Display R2 device.
267      * See Wifi Display technical specification v2.0.0, section 5.1.12 for Wifi Display R2.
268      * Before calling this API, call {@link WifiManager#isWifiDisplayR2Supported()
269      * to know whether Wifi Display R2 is supported or not.
270      * If R2 info was filled without Wifi Display R2 support,
271      * {@link WifiP2pManager#setWfdInfo(Channel, WifiP2pWfdInfo, ActionListener)
272      * would fail.
273      *
274      * @param deviceType One of {@link #DEVICE_TYPE_WFD_SOURCE}, {@link #DEVICE_TYPE_PRIMARY_SINK},
275      * {@link #DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK}
276      * @return true if the device type was successfully set, false otherwise
277      */
278     @RequiresApi(Build.VERSION_CODES.S)
setR2DeviceType(@eviceType int deviceType)279     public boolean setR2DeviceType(@DeviceType int deviceType) {
280         if (!SdkLevel.isAtLeastS()) {
281             throw new UnsupportedOperationException();
282         }
283         if (DEVICE_TYPE_WFD_SOURCE != deviceType
284                 && DEVICE_TYPE_PRIMARY_SINK != deviceType
285                 && DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK != deviceType) {
286             return false;
287         }
288         if (!isR2Supported()) mR2DeviceInfo = 0;
289         mR2DeviceInfo &= ~DEVICE_INFO_DEVICE_TYPE_MASK;
290         mR2DeviceInfo |= deviceType;
291         return true;
292     }
293 
294     /**
295      * Get the type of the device.
296      * One of {@link #DEVICE_TYPE_WFD_SOURCE}, {@link #DEVICE_TYPE_PRIMARY_SINK},
297      * {@link #DEVICE_TYPE_SECONDARY_SINK}, {@link #DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK}
298      */
299     @DeviceType
getDeviceType()300     public int getDeviceType() {
301         return mDeviceInfo & DEVICE_INFO_DEVICE_TYPE_MASK;
302     }
303 
304     /**
305      * Get the type of the R2 device.
306      * One of {@link #DEVICE_TYPE_WFD_SOURCE}, {@link #DEVICE_TYPE_PRIMARY_SINK},
307      * or {@link #DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK}
308      */
309     @DeviceType
getR2DeviceType()310     public int getR2DeviceType() {
311         return mR2DeviceInfo & DEVICE_INFO_DEVICE_TYPE_MASK;
312     }
313 
314     /**
315      * Sets the type of the device.
316      *
317      * @param deviceType One of {@link #DEVICE_TYPE_WFD_SOURCE}, {@link #DEVICE_TYPE_PRIMARY_SINK},
318      * {@link #DEVICE_TYPE_SECONDARY_SINK}, {@link #DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK}
319      * @return true if the device type was successfully set, false otherwise
320      */
setDeviceType(@eviceType int deviceType)321     public boolean setDeviceType(@DeviceType int deviceType) {
322         if (DEVICE_TYPE_WFD_SOURCE <= deviceType
323                 && deviceType <= DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK) {
324             mDeviceInfo &= ~DEVICE_INFO_DEVICE_TYPE_MASK;
325             mDeviceInfo |= deviceType;
326             return true;
327         }
328         return false;
329     }
330 
331     /** Returns true if a session is available, false otherwise. */
isSessionAvailable()332     public boolean isSessionAvailable() {
333         return (mDeviceInfo & DEVICE_INFO_SESSION_AVAILABLE_MASK) != 0;
334     }
335 
336     /**
337      * Sets whether a session is available.
338      *
339      * @param enabled true to indicate that a session is available, false otherwise.
340      */
setSessionAvailable(boolean enabled)341     public void setSessionAvailable(boolean enabled) {
342         if (enabled) {
343             mDeviceInfo |= SESSION_AVAILABLE_BIT1;
344             mDeviceInfo &= ~SESSION_AVAILABLE_BIT2;
345         } else {
346             mDeviceInfo &= ~DEVICE_INFO_SESSION_AVAILABLE_MASK;
347         }
348     }
349 
350     /**
351      * @return true if Content Protection using the HDCP system 2.0/2.1 is supported.
352      */
isContentProtectionSupported()353     public boolean isContentProtectionSupported() {
354         return (mDeviceInfo & DEVICE_INFO_CONTENT_PROTECTION_SUPPORT) != 0;
355     }
356 
357     /**
358      * Sets whether Content Protection using the HDCP system 2.0/2.1 is supported.
359      *
360      * @param enabled true to indicate that Content Protection is supported, false otherwise.
361      */
setContentProtectionSupported(boolean enabled)362     public void setContentProtectionSupported(boolean enabled) {
363         if (enabled) {
364             mDeviceInfo |= DEVICE_INFO_CONTENT_PROTECTION_SUPPORT;
365         } else {
366             mDeviceInfo &= ~DEVICE_INFO_CONTENT_PROTECTION_SUPPORT;
367         }
368     }
369 
370     /**
371      * Returns true if Coupled Sink is supported by WFD Source.
372      * See Wifi Display technical specification v1.0.0, section 4.9.
373      */
isCoupledSinkSupportedAtSource()374     public boolean isCoupledSinkSupportedAtSource() {
375         return (mDeviceInfo & DEVICE_INFO_COUPLED_SINK_SUPPORT_AT_SOURCE) != 0;
376     }
377 
378     /**
379      * Sets whether Coupled Sink feature is supported by WFD Source.
380      * See Wifi Display technical specification v1.0.0, section 4.9.
381      *
382      * @param enabled true to indicate support for coupled sink, false otherwise.
383      */
setCoupledSinkSupportAtSource(boolean enabled)384     public void setCoupledSinkSupportAtSource(boolean enabled) {
385         if (enabled) {
386             mDeviceInfo |= DEVICE_INFO_COUPLED_SINK_SUPPORT_AT_SOURCE;
387         } else {
388             mDeviceInfo &= ~DEVICE_INFO_COUPLED_SINK_SUPPORT_AT_SOURCE;
389         }
390     }
391 
392     /**
393      * Returns true if Coupled Sink is supported by WFD Sink.
394      * See Wifi Display technical specification v1.0.0, section 4.9.
395      */
isCoupledSinkSupportedAtSink()396     public boolean isCoupledSinkSupportedAtSink() {
397         return (mDeviceInfo & DEVICE_INFO_COUPLED_SINK_SUPPORT_AT_SINK) != 0;
398     }
399 
400     /**
401      * Sets whether Coupled Sink feature is supported by WFD Sink.
402      * See Wifi Display technical specification v1.0.0, section 4.9.
403      *
404      * @param enabled true to indicate support for coupled sink, false otherwise.
405      */
setCoupledSinkSupportAtSink(boolean enabled)406     public void setCoupledSinkSupportAtSink(boolean enabled) {
407         if (enabled) {
408             mDeviceInfo |= DEVICE_INFO_COUPLED_SINK_SUPPORT_AT_SINK;
409         } else {
410             mDeviceInfo &= ~DEVICE_INFO_COUPLED_SINK_SUPPORT_AT_SINK;
411         }
412     }
413 
414     /** Returns the TCP port at which the WFD Device listens for RTSP messages. */
getControlPort()415     public int getControlPort() {
416         return mCtrlPort;
417     }
418 
419     /** Sets the TCP port at which the WFD Device listens for RTSP messages. */
setControlPort(@ntRangefrom = 0) int port)420     public void setControlPort(@IntRange(from = 0) int port) {
421         mCtrlPort = port;
422     }
423 
424     /** Sets the maximum average throughput capability of the WFD Device, in megabits/second. */
setMaxThroughput(@ntRangefrom = 0) int maxThroughput)425     public void setMaxThroughput(@IntRange(from = 0) int maxThroughput) {
426         mMaxThroughput = maxThroughput;
427     }
428 
429     /** Returns the maximum average throughput capability of the WFD Device, in megabits/second. */
getMaxThroughput()430     public int getMaxThroughput() {
431         return mMaxThroughput;
432     }
433 
434     /** @hide */
getDeviceInfoHex()435     public String getDeviceInfoHex() {
436         return String.format(
437                 Locale.US, "%04x%04x%04x", mDeviceInfo, mCtrlPort, mMaxThroughput);
438     }
439 
440     /** @hide */
getR2DeviceInfoHex()441     public String getR2DeviceInfoHex() {
442         return String.format(Locale.US, "%04x%04x", 2, mR2DeviceInfo);
443     }
444 
445     @Override
toString()446     public String toString() {
447         StringBuffer sbuf = new StringBuffer();
448         sbuf.append("WFD enabled: ").append(mEnabled);
449         sbuf.append("WFD DeviceInfo: ").append(mDeviceInfo);
450         sbuf.append("\n WFD CtrlPort: ").append(mCtrlPort);
451         sbuf.append("\n WFD MaxThroughput: ").append(mMaxThroughput);
452         sbuf.append("\n WFD R2 DeviceInfo: ").append(mR2DeviceInfo);
453         return sbuf.toString();
454     }
455 
456     /** Implement the Parcelable interface */
describeContents()457     public int describeContents() {
458         return 0;
459     }
460 
461     /** Copy constructor. */
WifiP2pWfdInfo(@ullable WifiP2pWfdInfo source)462     public WifiP2pWfdInfo(@Nullable WifiP2pWfdInfo source) {
463         if (source != null) {
464             mEnabled = source.mEnabled;
465             mDeviceInfo = source.mDeviceInfo;
466             mCtrlPort = source.mCtrlPort;
467             mMaxThroughput = source.mMaxThroughput;
468             mR2DeviceInfo = source.mR2DeviceInfo;
469         }
470     }
471 
472     /** Implement the Parcelable interface */
473     @Override
writeToParcel(@onNull Parcel dest, int flags)474     public void writeToParcel(@NonNull Parcel dest, int flags) {
475         dest.writeInt(mEnabled ? 1 : 0);
476         dest.writeInt(mDeviceInfo);
477         dest.writeInt(mCtrlPort);
478         dest.writeInt(mMaxThroughput);
479         dest.writeInt(mR2DeviceInfo);
480     }
481 
readFromParcel(Parcel in)482     private void readFromParcel(Parcel in) {
483         mEnabled = (in.readInt() == 1);
484         mDeviceInfo = in.readInt();
485         mCtrlPort = in.readInt();
486         mMaxThroughput = in.readInt();
487         mR2DeviceInfo = in.readInt();
488     }
489 
490     /** Implement the Parcelable interface */
491     public static final @NonNull Creator<WifiP2pWfdInfo> CREATOR =
492         new Creator<WifiP2pWfdInfo>() {
493             public WifiP2pWfdInfo createFromParcel(Parcel in) {
494                 WifiP2pWfdInfo device = new WifiP2pWfdInfo();
495                 device.readFromParcel(in);
496                 return device;
497             }
498 
499             public WifiP2pWfdInfo[] newArray(int size) {
500                 return new WifiP2pWfdInfo[size];
501             }
502         };
503 }
504