1d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin/*
28089858bfb034e36d45172ff6a5437d7dce86cb7Steve Pfetsch *  Copyright (c) 2012-2014, 2016, The Linux Foundation. All rights reserved.
3d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin *
4d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * Redistribution and use in source and binary forms, with or without
5d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * modification, are permitted provided that the following conditions are
6d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * met:
7d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin *     * Redistributions of source code must retain the above copyright
8d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin *       notice, this list of conditions and the following disclaimer.
9d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin *     * Redistributions in binary form must reproduce the above
10d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin *       copyright notice, this list of conditions and the following
11d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin *       disclaimer in the documentation and/or other materials provided
12d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin *       with the distribution.
13d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin *     * Neither the name of The Linux Foundation nor the names of its
14d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin *       contributors may be used to endorse or promote products derived
15d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin *       from this software without specific prior written permission.
16d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin *
17d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin */
29d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
30d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <QService.h>
31d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <binder/Parcel.h>
32d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <binder/IPCThreadState.h>
33d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
34d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#define QSERVICE_DEBUG 0
35d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
36d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinusing namespace android;
37d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
38d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinnamespace qService {
39d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
40d68a2e45260f864503d7bd6da93fd29589afd89ePatrick TjinQService* QService::sQService = NULL;
41d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin// ----------------------------------------------------------------------------
42d68a2e45260f864503d7bd6da93fd29589afd89ePatrick TjinQService::QService()
43d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin{
44d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ALOGD_IF(QSERVICE_DEBUG, "QService Constructor invoked");
45d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
46d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
47d68a2e45260f864503d7bd6da93fd29589afd89ePatrick TjinQService::~QService()
48d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin{
49d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ALOGD_IF(QSERVICE_DEBUG,"QService Destructor invoked");
50d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
51d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
52d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinvoid QService::connect(const sp<qClient::IQClient>& client) {
53d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ALOGD_IF(QSERVICE_DEBUG,"HWC client connected");
54d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    mClient = client;
55d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
56d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
57d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinvoid QService::connect(const sp<qClient::IQHDMIClient>& client) {
588089858bfb034e36d45172ff6a5437d7dce86cb7Steve Pfetsch    ALOGD_IF(QSERVICE_DEBUG,"HDMI client connected");
59d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    mHDMIClient = client;
60d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
61d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
62d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinstatus_t QService::dispatch(uint32_t command, const Parcel* inParcel,
63d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        Parcel* outParcel) {
64d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    status_t err = (status_t) FAILED_TRANSACTION;
65d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    IPCThreadState* ipc = IPCThreadState::self();
66d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    //Rewind parcel in case we're calling from the same process
67d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    bool sameProcess = (ipc->getCallingPid() == getpid());
68d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if(sameProcess)
69d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        inParcel->setDataPosition(0);
70d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (mClient.get()) {
71d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ALOGD_IF(QSERVICE_DEBUG, "Dispatching command: %d", command);
72d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        err = mClient->notifyCallback(command, inParcel, outParcel);
73d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        //Rewind parcel in case we're calling from the same process
74d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        if (sameProcess)
75d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            outParcel->setDataPosition(0);
76d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
77d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return err;
78d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
79d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
80d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinvoid QService::onHdmiHotplug(int connected) {
81d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if(mHDMIClient.get()) {
82d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ALOGD_IF(QSERVICE_DEBUG, "%s: HDMI hotplug", __FUNCTION__);
83d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        mHDMIClient->onHdmiHotplug(connected);
84d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    } else {
858089858bfb034e36d45172ff6a5437d7dce86cb7Steve Pfetsch        ALOGW("%s: Failed to get a valid HDMI client", __FUNCTION__);
86d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
87d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
88d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
89d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinvoid QService::onCECMessageReceived(char *msg, ssize_t len) {
90d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if(mHDMIClient.get()) {
91d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ALOGD_IF(QSERVICE_DEBUG, "%s: CEC message received", __FUNCTION__);
92d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        mHDMIClient->onCECMessageRecieved(msg, len);
93d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    } else {
948089858bfb034e36d45172ff6a5437d7dce86cb7Steve Pfetsch        ALOGW("%s: Failed to get a valid HDMI client", __FUNCTION__);
95d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
96d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
97d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
98d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
99d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinvoid QService::init()
100d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin{
101d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if(!sQService) {
102d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        sQService = new QService();
103d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        sp<IServiceManager> sm = defaultServiceManager();
104d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        sm->addService(String16("display.qservice"), sQService);
105d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        if(sm->checkService(String16("display.qservice")) != NULL)
106d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ALOGD_IF(QSERVICE_DEBUG, "adding display.qservice succeeded");
107d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        else
108d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ALOGD_IF(QSERVICE_DEBUG, "adding display.qservice failed");
109d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
110d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
111d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
112d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
113