summaryrefslogtreecommitdiff
authorTellen Yu <tellen.yu@amlogic.com>2017-11-07 06:57:02 (GMT)
committer Tellen Yu <tellen.yu@amlogic.com>2017-11-07 11:13:05 (GMT)
commit59ddd46ea10c3abd736846eac6a24053e177e922 (patch)
tree49193362b6aa7089e82f32c6ee331f8850d85578
parent852e44b279edcbf7e0aa14c28853172e47bceaeb (diff)
downloadframeworks-59ddd46ea10c3abd736846eac6a24053e177e922.zip
frameworks-59ddd46ea10c3abd736846eac6a24053e177e922.tar.gz
frameworks-59ddd46ea10c3abd736846eac6a24053e177e922.tar.bz2
hdmicec: need create server to client death recipient [2/4]
PD# 152527 client to server need create server death recipient, if client set callback to server, need create server to client death recipient. Otherwise, when client died or restart, server still use the origin callback will crash. Change-Id: I36dfd67d43f9d0f148d3dd40dad5fecb06a94497
Diffstat
-rw-r--r--core/jni/hdmi_cec/HdmiCecExtend.cpp2
-rw-r--r--services/hdmicec/binder/HdmiCecHidlClient.cpp27
-rw-r--r--services/hdmicec/binder/HdmiCecHidlClient.h12
-rw-r--r--services/hdmicec/libhdmi_cec/HdmiCecControl.cpp54
-rw-r--r--services/hdmicec/server/DroidHdmiCec.cpp115
-rw-r--r--services/hdmicec/server/DroidHdmiCec.h29
-rw-r--r--services/systemcontrol/SystemControlHal.cpp50
-rw-r--r--services/systemcontrol/SystemControlHal.h19
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