HdmiCecMessage.java revision 119160a68195bcb2f5bdf4a269807e01228eca97
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 com.android.server.hdmi;
18
19import android.os.Parcel;
20import android.os.Parcelable;
21
22import libcore.util.EmptyArray;
23
24import java.util.Arrays;
25
26/**
27 * A class to encapsulate HDMI-CEC message used for the devices connected via
28 * HDMI cable to communicate with one another. A message is defined by its
29 * source and destination address, command (or opcode), and optional parameters.
30 */
31public final class HdmiCecMessage implements Parcelable {
32
33    public static final byte[] EMPTY_PARAM = EmptyArray.BYTE;
34
35    private static final int MAX_MESSAGE_LENGTH = 16;
36
37    private final int mSource;
38    private final int mDestination;
39
40    private final int mOpcode;
41    private final byte[] mParams;
42
43    /**
44     * Constructor.
45     */
46    public HdmiCecMessage(int source, int destination, int opcode, byte[] params) {
47        mSource = source;
48        mDestination = destination;
49        mOpcode = opcode & 0xFF;
50        mParams = Arrays.copyOf(params, params.length);
51    }
52
53    /**
54     * Return the source address field of the message. It is the logical address
55     * of the device which generated the message.
56     *
57     * @return source address
58     */
59    public int getSource() {
60        return mSource;
61    }
62
63    /**
64     * Return the destination address field of the message. It is the logical address
65     * of the device to which the message is sent.
66     *
67     * @return destination address
68     */
69    public int getDestination() {
70        return mDestination;
71    }
72
73    /**
74     * Return the opcode field of the message. It is the type of the message that
75     * tells the destination device what to do.
76     *
77     * @return opcode
78     */
79    public int getOpcode() {
80        return mOpcode;
81    }
82
83    /**
84     * Return the parameter field of the message. The contents of parameter varies
85     * from opcode to opcode, and is used together with opcode to describe
86     * the action for the destination device to take.
87     *
88     * @return parameter
89     */
90    public byte[] getParams() {
91        return mParams;
92    }
93
94    /**
95     * Describe the kinds of special objects contained in this Parcelable's
96     * marshalled representation.
97     */
98    @Override
99    public int describeContents() {
100        return 0;
101    }
102
103    /**
104     * Flatten this object in to a Parcel.
105     *
106     * @param dest The Parcel in which the object should be written.
107     * @param flags Additional flags about how the object should be written.
108     *        May be 0 or {@link Parcelable#PARCELABLE_WRITE_RETURN_VALUE}.
109     */
110    @Override
111    public void writeToParcel(Parcel dest, int flags) {
112        dest.writeInt(mSource);
113        dest.writeInt(mDestination);
114        dest.writeInt(mOpcode);
115        dest.writeInt(mParams.length);
116        dest.writeByteArray(mParams);
117    }
118
119    public static final Parcelable.Creator<HdmiCecMessage> CREATOR
120            = new Parcelable.Creator<HdmiCecMessage>() {
121        /**
122         * Rebuild a HdmiCecMessage previously stored with writeToParcel().
123         * @param p HdmiCecMessage object to read the Rating from
124         * @return a new HdmiCecMessage created from the data in the parcel
125         */
126        @Override
127        public HdmiCecMessage createFromParcel(Parcel p) {
128            int source = p.readInt();
129            int destination = p.readInt();
130            int opcode = p.readInt();
131            byte[] params = new byte[p.readInt()];
132            p.readByteArray(params);
133            return new HdmiCecMessage(source, destination, opcode, params);
134        }
135        @Override
136        public HdmiCecMessage[] newArray(int size) {
137            return new HdmiCecMessage[size];
138        }
139    };
140
141    @Override
142    public String toString() {
143        StringBuffer s = new StringBuffer();
144        s.append(String.format("<%s> src: %d, dst: %d",
145                opcodeToString(mOpcode), mSource, mDestination));
146        if (mParams.length > 0) {
147            s.append(", params:");
148            for (byte data : mParams) {
149                s.append(String.format(" %02X", data));
150            }
151        }
152        return s.toString();
153    }
154
155    private static String opcodeToString(int opcode) {
156        switch (opcode) {
157            case Constants.MESSAGE_FEATURE_ABORT:
158                return "Feature Abort";
159            case Constants.MESSAGE_CEC_VERSION:
160                return "CEC Version";
161            case Constants.MESSAGE_REQUEST_ARC_INITIATION:
162                return "Request ARC Initiation";
163            case Constants.MESSAGE_REQUEST_ARC_TERMINATION:
164                return "Request ARC Termination";
165            case Constants.MESSAGE_REPORT_ARC_INITIATED:
166                return "Report ARC Initiated";
167            case Constants.MESSAGE_REPORT_ARC_TERMINATED:
168                return "Report ARC Terminated";
169            case Constants.MESSAGE_TEXT_VIEW_ON:
170                return "Text View On";
171            case Constants.MESSAGE_ACTIVE_SOURCE:
172                return "Active Source";
173            case Constants.MESSAGE_GIVE_DEVICE_POWER_STATUS:
174                return "Give Device Power Status";
175            case Constants.MESSAGE_VENDOR_COMMAND:
176                return "Vendor Command";
177            case Constants.MESSAGE_VENDOR_COMMAND_WITH_ID:
178                return "Vendor Command With ID";
179            default:
180                return String.format("Opcode: %02X", opcode);
181        }
182    }
183}
184
185