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      * 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 */
    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      */
    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      */
    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      */
    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 */
    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 */
    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 */
    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 */
    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 */
    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 */
    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 */
    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 */
    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
    244     public String toString() {
    245         return "UsbPort{id=" + mId + ", supportedModes=" + modeToString(mSupportedModes) + "}";
    246     }
    247 
    248     @Override
    249     public int describeContents() {
    250         return 0;
    251     }
    252 
    253     @Override
    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