Initialize Tizen 2.3
[framework/appfw/aul-1.git] / am_daemon / amd_launch.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 <signal.h>
23 #include <Ecore_X.h>
24 #include <Ecore_Input.h>
25 #include <utilX.h>
26 #include <Ecore.h>
27 #include <Evas.h>
28 #include <Ecore_Evas.h>
29
30 #include <bundle.h>
31 #include <aul.h>
32 #include <glib.h>
33 #include <string.h>
34 #include <stdlib.h>
35 #include <stdio.h>
36 #include <stdbool.h>
37 #include <sys/types.h>
38 #include <sys/stat.h>
39 #include <fcntl.h>
40 #include <sys/prctl.h>
41 #include <pkgmgr-info.h>
42 #include <vconf.h>
43 #ifdef WEARABLE_PROFILE
44 #include <proc_stat.h>
45 #endif
46 #include <poll.h>
47 #include <privacy_manager_client.h>
48
49 #include "amd_config.h"
50 #include "amd_launch.h"
51 #include "amd_appinfo.h"
52 #include "amd_status.h"
53 #include "app_sock.h"
54 #include "simple_util.h"
55 #include "amd_cgutil.h"
56 #include "launch.h"
57 #include "app_signal.h"
58
59 #define DAC_ACTIVATE
60
61 #include "access_control.h"
62
63 #ifdef WEARABLE_PROFILE
64 #include "dd-display.h"
65 #endif
66
67 #define TERM_WAIT_SEC 3
68 #define INIT_PID 1
69
70 #define AUL_PR_NAME                     16
71 #define PATH_APP_ROOT "/opt/usr/apps"
72 #define PATH_DATA "/data"
73 #define SDK_CODE_COVERAGE "CODE_COVERAGE"
74 #define SDK_DYNAMIC_ANALYSIS "DYNAMIC_ANALYSIS"
75 #define PATH_DA_SO "/home/developer/sdk_tools/da/da_probe.so"
76
77 #define PHONE_ORIENTATION_MODE "memory/private/sensor/10001"
78 #define AMD_EFFECT_IMAGE_ENABLE "db/setting/effect_image"
79 #define PHONE_ROTATE_LOCK "db/setting/auto_rotate_screen"
80
81 #define SYS_MIN_CPU_LOCK_FILE "/sys/devices/system/cpu/cpufreq/slp/min_cpu_lock"
82 #define MIN_CPU_LCK_CNT 0
83 #define MAX_CPU_LCK_CNT 2
84
85 #define HIDE_INDICATOR 0
86 #define SHOW_INDICATOR 1
87
88 struct appinfomgr *_laf;
89 struct cginfo *_lcg;
90
91 DBusConnection *conn;
92
93 #if 0
94 /*Unused data structure. Will be removed*/
95 typedef struct {
96         char *pkg_name;         /* package */
97         char *app_path;         /* exec */
98         char *original_app_path;        /* exec */
99         int multiple;           /* x_slp_multiple */
100         char *pkg_type;
101 } app_info_from_pkgmgr;
102 #endif
103
104 static GList *_kill_list;
105
106 struct ktimer {
107         pid_t pid;
108         char *group;
109         guint tid; /* timer ID */
110         struct cginfo *cg;
111 };
112
113 static const char *atom_name = "_E_COMP_FAKE_LAUNCH_IMAGE"; // Atomic ID string
114 static Ecore_X_Atom ATOM_IMAGE_EFFECT; //Atomic ID
115 static void __amd_effect_image_file_set(char *image_file);
116 static void __amd_send_message_to_e17(int screenmode, const char * indicator);
117 static int __amd_change_min_cpulock_count(int value);
118 static Eina_Bool __amd_restore_min_cpulock_count_cb(void *data);
119
120 static void _set_sdk_env(const char* appid, char* str) {
121         char buf[MAX_LOCAL_BUFSZ];
122         int ret;
123
124         _D("key : %s / value : %s", AUL_K_SDK, str);
125         /* http://gcc.gnu.org/onlinedocs/gcc/Cross_002dprofiling.html*/
126         /* GCOV_PREFIX contains the prefix to add to the absolute paths in the object file. */
127         /*              Prefix can be absolute, or relative. The default is no prefix.  */
128         /* GCOV_PREFIX_STRIP indicates the how many initial directory names */
129         /*              to stripoff the hardwired absolute paths. Default value is 0. */
130         if (strncmp(str, SDK_CODE_COVERAGE, strlen(str)) == 0) {
131                 snprintf(buf, MAX_LOCAL_BUFSZ, PATH_APP_ROOT"/%s"PATH_DATA, appid);
132                 ret = setenv("GCOV_PREFIX", buf, 1);
133                 _D("GCOV_PREFIX : %d", ret);
134                 ret = setenv("GCOV_PREFIX_STRIP", "4096", 1);
135                 _D("GCOV_PREFIX_STRIP : %d", ret);
136         } else if (strncmp(str, SDK_DYNAMIC_ANALYSIS, strlen(str)) == 0) {
137                 ret = setenv("LD_PRELOAD", PATH_DA_SO, 1);
138                 _D("LD_PRELOAD : %d", ret);
139         }
140 }
141
142 #define USE_ENGINE(engine) setenv("ELM_ENGINE", engine, 1);
143
144 static void _set_env(const char *appid, bundle * kb, const char *hwacc)
145 {
146         const char *str;
147         const char **str_array;
148         int len;
149         int i;
150
151         setenv("PKG_NAME", appid, 1);
152
153         USE_ENGINE("gl")
154
155         str = bundle_get_val(kb, AUL_K_STARTTIME);
156         if (str != NULL)
157                 setenv("APP_START_TIME", str, 1);
158
159         if(bundle_get_type(kb, AUL_K_SDK) & BUNDLE_TYPE_ARRAY) {
160                 str_array = bundle_get_str_array(kb, AUL_K_SDK, &len);
161                 if(str_array != NULL) {
162                         for (i = 0; i < len; i++) {
163                                 _D("index : [%d]", i);
164                                 _set_sdk_env(appid, (char *)str_array[i]);
165                         }
166                 }
167         } else {
168                 str = bundle_get_val(kb, AUL_K_SDK);
169                 if(str != NULL) {
170                         _set_sdk_env(appid, (char *)str);
171                 }
172         }
173         if (hwacc != NULL)
174                 setenv("HWACC", hwacc, 1);
175 }
176
177 static void _prepare_exec(const char *appid, bundle *kb)
178 {
179         const struct appinfo *ai;
180         const char *app_path = NULL;
181         const char *pkg_type = NULL;
182         char *file_name;
183         char process_name[AUL_PR_NAME];
184         const char *hwacc;
185         int ret;
186
187         setsid();
188
189         signal(SIGINT, SIG_DFL);
190         signal(SIGTERM, SIG_DFL);
191         signal(SIGCHLD, SIG_DFL);
192
193         ai = appinfo_find(_laf, appid);
194
195         app_path = appinfo_get_value(ai, AIT_EXEC);
196         pkg_type = appinfo_get_value(ai, AIT_TYPE);
197         hwacc = appinfo_get_value(ai, AIT_HWACC);
198
199         /* SET PRIVILEGES*/
200          _D("appid : %s / pkg_type : %s / app_path : %s ", appid, pkg_type, app_path);
201         if ((ret = __set_access(appid, pkg_type, app_path)) < 0) {
202                  _D("fail to set privileges - check your package's credential : %d\n", ret);
203                 return;
204         }
205
206         /* SET DUMPABLE - for coredump*/
207         prctl(PR_SET_DUMPABLE, 1);
208
209         /* SET PROCESS NAME*/
210         if (app_path == NULL) {
211                 _D("app_path should not be NULL - check menu db");
212                 return;
213         }
214         file_name = strrchr(app_path, '/') + 1;
215         if (file_name == NULL) {
216                 _D("can't locate file name to execute");
217                 return;
218         }
219         memset(process_name, '\0', AUL_PR_NAME);
220         snprintf(process_name, AUL_PR_NAME, "%s", file_name);
221         prctl(PR_SET_NAME, process_name);
222
223         /* SET ENVIROMENT*/
224         _set_env(appid, kb, hwacc);
225
226         /* TODO: do security job */
227         /* TODO: setuid */
228 }
229
230 static int _add_cgroup(struct cginfo *cg, const char *group, int pid)
231 {
232         int r;
233
234         r = cgutil_exist_group(cg, CTRL_MGR, group);
235         if (r == -1) {
236                 _E("exist check error: %s", strerror(errno));
237                 return -1;
238         }
239
240         if (r == 0) { /* not exist */
241                 r = cgutil_create_group(cg, CTRL_MGR, group);
242                 if (r == -1) {
243                         _E("create group error");
244                         return -1;
245                 }
246         }
247
248         r = cgutil_group_add_pid(cg, CTRL_MGR, group, pid);
249         if (r == -1) {
250                 _E("add pid to group error");
251                 cgutil_remove_group(cg, CTRL_MGR, group);
252                 return -1;
253         }
254
255         return 0;
256 }
257
258 static char **__create_argc_argv(bundle * kb, int *margc)
259 {
260         char **argv;
261         int argc;
262
263         argc = bundle_export_to_argv(kb, &argv);
264
265         *margc = argc;
266         return argv;
267 }
268 static void _do_exec(struct cginfo *cg, const char *cmd, const char *group, bundle *kb)
269 {
270         gchar **argv;
271         gint argc;
272         char **b_argv;
273         int b_argc;
274         gboolean b;
275         int r;
276
277         r = _add_cgroup(cg, group, getpid());
278         if (r == -1)
279                 return;
280
281         b = g_shell_parse_argv(cmd, &argc, &argv, NULL);
282
283         if (kb) {
284                 b_argv = __create_argc_argv(kb, &b_argc);
285                 b_argv[0] = strdup(argv[0]);
286                 _prepare_exec(group, kb);
287                 execv(b_argv[0], b_argv);
288         }
289
290         if (b) {
291                 _prepare_exec(group, kb);
292                 execv(argv[0], argv);
293         }
294
295         _E("exec error: %s", strerror(errno));
296         g_strfreev(argv);
297 }
298
299 int service_start(struct cginfo *cg, const char *group, const char *cmd, bundle *kb)
300 {
301         int r;
302         pid_t p;
303
304         if (!cg || !group || !*group || !cmd || !*cmd) {
305                 errno = EINVAL;
306                 _E("service start: %s", strerror(errno));
307                 return -1;
308         }
309
310         p = fork();
311         switch (p) {
312         case 0: /* child process */
313                 _D("start service");
314                 _do_exec(cg, cmd, group, kb);
315                 /* exec error */
316
317                 exit(0);
318                 break;
319         case -1:
320                 _E("service start: fork: %s", strerror(errno));
321                 r = -1;
322                 break;
323         default: /* parent process */
324                 _D("child process: %d", p);
325                 r = p;
326                 break;
327         }
328
329         return r;
330 }
331
332 int _start_srv(const struct appinfo *ai, bundle *kb)
333 {
334         int r;
335         const char *group;
336         const char *cmd;
337
338         group = appinfo_get_filename(ai);
339
340         cmd = appinfo_get_value(ai, AIT_EXEC);
341         if (!cmd) {
342                 _E("start service: '%s' has no exec", group);
343                 return -1;
344         }
345
346         r = service_start(_lcg, group, cmd, kb);
347         if (r == -1) {
348                 _E("start service: '%s': failed", group);
349                 return -1;
350         }
351
352         return 0;
353 }
354
355 static void _free_kt(struct ktimer *kt)
356 {
357         if (!kt)
358                 return;
359
360         cgutil_unref(&kt->cg);
361         free(kt->group);
362         free(kt);
363 }
364
365 static void _kill_pid(struct cginfo *cg, const char *group, pid_t pid)
366 {
367         int r;
368
369         if (pid <= INIT_PID) /* block sending to all process or init */
370                 return;
371
372         r = cgutil_exist_group(cg, CTRL_MGR, group);
373         if (r == -1) {
374                 _E("send SIGKILL: exist: %s", strerror(errno));
375                 return;
376         }
377         if (r == 0) {
378                 _D("send SIGKILL: '%s' not exist", group);
379                 return;
380         }
381
382         /* TODO: check pid exist in group */
383
384         r = kill(pid, 0);
385         if (r == -1) {
386                 _D("send SIGKILL: pid %d not exist", pid);
387                 return;
388         }
389
390         r = kill(pid, SIGKILL);
391         if (r == -1)
392                 _E("send SIGKILL: %s", strerror(errno));
393 }
394
395 static gboolean _ktimer_cb(gpointer data)
396 {
397         struct ktimer *kt = data;
398
399         _kill_pid(kt->cg, kt->group, kt->pid);
400         _kill_list = g_list_remove(_kill_list, kt);
401         _free_kt(kt);
402
403         return FALSE;
404 }
405
406 static void _add_list(struct cginfo *cg, const char *group, pid_t pid)
407 {
408         struct ktimer *kt;
409
410         kt = calloc(1, sizeof(*kt));
411         if (!kt)
412                 return;
413
414         kt->pid = pid;
415         kt->group = strdup(group);
416         if (!kt->group) {
417                 free(kt);
418                 return;
419         }
420
421         kt->cg = cgutil_ref(cg);
422         kt->tid = g_timeout_add_seconds(TERM_WAIT_SEC, _ktimer_cb, kt);
423
424         _kill_list = g_list_append(_kill_list, kt);
425 }
426
427 static inline void _del_list(GList *l)
428 {
429         struct ktimer *kt;
430
431         if (!l)
432                 return;
433
434         kt = l->data;
435
436         g_source_remove(kt->tid);
437         _free_kt(kt);
438         _kill_list = g_list_delete_link(_kill_list, l);
439 }
440
441 static int _kill_pid_cb(void *user_data, const char *group, pid_t pid)
442 {
443         int r;
444
445         if (pid <= INIT_PID) /* block sending to all process or init */
446                 return 0;
447
448         r = kill(pid, SIGTERM);
449         if (r == -1)
450                 _E("send SIGTERM: %s", strerror(errno));
451
452         _add_list(user_data, group, pid);
453
454         return 0;
455 }
456
457 int service_stop(struct cginfo *cg, const char *group)
458 {
459         if (!cg || !group || !*group) {
460                 errno = EINVAL;
461                 return -1;
462         }
463
464         return cgutil_group_foreach_pid(cg, CTRL_MGR, FILENAME(group),
465                         _kill_pid_cb, cg);
466 }
467
468 void service_release(const char *group)
469 {
470         GList *l;
471         GList *d;
472
473         if (!group || !*group)
474                 return;
475
476         group = FILENAME(group);
477
478         d = NULL;
479         for (l = _kill_list; l; l = g_list_next(l)) {
480                 struct ktimer *k = l->data;
481
482                 _del_list(d);
483
484                 if (k->group && !strcmp(k->group, group))
485                         d = l;
486         }
487
488         _del_list(d);
489 }
490
491 int _send_to_sigkill(int pid)
492 {
493         int pgid;
494
495         pgid = getpgid(pid);
496         if (pgid <= 1)
497                 return -1;
498
499         if (killpg(pgid, SIGKILL) < 0)
500                 return -1;
501
502         return 0;
503 }
504 int _resume_app(int pid)
505 {
506         int dummy;
507         int ret;
508         if ((ret =
509              __app_send_raw_with_delay_reply(pid, APP_RESUME_BY_PID, (unsigned char *)&dummy,
510                             sizeof(int))) < 0) {
511                 if (ret == -EAGAIN)
512                         _E("resume packet timeout error");
513                 else {
514                         _E("raise failed - %d resume fail\n", pid);
515                         _E("we will term the app - %d\n", pid);
516                         _send_to_sigkill(pid);
517                         ret = -1;
518                 }
519         }
520         _D("resume done\n");
521         return ret;
522 }
523
524 int _fake_launch_app(int cmd, int pid, bundle * kb)
525 {
526         int datalen;
527         int ret;
528         bundle_raw *kb_data;
529
530         bundle_encode(kb, &kb_data, &datalen);
531         if ((ret = __app_send_raw_with_delay_reply(pid, cmd, kb_data, datalen)) < 0)
532                 _E("error request fake launch - error code = %d", ret);
533         free(kb_data);
534         return ret;
535 }
536
537 static void __real_send(int clifd, int ret)
538 {
539         if (send(clifd, &ret, sizeof(int), MSG_NOSIGNAL) < 0) {
540                 if (errno == EPIPE) {
541                         _E("send failed due to EPIPE.\n");
542                 }
543                 _E("send fail to client");
544         }
545
546         close(clifd);
547 }
548
549 static gboolean __au_glib_check(GSource *src)
550 {
551         GSList *fd_list;
552         GPollFD *tmp;
553
554         fd_list = src->poll_fds;
555         do {
556                 tmp = (GPollFD *) fd_list->data;
557                 if ((tmp->revents & (POLLIN | POLLPRI)))
558                         return TRUE;
559                 fd_list = fd_list->next;
560         } while (fd_list);
561
562         return FALSE;
563 }
564
565 static gboolean __au_glib_dispatch(GSource *src, GSourceFunc callback,
566                 gpointer data)
567 {
568         callback(data);
569         return TRUE;
570 }
571
572 static gboolean __au_glib_prepare(GSource *src, gint *timeout)
573 {
574         return FALSE;
575 }
576
577 static GSourceFuncs funcs = {
578         .prepare = __au_glib_prepare,
579         .check = __au_glib_check,
580         .dispatch = __au_glib_dispatch,
581         .finalize = NULL
582 };
583
584 struct reply_info {
585         GSource *src;
586         GPollFD *gpollfd;
587         guint timer_id;
588         int clifd;
589         int pid;
590         int cmd;
591 };
592
593 static gboolean __reply_handler(gpointer data)
594 {
595         struct reply_info *r_info = (struct reply_info *) data;;
596         int fd = r_info->gpollfd->fd;
597         int len;
598         int res = 0;
599         int clifd = r_info->clifd;
600         int pid = r_info->pid;
601         int cmd = r_info->cmd;
602
603         len = recv(fd, &res, sizeof(int), 0);
604         if (len == -1) {
605                 if (errno == EAGAIN) {
606                         _E("recv timeout : %s", strerror(errno));
607                         res = -EAGAIN;
608                 } else {
609                         _E("recv error : %s", strerror(errno));
610                         res = -ECOMM;
611                 }
612         }
613         close(fd);
614
615         if(res < 0) {
616                 if ( cmd == APP_TERM_BY_PID ) {
617                         __real_send(clifd, -1);
618                 } else if ( cmd == APP_START_ASYNC ) {
619                         close(clifd);
620                 } else {
621                         __real_send(clifd, res);
622                 }
623         } else {
624                 if ( cmd == APP_TERM_BY_PID ) {
625                         __real_send(clifd, 0);
626                 } else if ( cmd == APP_START_ASYNC ) {
627                         close(clifd);
628                 } else {
629                         __real_send(clifd, pid);
630                 }
631         }
632
633         _D("listen fd(%d) , send fd(%d), pid(%d), cmd(%d)", fd, clifd, pid, cmd);
634
635         g_source_remove(r_info->timer_id);
636         g_source_remove_poll(r_info->src, r_info->gpollfd);
637         g_source_destroy(r_info->src);
638         g_free(r_info->gpollfd);
639         free(r_info);
640
641         return TRUE;
642 }
643
644 static gboolean __recv_timeout_handler(gpointer data)
645 {
646         struct reply_info *r_info = (struct reply_info *) data;
647         int fd = r_info->gpollfd->fd;
648
649         _E("application is not responding : pid(%d) cmd(%d)", r_info->pid, r_info->cmd);
650
651         close(fd);
652
653         if( r_info->cmd == APP_TERM_BY_PID ) {
654                 if (_send_to_sigkill(r_info->pid) < 0) {
655                         _E("fail to killing - %d\n", r_info->pid);
656                         __real_send(r_info->clifd, -1);
657                         return -1;
658                 }
659                 __real_send(r_info->clifd, 0);
660         }
661
662         g_source_remove_poll(r_info->src, r_info->gpollfd);
663         g_source_destroy(r_info->src);
664         g_free(r_info->gpollfd);
665         free(r_info);
666
667         return FALSE;
668 }
669
670 _term_app(int pid, int clifd)
671 {
672         int dummy;
673         int ret;
674         int r;
675         GPollFD *gpollfd;
676         GSource *src;
677         struct reply_info *r_info;
678
679         if ( (ret = __app_send_raw_with_delay_reply
680             (pid, APP_TERM_BY_PID, (unsigned char *)&dummy, sizeof(int))) < 0) {
681                 _D("terminate packet send error - use SIGKILL");
682                 if (_send_to_sigkill(pid) < 0) {
683                         _E("fail to killing - %d\n", pid);
684                         __real_send(clifd, -1);
685                         return -1;
686                 }
687                 __real_send(clifd, 0);
688         }
689         _D("term done\n");
690         if(ret > 0) {
691                 src = g_source_new(&funcs, sizeof(GSource));
692
693                 gpollfd = (GPollFD *) g_malloc(sizeof(GPollFD));
694                 gpollfd->events = POLLIN;
695                 gpollfd->fd = ret;
696
697                 r_info = malloc(sizeof(*r_info));
698                 r_info->clifd = clifd;
699                 r_info->pid = pid;
700                 r_info->src = src;
701                 r_info->gpollfd = gpollfd;
702                 r_info->cmd = APP_TERM_BY_PID;
703
704                 _D("listen fd : %d, send fd : %d", ret, clifd);
705
706                 r_info->timer_id = g_timeout_add(5000, __recv_timeout_handler, (gpointer) r_info);
707                 g_source_add_poll(src, gpollfd);
708                 g_source_set_callback(src, (GSourceFunc) __reply_handler,
709                                 (gpointer) r_info, NULL);
710                 g_source_set_priority(src, G_PRIORITY_DEFAULT);
711                 r = g_source_attach(src, NULL);
712         }
713         return 0;
714 }
715
716 static int __nofork_processing(int cmd, int pid, bundle * kb, int clifd)
717 {
718         int ret = -1;
719         int r;
720         GPollFD *gpollfd;
721         GSource *src;
722         struct reply_info *r_info;
723         const char *operation;
724
725         operation = bundle_get_val(kb, "__APP_SVC_OP_TYPE__");
726
727         if ( cmd == APP_OPEN ||
728                 (operation != NULL && strncmp(operation, "http://tizen.org/appcontrol/operation/main", 512) == 0)){
729                 char *arr[2];
730                 char val[32];
731                 snprintf(val, sizeof(val), "%d", 800);
732                 arr[0] = val;
733                 arr[1] = NULL;
734                 ret = invoke_dbus_method_sync(SYSTEM_BUS_NAME, SYSTEM_OBJECT_PATH,
735                                                                 SYSTEM_INTERFACE_NAME, SYSTEM_METHOD_NAME, "i", arr);
736                 _D("%s-%s : %d", SYSTEM_INTERFACE_NAME, SYSTEM_METHOD_NAME, ret);
737         }
738
739         switch (cmd) {
740         case APP_OPEN:
741         case APP_RESUME:
742                 _D("resume app's pid : %d\n", pid);
743                 if ((ret = _resume_app(pid)) < 0)
744                         _E("__resume_app failed. error code = %d", ret);
745                 _D("resume app done");
746                 break;
747
748         case APP_START:
749         case APP_START_RES:
750         case APP_START_ASYNC:
751                 _D("fake launch pid : %d\n", pid);
752                 if ((ret = _fake_launch_app(cmd, pid, kb)) < 0)
753                         _E("fake_launch failed. error code = %d", ret);
754                 _D("fake launch done");
755                 break;
756         }
757
758         if(ret > 0) {
759                 src = g_source_new(&funcs, sizeof(GSource));
760
761                 gpollfd = (GPollFD *) g_malloc(sizeof(GPollFD));
762                 gpollfd->events = POLLIN;
763                 gpollfd->fd = ret;
764
765                 r_info = malloc(sizeof(*r_info));
766                 r_info->clifd = clifd;
767                 r_info->pid = pid;
768                 r_info->src = src;
769                 r_info->gpollfd = gpollfd;
770                 r_info->cmd = cmd;
771
772                 _D("listen fd : %d, send fd : %d", ret, clifd);
773
774                 r_info->timer_id = g_timeout_add(5200, __recv_timeout_handler, (gpointer) r_info);
775                 g_source_add_poll(src, gpollfd);
776                 g_source_set_callback(src, (GSourceFunc) __reply_handler,
777                                 (gpointer) r_info, NULL);
778                 g_source_set_priority(src, G_PRIORITY_DEFAULT);
779                 r = g_source_attach(src, NULL);
780         }
781
782         return ret;
783 }
784
785 #if __CPU_FREQ_CON
786 #include <sysman.h>
787 static Eina_Bool
788 __amd_sysman_restore_hz_timer_cb(void *data)
789 {
790    struct context *ctxt = data;
791
792    if (ctxt->timer)
793      ctxt->timer = NULL;
794
795    sysman_release_cpu_min_frequency ();
796
797    _D("*******[1.6MHZ Support] Released\n " );
798
799    return ECORE_CALLBACK_CANCEL; // same as EINA_FALSE
800 }
801 #endif
802
803 struct context{
804         Ecore_Timer *timer;
805 };
806
807 static int __amd_change_min_cpulock_count(int value)
808 {
809         int fd = -1;
810         char buf[16]={0,};
811         fd = open(SYS_MIN_CPU_LOCK_FILE, O_WRONLY);
812         if (fd == -1)
813                 return -1;
814         snprintf(buf, sizeof(buf), "%d", value);
815         if (write(fd, buf, strlen(buf)) < 0) {
816                 _E("[AMD]: Unable to change min_cpu_lock value!, err: %s\n",strerror(errno));
817                 close(fd);
818                 return -1;
819         }
820         close(fd);
821         _D("[AMD]: Succesfully changed min cpu value to %d\n", value);
822         return 0;
823 }
824
825 static Eina_Bool __amd_restore_min_cpulock_count_cb(void *data)
826 {
827         struct context *ctxt = data;
828         if (ctxt->timer)
829                 ctxt->timer = NULL;
830         __amd_change_min_cpulock_count(MIN_CPU_LCK_CNT);
831         return ECORE_CALLBACK_CANCEL;
832 }
833
834 static void __amd_effect_image_file_set(char *image_file)
835 {
836         Ecore_X_Window root_win;
837         root_win = ecore_x_window_root_first_get();
838         ecore_x_window_prop_string_set(root_win, ATOM_IMAGE_EFFECT,image_file);
839 }
840
841
842 static void __amd_send_message_to_e17(int screenmode, const char * indicator)
843 {
844         Ecore_X_Window root_win;
845         int ret;
846         root_win = ecore_x_window_root_first_get();
847          _D("root win : %x",root_win);
848         int screen_orientation[5]={0,270,0,180,90};
849         if (screenmode > 4 || screenmode < 0)
850                 screenmode=0;
851
852         if (strncmp(indicator, "true", 4) == 0){
853                 _D("[LAUNCHING EFFECT]: screen mode is %d, indicator show\n", screen_orientation[screenmode] );
854                 ret = ecore_x_client_message32_send (root_win, ATOM_IMAGE_EFFECT,
855                         ECORE_X_EVENT_MASK_WINDOW_PROPERTY, 1,
856                         screen_orientation[screenmode],
857                         SHOW_INDICATOR, 0, 0);
858
859         }else{
860                 _D("[LAUNCHING EFFECT]: screen mode is %d, indicator hide\n", screen_orientation[screenmode] );
861                 ret = ecore_x_client_message32_send (root_win, ATOM_IMAGE_EFFECT,
862                         ECORE_X_EVENT_MASK_WINDOW_PROPERTY, 1,
863                         screen_orientation[screenmode],
864                         HIDE_INDICATOR, 0, 0);
865         }
866         ecore_x_flush();
867         _D("ecore_x_client_message32_send : %d",ret);
868 }
869
870
871
872 static int append_variant(DBusMessageIter *iter, const char *sig, char *param[])
873 {
874         char *ch;
875         int i;
876         int int_type;
877         uint64_t int64_type;
878
879         if (!sig || !param)
880                 return 0;
881
882         for (ch = (char*)sig, i = 0; *ch != '\0'; ++i, ++ch) {
883                 switch (*ch) {
884                 case 'i':
885                         int_type = atoi(param[i]);
886                         dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &int_type);
887                         break;
888                 case 'u':
889                         int_type = atoi(param[i]);
890                         dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, &int_type);
891                         break;
892                 case 't':
893                         int64_type = atoi(param[i]);
894                         dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT64, &int64_type);
895                         break;
896                 case 's':
897                         dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, param[i]);
898                         break;
899                 default:
900                         return -EINVAL;
901                 }
902         }
903
904         return 0;
905 }
906
907 int invoke_dbus_method_sync(const char *dest, const char *path,
908                 const char *interface, const char *method,
909                 const char *sig, char *param[])
910 {
911         DBusMessage *msg;
912         DBusMessageIter iter;
913         DBusMessage *reply;
914         DBusError err;
915         int r, ret;
916
917         msg = dbus_message_new_method_call(dest, path, interface, method);
918         if (!msg) {
919                 _E("dbus_message_new_method_call(%s:%s-%s)", path, interface, method);
920                 return -EBADMSG;
921         }
922
923         dbus_message_iter_init_append(msg, &iter);
924         r = append_variant(&iter, sig, param);
925         if (r < 0) {
926                 _E("append_variant error(%d)", r);
927                 dbus_message_unref(msg);
928                 return -EBADMSG;
929         }
930
931         dbus_error_init(&err);
932
933         reply = dbus_connection_send_with_reply_and_block(conn, msg, 500, &err);
934         dbus_message_unref(msg);
935         if (!reply) {
936                 _E("dbus_connection_send error(%s:%s)", err.name, err.message);
937                 dbus_error_free(&err);
938                 return -EBADMSG;
939         }
940
941         r = dbus_message_get_args(reply, &err, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INVALID);
942         dbus_message_unref(reply);
943         if (!r) {
944                 _E("no message : [%s:%s]", err.name, err.message);
945                 dbus_error_free(&err);
946                 return -EBADMSG;
947         }
948
949         return ret;
950 }
951
952 int _start_app(char* appid, bundle* kb, int cmd, int caller_pid, uid_t caller_uid, int fd)
953 {
954         const struct appinfo *ai;
955         int ret = -1;
956         const char *multiple = NULL;
957         const char *app_path = NULL;
958         const char *pkg_type = NULL;
959         const char *component_type = NULL;
960         int pid = -1;
961         char tmp_pid[MAX_PID_STR_BUFSZ];
962         const char *hwacc;
963         const char *permission;
964         const char *pkgid;
965         const char *taskmanage;
966         const char *preload;
967         const char *pkg_status;
968         const char *operation;
969         char caller_appid[256];
970         char* caller = NULL;
971         pkgmgrinfo_cert_compare_result_type_e compare_result;
972         int delay_reply = 0;
973         int pad_pid = LAUNCHPAD_PID;
974         int status = -1;
975         int r = -1;
976         char trm_buf[MAX_PACKAGE_STR_SIZE];
977         bool consented = true;
978
979         int effect_mode = 0;
980 #ifdef WEARABLE_PROFILE
981         int wmanager_connected = 0;
982 #endif
983
984         snprintf(tmp_pid, MAX_PID_STR_BUFSZ, "%d", caller_pid);
985         bundle_add(kb, AUL_K_CALLER_PID, tmp_pid);
986
987         if (cmd == APP_START_RES)
988                 bundle_add(kb, AUL_K_WAIT_RESULT, "1");
989
990         caller = _status_app_get_appid_bypid(caller_pid);
991         if(caller == NULL) {
992                 ret = aul_app_get_appid_bypid(caller_pid, caller_appid, sizeof(caller_appid));
993                 if(ret == 0) {
994                         bundle_add(kb, AUL_K_CALLER_APPID, caller_appid);
995                 }
996         } else {
997                 bundle_add(kb, AUL_K_CALLER_APPID, caller);
998         }
999         SECURE_LOGD("caller : %s", bundle_get_val(kb,AUL_K_CALLER_APPID));
1000
1001         ai = appinfo_find(_laf, appid);
1002
1003         if(ai == NULL) {
1004                 _D("no appinfo");
1005                 __real_send(fd, -1);
1006                 return -1;
1007         } else {
1008                 pkg_status = appinfo_get_value(ai, AIT_STATUS);
1009                 if(pkg_status && strncmp(pkg_status, "upgrading", 9) == 0 ) {
1010                         _D("upgrading");
1011                         __real_send(fd, -1);
1012                         return -1;
1013                 } else if(pkg_status && strncmp(pkg_status, "unmounted", 9) == 0 ) {
1014                         _D("unmounted");
1015                         __real_send(fd, -1);
1016                         return -1;
1017                 }
1018         }
1019
1020         pkgid = appinfo_get_value(ai, AIT_PKGID);
1021
1022         if(bundle_get_val(kb, AUL_K_PRIVACY_APPID)){
1023                 bundle_del(kb, AUL_K_PRIVACY_APPID);
1024         } else {
1025                 privacy_manager_client_check_user_consented(pkgid, &consented);
1026
1027                 _D("consented : %d", consented);
1028
1029                 if(consented == false && bundle_get_val(kb, AUL_K_SDK) == NULL) {
1030                         _D("appid : %s", appid);
1031                         bundle_add(kb, AUL_K_PRIVACY_APPID, appid);
1032                         appid = PRIVACY_POPUP;
1033                         bundle_del(kb, AUL_K_PKG_NAME);
1034                         bundle_add(kb, AUL_K_PKG_NAME, appid);
1035                         ai = appinfo_find(_laf, appid);
1036                 }
1037         }
1038
1039         app_path = appinfo_get_value(ai, AIT_EXEC);
1040         pkg_type = appinfo_get_value(ai, AIT_TYPE);
1041         permission = appinfo_get_value(ai, AIT_PERM);
1042         pkgid = appinfo_get_value(ai, AIT_PKGID);
1043         component_type = appinfo_get_value(ai, AIT_COMPTYPE);
1044
1045         if(permission && strncmp(permission, "signature", 9) == 0 ) {
1046                 if(caller_uid != 0 && (cmd == APP_START || cmd == APP_START_RES || cmd == APP_START_ASYNC)){
1047                         const struct appinfo *caller_ai;
1048                         caller_ai = appinfo_find(_laf, caller_appid);
1049                         preload = appinfo_get_value(caller_ai, AIT_PRELOAD);
1050                         if( preload && strncmp(preload, "true", 4) != 0 ) {
1051                                 pkgmgrinfo_pkginfo_compare_app_cert_info(caller_appid, appid, &compare_result);
1052                                 if(compare_result != PMINFO_CERT_COMPARE_MATCH) {
1053                                         pid = -EILLEGALACCESS;
1054                                         __real_send(fd, pid);
1055                                         return pid;
1056                                 }
1057                         }
1058                 }
1059         }
1060
1061         pkgmgrinfo_client_request_enable_external_pkg(pkgid);
1062
1063         if (component_type && strncmp(component_type, "uiapp", 5) == 0) {
1064                 multiple = appinfo_get_value(ai, AIT_MULTI);
1065                 if (!multiple || strncmp(multiple, "false", 5) == 0) {
1066                         pid = _status_app_is_running_v2(appid);
1067                 }
1068
1069                 status = _status_get_app_info_status(pid);
1070                 if (pid > 0 && status != STATUS_DYING) {
1071                         if (caller_pid == pid) {
1072                                 SECURE_LOGD("caller process & callee process is same.[%s:%d]", appid, pid);
1073                                 pid = -ELOCALLAUNCH_ID;
1074                         } else {
1075 #ifdef WEARABLE_PROFILE
1076                                 proc_group_change_status(PROC_CGROUP_SET_RESUME_REQUEST, pid, appid);
1077 #endif
1078                                 if ((ret = __nofork_processing(cmd, pid, kb, fd)) < 0) {
1079                                         pid = ret;
1080                                 } else {
1081                                         delay_reply = 1;
1082                                 }
1083                         }
1084                 } else if (cmd != APP_RESUME) {
1085                         if(status == STATUS_DYING && pid > 0) {
1086                                 r = kill(pid, SIGKILL);
1087                                 if (r == -1)
1088                                         _D("send SIGKILL: %s", strerror(errno));
1089                         }
1090                         hwacc = appinfo_get_value(ai, AIT_HWACC);
1091                         bundle_add(kb, AUL_K_HWACC, hwacc);
1092                         taskmanage = appinfo_get_value(ai, AIT_TASKMANAGE);
1093                         bundle_add(kb, AUL_K_TASKMANAGE, taskmanage);
1094                         operation = bundle_get_val(kb, "__APP_SVC_OP_TYPE__");
1095
1096                         if ( cmd == APP_OPEN ||
1097                                 (operation != NULL && strncmp(operation, "http://tizen.org/appcontrol/operation/main", 512) == 0) ||
1098                                 (caller != NULL && strcmp(caller, "com.samsung.wnotification2") == 0) ){
1099                                 char *arr[2];
1100                                 char val[32];
1101                                 snprintf(val, sizeof(val), "%d", 1200);
1102                                 arr[0] = val;
1103                                 arr[1] = NULL;
1104                                 ret = invoke_dbus_method_sync(SYSTEM_BUS_NAME, SYSTEM_OBJECT_PATH,
1105                                                                 SYSTEM_INTERFACE_NAME, SYSTEM_METHOD_NAME, "i", arr);
1106                                 _D("%s-%s : %d", SYSTEM_INTERFACE_NAME, SYSTEM_METHOD_NAME, ret);
1107                         }
1108
1109                         /*
1110                          *      effect_mode = 0
1111                          *              default mode : fake effect off, 1.6 MHZ off
1112                          *      effect_mode = 1
1113                          *              full mode : fake effect on, 1.6 MHZ on
1114                          *      effect_mode = 2
1115                          *              fake effect mode : fake effect on, 1.6 MHZ off
1116                          *      effect_mode = 3
1117                          *              1.6 MHZ mode : faek effect off, 1.6MHZ on
1118                          *
1119                          */
1120                         vconf_get_int(AMD_EFFECT_IMAGE_ENABLE, &effect_mode);
1121 #ifdef WEARABLE_PROFILE
1122                         vconf_get_bool(VCONFKEY_WMS_WMANAGER_CONNECTED, &wmanager_connected);
1123                         //_D("*******[effect_mode] Mode : %d\n ", effect_mode );
1124
1125                         if ( ( cmd == APP_OPEN || (operation != NULL && strncmp(operation, "http://tizen.org/appcontrol/operation/main", 512) == 0) )
1126                                 && (effect_mode == 1 || effect_mode == 2) && wmanager_connected == true){
1127 #else
1128                         if ( ( cmd == APP_OPEN || (operation != NULL && strncmp(operation, "http://tizen.org/appcontrol/operation/main", 512) == 0) )
1129                                 && (effect_mode == 1 || effect_mode == 2)){
1130 #endif
1131                                 char image_filename[256] = {0,};
1132                                 const char *portraitimg = NULL;
1133                                 const char *indicator = NULL;
1134                                 bool rotate_allowed = false;
1135
1136                                 vconf_get_bool(PHONE_ROTATE_LOCK, &rotate_allowed); /*TODO: use vconf_notify_key_changed()*/
1137                                 portraitimg = appinfo_get_value(ai, AIT_EFFECTIMAGEPORT);
1138                                 indicator = appinfo_get_value(ai, AIT_INDICATOR_DISP);
1139                                 /*Currently we assume apps supporting launching effect supports portrait mode*/
1140                                 if (portraitimg){
1141                                         snprintf(image_filename, 255, "%s", portraitimg);
1142                                         if (access(image_filename, R_OK) == 0){
1143                                                 __amd_effect_image_file_set("/usr/share/splash_images/type0_portrait.bmp");
1144                                                 __amd_send_message_to_e17(0, indicator);
1145                                         }
1146                                 }
1147                         }
1148
1149                         bundle_add(kb, AUL_K_EXEC, app_path);
1150                         bundle_add(kb, AUL_K_PACKAGETYPE, pkg_type);
1151                         if(bundle_get_type(kb, AUL_K_SDK) != BUNDLE_TYPE_NONE) {
1152                                 pad_pid = DEBUG_LAUNCHPAD_PID;
1153                         } else if(strncmp(pkg_type, "wgt", 3) == 0) {
1154                                 pad_pid = WEB_LAUNCHPAD_PID;
1155                         }
1156 #ifdef PROCESS_POOL_ENABLE
1157                         else {
1158                                 const char *process_pool = appinfo_get_value(ai, AIT_POOL);
1159                                 _D("process_pool: %s\n", process_pool);
1160
1161                                 if (strncmp(process_pool, "true", 4) == 0)
1162                                 {
1163                                         pad_pid = PROCESS_POOL_LAUNCHPAD_PID;
1164                                 }
1165                         }
1166 #endif
1167
1168                         pid = app_send_cmd(pad_pid, cmd, kb);
1169                         if(pid == -3) {
1170                                 pid = -ENOLAUNCHPAD;
1171                         }
1172                         //_add_cgroup(_lcg, appid, pid);
1173 #ifdef WEARABLE_PROFILE
1174                         proc_group_change_status(PROC_CGROUP_SET_LAUNCH_REQUEST, pid, appid);
1175                         snprintf(trm_buf, MAX_PACKAGE_STR_SIZE, "appinfo_launch:%s[PID]%d", appid, pid);
1176                         __trm_app_info_send_socket(trm_buf);
1177 #endif
1178                 }
1179         }
1180         else if (component_type && strncmp(component_type, "svcapp", 6) == 0) {
1181                 pid = _status_app_is_running_v2(appid);
1182                 if (pid > 0) {
1183                         if ((ret = __nofork_processing(cmd, pid, kb, fd)) < 0) {
1184                                 pid = ret;
1185                         }
1186                 } else if (cmd != APP_RESUME) {
1187                         pid = service_start(_lcg, appid, app_path, kb);
1188 #ifdef WEARABLE_PROFILE
1189                         proc_group_change_status(PROC_CGROUP_SET_SERVICE_REQUEST, pid, appid);
1190 #endif
1191                 }
1192         } else {
1193                 _E("unkown application");
1194         }
1195
1196         if(!delay_reply) {
1197                 if(cmd == APP_START_ASYNC)
1198                         close(fd);
1199                 else
1200                         __real_send(fd, pid);
1201         }
1202
1203         if(pid > 0) {
1204                 _status_add_app_info_list(appid, app_path, pid, pad_pid);
1205         }
1206
1207 #ifdef WEARABLE_PROFILE
1208         display_lock_state(LCD_OFF, STAY_CUR_STATE, 1000);
1209 #endif
1210
1211         return pid;
1212 }
1213
1214
1215 int _launch_init(struct amdmgr* amd)
1216 {
1217         _laf = amd->af;
1218         _lcg = amd->cg;
1219         conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
1220         if (!conn) {
1221                 _E("dbus_bus_get error");
1222                 return -EBADMSG;
1223         }
1224         return 0;
1225 }
1226
1227 void _set_atom_effect(void)
1228 {
1229         ATOM_IMAGE_EFFECT = ecore_x_atom_get(atom_name);
1230 }
1231
1232