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 com.android.server.hdmi.Constants.AudioCodec; 20 21 import java.io.UnsupportedEncodingException; 22 import java.util.Arrays; 23 24 /** 25 * A helper class to build {@link HdmiCecMessage} from various cec commands. 26 */ 27 public class HdmiCecMessageBuilder { 28 private static final int OSD_NAME_MAX_LENGTH = 13; 29 HdmiCecMessageBuilder()30 private HdmiCecMessageBuilder() {} 31 32 /** 33 * Build {@link HdmiCecMessage} from raw data. 34 * 35 * @param src source address of command 36 * @param dest destination address of command 37 * @param body body of message. It includes opcode. 38 * @return newly created {@link HdmiCecMessage} 39 */ of(int src, int dest, byte[] body)40 static HdmiCecMessage of(int src, int dest, byte[] body) { 41 byte opcode = body[0]; 42 byte params[] = Arrays.copyOfRange(body, 1, body.length); 43 return new HdmiCecMessage(src, dest, opcode, params); 44 } 45 46 /** 47 * Build <Feature Abort> command. <Feature Abort> consists of 48 * 1 byte original opcode and 1 byte reason fields with basic fields. 49 * 50 * @param src source address of command 51 * @param dest destination address of command 52 * @param originalOpcode original opcode causing feature abort 53 * @param reason reason of feature abort 54 * @return newly created {@link HdmiCecMessage} 55 */ buildFeatureAbortCommand(int src, int dest, int originalOpcode, int reason)56 static HdmiCecMessage buildFeatureAbortCommand(int src, int dest, int originalOpcode, 57 int reason) { 58 byte[] params = new byte[] { 59 (byte) (originalOpcode & 0xFF), 60 (byte) (reason & 0xFF), 61 }; 62 return buildCommand(src, dest, Constants.MESSAGE_FEATURE_ABORT, params); 63 } 64 65 /** 66 * Build <Give Physical Address> command. 67 * 68 * @param src source address of command 69 * @param dest destination address of command 70 * @return newly created {@link HdmiCecMessage} 71 */ buildGivePhysicalAddress(int src, int dest)72 static HdmiCecMessage buildGivePhysicalAddress(int src, int dest) { 73 return buildCommand(src, dest, Constants.MESSAGE_GIVE_PHYSICAL_ADDRESS); 74 } 75 76 /** 77 * Build <Give Osd Name> command. 78 * 79 * @param src source address of command 80 * @param dest destination address of command 81 * @return newly created {@link HdmiCecMessage} 82 */ buildGiveOsdNameCommand(int src, int dest)83 static HdmiCecMessage buildGiveOsdNameCommand(int src, int dest) { 84 return buildCommand(src, dest, Constants.MESSAGE_GIVE_OSD_NAME); 85 } 86 87 /** 88 * Build <Give Vendor Id Command> command. 89 * 90 * @param src source address of command 91 * @param dest destination address of command 92 * @return newly created {@link HdmiCecMessage} 93 */ buildGiveDeviceVendorIdCommand(int src, int dest)94 static HdmiCecMessage buildGiveDeviceVendorIdCommand(int src, int dest) { 95 return buildCommand(src, dest, Constants.MESSAGE_GIVE_DEVICE_VENDOR_ID); 96 } 97 98 /** 99 * Build <Set Menu Language > command. 100 * 101 * <p>This is a broadcast message sent to all devices on the bus. 102 * 103 * @param src source address of command 104 * @param language 3-letter ISO639-2 based language code 105 * @return newly created {@link HdmiCecMessage} if language is valid. 106 * Otherwise, return null 107 */ buildSetMenuLanguageCommand(int src, String language)108 static HdmiCecMessage buildSetMenuLanguageCommand(int src, String language) { 109 if (language.length() != 3) { 110 return null; 111 } 112 // Hdmi CEC uses lower-cased ISO 639-2 (3 letters code). 113 String normalized = language.toLowerCase(); 114 byte[] params = new byte[] { 115 (byte) (normalized.charAt(0) & 0xFF), 116 (byte) (normalized.charAt(1) & 0xFF), 117 (byte) (normalized.charAt(2) & 0xFF), 118 }; 119 // <Set Menu Language> is broadcast message. 120 return buildCommand(src, Constants.ADDR_BROADCAST, 121 Constants.MESSAGE_SET_MENU_LANGUAGE, params); 122 } 123 124 /** 125 * Build <Set Osd Name > command. 126 * 127 * @param src source address of command 128 * @param name display (OSD) name of device 129 * @return newly created {@link HdmiCecMessage} if valid name. Otherwise, 130 * return null 131 */ buildSetOsdNameCommand(int src, int dest, String name)132 static HdmiCecMessage buildSetOsdNameCommand(int src, int dest, String name) { 133 int length = Math.min(name.length(), OSD_NAME_MAX_LENGTH); 134 byte[] params; 135 try { 136 params = name.substring(0, length).getBytes("US-ASCII"); 137 } catch (UnsupportedEncodingException e) { 138 return null; 139 } 140 return buildCommand(src, dest, Constants.MESSAGE_SET_OSD_NAME, params); 141 } 142 143 /** 144 * Build <Report Physical Address> command. It has two bytes physical 145 * address and one byte device type as parameter. 146 * 147 * <p>This is a broadcast message sent to all devices on the bus. 148 * 149 * @param src source address of command 150 * @param address physical address of device 151 * @param deviceType type of device 152 * @return newly created {@link HdmiCecMessage} 153 */ buildReportPhysicalAddressCommand(int src, int address, int deviceType)154 static HdmiCecMessage buildReportPhysicalAddressCommand(int src, int address, int deviceType) { 155 byte[] params = new byte[] { 156 // Two bytes for physical address 157 (byte) ((address >> 8) & 0xFF), 158 (byte) (address & 0xFF), 159 // One byte device type 160 (byte) (deviceType & 0xFF) 161 }; 162 // <Report Physical Address> is broadcast message. 163 return buildCommand(src, Constants.ADDR_BROADCAST, 164 Constants.MESSAGE_REPORT_PHYSICAL_ADDRESS, params); 165 } 166 167 /** 168 * Build <Device Vendor Id> command. It has three bytes vendor id as 169 * parameter. 170 * 171 * <p>This is a broadcast message sent to all devices on the bus. 172 * 173 * @param src source address of command 174 * @param vendorId device's vendor id 175 * @return newly created {@link HdmiCecMessage} 176 */ buildDeviceVendorIdCommand(int src, int vendorId)177 static HdmiCecMessage buildDeviceVendorIdCommand(int src, int vendorId) { 178 byte[] params = new byte[] { 179 (byte) ((vendorId >> 16) & 0xFF), 180 (byte) ((vendorId >> 8) & 0xFF), 181 (byte) (vendorId & 0xFF) 182 }; 183 // <Device Vendor Id> is broadcast message. 184 return buildCommand(src, Constants.ADDR_BROADCAST, 185 Constants.MESSAGE_DEVICE_VENDOR_ID, params); 186 } 187 188 /** 189 * Build <Device Vendor Id> command. It has one byte cec version as parameter. 190 * 191 * @param src source address of command 192 * @param dest destination address of command 193 * @param version version of cec. Use 0x04 for "Version 1.3a" and 0x05 for 194 * "Version 1.4 or 1.4a or 1.4b 195 * @return newly created {@link HdmiCecMessage} 196 */ buildCecVersion(int src, int dest, int version)197 static HdmiCecMessage buildCecVersion(int src, int dest, int version) { 198 byte[] params = new byte[] { 199 (byte) (version & 0xFF) 200 }; 201 return buildCommand(src, dest, Constants.MESSAGE_CEC_VERSION, params); 202 } 203 204 /** 205 * Build <Request Arc Initiation> 206 * 207 * @param src source address of command 208 * @param dest destination address of command 209 * @return newly created {@link HdmiCecMessage} 210 */ buildRequestArcInitiation(int src, int dest)211 static HdmiCecMessage buildRequestArcInitiation(int src, int dest) { 212 return buildCommand(src, dest, Constants.MESSAGE_REQUEST_ARC_INITIATION); 213 } 214 215 /** 216 * Build <Initiate Arc> 217 * 218 * @param src source address of command 219 * @param dest destination address of command 220 * @return newly created {@link HdmiCecMessage} 221 */ buildInitiateArc(int src, int dest)222 static HdmiCecMessage buildInitiateArc(int src, int dest) { 223 return buildCommand(src, dest, Constants.MESSAGE_INITIATE_ARC); 224 } 225 226 /** 227 * Build <Terminate Arc> 228 * 229 * @param src source address of command 230 * @param dest destination address of command 231 * @return newly created {@link HdmiCecMessage} 232 */ buildTerminateArc(int src, int dest)233 static HdmiCecMessage buildTerminateArc(int src, int dest) { 234 return buildCommand(src, dest, Constants.MESSAGE_TERMINATE_ARC); 235 } 236 237 /** 238 * Build <Request Arc Termination> 239 * 240 * @param src source address of command 241 * @param dest destination address of command 242 * @return newly created {@link HdmiCecMessage} 243 */ buildRequestArcTermination(int src, int dest)244 static HdmiCecMessage buildRequestArcTermination(int src, int dest) { 245 return buildCommand(src, dest, Constants.MESSAGE_REQUEST_ARC_TERMINATION); 246 } 247 248 /** 249 * Build <Report Arc Initiated> 250 * 251 * @param src source address of command 252 * @param dest destination address of command 253 * @return newly created {@link HdmiCecMessage} 254 */ buildReportArcInitiated(int src, int dest)255 static HdmiCecMessage buildReportArcInitiated(int src, int dest) { 256 return buildCommand(src, dest, Constants.MESSAGE_REPORT_ARC_INITIATED); 257 } 258 259 /** 260 * Build <Report Arc Terminated> 261 * 262 * @param src source address of command 263 * @param dest destination address of command 264 * @return newly created {@link HdmiCecMessage} 265 */ buildReportArcTerminated(int src, int dest)266 static HdmiCecMessage buildReportArcTerminated(int src, int dest) { 267 return buildCommand(src, dest, Constants.MESSAGE_REPORT_ARC_TERMINATED); 268 } 269 270 271 /** 272 * Build <Request Short Audio Descriptor> command. 273 * 274 * @param src source address of command 275 * @param dest destination address of command 276 * @param audioFormats the {@link AudioCodec}s desired 277 * @return newly created {@link HdmiCecMessage} 278 */ buildRequestShortAudioDescriptor(int src, int dest, @AudioCodec int[] audioFormats)279 static HdmiCecMessage buildRequestShortAudioDescriptor(int src, int dest, 280 @AudioCodec int[] audioFormats) { 281 byte[] params = new byte[Math.min(audioFormats.length,4)] ; 282 for (int i = 0; i < params.length ; i++){ 283 params[i] = (byte) (audioFormats[i] & 0xff); 284 } 285 return buildCommand(src, dest, Constants.MESSAGE_REQUEST_SHORT_AUDIO_DESCRIPTOR, params); 286 } 287 288 289 /** 290 * Build <Text View On> command. 291 * 292 * @param src source address of command 293 * @param dest destination address of command 294 * @return newly created {@link HdmiCecMessage} 295 */ buildTextViewOn(int src, int dest)296 static HdmiCecMessage buildTextViewOn(int src, int dest) { 297 return buildCommand(src, dest, Constants.MESSAGE_TEXT_VIEW_ON); 298 } 299 300 /** 301 * Build <Request Active Source> command. 302 * 303 * @param src source address of command 304 * @return newly created {@link HdmiCecMessage} 305 */ buildRequestActiveSource(int src)306 static HdmiCecMessage buildRequestActiveSource(int src) { 307 return buildCommand(src, Constants.ADDR_BROADCAST, Constants.MESSAGE_REQUEST_ACTIVE_SOURCE); 308 } 309 310 /** 311 * Build <Active Source> command. 312 * 313 * @param src source address of command 314 * @param physicalAddress physical address of the device to become active 315 * @return newly created {@link HdmiCecMessage} 316 */ buildActiveSource(int src, int physicalAddress)317 static HdmiCecMessage buildActiveSource(int src, int physicalAddress) { 318 return buildCommand(src, Constants.ADDR_BROADCAST, Constants.MESSAGE_ACTIVE_SOURCE, 319 physicalAddressToParam(physicalAddress)); 320 } 321 322 /** 323 * Build <Inactive Source> command. 324 * 325 * @param src source address of command 326 * @param physicalAddress physical address of the device to become inactive 327 * @return newly created {@link HdmiCecMessage} 328 */ buildInactiveSource(int src, int physicalAddress)329 static HdmiCecMessage buildInactiveSource(int src, int physicalAddress) { 330 return buildCommand(src, Constants.ADDR_TV, 331 Constants.MESSAGE_INACTIVE_SOURCE, physicalAddressToParam(physicalAddress)); 332 } 333 334 /** 335 * Build <Set Stream Path> command. 336 * 337 * <p>This is a broadcast message sent to all devices on the bus. 338 * 339 * @param src source address of command 340 * @param streamPath physical address of the device to start streaming 341 * @return newly created {@link HdmiCecMessage} 342 */ buildSetStreamPath(int src, int streamPath)343 static HdmiCecMessage buildSetStreamPath(int src, int streamPath) { 344 return buildCommand(src, Constants.ADDR_BROADCAST, 345 Constants.MESSAGE_SET_STREAM_PATH, physicalAddressToParam(streamPath)); 346 } 347 348 /** 349 * Build <Routing Change> command. 350 * 351 * <p>This is a broadcast message sent to all devices on the bus. 352 * 353 * @param src source address of command 354 * @param oldPath physical address of the currently active routing path 355 * @param newPath physical address of the new active routing path 356 * @return newly created {@link HdmiCecMessage} 357 */ buildRoutingChange(int src, int oldPath, int newPath)358 static HdmiCecMessage buildRoutingChange(int src, int oldPath, int newPath) { 359 byte[] param = new byte[] { 360 (byte) ((oldPath >> 8) & 0xFF), (byte) (oldPath & 0xFF), 361 (byte) ((newPath >> 8) & 0xFF), (byte) (newPath & 0xFF) 362 }; 363 return buildCommand(src, Constants.ADDR_BROADCAST, Constants.MESSAGE_ROUTING_CHANGE, 364 param); 365 } 366 367 /** 368 * Build <Routing Information> command. 369 * 370 * <p>This is a broadcast message sent to all devices on the bus. 371 * 372 * @param src source address of command 373 * @param physicalAddress physical address of the new active routing path 374 * @return newly created {@link HdmiCecMessage} 375 */ buildRoutingInformation(int src, int physicalAddress)376 static HdmiCecMessage buildRoutingInformation(int src, int physicalAddress) { 377 return buildCommand(src, Constants.ADDR_BROADCAST, 378 Constants.MESSAGE_ROUTING_INFORMATION, physicalAddressToParam(physicalAddress)); 379 } 380 381 /** 382 * Build <Give Device Power Status> command. 383 * 384 * @param src source address of command 385 * @param dest destination address of command 386 * @return newly created {@link HdmiCecMessage} 387 */ buildGiveDevicePowerStatus(int src, int dest)388 static HdmiCecMessage buildGiveDevicePowerStatus(int src, int dest) { 389 return buildCommand(src, dest, Constants.MESSAGE_GIVE_DEVICE_POWER_STATUS); 390 } 391 392 /** 393 * Build <Report Power Status> command. 394 * 395 * @param src source address of command 396 * @param dest destination address of command 397 * @param powerStatus power status of the device 398 * @return newly created {@link HdmiCecMessage} 399 */ buildReportPowerStatus(int src, int dest, int powerStatus)400 static HdmiCecMessage buildReportPowerStatus(int src, int dest, int powerStatus) { 401 byte[] param = new byte[] { 402 (byte) (powerStatus & 0xFF) 403 }; 404 return buildCommand(src, dest, Constants.MESSAGE_REPORT_POWER_STATUS, param); 405 } 406 407 /** 408 * Build <Report Menu Status> command. 409 * 410 * @param src source address of command 411 * @param dest destination address of command 412 * @param menuStatus menu status of the device 413 * @return newly created {@link HdmiCecMessage} 414 */ buildReportMenuStatus(int src, int dest, int menuStatus)415 static HdmiCecMessage buildReportMenuStatus(int src, int dest, int menuStatus) { 416 byte[] param = new byte[] { 417 (byte) (menuStatus & 0xFF) 418 }; 419 return buildCommand(src, dest, Constants.MESSAGE_MENU_STATUS, param); 420 } 421 422 /** 423 * Build <System Audio Mode Request> command. 424 * 425 * @param src source address of command 426 * @param avr destination address of command, it should be AVR 427 * @param avrPhysicalAddress physical address of AVR 428 * @param enableSystemAudio whether to enable System Audio Mode or not 429 * @return newly created {@link HdmiCecMessage} 430 */ buildSystemAudioModeRequest(int src, int avr, int avrPhysicalAddress, boolean enableSystemAudio)431 static HdmiCecMessage buildSystemAudioModeRequest(int src, int avr, int avrPhysicalAddress, 432 boolean enableSystemAudio) { 433 if (enableSystemAudio) { 434 return buildCommand(src, avr, Constants.MESSAGE_SYSTEM_AUDIO_MODE_REQUEST, 435 physicalAddressToParam(avrPhysicalAddress)); 436 } else { 437 return buildCommand(src, avr, Constants.MESSAGE_SYSTEM_AUDIO_MODE_REQUEST); 438 } 439 } 440 441 /** 442 * Build <Set System Audio Mode> command. 443 * 444 * @param src source address of command 445 * @param des destination address of command 446 * @param systemAudioStatus whether to set System Audio Mode on or off 447 * @return newly created {@link HdmiCecMessage} 448 */ buildSetSystemAudioMode(int src, int des, boolean systemAudioStatus)449 static HdmiCecMessage buildSetSystemAudioMode(int src, int des, boolean systemAudioStatus) { 450 return buildCommandWithBooleanParam(src, des, Constants.MESSAGE_SET_SYSTEM_AUDIO_MODE, 451 systemAudioStatus 452 ); 453 } 454 455 /** 456 * Build <Report System Audio Mode> command. 457 * 458 * @param src source address of command 459 * @param des destination address of command 460 * @param systemAudioStatus whether System Audio Mode is on or off 461 * @return newly created {@link HdmiCecMessage} 462 */ buildReportSystemAudioMode(int src, int des, boolean systemAudioStatus)463 static HdmiCecMessage buildReportSystemAudioMode(int src, int des, boolean systemAudioStatus) { 464 return buildCommandWithBooleanParam(src, des, Constants.MESSAGE_SYSTEM_AUDIO_MODE_STATUS, 465 systemAudioStatus 466 ); 467 } 468 469 /** 470 * Build <Report Short Audio Descriptor> command. 471 * 472 * @param src source address of command 473 * @param des destination address of command 474 * @param sadBytes Short Audio Descriptor in bytes 475 * @return newly created {@link HdmiCecMessage} 476 */ buildReportShortAudioDescriptor(int src, int des, byte[] sadBytes)477 static HdmiCecMessage buildReportShortAudioDescriptor(int src, int des, byte[] sadBytes) { 478 // TODO(b/80297701) validate. 479 return buildCommand(src, des, Constants.MESSAGE_REPORT_SHORT_AUDIO_DESCRIPTOR, sadBytes); 480 } 481 482 /** 483 * Build <Give Audio Status> command. 484 * 485 * @param src source address of command 486 * @param dest destination address of command 487 * @return newly created {@link HdmiCecMessage} 488 */ buildGiveAudioStatus(int src, int dest)489 static HdmiCecMessage buildGiveAudioStatus(int src, int dest) { 490 return buildCommand(src, dest, Constants.MESSAGE_GIVE_AUDIO_STATUS); 491 } 492 493 /** 494 * Build <Report Audio Status> command. 495 * 496 * @param src source address of command 497 * @param dest destination address of command 498 * @param volume volume level of current device in param 499 * @param mute mute status of current device in param 500 * @return newly created {@link HdmiCecMessage} 501 */ buildReportAudioStatus(int src, int dest, int volume, boolean mute)502 static HdmiCecMessage buildReportAudioStatus(int src, int dest, int volume, boolean mute) { 503 byte status = (byte) ((byte) (mute ? 1 << 7 : 0) | ((byte) volume & 0x7F)); 504 byte[] params = new byte[] { status }; 505 return buildCommand(src, dest, Constants.MESSAGE_REPORT_AUDIO_STATUS, params); 506 } 507 508 /** 509 * Build <User Control Pressed> command. 510 * 511 * @param src source address of command 512 * @param dest destination address of command 513 * @param uiCommand keycode that user pressed 514 * @return newly created {@link HdmiCecMessage} 515 */ buildUserControlPressed(int src, int dest, int uiCommand)516 static HdmiCecMessage buildUserControlPressed(int src, int dest, int uiCommand) { 517 return buildUserControlPressed(src, dest, new byte[] { (byte) (uiCommand & 0xFF) }); 518 } 519 520 /** 521 * Build <User Control Pressed> command. 522 * 523 * @param src source address of command 524 * @param dest destination address of command 525 * @param commandParam uiCommand and the additional parameter 526 * @return newly created {@link HdmiCecMessage} 527 */ buildUserControlPressed(int src, int dest, byte[] commandParam)528 static HdmiCecMessage buildUserControlPressed(int src, int dest, byte[] commandParam) { 529 return buildCommand(src, dest, Constants.MESSAGE_USER_CONTROL_PRESSED, commandParam); 530 } 531 532 /** 533 * Build <User Control Released> command. 534 * 535 * @param src source address of command 536 * @param dest destination address of command 537 * @return newly created {@link HdmiCecMessage} 538 */ buildUserControlReleased(int src, int dest)539 static HdmiCecMessage buildUserControlReleased(int src, int dest) { 540 return buildCommand(src, dest, Constants.MESSAGE_USER_CONTROL_RELEASED); 541 } 542 543 /** 544 * Build <Give System Audio Mode Status> command. 545 * 546 * @param src source address of command 547 * @param dest destination address of command 548 * @return newly created {@link HdmiCecMessage} 549 */ buildGiveSystemAudioModeStatus(int src, int dest)550 static HdmiCecMessage buildGiveSystemAudioModeStatus(int src, int dest) { 551 return buildCommand(src, dest, Constants.MESSAGE_GIVE_SYSTEM_AUDIO_MODE_STATUS); 552 } 553 554 /** 555 * Build <Standby> command. 556 * 557 * @param src source address of command 558 * @param dest destination address of command 559 * @return newly created {@link HdmiCecMessage} 560 */ buildStandby(int src, int dest)561 public static HdmiCecMessage buildStandby(int src, int dest) { 562 return buildCommand(src, dest, Constants.MESSAGE_STANDBY); 563 } 564 565 /** 566 * Build <Vendor Command> command. 567 * 568 * @param src source address of command 569 * @param dest destination address of command 570 * @param params vendor-specific parameters 571 * @return newly created {@link HdmiCecMessage} 572 */ buildVendorCommand(int src, int dest, byte[] params)573 static HdmiCecMessage buildVendorCommand(int src, int dest, byte[] params) { 574 return buildCommand(src, dest, Constants.MESSAGE_VENDOR_COMMAND, params); 575 } 576 577 /** 578 * Build <Vendor Command With ID> command. 579 * 580 * @param src source address of command 581 * @param dest destination address of command 582 * @param vendorId vendor ID 583 * @param operands vendor-specific parameters 584 * @return newly created {@link HdmiCecMessage} 585 */ buildVendorCommandWithId(int src, int dest, int vendorId, byte[] operands)586 static HdmiCecMessage buildVendorCommandWithId(int src, int dest, int vendorId, 587 byte[] operands) { 588 byte[] params = new byte[operands.length + 3]; // parameter plus len(vendorId) 589 params[0] = (byte) ((vendorId >> 16) & 0xFF); 590 params[1] = (byte) ((vendorId >> 8) & 0xFF); 591 params[2] = (byte) (vendorId & 0xFF); 592 System.arraycopy(operands, 0, params, 3, operands.length); 593 return buildCommand(src, dest, Constants.MESSAGE_VENDOR_COMMAND_WITH_ID, params); 594 } 595 596 /** 597 * Build <Record On> command. 598 * 599 * @param src source address of command 600 * @param dest destination address of command 601 * @param params parameter of command 602 * @return newly created {@link HdmiCecMessage} 603 */ buildRecordOn(int src, int dest, byte[] params)604 static HdmiCecMessage buildRecordOn(int src, int dest, byte[] params) { 605 return buildCommand(src, dest, Constants.MESSAGE_RECORD_ON, params); 606 } 607 608 /** 609 * Build <Record Off> command. 610 * 611 * @param src source address of command 612 * @param dest destination address of command 613 * @return newly created {@link HdmiCecMessage} 614 */ buildRecordOff(int src, int dest)615 static HdmiCecMessage buildRecordOff(int src, int dest) { 616 return buildCommand(src, dest, Constants.MESSAGE_RECORD_OFF); 617 } 618 619 /** 620 * Build <Set Digital Timer> command. 621 * 622 * @param src source address of command 623 * @param dest destination address of command 624 * @param params byte array of timing information and digital service information to be recorded 625 * @return newly created {@link HdmiCecMessage} 626 */ buildSetDigitalTimer(int src, int dest, byte[] params)627 static HdmiCecMessage buildSetDigitalTimer(int src, int dest, byte[] params) { 628 return buildCommand(src, dest, Constants.MESSAGE_SET_DIGITAL_TIMER, params); 629 } 630 631 /** 632 * Build <Set Analogue Timer> command. 633 * 634 * @param src source address of command 635 * @param dest destination address of command 636 * @param params byte array of timing information and analog service information to be recorded 637 * @return newly created {@link HdmiCecMessage} 638 */ buildSetAnalogueTimer(int src, int dest, byte[] params)639 static HdmiCecMessage buildSetAnalogueTimer(int src, int dest, byte[] params) { 640 return buildCommand(src, dest, Constants.MESSAGE_SET_ANALOG_TIMER, params); 641 } 642 643 /** 644 * Build <Set External Timer> command. 645 * 646 * @param src source address of command 647 * @param dest destination address of command 648 * @param params byte array of timing information and external source information to be recorded 649 * @return newly created {@link HdmiCecMessage} 650 */ buildSetExternalTimer(int src, int dest, byte[] params)651 static HdmiCecMessage buildSetExternalTimer(int src, int dest, byte[] params) { 652 return buildCommand(src, dest, Constants.MESSAGE_SET_EXTERNAL_TIMER, params); 653 } 654 655 /** 656 * Build <Clear Digital Timer> command. 657 * 658 * @param src source address of command 659 * @param dest destination address of command 660 * @param params byte array of timing information and digital service information to be cleared 661 * @return newly created {@link HdmiCecMessage} 662 */ buildClearDigitalTimer(int src, int dest, byte[] params)663 static HdmiCecMessage buildClearDigitalTimer(int src, int dest, byte[] params) { 664 return buildCommand(src, dest, Constants.MESSAGE_CLEAR_DIGITAL_TIMER, params); 665 } 666 667 /** 668 * Build <Clear Analog Timer> command. 669 * 670 * @param src source address of command 671 * @param dest destination address of command 672 * @param params byte array of timing information and analog service information to be cleared 673 * @return newly created {@link HdmiCecMessage} 674 */ buildClearAnalogueTimer(int src, int dest, byte[] params)675 static HdmiCecMessage buildClearAnalogueTimer(int src, int dest, byte[] params) { 676 return buildCommand(src, dest, Constants.MESSAGE_CLEAR_ANALOG_TIMER, params); 677 } 678 679 /** 680 * Build <Clear Digital Timer> command. 681 * 682 * @param src source address of command 683 * @param dest destination address of command 684 * @param params byte array of timing information and external source information to be cleared 685 * @return newly created {@link HdmiCecMessage} 686 */ buildClearExternalTimer(int src, int dest, byte[] params)687 static HdmiCecMessage buildClearExternalTimer(int src, int dest, byte[] params) { 688 return buildCommand(src, dest, Constants.MESSAGE_CLEAR_EXTERNAL_TIMER, params); 689 } 690 691 /***** Please ADD new buildXXX() methods above. ******/ 692 693 /** 694 * Build a {@link HdmiCecMessage} without extra parameter. 695 * 696 * @param src source address of command 697 * @param dest destination address of command 698 * @param opcode opcode for a message 699 * @return newly created {@link HdmiCecMessage} 700 */ buildCommand(int src, int dest, int opcode)701 private static HdmiCecMessage buildCommand(int src, int dest, int opcode) { 702 return new HdmiCecMessage(src, dest, opcode, HdmiCecMessage.EMPTY_PARAM); 703 } 704 705 /** 706 * Build a {@link HdmiCecMessage} with given values. 707 * 708 * @param src source address of command 709 * @param dest destination address of command 710 * @param opcode opcode for a message 711 * @param params extra parameters for command 712 * @return newly created {@link HdmiCecMessage} 713 */ buildCommand(int src, int dest, int opcode, byte[] params)714 private static HdmiCecMessage buildCommand(int src, int dest, int opcode, byte[] params) { 715 return new HdmiCecMessage(src, dest, opcode, params); 716 } 717 718 /** 719 * Build a {@link HdmiCecMessage} with a boolean param and other given values. 720 * 721 * @param src source address of command 722 * @param des destination address of command 723 * @param opcode opcode for a message 724 * @param param boolean param for building the command 725 * @return newly created {@link HdmiCecMessage} 726 */ buildCommandWithBooleanParam(int src, int des, int opcode, boolean param)727 private static HdmiCecMessage buildCommandWithBooleanParam(int src, int des, 728 int opcode, boolean param) { 729 byte[] params = new byte[]{ 730 param ? (byte) 0b1 : 0b0 731 }; 732 return buildCommand(src, des, opcode, params); 733 } 734 physicalAddressToParam(int physicalAddress)735 private static byte[] physicalAddressToParam(int physicalAddress) { 736 return new byte[] { 737 (byte) ((physicalAddress >> 8) & 0xFF), 738 (byte) (physicalAddress & 0xFF) 739 }; 740 } 741 } 742