blob: 3f949bab8a2e436cc460be3400f4533854f26731 [file] [log] [blame]
Jungshik Janga1fa91f2014-05-08 20:56:41 +09001/*
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
Nick Chalko167529c2018-07-18 13:11:31 -070019import com.android.server.hdmi.Constants.AudioCodec;
20
Jungshik Janga1fa91f2014-05-08 20:56:41 +090021import java.io.UnsupportedEncodingException;
Jungshik Jang4085d0e2014-05-27 19:52:39 +090022import java.util.Arrays;
Jungshik Janga1fa91f2014-05-08 20:56:41 +090023
24/**
25 * A helper class to build {@link HdmiCecMessage} from various cec commands.
26 */
27public class HdmiCecMessageBuilder {
Jungshik Janga1fa91f2014-05-08 20:56:41 +090028 private static final int OSD_NAME_MAX_LENGTH = 13;
29
30 private HdmiCecMessageBuilder() {}
31
32 /**
Jungshik Jang4085d0e2014-05-27 19:52:39 +090033 * 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 */
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 /**
Jungshik Janga1fa91f2014-05-08 20:56:41 +090047 * 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 */
56 static HdmiCecMessage buildFeatureAbortCommand(int src, int dest, int originalOpcode,
57 int reason) {
58 byte[] params = new byte[] {
Jungshik Jang339227d2014-08-25 15:37:20 +090059 (byte) (originalOpcode & 0xFF),
60 (byte) (reason & 0xFF),
Jungshik Janga1fa91f2014-05-08 20:56:41 +090061 };
Jinsuk Kimc0c20d02014-07-04 14:34:31 +090062 return buildCommand(src, dest, Constants.MESSAGE_FEATURE_ABORT, params);
Jungshik Janga1fa91f2014-05-08 20:56:41 +090063 }
64
65 /**
Jungshik Jangcc5ef8c2014-05-27 13:27:36 +090066 * 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 */
72 static HdmiCecMessage buildGivePhysicalAddress(int src, int dest) {
Jinsuk Kimc0c20d02014-07-04 14:34:31 +090073 return buildCommand(src, dest, Constants.MESSAGE_GIVE_PHYSICAL_ADDRESS);
Jungshik Jangcc5ef8c2014-05-27 13:27:36 +090074 }
75
76 /**
Jungshik Jangbe9cd8e2014-05-15 14:29:01 +090077 * Build <Give Osd Name> command.
Jungshik Janga1fa91f2014-05-08 20:56:41 +090078 *
79 * @param src source address of command
80 * @param dest destination address of command
81 * @return newly created {@link HdmiCecMessage}
82 */
Jungshik Jangbe9cd8e2014-05-15 14:29:01 +090083 static HdmiCecMessage buildGiveOsdNameCommand(int src, int dest) {
Jinsuk Kimc0c20d02014-07-04 14:34:31 +090084 return buildCommand(src, dest, Constants.MESSAGE_GIVE_OSD_NAME);
Jungshik Janga1fa91f2014-05-08 20:56:41 +090085 }
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 */
94 static HdmiCecMessage buildGiveDeviceVendorIdCommand(int src, int dest) {
Jinsuk Kimc0c20d02014-07-04 14:34:31 +090095 return buildCommand(src, dest, Constants.MESSAGE_GIVE_DEVICE_VENDOR_ID);
Jungshik Janga1fa91f2014-05-08 20:56:41 +090096 }
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 */
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[] {
Jungshik Jang339227d2014-08-25 15:37:20 +0900115 (byte) (normalized.charAt(0) & 0xFF),
116 (byte) (normalized.charAt(1) & 0xFF),
117 (byte) (normalized.charAt(2) & 0xFF),
Jungshik Janga1fa91f2014-05-08 20:56:41 +0900118 };
119 // <Set Menu Language> is broadcast message.
Jinsuk Kimc0c20d02014-07-04 14:34:31 +0900120 return buildCommand(src, Constants.ADDR_BROADCAST,
121 Constants.MESSAGE_SET_MENU_LANGUAGE, params);
Jungshik Janga1fa91f2014-05-08 20:56:41 +0900122 }
123
124 /**
125 * Build &lt;Set Osd Name &gt; 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 */
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 }
Jinsuk Kimc0c20d02014-07-04 14:34:31 +0900140 return buildCommand(src, dest, Constants.MESSAGE_SET_OSD_NAME, params);
Jungshik Janga1fa91f2014-05-08 20:56:41 +0900141 }
142
143 /**
144 * Build &lt;Report Physical Address&gt; 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 */
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
Jungshik Jang339227d2014-08-25 15:37:20 +0900160 (byte) (deviceType & 0xFF)
Jungshik Janga1fa91f2014-05-08 20:56:41 +0900161 };
162 // <Report Physical Address> is broadcast message.
Jinsuk Kimc0c20d02014-07-04 14:34:31 +0900163 return buildCommand(src, Constants.ADDR_BROADCAST,
164 Constants.MESSAGE_REPORT_PHYSICAL_ADDRESS, params);
Jungshik Janga1fa91f2014-05-08 20:56:41 +0900165 }
166
167 /**
168 * Build &lt;Device Vendor Id&gt; 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 */
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.
Jinsuk Kimc0c20d02014-07-04 14:34:31 +0900184 return buildCommand(src, Constants.ADDR_BROADCAST,
185 Constants.MESSAGE_DEVICE_VENDOR_ID, params);
Jungshik Janga1fa91f2014-05-08 20:56:41 +0900186 }
187
188 /**
189 * Build &lt;Device Vendor Id&gt; 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 */
197 static HdmiCecMessage buildCecVersion(int src, int dest, int version) {
198 byte[] params = new byte[] {
Jungshik Jang339227d2014-08-25 15:37:20 +0900199 (byte) (version & 0xFF)
Jungshik Janga1fa91f2014-05-08 20:56:41 +0900200 };
Jinsuk Kimc0c20d02014-07-04 14:34:31 +0900201 return buildCommand(src, dest, Constants.MESSAGE_CEC_VERSION, params);
Jungshik Janga1fa91f2014-05-08 20:56:41 +0900202 }
203
204 /**
Jungshik Jang67ea5212014-05-15 14:05:24 +0900205 * Build &lt;Request Arc Initiation&gt;
206 *
207 * @param src source address of command
208 * @param dest destination address of command
209 * @return newly created {@link HdmiCecMessage}
210 */
211 static HdmiCecMessage buildRequestArcInitiation(int src, int dest) {
Jinsuk Kimc0c20d02014-07-04 14:34:31 +0900212 return buildCommand(src, dest, Constants.MESSAGE_REQUEST_ARC_INITIATION);
Jungshik Jang67ea5212014-05-15 14:05:24 +0900213 }
214
215 /**
Amy3c161d42018-06-04 11:42:08 -0700216 * Build &lt;Initiate Arc&gt;
217 *
218 * @param src source address of command
219 * @param dest destination address of command
220 * @return newly created {@link HdmiCecMessage}
221 */
222 static HdmiCecMessage buildInitiateArc(int src, int dest) {
223 return buildCommand(src, dest, Constants.MESSAGE_INITIATE_ARC);
224 }
225
226 /**
227 * Build &lt;Terminate Arc&gt;
228 *
229 * @param src source address of command
230 * @param dest destination address of command
231 * @return newly created {@link HdmiCecMessage}
232 */
233 static HdmiCecMessage buildTerminateArc(int src, int dest) {
234 return buildCommand(src, dest, Constants.MESSAGE_TERMINATE_ARC);
235 }
236
237 /**
Jungshik Jang67ea5212014-05-15 14:05:24 +0900238 * Build &lt;Request Arc Termination&gt;
239 *
240 * @param src source address of command
241 * @param dest destination address of command
242 * @return newly created {@link HdmiCecMessage}
243 */
244 static HdmiCecMessage buildRequestArcTermination(int src, int dest) {
Jinsuk Kimc0c20d02014-07-04 14:34:31 +0900245 return buildCommand(src, dest, Constants.MESSAGE_REQUEST_ARC_TERMINATION);
Jungshik Jang67ea5212014-05-15 14:05:24 +0900246 }
247
248 /**
249 * Build &lt;Report Arc Initiated&gt;
250 *
251 * @param src source address of command
252 * @param dest destination address of command
253 * @return newly created {@link HdmiCecMessage}
254 */
255 static HdmiCecMessage buildReportArcInitiated(int src, int dest) {
Jinsuk Kimc0c20d02014-07-04 14:34:31 +0900256 return buildCommand(src, dest, Constants.MESSAGE_REPORT_ARC_INITIATED);
Jungshik Jang67ea5212014-05-15 14:05:24 +0900257 }
258
259 /**
260 * Build &lt;Report Arc Terminated&gt;
261 *
262 * @param src source address of command
263 * @param dest destination address of command
264 * @return newly created {@link HdmiCecMessage}
265 */
266 static HdmiCecMessage buildReportArcTerminated(int src, int dest) {
Jinsuk Kimc0c20d02014-07-04 14:34:31 +0900267 return buildCommand(src, dest, Constants.MESSAGE_REPORT_ARC_TERMINATED);
Jungshik Jang67ea5212014-05-15 14:05:24 +0900268 }
269
Nick Chalkoc448a8e2018-07-26 13:59:33 -0700270
271 /**
272 * Build &lt;Request Short Audio Descriptor&gt; 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 */
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
Jungshik Jang67ea5212014-05-15 14:05:24 +0900289 /**
Jinsuk Kim78d695d2014-05-13 16:36:15 +0900290 * Build &lt;Text View On&gt; command.
291 *
292 * @param src source address of command
293 * @param dest destination address of command
294 * @return newly created {@link HdmiCecMessage}
295 */
296 static HdmiCecMessage buildTextViewOn(int src, int dest) {
Jinsuk Kimc0c20d02014-07-04 14:34:31 +0900297 return buildCommand(src, dest, Constants.MESSAGE_TEXT_VIEW_ON);
Jinsuk Kim78d695d2014-05-13 16:36:15 +0900298 }
299
300 /**
Shubang595a1832018-06-27 17:52:18 -0700301 * Build &lt;Request Active Source&gt; command.
302 *
303 * @param src source address of command
304 * @return newly created {@link HdmiCecMessage}
305 */
306 static HdmiCecMessage buildRequestActiveSource(int src) {
307 return buildCommand(src, Constants.ADDR_BROADCAST, Constants.MESSAGE_REQUEST_ACTIVE_SOURCE);
308 }
309
310 /**
Jinsuk Kim78d695d2014-05-13 16:36:15 +0900311 * Build &lt;Active Source&gt; 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 */
317 static HdmiCecMessage buildActiveSource(int src, int physicalAddress) {
Jinsuk Kimc0c20d02014-07-04 14:34:31 +0900318 return buildCommand(src, Constants.ADDR_BROADCAST, Constants.MESSAGE_ACTIVE_SOURCE,
Jinsuk Kim78d695d2014-05-13 16:36:15 +0900319 physicalAddressToParam(physicalAddress));
320 }
321
322 /**
Yuncheol Heo38db6292014-07-01 14:15:14 +0900323 * Build &lt;Inactive Source&gt; 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 */
329 static HdmiCecMessage buildInactiveSource(int src, int physicalAddress) {
Jungshik Jang4fc1d102014-07-09 19:24:50 +0900330 return buildCommand(src, Constants.ADDR_TV,
Jinsuk Kimc0c20d02014-07-04 14:34:31 +0900331 Constants.MESSAGE_INACTIVE_SOURCE, physicalAddressToParam(physicalAddress));
Yuncheol Heo38db6292014-07-01 14:15:14 +0900332 }
333
334 /**
Jinsuk Kima6ce7702014-05-11 06:54:49 +0900335 * Build &lt;Set Stream Path&gt; 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 */
343 static HdmiCecMessage buildSetStreamPath(int src, int streamPath) {
Jinsuk Kimc0c20d02014-07-04 14:34:31 +0900344 return buildCommand(src, Constants.ADDR_BROADCAST,
345 Constants.MESSAGE_SET_STREAM_PATH, physicalAddressToParam(streamPath));
Jinsuk Kima6ce7702014-05-11 06:54:49 +0900346 }
347
348 /**
349 * Build &lt;Routing Change&gt; 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 */
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 };
Jinsuk Kimc0c20d02014-07-04 14:34:31 +0900363 return buildCommand(src, Constants.ADDR_BROADCAST, Constants.MESSAGE_ROUTING_CHANGE,
364 param);
Jinsuk Kima6ce7702014-05-11 06:54:49 +0900365 }
366
367 /**
Amyd76888a2018-08-31 11:31:38 -0700368 * Build &lt;Routing Information&gt; 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 */
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 /**
Jinsuk Kim78d695d2014-05-13 16:36:15 +0900382 * Build &lt;Give Device Power Status&gt; command.
383 *
384 * @param src source address of command
385 * @param dest destination address of command
386 * @return newly created {@link HdmiCecMessage}
387 */
388 static HdmiCecMessage buildGiveDevicePowerStatus(int src, int dest) {
Jinsuk Kimc0c20d02014-07-04 14:34:31 +0900389 return buildCommand(src, dest, Constants.MESSAGE_GIVE_DEVICE_POWER_STATUS);
Jinsuk Kim78d695d2014-05-13 16:36:15 +0900390 }
391
392 /**
Yuncheol Heo38db6292014-07-01 14:15:14 +0900393 * Build &lt;Report Power Status&gt; 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 */
400 static HdmiCecMessage buildReportPowerStatus(int src, int dest, int powerStatus) {
401 byte[] param = new byte[] {
Jungshik Jang339227d2014-08-25 15:37:20 +0900402 (byte) (powerStatus & 0xFF)
Yuncheol Heo38db6292014-07-01 14:15:14 +0900403 };
Jinsuk Kimc0c20d02014-07-04 14:34:31 +0900404 return buildCommand(src, dest, Constants.MESSAGE_REPORT_POWER_STATUS, param);
Yuncheol Heo38db6292014-07-01 14:15:14 +0900405 }
406
407 /**
Terry Heo3e1564e2014-08-12 14:41:00 +0900408 * Build &lt;Report Menu Status&gt; 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 */
415 static HdmiCecMessage buildReportMenuStatus(int src, int dest, int menuStatus) {
416 byte[] param = new byte[] {
Jungshik Jang339227d2014-08-25 15:37:20 +0900417 (byte) (menuStatus & 0xFF)
Terry Heo3e1564e2014-08-12 14:41:00 +0900418 };
419 return buildCommand(src, dest, Constants.MESSAGE_MENU_STATUS, param);
420 }
421
422 /**
Yuncheol Heo63a2e062014-05-27 23:06:01 +0900423 * Build &lt;System Audio Mode Request&gt; 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 */
431 static HdmiCecMessage buildSystemAudioModeRequest(int src, int avr, int avrPhysicalAddress,
432 boolean enableSystemAudio) {
433 if (enableSystemAudio) {
Jinsuk Kimc0c20d02014-07-04 14:34:31 +0900434 return buildCommand(src, avr, Constants.MESSAGE_SYSTEM_AUDIO_MODE_REQUEST,
Yuncheol Heo63a2e062014-05-27 23:06:01 +0900435 physicalAddressToParam(avrPhysicalAddress));
436 } else {
Jinsuk Kimc0c20d02014-07-04 14:34:31 +0900437 return buildCommand(src, avr, Constants.MESSAGE_SYSTEM_AUDIO_MODE_REQUEST);
Yuncheol Heo63a2e062014-05-27 23:06:01 +0900438 }
439 }
440
441 /**
Amy3c161d42018-06-04 11:42:08 -0700442 * Build &lt;Set System Audio Mode&gt; 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 */
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 &lt;Report System Audio Mode&gt; 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 */
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 /**
Nick Chalko167529c2018-07-18 13:11:31 -0700470 * Build &lt;Report Short Audio Descriptor&gt; 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 */
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 /**
Yuncheol Heo63a2e062014-05-27 23:06:01 +0900483 * Build &lt;Give Audio Status&gt; command.
484 *
485 * @param src source address of command
486 * @param dest destination address of command
487 * @return newly created {@link HdmiCecMessage}
488 */
489 static HdmiCecMessage buildGiveAudioStatus(int src, int dest) {
Jinsuk Kimc0c20d02014-07-04 14:34:31 +0900490 return buildCommand(src, dest, Constants.MESSAGE_GIVE_AUDIO_STATUS);
Yuncheol Heo63a2e062014-05-27 23:06:01 +0900491 }
492
493 /**
Amy3c161d42018-06-04 11:42:08 -0700494 * Build &lt;Report Audio Status&gt; 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 */
502 static HdmiCecMessage buildReportAudioStatus(int src, int dest, int volume, boolean mute) {
Shubangf0f23e42018-06-07 18:30:07 -0700503 byte status = (byte) ((byte) (mute ? 1 << 7 : 0) | ((byte) volume & 0x7F));
504 byte[] params = new byte[] { status };
Amy3c161d42018-06-04 11:42:08 -0700505 return buildCommand(src, dest, Constants.MESSAGE_REPORT_AUDIO_STATUS, params);
506 }
507
508 /**
Yuncheol Heo63a2e062014-05-27 23:06:01 +0900509 * Build &lt;User Control Pressed&gt; 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 */
516 static HdmiCecMessage buildUserControlPressed(int src, int dest, int uiCommand) {
Jungshik Jang339227d2014-08-25 15:37:20 +0900517 return buildUserControlPressed(src, dest, new byte[] { (byte) (uiCommand & 0xFF) });
Jinsuk Kimcd97baf2014-05-02 16:27:32 +0900518 }
519
520 /**
521 * Build &lt;User Control Pressed&gt; 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 */
528 static HdmiCecMessage buildUserControlPressed(int src, int dest, byte[] commandParam) {
Jinsuk Kimc0c20d02014-07-04 14:34:31 +0900529 return buildCommand(src, dest, Constants.MESSAGE_USER_CONTROL_PRESSED, commandParam);
Yuncheol Heo63a2e062014-05-27 23:06:01 +0900530 }
531
532 /**
533 * Build &lt;User Control Released&gt; command.
534 *
535 * @param src source address of command
536 * @param dest destination address of command
537 * @return newly created {@link HdmiCecMessage}
538 */
539 static HdmiCecMessage buildUserControlReleased(int src, int dest) {
Jinsuk Kimc0c20d02014-07-04 14:34:31 +0900540 return buildCommand(src, dest, Constants.MESSAGE_USER_CONTROL_RELEASED);
Yuncheol Heo63a2e062014-05-27 23:06:01 +0900541 }
542
Jungshik Jang187d0172014-06-17 17:48:42 +0900543 /**
544 * Build &lt;Give System Audio Mode Status&gt; command.
545 *
546 * @param src source address of command
547 * @param dest destination address of command
548 * @return newly created {@link HdmiCecMessage}
549 */
550 static HdmiCecMessage buildGiveSystemAudioModeStatus(int src, int dest) {
Jinsuk Kimc0c20d02014-07-04 14:34:31 +0900551 return buildCommand(src, dest, Constants.MESSAGE_GIVE_SYSTEM_AUDIO_MODE_STATUS);
Jungshik Jang187d0172014-06-17 17:48:42 +0900552 }
553
Yuncheol Heo38db6292014-07-01 14:15:14 +0900554 /**
555 * Build &lt;Standby&gt; command.
556 *
557 * @param src source address of command
558 * @param dest destination address of command
559 * @return newly created {@link HdmiCecMessage}
560 */
561 public static HdmiCecMessage buildStandby(int src, int dest) {
Jinsuk Kimc0c20d02014-07-04 14:34:31 +0900562 return buildCommand(src, dest, Constants.MESSAGE_STANDBY);
Yuncheol Heo38db6292014-07-01 14:15:14 +0900563 }
564
Jinsuk Kim119160a2014-07-07 18:48:10 +0900565 /**
566 * Build &lt;Vendor Command&gt; 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 */
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 &lt;Vendor Command With ID&gt; 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 */
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
Jungshik Jangb6591b82014-07-23 16:10:23 +0900596 /**
597 * Build &lt;Record On&gt; 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 */
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 &lt;Record Off&gt; command.
610 *
611 * @param src source address of command
612 * @param dest destination address of command
613 * @return newly created {@link HdmiCecMessage}
614 */
615 static HdmiCecMessage buildRecordOff(int src, int dest) {
616 return buildCommand(src, dest, Constants.MESSAGE_RECORD_OFF);
617 }
618
Jungshik Jang12e5dce2014-07-24 15:27:44 +0900619 /**
620 * Build &lt;Set Digital Timer&gt; 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 */
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 &lt;Set Analogue Timer&gt; 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 */
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 &lt;Set External Timer&gt; 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 */
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 &lt;Clear Digital Timer&gt; 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 */
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 &lt;Clear Analog Timer&gt; 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 */
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 &lt;Clear Digital Timer&gt; 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 */
687 static HdmiCecMessage buildClearExternalTimer(int src, int dest, byte[] params) {
688 return buildCommand(src, dest, Constants.MESSAGE_CLEAR_EXTERNAL_TIMER, params);
689 }
690
Yuncheol Heo63a2e062014-05-27 23:06:01 +0900691 /***** Please ADD new buildXXX() methods above. ******/
692
693 /**
Jungshik Janga1fa91f2014-05-08 20:56:41 +0900694 * 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 */
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 */
714 private static HdmiCecMessage buildCommand(int src, int dest, int opcode, byte[] params) {
715 return new HdmiCecMessage(src, dest, opcode, params);
716 }
Jinsuk Kim78d695d2014-05-13 16:36:15 +0900717
Amy3c161d42018-06-04 11:42:08 -0700718 /**
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 */
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
Jinsuk Kim78d695d2014-05-13 16:36:15 +0900735 private static byte[] physicalAddressToParam(int physicalAddress) {
736 return new byte[] {
Jungshik Jang339227d2014-08-25 15:37:20 +0900737 (byte) ((physicalAddress >> 8) & 0xFF),
Jinsuk Kim78d695d2014-05-13 16:36:15 +0900738 (byte) (physicalAddress & 0xFF)
739 };
740 }
Jungshik Janga1fa91f2014-05-08 20:56:41 +0900741}