blob: ad89312e8c3fec91909845a088eeebcac387bec9 [file] [log] [blame]
Shraddha Basantwanif3a43c82021-05-27 19:40:17 +05301/*
2 * Copyright (C) 2021 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#define LOG_TAG "android.hardware.tv.cec@1.0-impl"
18#include <android-base/logging.h>
Shraddha Basantwanidedd40e2021-09-16 15:56:20 +053019#include <android-base/properties.h>
Shraddha Basantwanif3a43c82021-05-27 19:40:17 +053020
Shraddha Basantwani33254102021-06-01 13:29:47 +053021#include <cutils/properties.h>
Shraddha Basantwanif3a43c82021-05-27 19:40:17 +053022#include <errno.h>
23#include <fcntl.h>
Shraddha Basantwanif3a43c82021-05-27 19:40:17 +053024#include <linux/ioctl.h>
Shraddha Basantwani0c8a0542021-06-04 15:10:06 +053025#include <poll.h>
Shraddha Basantwanif3a43c82021-05-27 19:40:17 +053026#include <sys/eventfd.h>
Shraddha Basantwani0c8a0542021-06-04 15:10:06 +053027#include <algorithm>
Shraddha Basantwanif3a43c82021-05-27 19:40:17 +053028
29#include "HdmiCecDefault.h"
30
31namespace android {
32namespace hardware {
33namespace tv {
34namespace cec {
35namespace V1_0 {
36namespace implementation {
37
Shraddha Basantwanidedd40e2021-09-16 15:56:20 +053038using android::base::GetUintProperty;
Shraddha Basantwanif3a43c82021-05-27 19:40:17 +053039
40HdmiCecDefault::HdmiCecDefault() {
41 mCecFd = -1;
42 mExitFd = -1;
Shraddha Basantwanid591d972021-06-15 19:40:16 +053043 mCecEnabled = false;
Shraddha Basantwani05c454f2021-06-18 12:42:27 +053044 mWakeupEnabled = false;
Shraddha Basantwani9fb5e822021-06-23 20:42:08 +053045 mCecControlEnabled = false;
Shraddha Basantwani92fa8e92021-06-02 12:11:26 +053046 mCallback = nullptr;
Shraddha Basantwanif3a43c82021-05-27 19:40:17 +053047}
48
49HdmiCecDefault::~HdmiCecDefault() {
50 release();
51}
52
53// Methods from ::android::hardware::tv::cec::V1_0::IHdmiCec follow.
Shraddha Basantwanid50fd042021-06-02 09:35:53 +053054Return<Result> HdmiCecDefault::addLogicalAddress(CecLogicalAddress addr) {
55 if (addr < CecLogicalAddress::TV || addr >= CecLogicalAddress::BROADCAST) {
56 LOG(ERROR) << "Add logical address failed, Invalid address";
57 return Result::FAILURE_INVALID_ARGS;
58 }
59
Shraddha Basantwanidedd40e2021-09-16 15:56:20 +053060 cec_log_addrs cecLogAddrs;
Shraddha Basantwanid50fd042021-06-02 09:35:53 +053061 int ret = ioctl(mCecFd, CEC_ADAP_G_LOG_ADDRS, &cecLogAddrs);
62 if (ret) {
63 LOG(ERROR) << "Add logical address failed, Error = " << strerror(errno);
64 return Result::FAILURE_BUSY;
65 }
66
67 cecLogAddrs.cec_version = getCecVersion();
68 cecLogAddrs.vendor_id = getVendorId();
69
70 unsigned int logAddrType = CEC_LOG_ADDR_TYPE_UNREGISTERED;
71 unsigned int allDevTypes = 0;
72 unsigned int primDevType = 0xff;
73 switch (addr) {
74 case CecLogicalAddress::TV:
75 primDevType = CEC_OP_PRIM_DEVTYPE_TV;
76 logAddrType = CEC_LOG_ADDR_TYPE_TV;
77 allDevTypes = CEC_OP_ALL_DEVTYPE_TV;
78 break;
79 case CecLogicalAddress::RECORDER_1:
80 case CecLogicalAddress::RECORDER_2:
81 case CecLogicalAddress::RECORDER_3:
82 primDevType = CEC_OP_PRIM_DEVTYPE_RECORD;
83 logAddrType = CEC_LOG_ADDR_TYPE_RECORD;
84 allDevTypes = CEC_OP_ALL_DEVTYPE_RECORD;
85 break;
86 case CecLogicalAddress::TUNER_1:
87 case CecLogicalAddress::TUNER_2:
88 case CecLogicalAddress::TUNER_3:
89 case CecLogicalAddress::TUNER_4:
90 primDevType = CEC_OP_PRIM_DEVTYPE_TUNER;
91 logAddrType = CEC_LOG_ADDR_TYPE_TUNER;
92 allDevTypes = CEC_OP_ALL_DEVTYPE_TUNER;
93 break;
94 case CecLogicalAddress::PLAYBACK_1:
95 case CecLogicalAddress::PLAYBACK_2:
96 case CecLogicalAddress::PLAYBACK_3:
97 primDevType = CEC_OP_PRIM_DEVTYPE_PLAYBACK;
98 logAddrType = CEC_LOG_ADDR_TYPE_PLAYBACK;
99 allDevTypes = CEC_OP_ALL_DEVTYPE_PLAYBACK;
100 cecLogAddrs.flags |= CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU;
101 break;
102 case CecLogicalAddress::AUDIO_SYSTEM:
103 primDevType = CEC_OP_PRIM_DEVTYPE_AUDIOSYSTEM;
104 logAddrType = CEC_LOG_ADDR_TYPE_AUDIOSYSTEM;
105 allDevTypes = CEC_OP_ALL_DEVTYPE_AUDIOSYSTEM;
106 break;
107 case CecLogicalAddress::FREE_USE:
108 primDevType = CEC_OP_PRIM_DEVTYPE_PROCESSOR;
109 logAddrType = CEC_LOG_ADDR_TYPE_SPECIFIC;
110 allDevTypes = CEC_OP_ALL_DEVTYPE_SWITCH;
111 break;
112 case CecLogicalAddress::UNREGISTERED:
113 cecLogAddrs.flags |= CEC_LOG_ADDRS_FL_ALLOW_UNREG_FALLBACK;
114 break;
115 }
116
117 int logAddrIndex = cecLogAddrs.num_log_addrs;
118
119 cecLogAddrs.num_log_addrs += 1;
120 cecLogAddrs.log_addr[logAddrIndex] = static_cast<cec_logical_address_t>(addr);
121 cecLogAddrs.log_addr_type[logAddrIndex] = logAddrType;
122 cecLogAddrs.primary_device_type[logAddrIndex] = primDevType;
123 cecLogAddrs.all_device_types[logAddrIndex] = allDevTypes;
124 cecLogAddrs.features[logAddrIndex][0] = 0;
125 cecLogAddrs.features[logAddrIndex][1] = 0;
126
127 ret = ioctl(mCecFd, CEC_ADAP_S_LOG_ADDRS, &cecLogAddrs);
128 if (ret) {
129 LOG(ERROR) << "Add logical address failed, Error = " << strerror(errno);
130 return Result::FAILURE_BUSY;
131 }
132 return Result::SUCCESS;
Shraddha Basantwanif3a43c82021-05-27 19:40:17 +0530133}
134
135Return<void> HdmiCecDefault::clearLogicalAddress() {
Shraddha Basantwanidedd40e2021-09-16 15:56:20 +0530136 cec_log_addrs cecLogAddrs;
Shraddha Basantwani0dacc5c2021-06-01 10:32:22 +0530137 memset(&cecLogAddrs, 0, sizeof(cecLogAddrs));
138 int ret = ioctl(mCecFd, CEC_ADAP_S_LOG_ADDRS, &cecLogAddrs);
139 if (ret) {
140 LOG(ERROR) << "Clear logical Address failed, Error = " << strerror(errno);
141 }
Shraddha Basantwanif3a43c82021-05-27 19:40:17 +0530142 return Void();
143}
144
Shraddha Basantwani9b1e5292021-05-31 16:38:38 +0530145Return<void> HdmiCecDefault::getPhysicalAddress(getPhysicalAddress_cb callback) {
146 uint16_t addr;
147 int ret = ioctl(mCecFd, CEC_ADAP_G_PHYS_ADDR, &addr);
148 if (ret) {
149 LOG(ERROR) << "Get physical address failed, Error = " << strerror(errno);
150 callback(Result::FAILURE_INVALID_STATE, addr);
151 return Void();
152 }
153 callback(Result::SUCCESS, addr);
Shraddha Basantwanif3a43c82021-05-27 19:40:17 +0530154 return Void();
155}
156
Shraddha Basantwani971853b2021-05-31 16:28:23 +0530157Return<SendMessageResult> HdmiCecDefault::sendMessage(const CecMessage& message) {
Shraddha Basantwanid591d972021-06-15 19:40:16 +0530158 if (!mCecEnabled) {
159 return SendMessageResult::FAIL;
160 }
161
Shraddha Basantwanidedd40e2021-09-16 15:56:20 +0530162 cec_msg cecMsg;
Shraddha Basantwani971853b2021-05-31 16:28:23 +0530163 memset(&cecMsg, 0, sizeof(cec_msg));
164
165 int initiator = static_cast<cec_logical_address_t>(message.initiator);
166 int destination = static_cast<cec_logical_address_t>(message.destination);
167
168 cecMsg.msg[0] = (initiator << 4) | destination;
169 for (size_t i = 0; i < message.body.size(); ++i) {
170 cecMsg.msg[i + 1] = message.body[i];
171 }
172 cecMsg.len = message.body.size() + 1;
173
174 int ret = ioctl(mCecFd, CEC_TRANSMIT, &cecMsg);
175
176 if (ret) {
177 LOG(ERROR) << "Send message failed, Error = " << strerror(errno);
178 return SendMessageResult::FAIL;
179 }
180
181 if (cecMsg.tx_status != CEC_TX_STATUS_OK) {
182 LOG(ERROR) << "Send message tx_status = " << cecMsg.tx_status;
183 }
184
185 switch (cecMsg.tx_status) {
186 case CEC_TX_STATUS_OK:
187 return SendMessageResult::SUCCESS;
188 case CEC_TX_STATUS_ARB_LOST:
189 return SendMessageResult::BUSY;
190 case CEC_TX_STATUS_NACK:
191 return SendMessageResult::NACK;
192 default:
193 return SendMessageResult::FAIL;
194 }
Shraddha Basantwanif3a43c82021-05-27 19:40:17 +0530195}
196
Shraddha Basantwani92fa8e92021-06-02 12:11:26 +0530197Return<void> HdmiCecDefault::setCallback(const sp<IHdmiCecCallback>& callback) {
198 if (mCallback != nullptr) {
199 mCallback->unlinkToDeath(this);
200 mCallback = nullptr;
201 }
202
203 if (callback != nullptr) {
204 mCallback = callback;
205 mCallback->linkToDeath(this, 0 /*cookie*/);
206 }
Shraddha Basantwanif3a43c82021-05-27 19:40:17 +0530207 return Void();
208}
209
210Return<int32_t> HdmiCecDefault::getCecVersion() {
Shraddha Basantwani105b1c32021-06-01 18:45:21 +0530211 return property_get_int32("ro.hdmi.cec_version", CEC_OP_CEC_VERSION_1_4);
Shraddha Basantwanif3a43c82021-05-27 19:40:17 +0530212}
213
214Return<uint32_t> HdmiCecDefault::getVendorId() {
Shraddha Basantwani697e2802021-06-01 16:20:10 +0530215 return property_get_int32("ro.hdmi.vendor_id", 0x000c03 /* HDMI LLC vendor ID */);
Shraddha Basantwanif3a43c82021-05-27 19:40:17 +0530216}
217
Shraddha Basantwani33254102021-06-01 13:29:47 +0530218Return<void> HdmiCecDefault::getPortInfo(getPortInfo_cb callback) {
219 uint16_t addr;
220 int ret = ioctl(mCecFd, CEC_ADAP_G_PHYS_ADDR, &addr);
221 if (ret) {
222 LOG(ERROR) << "Get port info failed, Error = " << strerror(errno);
223 }
224
Shraddha Basantwanidedd40e2021-09-16 15:56:20 +0530225 uint32_t type = GetUintProperty<uint32_t>("ro.hdmi.device_type", CEC_DEVICE_PLAYBACK);
Shraddha Basantwani33254102021-06-01 13:29:47 +0530226 hidl_vec<HdmiPortInfo> portInfos(1);
227 portInfos[0] = {.type = (type == CEC_DEVICE_TV ? HdmiPortType::INPUT : HdmiPortType::OUTPUT),
228 .portId = 1,
229 .cecSupported = true,
230 .arcSupported = false,
231 .physicalAddress = addr};
232 callback(portInfos);
Shraddha Basantwanif3a43c82021-05-27 19:40:17 +0530233 return Void();
234}
235
Shraddha Basantwanid591d972021-06-15 19:40:16 +0530236Return<void> HdmiCecDefault::setOption(OptionKey key, bool value) {
237 switch (key) {
238 case OptionKey::ENABLE_CEC:
239 LOG(DEBUG) << "setOption: Enable CEC: " << value;
240 mCecEnabled = value;
241 break;
Shraddha Basantwani05c454f2021-06-18 12:42:27 +0530242 case OptionKey::WAKEUP:
243 LOG(DEBUG) << "setOption: WAKEUP: " << value;
244 mWakeupEnabled = value;
245 break;
Shraddha Basantwani9fb5e822021-06-23 20:42:08 +0530246 case OptionKey::SYSTEM_CEC_CONTROL:
247 LOG(DEBUG) << "setOption: SYSTEM_CEC_CONTROL: " << value;
248 mCecControlEnabled = value;
Shraddha Basantwanid591d972021-06-15 19:40:16 +0530249 break;
250 }
Shraddha Basantwanif3a43c82021-05-27 19:40:17 +0530251 return Void();
252}
253
254Return<void> HdmiCecDefault::setLanguage(const hidl_string& /*language*/) {
255 return Void();
256}
257
258Return<void> HdmiCecDefault::enableAudioReturnChannel(int32_t /*portId*/, bool /*enable*/) {
259 return Void();
260}
261
262Return<bool> HdmiCecDefault::isConnected(int32_t /*portId*/) {
Shraddha Basantwani21207902021-06-01 16:35:07 +0530263 uint16_t addr;
264 int ret = ioctl(mCecFd, CEC_ADAP_G_PHYS_ADDR, &addr);
265 if (ret) {
266 LOG(ERROR) << "Is connected failed, Error = " << strerror(errno);
267 return false;
268 }
269 if (addr == CEC_PHYS_ADDR_INVALID) {
270 return false;
271 }
272 return true;
Shraddha Basantwanif3a43c82021-05-27 19:40:17 +0530273}
274
275// Initialise the cec file descriptor
276Return<Result> HdmiCecDefault::init() {
277 const char* path = "/dev/cec0";
278 mCecFd = open(path, O_RDWR);
279 if (mCecFd < 0) {
280 LOG(ERROR) << "Failed to open " << path << ", Error = " << strerror(errno);
281 return Result::FAILURE_NOT_SUPPORTED;
282 }
283 mExitFd = eventfd(0, EFD_NONBLOCK);
284 if (mExitFd < 0) {
285 LOG(ERROR) << "Failed to open eventfd, Error = " << strerror(errno);
286 release();
287 return Result::FAILURE_NOT_SUPPORTED;
288 }
289
290 // Ensure the CEC device supports required capabilities
Shraddha Basantwanidedd40e2021-09-16 15:56:20 +0530291 cec_caps caps = {};
Shraddha Basantwanif3a43c82021-05-27 19:40:17 +0530292 int ret = ioctl(mCecFd, CEC_ADAP_G_CAPS, &caps);
293 if (ret) {
294 LOG(ERROR) << "Unable to query cec adapter capabilities, Error = " << strerror(errno);
295 release();
296 return Result::FAILURE_NOT_SUPPORTED;
297 }
298
299 if (!(caps.capabilities & (CEC_CAP_LOG_ADDRS | CEC_CAP_TRANSMIT | CEC_CAP_PASSTHROUGH))) {
300 LOG(ERROR) << "Wrong cec adapter capabilities " << caps.capabilities;
301 release();
302 return Result::FAILURE_NOT_SUPPORTED;
303 }
304
Shraddha Basantwani0c8a0542021-06-04 15:10:06 +0530305 uint32_t mode = CEC_MODE_INITIATOR | CEC_MODE_EXCL_FOLLOWER_PASSTHRU;
Shraddha Basantwanif3a43c82021-05-27 19:40:17 +0530306 ret = ioctl(mCecFd, CEC_S_MODE, &mode);
307 if (ret) {
308 LOG(ERROR) << "Unable to set initiator mode, Error = " << strerror(errno);
309 release();
310 return Result::FAILURE_NOT_SUPPORTED;
311 }
312
Shraddha Basantwanidedd40e2021-09-16 15:56:20 +0530313 mEventThread = thread(&HdmiCecDefault::event_thread, this);
Shraddha Basantwani0c8a0542021-06-04 15:10:06 +0530314
Shraddha Basantwanid591d972021-06-15 19:40:16 +0530315 mCecEnabled = true;
Shraddha Basantwani05c454f2021-06-18 12:42:27 +0530316 mWakeupEnabled = true;
Shraddha Basantwani9fb5e822021-06-23 20:42:08 +0530317 mCecControlEnabled = true;
Shraddha Basantwanif3a43c82021-05-27 19:40:17 +0530318 return Result::SUCCESS;
319}
320
321Return<void> HdmiCecDefault::release() {
322 if (mExitFd > 0) {
323 uint64_t tmp = 1;
324 write(mExitFd, &tmp, sizeof(tmp));
Shraddha Basantwanidedd40e2021-09-16 15:56:20 +0530325 if (mEventThread.joinable()) {
326 mEventThread.join();
327 }
Shraddha Basantwanif3a43c82021-05-27 19:40:17 +0530328 }
329 if (mExitFd > 0) {
330 close(mExitFd);
331 }
332 if (mCecFd > 0) {
333 close(mCecFd);
334 }
Shraddha Basantwanid591d972021-06-15 19:40:16 +0530335 mCecEnabled = false;
Shraddha Basantwani05c454f2021-06-18 12:42:27 +0530336 mWakeupEnabled = false;
Shraddha Basantwani9fb5e822021-06-23 20:42:08 +0530337 mCecControlEnabled = false;
Shraddha Basantwanif3a43c82021-05-27 19:40:17 +0530338 setCallback(nullptr);
339 return Void();
340}
Shraddha Basantwani0c8a0542021-06-04 15:10:06 +0530341
Shraddha Basantwanidedd40e2021-09-16 15:56:20 +0530342void HdmiCecDefault::event_thread() {
343 pollfd ufds[3] = {
Shraddha Basantwani0c8a0542021-06-04 15:10:06 +0530344 {mCecFd, POLLIN, 0},
345 {mCecFd, POLLERR, 0},
346 {mExitFd, POLLIN, 0},
347 };
348
349 while (1) {
350 ufds[0].revents = 0;
351 ufds[1].revents = 0;
352 ufds[2].revents = 0;
353
354 int ret = poll(ufds, /* size(ufds) = */ 3, /* timeout = */ -1);
355
356 if (ret <= 0) {
357 continue;
358 }
359
360 if (ufds[2].revents == POLLIN) { /* Exit */
361 break;
362 }
363
364 if (ufds[1].revents == POLLERR) { /* CEC Event */
Shraddha Basantwanidedd40e2021-09-16 15:56:20 +0530365 cec_event ev;
Shraddha Basantwani0c8a0542021-06-04 15:10:06 +0530366 ret = ioctl(mCecFd, CEC_DQEVENT, &ev);
367
368 if (ret) {
369 LOG(ERROR) << "CEC_DQEVENT failed, Error = " << strerror(errno);
370 continue;
371 }
372
Shraddha Basantwanidedd40e2021-09-16 15:56:20 +0530373 if (!mCecEnabled) {
374 continue;
375 }
376
Shraddha Basantwani0c8a0542021-06-04 15:10:06 +0530377 if (ev.event == CEC_EVENT_STATE_CHANGE) {
378 if (mCallback != nullptr) {
379 HotplugEvent hotplugEvent{
380 .connected = (ev.state_change.phys_addr != CEC_PHYS_ADDR_INVALID),
381 .portId = 1};
382 mCallback->onHotplugEvent(hotplugEvent);
383 } else {
384 LOG(ERROR) << "No event callback for hotplug";
385 }
386 }
387 }
388
389 if (ufds[0].revents == POLLIN) { /* CEC Driver */
Shraddha Basantwanidedd40e2021-09-16 15:56:20 +0530390 cec_msg msg = {};
Shraddha Basantwani0c8a0542021-06-04 15:10:06 +0530391 ret = ioctl(mCecFd, CEC_RECEIVE, &msg);
392
393 if (ret) {
394 LOG(ERROR) << "CEC_RECEIVE failed, Error = " << strerror(errno);
395 continue;
396 }
397
398 if (msg.rx_status != CEC_RX_STATUS_OK) {
399 LOG(ERROR) << "msg rx_status = " << msg.rx_status;
400 continue;
401 }
402
Shraddha Basantwanidedd40e2021-09-16 15:56:20 +0530403 if (!mCecEnabled) {
404 continue;
405 }
406
Shraddha Basantwani05c454f2021-06-18 12:42:27 +0530407 if (!mWakeupEnabled && isWakeupMessage(msg)) {
408 LOG(DEBUG) << "Filter wakeup message";
409 continue;
410 }
411
Shraddha Basantwani9fb5e822021-06-23 20:42:08 +0530412 if (!mCecControlEnabled && !isTransferableInSleep(msg)) {
413 LOG(DEBUG) << "Filter message in standby mode";
414 continue;
415 }
416
Shraddha Basantwani0c8a0542021-06-04 15:10:06 +0530417 if (mCallback != nullptr) {
418 size_t length = std::min(msg.len - 1, (uint32_t)MaxLength::MESSAGE_BODY);
419 CecMessage cecMessage{
420 .initiator = static_cast<CecLogicalAddress>(msg.msg[0] >> 4),
421 .destination = static_cast<CecLogicalAddress>(msg.msg[0] & 0xf),
422 };
423 cecMessage.body.resize(length);
424 for (size_t i = 0; i < length; ++i) {
425 cecMessage.body[i] = static_cast<uint8_t>(msg.msg[i + 1]);
426 }
427 mCallback->onCecMessage(cecMessage);
428 } else {
429 LOG(ERROR) << "no event callback for message";
430 }
431 }
432 }
Shraddha Basantwani0c8a0542021-06-04 15:10:06 +0530433}
434
Shraddha Basantwanidedd40e2021-09-16 15:56:20 +0530435int HdmiCecDefault::getOpcode(cec_msg message) {
436 return static_cast<uint8_t>(message.msg[1]);
Shraddha Basantwani05c454f2021-06-18 12:42:27 +0530437}
438
Shraddha Basantwanidedd40e2021-09-16 15:56:20 +0530439bool HdmiCecDefault::isWakeupMessage(cec_msg message) {
Shraddha Basantwani05c454f2021-06-18 12:42:27 +0530440 int opcode = getOpcode(message);
441 switch (opcode) {
442 case CEC_MESSAGE_TEXT_VIEW_ON:
443 case CEC_MESSAGE_IMAGE_VIEW_ON:
444 return true;
445 default:
446 return false;
447 }
448}
449
Shraddha Basantwani9fb5e822021-06-23 20:42:08 +0530450bool HdmiCecDefault::isTransferableInSleep(cec_msg message) {
451 int opcode = getOpcode(message);
452 switch (opcode) {
453 case CEC_MESSAGE_ABORT:
454 case CEC_MESSAGE_DEVICE_VENDOR_ID:
455 case CEC_MESSAGE_GET_CEC_VERSION:
456 case CEC_MESSAGE_GET_MENU_LANGUAGE:
457 case CEC_MESSAGE_GIVE_DEVICE_POWER_STATUS:
458 case CEC_MESSAGE_GIVE_DEVICE_VENDOR_ID:
459 case CEC_MESSAGE_GIVE_OSD_NAME:
460 case CEC_MESSAGE_GIVE_PHYSICAL_ADDRESS:
461 case CEC_MESSAGE_REPORT_PHYSICAL_ADDRESS:
462 case CEC_MESSAGE_REPORT_POWER_STATUS:
463 case CEC_MESSAGE_SET_OSD_NAME:
464 case CEC_MESSAGE_DECK_CONTROL:
465 case CEC_MESSAGE_PLAY:
466 case CEC_MESSAGE_IMAGE_VIEW_ON:
467 case CEC_MESSAGE_TEXT_VIEW_ON:
468 case CEC_MESSAGE_SYSTEM_AUDIO_MODE_REQUEST:
469 return true;
470 case CEC_MESSAGE_USER_CONTROL_PRESSED:
471 return isPowerUICommand(message);
472 default:
473 return false;
474 }
475}
476
477int HdmiCecDefault::getFirstParam(cec_msg message) {
478 return static_cast<uint8_t>(message.msg[2]);
479}
480
481bool HdmiCecDefault::isPowerUICommand(cec_msg message) {
482 int uiCommand = getFirstParam(message);
483 switch (uiCommand) {
484 case CEC_OP_UI_CMD_POWER:
485 case CEC_OP_UI_CMD_DEVICE_ROOT_MENU:
486 case CEC_OP_UI_CMD_POWER_ON_FUNCTION:
487 return true;
488 default:
489 return false;
490 }
491}
Shraddha Basantwanif3a43c82021-05-27 19:40:17 +0530492} // namespace implementation
493} // namespace V1_0
494} // namespace cec
495} // namespace tv
496} // namespace hardware
497} // namespace android