Loading tv/cec/1.0/default/HdmiCecDefault.cpp +25 −41 Original line number Diff line number Diff line Loading @@ -16,14 +16,13 @@ #define LOG_TAG "android.hardware.tv.cec@1.0-impl" #include <android-base/logging.h> #include <android-base/properties.h> #include <cutils/properties.h> #include <errno.h> #include <fcntl.h> #include <linux/cec.h> #include <linux/ioctl.h> #include <poll.h> #include <pthread.h> #include <sys/eventfd.h> #include <algorithm> Loading @@ -36,18 +35,7 @@ namespace cec { namespace V1_0 { namespace implementation { // When set to false, all the CEC commands are discarded. True by default after initialization. bool mCecEnabled; /* * When set to false, HAL does not wake up the system upon receiving <Image View On> or * <Text View On>. True by default after initialization. */ bool mWakeupEnabled; int mCecFd; int mExitFd; pthread_t mEventThread; sp<IHdmiCecCallback> mCallback; using android::base::GetUintProperty; HdmiCecDefault::HdmiCecDefault() { mCecFd = -1; Loading @@ -68,7 +56,7 @@ Return<Result> HdmiCecDefault::addLogicalAddress(CecLogicalAddress addr) { return Result::FAILURE_INVALID_ARGS; } struct cec_log_addrs cecLogAddrs; cec_log_addrs cecLogAddrs; int ret = ioctl(mCecFd, CEC_ADAP_G_LOG_ADDRS, &cecLogAddrs); if (ret) { LOG(ERROR) << "Add logical address failed, Error = " << strerror(errno); Loading Loading @@ -144,7 +132,7 @@ Return<Result> HdmiCecDefault::addLogicalAddress(CecLogicalAddress addr) { } Return<void> HdmiCecDefault::clearLogicalAddress() { struct cec_log_addrs cecLogAddrs; cec_log_addrs cecLogAddrs; memset(&cecLogAddrs, 0, sizeof(cecLogAddrs)); int ret = ioctl(mCecFd, CEC_ADAP_S_LOG_ADDRS, &cecLogAddrs); if (ret) { Loading @@ -170,7 +158,7 @@ Return<SendMessageResult> HdmiCecDefault::sendMessage(const CecMessage& message) return SendMessageResult::FAIL; } struct cec_msg cecMsg; cec_msg cecMsg; memset(&cecMsg, 0, sizeof(cec_msg)); int initiator = static_cast<cec_logical_address_t>(message.initiator); Loading Loading @@ -233,7 +221,7 @@ Return<void> HdmiCecDefault::getPortInfo(getPortInfo_cb callback) { LOG(ERROR) << "Get port info failed, Error = " << strerror(errno); } unsigned int type = property_get_int32("ro.hdmi.device_type", CEC_DEVICE_PLAYBACK); uint32_t type = GetUintProperty<uint32_t>("ro.hdmi.device_type", CEC_DEVICE_PLAYBACK); hidl_vec<HdmiPortInfo> portInfos(1); portInfos[0] = {.type = (type == CEC_DEVICE_TV ? HdmiPortType::INPUT : HdmiPortType::OUTPUT), .portId = 1, Loading Loading @@ -297,7 +285,7 @@ Return<Result> HdmiCecDefault::init() { } // Ensure the CEC device supports required capabilities struct cec_caps caps = {}; cec_caps caps = {}; int ret = ioctl(mCecFd, CEC_ADAP_G_CAPS, &caps); if (ret) { LOG(ERROR) << "Unable to query cec adapter capabilities, Error = " << strerror(errno); Loading @@ -319,12 +307,7 @@ Return<Result> HdmiCecDefault::init() { return Result::FAILURE_NOT_SUPPORTED; } /* thread loop for receiving cec messages and hotplug events*/ if (pthread_create(&mEventThread, NULL, event_thread, NULL)) { LOG(ERROR) << "Can't create event thread: " << strerror(errno); release(); return Result::FAILURE_NOT_SUPPORTED; } mEventThread = thread(&HdmiCecDefault::event_thread, this); mCecEnabled = true; mWakeupEnabled = true; Loading @@ -335,7 +318,9 @@ Return<void> HdmiCecDefault::release() { if (mExitFd > 0) { uint64_t tmp = 1; write(mExitFd, &tmp, sizeof(tmp)); pthread_join(mEventThread, NULL); if (mEventThread.joinable()) { mEventThread.join(); } } if (mExitFd > 0) { close(mExitFd); Loading @@ -349,8 +334,8 @@ Return<void> HdmiCecDefault::release() { return Void(); } void* HdmiCecDefault::event_thread(void*) { struct pollfd ufds[3] = { void HdmiCecDefault::event_thread() { pollfd ufds[3] = { {mCecFd, POLLIN, 0}, {mCecFd, POLLERR, 0}, {mExitFd, POLLIN, 0}, Loading @@ -372,15 +357,15 @@ void* HdmiCecDefault::event_thread(void*) { } if (ufds[1].revents == POLLERR) { /* CEC Event */ struct cec_event ev; cec_event ev; ret = ioctl(mCecFd, CEC_DQEVENT, &ev); if (!mCecEnabled) { if (ret) { LOG(ERROR) << "CEC_DQEVENT failed, Error = " << strerror(errno); continue; } if (ret) { LOG(ERROR) << "CEC_DQEVENT failed, Error = " << strerror(errno); if (!mCecEnabled) { continue; } Loading @@ -397,13 +382,9 @@ void* HdmiCecDefault::event_thread(void*) { } if (ufds[0].revents == POLLIN) { /* CEC Driver */ struct cec_msg msg = {}; cec_msg msg = {}; ret = ioctl(mCecFd, CEC_RECEIVE, &msg); if (!mCecEnabled) { continue; } if (ret) { LOG(ERROR) << "CEC_RECEIVE failed, Error = " << strerror(errno); continue; Loading @@ -414,6 +395,10 @@ void* HdmiCecDefault::event_thread(void*) { continue; } if (!mCecEnabled) { continue; } if (!mWakeupEnabled && isWakeupMessage(msg)) { LOG(DEBUG) << "Filter wakeup message"; continue; Loading @@ -435,14 +420,13 @@ void* HdmiCecDefault::event_thread(void*) { } } } return NULL; } int HdmiCecDefault::getOpcode(struct cec_msg message) { return (static_cast<uint8_t>(message.msg[1]) & 0xff); int HdmiCecDefault::getOpcode(cec_msg message) { return static_cast<uint8_t>(message.msg[1]); } bool HdmiCecDefault::isWakeupMessage(struct cec_msg message) { bool HdmiCecDefault::isWakeupMessage(cec_msg message) { int opcode = getOpcode(message); switch (opcode) { case CEC_MESSAGE_TEXT_VIEW_ON: Loading tv/cec/1.0/default/HdmiCecDefault.h +25 −5 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ #include <android/hardware/tv/cec/1.0/IHdmiCec.h> #include <hardware/hdmi_cec.h> #include <linux/cec.h> #include <thread> namespace android { namespace hardware { Loading @@ -24,7 +26,10 @@ namespace cec { namespace V1_0 { namespace implementation { struct HdmiCecDefault : public IHdmiCec, public hidl_death_recipient { using std::thread; class HdmiCecDefault : public IHdmiCec, public hidl_death_recipient { public: HdmiCecDefault(); ~HdmiCecDefault(); // Methods from ::android::hardware::tv::cec::V1_0::IHdmiCec follow. Loading @@ -47,11 +52,26 @@ struct HdmiCecDefault : public IHdmiCec, public hidl_death_recipient { Return<Result> init(); Return<void> release(); static void* event_thread(void*); static int getOpcode(struct cec_msg message); static bool isWakeupMessage(struct cec_msg message); }; private: void event_thread(); static int getOpcode(cec_msg message); static bool isWakeupMessage(cec_msg message); thread mEventThread; // When set to false, all the CEC commands are discarded. True by default after initialization. bool mCecEnabled; /* * When set to false, HAL does not wake up the system upon receiving <Image View On> or * <Text View On>. True by default after initialization. */ bool mWakeupEnabled; sp<IHdmiCecCallback> mCallback; int mCecFd; int mExitFd; }; } // namespace implementation } // namespace V1_0 } // namespace cec Loading Loading
tv/cec/1.0/default/HdmiCecDefault.cpp +25 −41 Original line number Diff line number Diff line Loading @@ -16,14 +16,13 @@ #define LOG_TAG "android.hardware.tv.cec@1.0-impl" #include <android-base/logging.h> #include <android-base/properties.h> #include <cutils/properties.h> #include <errno.h> #include <fcntl.h> #include <linux/cec.h> #include <linux/ioctl.h> #include <poll.h> #include <pthread.h> #include <sys/eventfd.h> #include <algorithm> Loading @@ -36,18 +35,7 @@ namespace cec { namespace V1_0 { namespace implementation { // When set to false, all the CEC commands are discarded. True by default after initialization. bool mCecEnabled; /* * When set to false, HAL does not wake up the system upon receiving <Image View On> or * <Text View On>. True by default after initialization. */ bool mWakeupEnabled; int mCecFd; int mExitFd; pthread_t mEventThread; sp<IHdmiCecCallback> mCallback; using android::base::GetUintProperty; HdmiCecDefault::HdmiCecDefault() { mCecFd = -1; Loading @@ -68,7 +56,7 @@ Return<Result> HdmiCecDefault::addLogicalAddress(CecLogicalAddress addr) { return Result::FAILURE_INVALID_ARGS; } struct cec_log_addrs cecLogAddrs; cec_log_addrs cecLogAddrs; int ret = ioctl(mCecFd, CEC_ADAP_G_LOG_ADDRS, &cecLogAddrs); if (ret) { LOG(ERROR) << "Add logical address failed, Error = " << strerror(errno); Loading Loading @@ -144,7 +132,7 @@ Return<Result> HdmiCecDefault::addLogicalAddress(CecLogicalAddress addr) { } Return<void> HdmiCecDefault::clearLogicalAddress() { struct cec_log_addrs cecLogAddrs; cec_log_addrs cecLogAddrs; memset(&cecLogAddrs, 0, sizeof(cecLogAddrs)); int ret = ioctl(mCecFd, CEC_ADAP_S_LOG_ADDRS, &cecLogAddrs); if (ret) { Loading @@ -170,7 +158,7 @@ Return<SendMessageResult> HdmiCecDefault::sendMessage(const CecMessage& message) return SendMessageResult::FAIL; } struct cec_msg cecMsg; cec_msg cecMsg; memset(&cecMsg, 0, sizeof(cec_msg)); int initiator = static_cast<cec_logical_address_t>(message.initiator); Loading Loading @@ -233,7 +221,7 @@ Return<void> HdmiCecDefault::getPortInfo(getPortInfo_cb callback) { LOG(ERROR) << "Get port info failed, Error = " << strerror(errno); } unsigned int type = property_get_int32("ro.hdmi.device_type", CEC_DEVICE_PLAYBACK); uint32_t type = GetUintProperty<uint32_t>("ro.hdmi.device_type", CEC_DEVICE_PLAYBACK); hidl_vec<HdmiPortInfo> portInfos(1); portInfos[0] = {.type = (type == CEC_DEVICE_TV ? HdmiPortType::INPUT : HdmiPortType::OUTPUT), .portId = 1, Loading Loading @@ -297,7 +285,7 @@ Return<Result> HdmiCecDefault::init() { } // Ensure the CEC device supports required capabilities struct cec_caps caps = {}; cec_caps caps = {}; int ret = ioctl(mCecFd, CEC_ADAP_G_CAPS, &caps); if (ret) { LOG(ERROR) << "Unable to query cec adapter capabilities, Error = " << strerror(errno); Loading @@ -319,12 +307,7 @@ Return<Result> HdmiCecDefault::init() { return Result::FAILURE_NOT_SUPPORTED; } /* thread loop for receiving cec messages and hotplug events*/ if (pthread_create(&mEventThread, NULL, event_thread, NULL)) { LOG(ERROR) << "Can't create event thread: " << strerror(errno); release(); return Result::FAILURE_NOT_SUPPORTED; } mEventThread = thread(&HdmiCecDefault::event_thread, this); mCecEnabled = true; mWakeupEnabled = true; Loading @@ -335,7 +318,9 @@ Return<void> HdmiCecDefault::release() { if (mExitFd > 0) { uint64_t tmp = 1; write(mExitFd, &tmp, sizeof(tmp)); pthread_join(mEventThread, NULL); if (mEventThread.joinable()) { mEventThread.join(); } } if (mExitFd > 0) { close(mExitFd); Loading @@ -349,8 +334,8 @@ Return<void> HdmiCecDefault::release() { return Void(); } void* HdmiCecDefault::event_thread(void*) { struct pollfd ufds[3] = { void HdmiCecDefault::event_thread() { pollfd ufds[3] = { {mCecFd, POLLIN, 0}, {mCecFd, POLLERR, 0}, {mExitFd, POLLIN, 0}, Loading @@ -372,15 +357,15 @@ void* HdmiCecDefault::event_thread(void*) { } if (ufds[1].revents == POLLERR) { /* CEC Event */ struct cec_event ev; cec_event ev; ret = ioctl(mCecFd, CEC_DQEVENT, &ev); if (!mCecEnabled) { if (ret) { LOG(ERROR) << "CEC_DQEVENT failed, Error = " << strerror(errno); continue; } if (ret) { LOG(ERROR) << "CEC_DQEVENT failed, Error = " << strerror(errno); if (!mCecEnabled) { continue; } Loading @@ -397,13 +382,9 @@ void* HdmiCecDefault::event_thread(void*) { } if (ufds[0].revents == POLLIN) { /* CEC Driver */ struct cec_msg msg = {}; cec_msg msg = {}; ret = ioctl(mCecFd, CEC_RECEIVE, &msg); if (!mCecEnabled) { continue; } if (ret) { LOG(ERROR) << "CEC_RECEIVE failed, Error = " << strerror(errno); continue; Loading @@ -414,6 +395,10 @@ void* HdmiCecDefault::event_thread(void*) { continue; } if (!mCecEnabled) { continue; } if (!mWakeupEnabled && isWakeupMessage(msg)) { LOG(DEBUG) << "Filter wakeup message"; continue; Loading @@ -435,14 +420,13 @@ void* HdmiCecDefault::event_thread(void*) { } } } return NULL; } int HdmiCecDefault::getOpcode(struct cec_msg message) { return (static_cast<uint8_t>(message.msg[1]) & 0xff); int HdmiCecDefault::getOpcode(cec_msg message) { return static_cast<uint8_t>(message.msg[1]); } bool HdmiCecDefault::isWakeupMessage(struct cec_msg message) { bool HdmiCecDefault::isWakeupMessage(cec_msg message) { int opcode = getOpcode(message); switch (opcode) { case CEC_MESSAGE_TEXT_VIEW_ON: Loading
tv/cec/1.0/default/HdmiCecDefault.h +25 −5 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ #include <android/hardware/tv/cec/1.0/IHdmiCec.h> #include <hardware/hdmi_cec.h> #include <linux/cec.h> #include <thread> namespace android { namespace hardware { Loading @@ -24,7 +26,10 @@ namespace cec { namespace V1_0 { namespace implementation { struct HdmiCecDefault : public IHdmiCec, public hidl_death_recipient { using std::thread; class HdmiCecDefault : public IHdmiCec, public hidl_death_recipient { public: HdmiCecDefault(); ~HdmiCecDefault(); // Methods from ::android::hardware::tv::cec::V1_0::IHdmiCec follow. Loading @@ -47,11 +52,26 @@ struct HdmiCecDefault : public IHdmiCec, public hidl_death_recipient { Return<Result> init(); Return<void> release(); static void* event_thread(void*); static int getOpcode(struct cec_msg message); static bool isWakeupMessage(struct cec_msg message); }; private: void event_thread(); static int getOpcode(cec_msg message); static bool isWakeupMessage(cec_msg message); thread mEventThread; // When set to false, all the CEC commands are discarded. True by default after initialization. bool mCecEnabled; /* * When set to false, HAL does not wake up the system upon receiving <Image View On> or * <Text View On>. True by default after initialization. */ bool mWakeupEnabled; sp<IHdmiCecCallback> mCallback; int mCecFd; int mExitFd; }; } // namespace implementation } // namespace V1_0 } // namespace cec Loading