blob: 136211679c6ba456e97a78bc2d5779eed7ec309f [file] [log] [blame]
Jungshik Jang61f4fbd2014-08-06 19:21:12 +09001/*
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
17package android.hardware.hdmi;
18
19import android.annotation.SystemApi;
20import android.os.Parcel;
21import 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
33public 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
Jinsuk Kimcb8661c2015-01-19 12:39:06 +090080 /** 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
Jinsuk Kim8960d1b2014-08-13 10:48:30 +090086 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
Jinsuk Kimcb8661c2015-01-19 12:39:06 +090090 // Type used to indicate the device that has relinquished its active source status.
91 private static final int HDMI_DEVICE_TYPE_INACTIVE = 100;
92
Jinsuk Kim8960d1b2014-08-13 10:48:30 +090093 // 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;
Jungshik Jang61f4fbd2014-08-06 19:21:12 +090098
99 // Common parameters for all device.
Jinsuk Kim8960d1b2014-08-13 10:48:30 +0900100 private final int mId;
Jungshik Jang61f4fbd2014-08-06 19:21:12 +0900101 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 */
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -0700119 public static final @android.annotation.NonNull Parcelable.Creator<HdmiDeviceInfo> CREATOR =
Jungshik Jang61f4fbd2014-08-06 19:21:12 +0900120 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);
Jinsuk Kim8960d1b2014-08-13 10:48:30 +0900140 case HDMI_DEVICE_TYPE_HARDWARE:
Jungshik Jang61f4fbd2014-08-06 19:21:12 +0900141 return new HdmiDeviceInfo(physicalAddress, portId);
Jinsuk Kimcb8661c2015-01-19 12:39:06 +0900142 case HDMI_DEVICE_TYPE_INACTIVE:
143 return HdmiDeviceInfo.INACTIVE_DEVICE;
Jungshik Jang61f4fbd2014-08-06 19:21:12 +0900144 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
Jinsuk Kim8960d1b2014-08-13 10:48:30 +0900173 mId = idForCecDevice(logicalAddress);
Jungshik Jang61f4fbd2014-08-06 19:21:12 +0900174 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 /**
Jinsuk Kim8960d1b2014-08-13 10:48:30 +0900202 * Constructor. Used to initialize the instance for device representing hardware port.
Jungshik Jang61f4fbd2014-08-06 19:21:12 +0900203 *
Jinsuk Kim8960d1b2014-08-13 10:48:30 +0900204 * @param physicalAddress physical address of the port
Jungshik Jang61f4fbd2014-08-06 19:21:12 +0900205 * @param portId HDMI port ID (1 for HDMI1)
206 * @hide
207 */
208 public HdmiDeviceInfo(int physicalAddress, int portId) {
Jinsuk Kim8960d1b2014-08-13 10:48:30 +0900209 mHdmiDeviceType = HDMI_DEVICE_TYPE_HARDWARE;
Jungshik Jang61f4fbd2014-08-06 19:21:12 +0900210 mPhysicalAddress = physicalAddress;
211 mPortId = portId;
212
Jinsuk Kim8960d1b2014-08-13 10:48:30 +0900213 mId = idForHardware(portId);
Jungshik Jang61f4fbd2014-08-06 19:21:12 +0900214 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;
Jungshik Jang61f4fbd2014-08-06 19:21:12 +0900222 }
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
Jinsuk Kim8960d1b2014-08-13 10:48:30 +0900238 mId = idForMhlDevice(portId);
Jungshik Jang61f4fbd2014-08-06 19:21:12 +0900239 mLogicalAddress = -1;
240 mDeviceType = DEVICE_RESERVED;
241 mVendorId = 0;
242 mDevicePowerStatus = HdmiControlManager.POWER_STATUS_UNKNOWN;
Jinsuk Kimed086452014-08-18 15:01:53 +0900243 mDisplayName = "Mobile";
Jungshik Jang61f4fbd2014-08-06 19:21:12 +0900244
245 mDeviceId = adopterId;
246 mAdopterId = deviceId;
247 }
248
249 /**
Jinsuk Kimcb8661c2015-01-19 12:39:06 +0900250 * 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 /**
Yuncheol Heo2b0da5c2014-10-22 14:32:27 +0900272 * Returns the id of the device.
Jinsuk Kim8960d1b2014-08-13 10:48:30 +0900273 */
274 public int getId() {
275 return mId;
276 }
277
278 /**
Yuncheol Heo2b0da5c2014-10-22 14:32:27 +0900279 * Returns the id to be used for CEC device.
Jinsuk Kim8960d1b2014-08-13 10:48:30 +0900280 *
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 /**
Yuncheol Heo2b0da5c2014-10-22 14:32:27 +0900290 * Returns the id to be used for MHL device.
Jinsuk Kim8960d1b2014-08-13 10:48:30 +0900291 *
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 /**
Yuncheol Heo2b0da5c2014-10-22 14:32:27 +0900301 * Returns the id to be used for hardware port.
Jinsuk Kim8960d1b2014-08-13 10:48:30 +0900302 *
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 /**
Yuncheol Heo2b0da5c2014-10-22 14:32:27 +0900311 * Returns the CEC logical address of the device.
Jungshik Jang61f4fbd2014-08-06 19:21:12 +0900312 */
313 public int getLogicalAddress() {
314 return mLogicalAddress;
315 }
316
317 /**
Yuncheol Heo2b0da5c2014-10-22 14:32:27 +0900318 * Returns the physical address of the device.
Jungshik Jang61f4fbd2014-08-06 19:21:12 +0900319 */
320 public int getPhysicalAddress() {
321 return mPhysicalAddress;
322 }
323
324 /**
Yuncheol Heo2b0da5c2014-10-22 14:32:27 +0900325 * Returns the port ID.
Jungshik Jang61f4fbd2014-08-06 19:21:12 +0900326 */
327 public int getPortId() {
328 return mPortId;
329 }
330
331 /**
Yuncheol Heo2b0da5c2014-10-22 14:32:27 +0900332 * Returns CEC type of the device. For more details, refer constants between {@link #DEVICE_TV}
Jungshik Jang61f4fbd2014-08-06 19:21:12 +0900333 * and {@link #DEVICE_INACTIVE}.
334 */
335 public int getDeviceType() {
336 return mDeviceType;
337 }
338
339 /**
Yuncheol Heo2b0da5c2014-10-22 14:32:27 +0900340 * Returns device's power status. It should be one of the following values.
Jungshik Jang61f4fbd2014-08-06 19:21:12 +0900341 * <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 /**
Yuncheol Heo2b0da5c2014-10-22 14:32:27 +0900354 * Returns MHL device id. Return -1 for non-MHL device.
Jungshik Jang61f4fbd2014-08-06 19:21:12 +0900355 */
356 public int getDeviceId() {
357 return mDeviceId;
358 }
359
360 /**
Yuncheol Heo2b0da5c2014-10-22 14:32:27 +0900361 * Returns MHL adopter id. Return -1 for non-MHL device.
Jungshik Jang61f4fbd2014-08-06 19:21:12 +0900362 */
363 public int getAdopterId() {
364 return mAdopterId;
365 }
366
367 /**
Yuncheol Heo2b0da5c2014-10-22 14:32:27 +0900368 * Returns {@code true} if the device is of a type that can be an input source.
Jungshik Jang61f4fbd2014-08-06 19:21:12 +0900369 */
370 public boolean isSourceType() {
Jinsuk Kime416d0f2015-01-05 16:07:28 +0900371 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 }
Jungshik Jang61f4fbd2014-08-06 19:21:12 +0900380 }
381
382 /**
Yuncheol Heo2b0da5c2014-10-22 14:32:27 +0900383 * Returns {@code true} if the device represents an HDMI-CEC device. {@code false} if the device
Jungshik Jang61f4fbd2014-08-06 19:21:12 +0900384 * is either MHL or other device.
385 */
386 public boolean isCecDevice() {
387 return mHdmiDeviceType == HDMI_DEVICE_TYPE_CEC;
388 }
389
390 /**
Yuncheol Heo2b0da5c2014-10-22 14:32:27 +0900391 * Returns {@code true} if the device represents an MHL device. {@code false} if the device is
Jungshik Jang61f4fbd2014-08-06 19:21:12 +0900392 * either CEC or other device.
393 */
394 public boolean isMhlDevice() {
395 return mHdmiDeviceType == HDMI_DEVICE_TYPE_MHL;
396 }
397
398 /**
Jinsuk Kimcb8661c2015-01-19 12:39:06 +0900399 * 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 /**
Yuncheol Heo2b0da5c2014-10-22 14:32:27 +0900407 * Returns display (OSD) name of the device.
Jungshik Jang61f4fbd2014-08-06 19:21:12 +0900408 */
409 public String getDisplayName() {
410 return mDisplayName;
411 }
412
413 /**
Yuncheol Heo2b0da5c2014-10-22 14:32:27 +0900414 * Returns vendor id of the device. Vendor id is used to distinguish devices built by other
Jungshik Jang61f4fbd2014-08-06 19:21:12 +0900415 * manufactures. This is required for vendor-specific command on CEC standard.
416 */
417 public int getVendorId() {
418 return mVendorId;
419 }
420
421 /**
Yuncheol Heo2b0da5c2014-10-22 14:32:27 +0900422 * Describes the kinds of special objects contained in this Parcelable's marshalled
Jungshik Jang61f4fbd2014-08-06 19:21:12 +0900423 * representation.
424 */
425 @Override
426 public int describeContents() {
427 return 0;
428 }
429
430 /**
Yuncheol Heo2b0da5c2014-10-22 14:32:27 +0900431 * Serializes this object into a {@link Parcel}.
Jungshik Jang61f4fbd2014-08-06 19:21:12 +0900432 *
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;
Jinsuk Kimcb8661c2015-01-19 12:39:06 +0900454 case HDMI_DEVICE_TYPE_INACTIVE:
455 // flow through
Jungshik Jang61f4fbd2014-08-06 19:21:12 +0900456 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: ");
Jinsuk Kim87f22a22014-08-20 10:40:12 +0900467 s.append("logical_address: ").append(String.format("0x%02X", mLogicalAddress));
468 s.append(" ");
Jinsuk Kim8960d1b2014-08-13 10:48:30 +0900469 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(" ");
Jungshik Jang61f4fbd2014-08-06 19:21:12 +0900473 break;
474 case HDMI_DEVICE_TYPE_MHL:
475 s.append("MHL: ");
Jinsuk Kim87f22a22014-08-20 10:40:12 +0900476 s.append("device_id: ").append(String.format("0x%04X", mDeviceId)).append(" ");
477 s.append("adopter_id: ").append(String.format("0x%04X", mAdopterId)).append(" ");
Jungshik Jang61f4fbd2014-08-06 19:21:12 +0900478 break;
479
Jinsuk Kim8960d1b2014-08-13 10:48:30 +0900480 case HDMI_DEVICE_TYPE_HARDWARE:
481 s.append("Hardware: ");
Jungshik Jang61f4fbd2014-08-06 19:21:12 +0900482 break;
Jinsuk Kimcb8661c2015-01-19 12:39:06 +0900483 case HDMI_DEVICE_TYPE_INACTIVE:
484 s.append("Inactivated: ");
485 break;
Jungshik Jang61f4fbd2014-08-06 19:21:12 +0900486 default:
487 return "";
488 }
Jinsuk Kim87f22a22014-08-20 10:40:12 +0900489 s.append("physical_address: ").append(String.format("0x%04X", mPhysicalAddress));
490 s.append(" ");
Jungshik Jang61f4fbd2014-08-06 19:21:12 +0900491 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}