tizen 2.3.1 release
[apps/home/minicontrol.git] / src / minicontrol-internal.c
1 /*
2  * Copyright (c)  2013-2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #include <stdlib.h>
18 #include <unistd.h>
19 #include <dbus/dbus.h>
20 #include <dbus/dbus-glib-lowlevel.h>
21
22 #include "minicontrol-error.h"
23 #include "minicontrol-type.h"
24 #include "minicontrol-internal.h"
25 #include "minicontrol-log.h"
26 #include "minicontrol-handler.h"
27
28 #define MINICTRL_DBUS_PATH "/org/tizen/minicontrol"
29 #define MINICTRL_DBUS_INTERFACE "org.tizen.minicontrol.signal"
30
31 #define PROC_DBUS_OBJECT        "/Org/Tizen/ResourceD/Process"
32 #define PROC_DBUS_INTERFACE     "org.tizen.resourced.process"
33 #define PROC_DBUS_METHOD        "ProcExclude"
34 #define PROC_DBUS_EXCLUDE       "exclude"
35 #define PROC_DBUS_INCLUDE       "include"
36
37 struct _minictrl_sig_handle {
38         DBusConnection *conn;
39         void (*callback) (void *data, DBusMessage *msg);
40         void *user_data;
41         char *signal;
42 };
43
44 int _minictrl_viewer_req_message_send(void)
45 {
46         DBusConnection *connection = NULL;
47         DBusMessage *message = NULL;
48         DBusError err;
49         dbus_bool_t dbus_ret;
50         int ret = MINICONTROL_ERROR_NONE;
51
52         dbus_error_init(&err);
53         connection = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
54         if (!connection) {
55                 ERR("Fail to dbus_bus_get : %s", err.message);
56                 ret = MINICONTROL_ERROR_DBUS;
57                 goto release_n_return;
58         }
59
60         message = dbus_message_new_signal(MINICTRL_DBUS_PATH,
61                                 MINICTRL_DBUS_INTERFACE,
62                                 MINICTRL_DBUS_SIG_RUNNING_REQ);
63         if (!message) {
64                 ERR("fail to create dbus message");
65                 ret = MINICONTROL_ERROR_OUT_OF_MEMORY;
66                 goto release_n_return;
67         }
68
69         dbus_ret = dbus_connection_send(connection, message, NULL);
70         if (!dbus_ret) {
71                 ERR("fail to send dbus viewer req message");
72                 ret = MINICONTROL_ERROR_DBUS;
73                 goto release_n_return;
74         }
75
76         dbus_connection_flush(connection);
77
78 release_n_return:
79         dbus_error_free(&err);
80
81         if (message)
82                 dbus_message_unref(message);
83
84         if (connection)
85                 dbus_connection_unref(connection);
86
87         return ret;
88 }
89
90 int _minictrl_provider_proc_send(int type)
91 {
92         DBusError err;
93         DBusConnection* conn = NULL;
94         DBusMessage* msg = NULL;
95         int ret = -1;
96         int pid = getpid();
97         dbus_uint32_t serial = 0;
98         char *typestr;
99         if (type == MINICONTROL_DBUS_PROC_EXCLUDE)
100                 typestr = PROC_DBUS_EXCLUDE;
101         else if  (type == MINICONTROL_DBUS_PROC_INCLUDE)
102                 typestr = PROC_DBUS_INCLUDE;
103         else {
104                 ERR("Check unsupported type : %d", type);
105                 return ret;
106         }
107         DBG("_minictrl_provider_proc_send : %d, %d", pid, type);
108         dbus_error_init(&err);
109         conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
110         if (!conn) {
111                 ERR("Fail to dbus_bus_get : %s", err.message);
112                 ret = MINICONTROL_ERROR_DBUS;
113                 goto release_n_return;
114         }
115         msg = dbus_message_new_signal(PROC_DBUS_OBJECT, // object name of the signal
116                             PROC_DBUS_INTERFACE, // interface name of the signal
117                             PROC_DBUS_METHOD); // name of the signal
118         if (!msg) {
119                 ERR("ERR Could not create DBus Message");
120                 goto release_n_return;
121         }
122         ret = dbus_message_append_args(msg,
123                             DBUS_TYPE_STRING, &typestr,
124                             DBUS_TYPE_INT32, &pid,
125                             DBUS_TYPE_INVALID);
126         if (!dbus_connection_send(conn, msg, &serial))
127                 ERR("ERR send DBus Message");
128         dbus_connection_flush(conn);
129 release_n_return:
130         dbus_error_free(&err);
131
132         if (msg)
133                 dbus_message_unref(msg);
134
135         if (conn)
136                 dbus_connection_unref(conn);
137
138         return ret;
139
140 }
141
142 int _minictrl_provider_message_send(const char *sig_name, const char *svr_name,
143                                 unsigned int witdh, unsigned int height,
144                                 minicontrol_priority_e priority,
145                                 minicontrol_h handler)
146 {
147         DBusConnection *connection = NULL;
148         DBusMessage *message = NULL;
149         DBusError err;
150         dbus_bool_t dbus_ret;
151         int ret = MINICONTROL_ERROR_NONE;
152         int handler_raw_data_len = 0;
153         char *handler_raw_data = NULL;
154
155         if (!sig_name) {
156                 ERR("sig_name is NULL, invaild parameter");
157                 return MINICONTROL_ERROR_INVALID_PARAMETER;
158         }
159
160         if (!svr_name) {
161                 ERR("svr_name is NULL, invaild parameter");
162                 return MINICONTROL_ERROR_INVALID_PARAMETER;
163         }
164
165         if (handler != NULL) {
166                 _minictrl_handler_get_raw_data(handler, &handler_raw_data, &handler_raw_data_len);
167         }
168
169         dbus_error_init(&err);
170         connection = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
171         if (!connection) {
172                 ERR("Fail to dbus_bus_get : %s", err.message);
173                 ret = MINICONTROL_ERROR_DBUS;
174                 goto release_n_return;
175         }
176
177         message = dbus_message_new_signal(MINICTRL_DBUS_PATH,
178                                 MINICTRL_DBUS_INTERFACE,
179                                 sig_name);
180
181         if (!message) {
182                 ERR("fail to create dbus message");
183                 ret = MINICONTROL_ERROR_OUT_OF_MEMORY;
184                 goto release_n_return;
185         }
186
187
188         if (handler_raw_data != NULL && handler_raw_data_len > 0) {
189                 dbus_ret = dbus_message_append_args(message,
190                                 DBUS_TYPE_STRING, &svr_name,
191                                 DBUS_TYPE_UINT32, &witdh,
192                                 DBUS_TYPE_UINT32, &height,
193                                 DBUS_TYPE_UINT32, &priority,
194                                 DBUS_TYPE_STRING, &handler_raw_data,
195                                 DBUS_TYPE_UINT32, &handler_raw_data_len,
196                                 DBUS_TYPE_INVALID);
197         } else {
198                 dbus_ret = dbus_message_append_args(message,
199                                 DBUS_TYPE_STRING, &svr_name,
200                                 DBUS_TYPE_UINT32, &witdh,
201                                 DBUS_TYPE_UINT32, &height,
202                                 DBUS_TYPE_UINT32, &priority,
203                                 DBUS_TYPE_INVALID);
204         }
205         if (!dbus_ret) {
206                 ERR("fail to append name to dbus message : %s", svr_name);
207                 ret = MINICONTROL_ERROR_OUT_OF_MEMORY;
208                 goto release_n_return;
209         }
210
211         dbus_ret = dbus_connection_send(connection, message, NULL);
212         if (!dbus_ret) {
213                 ERR("fail to send dbus message : %s", svr_name);
214                 ret = MINICONTROL_ERROR_DBUS;
215                 goto release_n_return;
216         }
217
218         dbus_connection_flush(connection);
219
220 release_n_return:
221         dbus_error_free(&err);
222
223         if (message)
224                 dbus_message_unref(message);
225
226         if (connection)
227                 dbus_connection_unref(connection);
228
229         return ret;
230 }
231
232 static DBusHandlerResult _minictrl_signal_filter(DBusConnection *conn,
233                 DBusMessage *msg, void *user_data)
234 {
235         minictrl_sig_handle *handle = NULL;
236         const char *interface;
237         DBusError error;
238         dbus_bool_t ret;
239
240         if (!user_data)
241                 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
242
243         handle = user_data;
244
245         dbus_error_init(&error);
246
247         interface = dbus_message_get_interface(msg);
248         if (!interface)
249                 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
250
251         if (strcmp(MINICTRL_DBUS_INTERFACE, interface))
252                 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
253
254         ret = dbus_message_is_signal(msg, interface, handle->signal);
255         if (!ret) {
256                 DBG("this msg is not signal");
257                 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
258         }
259
260         if (handle->callback)
261                 handle->callback(handle->user_data, msg);
262
263         return DBUS_HANDLER_RESULT_HANDLED;
264 }
265
266
267 minictrl_sig_handle *_minictrl_dbus_sig_handle_attach(const char *signal,
268                                 void (*callback) (void *data, DBusMessage *msg),
269                                 void *data)
270 {
271         minictrl_sig_handle *handle = NULL;
272         DBusError err;
273         DBusConnection *conn = NULL;
274         char rule[1024] = {'\0', };
275
276         if (!signal) {
277                 ERR("signal is NULL");
278                 return NULL;
279         }
280
281         if (!callback) {
282                 ERR("call is NULL");
283                 return NULL;
284         }
285
286         handle = malloc(sizeof(minictrl_sig_handle));
287         if (!handle) {
288                 ERR("fail to alloc handle");
289                 return NULL;
290         }
291
292         dbus_error_init(&err);
293         conn = dbus_bus_get_private(DBUS_BUS_SYSTEM, &err);
294         if (!conn) {
295                 ERR("fail to get bus : %s", err.message);
296                 goto error_n_return;
297         }
298
299         dbus_connection_setup_with_g_main(conn, NULL);
300         snprintf(rule, 1024,
301                 "path='%s',type='signal',interface='%s',member='%s'",
302                 MINICTRL_DBUS_PATH,
303                 MINICTRL_DBUS_INTERFACE,
304                 signal);
305
306         dbus_bus_add_match(conn, rule, &err);
307         if (dbus_error_is_set(&err)) {
308                 ERR("fail to dbus_bus_remove_match : %s",
309                                 err.message);
310                 goto error_n_return;
311         }
312
313         if (dbus_connection_add_filter(conn, _minictrl_signal_filter,
314                                         handle, NULL) == FALSE) {
315                 ERR("fail to dbus_connection_add_filter : %s",
316                                 err.message);
317                 goto error_n_return;
318         }
319
320         dbus_connection_set_exit_on_disconnect(conn, FALSE);
321
322         handle->conn = conn;
323         handle->callback = callback;
324         handle->user_data = data;
325         handle->signal = strdup(signal);
326
327         INFO("success to attach signal[%s]-[%p, %p]", signal, callback, data);
328
329         return handle;
330
331
332 error_n_return:
333         if (handle)
334                 free(handle);
335
336         dbus_error_free(&err);
337
338         if (conn)
339                 dbus_connection_close(conn);
340
341         return NULL;
342 }
343
344 void _minictrl_dbus_sig_handle_dettach(minictrl_sig_handle *handle)
345 {
346         DBusError err;
347         char rule[1024] = {'\0', };
348
349         if (!handle) {
350                 ERR("handle is NULL");
351                 return;
352         }
353
354         dbus_error_init(&err);
355
356         dbus_connection_remove_filter(handle->conn,
357                         _minictrl_signal_filter, handle);
358
359         snprintf(rule, 1024,
360                 "path='%s',type='signal',interface='%s',member='%s'",
361                 MINICTRL_DBUS_PATH,
362                 MINICTRL_DBUS_INTERFACE,
363                 handle->signal);
364
365         dbus_bus_remove_match(handle->conn, rule, &err);
366         if (dbus_error_is_set(&err)) {
367                 ERR("fail to dbus_bus_remove_match : %s", err.message);
368                 dbus_error_free(&err);
369         }
370
371         dbus_connection_close(handle->conn);
372
373         free(handle->signal);
374         free(handle);
375
376         return;
377 }
378