• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 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.hardware.usb;
18 
19 import android.hardware.usb.V1_0.Constants;
20 import android.os.Parcel;
21 import android.os.Parcelable;
22 
23 import com.android.internal.util.Preconditions;
24 
25 /**
26  * Represents a physical USB port and describes its characteristics.
27  * <p>
28  * This object is immutable.
29  * </p>
30  *
31  * @hide
32  */
33 public final class UsbPort implements Parcelable {
34     private final String mId;
35     private final int mSupportedModes;
36 
37     public static final int MODE_NONE = Constants.PortMode.NONE;
38     /**
39      * Mode bit: This USB port can act as a downstream facing port (host).
40      * <p>
41      * Implies that the port supports the {@link #POWER_ROLE_SOURCE} and {@link #DATA_ROLE_HOST}
42      * combination of roles (and possibly others as well).
43      * </p>
44      */
45     public static final int MODE_DFP = Constants.PortMode.DFP;
46 
47     /**
48      * Mode bit: This USB port can act as an upstream facing port (device).
49      * <p>
50      * Implies that the port supports the {@link #POWER_ROLE_SINK} and {@link #DATA_ROLE_DEVICE}
51      * combination of roles (and possibly others as well).
52      * </p>
53      */
54     public static final int MODE_UFP = Constants.PortMode.UFP;
55 
56     /**
57      * Mode bit: This USB port can act either as an downstream facing port (host) or as
58      * an upstream facing port (device).
59      * <p>
60      * Implies that the port supports the {@link #POWER_ROLE_SOURCE} and {@link #DATA_ROLE_HOST}
61      * combination of roles and the {@link #POWER_ROLE_SINK} and {@link #DATA_ROLE_DEVICE}
62      * combination of roles (and possibly others as well).
63      * </p>
64      */
65     public static final int MODE_DUAL = Constants.PortMode.DRP;
66 
67     /**
68      * Mode bit: This USB port can support USB Type-C Audio accessory.
69      */
70     public static final int MODE_AUDIO_ACCESSORY =
71             android.hardware.usb.V1_1.Constants.PortMode_1_1.AUDIO_ACCESSORY;
72 
73     /**
74      * Mode bit: This USB port can support USB Type-C debug accessory.
75      */
76     public static final int MODE_DEBUG_ACCESSORY =
77             android.hardware.usb.V1_1.Constants.PortMode_1_1.DEBUG_ACCESSORY;
78 
79     /**
80      * Power role: This USB port does not have a power role.
81      */
82     public static final int POWER_ROLE_NONE = Constants.PortPowerRole.NONE;
83 
84     /**
85      * Power role: This USB port can act as a source (provide power).
86      */
87     public static final int POWER_ROLE_SOURCE = Constants.PortPowerRole.SOURCE;
88 
89     /**
90      * Power role: This USB port can act as a sink (receive power).
91      */
92     public static final int POWER_ROLE_SINK = Constants.PortPowerRole.SINK;
93 
94     /**
95      * Power role: This USB port does not have a data role.
96      */
97     public static final int DATA_ROLE_NONE = Constants.PortDataRole.NONE;
98 
99     /**
100      * Data role: This USB port can act as a host (access data services).
101      */
102     public static final int DATA_ROLE_HOST = Constants.PortDataRole.HOST;
103 
104     /**
105      * Data role: This USB port can act as a device (offer data services).
106      */
107     public static final int DATA_ROLE_DEVICE = Constants.PortDataRole.DEVICE;
108 
109     private static final int NUM_DATA_ROLES = Constants.PortDataRole.NUM_DATA_ROLES;
110     /**
111      * Points to the first power role in the IUsb HAL.
112      */
113     private static final int POWER_ROLE_OFFSET = Constants.PortPowerRole.NONE;
114 
115     /** @hide */
UsbPort(String id, int supportedModes)116     public UsbPort(String id, int supportedModes) {
117         mId = id;
118         mSupportedModes = supportedModes;
119     }
120 
121     /**
122      * Gets the unique id of the port.
123      *
124      * @return The unique id of the port; not intended for display.
125      */
getId()126     public String getId() {
127         return mId;
128     }
129 
130     /**
131      * Gets the supported modes of the port.
132      * <p>
133      * The actual mode of the port may vary depending on what is plugged into it.
134      * </p>
135      *
136      * @return The supported modes: one of {@link #MODE_DFP}, {@link #MODE_UFP}, or
137      * {@link #MODE_DUAL}.
138      */
getSupportedModes()139     public int getSupportedModes() {
140         return mSupportedModes;
141     }
142 
143     /**
144      * Combines one power and one data role together into a unique value with
145      * exactly one bit set.  This can be used to efficiently determine whether
146      * a combination of roles is supported by testing whether that bit is present
147      * in a bit-field.
148      *
149      * @param powerRole The desired power role: {@link UsbPort#POWER_ROLE_SOURCE}
150      *                  or {@link UsbPort#POWER_ROLE_SINK}, or 0 if no power role.
151      * @param dataRole  The desired data role: {@link UsbPort#DATA_ROLE_HOST}
152      *                  or {@link UsbPort#DATA_ROLE_DEVICE}, or 0 if no data role.
153      * @hide
154      */
combineRolesAsBit(int powerRole, int dataRole)155     public static int combineRolesAsBit(int powerRole, int dataRole) {
156         checkRoles(powerRole, dataRole);
157         final int index = ((powerRole - POWER_ROLE_OFFSET) * NUM_DATA_ROLES) + dataRole;
158         return 1 << index;
159     }
160 
161     /** @hide */
modeToString(int mode)162     public static String modeToString(int mode) {
163         StringBuilder modeString = new StringBuilder();
164         if (mode == MODE_NONE) {
165             return "none";
166         }
167 
168         if ((mode & MODE_DUAL) == MODE_DUAL) {
169             modeString.append("dual, ");
170         } else {
171             if ((mode & MODE_DFP) == MODE_DFP) {
172                 modeString.append("dfp, ");
173             } else if ((mode & MODE_UFP) == MODE_UFP) {
174                 modeString.append("ufp, ");
175             }
176         }
177         if ((mode & MODE_AUDIO_ACCESSORY) == MODE_AUDIO_ACCESSORY) {
178             modeString.append("audio_acc, ");
179         }
180         if ((mode & MODE_DEBUG_ACCESSORY) == MODE_DEBUG_ACCESSORY) {
181             modeString.append("debug_acc, ");
182         }
183 
184         if (modeString.length() == 0) {
185             return Integer.toString(mode);
186         }
187         return modeString.substring(0, modeString.length() - 2);
188     }
189 
190     /** @hide */
powerRoleToString(int role)191     public static String powerRoleToString(int role) {
192         switch (role) {
193             case POWER_ROLE_NONE:
194                 return "no-power";
195             case POWER_ROLE_SOURCE:
196                 return "source";
197             case POWER_ROLE_SINK:
198                 return "sink";
199             default:
200                 return Integer.toString(role);
201         }
202     }
203 
204     /** @hide */
dataRoleToString(int role)205     public static String dataRoleToString(int role) {
206         switch (role) {
207             case DATA_ROLE_NONE:
208                 return "no-data";
209             case DATA_ROLE_HOST:
210                 return "host";
211             case DATA_ROLE_DEVICE:
212                 return "device";
213             default:
214                 return Integer.toString(role);
215         }
216     }
217 
218     /** @hide */
roleCombinationsToString(int combo)219     public static String roleCombinationsToString(int combo) {
220         StringBuilder result = new StringBuilder();
221         result.append("[");
222 
223         boolean first = true;
224         while (combo != 0) {
225             final int index = Integer.numberOfTrailingZeros(combo);
226             combo &= ~(1 << index);
227             final int powerRole = (index / NUM_DATA_ROLES + POWER_ROLE_OFFSET);
228             final int dataRole = index % NUM_DATA_ROLES;
229             if (first) {
230                 first = false;
231             } else {
232                 result.append(", ");
233             }
234             result.append(powerRoleToString(powerRole));
235             result.append(':');
236             result.append(dataRoleToString(dataRole));
237         }
238 
239         result.append("]");
240         return result.toString();
241     }
242 
243     /** @hide */
checkMode(int powerRole)244     public static void checkMode(int powerRole) {
245         Preconditions.checkArgumentInRange(powerRole, Constants.PortMode.NONE,
246                 Constants.PortMode.NUM_MODES - 1, "portMode");
247     }
248 
249     /** @hide */
checkPowerRole(int dataRole)250     public static void checkPowerRole(int dataRole) {
251         Preconditions.checkArgumentInRange(dataRole, Constants.PortPowerRole.NONE,
252                 Constants.PortPowerRole.NUM_POWER_ROLES - 1, "powerRole");
253     }
254 
255     /** @hide */
checkDataRole(int mode)256     public static void checkDataRole(int mode) {
257         Preconditions.checkArgumentInRange(mode, Constants.PortDataRole.NONE,
258                 Constants.PortDataRole.NUM_DATA_ROLES - 1, "powerRole");
259     }
260 
261     /** @hide */
checkRoles(int powerRole, int dataRole)262     public static void checkRoles(int powerRole, int dataRole) {
263         Preconditions.checkArgumentInRange(powerRole, POWER_ROLE_NONE, POWER_ROLE_SINK,
264                 "powerRole");
265         Preconditions.checkArgumentInRange(dataRole, DATA_ROLE_NONE, DATA_ROLE_DEVICE, "dataRole");
266     }
267 
268     /** @hide */
isModeSupported(int mode)269     public boolean isModeSupported(int mode) {
270         if ((mSupportedModes & mode) == mode) return true;
271         return false;
272     }
273 
274 
275     @Override
toString()276     public String toString() {
277         return "UsbPort{id=" + mId + ", supportedModes=" + modeToString(mSupportedModes) + "}";
278     }
279 
280     @Override
describeContents()281     public int describeContents() {
282         return 0;
283     }
284 
285     @Override
writeToParcel(Parcel dest, int flags)286     public void writeToParcel(Parcel dest, int flags) {
287         dest.writeString(mId);
288         dest.writeInt(mSupportedModes);
289     }
290 
291     public static final Parcelable.Creator<UsbPort> CREATOR =
292             new Parcelable.Creator<UsbPort>() {
293                 @Override
294                 public UsbPort createFromParcel(Parcel in) {
295                     String id = in.readString();
296                     int supportedModes = in.readInt();
297                     return new UsbPort(id, supportedModes);
298                 }
299 
300                 @Override
301                 public UsbPort[] newArray(int size) {
302                     return new UsbPort[size];
303                 }
304             };
305 }
306