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 com.android.server.hdmi; 18 19 import android.annotation.Nullable; 20 21 import libcore.util.EmptyArray; 22 23 import java.util.Arrays; 24 import java.util.Objects; 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 */ 31 public final class HdmiCecMessage { 32 public static final byte[] EMPTY_PARAM = EmptyArray.BYTE; 33 34 private final int mSource; 35 private final int mDestination; 36 37 private final int mOpcode; 38 private final byte[] mParams; 39 40 /** 41 * Constructor. 42 */ HdmiCecMessage(int source, int destination, int opcode, byte[] params)43 public HdmiCecMessage(int source, int destination, int opcode, byte[] params) { 44 mSource = source; 45 mDestination = destination; 46 mOpcode = opcode & 0xFF; 47 mParams = Arrays.copyOf(params, params.length); 48 } 49 50 @Override equals(@ullable Object message)51 public boolean equals(@Nullable Object message) { 52 if (message instanceof HdmiCecMessage) { 53 HdmiCecMessage that = (HdmiCecMessage) message; 54 return this.mSource == that.getSource() && 55 this.mDestination == that.getDestination() && 56 this.mOpcode == that.getOpcode() && 57 Arrays.equals(this.mParams, that.getParams()); 58 } 59 return false; 60 } 61 62 @Override hashCode()63 public int hashCode() { 64 return Objects.hash( 65 mSource, 66 mDestination, 67 mOpcode, 68 Arrays.hashCode(mParams)); 69 } 70 71 /** 72 * Return the source address field of the message. It is the logical address 73 * of the device which generated the message. 74 * 75 * @return source address 76 */ getSource()77 public int getSource() { 78 return mSource; 79 } 80 81 /** 82 * Return the destination address field of the message. It is the logical address 83 * of the device to which the message is sent. 84 * 85 * @return destination address 86 */ getDestination()87 public int getDestination() { 88 return mDestination; 89 } 90 91 /** 92 * Return the opcode field of the message. It is the type of the message that 93 * tells the destination device what to do. 94 * 95 * @return opcode 96 */ getOpcode()97 public int getOpcode() { 98 return mOpcode; 99 } 100 101 /** 102 * Return the parameter field of the message. The contents of parameter varies 103 * from opcode to opcode, and is used together with opcode to describe 104 * the action for the destination device to take. 105 * 106 * @return parameter 107 */ getParams()108 public byte[] getParams() { 109 return mParams; 110 } 111 112 @Override toString()113 public String toString() { 114 StringBuffer s = new StringBuffer(); 115 s.append(String.format("<%s> %X%X:%02X", 116 opcodeToString(mOpcode), mSource, mDestination, mOpcode)); 117 if (mParams.length > 0) { 118 for (byte data : mParams) { 119 s.append(String.format(":%02X", data)); 120 } 121 } 122 return s.toString(); 123 } 124 opcodeToString(int opcode)125 private static String opcodeToString(int opcode) { 126 switch (opcode) { 127 case Constants.MESSAGE_FEATURE_ABORT: 128 return "Feature Abort"; 129 case Constants.MESSAGE_IMAGE_VIEW_ON: 130 return "Image View On"; 131 case Constants.MESSAGE_TUNER_STEP_INCREMENT: 132 return "Tuner Step Increment"; 133 case Constants.MESSAGE_TUNER_STEP_DECREMENT: 134 return "Tuner Step Decrement"; 135 case Constants.MESSAGE_TUNER_DEVICE_STATUS: 136 return "Tuner Device Status"; 137 case Constants.MESSAGE_GIVE_TUNER_DEVICE_STATUS: 138 return "Give Tuner Device Status"; 139 case Constants.MESSAGE_RECORD_ON: 140 return "Record On"; 141 case Constants.MESSAGE_RECORD_STATUS: 142 return "Record Status"; 143 case Constants.MESSAGE_RECORD_OFF: 144 return "Record Off"; 145 case Constants.MESSAGE_TEXT_VIEW_ON: 146 return "Text View On"; 147 case Constants.MESSAGE_RECORD_TV_SCREEN: 148 return "Record Tv Screen"; 149 case Constants.MESSAGE_GIVE_DECK_STATUS: 150 return "Give Deck Status"; 151 case Constants.MESSAGE_DECK_STATUS: 152 return "Deck Status"; 153 case Constants.MESSAGE_SET_MENU_LANGUAGE: 154 return "Set Menu Language"; 155 case Constants.MESSAGE_CLEAR_ANALOG_TIMER: 156 return "Clear Analog Timer"; 157 case Constants.MESSAGE_SET_ANALOG_TIMER: 158 return "Set Analog Timer"; 159 case Constants.MESSAGE_TIMER_STATUS: 160 return "Timer Status"; 161 case Constants.MESSAGE_STANDBY: 162 return "Standby"; 163 case Constants.MESSAGE_PLAY: 164 return "Play"; 165 case Constants.MESSAGE_DECK_CONTROL: 166 return "Deck Control"; 167 case Constants.MESSAGE_TIMER_CLEARED_STATUS: 168 return "Timer Cleared Status"; 169 case Constants.MESSAGE_USER_CONTROL_PRESSED: 170 return "User Control Pressed"; 171 case Constants.MESSAGE_USER_CONTROL_RELEASED: 172 return "User Control Release"; 173 case Constants.MESSAGE_GIVE_OSD_NAME: 174 return "Give Osd Name"; 175 case Constants.MESSAGE_SET_OSD_NAME: 176 return "Set Osd Name"; 177 case Constants.MESSAGE_SET_OSD_STRING: 178 return "Set Osd String"; 179 case Constants.MESSAGE_SET_TIMER_PROGRAM_TITLE: 180 return "Set Timer Program Title"; 181 case Constants.MESSAGE_SYSTEM_AUDIO_MODE_REQUEST: 182 return "System Audio Mode Request"; 183 case Constants.MESSAGE_GIVE_AUDIO_STATUS: 184 return "Give Audio Status"; 185 case Constants.MESSAGE_SET_SYSTEM_AUDIO_MODE: 186 return "Set System Audio Mode"; 187 case Constants.MESSAGE_REPORT_AUDIO_STATUS: 188 return "Report Audio Status"; 189 case Constants.MESSAGE_GIVE_SYSTEM_AUDIO_MODE_STATUS: 190 return "Give System Audio Mode Status"; 191 case Constants.MESSAGE_SYSTEM_AUDIO_MODE_STATUS: 192 return "System Audio Mode Status"; 193 case Constants.MESSAGE_ROUTING_CHANGE: 194 return "Routing Change"; 195 case Constants.MESSAGE_ROUTING_INFORMATION: 196 return "Routing Information"; 197 case Constants.MESSAGE_ACTIVE_SOURCE: 198 return "Active Source"; 199 case Constants.MESSAGE_GIVE_PHYSICAL_ADDRESS: 200 return "Give Physical Address"; 201 case Constants.MESSAGE_REPORT_PHYSICAL_ADDRESS: 202 return "Report Physical Address"; 203 case Constants.MESSAGE_REQUEST_ACTIVE_SOURCE: 204 return "Request Active Source"; 205 case Constants.MESSAGE_SET_STREAM_PATH: 206 return "Set Stream Path"; 207 case Constants.MESSAGE_DEVICE_VENDOR_ID: 208 return "Device Vendor Id"; 209 case Constants.MESSAGE_VENDOR_COMMAND: 210 return "Vendor Command"; 211 case Constants.MESSAGE_VENDOR_REMOTE_BUTTON_DOWN: 212 return "Vendor Remote Button Down"; 213 case Constants.MESSAGE_VENDOR_REMOTE_BUTTON_UP: 214 return "Vendor Remote Button Up"; 215 case Constants.MESSAGE_GIVE_DEVICE_VENDOR_ID: 216 return "Give Device Vendor Id"; 217 case Constants.MESSAGE_MENU_REQUEST: 218 return "Menu Request"; 219 case Constants.MESSAGE_MENU_STATUS: 220 return "Menu Status"; 221 case Constants.MESSAGE_GIVE_DEVICE_POWER_STATUS: 222 return "Give Device Power Status"; 223 case Constants.MESSAGE_REPORT_POWER_STATUS: 224 return "Report Power Status"; 225 case Constants.MESSAGE_GET_MENU_LANGUAGE: 226 return "Get Menu Language"; 227 case Constants.MESSAGE_SELECT_ANALOG_SERVICE: 228 return "Select Analog Service"; 229 case Constants.MESSAGE_SELECT_DIGITAL_SERVICE: 230 return "Select Digital Service"; 231 case Constants.MESSAGE_SET_DIGITAL_TIMER: 232 return "Set Digital Timer"; 233 case Constants.MESSAGE_CLEAR_DIGITAL_TIMER: 234 return "Clear Digital Timer"; 235 case Constants.MESSAGE_SET_AUDIO_RATE: 236 return "Set Audio Rate"; 237 case Constants.MESSAGE_INACTIVE_SOURCE: 238 return "InActive Source"; 239 case Constants.MESSAGE_CEC_VERSION: 240 return "Cec Version"; 241 case Constants.MESSAGE_GET_CEC_VERSION: 242 return "Get Cec Version"; 243 case Constants.MESSAGE_VENDOR_COMMAND_WITH_ID: 244 return "Vendor Command With Id"; 245 case Constants.MESSAGE_CLEAR_EXTERNAL_TIMER: 246 return "Clear External Timer"; 247 case Constants.MESSAGE_SET_EXTERNAL_TIMER: 248 return "Set External Timer"; 249 case Constants.MESSAGE_REPORT_SHORT_AUDIO_DESCRIPTOR: 250 return "Report Short Audio Descriptor"; 251 case Constants.MESSAGE_REQUEST_SHORT_AUDIO_DESCRIPTOR: 252 return "Request Short Audio Descriptor"; 253 case Constants.MESSAGE_INITIATE_ARC: 254 return "Initiate ARC"; 255 case Constants.MESSAGE_REPORT_ARC_INITIATED: 256 return "Report ARC Initiated"; 257 case Constants.MESSAGE_REPORT_ARC_TERMINATED: 258 return "Report ARC Terminated"; 259 case Constants.MESSAGE_REQUEST_ARC_INITIATION: 260 return "Request ARC Initiation"; 261 case Constants.MESSAGE_REQUEST_ARC_TERMINATION: 262 return "Request ARC Termination"; 263 case Constants.MESSAGE_TERMINATE_ARC: 264 return "Terminate ARC"; 265 case Constants.MESSAGE_CDC_MESSAGE: 266 return "Cdc Message"; 267 case Constants.MESSAGE_ABORT: 268 return "Abort"; 269 default: 270 return String.format("Opcode: %02X", opcode); 271 } 272 } 273 } 274 275