4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
23 #include <sys/types.h>
32 #ifdef _APPFW_FEATURE_APP_CONTROL_LITE
33 #include <pkgmgr-info.h>
34 #include <pkgmgrinfo_zone.h>
37 #include <bundle_internal.h>
43 #include "simple_util.h"
48 #ifdef _APPFW_FEATURE_EXPANSION_PKG_INSTALL
49 #include <dbus/dbus.h>
50 #include "app_signal.h"
51 #define TEP_ISMOUNT_MAX_RETRY_CNT 20
54 static int aul_initialized = 0;
57 static int (*_aul_handler) (aul_type type, bundle *kb, void *data) = NULL;
58 static void *_aul_data;
61 static int app_resume();
62 static int app_terminate();
63 static void __clear_internal_key(bundle *kb);
64 static inline void __set_stime(bundle *kb);
65 static int __app_start_internal(gpointer data);
66 static int __app_launch_local(bundle *b);
67 static int __send_result_to_launchpad(int fd, int res);
69 #ifdef _APPFW_FEATURE_PROCESS_POOL
70 static void *__window_object = NULL;
71 static void *__bg_object = NULL;
72 static void *__conformant_object = NULL;
75 #ifdef _APPFW_FEATURE_DATA_CONTROL
76 static data_control_provider_handler_fn __dc_handler = NULL;
79 extern int aul_launch_fini();
81 #ifdef _APPFW_FEATURE_EXPANSION_PKG_INSTALL
82 SLPAPI int aul_is_tep_mount_dbus_done(const char *tep_string)
90 DBusConnection *conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
92 _E("dbus_bus_get error");
96 msg = dbus_message_new_method_call(TEP_BUS_NAME, TEP_OBJECT_PATH, TEP_INTERFACE_NAME, TEP_IS_MOUNTED_METHOD);
98 _E("dbus_message_new_method_call(%s:%s-%s)", TEP_OBJECT_PATH, TEP_INTERFACE_NAME, TEP_IS_MOUNTED_METHOD);
102 if (!dbus_message_append_args(msg,
103 DBUS_TYPE_STRING, &tep_string,
104 DBUS_TYPE_INVALID)) {
105 _E("Ran out of memory while constructing args\n");
106 dbus_message_unref(msg);
110 dbus_error_init(&err);
111 reply = dbus_connection_send_with_reply_and_block(conn, msg, 500, &err);
113 _E("dbus_connection_send error(%s:%s)", err.name, err.message);
117 r = dbus_message_get_args(reply, &err, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INVALID);
119 _E("no message : [%s:%s]", err.name, err.message);
124 dbus_message_unref(msg);
125 dbus_error_free(&err);
129 SLPAPI int aul_check_tep_mount(const char *tep_path)
134 while(cnt < TEP_ISMOUNT_MAX_RETRY_CNT) {
135 rv = aul_is_tep_mount_dbus_done(tep_path);
141 /* incase after trying 1 sec, not getting mounted then quit */
143 _E("Not able to mount within 1 sec");
151 int aul_is_initialized()
153 return aul_initialized;
156 int __call_aul_handler(aul_type type, bundle *kb)
159 _aul_handler(type, kb, _aul_data);
163 int app_start(bundle *kb)
165 const char *str = NULL;
167 _app_start_res_prepare(kb);
168 __call_aul_handler(AUL_START, kb);
170 #ifdef _APPFW_FEATURE_DATA_CONTROL
171 // Handle the DataControl callback
172 str = bundle_get_val(kb, AUL_K_DATA_CONTROL_TYPE);
173 if (str != NULL && strcmp(str, "CORE") == 0)
175 if (__dc_handler != NULL)
177 __dc_handler(kb, 0, NULL); // bundle, request_id, data
184 static int app_resume()
186 __call_aul_handler(AUL_RESUME, NULL);
190 static int app_terminate()
192 __call_aul_handler(AUL_TERMINATE, NULL);
196 static int bgapp_terminate()
198 __call_aul_handler(AUL_TERMINATE_BGAPP, NULL);
202 static int app_pause()
204 __call_aul_handler(AUL_PAUSE, NULL);
208 static int app_prepare_to_suspend()
211 __call_aul_handler(AUL_SUSPEND, NULL);
215 static int app_prepare_to_wake()
218 __call_aul_handler(AUL_WAKE, NULL);
223 * @brief encode kb and send it to 'pid'
224 * @param[in] pid receiver's pid
225 * @param[in] cmd message's status (APP_START | APP_RESULT)
228 SLPAPI int app_send_cmd(int pid, int cmd, bundle *kb)
231 bundle_raw *kb_data = NULL;
234 res = bundle_encode(kb, &kb_data, &datalen);
235 if (res != BUNDLE_ERROR_NONE) {
238 if ((res = __app_send_raw(pid, cmd, kb_data, datalen)) < 0) {
247 res = AUL_R_ETIMEOUT;
249 case -ELOCALLAUNCH_ID:
252 case -EILLEGALACCESS:
256 res = AUL_R_ETERMINATING;
259 res = AUL_R_ENOLAUNCHPAD;
261 #ifdef _APPFW_FEATURE_APP_CONTROL_LITE
262 case -EUGLOCAL_LAUNCH:
263 res = AUL_R_UG_LOCAL;
267 res = AUL_R_EREJECTED;
281 SLPAPI int app_send_cmd_with_noreply(int pid, int cmd, bundle *kb)
284 bundle_raw *kb_data = NULL;
287 res = bundle_encode(kb, &kb_data, &datalen);
288 if (res != BUNDLE_ERROR_NONE) {
291 if ((res = __app_send_raw_with_noreply(pid, cmd, kb_data, datalen)) < 0) {
300 res = AUL_R_ETIMEOUT;
302 case -ELOCALLAUNCH_ID:
305 case -EILLEGALACCESS:
317 static void __clear_internal_key(bundle *kb)
319 bundle_del(kb, AUL_K_CALLER_PID);
320 bundle_del(kb, AUL_K_PKG_NAME);
321 bundle_del(kb, AUL_K_WAIT_RESULT);
322 bundle_del(kb, AUL_K_SEND_RESULT);
323 bundle_del(kb, AUL_K_ARGV0);
326 static inline void __set_stime(bundle *kb)
329 char tmp[MAX_LOCAL_BUFSZ];
331 gettimeofday(&tv, NULL);
332 snprintf(tmp, MAX_LOCAL_BUFSZ, "%ld/%ld", tv.tv_sec, tv.tv_usec);
333 bundle_add(kb, AUL_K_STARTTIME, tmp);
336 static int __app_start_internal(gpointer data)
340 kb = (bundle *) data;
347 static int __app_launch_local(bundle *b)
349 if (!aul_is_initialized())
350 return AUL_R_ENOINIT;
353 _E("bundle for APP_START is NULL");
355 if (g_idle_add(__app_start_internal, b) > 0)
361 static int __app_resume_local()
363 if (!aul_is_initialized())
364 return AUL_R_ENOINIT;
371 static int __app_pause_local()
373 if (!aul_is_initialized())
374 return AUL_R_ENOINIT;
382 * @brief start caller with kb
383 * @return callee's pid
385 int app_request_to_launchpad(int cmd, const char *pkgname, bundle *kb)
390 #ifdef _APPFW_FEATURE_APP_CONTROL_LITE
391 char oldZone[64] = { 0, };
392 pkgmgrinfo_pkginfo_set_zone(_cur_zone, oldZone, 64);
395 traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "AUL:REQ_TO_PAD");
396 SECURE_LOGD("launch request : %s", pkgname);
398 kb = bundle_create();
403 __clear_internal_key(kb);
406 ret = bundle_add(kb, AUL_K_PKG_NAME, pkgname);
407 if (ret != BUNDLE_ERROR_NONE) {
415 case APP_START_ASYNC:
417 case APP_PAUSE_BY_PID:
418 ret = app_send_cmd_with_noreply(AUL_UTIL_PID, cmd, kb);
421 ret = app_send_cmd(AUL_UTIL_PID, cmd, kb);
425 _D("launch request result : %d", ret);
426 if (ret == AUL_R_LOCAL
427 #ifdef _APPFW_FEATURE_APP_CONTROL_LITE
428 || ret == AUL_R_UG_LOCAL
431 _E("app_request_to_launchpad : Same Process Send Local");
434 #ifdef _APPFW_FEATURE_APP_CONTROL_LITE
435 if(ret == AUL_R_UG_LOCAL) {
436 pkgmgrinfo_appinfo_h handle;
439 pkgmgrinfo_appinfo_get_appinfo(pkgname, &handle);
440 pkgmgrinfo_appinfo_get_exec(handle, &exec);
442 bundle_add(kb, "__AUL_UG_EXEC__", exec);
444 pkgmgrinfo_appinfo_destroy_appinfo(handle);
451 #ifdef _APPFW_FEATURE_MULTI_INSTANCE
452 case APP_START_MULTI_INSTANCE:
455 ret = __app_launch_local(b);
459 case APP_RESUME_BY_PID:
460 ret = __app_resume_local();
463 case APP_PAUSE_BY_PID:
464 ret = __app_pause_local();
467 _E("no support packet");
476 #ifdef _APPFW_FEATURE_APP_CONTROL_LITE
477 pkgmgrinfo_pkginfo_set_zone(oldZone, NULL, 0);
480 traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
485 static int __send_result_to_launchpad(int fd, int res)
487 if (send(fd, &res, sizeof(int), MSG_NOSIGNAL) < 0) {
488 if (errno == EPIPE) {
489 _E("send failed due to EPIPE.\n");
493 _E("send fail to client");
500 * @brief caller & callee's sock handler
502 int aul_sock_handler(int fd)
509 const char *str = NULL;
513 if ((pkt = __app_recv_raw(fd, &clifd, &cr)) == NULL) {
518 if (pkt->cmd != APP_RESULT && pkt->cmd != APP_CANCEL && pkt->cmd != APP_SUSPEND && pkt->cmd != APP_WAKE
519 &&cr.uid != 0 && cr.uid != SYSTEM_UID) {
520 _E("security error");
521 __send_result_to_launchpad(clifd, -1);
526 if (pkt->cmd != APP_RESULT && pkt->cmd != APP_CANCEL && pkt->cmd != APP_KEY_EVENT && pkt->cmd != APP_TERM_BY_PID_ASYNC
527 && pkt->cmd != APP_SUSPEND && pkt->cmd != APP_WAKE ) {
528 ret = __send_result_to_launchpad(clifd, 0);
538 case APP_START: /* run in callee */
540 case APP_START_ASYNC:
541 #ifdef _APPFW_FEATURE_MULTI_INSTANCE
542 case APP_START_MULTI_INSTANCE:
544 kbundle = bundle_decode(pkt->data, pkt->len);
548 bundle_free(kbundle);
551 case APP_OPEN: /* run in callee */
553 case APP_RESUME_BY_PID:
558 app_prepare_to_suspend();
561 app_prepare_to_wake();
563 case APP_TERM_BY_PID: /* run in callee */
564 case APP_TERM_BY_PID_ASYNC:
568 case APP_TERM_BGAPP_BY_PID:
572 case APP_TERM_REQ_BY_PID: /* run in callee */
573 app_subapp_terminate_request();
576 case APP_RESULT: /* run in caller */
578 kbundle = bundle_decode(pkt->data, pkt->len);
582 str = bundle_get_val(kbundle, AUL_K_CALLEE_PID);
585 app_result(pkt->cmd, kbundle, pid);
587 bundle_free(kbundle);
590 case APP_KEY_EVENT: /* run in caller */
591 kbundle = bundle_decode(pkt->data, pkt->len);
594 app_key_event(kbundle);
595 bundle_free(kbundle);
598 case APP_PAUSE_BY_PID:
603 _E("no support packet");
614 int aul_make_bundle_from_argv(int argc, char **argv, bundle **kb)
620 *kb = bundle_create();
627 if ((argv != NULL) && (argv[0] != NULL)) {
628 buf = strdup(argv[0]);
634 bundle_add(*kb, AUL_K_ARGV0, buf);
636 if (buf) { /*Prevent FIX: ID 38717 */
642 if (ac + 1 == argc) {
643 if (bundle_add(*kb, argv[ac], "") < 0) {
644 _E("bundle add error pos - %d", ac);
645 return AUL_R_ECANCELED;
648 if (bundle_add(*kb, argv[ac], argv[ac + 1]) < 0) {
649 _E("bundle add error pos - %d", ac);
650 return AUL_R_ECANCELED;
659 int aul_register_init_callback(
660 int (*aul_handler) (aul_type type, bundle *, void *), void *data)
662 /* Save start handler function in static var */
663 _aul_handler = aul_handler;
670 if (aul_initialized) {
671 _E("aul already initialized");
672 return AUL_R_ECANCELED;
674 aul_fd = __create_server_sock(getpid() + _pid_offset);
676 _E("aul_init create sock failed");
684 SLPAPI void aul_finalize()
689 if (aul_initialized) {
698 SLPAPI int aul_launch_app(const char *appid, bundle *kb)
703 return app_request_to_launchpad(APP_START, appid, kb);
706 SLPAPI int aul_launch_app_async(const char *appid, bundle *kb)
711 return app_request_to_launchpad(APP_START_ASYNC, appid, kb);
714 #ifdef _APPFW_FEATURE_MULTI_INSTANCE
715 SLPAPI int aul_launch_app_for_multi_instance(const char *appid, bundle *kb)
720 return app_request_to_launchpad(APP_START_MULTI_INSTANCE, appid, kb);
724 SLPAPI int aul_open_app(const char *appid)
729 return app_request_to_launchpad(APP_OPEN, appid, NULL);
732 SLPAPI int aul_resume_app(const char *appid)
737 return app_request_to_launchpad(APP_RESUME, appid, NULL);
740 SLPAPI int aul_resume_pid(int pid)
742 char pkgname[MAX_PID_STR_BUFSZ];
748 snprintf(pkgname, MAX_PID_STR_BUFSZ, "%d", pid);
749 ret = app_request_to_launchpad(APP_RESUME_BY_PID, pkgname, NULL);
753 SLPAPI int aul_terminate_pid(int pid)
755 char pkgname[MAX_PID_STR_BUFSZ];
761 snprintf(pkgname, MAX_PID_STR_BUFSZ, "%d", pid);
762 ret = app_request_to_launchpad(APP_TERM_BY_PID, pkgname, NULL);
766 SLPAPI int aul_terminate_bgapp_pid(int pid)
768 char pkgname[MAX_PID_STR_BUFSZ];
774 snprintf(pkgname, MAX_PID_STR_BUFSZ, "%d", pid);
775 ret = app_request_to_launchpad(APP_TERM_BGAPP_BY_PID, pkgname, NULL);
779 SLPAPI int aul_terminate_pid_without_restart(int pid)
781 char pkgname[MAX_PID_STR_BUFSZ];
787 snprintf(pkgname, MAX_PID_STR_BUFSZ, "%d", pid);
788 ret = app_request_to_launchpad(APP_TERM_BY_PID_WITHOUT_RESTART, pkgname, NULL);
792 SLPAPI int aul_terminate_pid_async(int pid)
794 char pkgname[MAX_PID_STR_BUFSZ];
800 snprintf(pkgname, MAX_PID_STR_BUFSZ, "%d", pid);
801 ret = app_request_to_launchpad(APP_TERM_BY_PID_ASYNC, pkgname, NULL);
805 SLPAPI int aul_kill_pid(int pid)
807 char pkgname[MAX_PID_STR_BUFSZ];
813 snprintf(pkgname, MAX_PID_STR_BUFSZ, "%d", pid);
814 ret = app_request_to_launchpad(APP_KILL_BY_PID, pkgname, NULL);
818 #ifdef _APPFW_FEATURE_PROCESS_POOL
819 SLPAPI void aul_set_preinit_window(void *evas_object)
821 __window_object = evas_object;
824 SLPAPI void* aul_get_preinit_window(const char *win_name)
826 return __window_object;
829 SLPAPI void aul_set_preinit_background(void *evas_object)
831 __bg_object = evas_object;
834 SLPAPI void* aul_get_preinit_background(void)
839 SLPAPI void aul_set_preinit_conformant(void *evas_object)
841 __conformant_object = evas_object;
844 SLPAPI void* aul_get_preinit_conformant(void)
846 return __conformant_object;
850 #ifdef _APPFW_FEATURE_DATA_CONTROL
851 SLPAPI int aul_set_data_control_provider_cb(data_control_provider_handler_fn handler)
853 __dc_handler = handler;
857 SLPAPI int aul_unset_data_control_provider_cb(void)
864 SLPAPI int aul_pause_app(const char *appid)
871 ret = app_request_to_launchpad(APP_PAUSE, appid, NULL);
875 SLPAPI int aul_pause_pid(int pid)
877 char app_pid[MAX_PID_STR_BUFSZ];
883 snprintf(app_pid, MAX_PID_STR_BUFSZ, "%d", pid);
884 ret = app_request_to_launchpad(APP_PAUSE_BY_PID, app_pid, NULL);
888 /* vi: set ts=8 sts=8 sw=8: */