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 // Methods from ::android::hardware::tv::cec::V1_0::IHdmiCec follow.
    270 Return<Result> HdmiCec::addLogicalAddress(CecLogicalAddress addr) {
    271     int ret = mDevice->add_logical_address(mDevice, static_cast<cec_logical_address_t>(addr));
    272     switch (ret) {
    273         case 0:
    274             return Result::SUCCESS;
    275         case -EINVAL:
    276             return Result::FAILURE_INVALID_ARGS;
    277         case -ENOTSUP:
    278             return Result::FAILURE_NOT_SUPPORTED;
    279         case -EBUSY:
    280             return Result::FAILURE_BUSY;
    281         default:
    282             return Result::FAILURE_UNKNOWN;
    283     }
    284 }
    285 
    286 Return<void> HdmiCec::clearLogicalAddress() {
    287     mDevice->clear_logical_address(mDevice);
    288     return Void();
    289 }
    290 
    291 Return<void> HdmiCec::getPhysicalAddress(getPhysicalAddress_cb _hidl_cb) {
    292     uint16_t addr;
    293     int ret = mDevice->get_physical_address(mDevice, &addr);
    294     switch (ret) {
    295         case 0:
    296             _hidl_cb(Result::SUCCESS, addr);
    297             break;
    298         case -EBADF:
    299             _hidl_cb(Result::FAILURE_INVALID_STATE, addr);
    300             break;
    301         default:
    302             _hidl_cb(Result::FAILURE_UNKNOWN, addr);
    303             break;
    304     }
    305     return Void();
    306 }
    307 
    308 Return<SendMessageResult> HdmiCec::sendMessage(const CecMessage& message) {
    309     cec_message_t legacyMessage {
    310         .initiator = static_cast<cec_logical_address_t>(message.initiator),
    311         .destination = static_cast<cec_logical_address_t>(message.destination),
    312         .length = message.body.size(),
    313     };
    314     for (size_t i = 0; i < message.body.size(); ++i) {
    315         legacyMessage.body[i] = static_cast<unsigned char>(message.body[i]);
    316     }
    317     return static_cast<SendMessageResult>(mDevice->send_message(mDevice, &legacyMessage));
    318 }
    319 
    320 Return<void> HdmiCec::setCallback(const sp<IHdmiCecCallback>& callback) {
    321     if (mCallback != nullptr) {
    322         mCallback->unlinkToDeath(this);
    323         mCallback = nullptr;
    324     }
    325 
    326     if (callback != nullptr) {
    327         mCallback = callback;
    328         mCallback->linkToDeath(this, 0 /*cookie*/);
    329         mDevice->register_event_callback(mDevice, eventCallback, nullptr);
    330     }
    331     return Void();
    332 }
    333 
    334 Return<int32_t> HdmiCec::getCecVersion() {
    335     int version;
    336     mDevice->get_version(mDevice, &version);
    337     return static_cast<int32_t>(version);
    338 }
    339 
    340 Return<uint32_t> HdmiCec::getVendorId() {
    341     uint32_t vendor_id;
    342     mDevice->get_vendor_id(mDevice, &vendor_id);
    343     return vendor_id;
    344 }
    345 
    346 Return<void> HdmiCec::getPortInfo(getPortInfo_cb _hidl_cb) {
    347     struct hdmi_port_info* legacyPorts;
    348     int numPorts;
    349     hidl_vec<HdmiPortInfo> portInfos;
    350     mDevice->get_port_info(mDevice, &legacyPorts, &numPorts);
    351     portInfos.resize(numPorts);
    352     for (int i = 0; i < numPorts; ++i) {
    353         portInfos[i] = {
    354             .type = static_cast<HdmiPortType>(legacyPorts[i].type),
    355             .portId = static_cast<uint32_t>(legacyPorts[i].port_id),
    356             .cecSupported = legacyPorts[i].cec_supported != 0,
    357             .arcSupported = legacyPorts[i].arc_supported != 0,
    358             .physicalAddress = legacyPorts[i].physical_address
    359         };
    360     }
    361     _hidl_cb(portInfos);
    362     return Void();
    363 }
    364 
    365 Return<void> HdmiCec::setOption(OptionKey key, bool value) {
    366     mDevice->set_option(mDevice, static_cast<int>(key), value ? 1 : 0);
    367     return Void();
    368 }
    369 
    370 Return<void> HdmiCec::setLanguage(const hidl_string& language) {
    371     if (language.size() != 3) {
    372         LOG(ERROR) << "Wrong language code: expected 3 letters, but it was " << language.size()
    373                 << ".";
    374         return Void();
    375     }
    376     const char *languageStr = language.c_str();
    377     int convertedLanguage = ((languageStr[0] & 0xFF) << 16)
    378             | ((languageStr[1] & 0xFF) << 8)
    379             | (languageStr[2] & 0xFF);
    380     mDevice->set_option(mDevice, HDMI_OPTION_SET_LANG, convertedLanguage);
    381     return Void();
    382 }
    383 
    384 Return<void> HdmiCec::enableAudioReturnChannel(int32_t portId, bool enable) {
    385     mDevice->set_audio_return_channel(mDevice, portId, enable ? 1 : 0);
    386     return Void();
    387 }
    388 
    389 Return<bool> HdmiCec::isConnected(int32_t portId) {
    390     return mDevice->is_connected(mDevice, portId) > 0;
    391 }
    392 
    393 
    394 IHdmiCec* HIDL_FETCH_IHdmiCec(const char* hal) {
    395     hdmi_cec_device_t* hdmi_cec_device;
    396     int ret = 0;
    397     const hw_module_t* hw_module = nullptr;
    398 
    399     ret = hw_get_module (HDMI_CEC_HARDWARE_MODULE_ID, &hw_module);
    400     if (ret == 0) {
    401         ret = hdmi_cec_open (hw_module, &hdmi_cec_device);
    402         if (ret != 0) {
    403             LOG(ERROR) << "hdmi_cec_open " << hal << " failed: " << ret;
    404         }
    405     } else {
    406         LOG(ERROR) << "hw_get_module " << hal << " failed: " << ret;
    407     }
    408 
    409     if (ret == 0) {
    410         return new HdmiCec(hdmi_cec_device);
    411     } else {
    412         LOG(ERROR) << "Passthrough failed to load legacy HAL.";
    413         return nullptr;
    414     }
    415 }
    416 
    417 }  // namespace implementation
    418 }  // namespace V1_0
    419 }  // namespace cec
    420 }  // namespace tv
    421 }  // namespace hardware
    422 }  // namespace android
    423