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.
30 #include "simple_util.h"
34 /*#define ACTIVATE_PREEMPT_FEATURE*/
36 typedef struct _app_resultcb_info_t {
38 void (*cb_func) (bundle *kb, int is_cancel, void *data);
40 struct _app_resultcb_info_t *next;
41 } app_resultcb_info_t;
43 static int latest_caller_pid = -1;
44 static app_resultcb_info_t *rescb_head = NULL;
46 static void __add_resultcb(int pid, void (*cbfunc) (bundle *, int, void *),
48 static app_resultcb_info_t *__find_resultcb(int pid);
49 static void __remove_resultcb(app_resultcb_info_t *info);
50 static int __call_app_result_callback(bundle *kb, int is_cancel,
52 static int __get_caller_pid(bundle *kb);
56 static void __add_resultcb(int pid, void (*cbfunc) (bundle *, int, void *),
59 app_resultcb_info_t *info;
61 info = (app_resultcb_info_t *) malloc(sizeof(app_resultcb_info_t));
64 info->launched_pid = pid;
65 info->cb_func = cbfunc;
66 info->priv_data = data;
68 info->next = rescb_head;
72 static app_resultcb_info_t *__find_resultcb(int pid)
74 app_resultcb_info_t *tmp;
78 if (tmp->launched_pid == pid)
85 static void __remove_resultcb(app_resultcb_info_t *info)
87 app_resultcb_info_t *tmp;
89 if (rescb_head == NULL || info == NULL)
92 if (rescb_head == info) {
93 rescb_head = info->next;
100 if (tmp->next == info) {
101 tmp->next = info->next;
110 * call result callback function
113 static int __call_app_result_callback(bundle *kb, int is_cancel,
116 app_resultcb_info_t *info;
120 if (((info = __find_resultcb(launched_pid)) == NULL)
121 || (launched_pid < 0)) {
122 _E("reject by pid - wait pid = %d, recvd pid = %d\n", getpid(),
125 /* second chance - support app launched by shell script*/
126 pgid = getpgid(launched_pid);
129 if ((info = __find_resultcb(pgid)) == NULL) {
130 _E("second chance : also reject pgid - %d\n", pgid);
135 if (info->cb_func == NULL || kb == NULL)
138 /* In case of aul_forward_app, update the callback data */
140 (fwdpid_str = (char *)bundle_get_val(kb, AUL_K_FWD_CALLEE_PID)))
142 app_resultcb_info_t newinfo;
143 newinfo.launched_pid = atoi(fwdpid_str);
144 newinfo.cb_func = info->cb_func;
145 newinfo.priv_data = info->priv_data;
147 __remove_resultcb(info);
148 __add_resultcb(newinfo.launched_pid, newinfo.cb_func, newinfo.priv_data);
150 _D("change callback - %s\n",AUL_K_FWD_CALLEE_PID);
155 info->cb_func(kb, is_cancel, info->priv_data);
156 __remove_resultcb(info);
162 static int __get_caller_pid(bundle *kb)
167 pid_str = bundle_get_val(kb, AUL_K_ORG_CALLER_PID);
171 pid_str = bundle_get_val(kb, AUL_K_CALLER_PID);
183 #ifdef ACTIVATE_PREEMPT_FEATURE
184 static int __send_to_cancel(int pid)
186 /* Say "Your result request is cancel!" to caller */
189 char tmp_pid[MAX_PID_STR_BUFSZ];
191 kb = bundle_create();
194 bundle_add(kb, AUL_K_SEND_RESULT, "1");
196 snprintf(tmp_pid, MAX_PID_STR_BUFSZ, "%d", pid);
197 bundle_add(kb, AUL_K_CALLER_PID, tmp_pid);
199 ret = app_send_cmd(LAUNCHPAD_PID, APP_CANCEL, kb);
205 static int __send_to_cancel(int pid)
211 int _app_start_res_prepare(bundle *kb)
215 if (bundle_get_val(kb, AUL_K_WAIT_RESULT) == NULL)
218 if ((pid = __get_caller_pid(kb)) < 0) {
219 _E("caller pid is not valid");
222 /* If previous caller is still waiting result,
223 send cancel packet to the caller. */
224 if (latest_caller_pid != -1)
225 __send_to_cancel(latest_caller_pid);
227 latest_caller_pid = pid;
228 _D("result msg prepare done");
233 int app_result(int cmd, bundle *kb, int launched_pid)
237 __call_app_result_callback(kb, 0, launched_pid);
240 __call_app_result_callback(kb, 1, launched_pid);
247 SLPAPI int aul_launch_app_with_result(const char *pkgname, bundle *kb,
248 void (*cbfunc) (bundle *, int, void *),
253 if (!aul_is_initialized()) {
254 if (aul_launch_init(NULL, NULL) < 0)
255 return AUL_R_ENOINIT;
258 if (pkgname == NULL || cbfunc == NULL || kb == NULL)
261 ret = app_request_to_launchpad(APP_START_RES, pkgname, kb);
264 __add_resultcb(ret, cbfunc, data);
269 void __iterate(const char *key, const char *val, void *data)
272 _D("%d %s %s", i++, key, val);
275 SLPAPI int aul_forward_app(const char* pkgname, bundle *kb)
281 char tmp_pid[MAX_PID_STR_BUFSZ];
283 if(pkgname == NULL || kb == NULL)
286 caller = (char *)bundle_get_val(kb, AUL_K_CALLER_PID);
288 _E("original msg doest not have caller pid");
292 bundle_del(kb, AUL_K_ORG_CALLER_PID);
293 bundle_add(kb, AUL_K_ORG_CALLER_PID, caller);
295 dupb = bundle_dup(kb);
297 _E("bundle duplicate fail");
301 if(bundle_get_val(kb, AUL_K_WAIT_RESULT) != NULL) {
302 ret = app_request_to_launchpad(APP_START_RES, pkgname, kb);
306 ret = app_request_to_launchpad(APP_START, pkgname, kb);
310 // bundle_iterate(dupb, __iterate, NULL);
312 snprintf(tmp_pid, MAX_PID_STR_BUFSZ,"%d",ret);
314 ret = aul_create_result_bundle(dupb, &outb);
318 bundle_del(outb, AUL_K_FWD_CALLEE_PID);
319 bundle_add(outb, AUL_K_FWD_CALLEE_PID, tmp_pid);
321 // bundle_iterate(outb, __iterate, NULL);
323 ret = aul_send_result(outb, 1);
333 SLPAPI int aul_create_result_bundle(bundle *inb, bundle **outb)
340 _E("return msg create fail");
344 *outb = bundle_create();
346 _E("return msg create fail");
350 if(bundle_get_val(inb, AUL_K_WAIT_RESULT) != NULL) {
351 bundle_add(*outb, AUL_K_SEND_RESULT, "1");
352 _D("original msg is msg with result");
354 _D("original msg is not msg with result");
358 pid_str = bundle_get_val(inb, AUL_K_ORG_CALLER_PID);
360 bundle_add(*outb, AUL_K_ORG_CALLER_PID, pid_str);
364 pid_str = bundle_get_val(inb, AUL_K_CALLER_PID);
365 if (pid_str == NULL) {
366 _E("original msg doest not have caller pid");
371 bundle_add(*outb, AUL_K_CALLER_PID, pid_str);
377 int aul_send_result(bundle *kb, int is_cancel)
382 if ((pid = __get_caller_pid(kb)) < 0)
385 if (bundle_get_val(kb, AUL_K_SEND_RESULT) == NULL)
387 _D("original msg is not msg with result");
391 ret = app_send_cmd(AUL_UTIL_PID, (is_cancel==1)? APP_CANCEL : APP_RESULT, kb);
393 if(latest_caller_pid == pid)
394 latest_caller_pid = -1;