/* * Copyright (C) 2014-present Amlogic, Inc. All rights reserved. * * All information contained herein is Amlogic confidential. * * This software is provided to you pursuant to Software License Agreement * (SLA) with Amlogic Inc ("Amlogic"). This software may be used * only in accordance with the terms of this agreement. * * Redistribution and use in source and binary forms, with or without * modification is strictly prohibited without prior written permission from * Amlogic. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE 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 #include "dbus_defines.h" #define LOG_MODULE_TAG "TV" #define LOG_CLASS_TAG "TvService" #include "CTv.h" #include "CTvLog.h" static CTv *gs_ctv = nullptr; // functions defined inside dbus_wrapper.cpp #include "dbus_api_wrapper.cpp" class TvObserver : public CTv::TvIObserver { public: TvObserver(sd_bus *bus) { m_bus = bus; } ~TvObserver() = default; private: void onTvEvent(CTvEvent &event) { int eventType = event.getEventType(); LOGD("%s: eventType: %d\n", __FUNCTION__, eventType); switch (eventType) { case CTvEvent::TV_EVENT_SIGNAL_DETECT: SendSignalForSignalDetectEvent(event); break; case CTvEvent::TV_EVENT_SOURCE_CONNECT: SendSignalForSourceConnectEvent(event); break; case CTvEvent::TV_EVENT_SIG_DV_ALLM: SendSignalForDvAllmEvent(event); break; case CTvEvent::TV_EVENT_SIG_CHG_VRR: SendSignalForVrrEvent(event); break; case CTvEvent::TV_EVENT_QMS: SendSignalForQmsEvent(event); break; case CTvEvent::TV_EVENT_PIP_SIGNAL_DETECT: SendSignalForPipSignalDetectEvent(event); break; default: LOGE("TvService: invalid event type!\n"); break; } return; } void SendSignalForSignalDetectEvent(CTvEvent &event) { sd_bus_message *msg = nullptr; int r = sd_bus_message_new_signal(m_bus, &msg, TV_SERVICE_DBUS_OBJECT, TV_SERVICE_DBUS_INTERFACE, TV_SERVICE_SIGNAL_SIGNAL_DETECTED); if (r >= 0) { TvEvent::SignalDetectEvent *signalDetectEvent = (TvEvent::SignalDetectEvent *)(&event); r = sd_bus_message_append( msg, "iiiiiu", signalDetectEvent->mSourceInput, signalDetectEvent->mFmt, signalDetectEvent->mTrans_fmt, signalDetectEvent->mStatus, signalDetectEvent->mDviFlag, signalDetectEvent->mhdr_info); if (r >= 0) r = sd_bus_send(m_bus, msg, NULL); if (r < 0) { LOGE("Failed to send signal on %s %s %d\n", TV_SERVICE_DBUS_OBJECT, TV_SERVICE_DBUS_INTERFACE, r); } } if (msg) sd_bus_message_unref(msg); } void SendSignalForSourceConnectEvent(CTvEvent &event) { sd_bus_message *msg = nullptr; int r = sd_bus_message_new_signal(m_bus, &msg, TV_SERVICE_DBUS_OBJECT, TV_SERVICE_DBUS_INTERFACE, TV_SERVICE_SIGNAL_SOURCE_CONNECTED); if (r >= 0) { TvEvent::SourceConnectEvent *sourceConnectEvent = (TvEvent::SourceConnectEvent *)(&event); r = sd_bus_message_append(msg, "ii", sourceConnectEvent->mSourceInput, sourceConnectEvent->connectionState); if (r >= 0) r = sd_bus_send(m_bus, msg, NULL); if (r < 0) { LOGE("Failed to send signal on %s %s %d\n", TV_SERVICE_DBUS_OBJECT, TV_SERVICE_DBUS_INTERFACE, r); } } if (msg) sd_bus_message_unref(msg); } void SendSignalForDvAllmEvent(CTvEvent &event) { sd_bus_message *msg = nullptr; int r = sd_bus_message_new_signal(m_bus, &msg, TV_SERVICE_DBUS_OBJECT, TV_SERVICE_DBUS_INTERFACE, TV_SERVICE_SIGNAL_DV_ALLM_CHANGED); if (r >= 0) { TvEvent::SignalDvAllmEvent *signalDvAllmEvent = (TvEvent::SignalDvAllmEvent *)(&event); r = sd_bus_message_append(msg, "iii", signalDvAllmEvent->allm_mode, signalDvAllmEvent->it_content, signalDvAllmEvent->cn_type); if (r >= 0) r = sd_bus_send(m_bus, msg, NULL); if (r < 0) { LOGE("Failed to send signal on %s %s %d\n", TV_SERVICE_DBUS_OBJECT, TV_SERVICE_DBUS_INTERFACE, r); } } if (msg) sd_bus_message_unref(msg); } void SendSignalForVrrEvent(CTvEvent &event) { sd_bus_message *msg = nullptr; int r = sd_bus_message_new_signal(m_bus, &msg, TV_SERVICE_DBUS_OBJECT, TV_SERVICE_DBUS_INTERFACE, TV_SERVICE_SIGNAL_VRR_CHANGED); if (r >= 0) { TvEvent::SignalVrrEvent *signalVrrEvent = (TvEvent::SignalVrrEvent *)(&event); r = sd_bus_message_append(msg, "i", signalVrrEvent->cur_vrr_status); if (r >= 0) r = sd_bus_send(m_bus, msg, NULL); if (r < 0) { LOGE("Failed to send signal on %s %s %d\n", TV_SERVICE_DBUS_OBJECT, TV_SERVICE_DBUS_INTERFACE, r); } } if (msg) sd_bus_message_unref(msg); } void SendSignalForQmsEvent(CTvEvent &event) { sd_bus_message *msg = nullptr; int r = sd_bus_message_new_signal(m_bus, &msg, TV_SERVICE_DBUS_OBJECT, TV_SERVICE_DBUS_INTERFACE, TV_SERVICE_SIGNAL_QMS_CHANGED); if (r >= 0) { TvEvent::QMSEvent *signalQmsEvent = (TvEvent::QMSEvent *)(&event); r = sd_bus_message_append(msg, "iii", signalQmsEvent->qms_en, signalQmsEvent->qms_fps, signalQmsEvent->qms_base_fps); if (r >= 0) r = sd_bus_send(m_bus, msg, NULL); if (r < 0) { LOGE("Failed to send signal on %s %s %d\n", TV_SERVICE_DBUS_OBJECT, TV_SERVICE_DBUS_INTERFACE, r); } } if (msg) sd_bus_message_unref(msg); } void SendSignalForPipSignalDetectEvent(CTvEvent &event) { sd_bus_message *msg = nullptr; int r = sd_bus_message_new_signal(m_bus, &msg, TV_SERVICE_DBUS_OBJECT, TV_SERVICE_DBUS_INTERFACE, TV_SERVICE_SIGNAL_PIP_SIGNAL_DETECTED); if (r >= 0) { TvEvent::PipSignalDetectEvent *pipDetectEvent = (TvEvent::PipSignalDetectEvent *)(&event); r = sd_bus_message_append( msg, "iiiiiu", pipDetectEvent->mSourceInput, pipDetectEvent->mFmt, pipDetectEvent->mTrans_fmt, pipDetectEvent->mStatus, pipDetectEvent->mDviFlag, pipDetectEvent->mhdr_info); if (r >= 0) r = sd_bus_send(m_bus, msg, NULL); if (r < 0) { LOGE("Failed to send signal on %s %s %d\n", TV_SERVICE_DBUS_OBJECT, TV_SERVICE_DBUS_INTERFACE, r); } } if (msg) sd_bus_message_unref(msg); } private: sd_bus *m_bus; }; int main() { sd_bus *bus = nullptr; sd_event *event = nullptr; init_tv_logging(); int r = sd_bus_default_system(&bus); if (r < 0) { LOGE("Failed to create bus: %s\n", strerror(-r)); goto cleanup; } r = sd_bus_add_object_vtable(bus, NULL, TV_SERVICE_DBUS_OBJECT, TV_SERVICE_DBUS_INTERFACE, tvservice_vtable, NULL); if (r < 0) { LOGE("Failed to add object vtable: %s\n", strerror(-r)); goto cleanup; } r = sd_bus_request_name(bus, TV_SERVICE_DBUS_SERVICE, 0LL); if (r < 0) { LOGE("Failed to request name: %s\n", strerror(-r)); goto cleanup; } r = sd_event_default(&event); if (r < 0) { LOGE("Failed to create event: %s\n", strerror(-r)); goto cleanup; } r = sd_bus_attach_event(bus, event, 0); if (r < 0) { LOGE("Failed to attach event: %s\n", strerror(-r)); goto cleanup; } gs_ctv = new CTv(); gs_ctv->setTvObserver(new TvObserver(bus)); sd_event_loop(event); cleanup: LOGE("TvService exit!\n"); if (gs_ctv) { delete gs_ctv; gs_ctv = nullptr; } if (event) { sd_event_exit(event, 0); sd_event_unref(event); event = nullptr; } if (bus) { sd_bus_unref(bus); bus = nullptr; } return 0; }