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