2 * Copyright (c) 2011 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
24 #include <bundle_internal.h>
30 #include <app_control.h>
36 #define LOG_TAG "CAPI_APPFW_APP_CONTROL"
38 #ifndef TIZEN_PATH_MAX
39 #define TIZEN_PATH_MAX 1024
42 #define BUNDLE_KEY_PREFIX_AUL "__AUL_"
43 #define BUNDLE_KEY_PREFIX_SERVICE "__APP_SVC_"
45 #define BUNDLE_KEY_OPERATION "__APP_SVC_OP_TYPE__"
46 #define BUNDLE_KEY_URI "__APP_SVC_URI__"
47 #define BUNDLE_KEY_MIME "__APP_SVC_MIME_TYPE__"
48 #define BUNDLE_KEY_DATA "__APP_SVC_DATA__"
49 #define BUNDLE_KEY_PACKAGE "__APP_SVC_PKG_NAME__"
50 #define BUNDLE_KEY_WINDOW "__APP_SVC_K_WIN_ID__"
51 #define BUNDLE_KEY_CATEGORY "__APP_SVC_CATEGORY__"
53 #define LAUNCH_MODE_SIZE 8
54 #define LAUNCH_MODE_SINGLE "single"
55 #define LAUNCH_MODE_GROUP "group"
58 APP_CONTROL_TYPE_REQUEST,
59 APP_CONTROL_TYPE_EVENT,
60 APP_CONTROL_TYPE_REPLY,
63 struct app_control_s {
65 app_control_type_e type;
70 typedef struct app_control_request_context_s {
71 app_control_h app_control;
72 app_control_reply_cb reply_cb;
74 } *app_control_request_context_h;
76 extern int appsvc_allow_transient_app(bundle *b, unsigned int id);
77 extern int appsvc_request_transient_app(bundle *b, unsigned int callee_id, appsvc_host_res_fn cbfunc, void *data);
78 static int app_control_create_reply(bundle *data, struct app_control_s **app_control);
80 static const char *app_control_error_to_string(app_control_error_e error)
83 case APP_CONTROL_ERROR_NONE:
85 case APP_CONTROL_ERROR_INVALID_PARAMETER:
86 return "INVALID_PARAMETER";
87 case APP_CONTROL_ERROR_OUT_OF_MEMORY:
88 return "OUT_OF_MEMORY";
89 case APP_CONTROL_ERROR_APP_NOT_FOUND:
90 return "APP_NOT_FOUND";
91 case APP_CONTROL_ERROR_KEY_NOT_FOUND:
92 return "KEY_NOT_FOUND";
93 case APP_CONTROL_ERROR_KEY_REJECTED:
94 return "KEY_REJECTED";
95 case APP_CONTROL_ERROR_INVALID_DATA_TYPE:
96 return "INVALID_DATA_TYPE";
97 case APP_CONTROL_ERROR_LAUNCH_REJECTED:
98 return "LAUNCH_REJECTED";
99 case APP_CONTROL_ERROR_PERMISSION_DENIED:
100 return "PERMISSION_DENIED";
101 case APP_CONTROL_ERROR_LAUNCH_FAILED:
102 return "LAUNCH_FAILED";
103 case APP_CONTROL_ERROR_TIMED_OUT:
105 case APP_CONTROL_ERROR_IO_ERROR:
112 int app_control_error(app_control_error_e error, const char *function, const char *description)
115 LOGE("[%s] %s(0x%08x) : %s", function, app_control_error_to_string(error), error, description);
117 if (error == APP_CONTROL_ERROR_KEY_NOT_FOUND)
118 LOGW("[%s] %s(0x%08x)", function, app_control_error_to_string(error), error);
120 LOGE("[%s] %s(0x%08x)", function, app_control_error_to_string(error), error);
126 static int app_control_validate_extra_data(const char *data)
128 if (data == NULL || data[0] == '\0')
129 return APP_CONTROL_ERROR_INVALID_PARAMETER;
131 return APP_CONTROL_ERROR_NONE;
134 static int app_control_validate(app_control_h app_control)
136 if (app_control == NULL || app_control->data == NULL)
137 return APP_CONTROL_ERROR_INVALID_PARAMETER;
139 return APP_CONTROL_ERROR_NONE;
142 static int app_control_new_id()
148 int app_control_validate_internal_key(const char *key)
150 if (strncmp(BUNDLE_KEY_PREFIX_AUL, key, strlen(BUNDLE_KEY_PREFIX_AUL)) == 0)
153 if (strncmp(BUNDLE_KEY_PREFIX_SERVICE, key, strlen(BUNDLE_KEY_PREFIX_SERVICE)) == 0)
159 static void app_control_request_result_broker(bundle *appsvc_bundle, int appsvc_request_code, appsvc_result_val appsvc_result, void *appsvc_data)
161 app_control_request_context_h request_context;
162 app_control_h request;
163 app_control_h reply = NULL;
164 app_control_result_e result;
166 app_control_reply_cb reply_cb;
168 if (appsvc_data == NULL) {
169 app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid app_control reply");
173 if (app_control_create_reply(appsvc_bundle, &reply) != 0) {
174 app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to create app_control reply");
178 request_context = appsvc_data;
179 request = request_context->app_control;
181 switch (appsvc_result) {
183 result = APP_CONTROL_RESULT_SUCCEEDED;
185 case APPSVC_RES_NOT_OK:
186 result = APP_CONTROL_RESULT_FAILED;
188 case APPSVC_RES_CANCEL:
189 result = APP_CONTROL_RESULT_CANCELED;
192 result = APP_CONTROL_RESULT_CANCELED;
196 user_data = request_context->user_data;
197 reply_cb = request_context->reply_cb;
199 if (reply_cb != NULL)
200 reply_cb(request, reply, result, user_data);
202 app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid callback ");
204 app_control_destroy(reply);
206 if (request_context->app_control != NULL)
207 app_control_destroy(request_context->app_control);
209 free(request_context);
212 int app_control_create_request(bundle *data, app_control_h *app_control)
214 struct app_control_s *app_control_request;
216 if (app_control == NULL)
217 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
219 app_control_request = malloc(sizeof(struct app_control_s));
220 if (app_control_request == NULL)
221 return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create a app_control handle");
223 app_control_request->type = APP_CONTROL_TYPE_REQUEST;
226 app_control_request->data = bundle_dup(data);
228 app_control_request->data = bundle_create();
230 if (app_control_request->data == NULL) {
231 free(app_control_request);
232 return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create a bundle");
235 app_control_request->id = app_control_new_id();
236 app_control_request->launch_pid = -1;
238 *app_control = app_control_request;
240 return APP_CONTROL_ERROR_NONE;
243 int app_control_create(app_control_h *app_control)
245 return app_control_create_request(NULL, app_control);
248 int app_control_create_event(bundle *data, struct app_control_s **app_control)
250 struct app_control_s *app_control_event;
252 const char *operation;
254 if (data == NULL || app_control == NULL)
255 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
257 app_control_event = malloc(sizeof(struct app_control_s));
258 if (app_control_event == NULL)
259 return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create a app_control handle");
261 app_control_event->type = APP_CONTROL_TYPE_EVENT;
262 app_control_event->data = bundle_dup(data);
263 app_control_event->id = app_control_new_id();
265 operation = appsvc_get_operation(app_control_event->data);
266 if (operation == NULL)
267 appsvc_set_operation(app_control_event->data, APP_CONTROL_OPERATION_DEFAULT);
269 *app_control = app_control_event;
271 return APP_CONTROL_ERROR_NONE;
274 static int app_control_create_reply(bundle *data, struct app_control_s **app_control)
276 struct app_control_s *app_control_reply;
278 if (data == NULL || app_control == NULL)
279 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
281 app_control_reply = malloc(sizeof(struct app_control_s));
282 if (app_control_reply == NULL)
283 return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create a app_control handle");
285 app_control_reply->type = APP_CONTROL_TYPE_REPLY;
286 app_control_reply->data = bundle_dup(data);
287 app_control_reply->id = app_control_new_id();
289 *app_control = app_control_reply;
291 return APP_CONTROL_ERROR_NONE;
294 int app_control_destroy(app_control_h app_control)
296 if (app_control_validate(app_control))
297 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
299 if (app_control->type == APP_CONTROL_TYPE_REQUEST && app_control->launch_pid > 0
300 && bundle_get_val(app_control->data, AUL_SVC_K_LAUNCH_RESULT_APP_STARTED) == NULL)
301 aul_remove_caller_cb(app_control->launch_pid, app_control);
303 bundle_free(app_control->data);
304 app_control->data = NULL;
307 return APP_CONTROL_ERROR_NONE;
310 int app_control_to_bundle(app_control_h app_control, bundle **data)
312 if (app_control_validate(app_control) || data == NULL)
313 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
315 *data = app_control->data;
317 return APP_CONTROL_ERROR_NONE;
320 int app_control_set_operation(app_control_h app_control, const char *operation)
322 if (app_control_validate(app_control))
323 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
325 if (operation != NULL) {
326 if (appsvc_set_operation(app_control->data, operation) != 0)
327 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid operation");
329 bundle_del(app_control->data, BUNDLE_KEY_OPERATION);
332 return APP_CONTROL_ERROR_NONE;
335 int app_control_get_operation(app_control_h app_control, char **operation)
337 const char *operation_value;
339 if (app_control_validate(app_control) || operation == NULL)
340 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
342 operation_value = appsvc_get_operation(app_control->data);
343 if (operation_value != NULL)
344 *operation = strdup(operation_value);
348 return APP_CONTROL_ERROR_NONE;
351 int app_control_set_uri(app_control_h app_control, const char *uri)
353 if (app_control_validate(app_control))
354 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
357 if (appsvc_set_uri(app_control->data, uri) != 0)
358 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid URI");
360 bundle_del(app_control->data, BUNDLE_KEY_URI);
363 return APP_CONTROL_ERROR_NONE;
366 int app_control_get_uri(app_control_h app_control, char **uri)
368 const char *uri_value;
370 if (app_control_validate(app_control) || uri == NULL)
371 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
373 uri_value = appsvc_get_uri(app_control->data);
374 if (uri_value != NULL)
375 *uri = strdup(uri_value);
379 return APP_CONTROL_ERROR_NONE;
382 int app_control_set_mime(app_control_h app_control, const char *mime)
384 if (app_control_validate(app_control))
385 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
388 if (appsvc_set_mime(app_control->data, mime) != 0)
389 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid MIME type");
391 bundle_del(app_control->data, BUNDLE_KEY_MIME);
394 return APP_CONTROL_ERROR_NONE;
397 int app_control_get_mime(app_control_h app_control, char **mime)
399 const char *mime_value;
401 if (app_control_validate(app_control) || mime == NULL)
402 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
404 mime_value = appsvc_get_mime(app_control->data);
405 if (mime_value != NULL)
406 *mime = strdup(mime_value);
410 return APP_CONTROL_ERROR_NONE;
413 int app_control_set_category(app_control_h app_control, const char *category)
415 if (app_control_validate(app_control))
416 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
418 if (category != NULL) {
419 if (appsvc_set_category(app_control->data, category) != 0)
420 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid Category");
422 bundle_del(app_control->data, BUNDLE_KEY_CATEGORY);
425 return APP_CONTROL_ERROR_NONE;
428 int app_control_get_category(app_control_h app_control, char **category)
430 const char *category_value;
432 if (app_control_validate(app_control) || category == NULL)
433 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
435 category_value = appsvc_get_category(app_control->data);
436 if (category_value != NULL)
437 *category = strdup(category_value);
441 return APP_CONTROL_ERROR_NONE;
444 int app_control_set_package(app_control_h app_control, const char *package)
446 /* TODO: this function must be deprecated */
447 return app_control_set_app_id(app_control, package);
450 int app_control_get_package(app_control_h app_control, char **package)
452 /* TODO: this function must be deprecated */
453 return app_control_get_app_id(app_control, package);
456 int app_control_set_app_id(app_control_h app_control, const char *app_id)
458 if (app_control_validate(app_control))
459 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
461 if (app_id != NULL) {
462 if (appsvc_set_appid(app_control->data, app_id) != 0)
463 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid application ID");
465 bundle_del(app_control->data, BUNDLE_KEY_PACKAGE);
468 return APP_CONTROL_ERROR_NONE;
471 int app_control_get_app_id(app_control_h app_control, char **app_id)
473 const char *app_id_value;
475 if (app_control_validate(app_control) || app_id == NULL)
476 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
478 app_id_value = appsvc_get_appid(app_control->data);
479 if (app_id_value != NULL)
480 *app_id = strdup(app_id_value);
484 return APP_CONTROL_ERROR_NONE;
487 int app_control_set_window(app_control_h app_control, unsigned int id)
489 if (app_control_validate(app_control))
490 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
493 if (appsvc_allow_transient_app(app_control->data, id) != 0)
494 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid id");
496 bundle_del(app_control->data, BUNDLE_KEY_WINDOW);
499 return APP_CONTROL_ERROR_NONE;
502 int app_control_get_window(app_control_h app_control, unsigned int *id)
504 const char *window_id;
506 if (app_control_validate(app_control) || id == NULL)
507 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
509 window_id = bundle_get_val(app_control->data, BUNDLE_KEY_WINDOW);
510 if (window_id != NULL)
511 *id = atoi(window_id);
515 return APP_CONTROL_ERROR_NONE;
518 int app_control_clone(app_control_h *clone, app_control_h app_control)
520 app_control_h app_control_clone;
522 if (app_control_validate(app_control) || clone == NULL)
523 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
525 app_control_clone = malloc(sizeof(struct app_control_s));
526 if (app_control_clone == NULL)
527 return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create a app_control handle");
529 app_control_clone->id = app_control_new_id();
530 app_control_clone->type = app_control->type;
531 app_control_clone->data = bundle_dup(app_control->data);
533 *clone = app_control_clone;
535 return APP_CONTROL_ERROR_NONE;
538 int app_control_set_launch_mode(app_control_h app_control,
539 app_control_launch_mode_e mode)
541 char launch_mode[LAUNCH_MODE_SIZE] = { 0, };
543 if (app_control_validate(app_control)) {
544 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER,
549 case APP_CONTROL_LAUNCH_MODE_SINGLE:
550 strncpy(launch_mode, LAUNCH_MODE_SINGLE, strlen(LAUNCH_MODE_SINGLE));
552 case APP_CONTROL_LAUNCH_MODE_GROUP:
553 strncpy(launch_mode, LAUNCH_MODE_GROUP, strlen(LAUNCH_MODE_GROUP));
556 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER,
557 __FUNCTION__, "invalid mode");
560 return appsvc_set_launch_mode(app_control->data, launch_mode);
563 int app_control_get_launch_mode(app_control_h app_control,
564 app_control_launch_mode_e *mode)
566 const char *launch_mode;
568 if (app_control_validate(app_control)) {
569 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER,
573 launch_mode = appsvc_get_launch_mode(app_control->data);
574 if (launch_mode == NULL) {
575 *mode = APP_CONTROL_LAUNCH_MODE_SINGLE;
577 if (!strcmp(launch_mode, LAUNCH_MODE_SINGLE)) {
578 *mode = APP_CONTROL_LAUNCH_MODE_SINGLE;
579 } else if (!strcmp(launch_mode, LAUNCH_MODE_GROUP)) {
580 *mode = APP_CONTROL_LAUNCH_MODE_GROUP;
582 *mode = APP_CONTROL_LAUNCH_MODE_SINGLE;
583 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER,
584 __FUNCTION__, "launch_mode is not matched");
588 return APP_CONTROL_ERROR_NONE;
591 int app_control_set_defapp(app_control_h app_control, const char *app_id)
595 if (app_control_validate(app_control) || app_id == NULL)
596 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
598 ret = aul_svc_set_appid(app_control->data, app_id);
600 return app_control_error(APP_CONTROL_ERROR_IO_ERROR, __FUNCTION__, NULL);
602 ret = aul_set_default_app_by_operation(app_control->data);
604 if (ret == AUL_R_EILLACC)
605 return app_control_error(APP_CONTROL_ERROR_PERMISSION_DENIED, __FUNCTION__, NULL);
607 return app_control_error(APP_CONTROL_ERROR_IO_ERROR, __FUNCTION__, NULL);
610 return APP_CONTROL_ERROR_NONE;
613 int app_control_unset_defapp(const char *app_id)
618 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
620 ret = aul_unset_default_app_by_operation(app_id);
622 if (ret == AUL_R_EILLACC)
623 return app_control_error(APP_CONTROL_ERROR_PERMISSION_DENIED, __FUNCTION__, NULL);
625 return app_control_error(APP_CONTROL_ERROR_IO_ERROR, __FUNCTION__, NULL);
628 return APP_CONTROL_ERROR_NONE;
631 static void __update_launch_pid(int launched_pid, void *data)
633 app_control_h app_control;
640 app_control->launch_pid = launched_pid;
643 static void __handle_launch_result(int launched_pid, void *data)
645 app_control_request_context_h request_context;
646 app_control_h reply = NULL;
647 app_control_h request;
648 app_control_result_e result;
649 app_control_reply_cb reply_cb;
651 char callee[255] = {0, };
657 request_context = (app_control_request_context_h)data;
659 if (app_control_create_event(request_context->app_control->data, &reply) != 0) {
660 app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to create app_control event");
664 ret = aul_app_get_appid_bypid(launched_pid, callee, sizeof(callee));
666 LOGE("aul_app_get_appid_bypid failed: %d", launched_pid);
668 app_control_set_app_id(reply, callee);
669 LOGI("app control async result callback callee pid:%d", launched_pid);
671 result = APP_CONTROL_RESULT_APP_STARTED;
672 request = request_context->app_control;
673 user_data = request_context->user_data;
674 reply_cb = request_context->reply_cb;
676 if (reply_cb != NULL)
677 reply_cb(request, reply, result, user_data);
679 app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid callback ");
681 app_control_destroy(reply);
684 int app_control_send_launch_request(app_control_h app_control, app_control_reply_cb callback, void *user_data)
686 const char *operation;
687 bool implicit_default_operation = false;
689 app_control_request_context_h request_context = NULL;
691 if (app_control_validate(app_control))
692 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
694 operation = appsvc_get_operation(app_control->data);
695 if (operation == NULL) {
696 implicit_default_operation = true;
697 operation = APP_CONTROL_OPERATION_DEFAULT;
700 if (!strcmp(operation, APP_CONTROL_OPERATION_LAUNCH_ON_EVENT))
701 return app_control_error(APP_CONTROL_ERROR_LAUNCH_REJECTED, __FUNCTION__,
702 "Not supported operation value");
704 /* TODO: Check the privilege for call operation */
706 /* operation : default */
707 if (!strcmp(operation, APP_CONTROL_OPERATION_DEFAULT)) {
708 const char *appid = appsvc_get_appid(app_control->data);
710 return app_control_error(APP_CONTROL_ERROR_APP_NOT_FOUND, __FUNCTION__, "package must be specified if the operation is default value");
713 if (callback != NULL) {
714 app_control_h request_clone = NULL;
716 request_context = calloc(1, sizeof(struct app_control_request_context_s));
717 if (request_context == NULL)
718 return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
720 request_context->reply_cb = callback;
722 if (app_control_clone(&request_clone, app_control) != APP_CONTROL_ERROR_NONE) {
723 free(request_context);
724 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to clone the app_control request handle");
727 request_context->app_control = request_clone;
728 request_context->user_data = user_data;
731 if (implicit_default_operation == true)
732 appsvc_set_operation(app_control->data, APP_CONTROL_OPERATION_DEFAULT);
734 launch_pid = appsvc_usr_run_service(app_control->data, app_control->id, callback ? app_control_request_result_broker : NULL, request_context, getuid());
735 if (implicit_default_operation == true)
736 bundle_del(app_control->data, BUNDLE_KEY_OPERATION);
738 if (launch_pid < 0) {
739 if (launch_pid == APPSVC_RET_ENOMATCH)
740 return app_control_error(APP_CONTROL_ERROR_APP_NOT_FOUND, __FUNCTION__, NULL);
741 else if (launch_pid == APPSVC_RET_EILLACC)
742 return app_control_error(APP_CONTROL_ERROR_PERMISSION_DENIED, __FUNCTION__, NULL);
743 else if (launch_pid == APPSVC_RET_EINVAL)
744 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
746 return app_control_error(APP_CONTROL_ERROR_LAUNCH_REJECTED, __FUNCTION__, NULL);
749 app_control->launch_pid = launch_pid;
750 /* app_control_enable_app_started_result_event called */
751 if (bundle_get_val(app_control->data, AUL_SVC_K_LAUNCH_RESULT_APP_STARTED)) {
752 char callee[255] = {0,};
753 if (aul_app_get_appid_bypid(launch_pid, callee, sizeof(callee)) != AUL_R_OK)
754 LOGE("aul_app_get_appid_bypid failed: %d", launch_pid);
756 if (request_context && request_context->app_control)
757 request_context->app_control->launch_pid = launch_pid;
759 aul_add_caller_cb(launch_pid, __handle_launch_result, request_context);
761 /* launched without app selector */
762 if (strncmp(callee, APP_SELECTOR, strlen(APP_SELECTOR)) != 0)
763 aul_invoke_caller_cb(request_context);
765 } else { /* default case */
766 aul_add_caller_cb(launch_pid, __update_launch_pid, app_control);
769 return APP_CONTROL_ERROR_NONE;
772 int app_control_send_terminate_request(app_control_h app_control)
774 if (app_control_validate(app_control))
775 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
777 if (app_control->type != APP_CONTROL_TYPE_REQUEST || app_control->launch_pid < 0)
778 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
780 appsvc_subapp_terminate_request_pid(app_control->launch_pid);
782 return APP_CONTROL_ERROR_NONE;
785 static bool app_control_copy_reply_data_cb(app_control_h app_control, const char *key, void *user_data)
787 bundle *reply_data = user_data;
789 char **value_array = NULL;
790 int value_array_length = 0;
791 int value_array_index = 0;
793 if (reply_data == NULL) {
794 app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
798 if (appsvc_data_is_array(app_control->data, key)) {
799 app_control_get_extra_data_array(app_control, key, &value_array, &value_array_length);
800 appsvc_add_data_array(reply_data, key, (const char **)value_array, value_array_length);
802 for (value_array_index = 0; value_array_index < value_array_length; value_array_index++)
803 free(value_array[value_array_index]);
807 app_control_get_extra_data(app_control, key, &value);
808 appsvc_add_data(reply_data, key, value);
815 int app_control_reply_to_launch_request(app_control_h reply, app_control_h request, app_control_result_e result)
821 if (app_control_validate(reply) || app_control_validate(request))
822 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
824 if (result == APP_CONTROL_RESULT_APP_STARTED)
825 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "APP_CONTROL_RESULT_APP_STARTED is not allowed to use");
827 if (appsvc_create_result_bundle(request->data, &reply_data) != 0)
828 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to create a result bundle");
830 app_control_foreach_extra_data(reply, app_control_copy_reply_data_cb, reply_data);
833 case APP_CONTROL_RESULT_SUCCEEDED:
834 appsvc_result = APPSVC_RES_OK;
836 case APP_CONTROL_RESULT_FAILED:
837 appsvc_result = APPSVC_RES_NOT_OK;
839 case APP_CONTROL_RESULT_CANCELED:
840 appsvc_result = APPSVC_RES_CANCEL;
843 appsvc_result = APPSVC_RES_CANCEL;
847 ret = appsvc_send_result(reply_data, appsvc_result);
848 bundle_free(reply_data);
850 if (ret == APPSVC_RET_EINVAL)
851 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
853 return app_control_error(APP_CONTROL_ERROR_LAUNCH_REJECTED, __FUNCTION__, NULL);
856 return APP_CONTROL_ERROR_NONE;
860 int app_control_add_extra_data(app_control_h app_control, const char *key, const char *value)
862 if (app_control_validate(app_control) || app_control_validate_extra_data(key) || app_control_validate_extra_data(value))
863 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
865 if (app_control_validate_internal_key(key))
866 return app_control_error(APP_CONTROL_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use");
868 if (appsvc_get_data(app_control->data, key) != NULL) {
869 /* overwrite any existing value */
870 bundle_del(app_control->data, key);
873 if (appsvc_add_data(app_control->data, key, value) != 0)
874 return app_control_error(APP_CONTROL_ERROR_KEY_REJECTED, __FUNCTION__, "failed to add data to the appsvc handle");
876 return APP_CONTROL_ERROR_NONE;
880 int app_control_add_extra_data_array(app_control_h app_control, const char *key, const char* value[], int length)
882 if (app_control_validate(app_control) || app_control_validate_extra_data(key))
883 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
885 if (value == NULL || length <= 0)
886 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid array");
888 if (app_control_validate_internal_key(key))
889 return app_control_error(APP_CONTROL_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use");
891 if (appsvc_get_data_array(app_control->data, key, NULL) != NULL) {
892 /* overwrite any existing value */
893 bundle_del(app_control->data, key);
896 if (appsvc_add_data_array(app_control->data, key, value, length) != 0)
897 return app_control_error(APP_CONTROL_ERROR_KEY_REJECTED, __FUNCTION__, "failed to add array data to the appsvc handle");
899 return APP_CONTROL_ERROR_NONE;
902 int app_control_remove_extra_data(app_control_h app_control, const char *key)
904 if (app_control_validate(app_control) || app_control_validate_extra_data(key))
905 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
907 if (app_control_validate_internal_key(key))
908 return app_control_error(APP_CONTROL_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use");
910 if (bundle_del(app_control->data, key))
911 return app_control_error(APP_CONTROL_ERROR_KEY_NOT_FOUND, __FUNCTION__, NULL);
913 return APP_CONTROL_ERROR_NONE;
916 int app_control_get_extra_data(app_control_h app_control, const char *key, char **value)
918 const char *data_value;
920 if (app_control_validate(app_control) || app_control_validate_extra_data(key) || value == NULL)
921 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
923 if (app_control_validate_internal_key(key))
924 return app_control_error(APP_CONTROL_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use");
926 data_value = appsvc_get_data(app_control->data, key);
927 if (data_value == NULL) {
928 if (errno == ENOTSUP)
929 return app_control_error(APP_CONTROL_ERROR_INVALID_DATA_TYPE, __FUNCTION__, NULL);
931 return app_control_error(APP_CONTROL_ERROR_KEY_NOT_FOUND, __FUNCTION__, NULL);
934 *value = strdup(data_value);
936 return APP_CONTROL_ERROR_NONE;
939 int app_control_get_extra_data_array(app_control_h app_control, const char *key, char ***value, int *length)
941 const char **array_data;
942 int array_data_length;
943 char **array_data_clone;
946 if (app_control_validate(app_control) || app_control_validate_extra_data(key))
947 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
949 if (value == NULL || length == 0)
950 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
952 if (app_control_validate_internal_key(key))
953 return app_control_error(APP_CONTROL_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use");
955 array_data = appsvc_get_data_array(app_control->data, key, &array_data_length);
956 if (array_data == NULL) {
957 if (errno == ENOTSUP)
958 return app_control_error(APP_CONTROL_ERROR_INVALID_DATA_TYPE, __FUNCTION__, NULL);
960 return app_control_error(APP_CONTROL_ERROR_KEY_NOT_FOUND, __FUNCTION__, NULL);
963 array_data_clone = calloc(array_data_length, sizeof(char *));
964 if (array_data_clone == NULL)
965 return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
967 for (i = 0; i < array_data_length; i++) {
968 if (array_data[i] != NULL)
969 array_data_clone[i] = strdup(array_data[i]);
972 *value = array_data_clone;
973 *length = array_data_length;
975 return APP_CONTROL_ERROR_NONE;
978 int app_control_is_extra_data_array(app_control_h app_control, const char *key, bool *array)
980 if (app_control_validate(app_control) || app_control_validate_extra_data(key) || array == NULL)
981 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
983 if (app_control_validate_internal_key(key))
984 return app_control_error(APP_CONTROL_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use");
986 if (!appsvc_data_is_array(app_control->data, key))
991 return APP_CONTROL_ERROR_NONE;
995 app_control_h app_control;
996 app_control_extra_data_cb callback;
999 } foreach_context_extra_data_t;
1001 static void app_control_cb_broker_bundle_iterator(const char *key, const int type, const bundle_keyval_t *kv, void *user_data)
1003 foreach_context_extra_data_t *foreach_context = NULL;
1004 app_control_extra_data_cb extra_data_cb;
1006 if (key == NULL || !(type == BUNDLE_TYPE_STR || type == BUNDLE_TYPE_STR_ARRAY))
1009 foreach_context = (foreach_context_extra_data_t *)user_data;
1010 if (foreach_context->foreach_break == true)
1013 if (app_control_validate_internal_key(key))
1016 extra_data_cb = foreach_context->callback;
1018 if (extra_data_cb != NULL) {
1019 bool stop_foreach = false;
1021 stop_foreach = !extra_data_cb(foreach_context->app_control, key, foreach_context->user_data);
1023 foreach_context->foreach_break = stop_foreach;
1027 int app_control_foreach_extra_data(app_control_h app_control, app_control_extra_data_cb callback, void *user_data)
1029 foreach_context_extra_data_t foreach_context = {
1030 .app_control = app_control,
1031 .callback = callback,
1032 .user_data = user_data,
1033 .foreach_break = false
1036 if (app_control_validate(app_control) || callback == NULL)
1037 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1039 bundle_foreach(app_control->data, app_control_cb_broker_bundle_iterator, &foreach_context);
1041 return APP_CONTROL_ERROR_NONE;
1045 app_control_h app_control;
1046 app_control_app_matched_cb callback;
1049 } foreach_context_launchable_app_t;
1051 int app_control_cb_broker_foreach_app_matched(const char *package, void *data)
1053 foreach_context_launchable_app_t *foreach_context;
1054 app_control_app_matched_cb app_matched_cb;
1056 if (package == NULL || data == NULL) {
1057 app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1061 foreach_context = (foreach_context_launchable_app_t *)data;
1062 if (foreach_context->foreach_break == true)
1065 app_matched_cb = foreach_context->callback;
1066 if (app_matched_cb != NULL) {
1067 bool stop_foreach = false;
1069 stop_foreach = !app_matched_cb(foreach_context->app_control, package, foreach_context->user_data);
1071 foreach_context->foreach_break = stop_foreach;
1077 int app_control_foreach_app_matched(app_control_h app_control, app_control_app_matched_cb callback, void *user_data)
1079 foreach_context_launchable_app_t foreach_context = {
1080 .app_control = app_control,
1081 .callback = callback,
1082 .user_data = user_data,
1083 .foreach_break = false
1086 if (app_control_validate(app_control) || callback == NULL)
1087 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1089 appsvc_usr_get_list(app_control->data, app_control_cb_broker_foreach_app_matched, &foreach_context, getuid());
1091 return APP_CONTROL_ERROR_NONE;
1094 int app_control_get_caller(app_control_h app_control, char **package)
1096 const char *bundle_value;
1099 if (app_control_validate(app_control) || package == NULL)
1100 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1102 if (app_control->type != APP_CONTROL_TYPE_EVENT)
1103 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid app_control handle type");
1105 bundle_value = bundle_get_val(app_control->data, AUL_K_CALLER_APPID);
1106 if (bundle_value == NULL)
1107 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to retrieve the appid of the caller");
1109 package_dup = strdup(bundle_value);
1110 if (package_dup == NULL)
1111 return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
1113 *package = package_dup;
1115 return APP_CONTROL_ERROR_NONE;
1118 int app_control_is_reply_requested(app_control_h app_control, bool *requested)
1120 const char *bundle_value;
1122 if (app_control_validate(app_control) || requested == NULL)
1123 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1125 if (app_control->type != APP_CONTROL_TYPE_EVENT)
1126 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid app_control handle type");
1128 bundle_value = bundle_get_val(app_control->data, AUL_K_WAIT_RESULT);
1129 if (bundle_value != NULL)
1134 return APP_CONTROL_ERROR_NONE;
1137 int app_control_import_from_bundle(app_control_h app_control, bundle *data)
1139 bundle *data_dup = NULL;
1141 if (app_control_validate(app_control) || data == NULL)
1142 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1144 data_dup = bundle_dup(data);
1145 if (data_dup == NULL)
1146 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to duplicate the bundle");
1148 if (app_control->data != NULL)
1149 bundle_free(app_control->data);
1151 app_control->data = data_dup;
1153 return APP_CONTROL_ERROR_NONE;
1156 int app_control_export_as_bundle(app_control_h app_control, bundle **data)
1158 bundle *data_dup = NULL;
1160 if (app_control_validate(app_control) || data == NULL)
1161 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1163 data_dup = bundle_dup(app_control->data);
1164 if (data_dup == NULL)
1165 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to duplicate the bundle");
1169 return APP_CONTROL_ERROR_NONE;
1172 int app_control_request_transient_app(app_control_h app_control, unsigned int callee_id, app_control_host_res_fn cbfunc, void *data)
1176 if (app_control_validate(app_control))
1177 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1179 ret = appsvc_request_transient_app(app_control->data, callee_id, (appsvc_host_res_fn)cbfunc, data);
1181 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1183 return APP_CONTROL_ERROR_NONE;
1186 int app_control_enable_app_started_result_event(app_control_h app_control)
1190 if (app_control_validate(app_control))
1191 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1193 ret = aul_svc_subscribe_launch_result(app_control->data, AUL_SVC_K_LAUNCH_RESULT_APP_STARTED);
1195 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1197 return APP_CONTROL_ERROR_NONE;