tizen 2.3 release
[framework/appfw/aul-1.git] / src / app_signal.c
1 /*
2  *  aul
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22
23 #include <stdio.h>
24
25 #include "app_signal.h"
26 #include "aul_api.h"
27 #include "simple_util.h"
28 #include "aul.h"
29
30
31 static int (*_app_dead_handler) (int pid, void *data);
32 static void *_app_dead_data;
33
34 static int (*_app_launch_handler) (int pid, void *data);
35 static void *_app_launch_data;
36
37 static int (*_booting_done_handler) (int pid, void *data);
38 static void *_booting_done_data;
39
40 static int (*_status_handler) (int pid, int status, void *data);
41 static void *_status_data;
42
43 static int (*_cooldown_handler) (const char *cooldown_status, void *data);
44 static void *_cooldown_data;
45
46 #ifdef _APPFW_FEATURE_VISIBILITY_CHECK_BY_LCD_STATUS
47 static int (*_lcd_status_handler) (const char *lcd_status, void *data);
48 static void *_lcd_status_data;
49 #endif
50
51 static DBusConnection *bus;
52 static int app_dbus_signal_handler_initialized = 0;
53
54 static DBusHandlerResult
55 __app_dbus_signal_filter(DBusConnection *conn, DBusMessage *message,
56                        void *user_data)
57 {
58         const char *sender;
59         const char *interface;
60         const char *cooldown_status;
61         int pid;
62         int status;
63
64         DBusError error;
65         dbus_error_init(&error);
66
67         sender = dbus_message_get_sender(message);
68         if (sender == NULL)
69                 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
70
71         /*if (dbus_bus_get_unix_user(conn, sender, &error) != 0) {
72                 _E("reject by security issue - no allowed sender\n");
73                 dbus_error_free(&error);
74                 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
75         }*/
76
77         interface = dbus_message_get_interface(message);
78         if (interface == NULL) {
79                 _E("reject by security issue - no interface\n");
80                 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
81         }
82
83         if (dbus_message_is_signal(
84           message, interface, AUL_DBUS_APPDEAD_SIGNAL)) {
85                 if (dbus_message_get_args(message, &error, DBUS_TYPE_UINT32,
86                      &pid, DBUS_TYPE_INVALID) == FALSE) {
87                         _E("Failed to get data: %s", error.message);
88                         dbus_error_free(&error);
89                         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
90                 }
91                 if (_app_dead_handler)
92                         _app_dead_handler(pid, _app_dead_data);
93         } else if (dbus_message_is_signal(
94           message, interface, AUL_DBUS_APPLAUNCH_SIGNAL)) {
95                 if (dbus_message_get_args(message, &error, DBUS_TYPE_UINT32,
96                      &pid, DBUS_TYPE_INVALID) == FALSE) {
97                         _E("Failed to get data: %s", error.message);
98                         dbus_error_free(&error);
99                         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
100                 }
101                 if (_app_launch_handler)
102                         _app_launch_handler(pid, _app_launch_data);
103         } else if (dbus_message_is_signal(
104           message, interface, SYSTEM_SIGNAL_BOOTING_DONE)) {
105                 if (_booting_done_handler)
106                         _booting_done_handler(pid, _booting_done_data);
107         } else if (dbus_message_is_signal(
108           message, interface, RESOURCED_SIGNAL_PROCESS_STATUS)) {
109                 if (dbus_message_get_args(message, &error, DBUS_TYPE_INT32,&status,
110                         DBUS_TYPE_INT32,&pid, DBUS_TYPE_INVALID) == FALSE) {
111                         _E("Failed to get data: %s", error.message);
112                         dbus_error_free(&error);
113                         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
114                 }
115                 if (_status_handler)
116                         _status_handler(pid, status, _status_data);
117         } else if (dbus_message_is_signal(
118           message, interface, SYSTEM_SIGNAL_COOLDOWN_CHANGED)) {
119                 if (dbus_message_get_args(message, &error, DBUS_TYPE_STRING, &cooldown_status,
120                         DBUS_TYPE_INVALID) == FALSE) {
121                         _E("Failed to get data: %s", error.message);
122                         dbus_error_free(&error);
123                         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
124                 }
125                 if (_cooldown_handler)
126                         _cooldown_handler(cooldown_status, _cooldown_data);
127         }
128 #ifdef _APPFW_FEATURE_VISIBILITY_CHECK_BY_LCD_STATUS
129         else if (dbus_message_is_signal(
130           message, interface, DEVICED_SIGNAL_LCD_ON)) {
131                 if (_lcd_status_handler)
132                         _lcd_status_handler(DEVICED_SIGNAL_LCD_ON, _lcd_status_data);
133         } else if (dbus_message_is_signal(
134           message, interface, DEVICED_SIGNAL_LCD_OFF)) {
135                 if (_lcd_status_handler)
136                         _lcd_status_handler(DEVICED_SIGNAL_LCD_OFF, _lcd_status_data);
137         }
138 #endif
139
140         return DBUS_HANDLER_RESULT_HANDLED;
141 }
142
143 int __app_dbus_signal_handler_init(void)
144 {
145         int ret = 0;
146
147         if (app_dbus_signal_handler_initialized)
148                 return 0;
149
150         ret = __app_dbus_signal_handler_init_with_param(AUL_DBUS_PATH, AUL_DBUS_SIGNAL_INTERFACE);
151
152         app_dbus_signal_handler_initialized = 1;
153
154         return ret;
155 }
156
157 int __app_dbus_signal_handler_init_with_param(const char* path, const char* interface)
158 {
159         DBusError error;
160         char rule[MAX_LOCAL_BUFSZ];
161
162         dbus_error_init(&error);
163         bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
164         if (!bus) {
165                 _E("Failed to connect to the D-BUS daemon: %s", error.message);
166                 dbus_error_free(&error);
167                 return -1;
168         }
169         dbus_connection_setup_with_g_main(bus, NULL);
170
171         snprintf(rule, MAX_LOCAL_BUFSZ,
172                  "path='%s',type='signal',interface='%s'", path, interface);
173         /* listening to messages */
174         dbus_bus_add_match(bus, rule, &error);
175         if (dbus_error_is_set(&error)) {
176                 _E("Fail to rule set: %s", error.message);
177                 dbus_error_free(&error);
178                 return -1;
179         }
180
181         if (dbus_connection_add_filter(bus, 
182                 __app_dbus_signal_filter, NULL, NULL) == FALSE) {
183                 _E("add filter fail");
184                 return -1;
185         }
186
187         _D("app signal initialized");
188
189         return 0;
190 }
191
192 int __app_dbus_signal_handler_fini(void)
193 {
194         int ret = 0;
195
196         if (!app_dbus_signal_handler_initialized)
197                 return 0;
198
199         ret = __app_dbus_signal_handler_fini_with_param(AUL_DBUS_PATH, AUL_DBUS_SIGNAL_INTERFACE);
200
201         app_dbus_signal_handler_initialized = 0;
202
203         return ret;
204 }
205
206 int __app_dbus_signal_handler_fini_with_param(const char* path, const char* interface)
207 {
208         DBusError error;
209         char rule[MAX_LOCAL_BUFSZ];
210
211
212         dbus_error_init(&error);
213
214         dbus_connection_remove_filter(bus, __app_dbus_signal_filter, NULL);
215
216         snprintf(rule, MAX_LOCAL_BUFSZ,
217                  "path='%s',type='signal',interface='%s'", path, interface);
218         dbus_bus_remove_match(bus, rule, &error);
219         if (dbus_error_is_set(&error)) {
220                 _E("Fail to rule unset: %s", error.message);
221                 dbus_error_free(&error);
222                 return -1;
223         }
224
225         dbus_connection_close(bus);
226         dbus_connection_unref(bus);
227
228         _D("app signal finialized");
229
230         return 0;
231 }
232
233 SLPAPI int aul_listen_app_dead_signal(int (*func) (int, void *), void *data)
234 {
235         if (func) {
236                 if (__app_dbus_signal_handler_init() < 0) {
237                         _E("error app signal init");
238                         return AUL_R_ERROR;
239                 }
240         } else if (_app_launch_handler == NULL) {
241                 if (__app_dbus_signal_handler_fini() < 0) {
242                         _E("error app signal fini");
243                         return AUL_R_ERROR;
244                 }
245         }
246         _app_dead_handler = func;
247         _app_dead_data = data;
248
249         return AUL_R_OK;
250 }
251
252 SLPAPI int aul_listen_app_launch_signal(int (*func) (int, void *), void *data)
253 {
254         if (func) {
255                 if (__app_dbus_signal_handler_init() < 0) {
256                         _E("error app signal init");
257                         return AUL_R_ERROR;
258                 }
259         } else if (_app_dead_handler == NULL) {
260                 if (__app_dbus_signal_handler_fini() < 0) {
261                         _E("error app signal fini");
262                         return AUL_R_ERROR;
263                 }
264         }
265         _app_launch_handler = func;
266         _app_launch_data = data;
267
268         return AUL_R_OK;
269 }
270
271 SLPAPI int aul_listen_booting_done_signal(int (*func) (int, void *), void *data)
272 {
273         if (func) {
274                 if (__app_dbus_signal_handler_init_with_param(SYSTEM_PATH_CORE, SYSTEM_INTERFACE_CORE) < 0) {
275                         _E("error app signal init");
276                         return AUL_R_ERROR;
277                 }
278         } else if (_booting_done_handler == NULL) {
279                 if (__app_dbus_signal_handler_fini_with_param(SYSTEM_PATH_CORE, SYSTEM_INTERFACE_CORE) < 0) {
280                         _E("error app signal fini");
281                         return AUL_R_ERROR;
282                 }
283         }
284         _booting_done_handler = func;
285         _booting_done_data = data;
286
287         return AUL_R_OK;
288
289 }
290
291 SLPAPI int aul_listen_cooldown_signal(int (*func) (const char *, void *), void *data)
292 {
293         if (func) {
294                 if (__app_dbus_signal_handler_init_with_param(SYSTEM_PATH_SYSNOTI, SYSTEM_INTERFACE_SYSNOTI) < 0) {
295                         _E("error app signal init");
296                         return AUL_R_ERROR;
297                 }
298         } else if (_cooldown_handler == NULL) {
299                 if (__app_dbus_signal_handler_fini_with_param(SYSTEM_PATH_SYSNOTI, SYSTEM_INTERFACE_SYSNOTI) < 0) {
300                         _E("error app signal fini");
301                         return AUL_R_ERROR;
302                 }
303         }
304         _cooldown_handler = func;
305         _cooldown_data = data;
306
307         return AUL_R_OK;
308
309 }
310
311 SLPAPI int aul_listen_e17_status_signal(int (*func) (int, int, void *), void *data)
312 {
313         if (func) {
314                 if (__app_dbus_signal_handler_init_with_param(RESOURCED_PATH_CORE, RESOURCED_INTERFACE_CORE) < 0) {
315                         _E("error app signal init");
316                         return AUL_R_ERROR;
317                 }
318         }
319         _status_handler = func;
320         _status_data = data;
321
322         return AUL_R_OK;
323 }
324
325 #ifdef _APPFW_FEATURE_VISIBILITY_CHECK_BY_LCD_STATUS
326 SLPAPI int aul_listen_lcd_status_signal(int (*func) (const char *, void *), void *data)
327 {
328         if (func) {
329                 if (__app_dbus_signal_handler_init_with_param(DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY) < 0) {
330                         _E("error app signal init");
331                         return AUL_R_ERROR;
332                 }
333         }
334         _lcd_status_handler = func;
335         _lcd_status_data = data;
336
337         return AUL_R_OK;
338 }
339 #endif
340
341 SLPAPI int aul_update_freezer_status(int pid, const char* type)
342 {
343         DBusError err;
344         DBusConnection* conn = NULL;
345         DBusMessage* msg = NULL;
346         dbus_uint32_t serial = 0;
347
348         int ret = -1;
349
350         dbus_error_init(&err);
351
352         conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
353         if (!conn) {
354                 _E("Fail to dbus_bus_get : %s", err.message);
355                 return -1;
356         }
357
358         msg = dbus_message_new_signal(RESOURCED_PROC_OBJECT,
359                         RESOURCED_PROC_INTERFACE,
360                         RESOURCED_PROC_METHOD);
361         if (!msg) {
362                 _E("Could not create DBus Message.");
363                 ret = -1;
364                 goto end;
365         }
366
367         if (!dbus_message_append_args(msg,
368                         DBUS_TYPE_STRING, &type,
369                         DBUS_TYPE_INT32, &pid,
370                         DBUS_TYPE_INVALID)) {
371                 _E("Failed to append a D-Bus Message.");
372                 ret = -1;
373         }
374
375         _D("Send a freezer signal pid: %d, type: %s", pid, type);
376
377         if (!dbus_connection_send(conn, msg, &serial)) {
378                 _E("Failed to send a D-Bus Message.");
379                 ret = -1;
380         }
381
382         dbus_connection_flush(conn);
383
384 end:
385         dbus_error_free(&err);
386
387         if (msg) {
388                 dbus_message_unref(msg);
389         }
390
391         if (conn) {
392                 dbus_connection_unref(conn);
393         }
394
395         return ret;
396
397 }
398