Home | History | Annotate | Download | only in hdmi
      1 /*
      2  * Copyright (C) 2014 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.hdmi;
     18 
     19 import android.annotation.SystemApi;
     20 import android.os.Parcel;
     21 import android.os.Parcelable;
     22 
     23 /**
     24  * A class to encapsulate device information for HDMI devices including CEC and MHL. In terms of
     25  * CEC, this container includes basic information such as logical address, physical address and
     26  * device type, and additional information like vendor id and osd name. In terms of MHL device, this
     27  * container includes adopter id and device type. Otherwise, it keeps the information of other type
     28  * devices for which only port ID, physical address are meaningful.
     29  *
     30  * @hide
     31  */
     32 @SystemApi
     33 public class HdmiDeviceInfo implements Parcelable {
     34 
     35     /** TV device type. */
     36     public static final int DEVICE_TV = 0;
     37 
     38     /** Recording device type. */
     39     public static final int DEVICE_RECORDER = 1;
     40 
     41     /** Device type reserved for future usage. */
     42     public static final int DEVICE_RESERVED = 2;
     43 
     44     /** Tuner device type. */
     45     public static final int DEVICE_TUNER = 3;
     46 
     47     /** Playback device type. */
     48     public static final int DEVICE_PLAYBACK = 4;
     49 
     50     /** Audio system device type. */
     51     public static final int DEVICE_AUDIO_SYSTEM = 5;
     52 
     53     /** @hide Pure CEC switch device type. */
     54     public static final int DEVICE_PURE_CEC_SWITCH = 6;
     55 
     56     /** @hide Video processor device type. */
     57     public static final int DEVICE_VIDEO_PROCESSOR = 7;
     58 
     59     // Value indicating the device is not an active source.
     60     public static final int DEVICE_INACTIVE = -1;
     61 
     62     /**
     63      * Logical address used to indicate the source comes from internal device. The logical address
     64      * of TV(0) is used.
     65      */
     66     public static final int ADDR_INTERNAL = 0;
     67 
     68     /**
     69      * Physical address used to indicate the source comes from internal device. The physical address
     70      * of TV(0) is used.
     71      */
     72     public static final int PATH_INTERNAL = 0x0000;
     73 
     74     /** Invalid physical address (routing path) */
     75     public static final int PATH_INVALID = 0xFFFF;
     76 
     77     /** Invalid port ID */
     78     public static final int PORT_INVALID = -1;
     79 
     80     /** Invalid device ID */
     81     public static final int ID_INVALID = 0xFFFF;
     82 
     83     /** Device info used to indicate an inactivated device. */
     84     public static final HdmiDeviceInfo INACTIVE_DEVICE = new HdmiDeviceInfo();
     85 
     86     private static final int HDMI_DEVICE_TYPE_CEC = 0;
     87     private static final int HDMI_DEVICE_TYPE_MHL = 1;
     88     private static final int HDMI_DEVICE_TYPE_HARDWARE = 2;
     89 
     90     // Type used to indicate the device that has relinquished its active source status.
     91     private static final int HDMI_DEVICE_TYPE_INACTIVE = 100;
     92 
     93     // Offset used for id value. MHL devices, for instance, will be assigned the value from
     94     // ID_OFFSET_MHL.
     95     private static final int ID_OFFSET_CEC = 0x0;
     96     private static final int ID_OFFSET_MHL = 0x80;
     97     private static final int ID_OFFSET_HARDWARE = 0xC0;
     98 
     99     // Common parameters for all device.
    100     private final int mId;
    101     private final int mHdmiDeviceType;
    102     private final int mPhysicalAddress;
    103     private final int mPortId;
    104 
    105     // CEC only parameters.
    106     private final int mLogicalAddress;
    107     private final int mDeviceType;
    108     private final int mVendorId;
    109     private final String mDisplayName;
    110     private final int mDevicePowerStatus;
    111 
    112     // MHL only parameters.
    113     private final int mDeviceId;
    114     private final int mAdopterId;
    115 
    116     /**
    117      * A helper class to deserialize {@link HdmiDeviceInfo} for a parcel.
    118      */
    119     public static final Parcelable.Creator<HdmiDeviceInfo> CREATOR =
    120             new Parcelable.Creator<HdmiDeviceInfo>() {
    121                 @Override
    122                 public HdmiDeviceInfo createFromParcel(Parcel source) {
    123                     int hdmiDeviceType = source.readInt();
    124                     int physicalAddress = source.readInt();
    125                     int portId = source.readInt();
    126 
    127                     switch (hdmiDeviceType) {
    128                         case HDMI_DEVICE_TYPE_CEC:
    129                             int logicalAddress = source.readInt();
    130                             int deviceType = source.readInt();
    131                             int vendorId = source.readInt();
    132                             int powerStatus = source.readInt();
    133                             String displayName = source.readString();
    134                             return new HdmiDeviceInfo(logicalAddress, physicalAddress, portId,
    135                                     deviceType, vendorId, displayName, powerStatus);
    136                         case HDMI_DEVICE_TYPE_MHL:
    137                             int deviceId = source.readInt();
    138                             int adopterId = source.readInt();
    139                             return new HdmiDeviceInfo(physicalAddress, portId, adopterId, deviceId);
    140                         case HDMI_DEVICE_TYPE_HARDWARE:
    141                             return new HdmiDeviceInfo(physicalAddress, portId);
    142                         case HDMI_DEVICE_TYPE_INACTIVE:
    143                             return HdmiDeviceInfo.INACTIVE_DEVICE;
    144                         default:
    145                             return null;
    146                     }
    147                 }
    148 
    149                 @Override
    150                 public HdmiDeviceInfo[] newArray(int size) {
    151                     return new HdmiDeviceInfo[size];
    152                 }
    153             };
    154 
    155     /**
    156      * Constructor. Used to initialize the instance for CEC device.
    157      *
    158      * @param logicalAddress logical address of HDMI-CEC device
    159      * @param physicalAddress physical address of HDMI-CEC device
    160      * @param portId HDMI port ID (1 for HDMI1)
    161      * @param deviceType type of device
    162      * @param vendorId vendor id of device. Used for vendor specific command.
    163      * @param displayName name of device
    164      * @param powerStatus device power status
    165      * @hide
    166      */
    167     public HdmiDeviceInfo(int logicalAddress, int physicalAddress, int portId, int deviceType,
    168             int vendorId, String displayName, int powerStatus) {
    169         mHdmiDeviceType = HDMI_DEVICE_TYPE_CEC;
    170         mPhysicalAddress = physicalAddress;
    171         mPortId = portId;
    172 
    173         mId = idForCecDevice(logicalAddress);
    174         mLogicalAddress = logicalAddress;
    175         mDeviceType = deviceType;
    176         mVendorId = vendorId;
    177         mDevicePowerStatus = powerStatus;
    178         mDisplayName = displayName;
    179 
    180         mDeviceId = -1;
    181         mAdopterId = -1;
    182     }
    183 
    184     /**
    185      * Constructor. Used to initialize the instance for CEC device.
    186      *
    187      * @param logicalAddress logical address of HDMI-CEC device
    188      * @param physicalAddress physical address of HDMI-CEC device
    189      * @param portId HDMI port ID (1 for HDMI1)
    190      * @param deviceType type of device
    191      * @param vendorId vendor id of device. Used for vendor specific command.
    192      * @param displayName name of device
    193      * @hide
    194      */
    195     public HdmiDeviceInfo(int logicalAddress, int physicalAddress, int portId, int deviceType,
    196             int vendorId, String displayName) {
    197         this(logicalAddress, physicalAddress, portId, deviceType,
    198                 vendorId, displayName, HdmiControlManager.POWER_STATUS_UNKNOWN);
    199     }
    200 
    201     /**
    202      * Constructor. Used to initialize the instance for device representing hardware port.
    203      *
    204      * @param physicalAddress physical address of the port
    205      * @param portId HDMI port ID (1 for HDMI1)
    206      * @hide
    207      */
    208     public HdmiDeviceInfo(int physicalAddress, int portId) {
    209         mHdmiDeviceType = HDMI_DEVICE_TYPE_HARDWARE;
    210         mPhysicalAddress = physicalAddress;
    211         mPortId = portId;
    212 
    213         mId = idForHardware(portId);
    214         mLogicalAddress = -1;
    215         mDeviceType = DEVICE_RESERVED;
    216         mVendorId = 0;
    217         mDevicePowerStatus = HdmiControlManager.POWER_STATUS_UNKNOWN;
    218         mDisplayName = "HDMI" + portId;
    219 
    220         mDeviceId = -1;
    221         mAdopterId = -1;
    222     }
    223 
    224     /**
    225      * Constructor. Used to initialize the instance for MHL device.
    226      *
    227      * @param physicalAddress physical address of HDMI device
    228      * @param portId portId HDMI port ID (1 for HDMI1)
    229      * @param adopterId adopter id of MHL
    230      * @param deviceId device id of MHL
    231      * @hide
    232      */
    233     public HdmiDeviceInfo(int physicalAddress, int portId, int adopterId, int deviceId) {
    234         mHdmiDeviceType = HDMI_DEVICE_TYPE_MHL;
    235         mPhysicalAddress = physicalAddress;
    236         mPortId = portId;
    237 
    238         mId = idForMhlDevice(portId);
    239         mLogicalAddress = -1;
    240         mDeviceType = DEVICE_RESERVED;
    241         mVendorId = 0;
    242         mDevicePowerStatus = HdmiControlManager.POWER_STATUS_UNKNOWN;
    243         mDisplayName = "Mobile";
    244 
    245         mDeviceId = adopterId;
    246         mAdopterId = deviceId;
    247     }
    248 
    249     /**
    250      * Constructor. Used to initialize the instance representing an inactivated device.
    251      * Can be passed input change listener to indicate the active source yielded
    252      * its status, hence the listener should take an appropriate action such as
    253      * switching to other input.
    254      */
    255     public HdmiDeviceInfo() {
    256         mHdmiDeviceType = HDMI_DEVICE_TYPE_INACTIVE;
    257         mPhysicalAddress = PATH_INVALID;
    258         mId = ID_INVALID;
    259 
    260         mLogicalAddress = -1;
    261         mDeviceType = DEVICE_INACTIVE;
    262         mPortId = PORT_INVALID;
    263         mDevicePowerStatus = HdmiControlManager.POWER_STATUS_UNKNOWN;
    264         mDisplayName = "Inactive";
    265         mVendorId = 0;
    266 
    267         mDeviceId = -1;
    268         mAdopterId = -1;
    269     }
    270 
    271     /**
    272      * Returns the id of the device.
    273      */
    274     public int getId() {
    275         return mId;
    276     }
    277 
    278     /**
    279      * Returns the id to be used for CEC device.
    280      *
    281      * @param address logical address of CEC device
    282      * @return id for CEC device
    283      */
    284     public static int idForCecDevice(int address) {
    285         // The id is generated based on the logical address.
    286         return ID_OFFSET_CEC + address;
    287     }
    288 
    289     /**
    290      * Returns the id to be used for MHL device.
    291      *
    292      * @param portId port which the MHL device is connected to
    293      * @return id for MHL device
    294      */
    295     public static int idForMhlDevice(int portId) {
    296         // The id is generated based on the port id since there can be only one MHL device per port.
    297         return ID_OFFSET_MHL + portId;
    298     }
    299 
    300     /**
    301      * Returns the id to be used for hardware port.
    302      *
    303      * @param portId port id
    304      * @return id for hardware port
    305      */
    306     public static int idForHardware(int portId) {
    307         return ID_OFFSET_HARDWARE + portId;
    308     }
    309 
    310     /**
    311      * Returns the CEC logical address of the device.
    312      */
    313     public int getLogicalAddress() {
    314         return mLogicalAddress;
    315     }
    316 
    317     /**
    318      * Returns the physical address of the device.
    319      */
    320     public int getPhysicalAddress() {
    321         return mPhysicalAddress;
    322     }
    323 
    324     /**
    325      * Returns the port ID.
    326      */
    327     public int getPortId() {
    328         return mPortId;
    329     }
    330 
    331     /**
    332      * Returns CEC type of the device. For more details, refer constants between {@link #DEVICE_TV}
    333      * and {@link #DEVICE_INACTIVE}.
    334      */
    335     public int getDeviceType() {
    336         return mDeviceType;
    337     }
    338 
    339     /**
    340      * Returns device's power status. It should be one of the following values.
    341      * <ul>
    342      * <li>{@link HdmiControlManager#POWER_STATUS_ON}
    343      * <li>{@link HdmiControlManager#POWER_STATUS_STANDBY}
    344      * <li>{@link HdmiControlManager#POWER_STATUS_TRANSIENT_TO_ON}
    345      * <li>{@link HdmiControlManager#POWER_STATUS_TRANSIENT_TO_STANDBY}
    346      * <li>{@link HdmiControlManager#POWER_STATUS_UNKNOWN}
    347      * </ul>
    348      */
    349     public int getDevicePowerStatus() {
    350         return mDevicePowerStatus;
    351     }
    352 
    353     /**
    354      * Returns MHL device id. Return -1 for non-MHL device.
    355      */
    356     public int getDeviceId() {
    357         return mDeviceId;
    358     }
    359 
    360     /**
    361      * Returns MHL adopter id. Return -1 for non-MHL device.
    362      */
    363     public int getAdopterId() {
    364         return mAdopterId;
    365     }
    366 
    367     /**
    368      * Returns {@code true} if the device is of a type that can be an input source.
    369      */
    370     public boolean isSourceType() {
    371         if (isCecDevice()) {
    372             return mDeviceType == DEVICE_PLAYBACK
    373                     || mDeviceType == DEVICE_RECORDER
    374                     || mDeviceType == DEVICE_TUNER;
    375         } else if (isMhlDevice()) {
    376             return true;
    377         } else {
    378             return false;
    379         }
    380     }
    381 
    382     /**
    383      * Returns {@code true} if the device represents an HDMI-CEC device. {@code false} if the device
    384      * is either MHL or other device.
    385      */
    386     public boolean isCecDevice() {
    387         return mHdmiDeviceType == HDMI_DEVICE_TYPE_CEC;
    388     }
    389 
    390     /**
    391      * Returns {@code true} if the device represents an MHL device. {@code false} if the device is
    392      * either CEC or other device.
    393      */
    394     public boolean isMhlDevice() {
    395         return mHdmiDeviceType == HDMI_DEVICE_TYPE_MHL;
    396     }
    397 
    398     /**
    399      * Return {@code true} if the device represents an inactivated device that relinquishes
    400      * its status as active source by &lt;Active Source&gt; (HDMI-CEC) or Content-off (MHL).
    401      */
    402     public boolean isInactivated() {
    403         return mHdmiDeviceType == HDMI_DEVICE_TYPE_INACTIVE;
    404     }
    405 
    406     /**
    407      * Returns display (OSD) name of the device.
    408      */
    409     public String getDisplayName() {
    410         return mDisplayName;
    411     }
    412 
    413     /**
    414      * Returns vendor id of the device. Vendor id is used to distinguish devices built by other
    415      * manufactures. This is required for vendor-specific command on CEC standard.
    416      */
    417     public int getVendorId() {
    418         return mVendorId;
    419     }
    420 
    421     /**
    422      * Describes the kinds of special objects contained in this Parcelable's marshalled
    423      * representation.
    424      */
    425     @Override
    426     public int describeContents() {
    427         return 0;
    428     }
    429 
    430     /**
    431      * Serializes this object into a {@link Parcel}.
    432      *
    433      * @param dest The Parcel in which the object should be written.
    434      * @param flags Additional flags about how the object should be written. May be 0 or
    435      *            {@link Parcelable#PARCELABLE_WRITE_RETURN_VALUE}.
    436      */
    437     @Override
    438     public void writeToParcel(Parcel dest, int flags) {
    439         dest.writeInt(mHdmiDeviceType);
    440         dest.writeInt(mPhysicalAddress);
    441         dest.writeInt(mPortId);
    442         switch (mHdmiDeviceType) {
    443             case HDMI_DEVICE_TYPE_CEC:
    444                 dest.writeInt(mLogicalAddress);
    445                 dest.writeInt(mDeviceType);
    446                 dest.writeInt(mVendorId);
    447                 dest.writeInt(mDevicePowerStatus);
    448                 dest.writeString(mDisplayName);
    449                 break;
    450             case HDMI_DEVICE_TYPE_MHL:
    451                 dest.writeInt(mDeviceId);
    452                 dest.writeInt(mAdopterId);
    453                 break;
    454             case HDMI_DEVICE_TYPE_INACTIVE:
    455                 // flow through
    456             default:
    457                 // no-op
    458         }
    459     }
    460 
    461     @Override
    462     public String toString() {
    463         StringBuffer s = new StringBuffer();
    464         switch (mHdmiDeviceType) {
    465             case HDMI_DEVICE_TYPE_CEC:
    466                 s.append("CEC: ");
    467                 s.append("logical_address: ").append(String.format("0x%02X", mLogicalAddress));
    468                 s.append(" ");
    469                 s.append("device_type: ").append(mDeviceType).append(" ");
    470                 s.append("vendor_id: ").append(mVendorId).append(" ");
    471                 s.append("display_name: ").append(mDisplayName).append(" ");
    472                 s.append("power_status: ").append(mDevicePowerStatus).append(" ");
    473                 break;
    474             case HDMI_DEVICE_TYPE_MHL:
    475                 s.append("MHL: ");
    476                 s.append("device_id: ").append(String.format("0x%04X", mDeviceId)).append(" ");
    477                 s.append("adopter_id: ").append(String.format("0x%04X", mAdopterId)).append(" ");
    478                 break;
    479 
    480             case HDMI_DEVICE_TYPE_HARDWARE:
    481                 s.append("Hardware: ");
    482                 break;
    483             case HDMI_DEVICE_TYPE_INACTIVE:
    484                 s.append("Inactivated: ");
    485                 break;
    486             default:
    487                 return "";
    488         }
    489         s.append("physical_address: ").append(String.format("0x%04X", mPhysicalAddress));
    490         s.append(" ");
    491         s.append("port_id: ").append(mPortId);
    492         return s.toString();
    493     }
    494 
    495     @Override
    496     public boolean equals(Object obj) {
    497         if (!(obj instanceof HdmiDeviceInfo)) {
    498             return false;
    499         }
    500 
    501         HdmiDeviceInfo other = (HdmiDeviceInfo) obj;
    502         return mHdmiDeviceType == other.mHdmiDeviceType
    503                 && mPhysicalAddress == other.mPhysicalAddress
    504                 && mPortId == other.mPortId
    505                 && mLogicalAddress == other.mLogicalAddress
    506                 && mDeviceType == other.mDeviceType
    507                 && mVendorId == other.mVendorId
    508                 && mDevicePowerStatus == other.mDevicePowerStatus
    509                 && mDisplayName.equals(other.mDisplayName)
    510                 && mDeviceId == other.mDeviceId
    511                 && mAdopterId == other.mAdopterId;
    512     }
    513 }
    514