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>
29 #include <app_control.h>
30 #include <app_control_internal.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 static int app_control_create_reply(bundle *data, struct app_control_s **app_control);
78 static const char *app_control_error_to_string(app_control_error_e error)
81 case APP_CONTROL_ERROR_NONE:
83 case APP_CONTROL_ERROR_INVALID_PARAMETER:
84 return "INVALID_PARAMETER";
85 case APP_CONTROL_ERROR_OUT_OF_MEMORY:
86 return "OUT_OF_MEMORY";
87 case APP_CONTROL_ERROR_APP_NOT_FOUND:
88 return "APP_NOT_FOUND";
89 case APP_CONTROL_ERROR_KEY_NOT_FOUND:
90 return "KEY_NOT_FOUND";
91 case APP_CONTROL_ERROR_KEY_REJECTED:
92 return "KEY_REJECTED";
93 case APP_CONTROL_ERROR_INVALID_DATA_TYPE:
94 return "INVALID_DATA_TYPE";
95 case APP_CONTROL_ERROR_LAUNCH_REJECTED:
96 return "LAUNCH_REJECTED";
97 case APP_CONTROL_ERROR_PERMISSION_DENIED:
98 return "PERMISSION_DENIED";
99 case APP_CONTROL_ERROR_LAUNCH_FAILED:
100 return "LAUNCH_FAILED";
101 case APP_CONTROL_ERROR_TIMED_OUT:
103 case APP_CONTROL_ERROR_IO_ERROR:
110 int app_control_error(app_control_error_e error, const char *function, const char *description)
113 LOGE("[%s] %s(0x%08x) : %s", function, app_control_error_to_string(error), error, description);
115 if (error == APP_CONTROL_ERROR_KEY_NOT_FOUND)
116 LOGW("[%s] %s(0x%08x)", function, app_control_error_to_string(error), error);
118 LOGE("[%s] %s(0x%08x)", function, app_control_error_to_string(error), error);
124 static int app_control_validate_extra_data(const char *data)
126 if (data == NULL || data[0] == '\0')
127 return APP_CONTROL_ERROR_INVALID_PARAMETER;
129 return APP_CONTROL_ERROR_NONE;
132 static int app_control_validate(app_control_h app_control)
134 if (app_control == NULL || app_control->data == NULL)
135 return APP_CONTROL_ERROR_INVALID_PARAMETER;
137 return APP_CONTROL_ERROR_NONE;
140 static int app_control_new_id()
146 int app_control_validate_internal_key(const char *key)
148 if (strncmp(BUNDLE_KEY_PREFIX_AUL, key, strlen(BUNDLE_KEY_PREFIX_AUL)) == 0)
151 if (strncmp(BUNDLE_KEY_PREFIX_SERVICE, key, strlen(BUNDLE_KEY_PREFIX_SERVICE)) == 0)
157 /* LCOV_EXCL_START */
158 static void app_control_request_result_broker(bundle *appsvc_bundle, int appsvc_request_code, aul_svc_result_val appsvc_result, void *appsvc_data)
160 app_control_request_context_h request_context;
161 app_control_h request;
162 app_control_h reply = NULL;
163 app_control_result_e result;
165 app_control_reply_cb reply_cb;
167 if (appsvc_data == NULL) {
168 app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid app_control reply");
172 if (app_control_create_reply(appsvc_bundle, &reply) != 0) {
173 app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to create app_control reply");
177 request_context = appsvc_data;
178 request = request_context->app_control;
180 switch (appsvc_result) {
182 result = APP_CONTROL_RESULT_SUCCEEDED;
184 case AUL_SVC_RES_NOT_OK:
185 result = APP_CONTROL_RESULT_FAILED;
187 case AUL_SVC_RES_CANCEL:
188 result = APP_CONTROL_RESULT_CANCELED;
191 result = APP_CONTROL_RESULT_CANCELED;
195 user_data = request_context->user_data;
196 reply_cb = request_context->reply_cb;
198 if (reply_cb != NULL)
199 reply_cb(request, reply, result, user_data);
201 app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid callback ");
203 app_control_destroy(reply);
205 if (request_context->app_control != NULL)
206 app_control_destroy(request_context->app_control);
208 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 = aul_svc_get_operation(app_control_event->data);
266 if (operation == NULL)
267 aul_svc_set_operation(app_control_event->data, APP_CONTROL_OPERATION_DEFAULT);
269 *app_control = app_control_event;
271 return APP_CONTROL_ERROR_NONE;
274 /* LCOV_EXCL_START */
275 static int app_control_create_reply(bundle *data, struct app_control_s **app_control)
277 struct app_control_s *app_control_reply;
279 if (data == NULL || app_control == NULL)
280 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
282 app_control_reply = malloc(sizeof(struct app_control_s));
283 if (app_control_reply == NULL)
284 return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create a app_control handle");
286 app_control_reply->type = APP_CONTROL_TYPE_REPLY;
287 app_control_reply->data = bundle_dup(data);
288 app_control_reply->id = app_control_new_id();
290 *app_control = app_control_reply;
292 return APP_CONTROL_ERROR_NONE;
296 int app_control_destroy(app_control_h app_control)
298 if (app_control_validate(app_control))
299 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
301 if (app_control->type == APP_CONTROL_TYPE_REQUEST && app_control->launch_pid > 0
302 && bundle_get_val(app_control->data, AUL_SVC_K_LAUNCH_RESULT_APP_STARTED) == NULL)
303 aul_remove_caller_cb(app_control->launch_pid, app_control);
305 bundle_free(app_control->data);
306 app_control->data = NULL;
309 return APP_CONTROL_ERROR_NONE;
312 int app_control_to_bundle(app_control_h app_control, bundle **data)
314 if (app_control_validate(app_control) || data == NULL)
315 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
317 *data = app_control->data;
319 return APP_CONTROL_ERROR_NONE;
322 int app_control_set_operation(app_control_h app_control, const char *operation)
324 if (app_control_validate(app_control))
325 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
327 if (operation != NULL) {
328 if (aul_svc_set_operation(app_control->data, operation) != 0)
329 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid operation");
331 bundle_del(app_control->data, BUNDLE_KEY_OPERATION);
334 return APP_CONTROL_ERROR_NONE;
337 int app_control_get_operation(app_control_h app_control, char **operation)
339 const char *operation_value;
341 if (app_control_validate(app_control) || operation == NULL)
342 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
344 operation_value = aul_svc_get_operation(app_control->data);
345 if (operation_value != NULL)
346 *operation = strdup(operation_value);
350 return APP_CONTROL_ERROR_NONE;
353 int app_control_set_uri(app_control_h app_control, const char *uri)
355 if (app_control_validate(app_control))
356 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
359 if (aul_svc_set_uri(app_control->data, uri) != 0)
360 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid URI");
362 bundle_del(app_control->data, BUNDLE_KEY_URI);
365 return APP_CONTROL_ERROR_NONE;
368 int app_control_get_uri(app_control_h app_control, char **uri)
370 const char *uri_value;
372 if (app_control_validate(app_control) || uri == NULL)
373 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
375 uri_value = aul_svc_get_uri(app_control->data);
376 if (uri_value != NULL)
377 *uri = strdup(uri_value);
381 return APP_CONTROL_ERROR_NONE;
384 int app_control_set_mime(app_control_h app_control, const char *mime)
386 if (app_control_validate(app_control))
387 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
390 if (aul_svc_set_mime(app_control->data, mime) != 0)
391 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid MIME type");
393 bundle_del(app_control->data, BUNDLE_KEY_MIME);
396 return APP_CONTROL_ERROR_NONE;
399 int app_control_get_mime(app_control_h app_control, char **mime)
401 const char *mime_value;
403 if (app_control_validate(app_control) || mime == NULL)
404 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
406 mime_value = aul_svc_get_mime(app_control->data);
407 if (mime_value != NULL)
408 *mime = strdup(mime_value);
412 return APP_CONTROL_ERROR_NONE;
415 int app_control_set_category(app_control_h app_control, const char *category)
417 if (app_control_validate(app_control))
418 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
420 if (category != NULL) {
421 if (aul_svc_set_category(app_control->data, category) != 0)
422 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid Category");
424 bundle_del(app_control->data, BUNDLE_KEY_CATEGORY);
427 return APP_CONTROL_ERROR_NONE;
430 int app_control_get_category(app_control_h app_control, char **category)
432 const char *category_value;
434 if (app_control_validate(app_control) || category == NULL)
435 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
437 category_value = aul_svc_get_category(app_control->data);
438 if (category_value != NULL)
439 *category = strdup(category_value);
443 return APP_CONTROL_ERROR_NONE;
446 int app_control_set_package(app_control_h app_control, const char *package)
448 /* TODO: this function must be deprecated */
449 return app_control_set_app_id(app_control, package);
452 int app_control_get_package(app_control_h app_control, char **package)
454 /* TODO: this function must be deprecated */
455 return app_control_get_app_id(app_control, package);
458 int app_control_set_app_id(app_control_h app_control, const char *app_id)
460 if (app_control_validate(app_control))
461 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
463 if (app_id != NULL) {
464 if (aul_svc_set_appid(app_control->data, app_id) != 0)
465 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid application ID");
467 bundle_del(app_control->data, BUNDLE_KEY_PACKAGE);
470 return APP_CONTROL_ERROR_NONE;
473 int app_control_get_app_id(app_control_h app_control, char **app_id)
475 const char *app_id_value;
477 if (app_control_validate(app_control) || app_id == NULL)
478 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
480 app_id_value = aul_svc_get_appid(app_control->data);
481 if (app_id_value != NULL)
482 *app_id = strdup(app_id_value);
486 return APP_CONTROL_ERROR_NONE;
489 int app_control_set_window(app_control_h app_control, unsigned int id)
491 if (app_control_validate(app_control))
492 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
495 if (aul_svc_allow_transient_app(app_control->data, id) != 0)
496 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid id");
498 bundle_del(app_control->data, BUNDLE_KEY_WINDOW);
501 return APP_CONTROL_ERROR_NONE;
504 int app_control_get_window(app_control_h app_control, unsigned int *id)
506 const char *window_id;
508 if (app_control_validate(app_control) || id == NULL)
509 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
511 window_id = bundle_get_val(app_control->data, BUNDLE_KEY_WINDOW);
512 if (window_id != NULL)
513 *id = atoi(window_id);
517 return APP_CONTROL_ERROR_NONE;
520 int app_control_clone(app_control_h *clone, app_control_h app_control)
522 app_control_h app_control_clone;
524 if (app_control_validate(app_control) || clone == NULL)
525 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
527 app_control_clone = malloc(sizeof(struct app_control_s));
528 if (app_control_clone == NULL)
529 return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create a app_control handle");
531 app_control_clone->id = app_control_new_id();
532 app_control_clone->type = app_control->type;
533 app_control_clone->data = bundle_dup(app_control->data);
535 *clone = app_control_clone;
537 return APP_CONTROL_ERROR_NONE;
540 int app_control_set_launch_mode(app_control_h app_control,
541 app_control_launch_mode_e mode)
543 char launch_mode[LAUNCH_MODE_SIZE] = { 0, };
545 if (app_control_validate(app_control)) {
546 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER,
551 case APP_CONTROL_LAUNCH_MODE_SINGLE:
552 strncpy(launch_mode, LAUNCH_MODE_SINGLE, strlen(LAUNCH_MODE_SINGLE));
554 case APP_CONTROL_LAUNCH_MODE_GROUP:
555 strncpy(launch_mode, LAUNCH_MODE_GROUP, strlen(LAUNCH_MODE_GROUP));
558 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER,
559 __FUNCTION__, "invalid mode");
562 return aul_svc_set_launch_mode(app_control->data, launch_mode);
565 int app_control_get_launch_mode(app_control_h app_control,
566 app_control_launch_mode_e *mode)
568 const char *launch_mode;
570 if (app_control_validate(app_control)) {
571 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER,
575 launch_mode = aul_svc_get_launch_mode(app_control->data);
576 if (launch_mode == NULL) {
577 *mode = APP_CONTROL_LAUNCH_MODE_SINGLE;
579 if (!strcmp(launch_mode, LAUNCH_MODE_SINGLE)) {
580 *mode = APP_CONTROL_LAUNCH_MODE_SINGLE;
581 } else if (!strcmp(launch_mode, LAUNCH_MODE_GROUP)) {
582 *mode = APP_CONTROL_LAUNCH_MODE_GROUP;
584 *mode = APP_CONTROL_LAUNCH_MODE_SINGLE;
585 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER,
586 __FUNCTION__, "launch_mode is not matched");
590 return APP_CONTROL_ERROR_NONE;
593 int app_control_set_defapp(app_control_h app_control, const char *app_id)
597 if (app_control_validate(app_control) || app_id == NULL)
598 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
600 ret = aul_svc_set_appid(app_control->data, app_id);
602 return app_control_error(APP_CONTROL_ERROR_IO_ERROR, __FUNCTION__, NULL);
604 ret = aul_set_default_app_by_operation(app_control->data);
606 if (ret == AUL_R_EILLACC)
607 return app_control_error(APP_CONTROL_ERROR_PERMISSION_DENIED, __FUNCTION__, NULL);
609 return app_control_error(APP_CONTROL_ERROR_IO_ERROR, __FUNCTION__, NULL);
612 return APP_CONTROL_ERROR_NONE;
615 int app_control_unset_defapp(const char *app_id)
620 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
622 ret = aul_unset_default_app_by_operation(app_id);
624 if (ret == AUL_R_EILLACC)
625 return app_control_error(APP_CONTROL_ERROR_PERMISSION_DENIED, __FUNCTION__, NULL);
627 return app_control_error(APP_CONTROL_ERROR_IO_ERROR, __FUNCTION__, NULL);
630 return APP_CONTROL_ERROR_NONE;
633 /* LCOV_EXCL_START */
634 static void __update_launch_pid(int launched_pid, void *data)
636 app_control_h app_control;
643 app_control->launch_pid = launched_pid;
647 static void __handle_launch_result(int launched_pid, void *data)
649 app_control_request_context_h request_context;
650 app_control_h reply = NULL;
651 app_control_h request;
652 app_control_result_e result;
653 app_control_reply_cb reply_cb;
655 char callee[255] = {0, };
656 char instance_id[256] = {0,};
662 request_context = (app_control_request_context_h)data;
664 if (app_control_create_event(request_context->app_control->data, &reply) != 0) {
665 app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to create app_control event");
669 ret = aul_app_get_appid_bypid(launched_pid, callee, sizeof(callee));
671 LOGE("aul_app_get_appid_bypid failed: %d", launched_pid);
673 app_control_set_app_id(reply, callee);
674 LOGI("app control async result callback callee pid:%d", launched_pid);
676 ret = aul_app_get_instance_id_bypid(launched_pid, instance_id,
677 sizeof(instance_id));
678 if (ret == AUL_R_OK) {
679 app_control_set_instance_id(reply, instance_id);
680 LOGI("instance id(%s)", instance_id);
683 result = APP_CONTROL_RESULT_APP_STARTED;
684 request = request_context->app_control;
685 user_data = request_context->user_data;
686 reply_cb = request_context->reply_cb;
688 if (reply_cb != NULL)
689 reply_cb(request, reply, result, user_data);
691 app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid callback ");
693 app_control_destroy(reply);
696 int app_control_send_launch_request(app_control_h app_control, app_control_reply_cb callback, void *user_data)
698 const char *operation;
699 bool implicit_default_operation = false;
701 app_control_request_context_h request_context = NULL;
704 if (app_control_validate(app_control))
705 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
707 operation = aul_svc_get_operation(app_control->data);
708 if (operation == NULL) {
709 implicit_default_operation = true;
710 operation = APP_CONTROL_OPERATION_DEFAULT;
713 if (!strcmp(operation, APP_CONTROL_OPERATION_LAUNCH_ON_EVENT))
714 return app_control_error(APP_CONTROL_ERROR_LAUNCH_REJECTED, __FUNCTION__,
715 "Not supported operation value");
717 /* TODO: Check the privilege for call operation */
719 /* operation : default */
720 if (!strcmp(operation, APP_CONTROL_OPERATION_DEFAULT)) {
721 const char *appid = aul_svc_get_appid(app_control->data);
723 return app_control_error(APP_CONTROL_ERROR_APP_NOT_FOUND, __FUNCTION__, "package must be specified if the operation is default value");
726 if (callback != NULL) {
727 app_control_h request_clone = NULL;
729 request_context = calloc(1, sizeof(struct app_control_request_context_s));
730 if (request_context == NULL)
731 return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
733 request_context->reply_cb = callback;
735 ret = app_control_clone(&request_clone, app_control);
736 if (ret != APP_CONTROL_ERROR_NONE) {
737 free(request_context);
738 return app_control_error(ret, __FUNCTION__, "failed to clone the app_control request handle");
741 request_context->app_control = request_clone;
742 request_context->user_data = user_data;
745 if (implicit_default_operation == true)
746 aul_svc_set_operation(app_control->data, APP_CONTROL_OPERATION_DEFAULT);
748 launch_pid = aul_svc_run_service_for_uid(app_control->data, app_control->id, callback ? app_control_request_result_broker : NULL, request_context, getuid());
749 if (implicit_default_operation == true)
750 bundle_del(app_control->data, BUNDLE_KEY_OPERATION);
752 if (launch_pid < 0) {
753 if (request_context) {
754 if (request_context->app_control)
755 app_control_destroy(request_context->app_control);
757 free(request_context);
760 if (launch_pid == AUL_SVC_RET_ENOMATCH)
761 return app_control_error(APP_CONTROL_ERROR_APP_NOT_FOUND, __FUNCTION__, NULL);
762 else if (launch_pid == AUL_SVC_RET_EILLACC)
763 return app_control_error(APP_CONTROL_ERROR_PERMISSION_DENIED, __FUNCTION__, NULL);
764 else if (launch_pid == AUL_SVC_RET_EINVAL)
765 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
767 return app_control_error(APP_CONTROL_ERROR_LAUNCH_REJECTED, __FUNCTION__, NULL);
770 app_control->launch_pid = launch_pid;
771 /* app_control_enable_app_started_result_event called */
772 if (bundle_get_val(app_control->data, AUL_SVC_K_LAUNCH_RESULT_APP_STARTED)) {
773 char callee[255] = {0,};
774 if (aul_app_get_appid_bypid(launch_pid, callee, sizeof(callee)) != AUL_R_OK)
775 LOGE("aul_app_get_appid_bypid failed: %d", launch_pid);
777 if (request_context && request_context->app_control)
778 request_context->app_control->launch_pid = launch_pid;
780 aul_add_caller_cb(launch_pid, __handle_launch_result, request_context);
782 /* launched without app selector */
783 if ((strcmp(callee, APP_SELECTOR) != 0) &&
784 (strcmp(callee, SHARE_PANEL) != 0))
786 aul_invoke_caller_cb(request_context);
788 } else { /* default case */
789 aul_add_caller_cb(launch_pid, __update_launch_pid, app_control);
792 return APP_CONTROL_ERROR_NONE;
795 int app_control_send_terminate_request(app_control_h app_control)
797 if (app_control_validate(app_control))
798 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
800 if (app_control->type != APP_CONTROL_TYPE_REQUEST || app_control->launch_pid < 0)
801 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
803 aul_svc_subapp_terminate_request_pid(app_control->launch_pid);
805 return APP_CONTROL_ERROR_NONE;
808 /* LCOV_EXCL_START */
809 static bool app_control_copy_reply_data_cb(app_control_h app_control, const char *key, void *user_data)
811 bundle *reply_data = user_data;
813 char **value_array = NULL;
814 int value_array_length = 0;
815 int value_array_index = 0;
817 if (reply_data == NULL) {
818 app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
822 if (aul_svc_data_is_array(app_control->data, key)) {
823 app_control_get_extra_data_array(app_control, key, &value_array, &value_array_length);
824 aul_svc_add_data_array(reply_data, key, (const char **)value_array, value_array_length);
826 for (value_array_index = 0; value_array_index < value_array_length; value_array_index++)
827 free(value_array[value_array_index]);
831 app_control_get_extra_data(app_control, key, &value);
832 aul_svc_add_data(reply_data, key, value);
840 int app_control_reply_to_launch_request(app_control_h reply, app_control_h request, app_control_result_e result)
846 if (app_control_validate(reply) || app_control_validate(request))
847 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
849 if (result == APP_CONTROL_RESULT_APP_STARTED)
850 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "APP_CONTROL_RESULT_APP_STARTED is not allowed to use");
852 if (aul_svc_create_result_bundle(request->data, &reply_data) != 0)
853 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to create a result bundle");
855 app_control_foreach_extra_data(reply, app_control_copy_reply_data_cb, reply_data);
858 case APP_CONTROL_RESULT_SUCCEEDED:
859 appsvc_result = AUL_SVC_RES_OK;
861 case APP_CONTROL_RESULT_FAILED:
862 appsvc_result = AUL_SVC_RES_NOT_OK;
864 case APP_CONTROL_RESULT_CANCELED:
865 appsvc_result = AUL_SVC_RES_CANCEL;
868 appsvc_result = AUL_SVC_RES_CANCEL;
872 ret = aul_svc_send_result(reply_data, appsvc_result);
873 bundle_free(reply_data);
875 if (ret == AUL_SVC_RET_EINVAL)
876 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
878 return app_control_error(APP_CONTROL_ERROR_LAUNCH_REJECTED, __FUNCTION__, NULL);
881 return APP_CONTROL_ERROR_NONE;
885 int app_control_add_extra_data(app_control_h app_control, const char *key, const char *value)
887 if (app_control_validate(app_control) || app_control_validate_extra_data(key) || app_control_validate_extra_data(value))
888 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
890 if (app_control_validate_internal_key(key))
891 return app_control_error(APP_CONTROL_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use");
893 if (aul_svc_get_data(app_control->data, key) != NULL) {
894 /* overwrite any existing value */
895 bundle_del(app_control->data, key);
898 if (aul_svc_add_data(app_control->data, key, value) != 0)
899 return app_control_error(APP_CONTROL_ERROR_KEY_REJECTED, __FUNCTION__, "failed to add data to the appsvc handle");
901 return APP_CONTROL_ERROR_NONE;
905 int app_control_add_extra_data_array(app_control_h app_control, const char *key, const char* value[], int length)
907 if (app_control_validate(app_control) || app_control_validate_extra_data(key))
908 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
910 if (value == NULL || length <= 0)
911 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid array");
913 if (app_control_validate_internal_key(key))
914 return app_control_error(APP_CONTROL_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use");
916 if (aul_svc_get_data_array(app_control->data, key, NULL) != NULL) {
917 /* overwrite any existing value */
918 bundle_del(app_control->data, key);
921 if (aul_svc_add_data_array(app_control->data, key, value, length) != 0)
922 return app_control_error(APP_CONTROL_ERROR_KEY_REJECTED, __FUNCTION__, "failed to add array data to the appsvc handle");
924 return APP_CONTROL_ERROR_NONE;
927 int app_control_remove_extra_data(app_control_h app_control, const char *key)
929 if (app_control_validate(app_control) || app_control_validate_extra_data(key))
930 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
932 if (app_control_validate_internal_key(key))
933 return app_control_error(APP_CONTROL_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use");
935 if (bundle_del(app_control->data, key))
936 return app_control_error(APP_CONTROL_ERROR_KEY_NOT_FOUND, __FUNCTION__, NULL);
938 return APP_CONTROL_ERROR_NONE;
941 int app_control_get_extra_data(app_control_h app_control, const char *key, char **value)
943 const char *data_value;
945 if (app_control_validate(app_control) || app_control_validate_extra_data(key) || value == NULL)
946 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
948 if (app_control_validate_internal_key(key))
949 return app_control_error(APP_CONTROL_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use");
951 data_value = aul_svc_get_data(app_control->data, key);
952 if (data_value == NULL) {
953 if (errno == ENOTSUP)
954 return app_control_error(APP_CONTROL_ERROR_INVALID_DATA_TYPE, __FUNCTION__, NULL);
956 return app_control_error(APP_CONTROL_ERROR_KEY_NOT_FOUND, __FUNCTION__, NULL);
959 *value = strdup(data_value);
961 return APP_CONTROL_ERROR_NONE;
964 int app_control_get_extra_data_array(app_control_h app_control, const char *key, char ***value, int *length)
966 const char **array_data;
967 int array_data_length;
968 char **array_data_clone;
971 if (app_control_validate(app_control) || app_control_validate_extra_data(key))
972 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
974 if (value == NULL || length == 0)
975 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
977 if (app_control_validate_internal_key(key))
978 return app_control_error(APP_CONTROL_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use");
980 array_data = aul_svc_get_data_array(app_control->data, key, &array_data_length);
981 if (array_data == NULL) {
982 if (errno == ENOTSUP)
983 return app_control_error(APP_CONTROL_ERROR_INVALID_DATA_TYPE, __FUNCTION__, NULL);
985 return app_control_error(APP_CONTROL_ERROR_KEY_NOT_FOUND, __FUNCTION__, NULL);
988 array_data_clone = calloc(array_data_length, sizeof(char *));
989 if (array_data_clone == NULL)
990 return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
992 for (i = 0; i < array_data_length; i++) {
993 if (array_data[i] != NULL)
994 array_data_clone[i] = strdup(array_data[i]);
997 *value = array_data_clone;
998 *length = array_data_length;
1000 return APP_CONTROL_ERROR_NONE;
1003 int app_control_is_extra_data_array(app_control_h app_control, const char *key, bool *array)
1005 if (app_control_validate(app_control) || app_control_validate_extra_data(key) || array == NULL)
1006 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1008 if (app_control_validate_internal_key(key))
1009 return app_control_error(APP_CONTROL_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use");
1011 if (!aul_svc_data_is_array(app_control->data, key))
1016 return APP_CONTROL_ERROR_NONE;
1020 app_control_h app_control;
1021 app_control_extra_data_cb callback;
1024 } foreach_context_extra_data_t;
1026 static void app_control_cb_broker_bundle_iterator(const char *key, const int type, const bundle_keyval_t *kv, void *user_data)
1028 foreach_context_extra_data_t *foreach_context = NULL;
1029 app_control_extra_data_cb extra_data_cb;
1031 if (key == NULL || !(type == BUNDLE_TYPE_STR || type == BUNDLE_TYPE_STR_ARRAY))
1034 foreach_context = (foreach_context_extra_data_t *)user_data;
1035 if (foreach_context->foreach_break == true)
1038 if (app_control_validate_internal_key(key))
1041 extra_data_cb = foreach_context->callback;
1043 if (extra_data_cb != NULL) {
1044 bool stop_foreach = false;
1046 stop_foreach = !extra_data_cb(foreach_context->app_control, key, foreach_context->user_data);
1048 foreach_context->foreach_break = stop_foreach;
1052 int app_control_foreach_extra_data(app_control_h app_control, app_control_extra_data_cb callback, void *user_data)
1054 foreach_context_extra_data_t foreach_context = {
1055 .app_control = app_control,
1056 .callback = callback,
1057 .user_data = user_data,
1058 .foreach_break = false
1061 if (app_control_validate(app_control) || callback == NULL)
1062 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1064 bundle_foreach(app_control->data, app_control_cb_broker_bundle_iterator, &foreach_context);
1066 return APP_CONTROL_ERROR_NONE;
1070 app_control_h app_control;
1071 app_control_app_matched_cb callback;
1074 } foreach_context_launchable_app_t;
1076 /* LCOV_EXCL_START */
1077 int app_control_cb_broker_foreach_app_matched(const char *package, void *data)
1079 foreach_context_launchable_app_t *foreach_context;
1080 app_control_app_matched_cb app_matched_cb;
1082 if (package == NULL || data == NULL) {
1083 app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1087 foreach_context = (foreach_context_launchable_app_t *)data;
1088 if (foreach_context->foreach_break == true)
1091 app_matched_cb = foreach_context->callback;
1092 if (app_matched_cb != NULL) {
1093 bool stop_foreach = false;
1095 stop_foreach = !app_matched_cb(foreach_context->app_control, package, foreach_context->user_data);
1097 foreach_context->foreach_break = stop_foreach;
1102 /* LCOV_EXCL_STOP */
1104 int app_control_foreach_app_matched(app_control_h app_control, app_control_app_matched_cb callback, void *user_data)
1106 foreach_context_launchable_app_t foreach_context = {
1107 .app_control = app_control,
1108 .callback = callback,
1109 .user_data = user_data,
1110 .foreach_break = false
1113 if (app_control_validate(app_control) || callback == NULL)
1114 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1116 aul_svc_get_list_for_uid(app_control->data, app_control_cb_broker_foreach_app_matched, &foreach_context, getuid());
1118 return APP_CONTROL_ERROR_NONE;
1121 int app_control_get_caller(app_control_h app_control, char **package)
1123 const char *bundle_value;
1126 if (app_control_validate(app_control) || package == NULL)
1127 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1129 if (app_control->type != APP_CONTROL_TYPE_EVENT)
1130 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid app_control handle type");
1132 bundle_value = bundle_get_val(app_control->data, AUL_K_CALLER_APPID);
1133 if (bundle_value == NULL)
1134 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to retrieve the appid of the caller");
1136 package_dup = strdup(bundle_value);
1137 if (package_dup == NULL)
1138 return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
1140 *package = package_dup;
1142 return APP_CONTROL_ERROR_NONE;
1145 int app_control_is_reply_requested(app_control_h app_control, bool *requested)
1147 const char *bundle_value;
1149 if (app_control_validate(app_control) || requested == NULL)
1150 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1152 if (app_control->type != APP_CONTROL_TYPE_EVENT)
1153 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid app_control handle type");
1155 bundle_value = bundle_get_val(app_control->data, AUL_K_WAIT_RESULT);
1156 if (bundle_value != NULL)
1161 return APP_CONTROL_ERROR_NONE;
1164 int app_control_import_from_bundle(app_control_h app_control, bundle *data)
1166 bundle *data_dup = NULL;
1168 if (app_control_validate(app_control) || data == NULL)
1169 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1171 data_dup = bundle_dup(data);
1172 if (data_dup == NULL)
1173 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to duplicate the bundle");
1175 if (app_control->data != NULL)
1176 bundle_free(app_control->data);
1178 app_control->data = data_dup;
1180 return APP_CONTROL_ERROR_NONE;
1183 int app_control_export_as_bundle(app_control_h app_control, bundle **data)
1185 bundle *data_dup = NULL;
1187 if (app_control_validate(app_control) || data == NULL)
1188 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1190 data_dup = bundle_dup(app_control->data);
1191 if (data_dup == NULL)
1192 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to duplicate the bundle");
1196 return APP_CONTROL_ERROR_NONE;
1199 int app_control_request_transient_app(app_control_h app_control, unsigned int callee_id, app_control_host_res_fn cbfunc, void *data)
1203 if (app_control_validate(app_control))
1204 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1206 ret = aul_svc_request_transient_app(app_control->data, callee_id, (aul_svc_host_res_fn)cbfunc, data);
1208 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1210 return APP_CONTROL_ERROR_NONE;
1213 int app_control_enable_app_started_result_event(app_control_h app_control)
1217 if (app_control_validate(app_control))
1218 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1220 ret = aul_svc_subscribe_launch_result(app_control->data, AUL_SVC_K_LAUNCH_RESULT_APP_STARTED);
1222 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1224 return APP_CONTROL_ERROR_NONE;
1227 int app_control_set_instance_id(app_control_h app_control, const char *instance_id)
1231 if (app_control_validate(app_control) || instance_id == NULL)
1232 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1234 ret = aul_svc_set_instance_id(app_control->data, instance_id);
1236 return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, "Out of memory");
1238 return APP_CONTROL_ERROR_NONE;
1241 int app_control_get_instance_id(app_control_h app_control, char **instance_id)
1245 if (app_control_validate(app_control) || instance_id == NULL)
1246 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1248 id = aul_svc_get_instance_id(app_control->data);
1250 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "Failed to get the instance id");
1252 *instance_id = strdup(id);
1253 if (*instance_id == NULL)
1254 return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, "Failed to duplicate the instance id");
1256 return APP_CONTROL_ERROR_NONE;