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 com.android.internal.util.Preconditions;
     20 
     21 import android.os.Parcel;
     22 import android.os.Parcelable;
     23 
     24 /**
     25  * Represents a physical USB port and describes its characteristics.
     26  * <p>
     27  * This object is immutable.
     28  * </p>
     29  *
     30  * @hide
     31  */
     32 public final class UsbPort implements Parcelable {
     33     private final String mId;
     34     private final int mSupportedModes;
     35 
     36     /**
     37      * Mode bit: This USB port can act as a downstream facing port (host).
     38      * <p>
     39      * Implies that the port supports the {@link #POWER_ROLE_SOURCE} and {@link #DATA_ROLE_HOST}
     40      * combination of roles (and possibly others as well).
     41      * </p>
     42      */
     43     public static final int MODE_DFP = 1 << 0;
     44 
     45     /**
     46      * Mode bit: This USB port can act as an upstream facing port (device).
     47      * <p>
     48      * Implies that the port supports the {@link #POWER_ROLE_SINK} and {@link #DATA_ROLE_DEVICE}
     49      * combination of roles (and possibly others as well).
     50      * </p>
     51      */
     52     public static final int MODE_UFP = 1 << 1;
     53 
     54     /**
     55      * Mode bit: This USB port can act either as an downstream facing port (host) or as
     56      * an upstream facing port (device).
     57      * <p>
     58      * Implies that the port supports the {@link #POWER_ROLE_SOURCE} and {@link #DATA_ROLE_HOST}
     59      * combination of roles and the {@link #POWER_ROLE_SINK} and {@link #DATA_ROLE_DEVICE}
     60      * combination of roles (and possibly others as well).
     61      * </p>
     62      */
     63     public static final int MODE_DUAL = MODE_DFP | MODE_UFP;
     64 
     65     /**
     66      * Power role: This USB port can act as a source (provide power).
     67      */
     68     public static final int POWER_ROLE_SOURCE = 1;
     69 
     70     /**
     71      * Power role: This USB port can act as a sink (receive power).
     72      */
     73     public static final int POWER_ROLE_SINK = 2;
     74 
     75     /**
     76      * Data role: This USB port can act as a host (access data services).
     77      */
     78     public static final int DATA_ROLE_HOST = 1;
     79 
     80     /**
     81      * Data role: This USB port can act as a device (offer data services).
     82      */
     83     public static final int DATA_ROLE_DEVICE = 2;
     84 
     85     private static final int NUM_DATA_ROLES = 3;
     86 
     87     /** @hide */
     88     public UsbPort(String id, int supportedModes) {
     89         mId = id;
     90         mSupportedModes = supportedModes;
     91     }
     92 
     93     /**
     94      * Gets the unique id of the port.
     95      *
     96      * @return The unique id of the port; not intended for display.
     97      */
     98     public String getId() {
     99         return mId;
    100     }
    101 
    102     /**
    103      * Gets the supported modes of the port.
    104      * <p>
    105      * The actual mode of the port may vary depending on what is plugged into it.
    106      * </p>
    107      *
    108      * @return The supported modes: one of {@link #MODE_DFP}, {@link #MODE_UFP}, or
    109      * {@link #MODE_DUAL}.
    110      */
    111     public int getSupportedModes() {
    112         return mSupportedModes;
    113     }
    114 
    115     /**
    116      * Combines one power and one data role together into a unique value with
    117      * exactly one bit set.  This can be used to efficiently determine whether
    118      * a combination of roles is supported by testing whether that bit is present
    119      * in a bit-field.
    120      *
    121      * @param powerRole The desired power role: {@link UsbPort#POWER_ROLE_SOURCE}
    122      * or {@link UsbPort#POWER_ROLE_SINK}, or 0 if no power role.
    123      * @param dataRole The desired data role: {@link UsbPort#DATA_ROLE_HOST}
    124      * or {@link UsbPort#DATA_ROLE_DEVICE}, or 0 if no data role.
    125      * @hide
    126      */
    127     public static int combineRolesAsBit(int powerRole, int dataRole) {
    128         checkRoles(powerRole, dataRole);
    129         final int index = powerRole * NUM_DATA_ROLES + dataRole;
    130         return 1 << index;
    131     }
    132 
    133     /** @hide */
    134     public static String modeToString(int mode) {
    135         switch (mode) {
    136             case 0:
    137                 return "none";
    138             case MODE_DFP:
    139                 return "dfp";
    140             case MODE_UFP:
    141                 return "ufp";
    142             case MODE_DUAL:
    143                 return "dual";
    144             default:
    145                 return Integer.toString(mode);
    146         }
    147     }
    148 
    149     /** @hide */
    150     public static String powerRoleToString(int role) {
    151         switch (role) {
    152             case 0:
    153                 return "no-power";
    154             case POWER_ROLE_SOURCE:
    155                 return "source";
    156             case POWER_ROLE_SINK:
    157                 return "sink";
    158             default:
    159                 return Integer.toString(role);
    160         }
    161     }
    162 
    163     /** @hide */
    164     public static String dataRoleToString(int role) {
    165         switch (role) {
    166             case 0:
    167                 return "no-data";
    168             case DATA_ROLE_HOST:
    169                 return "host";
    170             case DATA_ROLE_DEVICE:
    171                 return "device";
    172             default:
    173                 return Integer.toString(role);
    174         }
    175     }
    176 
    177     /** @hide */
    178     public static String roleCombinationsToString(int combo) {
    179         StringBuilder result = new StringBuilder();
    180         result.append("[");
    181 
    182         boolean first = true;
    183         while (combo != 0) {
    184             final int index = Integer.numberOfTrailingZeros(combo);
    185             combo &= ~(1 << index);
    186             final int powerRole = index / NUM_DATA_ROLES;
    187             final int dataRole = index % NUM_DATA_ROLES;
    188             if (first) {
    189                 first = false;
    190             } else {
    191                 result.append(", ");
    192             }
    193             result.append(powerRoleToString(powerRole));
    194             result.append(':');
    195             result.append(dataRoleToString(dataRole));
    196         }
    197 
    198         result.append("]");
    199         return result.toString();
    200     }
    201 
    202     /** @hide */
    203     public static void checkRoles(int powerRole, int dataRole) {
    204         Preconditions.checkArgumentInRange(powerRole, 0, POWER_ROLE_SINK, "powerRole");
    205         Preconditions.checkArgumentInRange(dataRole, 0, DATA_ROLE_DEVICE, "dataRole");
    206     }
    207 
    208     @Override
    209     public String toString() {
    210         return "UsbPort{id=" + mId + ", supportedModes=" + modeToString(mSupportedModes) + "}";
    211     }
    212 
    213     @Override
    214     public int describeContents() {
    215         return 0;
    216     }
    217 
    218     @Override
    219     public void writeToParcel(Parcel dest, int flags) {
    220         dest.writeString(mId);
    221         dest.writeInt(mSupportedModes);
    222     }
    223 
    224     public static final Parcelable.Creator<UsbPort> CREATOR =
    225             new Parcelable.Creator<UsbPort>() {
    226         @Override
    227         public UsbPort createFromParcel(Parcel in) {
    228             String id = in.readString();
    229             int supportedModes = in.readInt();
    230             return new UsbPort(id, supportedModes);
    231         }
    232 
    233         @Override
    234         public UsbPort[] newArray(int size) {
    235             return new UsbPort[size];
    236         }
    237     };
    238 }
    239