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.Parcel;
25 import android.os.Parcelable;
26 
27 import java.lang.annotation.Retention;
28 import java.lang.annotation.RetentionPolicy;
29 import java.util.Locale;
30 
31 /**
32  * A class representing Wifi Display information for a device.
33  *
34  * See Wifi Display technical specification v1.0.0, section 5.1.2.
35  */
36 public final class WifiP2pWfdInfo implements Parcelable {
37 
38     private boolean mEnabled;
39 
40     /** Device information bitmap */
41     private int mDeviceInfo;
42 
43     /** @hide */
44     @Retention(RetentionPolicy.SOURCE)
45     @IntDef(prefix = { "DEVICE_TYPE_" }, value = {
46             DEVICE_TYPE_WFD_SOURCE,
47             DEVICE_TYPE_PRIMARY_SINK,
48             DEVICE_TYPE_SECONDARY_SINK,
49             DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK})
50     public @interface DeviceType {}
51 
52     /** The device is a Wifi Display Source. */
53     public static final int DEVICE_TYPE_WFD_SOURCE = 0;
54     /** The device is a primary sink. */
55     public static final int DEVICE_TYPE_PRIMARY_SINK = 1;
56     /** The device is a secondary sink. */
57     public static final int DEVICE_TYPE_SECONDARY_SINK = 2;
58     /** The device is dual-role capable i.e. either a WFD source or a primary sink. */
59     public static final int DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK = 3;
60 
61     /**
62      * {@link #mDeviceInfo} & {@link #DEVICE_TYPE} is one of {@link #DEVICE_TYPE_WFD_SOURCE},
63      * {@link #DEVICE_TYPE_PRIMARY_SINK}, {@link #DEVICE_TYPE_SECONDARY_SINK} or
64      * {@link #DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK}.
65      *
66      * The bit definition is listed in 5.1.2 WFD Device Information Subelement in
67      * Wi-Fi Display Technical Specification.
68      */
69     private static final int DEVICE_TYPE                            = 1 << 1 | 1 << 0;
70     private static final int COUPLED_SINK_SUPPORT_AT_SOURCE         = 1 << 2;
71     private static final int COUPLED_SINK_SUPPORT_AT_SINK           = 1 << 3;
72     private static final int SESSION_AVAILABLE_BIT1                 = 1 << 4;
73     private static final int SESSION_AVAILABLE_BIT2                 = 1 << 5;
74     private static final int SESSION_AVAILABLE                      =
75             SESSION_AVAILABLE_BIT2 | SESSION_AVAILABLE_BIT1;
76     /* The support of Content Protection using the HDCP system 2.0/2.1. */
77     private static final int CONTENT_PROTECTION_SUPPORT             = 1 << 8;
78 
79     private int mCtrlPort;
80 
81     private int mMaxThroughput;
82 
83     /** Default constructor. */
WifiP2pWfdInfo()84     public WifiP2pWfdInfo() {}
85 
86     /** @hide */
87     @UnsupportedAppUsage
WifiP2pWfdInfo(int devInfo, int ctrlPort, int maxTput)88     public WifiP2pWfdInfo(int devInfo, int ctrlPort, int maxTput) {
89         mEnabled = true;
90         mDeviceInfo = devInfo;
91         mCtrlPort = ctrlPort;
92         mMaxThroughput = maxTput;
93     }
94 
95     /** Returns true is Wifi Display is enabled, false otherwise. */
isEnabled()96     public boolean isEnabled() {
97         return mEnabled;
98     }
99 
100     /**
101      * Sets whether Wifi Display should be enabled.
102      *
103      * @param enabled true to enable Wifi Display, false to disable
104      */
setEnabled(boolean enabled)105     public void setEnabled(boolean enabled) {
106         mEnabled = enabled;
107     }
108 
109     /**
110      * Get the type of the device.
111      * One of {@link #DEVICE_TYPE_WFD_SOURCE}, {@link #DEVICE_TYPE_PRIMARY_SINK},
112      * {@link #DEVICE_TYPE_SECONDARY_SINK}, {@link #DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK}
113      */
114     @DeviceType
getDeviceType()115     public int getDeviceType() {
116         return mDeviceInfo & DEVICE_TYPE;
117     }
118 
119     /**
120      * Sets the type of the device.
121      *
122      * @param deviceType One of {@link #DEVICE_TYPE_WFD_SOURCE}, {@link #DEVICE_TYPE_PRIMARY_SINK},
123      * {@link #DEVICE_TYPE_SECONDARY_SINK}, {@link #DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK}
124      * @return true if the device type was successfully set, false otherwise
125      */
setDeviceType(@eviceType int deviceType)126     public boolean setDeviceType(@DeviceType int deviceType) {
127         if (DEVICE_TYPE_WFD_SOURCE <= deviceType
128                 && deviceType <= DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK) {
129             mDeviceInfo &= ~DEVICE_TYPE;
130             mDeviceInfo |= deviceType;
131             return true;
132         }
133         return false;
134     }
135 
136     /** Returns true if a session is available, false otherwise. */
isSessionAvailable()137     public boolean isSessionAvailable() {
138         return (mDeviceInfo & SESSION_AVAILABLE) != 0;
139     }
140 
141     /**
142      * Sets whether a session is available.
143      *
144      * @param enabled true to indicate that a session is available, false otherwise.
145      */
setSessionAvailable(boolean enabled)146     public void setSessionAvailable(boolean enabled) {
147         if (enabled) {
148             mDeviceInfo |= SESSION_AVAILABLE_BIT1;
149             mDeviceInfo &= ~SESSION_AVAILABLE_BIT2;
150         } else {
151             mDeviceInfo &= ~SESSION_AVAILABLE;
152         }
153     }
154 
155     /**
156      * @return true if Content Protection using the HDCP system 2.0/2.1 is supported.
157      */
isContentProtectionSupported()158     public boolean isContentProtectionSupported() {
159         return (mDeviceInfo & CONTENT_PROTECTION_SUPPORT) != 0;
160     }
161 
162     /**
163      * Sets whether Content Protection using the HDCP system 2.0/2.1 is supported.
164      *
165      * @param enabled true to indicate that Content Protection is supported, false otherwise.
166      */
setContentProtectionSupported(boolean enabled)167     public void setContentProtectionSupported(boolean enabled) {
168         if (enabled) {
169             mDeviceInfo |= CONTENT_PROTECTION_SUPPORT;
170         } else {
171             mDeviceInfo &= ~CONTENT_PROTECTION_SUPPORT;
172         }
173     }
174 
175     /** Returns the TCP port at which the WFD Device listens for RTSP messages. */
getControlPort()176     public int getControlPort() {
177         return mCtrlPort;
178     }
179 
180     /** Sets the TCP port at which the WFD Device listens for RTSP messages. */
setControlPort(@ntRangefrom = 0) int port)181     public void setControlPort(@IntRange(from = 0) int port) {
182         mCtrlPort = port;
183     }
184 
185     /** Sets the maximum average throughput capability of the WFD Device, in megabits/second. */
setMaxThroughput(@ntRangefrom = 0) int maxThroughput)186     public void setMaxThroughput(@IntRange(from = 0) int maxThroughput) {
187         mMaxThroughput = maxThroughput;
188     }
189 
190     /** Returns the maximum average throughput capability of the WFD Device, in megabits/second. */
getMaxThroughput()191     public int getMaxThroughput() {
192         return mMaxThroughput;
193     }
194 
195     /** @hide */
getDeviceInfoHex()196     public String getDeviceInfoHex() {
197         return String.format(
198                 Locale.US, "%04x%04x%04x", mDeviceInfo, mCtrlPort, mMaxThroughput);
199     }
200 
201     @Override
toString()202     public String toString() {
203         StringBuffer sbuf = new StringBuffer();
204         sbuf.append("WFD enabled: ").append(mEnabled);
205         sbuf.append("WFD DeviceInfo: ").append(mDeviceInfo);
206         sbuf.append("\n WFD CtrlPort: ").append(mCtrlPort);
207         sbuf.append("\n WFD MaxThroughput: ").append(mMaxThroughput);
208         return sbuf.toString();
209     }
210 
211     /** Implement the Parcelable interface */
describeContents()212     public int describeContents() {
213         return 0;
214     }
215 
216     /** Copy constructor. */
WifiP2pWfdInfo(@ullable WifiP2pWfdInfo source)217     public WifiP2pWfdInfo(@Nullable WifiP2pWfdInfo source) {
218         if (source != null) {
219             mEnabled = source.mEnabled;
220             mDeviceInfo = source.mDeviceInfo;
221             mCtrlPort = source.mCtrlPort;
222             mMaxThroughput = source.mMaxThroughput;
223         }
224     }
225 
226     /** Implement the Parcelable interface */
227     @Override
writeToParcel(@onNull Parcel dest, int flags)228     public void writeToParcel(@NonNull Parcel dest, int flags) {
229         dest.writeInt(mEnabled ? 1 : 0);
230         dest.writeInt(mDeviceInfo);
231         dest.writeInt(mCtrlPort);
232         dest.writeInt(mMaxThroughput);
233     }
234 
readFromParcel(Parcel in)235     private void readFromParcel(Parcel in) {
236         mEnabled = (in.readInt() == 1);
237         mDeviceInfo = in.readInt();
238         mCtrlPort = in.readInt();
239         mMaxThroughput = in.readInt();
240     }
241 
242     /** Implement the Parcelable interface */
243     public static final @NonNull Creator<WifiP2pWfdInfo> CREATOR =
244         new Creator<WifiP2pWfdInfo>() {
245             public WifiP2pWfdInfo createFromParcel(Parcel in) {
246                 WifiP2pWfdInfo device = new WifiP2pWfdInfo();
247                 device.readFromParcel(in);
248                 return device;
249             }
250 
251             public WifiP2pWfdInfo[] newArray(int size) {
252                 return new WifiP2pWfdInfo[size];
253             }
254         };
255 }
256