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