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 * Power role: This USB port does not have a power role. 69 */ 70 public static final int POWER_ROLE_NONE = Constants.PortPowerRole.NONE; 71 72 /** 73 * Power role: This USB port can act as a source (provide power). 74 */ 75 public static final int POWER_ROLE_SOURCE = Constants.PortPowerRole.SOURCE; 76 77 /** 78 * Power role: This USB port can act as a sink (receive power). 79 */ 80 public static final int POWER_ROLE_SINK = Constants.PortPowerRole.SINK; 81 82 /** 83 * Power role: This USB port does not have a data role. 84 */ 85 public static final int DATA_ROLE_NONE = Constants.PortDataRole.NONE; 86 87 /** 88 * Data role: This USB port can act as a host (access data services). 89 */ 90 public static final int DATA_ROLE_HOST = Constants.PortDataRole.HOST; 91 92 /** 93 * Data role: This USB port can act as a device (offer data services). 94 */ 95 public static final int DATA_ROLE_DEVICE = Constants.PortDataRole.DEVICE; 96 97 private static final int NUM_DATA_ROLES = Constants.PortDataRole.NUM_DATA_ROLES; 98 /** 99 * Points to the first power role in the IUsb HAL. 100 */ 101 private static final int POWER_ROLE_OFFSET = Constants.PortPowerRole.NONE; 102 103 /** @hide */ UsbPort(String id, int supportedModes)104 public UsbPort(String id, int supportedModes) { 105 mId = id; 106 mSupportedModes = supportedModes; 107 } 108 109 /** 110 * Gets the unique id of the port. 111 * 112 * @return The unique id of the port; not intended for display. 113 */ getId()114 public String getId() { 115 return mId; 116 } 117 118 /** 119 * Gets the supported modes of the port. 120 * <p> 121 * The actual mode of the port may vary depending on what is plugged into it. 122 * </p> 123 * 124 * @return The supported modes: one of {@link #MODE_DFP}, {@link #MODE_UFP}, or 125 * {@link #MODE_DUAL}. 126 */ getSupportedModes()127 public int getSupportedModes() { 128 return mSupportedModes; 129 } 130 131 /** 132 * Combines one power and one data role together into a unique value with 133 * exactly one bit set. This can be used to efficiently determine whether 134 * a combination of roles is supported by testing whether that bit is present 135 * in a bit-field. 136 * 137 * @param powerRole The desired power role: {@link UsbPort#POWER_ROLE_SOURCE} 138 * or {@link UsbPort#POWER_ROLE_SINK}, or 0 if no power role. 139 * @param dataRole The desired data role: {@link UsbPort#DATA_ROLE_HOST} 140 * or {@link UsbPort#DATA_ROLE_DEVICE}, or 0 if no data role. 141 * @hide 142 */ combineRolesAsBit(int powerRole, int dataRole)143 public static int combineRolesAsBit(int powerRole, int dataRole) { 144 checkRoles(powerRole, dataRole); 145 final int index = ((powerRole - POWER_ROLE_OFFSET) * NUM_DATA_ROLES) + dataRole; 146 return 1 << index; 147 } 148 149 /** @hide */ modeToString(int mode)150 public static String modeToString(int mode) { 151 switch (mode) { 152 case MODE_NONE: 153 return "none"; 154 case MODE_DFP: 155 return "dfp"; 156 case MODE_UFP: 157 return "ufp"; 158 case MODE_DUAL: 159 return "dual"; 160 default: 161 return Integer.toString(mode); 162 } 163 } 164 165 /** @hide */ powerRoleToString(int role)166 public static String powerRoleToString(int role) { 167 switch (role) { 168 case POWER_ROLE_NONE: 169 return "no-power"; 170 case POWER_ROLE_SOURCE: 171 return "source"; 172 case POWER_ROLE_SINK: 173 return "sink"; 174 default: 175 return Integer.toString(role); 176 } 177 } 178 179 /** @hide */ dataRoleToString(int role)180 public static String dataRoleToString(int role) { 181 switch (role) { 182 case DATA_ROLE_NONE: 183 return "no-data"; 184 case DATA_ROLE_HOST: 185 return "host"; 186 case DATA_ROLE_DEVICE: 187 return "device"; 188 default: 189 return Integer.toString(role); 190 } 191 } 192 193 /** @hide */ roleCombinationsToString(int combo)194 public static String roleCombinationsToString(int combo) { 195 StringBuilder result = new StringBuilder(); 196 result.append("["); 197 198 boolean first = true; 199 while (combo != 0) { 200 final int index = Integer.numberOfTrailingZeros(combo); 201 combo &= ~(1 << index); 202 final int powerRole = (index / NUM_DATA_ROLES + POWER_ROLE_OFFSET); 203 final int dataRole = index % NUM_DATA_ROLES; 204 if (first) { 205 first = false; 206 } else { 207 result.append(", "); 208 } 209 result.append(powerRoleToString(powerRole)); 210 result.append(':'); 211 result.append(dataRoleToString(dataRole)); 212 } 213 214 result.append("]"); 215 return result.toString(); 216 } 217 218 /** @hide */ checkMode(int powerRole)219 public static void checkMode(int powerRole) { 220 Preconditions.checkArgumentInRange(powerRole, Constants.PortMode.NONE, 221 Constants.PortMode.NUM_MODES - 1, "portMode"); 222 } 223 224 /** @hide */ checkPowerRole(int dataRole)225 public static void checkPowerRole(int dataRole) { 226 Preconditions.checkArgumentInRange(dataRole, Constants.PortPowerRole.NONE, 227 Constants.PortPowerRole.NUM_POWER_ROLES - 1, "powerRole"); 228 } 229 230 /** @hide */ checkDataRole(int mode)231 public static void checkDataRole(int mode) { 232 Preconditions.checkArgumentInRange(mode, Constants.PortDataRole.NONE, 233 Constants.PortDataRole.NUM_DATA_ROLES - 1, "powerRole"); 234 } 235 236 /** @hide */ checkRoles(int powerRole, int dataRole)237 public static void checkRoles(int powerRole, int dataRole) { 238 Preconditions.checkArgumentInRange(powerRole, POWER_ROLE_NONE, POWER_ROLE_SINK, 239 "powerRole"); 240 Preconditions.checkArgumentInRange(dataRole, DATA_ROLE_NONE, DATA_ROLE_DEVICE, "dataRole"); 241 } 242 243 @Override toString()244 public String toString() { 245 return "UsbPort{id=" + mId + ", supportedModes=" + modeToString(mSupportedModes) + "}"; 246 } 247 248 @Override describeContents()249 public int describeContents() { 250 return 0; 251 } 252 253 @Override writeToParcel(Parcel dest, int flags)254 public void writeToParcel(Parcel dest, int flags) { 255 dest.writeString(mId); 256 dest.writeInt(mSupportedModes); 257 } 258 259 public static final Parcelable.Creator<UsbPort> CREATOR = 260 new Parcelable.Creator<UsbPort>() { 261 @Override 262 public UsbPort createFromParcel(Parcel in) { 263 String id = in.readString(); 264 int supportedModes = in.readInt(); 265 return new UsbPort(id, supportedModes); 266 } 267 268 @Override 269 public UsbPort[] newArray(int size) { 270 return new UsbPort[size]; 271 } 272 }; 273 } 274