summaryrefslogtreecommitdiff
path: root/libqservice
diff options
context:
space:
mode:
authorNaseer Ahmed <naseer@codeaurora.org>2014-07-23 17:56:26 -0400
committerNaseer Ahmed <naseer@codeaurora.org>2015-03-02 14:54:49 -0500
commit7a7b66d1f03997b19ddc0b630dc36850c7826d97 (patch)
tree721f17316cc829a8009368ca5dc465c135a52a3c /libqservice
parent361b88f0c31d90b1966bc7371c2aee3e089185cb (diff)
downloaddisplay-7a7b66d1f03997b19ddc0b630dc36850c7826d97.tar.gz
display: Add HDMI CEC HAL
Implement the spec as per hardware/libhardware/include/hardware/hdmi_cec.h Change-Id: I02e1ba9deee1007b7e5922c363b9f5d6c6ad82a9
Diffstat (limited to 'libqservice')
-rw-r--r--libqservice/Android.mk3
-rw-r--r--libqservice/IQHDMIClient.cpp103
-rw-r--r--libqservice/IQHDMIClient.h57
-rw-r--r--libqservice/IQService.cpp29
-rw-r--r--libqservice/IQService.h11
-rw-r--r--libqservice/QService.cpp26
-rw-r--r--libqservice/QService.h4
7 files changed, 225 insertions, 8 deletions
diff --git a/libqservice/Android.mk b/libqservice/Android.mk
index 78b1d775..287e6ce8 100644
--- a/libqservice/Android.mk
+++ b/libqservice/Android.mk
@@ -10,7 +10,8 @@ LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdqservice\"
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
LOCAL_SRC_FILES := QService.cpp \
IQService.cpp \
- IQClient.cpp
+ IQClient.cpp \
+ IQHDMIClient.cpp
LOCAL_COPY_HEADERS_TO := $(common_header_export_path)
LOCAL_COPY_HEADERS := IQService.h \
IQClient.h
diff --git a/libqservice/IQHDMIClient.cpp b/libqservice/IQHDMIClient.cpp
new file mode 100644
index 00000000..9f5044a5
--- /dev/null
+++ b/libqservice/IQHDMIClient.cpp
@@ -0,0 +1,103 @@
+/*
+* Copyright (c) 2014 The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following
+* disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation. nor the names of its
+* contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#include <utils/Log.h>
+#include <binder/Parcel.h>
+#include "IQHDMIClient.h"
+
+using namespace android;
+namespace qClient {
+
+enum {
+ HDMI_CONNECTED = IBinder::FIRST_CALL_TRANSACTION,
+ CEC_MESSAGE_RECEIVED
+};
+
+class BpQHDMIClient : public BpInterface<IQHDMIClient>
+{
+public:
+ BpQHDMIClient(const sp<IBinder>& impl)
+ :BpInterface<IQHDMIClient>(impl)
+ {
+ }
+
+ void onHdmiHotplug(int connected)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IQHDMIClient::getInterfaceDescriptor());
+ data.writeInt32(connected);
+ remote()->transact(HDMI_CONNECTED, data, &reply, IBinder::FLAG_ONEWAY);
+ }
+
+ void onCECMessageRecieved(char *msg, ssize_t len)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IQHDMIClient::getInterfaceDescriptor());
+ data.writeInt32((int32_t)len);
+ void *buf = data.writeInplace(len);
+ if (buf != NULL)
+ memcpy(buf, msg, len);
+ remote()->transact(CEC_MESSAGE_RECEIVED, data, &reply,
+ IBinder::FLAG_ONEWAY);
+ }
+};
+
+IMPLEMENT_META_INTERFACE(QHDMIClient,
+ "android.display.IQHDMIClient");
+
+status_t BnQHDMIClient::onTransact(uint32_t code, const Parcel& data,
+ Parcel* reply, uint32_t flags)
+{
+ switch(code) {
+ case HDMI_CONNECTED: {
+ CHECK_INTERFACE(IQHDMIClient, data, reply);
+ int connected = data.readInt32();
+ onHdmiHotplug(connected);
+ return NO_ERROR;
+ }
+ case CEC_MESSAGE_RECEIVED: {
+ CHECK_INTERFACE(IQHDMIClient, data, reply);
+ ssize_t len = data.readInt32();
+ const void* msg;
+ if(len >= 0 && len <= (ssize_t) data.dataAvail()) {
+ msg = data.readInplace(len);
+ } else {
+ msg = NULL;
+ len = 0;
+ }
+ if (msg != NULL)
+ onCECMessageRecieved((char*) msg, len);
+ return NO_ERROR;
+ }
+ default: {
+ return BBinder::onTransact(code, data, reply, flags);
+ }
+ }
+}
+
+}; //namespace qClient
diff --git a/libqservice/IQHDMIClient.h b/libqservice/IQHDMIClient.h
new file mode 100644
index 00000000..c3d012a4
--- /dev/null
+++ b/libqservice/IQHDMIClient.h
@@ -0,0 +1,57 @@
+/*
+* Copyright (c) 2014 The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following
+* disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation. nor the names of its
+* contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef HDMI_EVENTS_LISTENER_H_
+#define HDMI_EVENTS_LISTENER_H_
+
+#include <utils/RefBase.h>
+#include <binder/IInterface.h>
+
+namespace qClient {
+
+class IQHDMIClient : public android::IInterface
+{
+public:
+ DECLARE_META_INTERFACE(QHDMIClient);
+ virtual void onHdmiHotplug(int connected) = 0;
+ virtual void onCECMessageRecieved(char *msg, ssize_t len) = 0;
+};
+
+class BnQHDMIClient : public android::BnInterface<IQHDMIClient>
+{
+public:
+ virtual android::status_t onTransact( uint32_t code,
+ const android::Parcel& data,
+ android::Parcel* reply, uint32_t flags = 0);
+};
+
+}; //namespace qhdmi
+
+#endif // HDMI_EVENTS_LISTENER_H_
+
diff --git a/libqservice/IQService.cpp b/libqservice/IQService.cpp
index eee22f08..5e67b15c 100644
--- a/libqservice/IQService.cpp
+++ b/libqservice/IQService.cpp
@@ -45,13 +45,22 @@ public:
: BpInterface<IQService>(impl) {}
virtual void connect(const sp<IQClient>& client) {
- ALOGD_IF(QSERVICE_DEBUG, "%s: connect client", __FUNCTION__);
+ ALOGD_IF(QSERVICE_DEBUG, "%s: connect HWC client", __FUNCTION__);
Parcel data, reply;
data.writeInterfaceToken(IQService::getInterfaceDescriptor());
data.writeStrongBinder(client->asBinder());
- remote()->transact(CONNECT, data, &reply);
+ remote()->transact(CONNECT_HWC_CLIENT, data, &reply);
}
+ virtual void connect(const sp<IQHDMIClient>& client) {
+ ALOGD_IF(QSERVICE_DEBUG, "%s: connect HDMI client", __FUNCTION__);
+ Parcel data, reply;
+ data.writeInterfaceToken(IQService::getInterfaceDescriptor());
+ data.writeStrongBinder(client->asBinder());
+ remote()->transact(CONNECT_HDMI_CLIENT, data, &reply);
+ }
+
+
virtual android::status_t dispatch(uint32_t command, const Parcel* inParcel,
Parcel* outParcel) {
ALOGD_IF(QSERVICE_DEBUG, "%s: dispatch in:%p", __FUNCTION__, inParcel);
@@ -90,10 +99,10 @@ status_t BnQService::onTransact(
callerUid == AID_ROOT ||
callerUid == AID_SYSTEM);
- if (code == CONNECT) {
+ if (code == CONNECT_HWC_CLIENT) {
CHECK_INTERFACE(IQService, data, reply);
if(callerUid != AID_GRAPHICS) {
- ALOGE("display.qservice CONNECT access denied: \
+ ALOGE("display.qservice CONNECT_HWC_CLIENT access denied: \
pid=%d uid=%d process=%s",
callerPid, callerUid, callingProcName);
return PERMISSION_DENIED;
@@ -102,6 +111,18 @@ status_t BnQService::onTransact(
interface_cast<IQClient>(data.readStrongBinder());
connect(client);
return NO_ERROR;
+ } else if(code == CONNECT_HDMI_CLIENT) {
+ CHECK_INTERFACE(IQService, data, reply);
+ if(callerUid != AID_SYSTEM && callerUid != AID_ROOT) {
+ ALOGE("display.qservice CONNECT_HDMI_CLIENT access denied: \
+ pid=%d uid=%d process=%s",
+ callerPid, callerUid, callingProcName);
+ return PERMISSION_DENIED;
+ }
+ sp<IQHDMIClient> client =
+ interface_cast<IQHDMIClient>(data.readStrongBinder());
+ connect(client);
+ return NO_ERROR;
} else if (code > COMMAND_LIST_START && code < COMMAND_LIST_END) {
if(!permission) {
ALOGE("display.qservice access denied: command=%d\
diff --git a/libqservice/IQService.h b/libqservice/IQService.h
index 796e506e..78cbd2ae 100644
--- a/libqservice/IQService.h
+++ b/libqservice/IQService.h
@@ -28,6 +28,7 @@
#include <binder/IInterface.h>
#include <binder/IBinder.h>
#include <IQClient.h>
+#include <IQHDMIClient.h>
namespace qService {
@@ -41,7 +42,7 @@ public:
COMMAND_LIST_START = android::IBinder::FIRST_CALL_TRANSACTION,
SECURING = 2, // Hardware securing start/end notification
UNSECURING = 3, // Hardware unsecuring start/end notification
- CONNECT = 4, // Connect to qservice
+ CONNECT_HWC_CLIENT = 4, // Connect to qservice
SCREEN_REFRESH = 5, // Refresh screen through SF invalidate
EXTERNAL_ORIENTATION = 6,// Set external orientation
BUFFER_MIRRORMODE = 7, // Buffer mirrormode
@@ -61,6 +62,7 @@ public:
TOGGLE_SCREEN_UPDATE = 20, // Provides ability to disable screen updates
SET_FRAME_DUMP_CONFIG = 21, // Provides ability to set the frame dump config
SET_S3D_MODE = 22, // Set the 3D mode as specified in msm_hdmi_modes.h
+ CONNECT_HDMI_CLIENT = 23, // Connect HDMI CEC HAL Client
COMMAND_LIST_END = 400,
};
@@ -85,8 +87,13 @@ public:
DUMP_VIRTUAL_DISPLAY,
};
- // Register a client that can be notified
+ // Register a HWC client that can be notified
+ // This client is generic and is intended to get
+ // dispatches of all events calling into QService
virtual void connect(const android::sp<qClient::IQClient>& client) = 0;
+ // Register an HDMI client. This client gets notification of HDMI events
+ // such as plug/unplug and CEC messages
+ virtual void connect(const android::sp<qClient::IQHDMIClient>& client) = 0;
// Generic function to dispatch binder commands
// The type of command decides how the data is parceled
virtual android::status_t dispatch(uint32_t command,
diff --git a/libqservice/QService.cpp b/libqservice/QService.cpp
index 12dd9956..52766953 100644
--- a/libqservice/QService.cpp
+++ b/libqservice/QService.cpp
@@ -50,10 +50,15 @@ QService::~QService()
}
void QService::connect(const sp<qClient::IQClient>& client) {
- ALOGD_IF(QSERVICE_DEBUG,"client connected");
+ ALOGD_IF(QSERVICE_DEBUG,"HWC client connected");
mClient = client;
}
+void QService::connect(const sp<qClient::IQHDMIClient>& client) {
+ ALOGD_IF(QSERVICE_DEBUG,"HWC client connected");
+ mHDMIClient = client;
+}
+
status_t QService::dispatch(uint32_t command, const Parcel* inParcel,
Parcel* outParcel) {
status_t err = (status_t) FAILED_TRANSACTION;
@@ -68,6 +73,25 @@ status_t QService::dispatch(uint32_t command, const Parcel* inParcel,
return err;
}
+void QService::onHdmiHotplug(int connected) {
+ if(mHDMIClient.get()) {
+ ALOGD_IF(QSERVICE_DEBUG, "%s: HDMI hotplug", __FUNCTION__);
+ mHDMIClient->onHdmiHotplug(connected);
+ } else {
+ ALOGE("%s: Failed to get a valid HDMI client", __FUNCTION__);
+ }
+}
+
+void QService::onCECMessageReceived(char *msg, ssize_t len) {
+ if(mHDMIClient.get()) {
+ ALOGD_IF(QSERVICE_DEBUG, "%s: CEC message received", __FUNCTION__);
+ mHDMIClient->onCECMessageRecieved(msg, len);
+ } else {
+ ALOGE("%s: Failed to get a valid HDMI client", __FUNCTION__);
+ }
+}
+
+
void QService::init()
{
if(!sQService) {
diff --git a/libqservice/QService.h b/libqservice/QService.h
index a8e4cdba..719c9b7c 100644
--- a/libqservice/QService.h
+++ b/libqservice/QService.h
@@ -46,13 +46,17 @@ class QService : public BnQService {
public:
virtual ~QService();
virtual void connect(const android::sp<qClient::IQClient>& client);
+ virtual void connect(const android::sp<qClient::IQHDMIClient>& client);
virtual android::status_t dispatch(uint32_t command,
const android::Parcel* data,
android::Parcel* reply);
+ void onHdmiHotplug(int connected);
+ void onCECMessageReceived(char *msg, ssize_t len);
static void init();
private:
QService();
android::sp<qClient::IQClient> mClient;
+ android::sp<qClient::IQHDMIClient> mHDMIClient;
static QService *sQService;
};
}; // namespace qService