Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cad5ed3f authored by Amy's avatar Amy Committed by android-build-merger
Browse files

Merge "Adding default HDMI CEC impl"

am: 42d10ce6

Change-Id: I40e20349695672ad34b72aff75a8611a938ac7bf
parents c573c0ad 42d10ce6
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line
@@ -39,3 +39,26 @@ cc_binary {
    ],

}

cc_binary {
    name: "android.hardware.tv.cec@1.0-service.mock",
    vintf_fragments: ["android.hardware.tv.cec@1.0-service.mock.xml"],
    relative_install_path: "hw",
    vendor: true,
    init_rc: ["android.hardware.tv.cec@1.0-service.mock.rc"],
    srcs: [
        "serviceMock.cpp",
        "HdmiCecMock.cpp",
    ],

    shared_libs: [
        "liblog",
        "libcutils",
        "libbase",
        "libutils",
        "libhardware",
        "libhidlbase",
        "libhidltransport",
        "android.hardware.tv.cec@1.0",
    ],
}
+157 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "android.hardware.tv.cec@1.0-mock"
#include <android-base/logging.h>
#include <utils/Log.h>

#include <hardware/hardware.h>
#include <hardware/hdmi_cec.h>
#include "HdmiCecMock.h"

namespace android {
namespace hardware {
namespace tv {
namespace cec {
namespace V1_0 {
namespace implementation {

/*
 * (*set_option)() passes flags controlling the way HDMI-CEC service works down
 * to HAL implementation. Those flags will be used in case the feature needs
 * update in HAL itself, firmware or microcontroller.
 */
void HdmiCecMock::cec_set_option(int flag, int value) {
    // maintain options and set them accordingly
    switch (flag) {
        case HDMI_OPTION_WAKEUP:
            mOptionWakeUp = value;
            break;
        case HDMI_OPTION_ENABLE_CEC:
            mOptionEnableCec = value;
            break;
        case HDMI_OPTION_SYSTEM_CEC_CONTROL:
            mOptionSystemCecControl = value;
            break;
        case HDMI_OPTION_SET_LANG:
            mOptionLanguage = value;
    }
}

// Methods from ::android::hardware::tv::cec::V1_0::IHdmiCec follow.
Return<Result> HdmiCecMock::addLogicalAddress(CecLogicalAddress addr) {
    // have a list to maintain logical addresses
    int size = mLogicalAddresses.size();
    mLogicalAddresses.resize(size + 1);
    mLogicalAddresses[size + 1] = addr;
    return Result::SUCCESS;
}

Return<void> HdmiCecMock::clearLogicalAddress() {
    // remove logical address from the list
    mLogicalAddresses = {};
    return Void();
}

Return<void> HdmiCecMock::getPhysicalAddress(getPhysicalAddress_cb _hidl_cb) {
    // maintain a physical address and return it
    // default 0xFFFF, update on hotplug event
    _hidl_cb(Result::SUCCESS, mPhysicalAddress);
    return Void();
}

Return<SendMessageResult> HdmiCecMock::sendMessage(const CecMessage& message) {
    if (message.body.size() == 0) {
        return SendMessageResult::NACK;
    }
    return SendMessageResult::SUCCESS;
}

Return<void> HdmiCecMock::setCallback(const sp<IHdmiCecCallback>& callback) {
    if (mCallback != nullptr) {
        mCallback = nullptr;
    }

    if (callback != nullptr) {
        mCallback = callback;
        mCallback->linkToDeath(this, 0 /*cookie*/);
    }
    return Void();
}

Return<int32_t> HdmiCecMock::getCecVersion() {
    // maintain a cec version and return it
    return mCecVersion;
}

Return<uint32_t> HdmiCecMock::getVendorId() {
    return mCecVendorId;
}

Return<void> HdmiCecMock::getPortInfo(getPortInfo_cb _hidl_cb) {
    vector<HdmiPortInfo> portInfos;
    // TODO ready port info from device specific config
    portInfos.resize(mTotalPorts);
    for (int i = 0; i < mTotalPorts; ++i) {
        portInfos[i] = {.type = HdmiPortType::INPUT,
                        .portId = static_cast<uint32_t>(i),
                        .cecSupported = true,
                        .arcSupported = (i == 0),
                        .physicalAddress = static_cast<uint16_t>(i << 12)};
    }
    _hidl_cb(portInfos);
    return Void();
}

Return<void> HdmiCecMock::setOption(OptionKey key, bool value) {
    cec_set_option(static_cast<int>(key), value ? 1 : 0);
    return Void();
}

Return<void> HdmiCecMock::setLanguage(const hidl_string& language) {
    if (language.size() != 3) {
        LOG(ERROR) << "Wrong language code: expected 3 letters, but it was " << language.size()
                   << ".";
        return Void();
    }
    // TODO validate if language is a valid language code
    const char* languageStr = language.c_str();
    int convertedLanguage = ((languageStr[0] & 0xFF) << 16) | ((languageStr[1] & 0xFF) << 8) |
                            (languageStr[2] & 0xFF);
    cec_set_option(HDMI_OPTION_SET_LANG, convertedLanguage);
    return Void();
}

Return<void> HdmiCecMock::enableAudioReturnChannel(int32_t portId __unused, bool enable __unused) {
    // Maintain ARC status
    return Void();
}

Return<bool> HdmiCecMock::isConnected(int32_t portId __unused) {
    // maintain port connection status and update on hotplug event
    return false;
}

HdmiCecMock::HdmiCecMock() {
    ALOGE("Opening a virtual HAL for testing and virtual machine.");
}

}  // namespace implementation
}  // namespace V1_0
}  // namespace cec
}  // namespace tv
}  // namespace hardware
}  // namespace android
+97 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ANDROID_HARDWARE_TV_CEC_V1_0_HDMICEC_H
#define ANDROID_HARDWARE_TV_CEC_V1_0_HDMICEC_H

