2 * Copyright (c) 2000 - 2022 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.
24 #include "include/aul.h"
27 #include "log_private.hh"
31 constexpr const char AUL_DBUS_PATH[] = "/aul/dbus_handler";
32 constexpr const char AUL_DBUS_SIGNAL_INTERFACE[] = "org.tizen.aul.signal";
33 constexpr const char AUL_DBUS_APPDEAD_SIGNAL[] = "app_dead";
34 constexpr const char AUL_DBUS_APPLAUNCH_SIGNAL[] = "app_launch";
36 constexpr const char AUL_APP_STATUS_DBUS_PATH[] = "/Org/Tizen/Aul/AppStatus";
37 constexpr const char AUL_APP_STATUS_DBUS_SIGNAL_INTERFACE[] =
38 "org.tizen.aul.AppStatus";
39 constexpr const char AUL_APP_STATUS_DBUS_LAUNCH_REQUEST[] = "AppLaunch";
40 constexpr const char AUL_APP_STATUS_DBUS_RESUME_REQUEST[] = "AppResume";
41 constexpr const char AUL_APP_STATUS_DBUS_TERMINATE_REQUEST[] = "AppTerminate";
42 constexpr const char AUL_APP_STATUS_DBUS_STATUS_CHANGE[] = "AppStatusChange";
43 constexpr const char AUL_APP_STATUS_DBUS_GROUP[] = "AppGroup";
44 constexpr const char AUL_APP_STATUS_DBUS_TERMINATED[] = "AppTerminated";
46 constexpr const char SYSTEM_PATH_CORE[] = "/org/tizen/system";
47 constexpr const char SYSTEM_INTERFACE_CORE[] = "org.tizen.system.Booting";
48 constexpr const char SYSTEM_SIGNAL_BOOTING_DONE[] = "BootingDone";
50 constexpr const char SYSTEM_PATH_THERMAL[] = "/Org/Tizen/System/Thermal";
51 constexpr const char SYSTEM_INTERFACE_THERMAL[] = "org.tizen.system.thermal";
52 constexpr const char SYSTEM_SIGNAL_COOLDOWN_MODE_CHANGED[] =
53 "CoolDownModeChanged";
55 constexpr const char RESOURCED_BUS_NAME[] = "org.tizen.resourced";
56 constexpr const char RESOURCED_PROC_PATH[] = "/Org/Tizen/ResourceD/Process";
57 constexpr const char RESOURCED_PROC_INTERFACE[] = "org.tizen.resourced.process";
58 constexpr const char RESOURCED_PROC_STATUS_SIGNAL[] = "ProcStatus";
59 constexpr const char RESOURCED_PROC_METHOD[] = "ProcExclude";
64 Event(std::string object_path, std::string interface_name,
65 std::string signal_name)
66 : object_path_(std::move(object_path)),
67 interface_name_(std::move(interface_name)),
68 signal_name_(std::move(signal_name)) {
75 const std::string& GetObjectPath() const { return object_path_; }
77 const std::string& GetInterfaceName() const { return interface_name_; }
79 const std::string& GetSignalName() const { return signal_name_; }
81 virtual void Invoke(GVariant* parameters) {}
83 T GetCallback() const { return cb_; }
85 void* GetUserData() const { return user_data_; }
88 std::lock_guard<std::recursive_mutex> lock(GetMutex());
92 GError* err = nullptr;
93 conn_ = g_bus_get_sync(G_BUS_TYPE_SYSTEM, nullptr, &err);
94 if (conn_ == nullptr) {
95 _E("g_bus_get_sync() is failed. error(%s)", err ? err->message : "");
100 source_ = g_dbus_connection_signal_subscribe(
101 conn_, nullptr, interface_name_.c_str(), signal_name_.c_str(),
102 object_path_.c_str(), nullptr, G_DBUS_SIGNAL_FLAGS_NONE, DBusSignalCb,
105 _E("g_dbus_connection_signal_subscribe() is failed");
106 g_object_unref(conn_);
114 bool SetCallback(T cb, void* user_data) {
115 std::lock_guard<std::recursive_mutex> lock(GetMutex());
117 user_data_ = user_data;
119 if (cb_ == nullptr) {
129 std::lock_guard<std::recursive_mutex> lock(GetMutex());
133 g_dbus_connection_signal_unsubscribe(conn_, source_);
136 g_object_unref(conn_);
140 std::recursive_mutex& GetMutex() const {
144 static void DBusSignalCb(GDBusConnection* connection,
145 const gchar* sender_name, const gchar* object_path,
146 const gchar* interface_name, const gchar* signal_name,
147 GVariant* parameters, gpointer user_data) {
148 auto* event = static_cast<Event*>(user_data);
149 std::lock_guard<std::recursive_mutex> lock(event->GetMutex());
150 if (event->source_ != 0)
151 event->Invoke(parameters);
155 std::string object_path_;
156 std::string interface_name_;
157 std::string signal_name_;
158 std::remove_pointer_t<T>* cb_ = nullptr;
159 void* user_data_ = nullptr;
160 GDBusConnection* conn_ = nullptr;
162 mutable std::recursive_mutex mutex_;
165 class AppDeadEvent : public Event<aul_app_dead_event_cb> {
167 AppDeadEvent() : Event<aul_app_dead_event_cb>(AUL_DBUS_PATH,
168 AUL_DBUS_SIGNAL_INTERFACE, AUL_DBUS_APPDEAD_SIGNAL) {
171 void Invoke(GVariant* parameters) override {
173 g_variant_get(parameters, "(u)", &pid);
175 auto cb = GetCallback();
177 cb(static_cast<int>(pid), GetUserData());
181 class AppLaunchEvent : public Event<aul_app_launch_event_cb> {
183 AppLaunchEvent() : Event<aul_app_launch_event_cb>(AUL_DBUS_PATH,
184 AUL_DBUS_SIGNAL_INTERFACE, AUL_DBUS_APPLAUNCH_SIGNAL) {
187 void Invoke(GVariant* parameters) override {
190 g_variant_get(parameters, "(u&s)", &pid, &appid);
192 auto cb = GetCallback();
194 cb(static_cast<int>(pid), GetUserData());
198 class AppLaunchEvent2 : public Event<aul_app_launch_event_cb_v2> {
200 AppLaunchEvent2() : Event<aul_app_launch_event_cb_v2>(AUL_DBUS_PATH,
201 AUL_DBUS_SIGNAL_INTERFACE, AUL_DBUS_APPLAUNCH_SIGNAL) {
204 void Invoke(GVariant* parameters) override {
207 g_variant_get(parameters, "(u&s)", &pid, &appid);
209 auto cb = GetCallback();
211 cb(static_cast<int>(pid), appid, GetUserData());
215 class BootingDoneEvent : public Event<aul_booting_done_event_cb> {
217 BootingDoneEvent() : Event<aul_booting_done_event_cb>(SYSTEM_PATH_CORE,
218 SYSTEM_INTERFACE_CORE, SYSTEM_SIGNAL_BOOTING_DONE) {
221 void Invoke(GVariant* parameters) override {
222 auto cb = GetCallback();
224 cb(0, GetUserData());
228 class CooldownEvent : public Event<aul_cooldown_event_cb> {
230 CooldownEvent() : Event<aul_cooldown_event_cb>(SYSTEM_PATH_THERMAL,
231 SYSTEM_INTERFACE_THERMAL, SYSTEM_SIGNAL_COOLDOWN_MODE_CHANGED) {
234 void Invoke(GVariant* parameters) override {
235 gchar* cooldown_status;
236 g_variant_get(parameters, "(&s)", &cooldown_status);
238 auto cb = GetCallback();
240 cb(cooldown_status, GetUserData());
244 class AppStatusChangedEvent : public Event<aul_app_status_changed_cb> {
246 AppStatusChangedEvent()
247 : Event<aul_app_status_changed_cb>(RESOURCED_PROC_PATH,
248 RESOURCED_PROC_INTERFACE, RESOURCED_PROC_STATUS_SIGNAL) {
251 void Invoke(GVariant* parameters) override {
254 g_variant_get(parameters, "(ii)", &status, &pid);
256 auto cb = GetCallback();
258 cb(pid, status, GetUserData());
262 class AppSignalContext {
264 AppSignalContext() = default;
265 ~AppSignalContext() {
268 bool AppDeadEventSubscribe(aul_app_dead_event_cb cb, void* user_data) {
269 std::lock_guard<std::recursive_mutex> lock(mutex_);
270 if (app_dead_event_ == nullptr)
271 app_dead_event_ = std::make_unique<AppDeadEvent>();
273 return app_dead_event_->SetCallback(cb, user_data);
276 bool AppLaunchEventSubscribe(aul_app_launch_event_cb cb, void* user_data) {
277 std::lock_guard<std::recursive_mutex> lock(mutex_);
278 if (app_launch_event_ == nullptr)
279 app_launch_event_ = std::make_unique<AppLaunchEvent>();
281 return app_launch_event_->SetCallback(cb, user_data);
284 bool AppLaunchEvent2Subscribe(aul_app_launch_event_cb_v2 cb,
286 std::lock_guard<std::recursive_mutex> lock(mutex_);
287 if (app_launch_event2_ == nullptr)
288 app_launch_event2_ = std::make_unique<AppLaunchEvent2>();
290 return app_launch_event2_->SetCallback(cb, user_data);
293 bool BootingDoneEventSubscribe(aul_booting_done_event_cb cb,
295 std::lock_guard<std::recursive_mutex> lock(mutex_);
296 if (app_dead_event_ == nullptr)
297 app_dead_event_ = std::make_unique<AppDeadEvent>();
299 return booting_done_event_->SetCallback(cb, user_data);
302 bool CooldownEventSubscribe(aul_cooldown_event_cb cb, void* user_data) {
303 std::lock_guard<std::recursive_mutex> lock(mutex_);
304 if (cooldown_event_ == nullptr)
305 cooldown_event_ = std::make_unique<CooldownEvent>();
307 return cooldown_event_->SetCallback(cb, user_data);
310 bool AppStatusChangedEventSubscribe(aul_app_status_changed_cb cb,
312 std::lock_guard<std::recursive_mutex> lock(mutex_);
313 if (app_status_changed_event_ == nullptr)
314 app_status_changed_event_ = std::make_unique<AppStatusChangedEvent>();
316 return app_status_changed_event_->SetCallback(cb, user_data);
320 std::recursive_mutex mutex_;
321 std::unique_ptr<AppDeadEvent> app_dead_event_;
322 std::unique_ptr<AppLaunchEvent> app_launch_event_;
323 std::unique_ptr<AppLaunchEvent2> app_launch_event2_;
324 std::unique_ptr<BootingDoneEvent> booting_done_event_;
325 std::unique_ptr<CooldownEvent> cooldown_event_;
326 std::unique_ptr<AppStatusChangedEvent> app_status_changed_event_;
329 AppSignalContext context;
331 bool EmitSignal(const std::string& object_path,
332 const std::string& interface_name, const std::string& signal_name,
333 GVariant* parameters) {
334 GError* err = nullptr;
335 auto* conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, nullptr, &err);
336 if (conn == nullptr) {
337 _E("g_bus_get_sync() is failed. error(%s)", err ? err->message : "");
341 std::unique_ptr<GDBusConnection, decltype(g_object_unref)*> conn_auto(
342 conn, g_object_unref);
344 if (!g_dbus_connection_emit_signal(conn, nullptr, object_path.c_str(),
345 interface_name.c_str(), signal_name.c_str(), parameters, &err)) {
346 _E("g_dbus_connection_emit_signal() is failed. error(%s)",
347 err ? err->message : "");
352 if (!g_dbus_connection_flush_sync(conn, nullptr, &err)) {
353 _E("g_dbus_connection_flush_sync() is failed. error(%s)",
354 err ? err->message : "");
362 bool SendMessage(const std::string& name, const std::string& path,
363 const std::string& interface, const std::string& method, GVariant* body) {
364 GError* err = nullptr;
365 auto* conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, nullptr, &err);
366 if (conn == nullptr) {
367 _E("g_bus_get_sync() is failed. error(%s)", err ? err->message : "");
371 std::unique_ptr<GDBusConnection, decltype(g_object_unref)*> conn_auto(
372 conn, g_object_unref);
374 auto* msg = g_dbus_message_new_method_call(name.c_str(), path.c_str(),
375 interface.c_str(), method.c_str());
376 if (msg == nullptr) {
377 _E("g_dbus_message_new_method_call() is failed");
380 std::unique_ptr<GDBusMessage, decltype(g_object_unref)*> msg_auto(
381 msg, g_object_unref);
383 g_dbus_message_set_body(msg, body);
384 g_dbus_connection_send_message_with_reply(conn, msg,
385 G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, nullptr, nullptr,
386 [](GObject* source_object, GAsyncResult* res, gpointer user_data) {
387 auto* conn = static_cast<GDBusConnection*>(user_data);
389 GError* err = nullptr;
390 auto* reply = g_dbus_connection_send_message_with_reply_finish(conn,
392 if (reply == nullptr) {
393 _E("No reply. error(%s)", err ? err->message : "");
400 if (reply != nullptr)
401 g_object_unref(reply);
403 g_object_unref(conn);
405 _I("Result: %d", result);
413 extern "C" API int aul_listen_app_dead_signal(aul_app_dead_event_cb callback,
415 if (!context.AppDeadEventSubscribe(callback, user_data))
421 extern "C" API int aul_listen_app_launch_signal(
422 aul_app_launch_event_cb callback, void* user_data) {
423 if (!context.AppLaunchEventSubscribe(callback, user_data))
429 extern "C" API int aul_listen_app_launch_signal_v2(
430 aul_app_launch_event_cb_v2 callback, void* user_data) {
431 if (!context.AppLaunchEvent2Subscribe(callback, user_data))
437 extern "C" API int aul_listen_booting_done_signal(
438 aul_booting_done_event_cb callback, void* user_data) {
439 _W("DEPRECATION WARNING: %s() is deprecated "
440 "and will be remove from next release.", __FUNCTION__);
441 if (!context.BootingDoneEventSubscribe(callback, user_data))
447 extern "C" API int aul_listen_cooldown_signal(aul_cooldown_event_cb callback,
449 _W("DEPRECATION WARNING: %s() is deprecated "
450 "and will be remove from next release.", __FUNCTION__);
451 if (!context.CooldownEventSubscribe(callback, user_data))
457 extern "C" API int aul_listen_app_status_signal(
458 aul_app_status_changed_cb callback, void *user_data) {
459 if (!context.AppStatusChangedEventSubscribe(callback, user_data))
465 extern "C" API int aul_update_freezer_status(int pid, const char* type) {
466 if (pid <= 1 || type == nullptr) {
467 _E("Invalid parameter");
471 GVariant* body = g_variant_new("(si)", type, pid);
472 if (body == nullptr) {
477 if (!SendMessage(RESOURCED_BUS_NAME, RESOURCED_PROC_PATH,
478 RESOURCED_PROC_INTERFACE, RESOURCED_PROC_METHOD, body)) {
479 g_variant_unref(body);
486 extern "C" API int aul_send_app_launch_request_signal(int pid,
487 const char* appid, const char* pkgid, const char* type) {
488 if (pid <= 1 || appid == nullptr || pkgid == nullptr || type == nullptr) {
489 _E("Invalid parameter");
493 GVariant* parameters = g_variant_new("(isss)", pid, appid, pkgid, type);
494 if (parameters == nullptr) {
499 if (!EmitSignal(AUL_APP_STATUS_DBUS_PATH,
500 AUL_APP_STATUS_DBUS_SIGNAL_INTERFACE,
501 AUL_APP_STATUS_DBUS_LAUNCH_REQUEST, parameters)) {
502 g_variant_unref(parameters);
509 extern "C" API int aul_send_app_resume_request_signal(int pid,
510 const char* appid, const char* pkgid, const char* type) {
512 _E("Invalid parameter");
516 if (appid == nullptr)
518 if (pkgid == nullptr)
523 GVariant* parameters = g_variant_new("(isss)", pid, appid, pkgid, type);
524 if (parameters == nullptr) {
529 if (!EmitSignal(AUL_APP_STATUS_DBUS_PATH,
530 AUL_APP_STATUS_DBUS_SIGNAL_INTERFACE,
531 AUL_APP_STATUS_DBUS_RESUME_REQUEST, parameters)) {
532 g_variant_unref(parameters);
539 extern "C" API int aul_send_app_terminate_request_signal(int pid,
540 const char* appid, const char* pkgid, const char* type) {
542 _E("Invalid parameter");
546 if (appid == nullptr)
548 if (pkgid == nullptr)
553 GVariant* parameters = g_variant_new("(isss)", pid, appid, pkgid, type);
554 if (parameters == nullptr) {
559 if (!EmitSignal(AUL_APP_STATUS_DBUS_PATH,
560 AUL_APP_STATUS_DBUS_SIGNAL_INTERFACE,
561 AUL_APP_STATUS_DBUS_TERMINATE_REQUEST, parameters)) {
562 g_variant_unref(parameters);
569 extern "C" API int aul_send_app_status_change_signal(int pid,
570 const char* appid, const char* pkgid, const char* status,
572 if (pid <= 1 || status == nullptr) {
573 _E("Invalid parameter");
577 if (appid == nullptr)
579 if (pkgid == nullptr)
584 GVariant* parameters = g_variant_new("(issss)",
585 pid, appid, pkgid, status, type);
586 if (parameters == nullptr) {
591 if (!EmitSignal(AUL_APP_STATUS_DBUS_PATH,
592 AUL_APP_STATUS_DBUS_SIGNAL_INTERFACE,
593 AUL_APP_STATUS_DBUS_STATUS_CHANGE, parameters)) {
594 g_variant_unref(parameters);
601 extern "C" API int aul_send_app_terminated_signal(int pid) {
603 _E("Invalid parameter");
607 GVariant* parameters = g_variant_new("(i)", pid);
608 if (parameters == nullptr) {
613 if (!EmitSignal(AUL_APP_STATUS_DBUS_PATH,
614 AUL_APP_STATUS_DBUS_SIGNAL_INTERFACE,
615 AUL_APP_STATUS_DBUS_TERMINATED, parameters)) {
616 g_variant_unref(parameters);
623 extern "C" API int aul_send_app_group_signal(int owner_pid, int child_pid,
624 const char* child_pkgid) {
625 if (owner_pid <= 1 || child_pid <= 1) {
626 _E("Invalid parameter");
630 if (child_pkgid == nullptr)
633 GVariant* parameters = g_variant_new("(iis)",
634 owner_pid, child_pid, child_pkgid);
635 if (parameters == nullptr) {
640 if (!EmitSignal(AUL_APP_STATUS_DBUS_PATH,
641 AUL_APP_STATUS_DBUS_SIGNAL_INTERFACE,
642 AUL_APP_STATUS_DBUS_GROUP, parameters)) {
643 g_variant_unref(parameters);