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