#include <android/hardware/tv/cec/1.0/IHdmiCec.h>
#include <hardware/hardware.h>
#include <hardware/hdmi_cec.h>
#include <hidl/MQDescriptor.h>
#include <hidl/Status.h>
#include <algorithm>
#include <vector>

using namespace std;

namespace android {
namespace hardware {
namespace tv {
namespace cec {
namespace V1_0 {
namespace implementation {

using ::android::sp;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::hardware::tv::cec::V1_0::CecLogicalAddress;
using ::android::hardware::tv::cec::V1_0::CecMessage;
using ::android::hardware::tv::cec::V1_0::HdmiPortInfo;
using ::android::hardware::tv::cec::V1_0::IHdmiCec;
using ::android::hardware::tv::cec::V1_0::IHdmiCecCallback;
using ::android::hardware::tv::cec::V1_0::MaxLength;
using ::android::hardware::tv::cec::V1_0::OptionKey;
using ::android::hardware::tv::cec::V1_0::Result;
using ::android::hardware::tv::cec::V1_0::SendMessageResult;

struct HdmiCecMock : public IHdmiCec, public hidl_death_recipient {
    HdmiCecMock();
    // Methods from ::android::hardware::tv::cec::V1_0::IHdmiCec follow.
    Return<Result> addLogicalAddress(CecLogicalAddress addr) override;
    Return<void> clearLogicalAddress() override;
    Return<void> getPhysicalAddress(getPhysicalAddress_cb _hidl_cb) override;
    Return<SendMessageResult> sendMessage(const CecMessage& message) override;
    Return<void> setCallback(const sp<IHdmiCecCallback>& callback) override;
    Return<int32_t> getCecVersion() override;
    Return<uint32_t> getVendorId() override;
    Return<void> getPortInfo(getPortInfo_cb _hidl_cb) override;
    Return<void> setOption(OptionKey key, bool value) override;
    Return<void> setLanguage(const hidl_string& language) override;
    Return<void> enableAudioReturnChannel(int32_t portId, bool enable) override;
    Return<bool> isConnected(int32_t portId) override;

    virtual void serviceDied(uint64_t /*cookie*/,
                             const wp<::android::hidl::base::V1_0::IBase>& /*who*/) {
        setCallback(nullptr);
    }

    void cec_set_option(int flag, int value);

  private:
    sp<IHdmiCecCallback> mCallback;
    // Variables for the virtual cec hal impl
    uint16_t mPhysicalAddress = 0xFFFF;
    vector<CecLogicalAddress> mLogicalAddresses;
    int32_t mCecVersion = 0;
    uint32_t mCecVendorId = 0;
    // Port configuration
    int mTotalPorts = 4;
    // CEC Option value
    int mOptionWakeUp = 0;
    int mOptionEnableCec = 0;
    int mOptionSystemCecControl = 0;
    int mOptionLanguage = 0;
};
}  // namespace implementation
}  // namespace V1_0
}  // namespace cec
}  // namespace tv
}  // namespace hardware
}  // namespace android

#endif  // ANDROID_HARDWARE_TV_CEC_V1_0_HDMICEC_H
+5 −0
Original line number Diff line number Diff line
service vendor.cec-hal-1-0-mock /vendor/bin/hw/android.hardware.tv.cec@1.0-service.mock
    interface android.hardware.tv.cec@1.0::IHdmiCec default
    class hal
    user system
    group system
+11 −0
Original line number Diff line number Diff line
<manifest version="1.0" type="device">
    <hal format="hidl">
        <name>android.hardware.tv.cec</name>
        <transport>hwbinder</transport>
        <version>1.0</version>
        <interface>
            <name>IHdmiCec</name>
            <instance>default</instance>
        </interface>
    </hal>
</manifest>
Loading