2 * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include "launchpad-process-pool/dbus.hh"
27 #include <shared-queue.hpp>
29 #include "launchpad-process-pool/log_private.hh"
34 constexpr const uint32_t ERROR_THRESHOLD = 10;
35 constexpr const uint32_t ERROR_MODULO = 1000;
36 constexpr const uint32_t PENDING_ITEM_INTERVAL = 1000;
37 constexpr const char AUL_DBUS_PATH[] = "/aul/dbus_handler";
38 constexpr const char AUL_DBUS_SIGNAL_INTERFACE[] = "org.tizen.aul.signal";
39 constexpr const char AUL_DBUS_APPDEAD_SIGNAL[] = "app_dead";
40 constexpr const char AUL_DBUS_APPLAUNCH_SIGNAL[] = "app_launch";
44 DBusMessage(std::string path, std::string interface, std::string signal_name,
45 GVariant *param, std::string log_message)
46 : path_(std::move(path)), interface_(std::move(interface)),
47 signal_name_(std::move(signal_name)), param_(param),
48 log_message_(std::move(log_message)) {}
50 explicit DBusMessage(bool done) : done_(done) {}
53 if (param_ != nullptr)
54 g_variant_unref(param_);
57 const std::string& GetPath() const { return path_; }
59 const std::string& GetInterface() const { return interface_; }
61 const std::string& GetSignalName() const { return signal_name_; }
63 GVariant* RemoveParam() {
64 GVariant *param = param_;
69 bool IsDone() const { return done_; }
71 const std::string& GetLogMessage() const { return log_message_; }
76 std::string interface_;
77 std::string signal_name_;
78 GVariant *param_ = nullptr;
79 std::string log_message_;
84 DBusManager(const DBusManager&) = delete;
85 DBusManager& operator = (const DBusManager&) = delete;
86 DBusManager(DBusManager&&) = delete;
87 DBusManager& operator = (DBusManager&&) = delete;
89 static DBusManager& GetInst() {
90 static DBusManager inst;
98 if (getpid() == pid_) {
99 queue_->Push(std::make_shared<DBusMessage>(true));
102 if (conn_ != nullptr) {
103 g_object_unref(conn_);
115 void Send(std::shared_ptr<DBusMessage> message) {
116 queue_->Push(std::move(message));
123 queue_ = new tizen_base::SharedQueue<std::shared_ptr<DBusMessage>>();
124 thread_ = std::thread([&]() -> void { WorkerThread(); });
129 DBusManager() = default;
130 ~DBusManager() { Dispose(); }
132 GDBusConnection* GetConnection() {
136 GError* error = nullptr;
137 conn_ = g_bus_get_sync(G_BUS_TYPE_SYSTEM, nullptr, &error);
138 if (conn_ == nullptr) {
140 if (error_count_ < ERROR_THRESHOLD || error_count_ % ERROR_MODULO == 0) {
141 _E("g_bus_get_sync() is failed. error(%s)",
142 error ? error->message : "Unknown");
145 g_clear_error(&error);
152 void EmitSignal(std::shared_ptr<DBusMessage> args) {
153 GError* error = nullptr;
154 if (!g_dbus_connection_emit_signal(conn_, nullptr, args->GetPath().c_str(),
155 args->GetInterface().c_str(), args->GetSignalName().c_str(),
156 args->RemoveParam(), &error)) {
157 _E("g_dbus_connection_emit_signal() is failed. error(%s)",
158 error ? error->message : "Unknown");
159 g_clear_error(&error);
163 if (!g_dbus_connection_flush_sync(conn_, nullptr, &error)) {
164 _E("g_dbus_connection_flush_sync() is failed. error(%s)",
165 error ? error->message : "Unknown");
166 g_clear_error(&error);
170 _W("[DBUS] %s", args->GetLogMessage().c_str());
173 void WorkerThread() {
176 auto conn = GetConnection();
177 if (conn == nullptr) {
178 _W("Wait for dbus ready");
179 std::this_thread::sleep_for(
180 std::chrono::milliseconds(PENDING_ITEM_INTERVAL));
184 auto message = queue_->WaitAndPop();
185 if (message->IsDone())
194 bool disposed_ = true;
195 pid_t pid_ = getpid();
196 GDBusConnection* conn_ = nullptr;
197 uint32_t error_count_ = 0;
199 tizen_base::SharedQueue<std::shared_ptr<DBusMessage>>* queue_;
204 void DBus::SendAppLaunchSignal(pid_t pid, const std::string_view appid) {
205 DBusManager::GetInst().Send(
206 std::make_shared<DBusMessage>(
207 AUL_DBUS_PATH, AUL_DBUS_SIGNAL_INTERFACE, AUL_DBUS_APPLAUNCH_SIGNAL,
208 g_variant_new("(us)", pid, appid.data()),
209 "App Launch. " + std::to_string(pid) + ":" + std::string(appid)));
212 void DBus::SendAppDeadSignal(pid_t pid, int status) {
213 DBusManager::GetInst().Send(std::make_shared<DBusMessage>(
214 AUL_DBUS_PATH, AUL_DBUS_SIGNAL_INTERFACE, AUL_DBUS_APPDEAD_SIGNAL,
215 g_variant_new("(ii)", pid, status),
216 "App Dead. pid: " + std::to_string(pid) +
217 ", status: " + std::to_string(status)));
221 DBusManager::GetInst().Init();
224 void DBus::Finish() {
225 DBusManager::GetInst().Dispose();
228 } // namespace launchpad