author | Tellen Yu <tellen.yu@amlogic.com> | 2017-11-08 02:13:18 (GMT) |
---|---|---|
committer | Gerrit Code Review <gituser@scgit.amlogic.com> | 2017-11-08 02:13:18 (GMT) |
commit | 9943e268dc4d47d9502a710fe9948fa702d0b59f (patch) | |
tree | 8d4e3491da7eabd8c813b94155e0b03e8db47cfc | |
parent | e8a55b271d8df784945faea90d7eac058af2da72 (diff) | |
parent | 59ddd46ea10c3abd736846eac6a24053e177e922 (diff) | |
download | frameworks-9943e268dc4d47d9502a710fe9948fa702d0b59f.zip frameworks-9943e268dc4d47d9502a710fe9948fa702d0b59f.tar.gz frameworks-9943e268dc4d47d9502a710fe9948fa702d0b59f.tar.bz2 |
Merge "hdmicec: need create server to client death recipient [2/4]" into o-amlogic
-rw-r--r-- | core/jni/hdmi_cec/HdmiCecExtend.cpp | 2 | ||||
-rw-r--r-- | services/hdmicec/binder/HdmiCecHidlClient.cpp | 27 | ||||
-rw-r--r-- | services/hdmicec/binder/HdmiCecHidlClient.h | 12 | ||||
-rw-r--r-- | services/hdmicec/libhdmi_cec/HdmiCecControl.cpp | 54 | ||||
-rw-r--r-- | services/hdmicec/server/DroidHdmiCec.cpp | 115 | ||||
-rw-r--r-- | services/hdmicec/server/DroidHdmiCec.h | 29 | ||||
-rw-r--r-- | services/systemcontrol/SystemControlHal.cpp | 50 | ||||
-rw-r--r-- | services/systemcontrol/SystemControlHal.h | 19 |
8 files changed, 247 insertions, 61 deletions
diff --git a/core/jni/hdmi_cec/HdmiCecExtend.cpp b/core/jni/hdmi_cec/HdmiCecExtend.cpp index fcf69d4..f1a5233 100644 --- a/core/jni/hdmi_cec/HdmiCecExtend.cpp +++ b/core/jni/hdmi_cec/HdmiCecExtend.cpp @@ -65,7 +65,7 @@ JHdmiCecExtend::JHdmiCecExtend(jobject callbacksObj) : //mHdmiCecClient = HdmiCecClient::connect(); //mHdmiCecClient->setEventObserver(this); - mHdmiCecHidlClient = HdmiCecHidlClient::connect(); + mHdmiCecHidlClient = HdmiCecHidlClient::connect(CONNECT_TYPE_EXTEND); mHdmiCecHidlClient->setEventObserver(this); } diff --git a/services/hdmicec/binder/HdmiCecHidlClient.cpp b/services/hdmicec/binder/HdmiCecHidlClient.cpp index cb488b4..e3a94f0 100644 --- a/services/hdmicec/binder/HdmiCecHidlClient.cpp +++ b/services/hdmicec/binder/HdmiCecHidlClient.cpp @@ -31,11 +31,11 @@ namespace android { Mutex HdmiCecHidlClient::mLock; -HdmiCecHidlClient::HdmiCecHidlClient() +HdmiCecHidlClient::HdmiCecHidlClient(cec_connect_type_t type): mType(type) { mHdmiCecService = getHdmiCecService(); mHdmiCecHidlCallback = new HdmiCecHidlCallback(this); - Return<void> ret = mHdmiCecService->setCallback(mHdmiCecHidlCallback); + Return<void> ret = mHdmiCecService->setCallback(mHdmiCecHidlCallback, static_cast<ConnectType>(type)); } HdmiCecHidlClient::~HdmiCecHidlClient() @@ -44,11 +44,20 @@ HdmiCecHidlClient::~HdmiCecHidlClient() delete mpPortInfo; } -HdmiCecHidlClient* HdmiCecHidlClient::connect() +HdmiCecHidlClient* HdmiCecHidlClient::connect(cec_connect_type_t type) { //sp<HdmiCecHidlClient> client = new HdmiCecHidlClient(); //return client; - return new HdmiCecHidlClient(); + return new HdmiCecHidlClient(type); +} + +void HdmiCecHidlClient::reconnect() +{ + ALOGI("hdmi cec client type:%d reconnect", mType); + mHdmiCecService.clear(); + //reconnect to server + mHdmiCecService = getHdmiCecService(); + mHdmiCecService->setCallback(mHdmiCecHidlCallback, static_cast<ConnectType>(mType)); } int HdmiCecHidlClient::openCecDevice() @@ -207,7 +216,7 @@ int HdmiCecHidlClient::sendMessage(const cec_message_t* message, bool isExtend) //change message from hwbinder data structure to needed data structure hidlMsg.initiator = static_cast<CecLogicalAddress>(message->initiator); hidlMsg.destination = static_cast<CecLogicalAddress>(message->destination); - + hidlMsg.body.resize(message->length); for (size_t i = 0; i < message->length; ++i) { hidlMsg.body[i] = message->body[i]; } @@ -303,11 +312,11 @@ Return<void> HdmiCecHidlClient::HdmiCecHidlCallback::notifyCallback(const CecEve void HdmiCecHidlClient::HdmiCecDaemonDeathRecipient::serviceDied(uint64_t cookie __unused, const ::android::wp<::android::hidl::base::V1_0::IBase>& who __unused) { - ALOGE("hdmi cec died."); + ALOGE("hdmi cec daemon died."); Mutex::Autolock _l(mLock); - cecClient->mHdmiCecService.clear(); - ALOGE("kill myself"); - kill(getpid(), SIGKILL); + + usleep(200*1000);//sleep 200ms + cecClient->reconnect(); } };//namespace android diff --git a/services/hdmicec/binder/HdmiCecHidlClient.h b/services/hdmicec/binder/HdmiCecHidlClient.h index f4908a1..4368b01 100644 --- a/services/hdmicec/binder/HdmiCecHidlClient.h +++ b/services/hdmicec/binder/HdmiCecHidlClient.h @@ -35,6 +35,7 @@ namespace android { using ::vendor::amlogic::hardware::hdmicec::V1_0::IDroidHdmiCEC; using ::vendor::amlogic::hardware::hdmicec::V1_0::IDroidHdmiCecCallback; +using ::vendor::amlogic::hardware::hdmicec::V1_0::ConnectType; using ::vendor::amlogic::hardware::hdmicec::V1_0::Result; using ::vendor::amlogic::hardware::hdmicec::V1_0::CecEvent; using ::vendor::amlogic::hardware::hdmicec::V1_0::HdmiPortInfo; @@ -48,12 +49,17 @@ using ::android::hardware::hidl_string; using ::android::hardware::Return; using ::android::hardware::Void; +typedef enum { + CONNECT_TYPE_HAL = 0, + CONNECT_TYPE_EXTEND = 1 +} cec_connect_type_t; + class HdmiCecHidlClient { public: - HdmiCecHidlClient(); + HdmiCecHidlClient(cec_connect_type_t type); virtual ~HdmiCecHidlClient(); - static HdmiCecHidlClient* connect(); + static HdmiCecHidlClient* connect(cec_connect_type_t type); virtual int openCecDevice(); virtual int closeCecDevice(); @@ -74,10 +80,12 @@ public: private: static Mutex mLock; + cec_connect_type_t mType; sp<IDroidHdmiCEC> mHdmiCecService; sp<HdmiCecEventListener> mEventListener; sp<IDroidHdmiCEC> getHdmiCecService(); + void reconnect(); class HdmiCecHidlCallback : public IDroidHdmiCecCallback { public: HdmiCecHidlCallback(HdmiCecHidlClient *client): cecClient(client) {}; diff --git a/services/hdmicec/libhdmi_cec/HdmiCecControl.cpp b/services/hdmicec/libhdmi_cec/HdmiCecControl.cpp index 9a6229e..0f33da7 100644 --- a/services/hdmicec/libhdmi_cec/HdmiCecControl.cpp +++ b/services/hdmicec/libhdmi_cec/HdmiCecControl.cpp @@ -34,7 +34,7 @@ namespace android { HdmiCecControl::HdmiCecControl() { - ALOGD("HdmiCecControl"); + ALOGD("[hcc] HdmiCecControl"); init(); } @@ -54,7 +54,7 @@ void HdmiCecControl::init() memset(value, 0, PROPERTY_VALUE_MAX); property_get("persist.sys.hdmi.keep_awake", value, "true"); mCecDevice.mExtendControl = (!strcmp(value, "false")) ? 1 : 0; - ALOGD("device_type: %d, ext_control: %d", mCecDevice.mDeviceType, mCecDevice.mExtendControl); + ALOGD("[hcc] device_type: %d, ext_control: %d", mCecDevice.mDeviceType, mCecDevice.mExtendControl); } /** @@ -70,7 +70,7 @@ int HdmiCecControl::closeCecDevice() close(mCecDevice.mFd); delete mCecDevice.mpPortData; - ALOGD("%s, cec has closed.", __FUNCTION__); + ALOGD("[hcc] %s, cec has closed.", __FUNCTION__); return 0; } @@ -92,7 +92,7 @@ int HdmiCecControl::openCecDevice() mCecDevice.isCecControlled = false; mCecDevice.mFd = open(CEC_FILE, O_RDWR); if (mCecDevice.mFd < 0) { - ALOGE("can't open device. fd < 0"); + ALOGE("[hcc] can't open device. fd < 0"); return -EINVAL; } int ret = ioctl(mCecDevice.mFd, CEC_IOC_SET_DEV_TYPE, mCecDevice.mDeviceType); @@ -111,7 +111,7 @@ void HdmiCecControl::getBootConnectStatus() int port, ret; ret = ioctl(mCecDevice.mFd, CEC_IOC_GET_PORT_NUM, &total); - ALOGD("total port:%d, ret:%d", total, ret); + ALOGD("[hcc] total port:%d, ret:%d", total, ret); if (ret < 0) return ; @@ -122,12 +122,12 @@ void HdmiCecControl::getBootConnectStatus() port = i + 1; ret = ioctl(mCecDevice.mFd, CEC_IOC_GET_CONNECT_STATUS, &port); if (ret) { - ALOGD("get port %d connected status failed, ret:%d", i, ret); + ALOGD("[hcc] get port %d connected status failed, ret:%d", i, ret); continue; } mCecDevice.mConnectStatus |= ((port ? 1 : 0) << i); } - ALOGD("mConnectStatus: %d", mCecDevice.mConnectStatus); + ALOGD("[hcc] mConnectStatus: %d", mCecDevice.mConnectStatus); } void* HdmiCecControl::__threadLoop(void *user) @@ -143,12 +143,12 @@ void HdmiCecControl::threadLoop() hdmi_cec_event_t event; int r = -1; - ALOGD("threadLoop start."); + //ALOGD("[hcc] threadLoop start."); while (mCecDevice.mFd < 0) { usleep(1000 * 1000); mCecDevice.mFd = open(CEC_FILE, O_RDWR); } - ALOGD("file open ok, fd = %d.", mCecDevice.mFd); + ALOGD("[hcc] file open ok, fd = %d.", mCecDevice.mFd); while (mCecDevice.mRun) { if (!mCecDevice.isCecEnabled) @@ -171,14 +171,14 @@ void HdmiCecControl::threadLoop() if (mCecDevice.mDeviceType == DEV_TYPE_PLAYBACK && msg_buf[1] == CEC_MESSAGE_SET_MENU_LANGUAGE && mCecDevice.mExtendControl) { - ALOGD("ignore menu language change for hdmi-tx."); + ALOGD("[hcc] ignore menu language change for hdmi-tx."); } else { if (mCecDevice.isCecControlled) { event.eventType |= HDMI_EVENT_CEC_MESSAGE; } } - ALOGD("mExtendControl = %d, mDeviceType = %d, isCecControlled = %d", + ALOGD("[hcc] mExtendControl = %d, mDeviceType = %d, isCecControlled = %d", mCecDevice.mExtendControl, mCecDevice.mDeviceType, mCecDevice.isCecControlled); /* call java method to process cec message for ext control */ if ((mCecDevice.mExtendControl == 0x03) @@ -190,7 +190,7 @@ void HdmiCecControl::threadLoop() mEventListener->onEventUpdate(&event); } } - ALOGE("thread end."); + //ALOGE("thread end."); mCecDevice.mExited = true; } @@ -205,12 +205,12 @@ void HdmiCecControl::checkConnectStatus() port = mCecDevice.mpPortData[i].port_id; ret = ioctl(mCecDevice.mFd, CEC_IOC_GET_CONNECT_STATUS, &port); if (ret) { - ALOGE("get port %d connected status failed, ret:%d\n", mCecDevice.mpPortData[i].port_id, ret); + ALOGE("[hcc] get port %d connected status failed, ret:%d\n", mCecDevice.mpPortData[i].port_id, ret); continue; } bit = prev_status & (1 << i); if (bit ^ ((port ? 1 : 0) << i)) {//connect status has changed - ALOGD("port:%d, connect status changed, now:%d, prev_status:%x\n", + ALOGD("[hcc] port:%d, connect status changed, now:%d, prev_status:%x\n", mCecDevice.mpPortData[i].port_id, port, prev_status); if (mEventListener != NULL && mCecDevice.isCecEnabled && mCecDevice.isCecControlled) { event.eventType = HDMI_EVENT_HOT_PLUG; @@ -220,7 +220,7 @@ void HdmiCecControl::checkConnectStatus() } prev_status &= ~(bit); prev_status |= ((port ? 1 : 0) << i); - ALOGD("now mask:%x\n", prev_status); + //ALOGD("[hcc] now mask:%x\n", prev_status); } } mCecDevice.mConnectStatus = prev_status; @@ -236,7 +236,7 @@ int HdmiCecControl::readMessage(unsigned char *buf, int msg_cnt) /* maybe blocked at driver */ ret = read(mCecDevice.mFd, buf, msg_cnt); if (ret < 0) { - ALOGE("read :%s failed, ret:%d\n", CEC_FILE, ret); + ALOGE("[hcc] read :%s failed, ret:%d\n", CEC_FILE, ret); return -1; } @@ -250,7 +250,7 @@ void HdmiCecControl::getPortInfos(hdmi_port_info_t* list[], int* total) ioctl(mCecDevice.mFd, CEC_IOC_GET_PORT_NUM, total); - ALOGD("total port:%d", *total); + ALOGD("[hcc] total port:%d", *total); if (*total > MAX_PORT) *total = MAX_PORT; @@ -258,7 +258,7 @@ void HdmiCecControl::getPortInfos(hdmi_port_info_t* list[], int* total) delete mCecDevice.mpPortData; mCecDevice.mpPortData = new hdmi_port_info[*total]; if (!mCecDevice.mpPortData) { - ALOGE("alloc port_data failed"); + ALOGE("[hcc] alloc port_data failed"); *total = 0; return; } @@ -266,7 +266,7 @@ void HdmiCecControl::getPortInfos(hdmi_port_info_t* list[], int* total) ioctl(mCecDevice.mFd, CEC_IOC_GET_PORT_INFO, mCecDevice.mpPortData); for (int i = 0; i < *total; i++) { - ALOGD("port %d, type:%s, id:%d, cec support:%d, arc support:%d, physical address:%x", + ALOGD("[hcc] port %d, type:%s, id:%d, cec support:%d, arc support:%d, physical address:%x", i, mCecDevice.mpPortData[i].type ? "output" : "input", mCecDevice.mpPortData[i].port_id, mCecDevice.mpPortData[i].cec_supported, @@ -295,7 +295,7 @@ int HdmiCecControl::addLogicalAddress(cec_logical_address_t address) mEventListener->onEventUpdate(&event); } } - ALOGD("addr:%x, bitmap:%x\n", address, mCecDevice.mAddrBitmap); + ALOGD("[hcc] addr:%x, bitmap:%x\n", address, mCecDevice.mAddrBitmap); return ioctl(mCecDevice.mFd, CEC_IOC_ADD_LOGICAL_ADDR, address); } @@ -346,7 +346,7 @@ void HdmiCecControl::setOption(int flag, int value) default: break; } - ALOGD("%s, flag:0x%x, value:0x%x, ret:%d, isCecControlled:%x", __FUNCTION__, flag, value, ret, mCecDevice.isCecControlled); + ALOGD("[hcc] %s, flag:0x%x, value:0x%x, ret:%d, isCecControlled:%x", __FUNCTION__, flag, value, ret, mCecDevice.isCecControlled); } void HdmiCecControl::setAudioReturnChannel(int port, bool flag) @@ -355,7 +355,7 @@ void HdmiCecControl::setAudioReturnChannel(int port, bool flag) return; int ret = ioctl(mCecDevice.mFd, CEC_IOC_SET_ARC_ENABLE, flag); - ALOGD("%s, port id:%d, flag:%x, ret:%d\n", __FUNCTION__, port, flag, ret); + ALOGD("[hcc] %s, port id:%d, flag:%x, ret:%d\n", __FUNCTION__, port, flag, ret); } bool HdmiCecControl::isConnected(int port) @@ -369,7 +369,7 @@ bool HdmiCecControl::isConnected(int port) ret = ioctl(mCecDevice.mFd, CEC_IOC_GET_CONNECT_STATUS, &status); if (ret) return false; - ALOGD("%s, port:%d, connected:%s", __FUNCTION__, port, status ? "yes" : "no"); + ALOGD("[hcc] %s, port:%d, connected:%s", __FUNCTION__, port, status ? "yes" : "no"); return status; } @@ -379,7 +379,7 @@ int HdmiCecControl::getVersion(int* version) return -1; int ret = ioctl(mCecDevice.mFd, CEC_IOC_GET_VERSION, version); - ALOGD("%s, version:%x, ret = %d", __FUNCTION__, *version, ret); + ALOGD("[hcc] %s, version:%x, ret = %d", __FUNCTION__, *version, ret); return ret; } @@ -389,7 +389,7 @@ int HdmiCecControl::getVendorId(uint32_t* vendorId) return -1; int ret = ioctl(mCecDevice.mFd, CEC_IOC_GET_VENDOR_ID, vendorId); - ALOGD("%s, vendorId: %x, ret = %d", __FUNCTION__, *vendorId, ret); + ALOGD("[hcc] %s, vendorId: %x, ret = %d", __FUNCTION__, *vendorId, ret); return ret; } @@ -399,7 +399,7 @@ int HdmiCecControl::getPhysicalAddress(uint16_t* addr) return -EINVAL; int ret = ioctl(mCecDevice.mFd, CEC_IOC_GET_PHYSICAL_ADDR, addr); - ALOGD("%s, physical addr: %x, ret = %d", __FUNCTION__, *addr, ret); + ALOGD("[hcc] %s, physical addr: %x, ret = %d", __FUNCTION__, *addr, ret); return ret; } @@ -409,7 +409,7 @@ int HdmiCecControl::sendMessage(const cec_message_t* message, bool isExtend) return -EINVAL; if (isExtend) { - ALOGD("isExtend = %d, mExtendControl = %d", isExtend, mCecDevice.mExtendControl); + ALOGD("[hcc] isExtend = %d, mExtendControl = %d", isExtend, mCecDevice.mExtendControl); return sendExtMessage(message); } /* don't send message if controlled by extend */ diff --git a/services/hdmicec/server/DroidHdmiCec.cpp b/services/hdmicec/server/DroidHdmiCec.cpp index 0760605..e438d20 100644 --- a/services/hdmicec/server/DroidHdmiCec.cpp +++ b/services/hdmicec/server/DroidHdmiCec.cpp @@ -23,6 +23,7 @@ #include <inttypes.h> #include <string> +#include <cutils/properties.h> #include "../binder/HdmiCecBase.h" #include "DroidHdmiCec.h" @@ -39,10 +40,12 @@ void DroidHdmiCec::instantiate() DroidHdmiCec *pcec = new DroidHdmiCec(); } -DroidHdmiCec::DroidHdmiCec() +DroidHdmiCec::DroidHdmiCec() : mDeathRecipient(new DeathRecipient(this)) { mHdmiCecControl = new HdmiCecControl(); mHdmiCecControl->setEventObserver(this); + + mDebug = property_get_bool("persist.hdmicec.debug", true); } DroidHdmiCec::~DroidHdmiCec() @@ -58,6 +61,10 @@ Return<void> DroidHdmiCec::openCecDevice(openCecDevice_cb _hidl_cb) } _hidl_cb(Result::SUCCESS, fd); + + if (mDebug) + ALOGI("openCecDevice fd: %d", fd); + return Void(); } @@ -66,6 +73,10 @@ Return<void> DroidHdmiCec::closeCecDevice() if (NULL != mHdmiCecControl) { mHdmiCecControl->closeCecDevice(); } + + if (mDebug) + ALOGI("closeCecDevice"); + return Void(); } @@ -75,6 +86,10 @@ Return<int32_t> DroidHdmiCec::getCecVersion() if (NULL != mHdmiCecControl) { return mHdmiCecControl->getVersion(&version); } + + if (mDebug) + ALOGI("getCecVersion version: %d", version); + return version; } @@ -84,6 +99,10 @@ Return<uint32_t> DroidHdmiCec::getVendorId() if (NULL != mHdmiCecControl) { return mHdmiCecControl->getVendorId(&vendorId); } + + if (mDebug) + ALOGI("getVendorId vendorId: %d", vendorId); + return vendorId; } @@ -138,13 +157,15 @@ Return<void> DroidHdmiCec::getPortInfo(getPortInfo_cb _hidl_cb) .arcSupported = legacyPorts[i].arc_supported != 0, .physicalAddress = legacyPorts[i].physical_address }; - /* - ALOGD("droidhdmicec port %d, type:%s, id:%d, cec support:%d, arc support:%d, physical address:%x", - i, (HDMI_OUTPUT==static_cast<hdmi_port_type_t>(portInfos[i].type)) ? "output" : "input", - portInfos[i].portId, - portInfos[i].cecSupported?1:0, - portInfos[i].arcSupported?1:0, - portInfos[i].physicalAddress);*/ + + if (mDebug) + ALOGD("droidhdmicec port %d, type:%s, id:%d, cec support:%d, arc support:%d, physical address:%x", + i, (HDMI_OUTPUT==static_cast<hdmi_port_type_t>(portInfos[i].type)) ? "output" : "input", + portInfos[i].portId, + portInfos[i].cecSupported?1:0, + portInfos[i].arcSupported?1:0, + portInfos[i].physicalAddress); + } _hidl_cb(portInfos); @@ -155,6 +176,9 @@ Return<void> DroidHdmiCec::getPortInfo(getPortInfo_cb _hidl_cb) Return<Result> DroidHdmiCec::addLogicalAddress(CecLogicalAddress addr) { + if (mDebug) + ALOGI("addLogicalAddress addr: %d", addr); + if (NULL != mHdmiCecControl) { mHdmiCecControl->addLogicalAddress(static_cast<cec_logical_address_t>(addr)); return Result::SUCCESS; @@ -164,6 +188,9 @@ Return<Result> DroidHdmiCec::addLogicalAddress(CecLogicalAddress addr) Return<void> DroidHdmiCec::clearLogicalAddress() { + if (mDebug) + ALOGI("clearLogicalAddress"); + if (NULL != mHdmiCecControl) { mHdmiCecControl->clearLogicaladdress(); } @@ -172,6 +199,9 @@ Return<void> DroidHdmiCec::clearLogicalAddress() Return<void> DroidHdmiCec::setOption(OptionKey key, bool value) { + if (mDebug) + ALOGI("setOption key: %d, value:%d", key, value?1:0); + if (NULL != mHdmiCecControl) { mHdmiCecControl->setOption((int)key, value); } @@ -180,6 +210,9 @@ Return<void> DroidHdmiCec::setOption(OptionKey key, bool value) Return<void> DroidHdmiCec::enableAudioReturnChannel(int32_t portId, bool enable) { + if (mDebug) + ALOGI("enableAudioReturnChannel portId: %d enable:%d", portId, enable?1:0); + if (NULL != mHdmiCecControl) { mHdmiCecControl->setAudioReturnChannel(portId, enable); } @@ -188,16 +221,37 @@ Return<void> DroidHdmiCec::enableAudioReturnChannel(int32_t portId, bool enable) Return<bool> DroidHdmiCec::isConnected(int32_t portId) { + if (mDebug) + ALOGI("isConnected portId: %d", portId); + if (NULL != mHdmiCecControl) { return mHdmiCecControl->isConnected(portId); } return false; } -Return<void> DroidHdmiCec::setCallback(const sp<IDroidHdmiCecCallback>& callback) +Return<void> DroidHdmiCec::setCallback(const sp<IDroidHdmiCecCallback>& callback, ConnectType type) { - if (callback != NULL) { - mClients.push_back(callback); + if ((int)type > (int)ConnectType::TYPE_TOTAL - 1) { + ALOGE("%s don't support type:%d", __FUNCTION__, (int)type); + return Void(); + } + + if (callback != nullptr) { + if (mClients[(int)type] != nullptr) { + ALOGW("%s this type:%s had a callback, cover it", __FUNCTION__, getConnectTypeStr(type)); + mClients[(int)type]->unlinkToDeath(mDeathRecipient); + } + + mClients[(int)type] = callback; + Return<bool> linkResult = callback->linkToDeath(mDeathRecipient, (int)type); + bool linkSuccess = linkResult.isOk() ? static_cast<bool>(linkResult) : false; + if (!linkSuccess) { + ALOGW("Couldn't link death recipient for type: %s", getConnectTypeStr(type)); + } + + if (mDebug) + ALOGI("%s this type:%s, client size:%d", __FUNCTION__, getConnectTypeStr(type), (int)mClients.size()); } return Void(); } @@ -218,20 +272,22 @@ void DroidHdmiCec::onEventUpdate(const hdmi_cec_event_t* event) else if (0 != event->eventType) { hidlEvent.cec.initiator = static_cast<CecLogicalAddress>(event->cec.initiator); hidlEvent.cec.destination = static_cast<CecLogicalAddress>(event->cec.destination); + hidlEvent.cec.body.resize(event->cec.length); for (size_t i = 0; i < event->cec.length; i++) { hidlEvent.cec.body[i] = event->cec.body[i]; } } int clientSize = mClients.size(); - ALOGV("%s, %s, client size:%d", __FUNCTION__, getEventType(event->eventType), clientSize); - for (int i = 0; i < clientSize; i++) { - mClients[i]->notifyCallback(hidlEvent); + if (mClients[i] != nullptr) { + ALOGI("%s, client index:%d, connect type:%s, event:%s", __FUNCTION__, i, getConnectTypeStr((ConnectType)i), getEventTypeStr(event->eventType)); + mClients[i]->notifyCallback(hidlEvent); + } } } -const char* DroidHdmiCec::getEventType(int eventType) +const char* DroidHdmiCec::getEventTypeStr(int eventType) { switch (eventType) { case HDMI_EVENT_CEC_MESSAGE: @@ -249,6 +305,35 @@ const char* DroidHdmiCec::getEventType(int eventType) } } +const char* DroidHdmiCec::getConnectTypeStr(ConnectType type) +{ + switch (type) { + case ConnectType::TYPE_HAL: + return "HAL"; + case ConnectType::TYPE_EXTEND: + return "EXTEND"; + default: + return "unknown type"; + } +} + +void DroidHdmiCec::handleServiceDeath(uint32_t type) { + ALOGI("hdmicec daemon client:%s died", getConnectTypeStr((ConnectType)type)); + mClients[type].clear(); +} + +DroidHdmiCec::DeathRecipient::DeathRecipient(sp<DroidHdmiCec> cec) + : mDroidHdmiCec(cec) {} + +void DroidHdmiCec::DeathRecipient::serviceDied( + uint64_t cookie, + const wp<::android::hidl::base::V1_0::IBase>& /*who*/) { + ALOGE("droid hdmi cec daemon a client died cookie:%d", (int)cookie); + + uint32_t type = static_cast<uint32_t>(cookie); + mDroidHdmiCec->handleServiceDeath(type); +} + } // namespace implementation } // namespace V1_0 } // namespace hdmicec diff --git a/services/hdmicec/server/DroidHdmiCec.h b/services/hdmicec/server/DroidHdmiCec.h index c060f6a..c2655a4 100644 --- a/services/hdmicec/server/DroidHdmiCec.h +++ b/services/hdmicec/server/DroidHdmiCec.h @@ -22,8 +22,10 @@ #ifndef ANDROID_DROIDLOGIC_HDMI_CEC_V1_0_H #define ANDROID_DROIDLOGIC_HDMI_CEC_V1_0_H +#include <binder/IBinder.h> #include <utils/Mutex.h> #include <vector> +#include <map> #include <HdmiCecControl.h> #include <vendor/amlogic/hardware/hdmicec/1.0/IDroidHdmiCEC.h> @@ -36,6 +38,7 @@ namespace implementation { using ::vendor::amlogic::hardware::hdmicec::V1_0::IDroidHdmiCEC; using ::vendor::amlogic::hardware::hdmicec::V1_0::IDroidHdmiCecCallback; +using ::vendor::amlogic::hardware::hdmicec::V1_0::ConnectType; using ::vendor::amlogic::hardware::hdmicec::V1_0::Result; using ::android::hardware::hidl_vec; using ::android::hardware::hidl_string; @@ -64,19 +67,39 @@ public: Return<void> enableAudioReturnChannel(int32_t portId, bool enable) override; Return<bool> isConnected(int32_t portId) override; - Return<void> setCallback(const sp<IDroidHdmiCecCallback>& callback) override; + Return<void> setCallback(const sp<IDroidHdmiCecCallback>& callback, ConnectType type) override; virtual void onEventUpdate(const hdmi_cec_event_t* event); static void instantiate(); private: - const char* getEventType(int eventType); + const char* getEventTypeStr(int eventType); + const char* getConnectTypeStr(ConnectType type); + // Handle the case where the callback registered for the given type dies + void handleServiceDeath(uint32_t type); + + bool mDebug = false; HdmiCecControl *mHdmiCecControl; - std::vector<sp<IDroidHdmiCecCallback>> mClients; + //std::vector<sp<IDroidHdmiCecCallback>> mClients; + std::map<uint32_t, sp<IDroidHdmiCecCallback>> mClients; mutable Mutex mLock; + + class DeathRecipient : public android::hardware::hidl_death_recipient { + public: + DeathRecipient(sp<DroidHdmiCec> cec); + + // hidl_death_recipient interface + virtual void serviceDied(uint64_t cookie, + const ::android::wp<::android::hidl::base::V1_0::IBase>& who) override; + + private: + sp<DroidHdmiCec> mDroidHdmiCec; + }; + + sp<DeathRecipient> mDeathRecipient; }; } // namespace implementation diff --git a/services/systemcontrol/SystemControlHal.cpp b/services/systemcontrol/SystemControlHal.cpp index 251517c..7416622 100644 --- a/services/systemcontrol/SystemControlHal.cpp +++ b/services/systemcontrol/SystemControlHal.cpp @@ -45,7 +45,8 @@ namespace V1_0 { namespace implementation { SystemControlHal::SystemControlHal(SystemControlService * control) - : mSysControl(control) { + : mSysControl(control), + mDeathRecipient(new DeathRecipient(this)) { control->setListener(this); } @@ -68,7 +69,10 @@ void SystemControlHal::onEvent(int event) { ALOGI("onEvent event:%d, client size:%d", event, clientSize); for (int i = 0; i < clientSize; i++) { - mClients[i]->notifyCallback(event); + if (mClients[i] != nullptr) { + ALOGI("%s, client cookie:%d notifyCallback", __FUNCTION__, i); + mClients[i]->notifyCallback(event); + } } } @@ -341,8 +345,31 @@ Return<void> SystemControlHal::resolveResolutionValue(const hidl_string& mode, r Return<void> SystemControlHal::setCallback(const sp<ISystemControlCallback>& callback) { if (callback != nullptr) { - mClients.push_back(callback); + int cookie = -1; + int clientSize = mClients.size(); + for (int i = 0; i < clientSize; i++) { + if (mClients[i] == nullptr) { + ALOGI("%s, client index:%d had died, this id give the new client", __FUNCTION__, i); + cookie = i; + mClients[i] = callback; + break; + } + } + + if (cookie < 0) { + cookie = clientSize; + mClients[clientSize] = callback; + } + + Return<bool> linkResult = callback->linkToDeath(mDeathRecipient, cookie); + bool linkSuccess = linkResult.isOk() ? static_cast<bool>(linkResult) : false; + if (!linkSuccess) { + ALOGW("Couldn't link death recipient for cookie: %d", cookie); + } + + ALOGI("%s cookie:%s, client size:%d", __FUNCTION__, cookie, (int)mClients.size()); } + return Void(); } @@ -407,6 +434,23 @@ Return<void> SystemControlHal::autoDetect3DForMbox() { } //3D end +void SystemControlHal::handleServiceDeath(uint32_t cookie) { + mClients[cookie]->unlinkToDeath(mDeathRecipient); + mClients[cookie].clear(); +} + +SystemControlHal::DeathRecipient::DeathRecipient(sp<SystemControlHal> sch) + : mSystemControlHal(sch) {} + +void SystemControlHal::DeathRecipient::serviceDied( + uint64_t cookie, + const wp<::android::hidl::base::V1_0::IBase>& /*who*/) { + ALOGE("systemcontrol daemon client died cookie:%d", (int)cookie); + + uint32_t type = static_cast<uint32_t>(cookie); + mSystemControlHal->handleServiceDeath(type); +} + } // namespace implementation } // namespace V1_0 } // namespace systemcontrol diff --git a/services/systemcontrol/SystemControlHal.h b/services/systemcontrol/SystemControlHal.h index b371bef..8c1afc9 100644 --- a/services/systemcontrol/SystemControlHal.h +++ b/services/systemcontrol/SystemControlHal.h @@ -101,8 +101,25 @@ struct SystemControlHal : public ISystemControl, public SystemControlNotify { virtual void onEvent(int event); private: + void handleServiceDeath(uint32_t cookie); + SystemControlService *mSysControl; - std::vector<sp<ISystemControlCallback>> mClients; + std::map<uint32_t, sp<ISystemControlCallback>> mClients; + + class DeathRecipient : public android::hardware::hidl_death_recipient { + public: + DeathRecipient(sp<SystemControlHal> sch); + + // hidl_death_recipient interface + virtual void serviceDied(uint64_t cookie, + const ::android::wp<::android::hidl::base::V1_0::IBase>& who) override; + + private: + sp<SystemControlHal> mSystemControlHal; + }; + + sp<DeathRecipient> mDeathRecipient; + }; } // namespace implementation |