remove key initialize in i386
[framework/appfw/aul-1.git] / test / ac_daemon.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 #include <stdio.h>
23 #include <glib.h>
24 #include <stdbool.h>
25 #include <app-checker-server.h>
26 #include <rua.h>
27 #include <bundle.h>
28 #include <string.h>
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <fcntl.h>
32 #include <dirent.h>
33 #include <stdlib.h>
34 #include <dlfcn.h>
35 #include <poll.h>
36 #include <ail.h>
37 #include <aul.h>
38
39 #include "simple_util.h"
40 #include "app_sock.h"
41 #include "aul_util.h"
42 #include "menu_db_util.h"
43
44 #include <Ecore_X.h>
45 #include <Ecore_Input.h>
46 #include <utilX.h>
47 #include <Ecore.h>
48 #include <Evas.h>
49
50 static struct {
51         Evas_Object *win;
52         Ecore_Event_Handler *key_up;
53         Ecore_Event_Handler *key_down;
54 } key_info = {
55         .win = NULL,
56         .key_up = NULL,
57         .key_down = NULL,
58 };
59
60 GSList *key_pid_list = NULL;
61
62 extern int app_send_cmd(int pid, int cmd, bundle *kb);
63
64 static gboolean __add_history_handler(gpointer user_data)
65 {
66         struct rua_rec rec;
67         int ret;
68         app_pkt_t *pkt = (app_pkt_t *)user_data;
69         struct history_data *hd = (struct history_data *)pkt->data;
70
71         ret = rua_init();
72
73         memset(&rec, 0, sizeof(rec));
74
75         rec.pkg_name = hd->pkg_name;
76         rec.app_path = hd->app_path;
77
78         if(hd->len > 0) {
79                 rec.arg = (char *)hd->data;
80         }
81
82         _D("add rua history %s %s", rec.pkg_name, rec.app_path);
83
84         ret = rua_add_history(&rec);
85         if (ret == -1)
86                 _D("rua add history error");
87
88         free(pkt);
89
90         ret = rua_fini();
91
92         return false;
93 }
94
95 int __send_result_to_client(int fd, int res)
96 {
97         if (send(fd, &res, sizeof(int), MSG_NOSIGNAL) < 0) {
98                 if (errno == EPIPE)
99                         _E("send failed due to EPIPE.\n");
100                 _E("send fail to client");
101         }
102         close(fd);
103         return 0;
104 }
105
106 static int __get_pkginfo(const char *dname, const char *cmdline, void *priv)
107 {
108         app_info_from_db *menu_info;
109         char *r_info;
110
111         r_info = (char *)priv;
112
113         if ((menu_info = _get_app_info_from_db_by_apppath(cmdline)) == NULL)
114                 goto out;
115         else {
116                 strncat(r_info, dname, 8);
117                 strncat(r_info, ":", 1);
118                 strncat(r_info, _get_pkgname(menu_info), MAX_PACKAGE_STR_SIZE);
119                 strncat(r_info, ":", 1);
120                 strncat(r_info, _get_app_path(menu_info), MAX_PACKAGE_APP_PATH_SIZE);
121                 strncat(r_info, ";", 1);
122         }
123
124  out:
125         if (menu_info != NULL)
126                 _free_app_info_from_db(menu_info);
127         return 0;
128 }
129
130 int __send_running_appinfo(int fd)
131 {
132         app_pkt_t *pkt = NULL;
133         int len;
134
135         pkt = (app_pkt_t *) malloc(sizeof(char) * AUL_SOCK_MAXBUFF);
136         if(!pkt) {
137                 _E("malloc fail");
138                 return 0;
139         }
140
141         memset(pkt, 0, AUL_SOCK_MAXBUFF);
142
143         __proc_iter_cmdline(__get_pkginfo, pkt->data);
144
145         pkt->cmd = APP_RUNNING_INFO_RESULT;
146         pkt->len = strlen((char *)pkt->data) + 1;
147
148         if ((len = send(fd, pkt, pkt->len + 8, 0)) != pkt->len + 8) {
149                 if (errno == EPIPE)
150                         _E("send failed due to EPIPE.\n");
151                 _E("send fail to client");
152         }
153
154         if(pkt)
155                 free(pkt);
156
157         close(fd);
158         return 0;
159 }
160
161 int __app_is_running(const char *pkgname)
162 {
163         char *apppath = NULL;
164         ail_appinfo_h handle;
165         ail_error_e ail_ret;
166
167         int ret = 0;
168         int i = 0;
169
170         if (pkgname == NULL)
171                 return 0;
172
173         ail_ret = ail_package_get_appinfo(pkgname, &handle);
174         if (ail_ret != AIL_ERROR_OK) {
175                 _E("ail_get_appinfo with %s failed", pkgname);
176                 return ret;
177         }
178
179         ail_ret = ail_appinfo_get_str(handle, AIL_PROP_EXEC_STR, &apppath);
180         if (ail_ret != AIL_ERROR_OK) {
181                 _E("ail_appinfo_get_str failed");
182                 goto out;
183         }
184
185         if (apppath == NULL)
186                 goto out;
187
188         /*truncate apppath if it includes default bundles */
189         while (apppath[i] != 0) {
190                 if (apppath[i] == ' ' || apppath[i] == '\t') {
191                         apppath[i]='\0';
192                         break;
193                 }
194                 i++;
195         }
196
197         if (__proc_iter_cmdline(NULL, apppath) > 0)
198                 ret = 1;
199         else
200                 ret = 0;
201
202  out:
203         if (ail_destroy_appinfo(handle) != AIL_ERROR_OK)
204                 _E("ail_destroy_rs failed");
205         return ret;
206 }
207
208 static int __register_key_event(int pid)
209 {
210         int *pid_data;
211         GSList *entry;
212
213         pid_data = malloc(sizeof(int));
214         *pid_data = pid;
215
216         key_pid_list = g_slist_prepend(key_pid_list, pid_data);
217
218         _D("===key stack===");
219
220         for (entry = key_pid_list; entry; entry = entry->next) {
221                 if (entry->data) {
222                         pid_data = (int *) entry->data;
223                         _D("pid : %d",*pid_data);
224                 }
225         }
226
227         return 0;
228 }
229
230 static int __unregister_key_event(int pid)
231 {
232         GSList *entry;
233         int *pid_data;
234
235         for (entry = key_pid_list; entry; entry = entry->next) {
236                 if (entry->data) {
237                         pid_data = (int *) entry->data;
238                         if(pid == *pid_data) {
239                                 key_pid_list = g_slist_remove(key_pid_list, entry->data);
240                                 free(pid_data);
241                         }
242                 }
243         }
244
245         _D("===key stack===");
246
247         for (entry = key_pid_list; entry; entry = entry->next) {
248                 if (entry->data) {
249                         pid_data = (int *) entry->data;
250                         _D("pid : %d",*pid_data);
251                 }
252         }
253
254         return 0;
255 }
256
257 static gboolean __util_handler(gpointer data)
258 {
259         GPollFD *gpollfd = (GPollFD *) data;
260         int fd = gpollfd->fd;
261         app_pkt_t *pkt;
262         int clifd;
263         struct ucred cr;
264         struct history_data *hd;
265         int ret = -1;
266         char pkgname[MAX_PACKAGE_STR_SIZE];
267
268         if ((pkt = __app_recv_raw(fd, &clifd, &cr)) == NULL) {
269                 _E("recv error");
270                 return FALSE;
271         }
272
273         switch (pkt->cmd) {
274         case APP_ADD_HISTORY:
275                 hd = (struct history_data *)pkt->data;
276                 _D("cmd : %d, pkgname : %s, app_path : %s", pkt->cmd, hd->pkg_name, hd->app_path);
277                 __send_result_to_client(clifd, 0);
278                 g_timeout_add(1000, __add_history_handler, pkt);
279                 break;
280         case APP_RUNNING_INFO:
281                 __send_running_appinfo(clifd);
282                 free(pkt);
283                 break;
284         case APP_IS_RUNNING:
285                 strncpy(pkgname, (const char*)pkt->data, MAX_PACKAGE_STR_SIZE-1);
286                 ret = __app_is_running(pkgname);
287                 __send_result_to_client(clifd, ret);
288                 free(pkt);
289                 break;
290         case APP_KEY_RESERVE:
291                 ret = __register_key_event(cr.pid);
292                 __send_result_to_client(clifd, ret);
293                 free(pkt);
294                 break;
295         case APP_KEY_RELEASE:
296                 ret = __unregister_key_event(cr.pid);
297                 __send_result_to_client(clifd, ret);
298                 free(pkt);
299                 break;
300         default:
301                 _E("no support packet");
302         }
303
304         return TRUE;
305 }
306
307 static gboolean __au_glib_check(GSource *src)
308 {
309         GSList *fd_list;
310         GPollFD *tmp;
311
312         fd_list = src->poll_fds;
313         do {
314                 tmp = (GPollFD *) fd_list->data;
315                 if ((tmp->revents & (POLLIN | POLLPRI)))
316                         return TRUE;
317                 fd_list = fd_list->next;
318         } while (fd_list);
319
320         return FALSE;
321 }
322
323 static gboolean __au_glib_dispatch(GSource *src, GSourceFunc callback,
324                                   gpointer data)
325 {
326         callback(data);
327         return TRUE;
328 }
329
330 static gboolean __au_glib_prepare(GSource *src, gint *timeout)
331 {
332         return FALSE;
333 }
334
335 static GSourceFuncs funcs = {
336         .prepare = __au_glib_prepare,
337         .check = __au_glib_check,
338         .dispatch = __au_glib_dispatch,
339         .finalize = NULL
340 };
341
342 static Eina_Bool _key_release_cb(void *data, int type, void *event)
343 {
344         Evas_Event_Key_Up *ev = event;
345         int ret;
346         GSList *entry;
347         int *pid_data;
348         bundle *kb;
349
350         _D("Released");
351
352         if (!ev) {
353                 _D("Invalid event object");
354                 return ECORE_CALLBACK_RENEW;
355         }
356
357         entry = key_pid_list;
358         if (entry && entry->data) {
359                 pid_data = (int *) entry->data;
360
361                 kb = bundle_create();
362                 bundle_add(kb, AUL_K_MULTI_KEY, ev->keyname);
363                 bundle_add(kb, AUL_K_MULTI_KEY_EVENT, AUL_V_KEY_RELEASED);
364
365                 ret = app_send_cmd(*pid_data, APP_KEY_EVENT, kb);
366
367                 bundle_free(kb);
368         }
369
370         return ECORE_CALLBACK_RENEW;
371 }
372
373
374 static Eina_Bool _key_press_cb(void *data, int type, void *event)
375 {
376         Evas_Event_Key_Down *ev = event;
377         int ret;
378         GSList *entry;
379         int *pid_data;
380         bundle *kb;
381
382         _D("Pressed");
383
384         if (!ev) {
385                 _D("Invalid event object");
386                 return ECORE_CALLBACK_RENEW;
387         }
388
389         entry = key_pid_list;
390         if (entry && entry->data) {
391                 pid_data = (int *) entry->data;
392
393                 kb = bundle_create();
394                 bundle_add(kb, AUL_K_MULTI_KEY, ev->keyname);
395                 bundle_add(kb, AUL_K_MULTI_KEY_EVENT, AUL_V_KEY_PRESSED);
396
397                 ret = app_send_cmd(*pid_data, APP_KEY_EVENT, kb);
398
399                 bundle_free(kb);
400         }
401
402         return ECORE_CALLBACK_RENEW;
403 }
404
405 static int __app_dead_handler(int pid, void *data)
406 {
407         int ret;
408
409         ret = __unregister_key_event(pid);
410
411         return 0;
412 }
413
414 static void __ac_key_initailize()
415 {
416         key_info.win = ecore_x_window_input_new(0, 0, 0, 1, 1);
417         if (!key_info.win) {
418                 _D("Failed to create hidden window");
419         }
420
421         ecore_x_icccm_title_set(key_info.win, "acdaemon,key,receiver");
422         ecore_x_netwm_name_set(key_info.win, "acdaemon,key,receiver");
423         ecore_x_netwm_pid_set(key_info.win, getpid());
424
425         utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_PLAYCD, EXCLUSIVE_GRAB);
426         utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_STOPCD, EXCLUSIVE_GRAB);
427         utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_PAUSECD, EXCLUSIVE_GRAB);
428         utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_NEXTSONG, EXCLUSIVE_GRAB);
429         utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_PREVIOUSSONG, EXCLUSIVE_GRAB);
430         utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_REWIND, EXCLUSIVE_GRAB);
431         utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_FASTFORWARD, EXCLUSIVE_GRAB);
432
433         key_info.key_up = ecore_event_handler_add(ECORE_EVENT_KEY_UP, _key_release_cb, NULL);
434         if (!key_info.key_up) {
435                 _D("Failed to register a key up event handler");
436         }
437
438         key_info.key_down = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _key_press_cb, NULL);
439         if (!key_info.key_down) {
440                 _D("Failed to register a key down event handler");
441         }
442
443         aul_listen_app_dead_signal(__app_dead_handler, NULL);
444 }
445
446 static int __initialize()
447 {
448         int fd;
449         int r;
450         GPollFD *gpollfd;
451         GSource *src;
452
453         fd = __create_server_sock(AUL_UTIL_PID);
454
455         src = g_source_new(&funcs, sizeof(GSource));
456
457         gpollfd = (GPollFD *) g_malloc(sizeof(GPollFD));
458         gpollfd->events = POLLIN;
459         gpollfd->fd = fd;
460
461         g_source_add_poll(src, gpollfd);
462         g_source_set_callback(src, (GSourceFunc) __util_handler,
463                               (gpointer) gpollfd, NULL);
464         g_source_set_priority(src, G_PRIORITY_DEFAULT);
465
466         r = g_source_attach(src, NULL);
467         if (r  == 0)
468         {
469                 /* TODO: error handle*/
470                 return AC_R_ERROR;
471         }
472
473 #ifndef __i386__
474         __ac_key_initailize();
475 #endif
476
477         return AC_R_OK;
478 }
479
480 int main(int argc, char *argv[])
481 {
482         int ret;
483
484         ecore_init();
485         evas_init();
486         ecore_event_init();
487         ecore_x_init(NULL);
488
489         ret = ac_server_initailize();
490
491         ret = __initialize();
492
493         ecore_main_loop_begin();
494
495         return 0;
496 }