Tizen 2.4.0 rev3 SDK Public Release
[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 #define _GNU_SOURCE
23 #include <signal.h>
24 #include <Ecore_X.h>
25 #include <Ecore_Input.h>
26 #ifdef _APPFW_FEATURE_AMD_KEY
27 #include <utilX.h>
28 #endif
29 #include <Ecore.h>
30 #include <Evas.h>
31 #include <Ecore_Evas.h>
32 #include <security-server.h>
33 #include <aul_svc.h>
34 #include <bundle.h>
35 #include <bundle_internal.h>
36 #include <aul.h>
37 #include <aul_svc.h>
38 #include <aul_svc_priv_key.h>
39 #include <glib.h>
40 #ifdef _APPFW_FEATURE_APP_CHECKER
41 #include <app-checker-server.h>
42 #endif
43 #include <string.h>
44 #include <stdlib.h>
45 #include <stdio.h>
46 #include <stdbool.h>
47 #include <sys/types.h>
48 #include <sys/stat.h>
49 #include <fcntl.h>
50 #include <sys/prctl.h>
51 #include <sys/resource.h>
52 #include <pkgmgr-info.h>
53 #include <vconf.h>
54 #include <proc_stat.h>
55 #include <poll.h>
56 #include <ttrace.h>
57 #include <sys/smack.h>
58 #include <security-server-perm.h>
59
60 #ifdef _APPFW_FEATURE_PRIVATE_SERVICE
61 #include <cert-service.h>
62 #endif
63
64 #include "amd_config.h"
65 #include "amd_launch.h"
66 #include "amd_appinfo.h"
67 #include "amd_status.h"
68 #include "amd_key.h"
69 #include "app_sock.h"
70 #include "simple_util.h"
71 #include "launch.h"
72 #include "app_signal.h"
73 #include "amd_app_group.h"
74 #include "amd_request.h"
75
76 #define PREEXEC_ACTIVATE
77 #include "preexec.h"
78
79 #define DAC_ACTIVATE
80 #include "access_control.h"
81
82 #ifdef _APPFW_FEATURE_EXPANSION_PKG_INSTALL
83 #include "appfw_env.h"
84 #endif
85
86 #define TERM_WAIT_SEC 3
87 #define INIT_PID 1
88
89 #define AUL_PR_NAME                     16
90 #define PATH_APP_ROOT "/opt/usr/apps"
91 #define PATH_DATA "/data"
92 #define SDK_CODE_COVERAGE "CODE_COVERAGE"
93 #define SDK_DYNAMIC_ANALYSIS "DYNAMIC_ANALYSIS"
94 #define PATH_DA_SO "/home/developer/sdk_tools/da/da_probe.so"
95
96 #ifdef _APPFW_FEATURE_FAKE_EFFECT
97 #define PHONE_ORIENTATION_MODE "memory/private/sensor/10001"
98 #define PHONE_ROTATE_LOCK "db/setting/auto_rotate_screen"
99 #endif
100
101 #define SYS_MIN_CPU_LOCK_FILE "/sys/devices/system/cpu/cpufreq/slp/min_cpu_lock"
102 #define MIN_CPU_LCK_CNT 0
103 #define MAX_CPU_LCK_CNT 2
104
105 #define HIDE_INDICATOR 0
106 #define SHOW_INDICATOR 1
107
108 #define PROC_STATUS_FG  3
109 #define PROC_STATUS_BG  4
110 #ifdef _APPFW_FEATURE_CPU_BOOST
111 #define APP_BOOSTING_PERIOD 1500 //msec
112 #endif
113
114 #ifdef _APPFW_FEATURE_PRIVATE_SERVICE
115 #define OSP_K_LAUNCH_TYPE   "__OSP_LAUNCH_TYPE__"
116 #define OSP_V_LAUNCH_TYPE_DATACONTROL   "datacontrol"
117 #endif
118
119 static char *amd_cmdline;
120
121 struct appinfomgr *_laf;
122
123 DBusConnection *conn;
124 #ifdef _APPFW_FEATURE_AMD_KEY
125 guint grab_timer_id;
126 #endif
127
128
129 #if 0
130 /*Unused data structure. Will be removed*/
131 typedef struct {
132         char *pkg_name;         /* package */
133         char *app_path;         /* exec */
134         char *original_app_path;        /* exec */
135         int multiple;           /* x_slp_multiple */
136         char *pkg_type;
137 } app_info_from_pkgmgr;
138 #endif
139
140 static GList *_kill_list;
141
142 struct ktimer {
143         pid_t pid;
144         char *group;
145         guint tid; /* timer ID */
146         struct cginfo *cg;
147 };
148
149 static const char *atom_name = "_E_COMP_FAKE_LAUNCH_IMAGE"; // Atomic ID string
150 static Ecore_X_Atom ATOM_IMAGE_EFFECT; //Atomic ID
151 static void __amd_effect_image_file_set(char *image_file);
152 static void __amd_send_message_to_e17(int screenmode, const char * indicator, int effect_type, int theme);
153 static void __set_reply_handler(int fd, int pid, int clifd, int cmd);
154 static void __real_send(int clifd, int ret);
155 static int __send_proc_prelaunch_signal(const char *appid, const char *pkgid, int attribute);
156 int invoke_dbus_method_sync(const char *dest, const char *path,
157                             const char *interface, const char *method,
158                             const char *sig, char *param[]);
159
160 static void _set_sdk_env(const char* appid, char* str) {
161         char buf[MAX_LOCAL_BUFSZ];
162         int ret;
163
164         _D("key : %s / value : %s", AUL_K_SDK, str);
165         /* http://gcc.gnu.org/onlinedocs/gcc/Cross_002dprofiling.html*/
166         /* GCOV_PREFIX contains the prefix to add to the absolute paths in the object file. */
167         /*              Prefix can be absolute, or relative. The default is no prefix.  */
168         /* GCOV_PREFIX_STRIP indicates the how many initial directory names */
169         /*              to stripoff the hardwired absolute paths. Default value is 0. */
170         if (strncmp(str, SDK_CODE_COVERAGE, strlen(str)) == 0) {
171                 snprintf(buf, MAX_LOCAL_BUFSZ, PATH_APP_ROOT"/%s"PATH_DATA, appid);
172                 ret = setenv("GCOV_PREFIX", buf, 1);
173                 _D("GCOV_PREFIX : %d", ret);
174                 ret = setenv("GCOV_PREFIX_STRIP", "4096", 1);
175                 _D("GCOV_PREFIX_STRIP : %d", ret);
176         } else if (strncmp(str, SDK_DYNAMIC_ANALYSIS, strlen(str)) == 0) {
177                 ret = setenv("LD_PRELOAD", PATH_DA_SO, 1);
178                 _D("LD_PRELOAD : %d", ret);
179         }
180 }
181
182 #define USE_ENGINE(engine) setenv("ELM_ENGINE", engine, 1);
183
184 static void _set_env(const char *appid, bundle * kb, const char *hwacc)
185 {
186         const char *str;
187         const char **str_array;
188         int len;
189         int i;
190
191         setenv("PKG_NAME", appid, 1);
192
193         USE_ENGINE("gl")
194
195         str = bundle_get_val(kb, AUL_K_STARTTIME);
196         if (str != NULL)
197                 setenv("APP_START_TIME", str, 1);
198
199         if(bundle_get_type(kb, AUL_K_SDK) & BUNDLE_TYPE_ARRAY) {
200                 str_array = bundle_get_str_array(kb, AUL_K_SDK, &len);
201                 if(str_array != NULL) {
202                         for (i = 0; i < len; i++) {
203                                 _D("index : [%d]", i);
204                                 _set_sdk_env(appid, (char *)str_array[i]);
205                         }
206                 }
207         } else {
208                 str = bundle_get_val(kb, AUL_K_SDK);
209                 if(str != NULL) {
210                         _set_sdk_env(appid, (char *)str);
211                 }
212         }
213         if (hwacc != NULL)
214                 setenv("HWACC", hwacc, 1);
215 }
216
217 static void __set_oom(void)
218 {
219         char buf[MAX_OOM_ADJ_BUFSZ] = {0,};
220         FILE *fp = NULL;
221
222         /* we should reset oomadj value as default because child
223         inherits from parent oom_adj*/
224         snprintf(buf, MAX_OOM_ADJ_BUFSZ, "/proc/%d/oom_score_adj", getpid());
225         fp = fopen(buf, "w");
226         if (fp == NULL)
227                 return;
228         fprintf(fp, "%d", 100);
229         fclose(fp);
230 }
231
232 static void _prepare_exec(const char *appid, bundle *kb)
233 {
234         const struct appinfo *ai;
235         const char *app_path = NULL;
236         const char *pkg_type = NULL;
237         char *file_name;
238         char process_name[AUL_PR_NAME];
239         const char *hwacc;
240         int ret;
241
242         setsid();
243
244         signal(SIGINT, SIG_DFL);
245         signal(SIGTERM, SIG_DFL);
246         signal(SIGCHLD, SIG_DFL);
247
248         __set_oom();
249
250         ai = appinfo_find(_laf, appid);
251
252         app_path = appinfo_get_value(ai, AIT_EXEC);
253         pkg_type = appinfo_get_value(ai, AIT_TYPE);
254         hwacc = appinfo_get_value(ai, AIT_HWACC);
255
256         __preexec_run(pkg_type, appid, app_path);
257
258         /* SET PRIVILEGES*/
259          SECURE_LOGD("appid : %s / pkg_type : %s / app_path : %s ", appid, pkg_type, app_path);
260         if (pkg_type && strncmp(pkg_type, "wgt", 3) !=0 && (ret = __set_access(appid, pkg_type, app_path)) < 0) {
261                  _D("fail to set privileges - check your package's credential : %d\n", ret);
262                 return;
263         }
264
265         /* SET DUMPABLE - for coredump*/
266         prctl(PR_SET_DUMPABLE, 1);
267
268         /* SET PROCESS NAME*/
269         if (app_path == NULL) {
270                 _D("app_path should not be NULL - check menu db");
271                 return;
272         }
273         file_name = strrchr(app_path, '/') + 1;
274         if (file_name == NULL) {
275                 _D("can't locate file name to execute");
276                 return;
277         }
278         memset(process_name, '\0', AUL_PR_NAME);
279         snprintf(process_name, AUL_PR_NAME, "%s", file_name);
280         prctl(PR_SET_NAME, process_name);
281
282         /* SET ENVIROMENT*/
283         _set_env(appid, kb, hwacc);
284 }
285
286 static char **__create_argc_argv(bundle * kb, int *margc)
287 {
288         char **argv;
289         int argc;
290
291         argc = bundle_export_to_argv(kb, &argv);
292
293         *margc = argc;
294         return argv;
295 }
296 static void _do_exec(const char *cmd, const char *group, bundle *kb)
297 {
298         gchar **argv;
299         gint argc;
300         char **b_argv;
301         int b_argc;
302         gboolean b;
303
304         b = g_shell_parse_argv(cmd, &argc, &argv, NULL);
305
306         if (kb) {
307                 b_argv = __create_argc_argv(kb, &b_argc);
308                 b_argv[0] = strdup(argv[0]);
309                 _prepare_exec(group, kb);
310                 execv(b_argv[0], b_argv);
311         }
312
313         if (b) {
314                 _prepare_exec(group, kb);
315                 execv(argv[0], argv);
316         }
317
318         _E("exec error: %s", strerror(errno));
319         g_strfreev(argv);
320 }
321
322 static inline int __send_app_launch_signal(int launch_pid)
323 {
324         DBusMessage *message;
325
326         if (conn == NULL)
327                 return -1;
328
329         message = dbus_message_new_signal(AUL_DBUS_PATH,
330                                           AUL_DBUS_SIGNAL_INTERFACE,
331                                           AUL_DBUS_APPLAUNCH_SIGNAL);
332
333         if (dbus_message_append_args(message,
334                                      DBUS_TYPE_UINT32, &launch_pid,
335                                      DBUS_TYPE_INVALID) == FALSE) {
336                 _E("Failed to load data error");
337                 return -1;
338         }
339
340         if (dbus_connection_send(conn, message, NULL) == FALSE) {
341                 _E("dbus send error");
342                 return -1;
343         }
344
345         dbus_connection_flush(conn);
346         dbus_message_unref(message);
347
348         _W("send launch signal done: %d", launch_pid);
349
350         return 0;
351 }
352
353 static int __send_watchdog_signal(int pid, int signal_num)
354 {
355         DBusMessage *message;
356
357         if (conn == NULL)
358                 return -1;
359
360         if (!_get_platform_ready()) {
361                 _E("[Info]_get_platform_ready return false");
362                 return -1;
363         }
364
365 #ifdef _APPFW_FEATURE_COOLDOWN_MODE_SUPPORT
366         if(_status_get_cooldown_status() == COOLDOWN_LIMIT) {
367                 _E("[Info]cooldown status : LimitAction");
368                 return -1;
369         }
370 #endif // _APPFW_FEATURE_COOLDOWN_MODE_SUPPORT
371
372         message = dbus_message_new_signal(RESOURCED_PROC_OBJECT,
373                                           RESOURCED_PROC_INTERFACE,
374                                           RESOURCED_PROC_WATCHDOG_SIGNAL);
375
376         if (dbus_message_append_args(message,
377                                      DBUS_TYPE_INT32, &pid,
378                                      DBUS_TYPE_INT32, &signal_num,
379                                      DBUS_TYPE_INVALID) == FALSE) {
380                 _E("Failed to load data error");
381                 return -1;
382         }
383
384         if (dbus_connection_send(conn, message, NULL) == FALSE) {
385                 _E("dbus send error");
386                 return -1;
387         }
388
389         dbus_connection_flush(conn);
390         dbus_message_unref(message);
391
392         _W("send a watchdog signal done: %d", pid);
393
394         return 0;
395 }
396
397 static int __send_proc_prelaunch_signal(const char *appid, const char *pkgid, int attribute)
398 {
399         DBusMessage *message;
400
401         if (conn == NULL)
402                 return -1;
403
404         message = dbus_message_new_signal(RESOURCED_PROC_OBJECT,
405                                           RESOURCED_PROC_INTERFACE,
406                                           RESOURCED_PROC_PRELAUNCH_SIGNAL);
407
408         if (dbus_message_append_args(message,
409                                          DBUS_TYPE_STRING, &appid,
410                                          DBUS_TYPE_STRING, &pkgid,
411                                      DBUS_TYPE_INT32, &attribute,
412                                      DBUS_TYPE_INVALID) == FALSE) {
413                 _E("Failed to load data error");
414                 return -1;
415         }
416
417         if (dbus_connection_send(conn, message, NULL) == FALSE) {
418                 _E("dbus send error");
419                 return -1;
420         }
421
422         dbus_connection_flush(conn);
423         dbus_message_unref(message);
424
425         SECURE_LOGW("send a prelaunch signal done: appid(%s) pkgid(%s) attribute(%x)", appid, pkgid, attribute);
426
427         return 0;
428 }
429
430 static int __check_cmdline(int ret)
431 {
432         char *cmdline;
433         int wait_count;
434         int cmdline_changed = 0;
435         int cmdline_exist = 0;
436
437         if (ret <= 1)
438                 return -1;
439
440         /* check normally was launched?*/
441         wait_count = 1;
442         do {
443                 cmdline = __proc_get_cmdline_bypid(ret);
444                 if (cmdline == NULL) {
445                         _E("error founded when being launched with %d", ret);
446                         if (cmdline_exist || cmdline_changed) {
447                                 _E("The app process might be terminated while we are wating %d", ret);
448                                 break;
449                         }
450                 } else if (strcmp(cmdline, amd_cmdline)) {
451                         free(cmdline);
452                         cmdline_changed = 1;
453                         break;
454                 } else {
455                         cmdline_exist = 1;
456                         free(cmdline);
457                 }
458
459                 _D("-- now wait to change cmdline --");
460                 usleep(50 * 1000);      /* 50ms sleep*/
461                 wait_count++;
462         } while (wait_count <= 20);     /* max 50*20ms will be sleep*/
463
464         if ((!cmdline_exist) && (!cmdline_changed)) {
465                 _E("cmdline_exist 0 & cmdline_changed 0");
466                 return -1;
467         }
468
469         if (!cmdline_changed)
470                 _E("process launched, but cmdline not changed");
471
472         return ret;
473 }
474
475 int start_process(const char *group, const char *cmd, bundle *kb)
476 {
477         int r;
478         pid_t p;
479
480         p = fork();
481         switch (p) {
482         case 0: /* child process */
483                 _D("start application");
484                 _signal_unblock_sigchld();
485 #ifdef _APPFW_FEATURE_PRIORITY_CHANGE
486                 r = setpriority(PRIO_PROCESS, 0, 0);
487                 if (r == -1)
488                 {
489                         SECURE_LOGE("Setting process (%d) priority to 0 failed, errno: %d (%s)",
490                                         getpid(), errno, strerror(errno));
491                 }
492 #endif
493                 _do_exec(cmd, group, kb);
494                 /* exec error */
495
496                 exit(0);
497                 break;
498         case -1:
499                 _E("application start: fork: %s", strerror(errno));
500                 r = -1;
501                 break;
502         default: /* parent process */
503                 _W("child process: %d", p);
504                 r = __check_cmdline(p);
505                 if(r > 0)
506                         __send_app_launch_signal(r);
507                 else
508                         _E("cmdline change failed.");
509                 break;
510         }
511
512         return r;
513 }
514
515 static int __check_ver(const char *required, const char *actual)
516 {
517         int ret = 0;
518         if (required && actual) {
519                 ret = strverscmp(required, actual); // should 0 or less
520                 if (ret < 1)
521                         return 1;
522         }
523
524         return 0;
525 }
526
527 static int __get_prelaunch_attribute(const struct appinfo *ai)
528 {
529         int attribute_val = 0;
530         const char *attribute_str = NULL;
531
532         attribute_str = appinfo_get_value(ai, AIT_ALLOWED_BG);
533         if (attribute_str && strncmp(attribute_str, "ALLOWED_BG", sizeof("ALLOWED_BG")) == 0) {
534                 attribute_val |= RESOURCED_ALLOWED_BG_ATTRIBUTE;
535         }
536
537 #ifdef _APPFW_FEATURE_BACKGROUND_MANAGEMENT
538         attribute_val |= RESOURCED_BACKGROUND_MANAGEMENT_ATTRIBUTE;
539 #endif
540
541         attribute_str = appinfo_get_value(ai, AIT_API_VER);
542         if (attribute_str && __check_ver("2.4", attribute_str)) {
543                 attribute_val |= RESOURCED_API_VER_2_4_ATTRIBUTE;
544         }
545
546         return attribute_val;
547 }
548
549 int _start_srv(const struct appinfo *ai)
550 {
551         int r;
552         bundle *b = NULL;
553         const char *group;
554         const char *cmd;
555         const char *pkgid;
556         const char *appid = NULL;
557         int prelaunch_attribute = 0;
558
559         group = appinfo_get_filename(ai);
560
561         cmd = appinfo_get_value(ai, AIT_EXEC);
562         if (!cmd) {
563                 _E("start service: '%s' has no exec", group);
564                 return -1;
565         }
566
567         appid = appinfo_get_value(ai, AIT_NAME);
568         pkgid = appinfo_get_value(ai, AIT_PKGID);
569
570         prelaunch_attribute = __get_prelaunch_attribute(ai);
571         if ((prelaunch_attribute & RESOURCED_ALLOWED_BG_ATTRIBUTE) ||
572                 !(prelaunch_attribute & RESOURCED_API_VER_2_4_ATTRIBUTE)) {
573                 SECURE_LOGD("[__SUSPEND__] allowed background, appid :%s, app_type: %s, api version: %s",
574                         appid, APP_TYPE_SERVICE, appinfo_get_value(ai,  AIT_API_VER));
575                 if (b == NULL) {
576                         b = bundle_create();
577                 }
578
579                 bundle_add(b, AUL_K_ALLOWED_BG, "ALLOWED_BG");
580         }
581
582         __send_proc_prelaunch_signal(appid, pkgid, prelaunch_attribute);
583
584         r = start_process(group, cmd, b);
585         if (b) {
586                 bundle_free(b);
587                 b = NULL;
588         }
589
590         if (r == -1) {
591                 _E("start service: '%s': failed", group);
592
593                 return -1;
594         }
595
596         aul_send_app_launch_request_signal(r, group, pkgid, APP_TYPE_SERVICE);
597         _status_add_app_info_list(group, cmd, NULL, r, -1, 0);
598
599         return 0;
600 }
601
602 static void _free_kt(struct ktimer *kt)
603 {
604         if (!kt)
605                 return;
606
607         free(kt->group);
608         free(kt);
609 }
610
611 static void _kill_pid(struct cginfo *cg, const char *group, pid_t pid)
612 {
613         int r;
614
615         if (pid <= INIT_PID) /* block sending to all process or init */
616                 return;
617
618         /* TODO: check pid exist in group */
619
620         r = kill(pid, 0);
621         if (r == -1) {
622                 _E("send SIGKILL: pid %d not exist", pid);
623                 return;
624         }
625
626         r = kill(pid, SIGKILL);
627         if (r == -1)
628                 _E("send SIGKILL: %s", strerror(errno));
629 }
630
631 static gboolean _ktimer_cb(gpointer data)
632 {
633         struct ktimer *kt = data;
634
635         _kill_pid(kt->cg, kt->group, kt->pid);
636         _kill_list = g_list_remove(_kill_list, kt);
637         _free_kt(kt);
638
639         return FALSE;
640 }
641
642 static void _add_list(struct cginfo *cg, const char *group, pid_t pid)
643 {
644         struct ktimer *kt;
645
646         kt = calloc(1, sizeof(*kt));
647         if (!kt)
648                 return;
649
650         kt->pid = pid;
651         kt->group = strdup(group);
652         if (!kt->group) {
653                 free(kt);
654                 return;
655         }
656
657         kt->tid = g_timeout_add_seconds(TERM_WAIT_SEC, _ktimer_cb, kt);
658
659         _kill_list = g_list_append(_kill_list, kt);
660 }
661
662 static inline void _del_list(GList *l)
663 {
664         struct ktimer *kt;
665
666         if (!l)
667                 return;
668
669         kt = l->data;
670
671         g_source_remove(kt->tid);
672         _free_kt(kt);
673         _kill_list = g_list_delete_link(_kill_list, l);
674 }
675
676 static int _kill_pid_cb(void *user_data, const char *group, pid_t pid)
677 {
678         int r;
679
680         if (pid <= INIT_PID) /* block sending to all process or init */
681                 return 0;
682
683         r = kill(pid, SIGTERM);
684         if (r == -1)
685                 _E("send SIGTERM: %s", strerror(errno));
686
687         _add_list(user_data, group, pid);
688
689         return 0;
690 }
691
692 void service_release(const char *group)
693 {
694         GList *l;
695         GList *d;
696
697         if (!group || !*group)
698                 return;
699
700         group = FILENAME(group);
701
702         d = NULL;
703         for (l = _kill_list; l; l = g_list_next(l)) {
704                 struct ktimer *k = l->data;
705
706                 _del_list(d);
707
708                 if (k->group && !strcmp(k->group, group))
709                         d = l;
710                 else
711                         d = NULL;
712         }
713
714         _del_list(d);
715 }
716
717 int _send_to_sigkill(int pid)
718 {
719         int pgid;
720
721         pgid = getpgid(pid);
722         if (pgid <= 1)
723                 return -1;
724
725         if (killpg(pgid, SIGKILL) < 0)
726                 return -1;
727
728         return 0;
729 }
730 int _resume_app(int pid, int clifd)
731 {
732         int dummy;
733         int ret;
734         if ((ret =
735              __app_send_raw_with_delay_reply(pid, APP_RESUME_BY_PID, (unsigned char *)&dummy,
736                             sizeof(int))) < 0) {
737                 if (ret == -EAGAIN)
738                         _E("resume packet timeout error");
739                 else {
740                         _E("raise failed - %d resume fail\n", pid);
741                         _E("we will term the app - %d\n", pid);
742                         _send_to_sigkill(pid);
743                         ret = -1;
744                 }
745                 __real_send(clifd, ret);
746         }
747         _W("resume done\n");
748
749         if (ret > 0)
750                 __set_reply_handler(ret, pid, clifd, APP_RESUME_BY_PID);
751
752         return ret;
753 }
754
755 int _pause_app(int pid, int clifd)
756 {
757         int dummy;
758         int ret;
759         if ((ret =
760             __app_send_raw_with_delay_reply(pid, APP_PAUSE_BY_PID, (unsigned char *)&dummy,
761                             sizeof(int))) < 0) {
762                 if (ret == -EAGAIN)
763                         _E("pause packet timeout error");
764                 else {
765                         _E("iconify failed - %d pause fail\n", pid);
766                         _E("we will term the app - %d\n", pid);
767                         _send_to_sigkill(pid);
768                         ret = -1;
769                 }
770         }
771         _D("pause done\n");
772
773         if (ret > 0)
774                 __set_reply_handler(ret, pid, clifd, APP_PAUSE_BY_PID);
775
776         return ret;
777 }
778
779 int _fake_launch_app(int cmd, int pid, bundle * kb, int clifd)
780 {
781         int datalen;
782         int ret;
783         bundle_raw *kb_data = NULL;
784
785         if (!kb){
786                 __real_send(clifd, -EINVAL);
787                 return -EINVAL;
788         }
789
790         ret = bundle_encode(kb, &kb_data, &datalen);
791         if (ret != BUNDLE_ERROR_NONE) {
792                 __real_send(clifd, -EINVAL);
793                 return -EINVAL;
794         }
795         if ((ret = __app_send_raw_with_delay_reply(pid, cmd, kb_data, datalen)) < 0) {
796                 _E("error request fake launch - error code = %d", ret);
797                 __real_send(clifd, ret);
798         }
799         free(kb_data);
800
801         if (ret > 0)
802                 __set_reply_handler(ret, pid, clifd, cmd);
803
804         return ret;
805 }
806
807 static void __real_send(int clifd, int ret)
808 {
809         if(clifd <= 0) {
810                 return;
811         }
812         if (send(clifd, &ret, sizeof(int), MSG_NOSIGNAL) < 0) {
813                 if (errno == EPIPE) {
814                         _E("send failed due to EPIPE.\n");
815                 }
816                 _E("send fail to client");
817         }
818
819         close(clifd);
820 }
821
822 static gboolean __au_glib_check(GSource *src)
823 {
824         GSList *fd_list;
825         GPollFD *tmp;
826
827         fd_list = src->poll_fds;
828         do {
829                 tmp = (GPollFD *) fd_list->data;
830                 if ((tmp->revents & (POLLIN | POLLPRI)))
831                         return TRUE;
832                 fd_list = fd_list->next;
833         } while (fd_list);
834
835         return FALSE;
836 }
837
838 static gboolean __au_glib_dispatch(GSource *src, GSourceFunc callback,
839                 gpointer data)
840 {
841         callback(data);
842         return TRUE;
843 }
844
845 static gboolean __au_glib_prepare(GSource *src, gint *timeout)
846 {
847         return FALSE;
848 }
849
850 static GSourceFuncs funcs = {
851         .prepare = __au_glib_prepare,
852         .check = __au_glib_check,
853         .dispatch = __au_glib_dispatch,
854         .finalize = NULL
855 };
856
857 struct reply_info {
858         GSource *src;
859         GPollFD *gpollfd;
860         guint timer_id;
861         int clifd;
862         int pid;
863         int cmd;
864 };
865
866 static gboolean __reply_handler(gpointer data)
867 {
868         struct reply_info *r_info = (struct reply_info *) data;;
869         int fd = r_info->gpollfd->fd;
870         int len;
871         int res = 0;
872         int clifd = r_info->clifd;
873         int pid = r_info->pid;
874         int cmd = r_info->cmd;
875
876         len = recv(fd, &res, sizeof(int), 0);
877         if (len == -1) {
878                 if (errno == EAGAIN) {
879                         _E("recv timeout : %s", strerror(errno));
880                         res = -EAGAIN;
881                 } else {
882                         _E("recv error : %s", strerror(errno));
883                         res = -ECOMM;
884                 }
885         }
886         close(fd);
887
888         if(res < 0) {
889                 if (cmd == APP_TERM_BY_PID || cmd == APP_TERM_BGAPP_BY_PID) {
890                         __real_send(clifd, -1);
891                 } else if (cmd == APP_START_ASYNC || cmd == APP_PAUSE_BY_PID) {
892                         close(clifd);
893                 } else {
894                         __real_send(clifd, res);
895                 }
896         } else {
897                 if (cmd == APP_TERM_BY_PID || cmd == APP_TERM_BGAPP_BY_PID) {
898                         __real_send(clifd, 0);
899                 } else if (cmd == APP_START_ASYNC || cmd == APP_PAUSE_BY_PID) {
900                         close(clifd);
901                 } else {
902                         __real_send(clifd, pid);
903                 }
904         }
905
906         _W("listen fd(%d) , send fd(%d), pid(%d), cmd(%d)", fd, clifd, pid, cmd);
907
908         g_source_remove(r_info->timer_id);
909         g_source_remove_poll(r_info->src, r_info->gpollfd);
910         g_source_destroy(r_info->src);
911         g_free(r_info->gpollfd);
912         free(r_info);
913
914         return TRUE;
915 }
916
917 static gboolean __recv_timeout_handler(gpointer data)
918 {
919         struct reply_info *r_info = (struct reply_info *) data;
920         int fd = r_info->gpollfd->fd;
921         char *appid = NULL;
922         const struct appinfo *ai;
923         int task_manage = 0;
924
925         _E("application is not responding : pid(%d) cmd(%d)", r_info->pid, r_info->cmd);
926
927         close(fd);
928
929         switch (r_info->cmd) {
930         case APP_OPEN:
931         case APP_RESUME:
932         case APP_START:
933         case APP_START_RES:
934         case APP_START_ASYNC:
935 #ifdef _APPFW_FEATURE_MULTI_INSTANCE
936         case APP_START_MULTI_INSTANCE:
937 #endif
938                 appid = _status_app_get_appid_bypid(r_info->pid);
939                 if(appid == NULL)
940                         break;
941                 ai = appinfo_find(_laf, appid);
942                 if(ai == NULL) {
943                         _E("ai is NULL");
944                         break;
945                 }
946                 task_manage = appinfo_get_boolean(ai, AIT_TASKMANAGE);
947                 if(task_manage) {
948                         __send_watchdog_signal(r_info->pid, SIGKILL);
949                 }
950                 break;
951         case APP_TERM_BY_PID:
952         case APP_TERM_BGAPP_BY_PID:
953                 if (_send_to_sigkill(r_info->pid) < 0) {
954                         _E("fail to killing - %d\n", r_info->pid);
955                         __real_send(r_info->clifd, -1);
956                 } else {
957                         __real_send(r_info->clifd, 0);
958                 }
959                 break;
960         }
961
962         g_source_remove_poll(r_info->src, r_info->gpollfd);
963         g_source_destroy(r_info->src);
964         g_free(r_info->gpollfd);
965         free(r_info);
966
967         return FALSE;
968 }
969
970 static void __set_reply_handler(int fd, int pid, int clifd, int cmd)
971 {
972         GPollFD *gpollfd;
973         GSource *src;
974         struct reply_info *r_info;
975
976         src = g_source_new(&funcs, sizeof(GSource));
977
978         gpollfd = (GPollFD *) g_malloc(sizeof(GPollFD));
979         if (gpollfd == NULL) {
980                 _E("out of memory");
981                 g_source_unref(src);
982                 return;
983         }
984         gpollfd->events = POLLIN;
985         gpollfd->fd = fd;
986
987         r_info = malloc(sizeof(*r_info));
988         if (r_info == NULL) {
989                 _E("out of memory");
990                 g_free(gpollfd);
991                 g_source_unref(src);
992                 return;
993         }
994
995         r_info->clifd = clifd;
996         r_info->pid = pid;
997         r_info->src = src;
998         r_info->gpollfd = gpollfd;
999         r_info->cmd = cmd;
1000
1001
1002         r_info->timer_id = g_timeout_add(5000, __recv_timeout_handler, (gpointer) r_info);
1003         g_source_add_poll(src, gpollfd);
1004         g_source_set_callback(src, (GSourceFunc) __reply_handler,
1005                         (gpointer) r_info, NULL);
1006         g_source_set_priority(src, G_PRIORITY_DEFAULT);
1007         g_source_attach(src, NULL);
1008
1009         _D("listen fd : %d, send fd : %d", fd, clifd);
1010 }
1011
1012 void _term_sub_app(int pid)
1013 {
1014         int dummy;
1015         int ret;
1016
1017         if ( (ret = __app_send_raw_with_noreply(pid, APP_TERM_BY_PID_ASYNC,
1018                                         (unsigned char *)&dummy, sizeof(int))) < 0) {
1019                 _E("terminate packet send error - use SIGKILL");
1020                 if (_send_to_sigkill(pid) < 0) {
1021                         _E("fail to killing - %d\n", pid);
1022                         return;
1023                 }
1024         }
1025 }
1026
1027 int _term_app(int pid, int clifd)
1028 {
1029         int dummy;
1030         int ret;
1031
1032         if (app_group_is_leader_pid(pid)) {
1033                 int cnt;
1034                 int *pids = NULL;
1035                 int i;
1036
1037                 app_group_get_group_pids(pid, &cnt, &pids);
1038                 if (cnt > 0) {
1039                         for (i = cnt-1 ; i>=0; i--) {
1040                                 if (i != 0)
1041                                         _term_sub_app(pids[i]);
1042                                 app_group_remove(pids[i]);
1043
1044                         }
1045                 }
1046                 if (pids)
1047                         free(pids);
1048         }
1049
1050         if ( (ret = __app_send_raw_with_delay_reply
1051             (pid, APP_TERM_BY_PID, (unsigned char *)&dummy, sizeof(int))) < 0) {
1052                 _D("terminate packet send error - use SIGKILL");
1053                 if (_send_to_sigkill(pid) < 0) {
1054                         _E("fail to killing - %d\n", pid);
1055                         __real_send(clifd, -1);
1056                         return -1;
1057                 }
1058                 __real_send(clifd, 0);
1059         }
1060         _D("term done\n");
1061         if (ret > 0)
1062                 __set_reply_handler(ret, pid, clifd, APP_TERM_BY_PID);
1063
1064         return 0;
1065 }
1066
1067 int _term_req_app(int pid, int clifd)
1068 {
1069         int dummy;
1070         int ret;
1071
1072         if ( (ret = __app_send_raw_with_delay_reply
1073                 (pid, APP_TERM_REQ_BY_PID, (unsigned char *)&dummy, sizeof(int))) < 0) {
1074                 _D("terminate req send error");
1075                 __real_send(clifd, ret);
1076         }
1077
1078         if (ret > 0)
1079                 __set_reply_handler(ret, pid, clifd, APP_TERM_REQ_BY_PID);
1080
1081         return 0;
1082 }
1083
1084 int _term_bgapp(int pid, int clifd)
1085 {
1086         int dummy;
1087         int fd;
1088
1089         if (app_group_is_leader_pid(pid)) {
1090                 int cnt;
1091                 int *pids = NULL;
1092                 int i;
1093                 int status = -1;
1094
1095                 app_group_get_group_pids(pid, &cnt, &pids);
1096                 if (cnt > 0) {
1097                         status = _status_get_app_info_status(pids[cnt-1]);
1098                         if(status == STATUS_BG) {
1099                                 for (i = cnt-1 ; i>=0; i--) {
1100                                         if (i != 0)
1101                                                 _term_sub_app(pids[i]);
1102                                         app_group_remove(pids[i]);
1103                                 }
1104                         }
1105                 }
1106                 if (pids)
1107                         free(pids);
1108         }
1109
1110         if ( (fd = __app_send_raw_with_delay_reply
1111             (pid, APP_TERM_BGAPP_BY_PID, (unsigned char *)&dummy, sizeof(int))) < 0) {
1112                 _D("terminate packet send error - use SIGKILL");
1113                 if (_send_to_sigkill(pid) < 0) {
1114                         _E("fail to killing - %d\n", pid);
1115                         __real_send(clifd, -1);
1116                         return -1;
1117                 }
1118                 __real_send(clifd, 0);
1119         }
1120         _D("term_bgapp done\n");
1121         if (fd > 0)
1122                 __set_reply_handler(fd, pid, clifd, APP_TERM_BGAPP_BY_PID);
1123
1124         return 0;
1125 }
1126
1127 #include <dirent.h>
1128 #include <sqlite3.h>
1129 static int __launchpad_update_task_managed_field(const char* app_id, int task_managed)
1130 {
1131         sqlite3 *db = NULL;
1132         char *sqlite3_error_msg = NULL;
1133
1134         if (sqlite3_open("/opt/dbspace/.pkgmgr_parser.db", &db) != SQLITE_OK) {
1135             _E("sqlite3_open() failed! -> %s\n", sqlite3_errmsg(db));
1136             return -1;
1137         }
1138
1139         if (sqlite3_exec(db, "PRAGMA journal_mode = PERSIST", NULL, NULL, &sqlite3_error_msg) != SQLITE_OK) {
1140             _E("sqlite3_exec(\"PRAGMA journal_mode = PERSIST\") failed! -> %s", sqlite3_error_msg);
1141             sqlite3_free(sqlite3_error_msg);
1142             sqlite3_close(db);
1143             return -1;
1144         }
1145
1146         if (sqlite3_exec(db, "BEGIN EXCLUSIVE", NULL, NULL, &sqlite3_error_msg) != SQLITE_OK) {
1147                 _E("sqlite3_exec(\"BEGIN EXCLUSIVE\") failed! -> %s", sqlite3_error_msg);
1148             sqlite3_free(sqlite3_error_msg);
1149                 sqlite3_close(db);
1150                 return -1;
1151         }
1152
1153         char query[1024] = {0, };
1154         snprintf(query, 1024,"update package_app_info set app_taskmanage='%s' where app_id='%s'",
1155                 task_managed ? "true" : "false", app_id);
1156
1157         if (sqlite3_exec(db, query, NULL, NULL, &sqlite3_error_msg) != SQLITE_OK) {
1158                 _E("sqlite3_exec(\"%s\") failed! -> %s", query, sqlite3_error_msg);
1159                 sqlite3_free(sqlite3_error_msg);
1160                 return -1;
1161         }
1162
1163         if (sqlite3_exec(db, "COMMIT", NULL, NULL, NULL) != SQLITE_OK) {
1164                 _E("sqlite3_exec(\"COMMIT\") failed!");
1165                 if (sqlite3_exec(db, "ROLLBACK", NULL, NULL, NULL) != SQLITE_OK) {
1166                         _E("sqlite3_exec(\"ROLLBACK\") failed!");
1167                 }
1168                 sqlite3_close(db);
1169                 return -1;
1170         }
1171
1172         sqlite3_close(db);
1173
1174 return 0;
1175 }
1176
1177 static void __pre_launching_processing(const char* app_id)
1178 {
1179     const char* const PRE_LAUNCHING_LIST_DIR = "/opt/usr/etc/wrt_launchpad_daemon/pre_launching_list";
1180
1181     struct stat file_status;
1182     if (stat(PRE_LAUNCHING_LIST_DIR, &file_status) == 0) {
1183         if (S_ISDIR(file_status.st_mode)) {
1184             int ret;
1185             DIR *dir = NULL;
1186             struct dirent entry, *result = NULL;
1187
1188             dir = opendir(PRE_LAUNCHING_LIST_DIR);
1189
1190             if (dir) {
1191                 for (ret = readdir_r(dir, &entry, &result);
1192                      result != NULL && ret == 0;
1193                      ret = readdir_r(dir, &entry, &result)) {
1194                     if (strncmp(entry.d_name, ".", 2) == 0 ||
1195                         strncmp(entry.d_name, "..", 3) == 0) {
1196                         continue;
1197                     }
1198
1199                     if (strcmp(entry.d_name, app_id) == 0)
1200                     {
1201                         __launchpad_update_task_managed_field(app_id, 1);
1202                     }
1203                 }
1204
1205                 closedir(dir);
1206             }
1207             else {
1208                 _E("opendir(\"%s\") failed!", PRE_LAUNCHING_LIST_DIR);
1209             }
1210         }
1211     }
1212 }
1213
1214 static int __nofork_processing(int cmd, int pid, bundle * kb, int clifd)
1215 {
1216         int ret = -1;
1217 #ifdef _APPFW_FEATURE_CPU_BOOST
1218         const char *operation;
1219
1220         operation = bundle_get_val(kb, "__APP_SVC_OP_TYPE__");
1221
1222         //TODO: CPU boosting for relaunching will be removed.
1223         //Home screen requests CPU boosting on launching or relaunching during 200 msec.
1224         if (cmd == APP_OPEN ||
1225                         (operation != NULL && strncmp(operation, "http://tizen.org/appcontrol/operation/main", 512) == 0)) {
1226                 char *arr[2];
1227                 char val[32];
1228                 snprintf(val, sizeof(val), "%d", APP_BOOSTING_PERIOD);
1229                 arr[0] = val;
1230                 arr[1] = NULL;
1231                 ret = invoke_dbus_method_sync(SYSTEM_BUS_NAME, SYSTEM_OBJECT_PATH,
1232                                 SYSTEM_INTERFACE_NAME, SYSTEM_METHOD_NAME, "i", arr);
1233                 _D("%s-%s : %d", SYSTEM_INTERFACE_NAME, SYSTEM_METHOD_NAME, ret);
1234         }
1235 #endif
1236         _W("__nofork_processing, cmd: %d, pid: %d", cmd, pid);
1237         switch (cmd) {
1238         case APP_OPEN:
1239         case APP_RESUME:
1240                 _D("resume app's pid : %d\n", pid);
1241                 if ((ret = _resume_app(pid, clifd)) < 0)
1242                         _E("__resume_app failed. error code = %d", ret);
1243                 _D("resume app done");
1244                 break;
1245
1246         case APP_START:
1247         case APP_START_RES:
1248         case APP_START_ASYNC:
1249 #ifdef _APPFW_FEATURE_MULTI_INSTANCE
1250         case APP_START_MULTI_INSTANCE:
1251 #endif
1252                 _D("fake launch pid : %d\n", pid);
1253                 if ((ret = _fake_launch_app(cmd, pid, kb, clifd)) < 0)
1254                         _E("fake_launch failed. error code = %d", ret);
1255                 _D("fake launch done");
1256                 break;
1257
1258         default:
1259                 break;
1260         }
1261
1262         return ret;
1263 }
1264
1265 #if __CPU_FREQ_CON
1266 #include <sysman.h>
1267 static Eina_Bool
1268 __amd_sysman_restore_hz_timer_cb(void *data)
1269 {
1270    struct context *ctxt = data;
1271
1272    if (ctxt->timer)
1273      ctxt->timer = NULL;
1274
1275    sysman_release_cpu_min_frequency ();
1276
1277    _D("*******[1.6MHZ Support] Released\n " );
1278
1279    return ECORE_CALLBACK_CANCEL; // same as EINA_FALSE
1280 }
1281 #endif
1282
1283 struct context{
1284         Ecore_Timer *timer;
1285 };
1286
1287 #ifdef _APPFW_FEATURE_FAKE_EFFECT
1288 static void __amd_effect_image_file_set(char *image_file)
1289 {
1290         Ecore_X_Window root_win;
1291
1292         if(!_window_is_initialized())
1293                 return;
1294
1295         root_win = ecore_x_window_root_first_get();
1296         SECURE_LOGD("path : %s", image_file);
1297         ecore_x_window_prop_string_set(root_win, ATOM_IMAGE_EFFECT,image_file);
1298 }
1299
1300
1301 static void __amd_send_message_to_e17(int screenmode, const char * indicator, int effect_type, int theme)
1302 {
1303         Ecore_X_Window root_win;
1304         int ret;
1305
1306         if(!_window_is_initialized())
1307                 return;
1308
1309         root_win = ecore_x_window_root_first_get();
1310          _D("root win : %x",root_win);
1311         int screen_orientation[5]={0,0,270,180,90};
1312         if (screenmode > 4 || screenmode < 0)
1313                 screenmode=0;
1314
1315         if (strncmp(indicator, "true", 4) == 0){
1316                 _D("[LAUNCHING EFFECT]: screen mode(%d), effect type(%d), theme(%d), indicator show",
1317                         screen_orientation[screenmode], effect_type, theme);
1318                 ret = ecore_x_client_message32_send (root_win, ATOM_IMAGE_EFFECT,
1319                         ECORE_X_EVENT_MASK_WINDOW_PROPERTY, effect_type,
1320                         screen_orientation[screenmode],
1321                         SHOW_INDICATOR, theme, 0);
1322
1323         }else{
1324                 _D("[LAUNCHING EFFECT]: screen mode(%d), effect type(%d), theme(%d), indicator show",
1325                         screen_orientation[screenmode], effect_type, theme);
1326                 ret = ecore_x_client_message32_send (root_win, ATOM_IMAGE_EFFECT,
1327                         ECORE_X_EVENT_MASK_WINDOW_PROPERTY, effect_type,
1328                         screen_orientation[screenmode],
1329                         HIDE_INDICATOR, theme, 0);
1330         }
1331         ecore_x_flush();
1332         _D("ecore_x_client_message32_send : %d",ret);
1333 }
1334 #endif
1335
1336 static int append_variant(DBusMessageIter *iter, const char *sig, char *param[])
1337 {
1338         char *ch;
1339         int i;
1340         int int_type;
1341         uint64_t int64_type;
1342
1343         if (!sig || !param)
1344                 return 0;
1345
1346         for (ch = (char*)sig, i = 0; *ch != '\0'; ++i, ++ch) {
1347                 switch (*ch) {
1348                 case 'i':
1349                         int_type = atoi(param[i]);
1350                         dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &int_type);
1351                         break;
1352                 case 'u':
1353                         int_type = atoi(param[i]);
1354                         dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, &int_type);
1355                         break;
1356                 case 't':
1357                         int64_type = atoi(param[i]);
1358                         dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT64, &int64_type);
1359                         break;
1360                 case 's':
1361                         dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, param[i]);
1362                         break;
1363                 default:
1364                         return -EINVAL;
1365                 }
1366         }
1367
1368         return 0;
1369 }
1370
1371 int invoke_dbus_method_sync(const char *dest, const char *path,
1372                 const char *interface, const char *method,
1373                 const char *sig, char *param[])
1374 {
1375         DBusMessage *msg;
1376         DBusMessageIter iter;
1377         DBusMessage *reply;
1378         DBusError err;
1379         int r, ret;
1380
1381         msg = dbus_message_new_method_call(dest, path, interface, method);
1382         if (!msg) {
1383                 _E("dbus_message_new_method_call(%s:%s-%s)", path, interface, method);
1384                 return -EBADMSG;
1385         }
1386
1387         if( param ) {
1388                 dbus_message_iter_init_append(msg, &iter);
1389                 r = append_variant(&iter, sig, param);
1390                 if (r < 0) {
1391                         _E("append_variant error(%d)", r);
1392                         dbus_message_unref(msg);
1393                         return -EBADMSG;
1394                 }
1395         }
1396
1397         dbus_error_init(&err);
1398
1399         reply = dbus_connection_send_with_reply_and_block(conn, msg, 500, &err);
1400         dbus_message_unref(msg);
1401         if (!reply) {
1402                 _E("dbus_connection_send error(%s:%s)", err.name, err.message);
1403                 dbus_error_free(&err);
1404                 return -EBADMSG;
1405         }
1406
1407         r = dbus_message_get_args(reply, &err, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INVALID);
1408         dbus_message_unref(reply);
1409         if (!r) {
1410                 _E("no message : [%s:%s]", err.name, err.message);
1411                 dbus_error_free(&err);
1412                 return -EBADMSG;
1413         }
1414
1415         return ret;
1416 }
1417
1418 #ifdef _APPFW_FEATURE_AMD_KEY
1419 static gboolean __grab_timeout_handler(gpointer data)
1420 {
1421         int pid = (int) data;
1422
1423         if(_input_window_get() != 0)
1424                 ecore_x_pointer_ungrab();
1425         _D("pid(%d) ecore_x_pointer_ungrab", pid);
1426         if(_key_ungrab(KEY_BACK) < 0) {
1427                 _W("back key ungrab error");
1428         } else {
1429                 _D("back key ungrab");
1430         }
1431
1432         return FALSE;
1433 }
1434 #endif
1435
1436 #ifdef _APPFW_FEATURE_EXPANSION_PKG_INSTALL
1437 static int __tep_mount(char *mnt_path[])
1438 {
1439         DBusMessage *msg;
1440         int func_ret = 0;
1441         int rv = 0;
1442         struct stat link_buf = {0,};
1443
1444         rv = lstat(mnt_path[0], &link_buf);
1445         if (rv == 0) {
1446                 rv = unlink(mnt_path[0]);
1447                 if (rv)
1448                         _E("Unable tp remove link file %s", mnt_path[0]);
1449         }
1450
1451         msg = dbus_message_new_method_call(TEP_BUS_NAME, TEP_OBJECT_PATH,
1452                                            TEP_INTERFACE_NAME, TEP_MOUNT_METHOD);
1453         if (!msg) {
1454                 _E("dbus_message_new_method_call(%s:%s-%s)", TEP_OBJECT_PATH,
1455                    TEP_INTERFACE_NAME, TEP_MOUNT_METHOD);
1456                 return -1;
1457         }
1458
1459         if (!dbus_message_append_args(msg,
1460                                       DBUS_TYPE_STRING, &mnt_path[0],
1461                                       DBUS_TYPE_STRING, &mnt_path[1],
1462                                       DBUS_TYPE_INVALID)) {
1463                 _E("Ran out of memory while constructing args\n");
1464                 func_ret = -1;
1465                 goto func_out;
1466         }
1467
1468         if (dbus_connection_send(conn, msg, NULL) == FALSE) {
1469                 _E("dbus_connection_send error");
1470                 func_ret = -1;
1471                 goto func_out;
1472         }
1473 func_out :
1474         dbus_message_unref(msg);
1475         return func_ret;
1476 }
1477
1478 static void __send_mount_request(const struct appinfo *ai, const char *tep_name,
1479                                  bundle *kb)
1480 {
1481         SECURE_LOGD("tep name is: %s", tep_name);
1482         char *mnt_path[2] = {NULL, };
1483         const char *installed_storage = NULL;
1484         char tep_path[PATH_MAX] = {0, };
1485
1486         const char *pkgid = appinfo_get_value(ai, AIT_PKGID);
1487         installed_storage = appinfo_get_value(ai, AIT_STORAGE_TYPE);
1488         if (installed_storage != NULL) {
1489                 SECURE_LOGD("storage: %s", installed_storage);
1490                 if (strncmp(installed_storage, "internal", 8) == 0) {
1491                         snprintf(tep_path, PATH_MAX, "%s%s/res/%s", appfw_env_get_apps_path(), pkgid,
1492                                  tep_name);
1493                         mnt_path[1] = strdup(tep_path);
1494                         snprintf(tep_path, PATH_MAX, "%s%s/res/tep", appfw_env_get_apps_path(), pkgid);
1495                         mnt_path[0] = strdup(tep_path);
1496                 } else if (strncmp(installed_storage, "external", 8) == 0) {
1497                         snprintf(tep_path, PATH_MAX, "%step/%s", appfw_env_get_external_storage_path(),
1498                                  tep_name);
1499                         mnt_path[1] = strdup(tep_path);
1500                         snprintf(tep_path, PATH_MAX, "%step/tep-access",
1501                                  appfw_env_get_external_storage_path()); /* TODO : keeping tep/tep-access for now for external storage */
1502                         mnt_path[0] = strdup(tep_path);
1503                 }
1504
1505                 if (mnt_path[0] && mnt_path[1]) {
1506                         bundle_add(kb, AUL_TEP_PATH, mnt_path[0]);
1507                         int ret = -1;
1508                         ret = aul_is_tep_mount_dbus_done(mnt_path[0]);
1509                         if (ret != 1) {
1510                                 ret = __tep_mount(mnt_path);
1511                                 if (ret < 0)
1512                                         _E("dbus error %d", ret);
1513                         }
1514                 }
1515                 if (mnt_path[0])
1516                         free(mnt_path[0]);
1517                 if (mnt_path[1])
1518                         free(mnt_path[1]);
1519         }
1520 }
1521 #endif
1522
1523 static int __check_app_control_privilege(const char *operation, int caller_pid, const struct appinfo *caller)
1524 {
1525         int ret;
1526         const char *api_ver;
1527
1528         if (caller == NULL) // daemon
1529                 return 0;
1530
1531         if (operation == NULL || caller_pid < 1)
1532                 return 0;
1533
1534         if (strcmp(operation, AUL_SVC_OPERATION_DOWNLOAD) == 0) {
1535                 api_ver = appinfo_get_value(caller, AIT_API_VER);
1536
1537                 if (!api_ver) {
1538                         _E("failed to get api version");
1539                         return -1;
1540                 }
1541
1542                 if (api_ver && strverscmp("2.4", api_ver) < 1) { // ver 2.4 or later
1543                         ret = security_server_check_privilege_by_pid(caller_pid, "privilege::tizen::download", "rw");
1544                         if (ret != SECURITY_SERVER_API_SUCCESS) {
1545                                 _E("caller %d violates http://tizen.org/privilege/download privilege", caller_pid);
1546                                 return -EILLEGALACCESS;
1547                         }
1548                 }
1549         } else if (strcmp(operation, AUL_SVC_OPERATION_CALL) == 0) {
1550                 // Check the privilege for call operation
1551                 ret = security_server_check_privilege_by_pid(caller_pid, "privilege::tizen::call", "rw");
1552                 if (ret != SECURITY_SERVER_API_SUCCESS) {
1553                         _E("caller %d violates http://tizen.org/privilege/call privilege", caller_pid);
1554                         return -EILLEGALACCESS;
1555                 }
1556         }
1557
1558         return 0;
1559 }
1560
1561
1562 int __check_mode(const struct appinfo *ai)
1563 {
1564 #ifdef _APPFW_FEATURE_TTS_MODE
1565         int tts_mode = 0;
1566         const char *tts_support = NULL;
1567 #endif
1568 #ifdef _APPFW_FEATURE_ULTRA_POWER_SAVING_MODE
1569         int ups_mode = 0;
1570 #endif
1571
1572 #ifdef _APPFW_FEATURE_TTS_MODE
1573         vconf_get_bool(VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, &tts_mode);
1574         if(tts_mode) {
1575                 tts_support = appinfo_get_value(ai, AIT_TTS);
1576                 _W("tts : %d %s", tts_mode, tts_support);
1577                 if(strncmp(tts_support, "false", 5) == 0) {
1578                         _W("Cannot launch this app in TTS mode");
1579                         return -1;
1580                 }
1581         }
1582 #endif
1583
1584 #ifdef _APPFW_FEATURE_ULTRA_POWER_SAVING_MODE
1585         vconf_get_int(VCONFKEY_SETAPPL_PSMODE, &ups_mode);
1586         if (ups_mode == SETTING_PSMODE_EMERGENCY) {
1587                 const char *ups_support = appinfo_get_value(ai, AIT_UPS);
1588                 _W("ups : %d %s", ups_mode, ups_support);
1589         }
1590 #endif //_APPFW_FEATURE_ULTRA_POWER_SAVING_MODE
1591
1592         return 0;
1593 }
1594
1595 static void __prepare_to_suspend_services(int pid)
1596 {
1597         int dummy;
1598         SECURE_LOGD("[__SUSPEND__] pid: %d", pid);
1599         __app_send_raw_with_noreply(pid, APP_SUSPEND, (unsigned char *)&dummy, sizeof(int));
1600 }
1601
1602 static void __prepare_to_wake_services(int pid)
1603 {
1604         int dummy;
1605         SECURE_LOGD("[__SUSPEND__] pid: %d", pid);
1606         __app_send_raw_with_noreply(pid, APP_WAKE, (unsigned char *)&dummy, sizeof(int));
1607 }
1608
1609 static gboolean __check_service_only(gpointer user_data)
1610 {
1611         int pid = GPOINTER_TO_INT(user_data);
1612         SECURE_LOGD("[__SUSPEND__] pid :%d", pid);
1613
1614         _status_check_service_only(pid, __prepare_to_suspend_services);
1615
1616         return FALSE;
1617 }
1618
1619 #ifdef _APPFW_FEATURE_PRIVATE_SERVICE
1620 static int __get_visibility_from_cert_svc(const char *pkgid, int *visibility)
1621 {
1622         int ret = 0;
1623         const char *cert_value = NULL;
1624         pkgmgrinfo_certinfo_h certinfo = NULL;
1625
1626         ret = pkgmgrinfo_pkginfo_create_certinfo(&certinfo);
1627         if (ret != 0) {
1628                 _E("pkgmgrinfo_pkginfo_create_certinfo() failed.");
1629                 return -1;
1630         }
1631
1632         ret = pkgmgrinfo_pkginfo_load_certinfo(pkgid, certinfo);
1633         if (ret != 0) {
1634                 _E("pkgmgrinfo_pkginfo_load_certinfo() failed.");
1635                 ret = -1;
1636                 goto end;
1637         }
1638
1639         ret = pkgmgrinfo_pkginfo_get_cert_value(certinfo, PMINFO_DISTRIBUTOR_ROOT_CERT,
1640                                                 &cert_value);
1641         if (ret != 0 || cert_value == NULL) {
1642                 _E("pkgmgrinfo_pkginfo_get_cert_value() failed.");
1643                 ret = -1;
1644                 goto end;
1645         }
1646
1647         ret = cert_svc_get_visibility_by_root_certificate(cert_value,
1648                 strlen(cert_value), visibility);
1649         if (ret != 0) {
1650                 _E("cert_svc_get_visibility_by_root_cert() failed. err = [%d]", ret);
1651                 ret = -1;
1652                 goto end;
1653         }
1654         _D("visibility = [%d]", *visibility);
1655
1656 end:
1657         pkgmgrinfo_pkginfo_destroy_certinfo(certinfo);
1658         return ret;
1659 }
1660 #endif
1661
1662 static int __can_share(const char *path, const char *pkgid)
1663 {
1664         struct stat path_stat;
1665
1666         if (access(path, F_OK) != 0)
1667                 return -1;
1668
1669         if (stat(path, &path_stat) != 0)
1670                 return -1;
1671
1672         if (!S_ISREG(path_stat.st_mode))
1673                 return -1;
1674
1675         char buf[1024];
1676
1677         snprintf(buf, sizeof(buf) - 1, "/opt/usr/apps/%s/data/", pkgid);
1678         if (strncmp(path, buf, strlen(buf)) != 0)
1679                 return -1;
1680
1681         return 0;
1682 }
1683
1684 static int __get_current_security_attribute(int pid, char *buf, int size)
1685 {
1686         int fd;
1687         int ret;
1688         char path[1024] = { 0, };
1689
1690         snprintf(path, sizeof(path) - 1, "/proc/%d/attr/current", pid);
1691         fd = open(path, O_RDONLY);
1692         if (fd < 0)
1693                 return -1;
1694
1695         ret = read(fd, buf, size - 1);
1696         if (ret <= 0) {
1697                 close(fd);
1698                 return -1;
1699         } else
1700                 buf[ret] = 0;
1701
1702         close(fd);
1703
1704         return 0;
1705 }
1706
1707 static int __get_exec_label_by_pid(int pid, char** exec_label)
1708 {
1709         const char *appid = NULL;
1710         const char *exec = NULL;
1711         const char *type = NULL;
1712         const struct appinfo *ai = NULL;
1713         char attr[1024] = { 0, };
1714
1715         if (__get_current_security_attribute(pid, attr, sizeof(attr)) == 0) {
1716                 *exec_label = strdup(attr);
1717                 return 0;
1718         }
1719
1720         appid = _status_app_get_appid_bypid(pid);
1721         if (appid) {
1722                 ai = appinfo_find(_laf, appid);
1723                 exec = appinfo_get_value(ai, AIT_EXEC);
1724                 type = appinfo_get_value(ai, AIT_TYPE);
1725
1726                 if (exec && type) {
1727                         if (strcmp("wgt", type) == 0) {
1728                                 if (smack_lgetlabel(exec, exec_label, SMACK_LABEL_EXEC) == 0)
1729                                         return 0;
1730                         } else {
1731                                 if (smack_getlabel(exec, exec_label, SMACK_LABEL_EXEC) == 0)
1732                                         return 0;
1733                         }
1734                 }
1735         }
1736
1737         return -1;
1738 }
1739
1740 static int __get_exec_label_by_appid(const char *appid, char** exec_label)
1741 {
1742         const char *exec = NULL;
1743         const char *type = NULL;
1744         const struct appinfo *ai = NULL;
1745
1746         if (appid) {
1747                 ai = appinfo_find(_laf, appid);
1748                 exec = appinfo_get_value(ai, AIT_EXEC);
1749                 type = appinfo_get_value(ai, AIT_TYPE);
1750
1751                 if (exec && type) {
1752                         if (strcmp("wgt", type) == 0) {
1753                                 if (smack_lgetlabel(exec, exec_label, SMACK_LABEL_EXEC) == 0)
1754                                         return 0;
1755                         } else {
1756                                 if (smack_getlabel(exec, exec_label, SMACK_LABEL_EXEC) == 0)
1757                                         return 0;
1758                         }
1759                 }
1760         }
1761
1762         return -1;
1763 }
1764
1765 static int __get_owner_pid(int caller_pid, bundle *kb)
1766 {
1767         char *org_caller = NULL;
1768
1769         if (bundle_get_str(kb, AUL_K_ORG_CALLER_PID, &org_caller) == BUNDLE_ERROR_NONE) {
1770                 int org_caller_pid = atoi(org_caller);
1771                 char *c_exec_label = NULL;
1772
1773                 if (__get_exec_label_by_pid(caller_pid, &c_exec_label) == 0) {
1774
1775                         if (c_exec_label &&
1776                                 (strcmp(APP_SELECTOR, c_exec_label) == 0 ||
1777                                 strcmp(SHARE_PANEL, c_exec_label) == 0))
1778                                         caller_pid = org_caller_pid;
1779                 }
1780
1781                 if (c_exec_label)
1782                         free(c_exec_label);
1783         }
1784
1785         return caller_pid;
1786 }
1787
1788 static int __get_exec_label(char **caller_exec_label, char **callee_exec_label,
1789                                 int caller_pid, const char *appid)
1790 {
1791         char *label_caller = NULL;
1792         char *label = NULL;
1793
1794         if (__get_exec_label_by_pid(caller_pid, &label_caller) != 0) {
1795                 return -1;
1796         }
1797
1798         if (__get_exec_label_by_appid(appid, &label) != 0) {
1799                 free(label_caller);
1800                 return -1;
1801         }
1802
1803         *caller_exec_label = label_caller;
1804         *callee_exec_label = label;
1805         return 0;
1806 }
1807
1808 static int __grant_temporary_permission(int caller_pid, const char *appid, bundle *kb,
1809                                         char **out_caller_exec_label, char **out_callee_exec_label,
1810                                         char ***out_paths)
1811 {
1812         int type = bundle_get_type(kb, AUL_SVC_DATA_PATH);
1813         char *path = NULL;
1814         const char **path_array = NULL;
1815         int len;
1816         char *caller_exec_label = NULL;
1817         char *callee_exec_label = NULL;
1818         int i;
1819         char **paths = NULL;
1820         int ret = -1;
1821         int owner_pid = -1;
1822         const char *tmp_appid = NULL;
1823         const char *pkgid = NULL;
1824         const struct appinfo *ai = NULL;
1825
1826         switch (type) {
1827                 case BUNDLE_TYPE_STR:
1828                         bundle_get_str(kb, AUL_SVC_DATA_PATH, &path);
1829
1830                         if (!path) {
1831                                 _E("path was null");
1832                                 goto check_uri;
1833                         }
1834
1835                         owner_pid = __get_owner_pid(caller_pid, kb);
1836                         owner_pid = getpgid(owner_pid); /* for webapp */
1837                         tmp_appid = _status_app_get_appid_bypid(owner_pid);
1838
1839                         ai = appinfo_find(_laf, tmp_appid);
1840                         pkgid = appinfo_get_value(ai, AIT_PKGID);
1841
1842                         if (__can_share(path, pkgid) != 0) {
1843                                 _E("__can_share() returned an error");
1844                                 goto check_uri;
1845                         }
1846
1847                         if (__get_exec_label(&caller_exec_label, &callee_exec_label, owner_pid,
1848                                 appid) != 0) {
1849                                 _E("__get_exec_label() returned an error");
1850                                 goto finally;
1851                         }
1852
1853                         paths = (char**)malloc(sizeof(char*) * 3);
1854                         if (!paths) {
1855                                 _E("Out of memory");
1856                                 goto finally;
1857                         }
1858
1859                         paths[0] = strdup(path);
1860                         paths[1] = NULL;
1861                         paths[2] = NULL;
1862                         ret = 0;
1863                         break;
1864
1865                 case BUNDLE_TYPE_STR_ARRAY:
1866                         path_array = bundle_get_str_array(kb, AUL_SVC_DATA_PATH, &len);
1867                         if (!path_array || len <= 0) {
1868                                 _E("path_array was null");
1869                                 goto check_uri;
1870                         }
1871
1872                         owner_pid = __get_owner_pid(caller_pid, kb);
1873                         owner_pid = getpgid(owner_pid); /* for webapp */
1874                         tmp_appid = _status_app_get_appid_bypid(owner_pid);
1875                         ai = appinfo_find(_laf, tmp_appid);
1876                         pkgid = appinfo_get_value(ai, AIT_PKGID);
1877
1878                         if (__get_exec_label(&caller_exec_label, &callee_exec_label, owner_pid,
1879                                 appid) != 0) {
1880                                 _E("__get_exec_label() returned an error");
1881                                 goto finally;
1882                         }
1883
1884                         paths = (char**)malloc(sizeof(char*) * (len + 2));
1885                         if (!paths) {
1886                                 _E("Out of memory");
1887                                 goto finally;
1888                         }
1889
1890                         int cnt = 0;
1891                         for (i = 0; i < len; i++) {
1892                                 if (__can_share(path_array[i], pkgid) == 0) {
1893                                         paths[cnt++] = strdup(path_array[i]);
1894                                 }
1895                         }
1896                         if (cnt > 0){
1897                                 paths[cnt] = NULL;
1898                                 paths[cnt + 1] = NULL;
1899                                 ret = 0;
1900                         } else {
1901                                 free(paths);
1902                                 paths = NULL;
1903                         }
1904                         break;
1905         }
1906
1907 check_uri:
1908         if (bundle_get_str(kb, AUL_SVC_K_URI, &path) == BUNDLE_ERROR_NONE) {
1909                 if (!path) {
1910                         _E("path was null");
1911                         goto finally;
1912                 }
1913
1914                 if (strncmp(path, "file://", 7) == 0)
1915                         path = &path[7];
1916                 else {
1917                         _E("file wasn't started with file://");
1918                         goto finally;
1919                 }
1920
1921                 if (owner_pid == -1) {
1922                         owner_pid = __get_owner_pid(caller_pid, kb);
1923                         owner_pid = getpgid(owner_pid); /* for webapp */
1924                 }
1925
1926                 tmp_appid = _status_app_get_appid_bypid(owner_pid);
1927                 ai = appinfo_find(_laf, tmp_appid);
1928                 pkgid = appinfo_get_value(ai, AIT_PKGID);
1929
1930                 if (__can_share(path, pkgid) != 0) {
1931                         _E("__can_share() returned an error");
1932                         goto finally;
1933                 }
1934
1935                 if (!caller_exec_label && !callee_exec_label)
1936                         if (__get_exec_label(&caller_exec_label, &callee_exec_label, owner_pid,
1937                                 appid) != 0) {
1938                                 _E("__get_exec_label() returned an error");
1939                                 goto finally;
1940                         }
1941
1942                 if (!paths) {
1943                         paths = (char**)malloc(sizeof(char*) * 2);
1944                         if (!paths) {
1945                                 _E("Out of memory");
1946                                 goto finally;
1947                         }
1948
1949                         paths[0] = strdup(path);
1950                         paths[1] = NULL;
1951                 } else {
1952                         i = 0;
1953                         while (1) {
1954                                 if (paths[i] == NULL) {
1955                                         paths[i] = strdup(path);
1956                                         break;
1957                                 }
1958                                 i++;
1959                         }
1960                 }
1961                 ret = 0;
1962         }
1963 finally:
1964         if (ret == 0 && caller_exec_label && paths) {
1965                 _D("grant permission %s : %s : %s", paths[0], caller_exec_label,
1966                         callee_exec_label);
1967                 int r = security_server_perm_apply_sharing(NULL, (const char**)paths, caller_exec_label, callee_exec_label);
1968                 if (r != SECURITY_SERVER_API_SUCCESS) {
1969                         _E("security_server_perm_apply_sharing() returned an error %d",r);
1970                         ret = -1;
1971                 } else {
1972                         *out_caller_exec_label = caller_exec_label;
1973                         *out_callee_exec_label = callee_exec_label;
1974                         *out_paths = paths;
1975
1976                         caller_exec_label = NULL;
1977                         callee_exec_label = NULL;
1978                         paths = NULL;
1979                 }
1980         }
1981
1982         if (caller_exec_label)
1983                 free(caller_exec_label);
1984         if (callee_exec_label)
1985                 free(callee_exec_label);
1986         if (paths) {
1987                 i = 0;
1988                 while (1) {
1989                         if (paths[i] == NULL) {
1990                                 free(paths);
1991                                 break;
1992                         }
1993                         free(paths[i]);
1994                         i++;
1995                 }
1996         }
1997         return ret;
1998 }
1999
2000 static void __add_shared_info(int pid, const char *caller_exec_label, const char *callee_exec_label, char **paths)
2001 {
2002         _status_set_exec_label(pid, callee_exec_label);
2003         _status_add_shared_info(pid, caller_exec_label, paths);
2004 }
2005
2006 int _revoke_temporary_permission(int pid)
2007 {
2008         GList *list = _status_get_shared_info_list(pid);
2009         const char *callee_label = _status_get_exec_label(pid);
2010
2011         if (!list || !callee_label) {
2012                 _E("list or callee_label was null");
2013                 return -1;
2014         }
2015
2016         while (list) {
2017                 shared_info_t *sit = (shared_info_t*)list->data;
2018
2019                 _D("revoke permission %s : %s", sit->owner_exec_label, callee_label);
2020                 int r = security_server_perm_drop_sharing(NULL, (const char**)sit->paths,
2021                                 sit->owner_exec_label, callee_label);
2022
2023                 if (r != SECURITY_SERVER_API_SUCCESS)
2024                         _E("revoke error %d",r);
2025
2026                 list = g_list_next(list);
2027         }
2028         return _status_clear_shared_info_list(pid);
2029 }
2030
2031 int _start_app(const char* appid, bundle* kb, int cmd, int caller_pid, uid_t caller_uid, int fd)
2032 {
2033         const struct appinfo *ai;
2034         const struct appinfo *caller_ai;
2035         int ret = -1;
2036         const char *multiple = NULL;
2037         const char *app_path = NULL;
2038         const char *pkg_type = NULL;
2039         const char *component_type = NULL;
2040         int pid = -1;
2041         char tmp_pid[MAX_PID_STR_BUFSZ];
2042         const char *permission;
2043         const char *pkgid;
2044         const char *preload;
2045         const char *pkg_status;
2046         const char *operation;
2047         char caller_appid[256] = {0,};
2048         char* caller = NULL;
2049         char* old_caller = NULL;
2050         pkgmgrinfo_cert_compare_result_type_e compare_result;
2051         int delay_reply = 0;
2052         int pad_pid = NO_LAUNCHPAD_PID;
2053         int status = -1;
2054         int r = -1;
2055         char trm_buf[MAX_PACKAGE_STR_SIZE];
2056         gboolean is_group_app = FALSE;
2057 #ifdef _APPFW_FEATURE_AMD_MODULE_LOG
2058         char log_status[AUL_PR_NAME] = {0,};
2059 #endif
2060
2061 #ifdef _APPFW_FEATURE_FAKE_EFFECT
2062         const char *fake_effect;
2063         int effect_mode = 0;
2064 #ifdef _APPFW_FEATURE_WMS_CONNECTION_CHECK
2065         int wmanager_connected = 0;
2066 #endif
2067
2068 #endif /* _APPFW_FEATURE_FAKE_EFFECT */
2069
2070 #ifdef _APPFW_FEATURE_AMD_KEY
2071         const char *caller_component_type = NULL;
2072 #endif
2073         int prelaunch_attribute = 0;
2074
2075         bool bg_allowed = false;
2076         int lpid;
2077         gboolean can_attach;
2078         app_group_launch_mode launch_mode;
2079         char *caller_exec_label = NULL;
2080         char *callee_exec_label = NULL;
2081         char **paths = NULL;
2082         int grant_permission = 0;
2083
2084         traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "AUL:AMD:START_APP");
2085         if (appid == NULL || kb == NULL
2086                 || caller_pid < 0 || fd < 0) {
2087                 _D("invalid parameter");
2088                 if (fd >= 0)
2089                         __real_send(fd, -1);
2090                 traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
2091                 return -1;
2092         }
2093
2094         snprintf(tmp_pid, MAX_PID_STR_BUFSZ, "%d", caller_pid);
2095         bundle_add(kb, AUL_K_CALLER_PID, tmp_pid);
2096
2097         if (cmd == APP_START_RES)
2098                 bundle_add(kb, AUL_K_WAIT_RESULT, "1");
2099
2100         caller = _status_app_get_appid_bypid(caller_pid);
2101         if(caller == NULL) {
2102                 ret = aul_app_get_appid_bypid(caller_pid, caller_appid, sizeof(caller_appid));
2103                 if(ret == 0) {
2104                         bundle_add(kb, AUL_K_CALLER_APPID, caller_appid);
2105                         caller = caller_appid;
2106                 } else {
2107                         _E("no caller appid info, ret: %d", ret);
2108                 }
2109         } else {
2110                 bundle_add(kb, AUL_K_CALLER_APPID, caller);
2111         }
2112
2113         if (caller)
2114                 SECURE_LOGW("caller appid : %s", caller);
2115
2116         _W("caller pid : %d", caller_pid);
2117
2118         ai = appinfo_find(_laf, appid);
2119         if(ai == NULL) {
2120                 _E("no appinfo");
2121                 __real_send(fd, -ENOAPP);
2122                 traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
2123                 return -1;
2124         } else {
2125                 pkg_status = appinfo_get_value(ai, AIT_STATUS);
2126                 if(pkg_status && (strncmp(pkg_status, "blocking", 8) == 0 || strncmp(pkg_status, "restart", 7) == 0) ) {
2127                         _D("blocking");
2128                         __real_send(fd, -EREJECTED);
2129                         traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
2130                         return -EREJECTED;
2131                 } else if(pkg_status && strncmp(pkg_status, "unmounted", 9) == 0 ) {
2132                         _D("unmounted");
2133                         __real_send(fd, -1);
2134                         traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
2135                         return -1;
2136                 }
2137         }
2138
2139         app_path = appinfo_get_value(ai, AIT_EXEC);
2140         pkg_type = appinfo_get_value(ai, AIT_TYPE);
2141         permission = appinfo_get_value(ai, AIT_PERM);
2142         pkgid = appinfo_get_value(ai, AIT_PKGID);
2143         component_type = appinfo_get_value(ai, AIT_COMPTYPE);
2144
2145         if (pkg_type == NULL)
2146                 pkg_type = "unknown";
2147
2148 #ifdef _APPFW_FEATURE_EXPANSION_PKG_INSTALL
2149         const char *tep_name = NULL;
2150
2151         tep_name = appinfo_get_value(ai, AIT_TEP);
2152         if (tep_name != NULL) {
2153                 __send_mount_request(ai, tep_name, kb);
2154         }
2155 #endif
2156         operation = bundle_get_val(kb, "__APP_SVC_OP_TYPE__");
2157         caller_ai = appinfo_find(_laf, caller);
2158 #ifdef _APPFW_FEATURE_AMD_KEY
2159         caller_component_type = appinfo_get_value(caller_ai, AIT_COMPTYPE);
2160 #endif
2161
2162         if(permission && strncmp(permission, "signature", 9) == 0 ) {
2163                 if(caller_uid != 0 && (cmd == APP_START
2164                                         || cmd == APP_START_RES
2165                                         || cmd == APP_START_ASYNC
2166 #ifdef _APPFW_FEATURE_MULTI_INSTANCE
2167                                         || cmd == APP_START_MULTI_INSTANCE
2168 #endif
2169                                         ))
2170                 {
2171                         preload = appinfo_get_value(caller_ai, AIT_PRELOAD);
2172                         if( preload && strncmp(preload, "true", 4) != 0 ) {
2173                                 ret = pkgmgrinfo_pkginfo_compare_app_cert_info(caller, appid, &compare_result);
2174                                 if (ret != PMINFO_R_OK) {
2175                                         pid = -1;
2176                                         _E("compare app cert info failed : %d", ret);
2177                                         if(cmd == APP_START_ASYNC)
2178                                                 close(fd);
2179                                         else
2180                                                 __real_send(fd, pid);
2181                                         traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
2182                                         return pid;
2183                                 }
2184                                 if(compare_result != PMINFO_CERT_COMPARE_MATCH) {
2185                                         pid = -EILLEGALACCESS;
2186                                         if(cmd == APP_START_ASYNC)
2187                                                 close(fd);
2188                                         else
2189                                                 __real_send(fd, pid);
2190                                         traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
2191                                         return pid;
2192                                 }
2193                         }
2194                 }
2195         }
2196
2197         if(operation && caller_ai) {
2198                 ret = __check_app_control_privilege(operation, caller_pid, caller_ai);
2199                 if (ret < 0) {
2200                         if (cmd == APP_START_ASYNC)
2201                                 close(fd);
2202                         else
2203                                 __real_send(fd, ret);
2204                         traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
2205                         return ret;
2206                 }
2207         }
2208
2209         if(__check_mode(ai) < 0) {
2210                 pid = -EREJECTED;
2211                 if(cmd == APP_START_ASYNC)
2212                         close(fd);
2213                 else
2214                         __real_send(fd, pid);
2215                 traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
2216                 return pid;
2217         }
2218
2219         pkgmgrinfo_client_request_enable_external_pkg((char *)pkgid);
2220
2221         if (component_type && (strncmp(component_type, APP_TYPE_UI, strlen(APP_TYPE_UI)) == 0
2222                 || strncmp(component_type, APP_TYPE_WATCH, strlen(APP_TYPE_WATCH)) == 0
2223                 || strncmp(component_type, APP_TYPE_WIDGET, strlen(APP_TYPE_WIDGET)) == 0 )) {
2224                 gboolean new_process = FALSE;
2225
2226                 multiple = appinfo_get_value(ai, AIT_MULTI);
2227                 if (!multiple || strncmp(multiple, "false", 5) == 0) {
2228                         pid = _status_app_is_running_v2(appid);
2229                 } else if (operation != NULL && strncmp(operation, "http://tizen.org/appcontrol/operation/view", 512) == 0){
2230                         old_caller = _status_get_caller_by_appid(appid);
2231                         if(old_caller && caller) {
2232                                 if(strncmp(old_caller, caller, MAX_PACKAGE_STR_SIZE) == 0) {
2233                                         pid = _status_app_is_running_v2(appid);
2234                                 }
2235                         }
2236                 }
2237
2238                 if (strncmp(component_type, APP_TYPE_UI, strlen(APP_TYPE_UI)) == 0) {
2239                         if (app_group_is_group_app(kb)) {
2240                                 pid = -1;
2241                                 is_group_app = TRUE;
2242                         }
2243
2244                         int st = -1;
2245
2246                         if (pid > 0)
2247                                 st = _status_get_app_info_status(pid);
2248
2249                         if (pid == -1 || st == STATUS_DYING) {
2250                                 int found_pid = -1;
2251                                 int found_lpid = -1;
2252
2253                                 if (app_group_find_singleton(appid, &found_pid, &found_lpid) == 0) {
2254                                         pid = found_pid;
2255                                         new_process = FALSE;
2256                                 } else {
2257                                         new_process = TRUE;
2258                                 }
2259
2260                                 if (app_group_can_start_app(appid, kb, &can_attach, &lpid, &launch_mode) != 0 ) {
2261                                         _E("can't make group info");
2262                                         pid = -EILLEGALACCESS;
2263                                         if (cmd == APP_START_ASYNC)
2264                                                 close(fd);
2265                                         else
2266                                                 __real_send(fd, pid);
2267                                         traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
2268                                         return pid;
2269                                 }
2270
2271                                 if (can_attach && lpid == found_lpid) {
2272                                         _E("can't launch singleton app in the same group");
2273                                         pid = -EILLEGALACCESS;
2274                                         if (cmd == APP_START_ASYNC)
2275                                                 close(fd);
2276                                         else
2277                                                 __real_send(fd, pid);
2278                                         traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
2279                                         return pid;
2280                                 }
2281
2282                                 if (found_pid != -1)
2283                                         app_group_clear_top(found_pid);
2284                         }
2285
2286                         if (pid == -1 && can_attach)
2287                                 pid = app_group_find_pid_from_recycle_bin(appid);
2288                 }
2289
2290 #ifdef _APPFW_FEATURE_APP_CONTROL_LITE
2291                 char app_path_link[512] = {0,};
2292                 const char *caller_app_path = NULL;
2293                 char caller_app_path_link[512] = {0,};
2294
2295                 caller_app_path = appinfo_get_value(caller_ai, AIT_EXEC);
2296
2297                 SECURE_LOGD("callee path(%s) caller path(%s)", app_path, caller_app_path);
2298
2299                 readlink(app_path, app_path_link, 512);
2300                 readlink(caller_app_path, caller_app_path_link, 512);
2301
2302                 SECURE_LOGD("callee link(%s) caller link(%s)", app_path_link, caller_app_path_link);
2303
2304                 if(strncmp(app_path_link, "/usr/bin/ug-client", 512) == 0) {
2305                         if (strcmp(caller, "org.tizen.app-selector") == 0){
2306                                 pid = atoi(bundle_get_val(kb,AUL_K_ORG_CALLER_PID));
2307                                 bundle_add(kb, "__AUL_UG_EXEC__", app_path);
2308                                 SECURE_LOGD("app_path : %s , ug id(%s)", app_path, bundle_get_val(kb, "__AUL_UG_ID__"));
2309                         } else if(strncmp(caller_app_path_link, "/usr/bin/ug-client", 512) == 0) {
2310                                 __real_send(fd, -EUGLOCAL_LAUNCH);
2311                                 traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
2312                                 return -1;
2313                         }
2314                 }
2315 #endif
2316
2317                 if(caller) {
2318 #ifdef _APPFW_FEATURE_AMD_KEY
2319                         if (caller_component_type && strncmp(caller_component_type, APP_TYPE_UI, strlen(APP_TYPE_UI)) == 0) {
2320                                 Ecore_X_Window in_win;
2321                                 in_win = _input_window_get();
2322                                 if(in_win) {
2323                                         ret = ecore_x_pointer_grab(in_win);
2324                                         _D("win(%x) ecore_x_pointer_grab(%d)", in_win, ret);
2325                                 }
2326                                 if(_key_grab(KEY_BACK, EXCLUSIVE_GRAB) < 0) {
2327                                         _W("back key grab error");
2328                                 } else {
2329                                         _D("back key grab");
2330                                 }
2331                         }
2332 #endif
2333                 }
2334
2335                 if (__grant_temporary_permission(caller_pid, appid, kb,
2336                         &caller_exec_label, &callee_exec_label, &paths) == 0)
2337                         grant_permission = 1;
2338                 status = _status_get_app_info_status(pid);
2339                 if (pid > 0 && status != STATUS_DYING) {
2340                         if (caller_pid == pid) {
2341                                 SECURE_LOGD("caller process & callee process is same.[%s:%d]", appid, pid);
2342                                 pid = -ELOCALLAUNCH_ID;
2343                         } else {
2344                                 if(strncmp(pkg_type, "wgt", 3) == 0) {
2345                                         __pre_launching_processing(appid);
2346                                 }
2347
2348 #ifdef _APPFW_FEATURE_AMD_MODULE_LOG
2349                         strncpy(log_status, "RESUMING", strlen("RESUMING"));
2350 #endif
2351
2352                                 proc_group_change_status(PROC_CGROUP_SET_RESUME_REQUEST, pid, (char *)appid);
2353
2354                                 if ((ret = __nofork_processing(cmd, pid, kb, fd)) < 0) {
2355                                         pid = ret;
2356                                 } else {
2357                                         delay_reply = 1;
2358                                 }
2359                         }
2360                 } else if (cmd != APP_RESUME) {
2361                         if(status == STATUS_DYING && pid > 0) {
2362                                 r = kill(pid, SIGKILL);
2363                                 if (r == -1)
2364                                         _D("send SIGKILL: %s", strerror(errno));
2365                         }
2366
2367 #ifdef _APPFW_FEATURE_AMD_MODULE_LOG
2368                         strncpy(log_status, "LAUNCHING", strlen("LAUNCHING"));
2369 #endif
2370
2371                         // 2.4 bg categorized ui app || watch || widget -> bg allowed (2.3 ui app -> not allowed)
2372                         prelaunch_attribute = __get_prelaunch_attribute(ai);
2373                         if ((strncmp(component_type, APP_TYPE_UI, sizeof(APP_TYPE_UI)) == 0
2374                                 && (prelaunch_attribute & RESOURCED_ALLOWED_BG_ATTRIBUTE))
2375                                         || (strncmp(component_type, APP_TYPE_WATCH, sizeof(APP_TYPE_WATCH)) == 0)
2376                                         || (strncmp(component_type, APP_TYPE_WIDGET, sizeof(APP_TYPE_WIDGET)) == 0)) {
2377                                 _D("[__SUSPEND__] allowed background, appid: %s", appid);
2378                                 bundle_add(kb, AUL_K_ALLOWED_BG, "ALLOWED_BG");
2379                         }
2380
2381                         __send_proc_prelaunch_signal(appid, pkgid, prelaunch_attribute);
2382
2383 #ifdef _APPFW_FEATURE_FAKE_EFFECT
2384                         fake_effect = bundle_get_val(kb, "__FAKE_EFFECT__");
2385 #endif
2386
2387 #ifdef _APPFW_FEATURE_CPU_BOOST
2388                         if (cmd == APP_OPEN || operation != NULL ||
2389                                 (caller != NULL && strcmp(caller, "org.tizen.wnotification2") == 0) ||
2390                                 (caller != NULL && strcmp(caller, "org.tizen.wnotiboard-popup") == 0)) {
2391                                 char *arr[2];
2392                                 char val[32];
2393                                 snprintf(val, sizeof(val), "%d", APP_BOOSTING_PERIOD);
2394                                 arr[0] = val;
2395                                 arr[1] = NULL;
2396                                 ret = invoke_dbus_method_sync(SYSTEM_BUS_NAME, SYSTEM_OBJECT_PATH,
2397                                                 SYSTEM_INTERFACE_NAME, SYSTEM_METHOD_NAME, "i", arr);
2398                                 _D("%s-%s : %d", SYSTEM_INTERFACE_NAME, SYSTEM_METHOD_NAME, ret);
2399                         }
2400 #endif
2401
2402 #ifdef _APPFW_FEATURE_FAKE_EFFECT
2403                         /*
2404                          *      effect_mode = 0
2405                          *              default mode : fake effect off, 1.6 MHZ off
2406                          *      effect_mode = 1
2407                          *              full mode : fake effect on, 1.6 MHZ on
2408                          *      effect_mode = 2
2409                          *              fake effect mode : fake effect on, 1.6 MHZ off
2410                          *      effect_mode = 3
2411                          *              1.6 MHZ mode : faek effect off, 1.6MHZ on
2412                          *
2413                          */
2414                         vconf_get_int(VCONFKEY_AMD_EFFECT_IMAGE_ENABLE, &effect_mode);
2415 #ifdef _APPFW_FEATURE_WMS_CONNECTION_CHECK
2416                         vconf_get_bool(VCONFKEY_WMS_WMANAGER_CONNECTED, &wmanager_connected);
2417 #endif
2418                         //_D("*******[effect_mode] Mode : %d\n ", effect_mode );
2419
2420                         if ( ( cmd == APP_OPEN ||
2421                                 ( (operation != NULL && strncmp(operation, "http://tizen.org/appcontrol/operation/main", 512) == 0)
2422                                 && !(fake_effect != NULL && strncmp(fake_effect, "OFF", 3) == 0) )
2423                                 ) && (effect_mode == 1 || effect_mode == 2)
2424 #ifdef _APPFW_FEATURE_WMS_CONNECTION_CHECK
2425                                 && wmanager_connected == true
2426 #endif
2427                                 ){
2428                                 char image_filename[256] = {0,};
2429                                 const char *portraitimg = NULL;
2430                                 const char *landscapeimg = NULL;
2431 #ifdef _APPFW_FEATURE_CHANGEABLE_COLOR
2432                                 const char *effectimg_type = NULL;
2433 #endif
2434                                 const char *indicator = NULL;
2435                                 int screen_mode = 0;
2436                                 int rotate_allowed = 0;
2437                                 int file_type = 1;
2438                                 int theme = 0;
2439
2440                                 //vconf_get_int(PHONE_ORIENTATION_MODE, &screen_mode);
2441                                 screen_mode = invoke_dbus_method_sync(ROTATION_BUS_NAME, ROTATION_OBJECT_PATH,
2442                                                                 ROTATION_INTERFACE_NAME, ROTATION_METHOD_NAME, "i", NULL);
2443                                 _D("%s-%s : %d", ROTATION_INTERFACE_NAME, ROTATION_METHOD_NAME, screen_mode);
2444                                 vconf_get_bool(PHONE_ROTATE_LOCK, &rotate_allowed); /*TODO: use vconf_notify_key_changed()*/
2445                                 portraitimg = appinfo_get_value(ai, AIT_EFFECTIMAGEPORT);
2446                                 landscapeimg = appinfo_get_value(ai, AIT_EFFECTIMAGELAND);
2447 #ifdef _APPFW_FEATURE_CHANGEABLE_COLOR
2448                                 effectimg_type = appinfo_get_value(ai, AIT_EFFECTTYPE);
2449 #endif
2450                                 indicator = appinfo_get_value(ai, AIT_INDICATOR_DISP);
2451                                 /*Currently we assume apps supporting launching effect supports portrait mode*/
2452                                 if (indicator && portraitimg) {
2453                                         if (rotate_allowed == false) {
2454                                                 screen_mode = 1;
2455                                         }
2456                                         if ((screen_mode == 2 || screen_mode == 4) && (rotate_allowed == true)) {
2457                                                 /*if there is no landscape image, that means app supports only portrait mode.*/
2458                                                 if (landscapeimg) {
2459                                                         snprintf(image_filename, 255, "%s", landscapeimg);
2460                                                 }
2461                                         } else {
2462                                                 snprintf(image_filename, 255, "%s", portraitimg);
2463                                         }
2464                                         if (access(image_filename, R_OK) == 0) {
2465 #ifdef _APPFW_FEATURE_CHANGEABLE_COLOR
2466                                                 if(strncmp(effectimg_type, "edj-dark", strlen(effectimg_type)) == 0) {
2467                                                         file_type = 0;
2468                                                         theme = 0;
2469                                                 } else if (strncmp(effectimg_type, "edj-light", strlen(effectimg_type)) == 0) {
2470                                                         file_type = 0;
2471                                                         theme = 1;
2472                                                 } else if (strncmp(effectimg_type, "edj-default", strlen(effectimg_type)) == 0) {
2473                                                         file_type = 0;
2474                                                         theme = 2;
2475                                                 } else {
2476                                                         file_type = 1;
2477                                                         theme = 0;
2478                                                 }
2479
2480                                                 do {
2481                                                         if (file_type == 1)
2482                                                                 break;
2483                                                         r = snprintf(xml_filename, 255, "/usr/apps/%s/shared/res/tables/%s_ChangeableColorInfo.xml", pkgid, pkgid);
2484                                                         if (access(xml_filename, R_OK) == 0) {
2485                                                                 //snprintf(image_filename, 255, "%s:%s", image_filename, xml_filename);
2486                                                                 strcat(image_filename, ":");
2487                                                                 strcat(image_filename, xml_filename);
2488                                                                 break;
2489                                                         }
2490                                                         r = snprintf(xml_filename, 255, "/opt/usr/apps/%s/shared/res/tables/%s_ChangeableColorInfo.xml", pkgid, pkgid);
2491                                                         if (access(xml_filename, R_OK) == 0) {
2492                                                                 //snprintf(image_filename, 255, "%s:%s", image_filename, xml_filename);
2493                                                                 strcat(image_filename, ":");
2494                                                                 strcat(image_filename, xml_filename);
2495                                                                 break;
2496                                                         }
2497                                                 } while(0);
2498 #endif
2499 #ifndef _APPFW_FEATURE_DEFAULT_FAKE_IMAGE
2500                                                 __amd_effect_image_file_set(image_filename);
2501 #else
2502                                                 if(file_type == 1) {
2503                                                         __amd_effect_image_file_set("/usr/share/splash_images/type0_portrait.bmp");
2504                                                 } else {
2505                                                         __amd_effect_image_file_set(image_filename);
2506                                                 }
2507 #endif
2508                                                 __amd_send_message_to_e17(screen_mode, indicator, file_type, theme);
2509                                         }
2510                                 }
2511                         }
2512 #endif /* _APPFW_FEATURE_FAKE_EFFECT */
2513
2514 #ifdef _APPFW_FEATURE_DEBUG_LAUNCHPAD
2515                         if (bundle_get_type(kb, AUL_K_SDK) != BUNDLE_TYPE_NONE) {
2516                                 pad_pid = DEBUG_LAUNCHPAD_PID;
2517                         } else if (strncmp(pkg_type, "wgt", 3) == 0) {
2518                                 pad_pid = WEB_LAUNCHPAD_PID;
2519                         }
2520 #else
2521                         if (strncmp(pkg_type, "wgt", 3) == 0) {
2522                                 pad_pid = WEB_LAUNCHPAD_PID;
2523                         }
2524 #endif
2525 #ifdef _APPFW_FEATURE_PROCESS_POOL
2526                         else {
2527                                 const char *process_pool = appinfo_get_value(ai, AIT_POOL);
2528                                 _D("process_pool: %s", process_pool);
2529
2530                                 const char *hwacc = appinfo_get_value(ai, AIT_HWACC);
2531                                 _D("h/w acceleration: %s", hwacc);
2532
2533                                 SECURE_LOGD("appid: %s", appid);
2534
2535                                 pad_pid = PROCESS_POOL_LAUNCHPAD_PID;
2536                                 char pad_sock[UNIX_PATH_MAX] = { 0, };
2537                                 snprintf(pad_sock, UNIX_PATH_MAX, "%s/%d", AUL_SOCK_PREFIX, pad_pid);
2538                                 if (access(pad_sock, F_OK) != 0)
2539                                 {
2540                                         _W("Sending to legacy launchpad because process-pool launchpad is not initialized.");
2541                                         pad_pid = NO_LAUNCHPAD_PID;
2542                                 }
2543                         }
2544 #endif //_APPFW_FEATURE_PROCESS_POOL
2545                         _W("pad pid(%d)", pad_pid);
2546                         __set_appinfo_for_launchpad(ai, kb);
2547                         if (pad_pid == NO_LAUNCHPAD_PID)
2548                         {
2549                                 pid = start_process(appid, app_path, kb);
2550                         }
2551                         else
2552                         {
2553                                 pid = app_send_cmd(pad_pid, cmd, kb);
2554                                 if (pid == AUL_R_ENOLAUNCHPAD && pad_pid == PROCESS_POOL_LAUNCHPAD_PID) {
2555                                         _W("Launch with legacy way");
2556                                         pad_pid = NO_LAUNCHPAD_PID;
2557                                         pid = start_process(appid, app_path, kb);
2558                                 }
2559                         }
2560                         if(pid == AUL_R_ECOMM) {
2561                                 pid = -ENOLAUNCHPAD;
2562                         }
2563                         aul_send_app_launch_request_signal(pid, appid, pkgid, component_type);
2564                         snprintf(trm_buf, MAX_PACKAGE_STR_SIZE, "appinfo_launch:%s[PID]%d", appid, pid);
2565                         __trm_app_info_send_socket(trm_buf);
2566                 }
2567                 if(pid < 0) {
2568 #ifdef _APPFW_FEATURE_AMD_KEY
2569                         if(_input_window_get() != 0)
2570                                 ecore_x_pointer_ungrab();
2571                         _D("pid(%d) ecore_x_pointer_ungrab", pid);
2572                         if(_key_ungrab(KEY_BACK) < 0) {
2573                                 _W("back key ungrab error");
2574                         } else {
2575                                 _D("back key ungrab");
2576                         }
2577 #endif
2578                 } else {
2579                         if (new_process) {
2580                                 _D("add app group info");
2581                                 app_group_start_app(pid, kb, lpid, can_attach, launch_mode);
2582                         } else if (cmd == APP_START
2583                                         || cmd == APP_START_RES
2584                                         || cmd == APP_START_ASYNC
2585 #ifdef _APPFW_FEATURE_MULTI_INSTANCE
2586                                         || cmd == APP_START_MULTI_INSTANCE
2587 #endif
2588                                  ) {
2589                                 app_group_restart_app(pid, kb);
2590                         }
2591 #ifdef _APPFW_FEATURE_AMD_KEY
2592                         grab_timer_id = g_timeout_add(1000, __grab_timeout_handler, (void *)pid);
2593 #endif
2594                 }
2595         }
2596         else if (component_type && strncmp(component_type, APP_TYPE_SERVICE, sizeof(APP_TYPE_SERVICE)) == 0) {
2597 #ifdef _APPFW_FEATURE_PRIVATE_SERVICE
2598                 const char *caller_appid = _status_app_get_appid_bypid(caller_pid);
2599
2600                 if (caller_appid) {
2601                         const struct appinfo *ai = NULL;
2602                         const char *caller_pkgid = NULL;
2603                         const char *pkgid = NULL;
2604
2605                         ai = appinfo_find(_laf, appid);
2606                         pkgid = appinfo_get_value(ai, AIT_PKGID);
2607                         ai = appinfo_find(_laf, caller_appid);
2608                         caller_pkgid = appinfo_get_value(ai, AIT_PKGID);
2609
2610                         if (caller_pkgid && pkgid && strcmp(caller_pkgid, pkgid) != 0) {
2611                                 const char *launch_type = bundle_get_val(kb, OSP_K_LAUNCH_TYPE);
2612
2613                                 if (launch_type == NULL || strcmp(launch_type, OSP_V_LAUNCH_TYPE_DATACONTROL) != 0) {
2614                                         const char *v = appinfo_get_value(ai, AIT_VISIBILITY);
2615                                         char num[256] = { 0, };
2616
2617                                         if (v == NULL) {
2618                                                 int vi_num = 0;
2619
2620                                                 if (__get_visibility_from_cert_svc(caller_pkgid, &vi_num) == 0) {
2621                                                         snprintf(num, 255, "%d", vi_num);
2622                                                         appinfo_set_value((struct appinfo*)ai, AIT_VISIBILITY, num);
2623                                                         v = num;
2624                                                 } else
2625                                                         _E("Failed to get visibility");
2626                                         }
2627
2628                                         if (v) {
2629                                                 int visibility = atoi(v);
2630                                                 if (!(visibility & CERT_SVC_VISIBILITY_PLATFORM)) {
2631                                                         _E("Couldn't launch service app in other packages");
2632                                                         __real_send(fd, -EREJECTED);
2633                                                         traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
2634                                                         return -EREJECTED;
2635                                                 }
2636                                         }
2637                                 }
2638                         }
2639                 }
2640 #endif
2641                 pid = _status_app_is_running_v2(appid);
2642
2643                 prelaunch_attribute = __get_prelaunch_attribute(ai);
2644
2645                 // 2.4 bg-categorized svc app || 2.3 svc app -> bg allowed
2646                 if ((prelaunch_attribute & RESOURCED_ALLOWED_BG_ATTRIBUTE)
2647                                 || !(prelaunch_attribute & RESOURCED_API_VER_2_4_ATTRIBUTE)) {
2648                         _D("[__SUSPEND__] allowed backgroudn, appid: %s", appid);
2649                         bundle_add(kb, AUL_K_ALLOWED_BG, "ALLOWED_BG");
2650                         bg_allowed = true;
2651                 }
2652
2653                 if (__grant_temporary_permission(caller_pid, appid, kb,
2654                         &caller_exec_label, &callee_exec_label, &paths) == 0)
2655                         grant_permission = 1;
2656
2657                 if (pid > 0) {
2658 #ifdef _APPFW_FEATURE_AMD_MODULE_LOG
2659                         strncpy(log_status, "RESUMING", strlen("RESUMING"));
2660 #endif
2661                         aul_send_app_resume_request_signal(pid, appid, pkgid, APP_TYPE_SERVICE);
2662
2663                         if (!bg_allowed)
2664                                 __prepare_to_wake_services(pid);
2665
2666                         if ((ret = __nofork_processing(cmd, pid, kb, fd)) < 0) {
2667                                 pid = ret;
2668                         }
2669                 } else if (cmd != APP_RESUME) {
2670 #ifdef _APPFW_FEATURE_AMD_MODULE_LOG
2671                         strncpy(log_status, "LAUNCHING", strlen("LAUNCHING"));
2672 #endif
2673
2674                         __send_proc_prelaunch_signal(appid, pkgid, prelaunch_attribute);
2675
2676 #ifdef _APPFW_FEATURE_DEBUG_LAUNCHPAD
2677                         if (bundle_get_type(kb, AUL_K_SDK) != BUNDLE_TYPE_NONE) {
2678                                 SECURE_LOGD("The svcapp(%s) is launched by debug-launchpad", appid);
2679                                 __set_appinfo_for_launchpad(ai, kb);
2680                                 pid = app_send_cmd(DEBUG_LAUNCHPAD_PID, cmd, kb);
2681                                 if (pid == AUL_R_ECOMM) {
2682                                         pid = -ENOLAUNCHPAD;
2683                                 }
2684                         } else {
2685                                 pid = start_process(appid, app_path, kb);
2686                         }
2687 #else
2688                         pid = start_process(appid, app_path, kb);
2689 #endif
2690                         aul_send_app_launch_request_signal(pid, appid, pkgid, component_type);
2691                 }
2692
2693                 if (bg_allowed) {
2694                         g_idle_add(__check_service_only, (gpointer)pid);
2695                 }
2696
2697         } else {
2698                 _E("unkown application");
2699         }
2700
2701         if(!delay_reply) {
2702                 if(cmd == APP_START_ASYNC)
2703                         close(fd);
2704                 else
2705                         __real_send(fd, pid);
2706         }
2707
2708 #ifdef _APPFW_FEATURE_AMD_MODULE_LOG
2709         _status_log_save(log_status, appid);
2710 #endif
2711
2712         if(pid > 0) {
2713                 _status_add_app_info_list(appid, app_path, caller, pid, pad_pid, is_group_app);
2714                 _status_update_app_info_caller_pid(pid, caller_pid);
2715                 if (grant_permission) {
2716                         __add_shared_info(pid, caller_exec_label, callee_exec_label, paths);
2717                         if (caller_exec_label) {
2718                                 free(caller_exec_label);
2719                                 caller_exec_label = NULL;
2720                         }
2721                         if (callee_exec_label) {
2722                                 free(callee_exec_label);
2723                                 callee_exec_label = NULL;
2724                         }
2725                 }
2726
2727 #ifdef _APPFW_FEATURE_AMD_MODULE_LOG
2728                 snprintf(log_status, AUL_PR_NAME, "SUCCESS: %d", pid);
2729                 _status_log_save(log_status, appid);
2730 #endif
2731
2732 #ifdef _APPFW_FEATURE_APP_CHECKER
2733                 pkg_type = appinfo_get_value(ai, AIT_TYPE);
2734                 if (!pkg_type)
2735                         return -1;
2736
2737                 ret = ac_server_check_launch_privilege(appid, pkg_type, pid);
2738                 if (ret != AC_R_ERROR) {
2739                         traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
2740                         return pid;
2741                 } else {
2742                         traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
2743                         return -1;
2744                 }
2745 #endif
2746         }
2747 #ifdef _APPFW_FEATURE_AMD_MODULE_LOG
2748         else {
2749                 _status_log_save("FAILURE", appid);
2750         }
2751 #endif
2752
2753         traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
2754         return pid;
2755 }
2756
2757 int __e17_status_handler(int pid, int status, void *data)
2758 {
2759         if (status == PROC_STATUS_FG) {
2760 #ifdef _APPFW_FEATURE_AMD_KEY
2761                 _D("pid(%d) status(%d)", pid, status);
2762                 if(_input_window_get() != 0)
2763                         ecore_x_pointer_ungrab();
2764                 if(_key_ungrab(KEY_BACK) < 0) {
2765                         _W("back key ungrab error");
2766                 } else {
2767                         _D("back key ungrab");
2768                 }
2769                 g_source_remove(grab_timer_id);
2770 #endif
2771
2772                 _status_update_app_info_list(pid, STATUS_VISIBLE);
2773         } else if (status == PROC_STATUS_BG) {
2774                 _status_update_app_info_list(pid, STATUS_BG);
2775         }
2776
2777         return 0;
2778 }
2779
2780 int _launch_init(struct amdmgr* amd)
2781 {
2782         int ret = 0;
2783
2784         _D("_launch_init");
2785
2786         amd_cmdline = __proc_get_cmdline_bypid(getpid());
2787
2788         _laf = amd->af;
2789
2790         conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
2791         if (!conn) {
2792                 _E("dbus_bus_get error");
2793                 return -EBADMSG;
2794         }
2795
2796         ret = aul_listen_e17_status_signal(__e17_status_handler, NULL);
2797
2798         _D("ret : %d", ret);
2799
2800         __preexec_init(0, NULL);
2801
2802         return 0;
2803 }
2804
2805 void _set_atom_effect(void)
2806 {
2807         ATOM_IMAGE_EFFECT = ecore_x_atom_get(atom_name);
2808 }
2809
2810 void __set_appinfo_for_launchpad(const struct appinfo *ai, bundle *kb) {
2811         int ret;
2812
2813         _D("Add hwacc, taskmanage, app_path and pkg_type into bundle for sending those to launchpad.");
2814         ret = bundle_del(kb, AUL_K_HWACC);
2815         if (ret != BUNDLE_ERROR_NONE)
2816                 _D("bundle_del error: %d", ret);
2817         ret = bundle_add(kb, AUL_K_HWACC, appinfo_get_value(ai, AIT_HWACC));
2818         if (ret != BUNDLE_ERROR_NONE)
2819                 _E("failed to set AUL_K_HWACC: ret(%d)", ret);
2820
2821
2822         bundle_del(kb, AUL_K_TASKMANAGE);
2823         if (ret != BUNDLE_ERROR_NONE)
2824                 _D("bundle_del error: %d", ret);
2825         bundle_add(kb, AUL_K_TASKMANAGE, appinfo_get_value(ai, AIT_TASKMANAGE));
2826         if (ret != BUNDLE_ERROR_NONE)
2827                 _E("failed to set AUL_K_TASKMANAGE: ret(%d)", ret);
2828
2829         bundle_del(kb, AUL_K_EXEC);
2830         if (ret != BUNDLE_ERROR_NONE)
2831                 _D("bundle_del error: %d", ret);
2832         bundle_add(kb, AUL_K_EXEC, appinfo_get_value(ai, AIT_EXEC));
2833         if (ret != BUNDLE_ERROR_NONE)
2834                 _E("failed to set AUL_K_EXEC: ret(%d)", ret);
2835
2836         bundle_del(kb, AUL_K_PACKAGETYPE);
2837         if (ret != BUNDLE_ERROR_NONE)
2838                 _D("bundle_del error: %d", ret);
2839         bundle_add(kb, AUL_K_PACKAGETYPE, appinfo_get_value(ai, AIT_TYPE));
2840         if (ret != BUNDLE_ERROR_NONE)
2841                 _E("failed to set AUL_K_PACKAGETYPE: ret(%d)", ret);
2842
2843         bundle_del(kb, AUL_K_INTERNAL_POOL);
2844         if (ret != BUNDLE_ERROR_NONE)
2845                 _D("bundle_del error: %d", ret);
2846         bundle_add(kb, AUL_K_INTERNAL_POOL, appinfo_get_value(ai, AIT_POOL));
2847         if (ret != BUNDLE_ERROR_NONE)
2848                 _E("failed to set AUL_K_INTERNAL_POOL: ret(%d)", ret);
2849
2850         bundle_del(kb, AUL_K_PKGID);
2851         if (ret != BUNDLE_ERROR_NONE)
2852                 _D("bundle_del error: %d", ret);
2853         bundle_add(kb, AUL_K_PKGID, appinfo_get_value(ai, AIT_PKGID));
2854         if (ret != BUNDLE_ERROR_NONE)
2855                 _E("failed to set AUL_K_PKGID: ret(%d)", ret);
2856 }