Home | History | Annotate | Download | only in usb
      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 */
    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      */
    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      */
    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      */
    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 */
    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 */
    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 */
    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 */
    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 */
    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 */
    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 */
    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 */
    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 */
    269     public boolean isModeSupported(int mode) {
    270         if ((mSupportedModes & mode) == mode) return true;
    271         return false;
    272     }
    273 
    274 
    275     @Override
    276     public String toString() {
    277         return "UsbPort{id=" + mId + ", supportedModes=" + modeToString(mSupportedModes) + "}";
    278     }
    279 
    280     @Override
    281     public int describeContents() {
    282         return 0;
    283     }
    284 
    285     @Override
    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