bda7d09b2922556b3eb62a9cb3520faa42831c76
[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 #include "app_signal.h"
25 #include "aul_api.h"
26 #include "simple_util.h"
27
28 static int (*_app_dead_handler) (int pid, void *data);
29 static void *_app_dead_data;
30
31 static DBusConnection *bus;
32 static int app_dbus_signal_handler_initialized = 0;
33
34 static DBusHandlerResult
35 __app_dbus_signal_filter(DBusConnection *conn, DBusMessage *message,
36                        void *user_data)
37 {
38         const char *sender;
39         const char *interface;
40         int dead_pid;
41
42         DBusError error;
43         dbus_error_init(&error);
44
45         sender = dbus_message_get_sender(message);
46         if (sender == NULL)
47                 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
48
49         if (dbus_bus_get_unix_user(conn, sender, &error) != 0) {
50                 _E("reject by security issue - no allowed sender\n");
51                 dbus_error_free(&error);
52                 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
53         }
54
55         interface = dbus_message_get_interface(message);
56         if (interface == NULL) {
57                 _E("reject by security issue - no interface\n");
58                 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
59         }
60
61         if (dbus_message_is_signal(
62           message, interface, AUL_DBUS_APPDEAD_SIGNAL)) {
63                 if (dbus_message_get_args(message, &error, DBUS_TYPE_UINT32,
64                      &dead_pid, DBUS_TYPE_INVALID) == FALSE) {
65                         _E("Failed to get data: %s", error.message);
66                         dbus_error_free(&error);
67                         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
68                 }
69                 if (_app_dead_handler)
70                         _app_dead_handler(dead_pid, _app_dead_data);
71         }
72
73         return DBUS_HANDLER_RESULT_HANDLED;
74 }
75
76 int __app_dbus_signal_handler_init()
77 {
78         DBusError error;
79         char rule[MAX_LOCAL_BUFSZ];
80
81         if (app_dbus_signal_handler_initialized)
82                 return 0;
83
84         dbus_error_init(&error);
85         bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
86         if (!bus) {
87                 _E("Failed to connect to the D-BUS daemon: %s", error.message);
88                 dbus_error_free(&error);
89                 return -1;
90         }
91         dbus_connection_setup_with_g_main(bus, NULL);
92
93         snprintf(rule, MAX_LOCAL_BUFSZ,
94                  "path='%s',type='signal',interface='%s'", AUL_DBUS_PATH,
95                  AUL_DBUS_SIGNAL_INTERFACE);
96         /* listening to messages */
97         dbus_bus_add_match(bus, rule, &error);
98         if (dbus_error_is_set(&error)) {
99                 _E("Fail to rule set: %s", error.message);
100                 dbus_error_free(&error);
101                 return -1;
102         }
103
104         if (dbus_connection_add_filter(bus, 
105                 __app_dbus_signal_filter, NULL, NULL) == FALSE)
106                 return -1;
107
108         app_dbus_signal_handler_initialized = 1;
109
110         _D("app signal initialized");
111
112         return 0;
113 }
114
115 int __app_dbus_signal_handler_fini()
116 {
117         DBusError error;
118         char rule[MAX_LOCAL_BUFSZ];
119
120         if (!app_dbus_signal_handler_initialized)
121                 return 0;
122
123         dbus_error_init(&error);
124
125         dbus_connection_remove_filter(bus, __app_dbus_signal_filter, NULL);
126
127         snprintf(rule, MAX_LOCAL_BUFSZ,
128                  "path='%s',type='signal',interface='%s'", AUL_DBUS_PATH,
129                  AUL_DBUS_SIGNAL_INTERFACE);
130         dbus_bus_remove_match(bus, rule, &error);
131         if (dbus_error_is_set(&error)) {
132                 _E("Fail to rule unset: %s", error.message);
133                 dbus_error_free(&error);
134                 return -1;
135         }
136
137         dbus_connection_close(bus);
138
139         app_dbus_signal_handler_initialized = 0;
140
141         _D("app signal finialized");
142
143         return 0;
144 }
145
146 SLPAPI int aul_listen_app_dead_signal(int (*func) (int, void *), void *data)
147 {
148         if (func) {
149                 if (__app_dbus_signal_handler_init() < 0) {
150                         _E("error app signal init");
151                         return -1;
152                 }
153         } else {
154                 if (__app_dbus_signal_handler_fini() < 0) {
155                         _E("error app signal fini");
156                         return -1;
157                 }
158         }
159         _app_dead_handler = func;
160         _app_dead_data = data;
161
162         return 0;
163 }
164