Home | History | Annotate | Download | only in default
      1 /*
      2  * Copyright (C) 2016 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 (at) 1.0-impl"
     18 #include <android-base/logging.h>
     19 
     20 #include <hardware/hardware.h>
     21 #include <hardware/hdmi_cec.h>
     22 #include "HdmiCec.h"
     23 
     24 namespace android {
     25 namespace hardware {
     26 namespace tv {
     27 namespace cec {
     28 namespace V1_0 {
     29 namespace implementation {
     30 
     31 static_assert(CEC_DEVICE_INACTIVE == static_cast<int>(CecDeviceType::INACTIVE),
     32         "CecDeviceType::INACTIVE must match legacy value.");
     33 static_assert(CEC_DEVICE_TV == static_cast<int>(CecDeviceType::TV),
     34         "CecDeviceType::TV must match legacy value.");
     35 static_assert(CEC_DEVICE_RECORDER == static_cast<int>(CecDeviceType::RECORDER),
     36         "CecDeviceType::RECORDER must match legacy value.");
     37 static_assert(CEC_DEVICE_TUNER == static_cast<int>(CecDeviceType::TUNER),
     38         "CecDeviceType::TUNER must match legacy value.");
     39 static_assert(CEC_DEVICE_PLAYBACK == static_cast<int>(CecDeviceType::PLAYBACK),
     40         "CecDeviceType::PLAYBACK must match legacy value.");
     41 static_assert(CEC_DEVICE_AUDIO_SYSTEM == static_cast<int>(CecDeviceType::AUDIO_SYSTEM),
     42         "CecDeviceType::AUDIO_SYSTEM must match legacy value.");
     43 static_assert(CEC_DEVICE_MAX == static_cast<int>(CecDeviceType::MAX),
     44         "CecDeviceType::MAX must match legacy value.");
     45 
     46 static_assert(CEC_ADDR_TV == static_cast<int>(CecLogicalAddress::TV),
     47         "CecLogicalAddress::TV must match legacy value.");
     48 static_assert(CEC_ADDR_RECORDER_1 == static_cast<int>(CecLogicalAddress::RECORDER_1),
     49         "CecLogicalAddress::RECORDER_1 must match legacy value.");
     50 static_assert(CEC_ADDR_RECORDER_2 == static_cast<int>(CecLogicalAddress::RECORDER_2),
     51         "CecLogicalAddress::RECORDER_2 must match legacy value.");
     52 static_assert(CEC_ADDR_TUNER_1 == static_cast<int>(CecLogicalAddress::TUNER_1),
     53         "CecLogicalAddress::TUNER_1 must match legacy value.");
     54 static_assert(CEC_ADDR_PLAYBACK_1 == static_cast<int>(CecLogicalAddress::PLAYBACK_1),
     55         "CecLogicalAddress::PLAYBACK_1 must match legacy value.");
     56 static_assert(CEC_ADDR_AUDIO_SYSTEM == static_cast<int>(CecLogicalAddress::AUDIO_SYSTEM),
     57         "CecLogicalAddress::AUDIO_SYSTEM must match legacy value.");
     58 static_assert(CEC_ADDR_TUNER_2 == static_cast<int>(CecLogicalAddress::TUNER_2),
     59         "CecLogicalAddress::TUNER_2 must match legacy value.");
     60 static_assert(CEC_ADDR_TUNER_3 == static_cast<int>(CecLogicalAddress::TUNER_3),
     61         "CecLogicalAddress::TUNER_3 must match legacy value.");
     62 static_assert(CEC_ADDR_PLAYBACK_2 == static_cast<int>(CecLogicalAddress::PLAYBACK_2),
     63         "CecLogicalAddress::PLAYBACK_2 must match legacy value.");
     64 static_assert(CEC_ADDR_RECORDER_3 == static_cast<int>(CecLogicalAddress::RECORDER_3),
     65         "CecLogicalAddress::RECORDER_3 must match legacy value.");
     66 static_assert(CEC_ADDR_TUNER_4 == static_cast<int>(CecLogicalAddress::TUNER_4),
     67         "CecLogicalAddress::TUNER_4 must match legacy value.");
     68 static_assert(CEC_ADDR_PLAYBACK_3 == static_cast<int>(CecLogicalAddress::PLAYBACK_3),
     69         "CecLogicalAddress::PLAYBACK_3 must match legacy value.");
     70 static_assert(CEC_ADDR_FREE_USE == static_cast<int>(CecLogicalAddress::FREE_USE),
     71         "CecLogicalAddress::FREE_USE must match legacy value.");
     72 static_assert(CEC_ADDR_UNREGISTERED == static_cast<int>(CecLogicalAddress::UNREGISTERED),
     73         "CecLogicalAddress::UNREGISTERED must match legacy value.");
     74 static_assert(CEC_ADDR_BROADCAST == static_cast<int>(CecLogicalAddress::BROADCAST),
     75         "CecLogicalAddress::BROADCAST must match legacy value.");
     76 
     77 static_assert(CEC_MESSAGE_FEATURE_ABORT == static_cast<int>(CecMessageType::FEATURE_ABORT),
     78         "CecMessageType::FEATURE_ABORT must match legacy value.");
     79 static_assert(CEC_MESSAGE_IMAGE_VIEW_ON == static_cast<int>(CecMessageType::IMAGE_VIEW_ON),
     80         "CecMessageType::IMAGE_VIEW_ON must match legacy value.");
     81 static_assert(CEC_MESSAGE_TUNER_STEP_INCREMENT == static_cast<int>(
     82         CecMessageType::TUNER_STEP_INCREMENT),
     83         "CecMessageType::TUNER_STEP_INCREMENT must match legacy value.");
     84 static_assert(CEC_MESSAGE_TUNER_STEP_DECREMENT == static_cast<int>(
     85         CecMessageType::TUNER_STEP_DECREMENT),
     86         "CecMessageType::TUNER_STEP_DECREMENT must match legacy value.");
     87 static_assert(CEC_MESSAGE_TUNER_DEVICE_STATUS == static_cast<int>(
     88         CecMessageType::TUNER_DEVICE_STATUS),
     89         "CecMessageType::TUNER_DEVICE_STATUS must match legacy value.");
     90 static_assert(CEC_MESSAGE_GIVE_TUNER_DEVICE_STATUS == static_cast<int>(
     91         CecMessageType::GIVE_TUNER_DEVICE_STATUS),
     92         "CecMessageType::GIVE_TUNER_DEVICE_STATUS must match legacy value.");
     93 static_assert(CEC_MESSAGE_RECORD_ON == static_cast<int>(CecMessageType::RECORD_ON),
     94         "CecMessageType::RECORD_ON must match legacy value.");
     95 static_assert(CEC_MESSAGE_RECORD_STATUS == static_cast<int>(CecMessageType::RECORD_STATUS),
     96         "CecMessageType::RECORD_STATUS must match legacy value.");
     97 static_assert(CEC_MESSAGE_RECORD_OFF == static_cast<int>(CecMessageType::RECORD_OFF),
     98         "CecMessageType::RECORD_OFF must match legacy value.");
     99 static_assert(CEC_MESSAGE_TEXT_VIEW_ON == static_cast<int>(CecMessageType::TEXT_VIEW_ON),
    100         "CecMessageType::TEXT_VIEW_ON must match legacy value.");
    101 static_assert(CEC_MESSAGE_RECORD_TV_SCREEN == static_cast<int>(CecMessageType::RECORD_TV_SCREEN),
    102         "CecMessageType::RECORD_TV_SCREEN must match legacy value.");
    103 static_assert(CEC_MESSAGE_GIVE_DECK_STATUS == static_cast<int>(CecMessageType::GIVE_DECK_STATUS),
    104         "CecMessageType::GIVE_DECK_STATUS must match legacy value.");
    105 static_assert(CEC_MESSAGE_STANDBY == static_cast<int>(CecMessageType::STANDBY),
    106         "CecMessageType::STANDBY must match legacy value.");
    107 static_assert(CEC_MESSAGE_PLAY == static_cast<int>(CecMessageType::PLAY),
    108         "CecMessageType::PLAY must match legacy value.");
    109 static_assert(CEC_MESSAGE_DECK_CONTROL == static_cast<int>(CecMessageType::DECK_CONTROL),
    110         "CecMessageType::DECK_CONTROL must match legacy value.");
    111 static_assert(CEC_MESSAGE_TIMER_CLEARED_STATUS == static_cast<int>(
    112         CecMessageType::TIMER_CLEARED_STATUS),
    113         "CecMessageType::TIMER_CLEARED_STATUS must match legacy value.");
    114 static_assert(CEC_MESSAGE_USER_CONTROL_PRESSED == static_cast<int>(
    115         CecMessageType::USER_CONTROL_PRESSED),
    116         "CecMessageType::USER_CONTROL_PRESSED must match legacy value.");
    117 static_assert(CEC_MESSAGE_USER_CONTROL_RELEASED == static_cast<int>(
    118         CecMessageType::USER_CONTROL_RELEASED),
    119         "CecMessageType::USER_CONTROL_RELEASED must match legacy value.");
    120 static_assert(CEC_MESSAGE_GIVE_OSD_NAME == static_cast<int>(CecMessageType::GIVE_OSD_NAME),
    121         "CecMessageType::GIVE_OSD_NAME must match legacy value.");
    122 static_assert(CEC_MESSAGE_SET_OSD_NAME == static_cast<int>(CecMessageType::SET_OSD_NAME),
    123         "CecMessageType::SET_OSD_NAME must match legacy value.");
    124 static_assert(CEC_MESSAGE_SYSTEM_AUDIO_MODE_REQUEST == static_cast<int>(
    125         CecMessageType::SYSTEM_AUDIO_MODE_REQUEST),
    126         "CecMessageType::SYSTEM_AUDIO_MODE_REQUEST must match legacy value.");
    127 static_assert(CEC_MESSAGE_GIVE_AUDIO_STATUS == static_cast<int>(CecMessageType::GIVE_AUDIO_STATUS),
    128         "CecMessageType::GIVE_AUDIO_STATUS must match legacy value.");
    129 static_assert(CEC_MESSAGE_SET_SYSTEM_AUDIO_MODE == static_cast<int>(
    130         CecMessageType::SET_SYSTEM_AUDIO_MODE),
    131         "CecMessageType::SET_SYSTEM_AUDIO_MODE must match legacy value.");
    132 static_assert(CEC_MESSAGE_REPORT_AUDIO_STATUS == static_cast<int>(
    133         CecMessageType::REPORT_AUDIO_STATUS),
    134         "CecMessageType::REPORT_AUDIO_STATUS must match legacy value.");
    135 static_assert(CEC_MESSAGE_GIVE_SYSTEM_AUDIO_MODE_STATUS == static_cast<int>(
    136         CecMessageType::GIVE_SYSTEM_AUDIO_MODE_STATUS),
    137         "CecMessageType::GIVE_SYSTEM_AUDIO_MODE_STATUS must match legacy value.");
    138 static_assert(CEC_MESSAGE_SYSTEM_AUDIO_MODE_STATUS == static_cast<int>(
    139         CecMessageType::SYSTEM_AUDIO_MODE_STATUS),
    140         "CecMessageType::SYSTEM_AUDIO_MODE_STATUS must match legacy value.");
    141 static_assert(CEC_MESSAGE_ROUTING_CHANGE == static_cast<int>(CecMessageType::ROUTING_CHANGE),
    142         "CecMessageType::ROUTING_CHANGE must match legacy value.");
    143 static_assert(CEC_MESSAGE_ROUTING_INFORMATION == static_cast<int>(
    144         CecMessageType::ROUTING_INFORMATION),
    145         "CecMessageType::ROUTING_INFORMATION must match legacy value.");
    146 static_assert(CEC_MESSAGE_ACTIVE_SOURCE == static_cast<int>(CecMessageType::ACTIVE_SOURCE),
    147         "CecMessageType::ACTIVE_SOURCE must match legacy value.");
    148 static_assert(CEC_MESSAGE_GIVE_PHYSICAL_ADDRESS == static_cast<int>(
    149         CecMessageType::GIVE_PHYSICAL_ADDRESS),
    150         "CecMessageType::GIVE_PHYSICAL_ADDRESS must match legacy value.");
    151 static_assert(CEC_MESSAGE_REPORT_PHYSICAL_ADDRESS == static_cast<int>(
    152         CecMessageType::REPORT_PHYSICAL_ADDRESS),
    153         "CecMessageType::REPORT_PHYSICAL_ADDRESS must match legacy value.");
    154 static_assert(CEC_MESSAGE_REQUEST_ACTIVE_SOURCE == static_cast<int>(
    155         CecMessageType::REQUEST_ACTIVE_SOURCE),
    156         "CecMessageType::REQUEST_ACTIVE_SOURCE must match legacy value.");
    157 static_assert(CEC_MESSAGE_SET_STREAM_PATH == static_cast<int>(CecMessageType::SET_STREAM_PATH),
    158         "CecMessageType::SET_STREAM_PATH must match legacy value.");
    159 static_assert(CEC_MESSAGE_DEVICE_VENDOR_ID == static_cast<int>(CecMessageType::DEVICE_VENDOR_ID),
    160         "CecMessageType::DEVICE_VENDOR_ID must match legacy value.");
    161 static_assert(CEC_MESSAGE_VENDOR_COMMAND == static_cast<int>(CecMessageType::VENDOR_COMMAND),
    162         "CecMessageType::VENDOR_COMMAND must match legacy value.");
    163 static_assert(CEC_MESSAGE_VENDOR_REMOTE_BUTTON_DOWN == static_cast<int>(
    164         CecMessageType::VENDOR_REMOTE_BUTTON_DOWN),
    165         "CecMessageType::VENDOR_REMOTE_BUTTON_DOWN must match legacy value.");
    166 static_assert(CEC_MESSAGE_VENDOR_REMOTE_BUTTON_UP == static_cast<int>(
    167         CecMessageType::VENDOR_REMOTE_BUTTON_UP),
    168         "CecMessageType::VENDOR_REMOTE_BUTTON_UP must match legacy value.");
    169 static_assert(CEC_MESSAGE_GIVE_DEVICE_VENDOR_ID == static_cast<int>(
    170         CecMessageType::GIVE_DEVICE_VENDOR_ID),
    171         "CecMessageType::GIVE_DEVICE_VENDOR_ID must match legacy value.");
    172 static_assert(CEC_MESSAGE_MENU_REQUEST == static_cast<int>(CecMessageType::MENU_REQUEST),
    173         "CecMessageType::MENU_REQUEST must match legacy value.");
    174 static_assert(CEC_MESSAGE_MENU_STATUS == static_cast<int>(CecMessageType::MENU_STATUS),
    175         "CecMessageType::MENU_STATUS must match legacy value.");
    176 static_assert(CEC_MESSAGE_GIVE_DEVICE_POWER_STATUS == static_cast<int>(
    177         CecMessageType::GIVE_DEVICE_POWER_STATUS),
    178         "CecMessageType::GIVE_DEVICE_POWER_STATUS must match legacy value.");
    179 static_assert(CEC_MESSAGE_REPORT_POWER_STATUS == static_cast<int>(
    180         CecMessageType::REPORT_POWER_STATUS),
    181         "CecMessageType::REPORT_POWER_STATUS must match legacy value.");
    182 static_assert(CEC_MESSAGE_GET_MENU_LANGUAGE == static_cast<int>(CecMessageType::GET_MENU_LANGUAGE),
    183         "CecMessageType::GET_MENU_LANGUAGE must match legacy value.");
    184 static_assert(CEC_MESSAGE_SELECT_ANALOG_SERVICE == static_cast<int>(
    185         CecMessageType::SELECT_ANALOG_SERVICE),
    186         "CecMessageType::SELECT_ANALOG_SERVICE must match legacy value.");
    187 static_assert(CEC_MESSAGE_SELECT_DIGITAL_SERVICE == static_cast<int>(
    188         CecMessageType::SELECT_DIGITAL_SERVICE),
    189         "CecMessageType::SELECT_DIGITAL_SERVICE must match legacy value.");
    190 static_assert(CEC_MESSAGE_SET_DIGITAL_TIMER == static_cast<int>(CecMessageType::SET_DIGITAL_TIMER),
    191         "CecMessageType::SET_DIGITAL_TIMER must match legacy value.");
    192 static_assert(CEC_MESSAGE_CLEAR_DIGITAL_TIMER == static_cast<int>(
    193         CecMessageType::CLEAR_DIGITAL_TIMER),
    194         "CecMessageType::CLEAR_DIGITAL_TIMER must match legacy value.");
    195 static_assert(CEC_MESSAGE_SET_AUDIO_RATE == static_cast<int>(CecMessageType::SET_AUDIO_RATE),
    196         "CecMessageType::SET_AUDIO_RATE must match legacy value.");
    197 static_assert(CEC_MESSAGE_INACTIVE_SOURCE == static_cast<int>(CecMessageType::INACTIVE_SOURCE),
    198         "CecMessageType::INACTIVE_SOURCE must match legacy value.");
    199 static_assert(CEC_MESSAGE_CEC_VERSION == static_cast<int>(CecMessageType::CEC_VERSION),
    200         "CecMessageType::CEC_VERSION must match legacy value.");
    201 static_assert(CEC_MESSAGE_GET_CEC_VERSION == static_cast<int>(CecMessageType::GET_CEC_VERSION),
    202         "CecMessageType::GET_CEC_VERSION must match legacy value.");
    203 static_assert(CEC_MESSAGE_VENDOR_COMMAND_WITH_ID == static_cast<int>(
    204         CecMessageType::VENDOR_COMMAND_WITH_ID),
    205         "CecMessageType::VENDOR_COMMAND_WITH_ID must match legacy value.");
    206 static_assert(CEC_MESSAGE_CLEAR_EXTERNAL_TIMER == static_cast<int>(
    207         CecMessageType::CLEAR_EXTERNAL_TIMER),
    208         "CecMessageType::CLEAR_EXTERNAL_TIMER must match legacy value.");
    209 static_assert(CEC_MESSAGE_SET_EXTERNAL_TIMER == static_cast<int>(
    210         CecMessageType::SET_EXTERNAL_TIMER),
    211         "CecMessageType::SET_EXTERNAL_TIMER must match legacy value.");
    212 static_assert(CEC_MESSAGE_INITIATE_ARC == static_cast<int>(CecMessageType::INITIATE_ARC),
    213         "CecMessageType::INITIATE_ARC must match legacy value.");
    214 static_assert(CEC_MESSAGE_REPORT_ARC_INITIATED == static_cast<int>(
    215         CecMessageType::REPORT_ARC_INITIATED),
    216         "CecMessageType::REPORT_ARC_INITIATED must match legacy value.");
    217 static_assert(CEC_MESSAGE_REPORT_ARC_TERMINATED == static_cast<int>(
    218         CecMessageType::REPORT_ARC_TERMINATED),
    219         "CecMessageType::REPORT_ARC_TERMINATED must match legacy value.");
    220 static_assert(CEC_MESSAGE_REQUEST_ARC_INITIATION == static_cast<int>(
    221         CecMessageType::REQUEST_ARC_INITIATION),
    222         "CecMessageType::REQUEST_ARC_INITIATION must match legacy value.");
    223 static_assert(CEC_MESSAGE_REQUEST_ARC_TERMINATION == static_cast<int>(
    224         CecMessageType::REQUEST_ARC_TERMINATION),
    225         "CecMessageType::REQUEST_ARC_TERMINATION must match legacy value.");
    226 static_assert(CEC_MESSAGE_TERMINATE_ARC == static_cast<int>(CecMessageType::TERMINATE_ARC),
    227         "CecMessageType::TERMINATE_ARC must match legacy value.");
    228 static_assert(CEC_MESSAGE_ABORT == static_cast<int>(CecMessageType::ABORT),
    229         "CecMessageType::ABORT must match legacy value.");
    230 
    231 static_assert(ABORT_UNRECOGNIZED_MODE == static_cast<int>(AbortReason::UNRECOGNIZED_MODE),
    232         "AbortReason::UNRECOGNIZED_MODE must match legacy value.");
    233 static_assert(ABORT_NOT_IN_CORRECT_MODE == static_cast<int>(AbortReason::NOT_IN_CORRECT_MODE),
    234         "AbortReason::NOT_IN_CORRECT_MODE must match legacy value.");
    235 static_assert(ABORT_CANNOT_PROVIDE_SOURCE == static_cast<int>(AbortReason::CANNOT_PROVIDE_SOURCE),
    236         "AbortReason::CANNOT_PROVIDE_SOURCE must match legacy value.");
    237 static_assert(ABORT_INVALID_OPERAND == static_cast<int>(AbortReason::INVALID_OPERAND),
    238         "AbortReason::INVALID_OPERAND must match legacy value.");
    239 static_assert(ABORT_REFUSED == static_cast<int>(AbortReason::REFUSED),
    240         "AbortReason::REFUSED must match legacy value.");
    241 static_assert(ABORT_UNABLE_TO_DETERMINE == static_cast<int>(AbortReason::UNABLE_TO_DETERMINE),
    242         "AbortReason::UNABLE_TO_DETERMINE must match legacy value.");
    243 
    244 static_assert(HDMI_RESULT_SUCCESS == static_cast<int>(SendMessageResult::SUCCESS),
    245         "SendMessageResult::SUCCESS must match legacy value.");
    246 static_assert(HDMI_RESULT_NACK == static_cast<int>(SendMessageResult::NACK),
    247         "SendMessageResult::NACK must match legacy value.");
    248 static_assert(HDMI_RESULT_BUSY == static_cast<int>(SendMessageResult::BUSY),
    249         "SendMessageResult::BUSY must match legacy value.");
    250 static_assert(HDMI_RESULT_FAIL == static_cast<int>(SendMessageResult::FAIL),
    251         "SendMessageResult::FAIL must match legacy value.");
    252 
    253 static_assert(HDMI_INPUT == static_cast<int>(HdmiPortType::INPUT),
    254         "HdmiPortType::INPUT must match legacy value.");
    255 static_assert(HDMI_OUTPUT == static_cast<int>(HdmiPortType::OUTPUT),
    256         "HdmiPortType::OUTPUT must match legacy value.");
    257 
    258 static_assert(HDMI_OPTION_WAKEUP == static_cast<int>(OptionKey::WAKEUP),
    259         "OptionKey::WAKEUP must match legacy value.");
    260 static_assert(HDMI_OPTION_ENABLE_CEC == static_cast<int>(OptionKey::ENABLE_CEC),
    261         "OptionKey::ENABLE_CEC must match legacy value.");
    262 static_assert(HDMI_OPTION_SYSTEM_CEC_CONTROL == static_cast<int>(OptionKey::SYSTEM_CEC_CONTROL),
    263         "OptionKey::SYSTEM_CEC_CONTROL must match legacy value.");
    264 
    265 sp<IHdmiCecCallback> HdmiCec::mCallback = nullptr;
    266 
    267 HdmiCec::HdmiCec(hdmi_cec_device_t* device) : mDevice(device) {
    268 }
    269 
    270 // Methods from ::android::hardware::tv::cec::V1_0::IHdmiCec follow.
    271 Return<Result> HdmiCec::addLogicalAddress(CecLogicalAddress addr) {
    272     int ret = mDevice->add_logical_address(mDevice, static_cast<cec_logical_address_t>(addr));
    273     switch (ret) {
    274         case 0:
    275             return Result::SUCCESS;
    276         case -EINVAL:
    277             return Result::FAILURE_INVALID_ARGS;
    278         case -ENOTSUP:
    279             return Result::FAILURE_NOT_SUPPORTED;
    280         case -EBUSY:
    281             return Result::FAILURE_BUSY;
    282         default:
    283             return Result::FAILURE_UNKNOWN;
    284     }
    285 }
    286 
    287 Return<void> HdmiCec::clearLogicalAddress() {
    288     mDevice->clear_logical_address(mDevice);
    289     return Void();
    290 }
    291 
    292 Return<void> HdmiCec::getPhysicalAddress(getPhysicalAddress_cb _hidl_cb) {
    293     uint16_t addr;
    294     int ret = mDevice->get_physical_address(mDevice, &addr);
    295     switch (ret) {
    296         case 0:
    297             _hidl_cb(Result::SUCCESS, addr);
    298             break;
    299         case -EBADF:
    300             _hidl_cb(Result::FAILURE_INVALID_STATE, addr);
    301             break;
    302         default:
    303             _hidl_cb(Result::FAILURE_UNKNOWN, addr);
    304             break;
    305     }
    306     return Void();
    307 }
    308 
    309 Return<SendMessageResult> HdmiCec::sendMessage(const CecMessage& message) {
    310     cec_message_t legacyMessage {
    311         .initiator = static_cast<cec_logical_address_t>(message.initiator),
    312         .destination = static_cast<cec_logical_address_t>(message.destination),
    313         .length = message.body.size(),
    314     };
    315     for (size_t i = 0; i < message.body.size(); ++i) {
    316         legacyMessage.body[i] = static_cast<unsigned char>(message.body[i]);
    317     }
    318     return static_cast<SendMessageResult>(mDevice->send_message(mDevice, &legacyMessage));
    319 }
    320 
    321 Return<void> HdmiCec::setCallback(const sp<IHdmiCecCallback>& callback) {
    322     mCallback = callback;
    323     mDevice->register_event_callback(mDevice, eventCallback, nullptr);
    324     return Void();
    325 }
    326 
    327 Return<int32_t> HdmiCec::getCecVersion() {
    328     int version;
    329     mDevice->get_version(mDevice, &version);
    330     return static_cast<int32_t>(version);
    331 }
    332 
    333 Return<uint32_t> HdmiCec::getVendorId() {
    334     uint32_t vendor_id;
    335     mDevice->get_vendor_id(mDevice, &vendor_id);
    336     return vendor_id;
    337 }
    338 
    339 Return<void> HdmiCec::getPortInfo(getPortInfo_cb _hidl_cb) {
    340     struct hdmi_port_info* legacyPorts;
    341     int numPorts;
    342     hidl_vec<HdmiPortInfo> portInfos;
    343     mDevice->get_port_info(mDevice, &legacyPorts, &numPorts);
    344     portInfos.resize(numPorts);
    345     for (int i = 0; i < numPorts; ++i) {
    346         portInfos[i] = {
    347             .type = static_cast<HdmiPortType>(legacyPorts[i].type),
    348             .portId = static_cast<uint32_t>(legacyPorts[i].port_id),
    349             .cecSupported = legacyPorts[i].cec_supported != 0,
    350             .arcSupported = legacyPorts[i].arc_supported != 0,
    351             .physicalAddress = legacyPorts[i].physical_address
    352         };
    353     }
    354     _hidl_cb(portInfos);
    355     return Void();
    356 }
    357 
    358 Return<void> HdmiCec::setOption(OptionKey key, bool value) {
    359     mDevice->set_option(mDevice, static_cast<int>(key), value ? 1 : 0);
    360     return Void();
    361 }
    362 
    363 Return<void> HdmiCec::setLanguage(const hidl_string& language) {
    364     if (language.size() != 3) {
    365         LOG(ERROR) << "Wrong language code: expected 3 letters, but it was " << language.size()
    366                 << ".";
    367         return Void();
    368     }
    369     const char *languageStr = language.c_str();
    370     int convertedLanguage = ((languageStr[0] & 0xFF) << 16)
    371             | ((languageStr[1] & 0xFF) << 8)
    372             | (languageStr[2] & 0xFF);
    373     mDevice->set_option(mDevice, HDMI_OPTION_SET_LANG, convertedLanguage);
    374     return Void();
    375 }
    376 
    377 Return<void> HdmiCec::enableAudioReturnChannel(int32_t portId, bool enable) {
    378     mDevice->set_audio_return_channel(mDevice, portId, enable ? 1 : 0);
    379     return Void();
    380 }
    381 
    382 Return<bool> HdmiCec::isConnected(int32_t portId) {
    383     return mDevice->is_connected(mDevice, portId) > 0;
    384 }
    385 
    386 
    387 IHdmiCec* HIDL_FETCH_IHdmiCec(const char* hal) {
    388     hdmi_cec_device_t* hdmi_cec_device;
    389     int ret = 0;
    390     const hw_module_t* hw_module = nullptr;
    391 
    392     ret = hw_get_module (HDMI_CEC_HARDWARE_MODULE_ID, &hw_module);
    393     if (ret == 0) {
    394         ret = hdmi_cec_open (hw_module, &hdmi_cec_device);
    395         if (ret != 0) {
    396             LOG(ERROR) << "hdmi_cec_open " << hal << " failed: " << ret;
    397         }
    398     } else {
    399         LOG(ERROR) << "hw_get_module " << hal << " failed: " << ret;
    400     }
    401 
    402     if (ret == 0) {
    403         return new HdmiCec(hdmi_cec_device);
    404     } else {
    405         LOG(ERROR) << "Passthrough failed to load legacy HAL.";
    406         return nullptr;
    407     }
    408 }
    409 
    410 }  // namespace implementation
    411 }  // namespace V1_0
    412 }  // namespace cec
    413 }  // namespace tv
    414 }  // namespace hardware
    415 }  // namespace android
    416