Merge "[Common] Initialize e-dbus" into tizen
[apps/native/starter.git] / src / dbus_util.c
1 /*
2  * Copyright (c) 2000 - 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 <E_DBus.h>
18 #include <dbus/dbus-glib.h>
19 #include <dbus/dbus-glib-lowlevel.h>
20
21 #include "dbus_util.h"
22 #include "util.h"
23
24 #define DBUS_REPLY_TIMEOUT (120 * 1000)
25
26 #define POWEROFF_BUS_NAME       "org.tizen.system.popup"
27 #define POWEROFF_OBJECT_PATH    "/Org/Tizen/System/Popup/Poweroff"
28 #define POWEROFF_INTERFACE_NAME POWEROFF_BUS_NAME".Poweroff"
29 #define METHOD_POWEROFF_NAME    "PopupLaunch"
30
31 #define CPU_BOOSTER_OBJECT_PATH DEVICED_OBJECT_PATH"/PmQos"
32 #define CPU_BOOSTER_INTERFACE   DEVICED_BUS_NAME".PmQos"
33 #define METHOD_CPU_BOOSTER              "AppLaunchHome"
34 #define DBUS_CPU_BOOSTER_SEC    200
35
36 #define METHOD_LOCK_PMQOS_NAME  "LockScreen"
37 #define DBUS_LOCK_PMQOS_SEC (2 * 1000)
38
39 static struct _info {
40         DBusConnection *connection;
41 } s_info = {
42         .connection = NULL,
43 };
44
45
46
47 static DBusConnection *_dbus_connection_get(void)
48 {
49         DBusError derror;
50         DBusConnection *connection = NULL;
51
52         if (s_info.connection) {
53                 return s_info.connection;
54         }
55
56         _W("no connection for dbus. get dbus connection");
57
58         dbus_error_init(&derror);
59         connection = dbus_bus_get_private(DBUS_BUS_SYSTEM, &derror);
60         if (!connection) {
61                 _E("Failed to get dbus connection:%s", derror.message);
62                 dbus_error_free(&derror);
63                 return NULL;
64         }
65         dbus_connection_setup_with_g_main(connection, NULL);
66         dbus_error_free(&derror);
67
68         s_info.connection = connection;
69
70         return s_info.connection;
71 }
72
73
74
75 static int _append_variant(DBusMessageIter *iter, const char *sig, char *param[])
76 {
77         char *ch;
78         int i;
79         int int_type;
80         uint64_t int64_type;
81
82         if (!sig || !param)
83                 return 0;
84
85         for (ch = (char*)sig, i = 0; *ch != '\0'; ++i, ++ch) {
86                 switch (*ch) {
87                 case 'i':
88                         int_type = atoi(param[i]);
89                         dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &int_type);
90                         break;
91                 case 'u':
92                         int_type = atoi(param[i]);
93                         dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, &int_type);
94                         break;
95                 case 't':
96                         int64_type = (uint64_t) atoi(param[i]);
97                         dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT64, &int64_type);
98                         break;
99                 case 's':
100                         dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &param[i]);
101                         break;
102                 default:
103                         return -EINVAL;
104                 }
105         }
106
107         return 0;
108 }
109
110
111
112 static DBusMessage *_invoke_dbus_method_sync(const char *dest, const char *path,
113                 const char *interface, const char *method,
114                 const char *sig, char *param[])
115 {
116         DBusConnection *conn = NULL;
117         DBusMessage *msg;
118         DBusMessageIter iter;
119         DBusMessage *reply;
120         DBusError err;
121         int r;
122
123         conn = (DBusConnection *)_dbus_connection_get();
124         if (!conn) {
125                 _E("dbus_bus_get error");
126                 return NULL;
127         }
128
129         msg = dbus_message_new_method_call(dest, path, interface, method);
130         if (!msg) {
131                 _E("dbus_message_new_method_call(%s:%s-%s)", path, interface, method);
132                 return NULL;
133         }
134
135         dbus_message_iter_init_append(msg, &iter);
136         r = _append_variant(&iter, sig, param);
137         if (r < 0) {
138                 _E("append_variant error(%d)", r);
139                 dbus_message_unref(msg);
140                 return NULL;
141         }
142
143         dbus_error_init(&err);
144
145         reply = dbus_connection_send_with_reply_and_block(conn, msg, DBUS_REPLY_TIMEOUT, &err);
146         dbus_message_unref(msg);
147         if (!reply) {
148                 _E("dbus_connection_send error(%s:%s)", err.name, err.message);
149                 dbus_error_free(&err);
150                 return NULL;
151         }
152
153         return reply;
154 }
155
156
157
158 static int _invoke_dbus_method_async(const char *dest, const char *path,
159                 const char *interface, const char *method,
160                 const char *sig, char *param[])
161 {
162         DBusConnection *conn;
163         DBusMessage *msg;
164         DBusMessageIter iter;
165         int r;
166
167         conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
168         if (!conn) {
169                 _E("dbus_bus_get error");
170                 return 0;
171         }
172
173         msg = dbus_message_new_method_call(dest, path, interface, method);
174         if (!msg) {
175                 _E("dbus_message_new_method_call(%s:%s-%s)", path, interface, method);
176                 return 0;
177         }
178
179         dbus_message_iter_init_append(msg, &iter);
180         r = _append_variant(&iter, sig, param);
181         if (r < 0) {
182                 _E("append_variant error(%d)", r);
183                 dbus_message_unref(msg);
184                 return 0;
185         }
186
187         r = dbus_connection_send(conn, msg, NULL);
188         dbus_message_unref(msg);
189         if (r != TRUE) {
190                 _E("dbus_connection_send error(%s:%s:%s-%s)", dest, path, interface, method);
191                 return 0;
192         }
193
194         _D("dbus_connection_send, ret=%d", r);
195         return 1;
196 }
197
198
199
200 #if 0
201 static int _dbus_message_send(const char *path, const char *interface, const char *member)
202 {
203         int ret = 0;
204         DBusMessage *msg = NULL;
205         DBusConnection *conn = NULL;
206
207         conn = (DBusConnection *)_dbus_connection_get();
208         if (!conn) {
209                 _E("dbus_bus_get error");
210                 return -1;
211         }
212
213         msg = dbus_message_new_signal(path, interface, member);
214         if (!msg) {
215                 _E("dbus_message_new_signal(%s:%s-%s)", path, interface, member);
216                 return -1;
217         }
218
219         ret = dbus_connection_send(conn, msg, NULL); //async call
220         dbus_message_unref(msg);
221         if (ret != TRUE) {
222                 _E("dbus_connection_send error(%s:%s-%s)", path, interface, member);
223                 return -ECOMM;
224         }
225         _D("dbus_connection_send, ret=%d", ret);
226         return 0;
227 }
228 #endif
229
230
231
232 int dbus_util_send_oomadj(int pid, int oom_adj_value)
233 {
234         DBusError err;
235         DBusMessage *msg;
236         char *pa[4];
237         char buf1[BUF_SIZE_16];
238         char buf2[BUF_SIZE_16];
239         int ret, val;
240
241         if(pid <= 0){
242                 _E("Pid is invalid");
243                 return -1;
244         }
245
246         snprintf(buf1, sizeof(buf1), "%d", pid);
247         snprintf(buf2, sizeof(buf2), "%d", oom_adj_value);
248
249         pa[0] = DEVICED_SET_METHOD;
250         pa[1] = "2";
251         pa[2] = buf1;
252         pa[3] = buf2;
253
254         msg = _invoke_dbus_method_sync(DEVICED_BUS_NAME, DEVICED_PATH, DEVICED_INTERFACE, DEVICED_SET_METHOD, "siss", pa);
255         if (!msg)
256                 return -EBADMSG;
257
258         dbus_error_init(&err);
259
260         ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID);
261         if (!ret) {
262                 _E("no message : [%s:%s]", err.name, err.message);
263                 val = -EBADMSG;
264         }
265
266         dbus_message_unref(msg);
267         dbus_error_free(&err);
268
269         _D("%s-%s : %d", DEVICED_INTERFACE, pa[0], val);
270         return val;
271 }
272
273
274
275 void dbus_util_send_cpu_booster_signal(void)
276 {
277         int ret = 0;
278         char *arr[1];
279         char val[BUF_SIZE_32];
280
281         snprintf(val, sizeof(val), "%d", DBUS_CPU_BOOSTER_SEC);
282         arr[0] = val;
283
284         ret = _invoke_dbus_method_async(DEVICED_BUS_NAME, CPU_BOOSTER_OBJECT_PATH, CPU_BOOSTER_INTERFACE,
285                         METHOD_CPU_BOOSTER, "i", arr);
286         ret_if(!ret);
287
288         _D("%s-%s", CPU_BOOSTER_INTERFACE, METHOD_CPU_BOOSTER);
289 }
290
291
292
293 void dbus_util_send_poweroff_signal(void)
294 {
295         int ret = 0;
296
297         ret = _invoke_dbus_method_async(POWEROFF_BUS_NAME, POWEROFF_OBJECT_PATH, POWEROFF_INTERFACE_NAME,
298                         METHOD_POWEROFF_NAME, NULL, NULL);
299         ret_if(!ret);
300
301         _D("%s-%s", POWEROFF_INTERFACE_NAME, METHOD_POWEROFF_NAME);
302 }
303
304
305
306 void dbus_util_send_lock_PmQos_signal(void)
307 {
308         int ret = 0;
309
310         char *arr[1];
311         char val[BUF_SIZE_32];
312
313         snprintf(val, sizeof(val), "%d", DBUS_LOCK_PMQOS_SEC);
314         arr[0] = val;
315
316         ret = _invoke_dbus_method_async(DEVICED_BUS_NAME, CPU_BOOSTER_OBJECT_PATH, CPU_BOOSTER_INTERFACE,
317                         METHOD_LOCK_PMQOS_NAME, "i", arr);
318         ret_if(!ret);
319
320         _D("%s-%s", CPU_BOOSTER_INTERFACE, METHOD_LOCK_PMQOS_NAME);
321 }
322
323
324
325 void dbus_util_send_sys_lock_teminate_signal(void)
326 {
327         E_DBus_Connection *conn;
328         DBusMessage *msg;
329         int ret = 1;
330
331         conn = e_dbus_bus_get(DBUS_BUS_SYSTEM);
332         if (conn == NULL) {
333                 _E("e_dbus_bus_get error");
334         }
335
336         msg = dbus_message_new_signal(SYS_LOCK_OBJECT_PATH,
337                         SYS_LOCK_INTERFACE_TERMINATE,
338                         SYS_LOCK_MEMBER_TERMINATE);
339
340         dbus_message_append_args(msg,
341                         DBUS_TYPE_INT32, &ret,
342                         DBUS_TYPE_INVALID);
343
344         e_dbus_message_send(conn, msg, NULL, -1, NULL);
345         dbus_message_unref(msg);
346
347         _D("%s-%s", SYS_LOCK_INTERFACE_TERMINATE, SYS_LOCK_MEMBER_TERMINATE);
348 }
349
350
351
352 int dbus_util_receive_lcd_status(void (*changed_cb)(void *data, DBusMessage *msg), void *data)
353 {
354         E_DBus_Connection *conn;
355         E_DBus_Signal_Handler *handler;
356
357         conn = e_dbus_bus_get(DBUS_BUS_SYSTEM);
358         if (conn == NULL) {
359                 _E("e_dbus_bus_get error");
360                 return 0;
361         }
362
363         handler = e_dbus_signal_handler_add(conn, NULL, DISPLAY_OBJECT_PATH,
364                                                                 DEVICED_INTERFACE_DISPLAY, MEMBER_LCD_ON,
365                                                                 changed_cb, data);
366         if (handler == NULL) {
367                 _E("e_dbus_signal_handler_add error");
368                 return 0;
369         }
370
371         handler = e_dbus_signal_handler_add(conn, NULL, DISPLAY_OBJECT_PATH,
372                                                                 DEVICED_INTERFACE_DISPLAY, MEMBER_LCD_OFF,
373                                                                 changed_cb, data);
374         if (handler == NULL) {
375                 _E("e_dbus_signal_handler_add error");
376                 return 0;
377         }
378
379         return 1;
380 }
381
382
383
384 int dbus_util_receive_sys_lock_status(void (*changed_cb)(void *data, DBusMessage *msg), void *data)
385 {
386         E_DBus_Connection *conn;
387         E_DBus_Signal_Handler *handler;
388
389         conn = e_dbus_bus_get(DBUS_BUS_SYSTEM);
390         if (conn == NULL) {
391                 _E("e_dbus_bus_get error");
392                 return -1;
393         }
394
395         handler = e_dbus_signal_handler_add(conn, NULL, SYS_LOCK_OBJECT_PATH,
396                                                                 SYS_LOCK_INTERFACE_UNLOCK, SYS_LOCK_MEMBER_UNLOCK,
397                                                                 changed_cb, data);
398         if (handler == NULL) {
399                 _E("e_dbus_signal_handler_add error");
400                 return -1;
401         }
402
403         return 0;
404 }
405
406 char *dbus_util_msg_arg_get_str(DBusMessage *msg)
407 {
408         int ret = 0;
409         DBusError derror;
410         const char *state = NULL;
411         dbus_error_init(&derror);
412
413         ret = dbus_message_get_args(msg, &derror, DBUS_TYPE_STRING, &state, DBUS_TYPE_INVALID);
414         goto_if(!ret, ERROR);
415
416         dbus_error_free(&derror);
417
418         return strdup(state);
419
420 ERROR:
421         _E("Failed to get reply (%s:%s)", derror.name, derror.message);
422         dbus_error_free(&derror);
423
424         return NULL;
425 }