HdmiDeviceInfo.java revision e416d0f67bfed9c8a65573091016d49777c56e8f
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
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
80    private static final int HDMI_DEVICE_TYPE_CEC = 0;
81    private static final int HDMI_DEVICE_TYPE_MHL = 1;
82    private static final int HDMI_DEVICE_TYPE_HARDWARE = 2;
83
84    // Offset used for id value. MHL devices, for instance, will be assigned the value from
85    // ID_OFFSET_MHL.
86    private static final int ID_OFFSET_CEC = 0x0;
87    private static final int ID_OFFSET_MHL = 0x80;
88    private static final int ID_OFFSET_HARDWARE = 0xC0;
89
90    // Common parameters for all device.
91    private final int mId;
92    private final int mHdmiDeviceType;
93    private final int mPhysicalAddress;
94    private final int mPortId;
95
96    // CEC only parameters.
97    private final int mLogicalAddress;
98    private final int mDeviceType;
99    private final int mVendorId;
100    private final String mDisplayName;
101    private final int mDevicePowerStatus;
102
103    // MHL only parameters.
104    private final int mDeviceId;
105    private final int mAdopterId;
106
107    /**
108     * A helper class to deserialize {@link HdmiDeviceInfo} for a parcel.
109     */
110    public static final Parcelable.Creator<HdmiDeviceInfo> CREATOR =
111            new Parcelable.Creator<HdmiDeviceInfo>() {
112                @Override
113                public HdmiDeviceInfo createFromParcel(Parcel source) {
114                    int hdmiDeviceType = source.readInt();
115                    int physicalAddress = source.readInt();
116                    int portId = source.readInt();
117
118                    switch (hdmiDeviceType) {
119                        case HDMI_DEVICE_TYPE_CEC:
120                            int logicalAddress = source.readInt();
121                            int deviceType = source.readInt();
122                            int vendorId = source.readInt();
123                            int powerStatus = source.readInt();
124                            String displayName = source.readString();
125                            return new HdmiDeviceInfo(logicalAddress, physicalAddress, portId,
126                                    deviceType, vendorId, displayName, powerStatus);
127                        case HDMI_DEVICE_TYPE_MHL:
128                            int deviceId = source.readInt();
129                            int adopterId = source.readInt();
130                            return new HdmiDeviceInfo(physicalAddress, portId, adopterId, deviceId);
131                        case HDMI_DEVICE_TYPE_HARDWARE:
132                            return new HdmiDeviceInfo(physicalAddress, portId);
133                        default:
134                            return null;
135                    }
136                }
137
138                @Override
139                public HdmiDeviceInfo[] newArray(int size) {
140                    return new HdmiDeviceInfo[size];
141                }
142            };
143
144    /**
145     * Constructor. Used to initialize the instance for CEC device.
146     *
147     * @param logicalAddress logical address of HDMI-CEC device
148     * @param physicalAddress physical address of HDMI-CEC device
149     * @param portId HDMI port ID (1 for HDMI1)
150     * @param deviceType type of device
151     * @param vendorId vendor id of device. Used for vendor specific command.
152     * @param displayName name of device
153     * @param powerStatus device power status
154     * @hide
155     */
156    public HdmiDeviceInfo(int logicalAddress, int physicalAddress, int portId, int deviceType,
157            int vendorId, String displayName, int powerStatus) {
158        mHdmiDeviceType = HDMI_DEVICE_TYPE_CEC;
159        mPhysicalAddress = physicalAddress;
160        mPortId = portId;
161
162        mId = idForCecDevice(logicalAddress);
163        mLogicalAddress = logicalAddress;
164        mDeviceType = deviceType;
165        mVendorId = vendorId;
166        mDevicePowerStatus = powerStatus;
167        mDisplayName = displayName;
168
169        mDeviceId = -1;
170        mAdopterId = -1;
171    }
172
173    /**
174     * Constructor. Used to initialize the instance for CEC device.
175     *
176     * @param logicalAddress logical address of HDMI-CEC device
177     * @param physicalAddress physical address of HDMI-CEC device
178     * @param portId HDMI port ID (1 for HDMI1)
179     * @param deviceType type of device
180     * @param vendorId vendor id of device. Used for vendor specific command.
181     * @param displayName name of device
182     * @hide
183     */
184    public HdmiDeviceInfo(int logicalAddress, int physicalAddress, int portId, int deviceType,
185            int vendorId, String displayName) {
186        this(logicalAddress, physicalAddress, portId, deviceType,
187                vendorId, displayName, HdmiControlManager.POWER_STATUS_UNKNOWN);
188    }
189
190    /**
191     * Constructor. Used to initialize the instance for device representing hardware port.
192     *
193     * @param physicalAddress physical address of the port
194     * @param portId HDMI port ID (1 for HDMI1)
195     * @hide
196     */
197    public HdmiDeviceInfo(int physicalAddress, int portId) {
198        mHdmiDeviceType = HDMI_DEVICE_TYPE_HARDWARE;
199        mPhysicalAddress = physicalAddress;
200        mPortId = portId;
201
202        mId = idForHardware(portId);
203        mLogicalAddress = -1;
204        mDeviceType = DEVICE_RESERVED;
205        mVendorId = 0;
206        mDevicePowerStatus = HdmiControlManager.POWER_STATUS_UNKNOWN;
207        mDisplayName = "HDMI" + portId;
208
209        mDeviceId = -1;
210        mAdopterId = -1;
211
212    }
213
214    /**
215     * Constructor. Used to initialize the instance for MHL device.
216     *
217     * @param physicalAddress physical address of HDMI device
218     * @param portId portId HDMI port ID (1 for HDMI1)
219     * @param adopterId adopter id of MHL
220     * @param deviceId device id of MHL
221     * @hide
222     */
223    public HdmiDeviceInfo(int physicalAddress, int portId, int adopterId, int deviceId) {
224        mHdmiDeviceType = HDMI_DEVICE_TYPE_MHL;
225        mPhysicalAddress = physicalAddress;
226        mPortId = portId;
227
228        mId = idForMhlDevice(portId);
229        mLogicalAddress = -1;
230        mDeviceType = DEVICE_RESERVED;
231        mVendorId = 0;
232        mDevicePowerStatus = HdmiControlManager.POWER_STATUS_UNKNOWN;
233        mDisplayName = "Mobile";
234
235        mDeviceId = adopterId;
236        mAdopterId = deviceId;
237    }
238
239    /**
240     * Returns the id of the device.
241     */
242    public int getId() {
243        return mId;
244    }
245
246    /**
247     * Returns the id to be used for CEC device.
248     *
249     * @param address logical address of CEC device
250     * @return id for CEC device
251     */
252    public static int idForCecDevice(int address) {
253        // The id is generated based on the logical address.
254        return ID_OFFSET_CEC + address;
255    }
256
257    /**
258     * Returns the id to be used for MHL device.
259     *
260     * @param portId port which the MHL device is connected to
261     * @return id for MHL device
262     */
263    public static int idForMhlDevice(int portId) {
264        // The id is generated based on the port id since there can be only one MHL device per port.
265        return ID_OFFSET_MHL + portId;
266    }
267
268    /**
269     * Returns the id to be used for hardware port.
270     *
271     * @param portId port id
272     * @return id for hardware port
273     */
274    public static int idForHardware(int portId) {
275        return ID_OFFSET_HARDWARE + portId;
276    }
277
278    /**
279     * Returns the CEC logical address of the device.
280     */
281    public int getLogicalAddress() {
282        return mLogicalAddress;
283    }
284
285    /**
286     * Returns the physical address of the device.
287     */
288    public int getPhysicalAddress() {
289        return mPhysicalAddress;
290    }
291
292    /**
293     * Returns the port ID.
294     */
295    public int getPortId() {
296        return mPortId;
297    }
298
299    /**
300     * Returns CEC type of the device. For more details, refer constants between {@link #DEVICE_TV}
301     * and {@link #DEVICE_INACTIVE}.
302     */
303    public int getDeviceType() {
304        return mDeviceType;
305    }
306
307    /**
308     * Returns device's power status. It should be one of the following values.
309     * <ul>
310     * <li>{@link HdmiControlManager#POWER_STATUS_ON}
311     * <li>{@link HdmiControlManager#POWER_STATUS_STANDBY}
312     * <li>{@link HdmiControlManager#POWER_STATUS_TRANSIENT_TO_ON}
313     * <li>{@link HdmiControlManager#POWER_STATUS_TRANSIENT_TO_STANDBY}
314     * <li>{@link HdmiControlManager#POWER_STATUS_UNKNOWN}
315     * </ul>
316     */
317    public int getDevicePowerStatus() {
318        return mDevicePowerStatus;
319    }
320
321    /**
322     * Returns MHL device id. Return -1 for non-MHL device.
323     */
324    public int getDeviceId() {
325        return mDeviceId;
326    }
327
328    /**
329     * Returns MHL adopter id. Return -1 for non-MHL device.
330     */
331    public int getAdopterId() {
332        return mAdopterId;
333    }
334
335    /**
336     * Returns {@code true} if the device is of a type that can be an input source.
337     */
338    public boolean isSourceType() {
339        if (isCecDevice()) {
340            return mDeviceType == DEVICE_PLAYBACK
341                    || mDeviceType == DEVICE_RECORDER
342                    || mDeviceType == DEVICE_TUNER;
343        } else if (isMhlDevice()) {
344            return true;
345        } else {
346            return false;
347        }
348    }
349
350    /**
351     * Returns {@code true} if the device represents an HDMI-CEC device. {@code false} if the device
352     * is either MHL or other device.
353     */
354    public boolean isCecDevice() {
355        return mHdmiDeviceType == HDMI_DEVICE_TYPE_CEC;
356    }
357
358    /**
359     * Returns {@code true} if the device represents an MHL device. {@code false} if the device is
360     * either CEC or other device.
361     */
362    public boolean isMhlDevice() {
363        return mHdmiDeviceType == HDMI_DEVICE_TYPE_MHL;
364    }
365
366    /**
367     * Returns display (OSD) name of the device.
368     */
369    public String getDisplayName() {
370        return mDisplayName;
371    }
372
373    /**
374     * Returns vendor id of the device. Vendor id is used to distinguish devices built by other
375     * manufactures. This is required for vendor-specific command on CEC standard.
376     */
377    public int getVendorId() {
378        return mVendorId;
379    }
380
381    /**
382     * Describes the kinds of special objects contained in this Parcelable's marshalled
383     * representation.
384     */
385    @Override
386    public int describeContents() {
387        return 0;
388    }
389
390    /**
391     * Serializes this object into a {@link Parcel}.
392     *
393     * @param dest The Parcel in which the object should be written.
394     * @param flags Additional flags about how the object should be written. May be 0 or
395     *            {@link Parcelable#PARCELABLE_WRITE_RETURN_VALUE}.
396     */
397    @Override
398    public void writeToParcel(Parcel dest, int flags) {
399        dest.writeInt(mHdmiDeviceType);
400        dest.writeInt(mPhysicalAddress);
401        dest.writeInt(mPortId);
402        switch (mHdmiDeviceType) {
403            case HDMI_DEVICE_TYPE_CEC:
404                dest.writeInt(mLogicalAddress);
405                dest.writeInt(mDeviceType);
406                dest.writeInt(mVendorId);
407                dest.writeInt(mDevicePowerStatus);
408                dest.writeString(mDisplayName);
409                break;
410            case HDMI_DEVICE_TYPE_MHL:
411                dest.writeInt(mDeviceId);
412                dest.writeInt(mAdopterId);
413                break;
414            default:
415                // no-op
416        }
417    }
418
419    @Override
420    public String toString() {
421        StringBuffer s = new StringBuffer();
422        switch (mHdmiDeviceType) {
423            case HDMI_DEVICE_TYPE_CEC:
424                s.append("CEC: ");
425                s.append("logical_address: ").append(String.format("0x%02X", mLogicalAddress));
426                s.append(" ");
427                s.append("device_type: ").append(mDeviceType).append(" ");
428                s.append("vendor_id: ").append(mVendorId).append(" ");
429                s.append("display_name: ").append(mDisplayName).append(" ");
430                s.append("power_status: ").append(mDevicePowerStatus).append(" ");
431                break;
432            case HDMI_DEVICE_TYPE_MHL:
433                s.append("MHL: ");
434                s.append("device_id: ").append(String.format("0x%04X", mDeviceId)).append(" ");
435                s.append("adopter_id: ").append(String.format("0x%04X", mAdopterId)).append(" ");
436                break;
437
438            case HDMI_DEVICE_TYPE_HARDWARE:
439                s.append("Hardware: ");
440                break;
441            default:
442                return "";
443        }
444        s.append("physical_address: ").append(String.format("0x%04X", mPhysicalAddress));
445        s.append(" ");
446        s.append("port_id: ").append(mPortId);
447        return s.toString();
448    }
449
450    @Override
451    public boolean equals(Object obj) {
452        if (!(obj instanceof HdmiDeviceInfo)) {
453            return false;
454        }
455
456        HdmiDeviceInfo other = (HdmiDeviceInfo) obj;
457        return mHdmiDeviceType == other.mHdmiDeviceType
458                && mPhysicalAddress == other.mPhysicalAddress
459                && mPortId == other.mPortId
460                && mLogicalAddress == other.mLogicalAddress
461                && mDeviceType == other.mDeviceType
462                && mVendorId == other.mVendorId
463                && mDevicePowerStatus == other.mDevicePowerStatus
464                && mDisplayName.equals(other.mDisplayName)
465                && mDeviceId == other.mDeviceId
466                && mAdopterId == other.mAdopterId;
467    }
468}
469