2 * Copyright (c) 2020 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.
23 #include "launchpad_dbus.h"
24 #include "log_private.h"
26 #define AUL_DBUS_PATH "/aul/dbus_handler"
27 #define AUL_DBUS_SIGNAL_INTERFACE "org.tizen.aul.signal"
28 #define AUL_DBUS_APPDEAD_SIGNAL "app_dead"
29 #define AUL_DBUS_APPLAUNCH_SIGNAL "app_launch"
31 #define PENDING_ITEM_INTERVAL 1000
33 #define GET_CONNECTION_ERROR_THRESHOLD 10
34 #define GET_CONNECTION_ERROR_MODULO 1000
40 typedef struct pending_item_s {
43 app_signal_e app_signal;
46 static GList *__pending_items;
48 static GDBusConnection *__conn;
50 static void __set_pending_item_timer(void);
52 static void __destroy_pending_item(gpointer data)
54 pending_item_t *item = data;
60 static pending_item_t *__create_pending_item(const char *app_id,
61 int pid, app_signal_e app_signal)
65 item = calloc(1, sizeof(pending_item_t));
72 item->app_id = strdup(app_id);
74 _E("Failed to duplicate app ID(%s)", app_id);
75 __destroy_pending_item(item);
81 item->app_signal = app_signal;
86 static GDBusConnection *__get_connection(void)
89 static unsigned int error_count = 0;
94 __conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
97 if (error_count < GET_CONNECTION_ERROR_THRESHOLD ||
98 error_count % GET_CONNECTION_ERROR_MODULO == 0) {
99 _E("g_bus_get_sync() is failed. error(%s)",
100 error ? error->message : "Unknown");
103 g_clear_error(&error);
110 static int __emit_signal(const char *path,
111 const char *interface,
115 GDBusConnection *conn;
116 GError *error = NULL;
119 conn = __get_connection();
123 ret = g_dbus_connection_emit_signal(conn,
131 _E("g_dbus_connection_emit_signal() is failed. error(%s)",
132 error ? error->message : "Unknown");
133 g_clear_error(&error);
137 ret = g_dbus_connection_flush_sync(conn, NULL, &error);
139 _E("g_dbus_connection_flush_sync() is failed. error(%s)",
140 error ? error->message : "Unknown");
141 g_clear_error(&error);
148 static int __emit_app_launch_signal(int pid, const char *app_id)
152 ret = __emit_signal(AUL_DBUS_PATH,
153 AUL_DBUS_SIGNAL_INTERFACE,
154 AUL_DBUS_APPLAUNCH_SIGNAL,
155 g_variant_new("(us)", pid, app_id));
159 _D("App launch. pid(%d), app_id(%s)", pid, app_id);
164 static int __emit_app_dead_signal(int pid)
168 ret = __emit_signal(AUL_DBUS_PATH,
169 AUL_DBUS_SIGNAL_INTERFACE,
170 AUL_DBUS_APPDEAD_SIGNAL,
171 g_variant_new("(u)", pid));
175 _D("App dead. pid(%d)", pid);
180 static gboolean __flush_pending_item(gpointer data)
182 pending_item_t *item;
186 if (!__pending_items) {
188 return G_SOURCE_REMOVE;
191 iter = __pending_items;
193 item = (pending_item_t *)iter->data;
194 if (item->app_signal == APP_SIGNAL_DEAD)
195 ret = __emit_app_dead_signal(item->pid);
197 ret = __emit_app_launch_signal(item->pid, item->app_id);
200 return G_SOURCE_CONTINUE;
202 iter = g_list_next(iter);
203 __pending_items = g_list_remove(__pending_items, item);
204 __destroy_pending_item(item);
208 return G_SOURCE_REMOVE;
211 static void __set_pending_item_timer(void)
216 __timer = g_timeout_add(PENDING_ITEM_INTERVAL,
217 __flush_pending_item, NULL);
220 static void __unset_pending_item_timer(void)
225 g_source_remove(__timer);
229 int _dbus_send_app_launch_signal(int pid, const char *app_id)
231 pending_item_t *item;
234 if (pid <= 1 || !app_id) {
235 _E("Invalid parameter");
239 ret = __emit_app_launch_signal(pid, app_id);
241 item = __create_pending_item(app_id, pid, APP_SIGNAL_LAUNCH);
245 _W("Pend app launch signal. pid(%d), app_id(%s)", pid, app_id);
246 __pending_items = g_list_append(__pending_items, item);
247 __set_pending_item_timer();
253 int _dbus_send_app_dead_signal(int pid)
255 pending_item_t *item;
259 _E("Invalid parameter");
263 ret = __emit_app_dead_signal(pid);
265 item = __create_pending_item(NULL, pid, APP_SIGNAL_DEAD);
269 _W("Pend app dead signal. pid(%d)", pid);
270 __pending_items = g_list_append(__pending_items, item);
271 __set_pending_item_timer();
279 GDBusConnection *conn;
282 conn = __get_connection();
289 void _dbus_fini(void)
293 g_list_free_full(__pending_items, __destroy_pending_item);
295 __unset_pending_item_timer();
298 g_object_unref(__conn);