3d38111bd84af6877af60e43988e5e00f4eb926a
[platform/core/system/system-popup.git] / src / common / popup-common.c
1 /*
2  *  system-popup
3  *
4  * Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #include "popup-common.h"
21 #include <dd-display.h>
22
23 #define RETRY_MAX 10
24 #define DBUS_REPLY_TIMEOUT  (-1)
25 #define BUF_MAX 64
26
27 static E_DBus_Connection *edbus_conn = NULL;
28
29 /* Terminate window */
30 static Eina_Bool exit_idler_cb(void *data)
31 {
32         elm_exit();
33         return ECORE_CALLBACK_CANCEL;
34 }
35
36 void window_terminate(void)
37 {
38         if (ecore_idler_add(exit_idler_cb, NULL))
39                 return;
40
41         exit_idler_cb(NULL);
42 }
43
44 /* Feedback */
45 void play_feedback(int type, int pattern)
46 {
47         int ret;
48
49         ret = feedback_initialize();
50         if (ret != FEEDBACK_ERROR_NONE) {
51                 _E("Cannot initialize feedback");
52                 return;
53         }
54
55         switch (type) {
56         case FEEDBACK_TYPE_SOUND:
57         case FEEDBACK_TYPE_VIBRATION:
58                 ret = feedback_play_type(type, pattern);
59                 break;
60         case FEEDBACK_TYPE_NONE:
61                 ret = feedback_play(pattern);
62                 break;
63         default:
64                 _E("Play type is unknown");
65                 ret = 0;
66         }
67         if (ret != FEEDBACK_ERROR_NONE)
68                 _E("Cannot play feedback: %d", pattern);
69
70         ret = feedback_deinitialize();
71         if (ret != FEEDBACK_ERROR_NONE)
72                 _E("Cannot deinitialize feedback");
73 }
74
75 void init_multi_feedback(void)
76 {
77         int ret;
78
79         ret = feedback_initialize();
80         if (ret != FEEDBACK_ERROR_NONE)
81                 _E("Cannot initialize feedback");
82 }
83
84 void play_multi_feedback(int pattern)
85 {
86         int ret;
87
88         ret = feedback_play(pattern);
89         if (ret != FEEDBACK_ERROR_NONE)
90                 _E("Cannot play feedback: %d", pattern);
91 }
92
93 void stop_multi_feedback(void)
94 {
95         int ret;
96
97         ret = feedback_deinitialize();
98         if (ret != FEEDBACK_ERROR_NONE)
99                 _E("Cannot deinitialize feedback");
100 }
101
102 static void *thread_feedback(void* data)
103 {
104         long type = (long)data;
105         if (type < 0)
106                 type = FEEDBACK_PATTERN_LOWBATT; /* Warning */
107         play_feedback(FEEDBACK_TYPE_NONE, type);
108         return NULL;
109 }
110
111 static void *thread_display(void* data)
112 {
113         if (display_change_state(LCD_NORMAL) < 0)
114                 _E("FAIL: display_change_state()");
115         return NULL;
116 }
117
118 static void start_thread(void *(*operation)(void *), void *data)
119 {
120         pthread_t th;
121         int ret;
122
123         ret = pthread_create(&th, NULL, operation, data);
124         if (ret < 0) {
125                 _E("Failed to create pthread(%d)", ret);
126                 return;
127         }
128         pthread_detach(th);
129         return;
130 }
131
132 void change_display_state(void)
133 {
134         start_thread(thread_display, NULL);
135 }
136
137 void notify_feedback(long pattern)
138 {
139         start_thread(thread_feedback, (void *)pattern);
140 }
141
142 /* dbus */
143 int set_dbus_connection(void)
144 {
145         int retry;
146
147         if (edbus_conn)
148                 return 0;
149
150         retry = 0;
151         while (e_dbus_init() == 0) {
152                 if (retry++ >= RETRY_MAX)
153                         return -ENOMEM;
154         }
155
156         edbus_conn = e_dbus_bus_get(DBUS_BUS_SYSTEM);
157         if (!edbus_conn) {
158                 _E("Failed to get dbus bus");
159                 e_dbus_shutdown();
160                 return -ENOMEM;
161         }
162
163         return 0;
164 }
165
166 E_DBus_Connection *get_dbus_connection(void)
167 {
168         return edbus_conn;
169 }
170
171 void unset_dbus_connection(void)
172 {
173         if (edbus_conn) {
174                 e_dbus_connection_close(edbus_conn);
175                 e_dbus_shutdown();
176                 edbus_conn = NULL;
177         }
178 }
179
180 static int append_variant(DBusMessageIter *iter, const char *sig, char *param[])
181 {
182         char *ch;
183         int i;
184         int iValue;
185
186         if (!sig || !param)
187                 return 0;
188
189         for (ch = (char*)sig, i = 0; *ch != '\0'; ++i, ++ch) {
190                 switch (*ch) {
191                 case 'i':
192                         iValue = atoi(param[i]);
193                         dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &iValue);
194                         break;
195                 case 's':
196                         dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &param[i]);
197                         break;
198                 default:
199                         return -EINVAL;
200                 }
201         }
202         return 0;
203 }
204
205 int broadcast_dbus_signal(const char *path, const char *interface,
206                 const char *name, const char *sig, char *param[])
207 {
208         E_DBus_Connection *conn = NULL;
209         DBusPendingCall *pc;
210         DBusMessageIter iter;
211         DBusMessage *msg;
212         int ret;
213
214         if (!path || !interface || !name)
215                 return -EINVAL;
216
217         conn = get_dbus_connection();
218         if (!conn) {
219                 _E("Failed to get dbus connection");
220                 return -ENOMEM;
221         }
222
223         msg = dbus_message_new_signal(path, interface, name);
224         if (!msg) {
225                 _E("FAIL: dbus_message_new_signal()");
226                 return -ENOMEM;
227         }
228
229         dbus_message_iter_init_append(msg, &iter);
230         ret = append_variant(&iter, sig, param);
231         if (ret < 0) {
232                 _E("append_variant error(%d)", ret);
233                 goto out;
234         }
235
236         pc = e_dbus_message_send(conn, msg, NULL, -1, NULL);
237         if (!pc) {
238                 _E("FAIL: e_dbus_message_send()");
239                 ret = -ECONNREFUSED;
240                 goto out;
241         }
242
243         ret = 0;
244
245 out:
246         dbus_message_unref(msg);
247         return ret;
248 }
249
250 int popup_dbus_method_sync(const char *dest, const char *path,
251                 const char *interface, const char *method,
252                 const char *sig, char *param[])
253 {
254         DBusConnection *conn = NULL;
255         DBusMessage *msg = NULL;
256         DBusMessageIter iter;
257         DBusMessage *reply = NULL;
258         DBusError err;
259         int ret, result;
260
261         conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
262         if (!conn) {
263                 _E("dbus_bus_get error");
264                 return -EPERM;
265         }
266
267         msg = dbus_message_new_method_call(dest, path, interface, method);
268         if (!msg) {
269                 _E("dbus_message_new_method_call(%s:%s-%s)",
270                                 path, interface, method);
271                 ret = -EBADMSG;
272                 goto out;
273         }
274
275         dbus_message_iter_init_append(msg, &iter);
276         ret = append_variant(&iter, sig, param);
277         if (ret < 0) {
278                 _E("append_variant error(%d)", ret);
279                 goto out;
280         }
281
282         dbus_error_init(&err);
283
284         reply = dbus_connection_send_with_reply_and_block(conn,
285                         msg, DBUS_REPLY_TIMEOUT, &err);
286         if (!reply) {
287                 _E("dbus_connection_send error(%s:%s)", err.name, err.message);
288                 dbus_error_free(&err);
289                 ret = -ECOMM;
290                 goto out;
291         }
292
293         ret = dbus_message_get_args(reply, &err,
294                         DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
295         if (!ret) {
296                 _E("no message : [%s:%s]", err.name, err.message);
297                 dbus_error_free(&err);
298                 ret = -ENOMSG;
299                 goto out;
300         }
301
302         ret = result;
303
304 out:
305         if (msg)
306                 dbus_message_unref(msg);
307         if (reply)
308                 dbus_message_unref(reply);
309         if (conn)
310                 dbus_connection_unref(conn);
311         return ret;
312 }
313
314 void unregister_dbus_signal_handler(E_DBus_Signal_Handler *handler)
315 {
316         E_DBus_Connection *conn;
317
318         if (!handler)
319                 return;
320
321         conn = get_dbus_connection();
322         if (!conn) {
323                 _E("Failed to get dbus connection");
324                 return;
325         }
326
327         e_dbus_signal_handler_del(conn, handler);
328 }
329
330 int register_dbus_signal_handler(
331                 E_DBus_Signal_Handler **handler,
332                 const char *path,
333                 const char *iface,
334                 const char *name,
335                 void (*signal_cb)(void *data, DBusMessage *msg),
336                 void *data)
337 {
338         E_DBus_Connection *conn;
339         E_DBus_Signal_Handler *h;
340
341         if (!handler || !path || !iface || !name || !signal_cb)
342                 return -EINVAL;
343
344         conn = get_dbus_connection();
345         if (!conn) {
346                 _E("Failed to get dbus connection");
347                 return -ENOMEM;
348         }
349
350         h = e_dbus_signal_handler_add(conn, NULL,
351                         path, iface, name, signal_cb, data);
352         if (!h)
353                 return -ECONNREFUSED;
354
355         *handler = h;
356
357         return 0;
358 }
359