Files
2026-08-24 10:03:24 +08:00

273 lines
8.8 KiB
C++

/*
* 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 <systemd/sd-bus.h>
#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;
}