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 @android.annotation.NonNull 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 */ HdmiDeviceInfo(int logicalAddress, int physicalAddress, int portId, int deviceType, int vendorId, String displayName, int powerStatus)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 */ HdmiDeviceInfo(int logicalAddress, int physicalAddress, int portId, int deviceType, int vendorId, String displayName)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 */ HdmiDeviceInfo(int physicalAddress, int portId)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 */ HdmiDeviceInfo(int physicalAddress, int portId, int adopterId, int deviceId)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 */ HdmiDeviceInfo()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 */ getId()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 */ idForCecDevice(int address)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 */ idForMhlDevice(int portId)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 */ idForHardware(int portId)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 */ getLogicalAddress()313 public int getLogicalAddress() { 314 return mLogicalAddress; 315 } 316 317 /** 318 * Returns the physical address of the device. 319 */ getPhysicalAddress()320 public int getPhysicalAddress() { 321 return mPhysicalAddress; 322 } 323 324 /** 325 * Returns the port ID. 326 */ getPortId()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 */ getDeviceType()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 */ getDevicePowerStatus()349 public int getDevicePowerStatus() { 350 return mDevicePowerStatus; 351 } 352 353 /** 354 * Returns MHL device id. Return -1 for non-MHL device. 355 */ getDeviceId()356 public int getDeviceId() { 357 return mDeviceId; 358 } 359 360 /** 361 * Returns MHL adopter id. Return -1 for non-MHL device. 362 */ getAdopterId()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 */ isSourceType()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 */ isCecDevice()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 */ isMhlDevice()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 <Active Source> (HDMI-CEC) or Content-off (MHL). 401 */ isInactivated()402 public boolean isInactivated() { 403 return mHdmiDeviceType == HDMI_DEVICE_TYPE_INACTIVE; 404 } 405 406 /** 407 * Returns display (OSD) name of the device. 408 */ getDisplayName()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 */ getVendorId()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 describeContents()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 writeToParcel(Parcel dest, int flags)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 toString()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 equals(Object obj)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