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 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
348 *operation = strdup(operation_value);
349 if (*operation == NULL)
350 return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
352 return APP_CONTROL_ERROR_NONE;
355 int app_control_set_uri(app_control_h app_control, const char *uri)
357 if (app_control_validate(app_control))
358 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
361 if (aul_svc_set_uri(app_control->data, uri) != 0)
362 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid URI");
364 bundle_del(app_control->data, BUNDLE_KEY_URI);
367 return APP_CONTROL_ERROR_NONE;
370 int app_control_get_uri(app_control_h app_control, char **uri)
372 const char *uri_value;
374 if (app_control_validate(app_control) || uri == NULL)
375 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
377 uri_value = aul_svc_get_uri(app_control->data);
378 if (uri_value == NULL)
379 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
381 *uri = strdup(uri_value);
383 return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
385 return APP_CONTROL_ERROR_NONE;
388 int app_control_set_mime(app_control_h app_control, const char *mime)
390 if (app_control_validate(app_control))
391 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
394 if (aul_svc_set_mime(app_control->data, mime) != 0)
395 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid MIME type");
397 bundle_del(app_control->data, BUNDLE_KEY_MIME);
400 return APP_CONTROL_ERROR_NONE;
403 int app_control_get_mime(app_control_h app_control, char **mime)
405 const char *mime_value;
407 if (app_control_validate(app_control) || mime == NULL)
408 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
410 mime_value = aul_svc_get_mime(app_control->data);
411 if (mime_value == NULL)
412 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
414 *mime = strdup(mime_value);
416 return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
418 return APP_CONTROL_ERROR_NONE;
421 int app_control_set_category(app_control_h app_control, const char *category)
423 if (app_control_validate(app_control))
424 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
426 if (category != NULL) {
427 if (aul_svc_set_category(app_control->data, category) != 0)
428 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid Category");
430 bundle_del(app_control->data, BUNDLE_KEY_CATEGORY);
433 return APP_CONTROL_ERROR_NONE;
436 int app_control_get_category(app_control_h app_control, char **category)
438 const char *category_value;
440 if (app_control_validate(app_control) || category == NULL)
441 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
443 category_value = aul_svc_get_category(app_control->data);
444 if (category_value == NULL)
445 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
447 *category = strdup(category_value);
448 if (*category == NULL)
449 return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
451 return APP_CONTROL_ERROR_NONE;
454 int app_control_set_package(app_control_h app_control, const char *package)
456 /* TODO: this function must be deprecated */
457 return app_control_set_app_id(app_control, package);
460 int app_control_get_package(app_control_h app_control, char **package)
462 /* TODO: this function must be deprecated */
463 return app_control_get_app_id(app_control, package);
466 int app_control_set_app_id(app_control_h app_control, const char *app_id)
468 if (app_control_validate(app_control))
469 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
471 if (app_id != NULL) {
472 if (aul_svc_set_appid(app_control->data, app_id) != 0)
473 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid application ID");
475 bundle_del(app_control->data, BUNDLE_KEY_PACKAGE);
478 return APP_CONTROL_ERROR_NONE;
481 int app_control_get_app_id(app_control_h app_control, char **app_id)
483 const char *app_id_value;
485 if (app_control_validate(app_control) || app_id == NULL)
486 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
488 app_id_value = aul_svc_get_appid(app_control->data);
489 if (app_id_value == NULL)
490 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
492 *app_id = strdup(app_id_value);
494 return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
496 return APP_CONTROL_ERROR_NONE;
499 int app_control_set_window(app_control_h app_control, unsigned int id)
501 if (app_control_validate(app_control))
502 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
505 if (aul_svc_allow_transient_app(app_control->data, id) != 0)
506 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid id");
508 bundle_del(app_control->data, BUNDLE_KEY_WINDOW);
511 return APP_CONTROL_ERROR_NONE;
514 int app_control_get_window(app_control_h app_control, unsigned int *id)
516 const char *window_id;
518 if (app_control_validate(app_control) || id == NULL)
519 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
521 window_id = bundle_get_val(app_control->data, BUNDLE_KEY_WINDOW);
522 if (window_id != NULL)
523 *id = atoi(window_id);
527 return APP_CONTROL_ERROR_NONE;
530 int app_control_clone(app_control_h *clone, app_control_h app_control)
532 app_control_h app_control_clone;
534 if (app_control_validate(app_control) || clone == NULL)
535 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
537 app_control_clone = malloc(sizeof(struct app_control_s));
538 if (app_control_clone == NULL)
539 return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create a app_control handle");
541 app_control_clone->id = app_control_new_id();
542 app_control_clone->type = app_control->type;
543 app_control_clone->data = bundle_dup(app_control->data);
545 *clone = app_control_clone;
547 return APP_CONTROL_ERROR_NONE;
550 int app_control_set_launch_mode(app_control_h app_control,
551 app_control_launch_mode_e mode)
553 char launch_mode[LAUNCH_MODE_SIZE] = { 0, };
555 if (app_control_validate(app_control)) {
556 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER,
561 case APP_CONTROL_LAUNCH_MODE_SINGLE:
562 strncpy(launch_mode, LAUNCH_MODE_SINGLE, strlen(LAUNCH_MODE_SINGLE));
564 case APP_CONTROL_LAUNCH_MODE_GROUP:
565 strncpy(launch_mode, LAUNCH_MODE_GROUP, strlen(LAUNCH_MODE_GROUP));
568 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER,
569 __FUNCTION__, "invalid mode");
572 return aul_svc_set_launch_mode(app_control->data, launch_mode);
575 int app_control_get_launch_mode(app_control_h app_control,
576 app_control_launch_mode_e *mode)
578 const char *launch_mode;
580 if (app_control_validate(app_control)) {
581 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER,
585 launch_mode = aul_svc_get_launch_mode(app_control->data);
586 if (launch_mode == NULL) {
587 *mode = APP_CONTROL_LAUNCH_MODE_SINGLE;
589 if (!strcmp(launch_mode, LAUNCH_MODE_SINGLE)) {
590 *mode = APP_CONTROL_LAUNCH_MODE_SINGLE;
591 } else if (!strcmp(launch_mode, LAUNCH_MODE_GROUP)) {
592 *mode = APP_CONTROL_LAUNCH_MODE_GROUP;
594 *mode = APP_CONTROL_LAUNCH_MODE_SINGLE;
595 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER,
596 __FUNCTION__, "launch_mode is not matched");
600 return APP_CONTROL_ERROR_NONE;
603 int app_control_set_defapp(app_control_h app_control, const char *app_id)
607 if (app_control_validate(app_control) || app_id == NULL)
608 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
610 ret = aul_svc_set_appid(app_control->data, app_id);
612 return app_control_error(APP_CONTROL_ERROR_IO_ERROR, __FUNCTION__, NULL);
614 ret = aul_set_default_app_by_operation(app_control->data);
616 if (ret == AUL_R_EILLACC)
617 return app_control_error(APP_CONTROL_ERROR_PERMISSION_DENIED, __FUNCTION__, NULL);
619 return app_control_error(APP_CONTROL_ERROR_IO_ERROR, __FUNCTION__, NULL);
622 return APP_CONTROL_ERROR_NONE;
625 int app_control_unset_defapp(const char *app_id)
630 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
632 ret = aul_unset_default_app_by_operation(app_id);
634 if (ret == AUL_R_EILLACC)
635 return app_control_error(APP_CONTROL_ERROR_PERMISSION_DENIED, __FUNCTION__, NULL);
637 return app_control_error(APP_CONTROL_ERROR_IO_ERROR, __FUNCTION__, NULL);
640 return APP_CONTROL_ERROR_NONE;
643 /* LCOV_EXCL_START */
644 static void __update_launch_pid(int launched_pid, void *data)
646 app_control_h app_control;
653 app_control->launch_pid = launched_pid;
657 static void __handle_launch_result(int launched_pid, void *data)
659 app_control_request_context_h request_context;
660 app_control_h reply = NULL;
661 app_control_h request;
662 app_control_result_e result;
663 app_control_reply_cb reply_cb;
665 char callee[255] = {0, };
666 char instance_id[256] = {0,};
672 request_context = (app_control_request_context_h)data;
674 if (app_control_create_event(request_context->app_control->data, &reply) != 0) {
675 app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to create app_control event");
679 ret = aul_app_get_appid_bypid(launched_pid, callee, sizeof(callee));
681 LOGE("aul_app_get_appid_bypid failed: %d", launched_pid);
683 app_control_set_app_id(reply, callee);
684 LOGI("app control async result callback callee pid:%d", launched_pid);
686 ret = aul_app_get_instance_id_bypid(launched_pid, instance_id,
687 sizeof(instance_id));
688 if (ret == AUL_R_OK) {
689 app_control_set_instance_id(reply, instance_id);
690 LOGI("instance id(%s)", instance_id);
693 result = APP_CONTROL_RESULT_APP_STARTED;
694 request = request_context->app_control;
695 user_data = request_context->user_data;
696 reply_cb = request_context->reply_cb;
698 if (reply_cb != NULL)
699 reply_cb(request, reply, result, user_data);
701 app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid callback ");
703 app_control_destroy(reply);
706 int app_control_send_launch_request(app_control_h app_control, app_control_reply_cb callback, void *user_data)
708 const char *operation;
709 bool implicit_default_operation = false;
711 app_control_request_context_h request_context = NULL;
714 if (app_control_validate(app_control))
715 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
717 operation = aul_svc_get_operation(app_control->data);
718 if (operation == NULL) {
719 implicit_default_operation = true;
720 operation = APP_CONTROL_OPERATION_DEFAULT;
723 if (!strcmp(operation, APP_CONTROL_OPERATION_LAUNCH_ON_EVENT))
724 return app_control_error(APP_CONTROL_ERROR_LAUNCH_REJECTED, __FUNCTION__,
725 "Not supported operation value");
727 /* TODO: Check the privilege for call operation */
729 /* operation : default */
730 if (!strcmp(operation, APP_CONTROL_OPERATION_DEFAULT)) {
731 const char *appid = aul_svc_get_appid(app_control->data);
733 return app_control_error(APP_CONTROL_ERROR_APP_NOT_FOUND, __FUNCTION__, "package must be specified if the operation is default value");
736 if (callback != NULL) {
737 app_control_h request_clone = NULL;
739 request_context = calloc(1, sizeof(struct app_control_request_context_s));
740 if (request_context == NULL)
741 return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
743 request_context->reply_cb = callback;
745 ret = app_control_clone(&request_clone, app_control);
746 if (ret != APP_CONTROL_ERROR_NONE) {
747 free(request_context);
748 return app_control_error(ret, __FUNCTION__, "failed to clone the app_control request handle");
751 request_context->app_control = request_clone;
752 request_context->user_data = user_data;
755 if (implicit_default_operation == true)
756 aul_svc_set_operation(app_control->data, APP_CONTROL_OPERATION_DEFAULT);
758 launch_pid = aul_svc_run_service_for_uid(app_control->data, app_control->id, callback ? app_control_request_result_broker : NULL, request_context, getuid());
759 if (implicit_default_operation == true)
760 bundle_del(app_control->data, BUNDLE_KEY_OPERATION);
762 if (launch_pid < 0) {
763 if (request_context) {
764 if (request_context->app_control)
765 app_control_destroy(request_context->app_control);
767 free(request_context);
770 if (launch_pid == AUL_SVC_RET_ENOMATCH)
771 return app_control_error(APP_CONTROL_ERROR_APP_NOT_FOUND, __FUNCTION__, NULL);
772 else if (launch_pid == AUL_SVC_RET_EILLACC)
773 return app_control_error(APP_CONTROL_ERROR_PERMISSION_DENIED, __FUNCTION__, NULL);
774 else if (launch_pid == AUL_SVC_RET_EINVAL)
775 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
777 return app_control_error(APP_CONTROL_ERROR_LAUNCH_REJECTED, __FUNCTION__, NULL);
780 app_control->launch_pid = launch_pid;
781 /* app_control_enable_app_started_result_event called */
782 if (bundle_get_val(app_control->data, AUL_SVC_K_LAUNCH_RESULT_APP_STARTED)) {
783 char callee[255] = {0,};
784 if (aul_app_get_appid_bypid(launch_pid, callee, sizeof(callee)) != AUL_R_OK)
785 LOGE("aul_app_get_appid_bypid failed: %d", launch_pid);
787 if (request_context && request_context->app_control)
788 request_context->app_control->launch_pid = launch_pid;
790 aul_add_caller_cb(launch_pid, __handle_launch_result, request_context);
792 /* launched without app selector */
793 if ((strcmp(callee, APP_SELECTOR) != 0) &&
794 (strcmp(callee, SHARE_PANEL) != 0))
796 aul_invoke_caller_cb(request_context);
798 } else { /* default case */
799 aul_add_caller_cb(launch_pid, __update_launch_pid, app_control);
802 return APP_CONTROL_ERROR_NONE;
805 int app_control_send_terminate_request(app_control_h app_control)
807 if (app_control_validate(app_control))
808 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
810 if (app_control->type != APP_CONTROL_TYPE_REQUEST || app_control->launch_pid < 0)
811 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
813 aul_svc_subapp_terminate_request_pid(app_control->launch_pid);
815 return APP_CONTROL_ERROR_NONE;
818 /* LCOV_EXCL_START */
819 static bool app_control_copy_reply_data_cb(app_control_h app_control, const char *key, void *user_data)
821 bundle *reply_data = user_data;
823 char **value_array = NULL;
824 int value_array_length = 0;
825 int value_array_index = 0;
827 if (reply_data == NULL) {
828 app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
832 if (aul_svc_data_is_array(app_control->data, key)) {
833 app_control_get_extra_data_array(app_control, key, &value_array, &value_array_length);
834 aul_svc_add_data_array(reply_data, key, (const char **)value_array, value_array_length);
836 for (value_array_index = 0; value_array_index < value_array_length; value_array_index++)
837 free(value_array[value_array_index]);
841 app_control_get_extra_data(app_control, key, &value);
842 aul_svc_add_data(reply_data, key, value);
850 int app_control_reply_to_launch_request(app_control_h reply, app_control_h request, app_control_result_e result)
856 if (app_control_validate(reply) || app_control_validate(request))
857 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
859 if (result == APP_CONTROL_RESULT_APP_STARTED)
860 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "APP_CONTROL_RESULT_APP_STARTED is not allowed to use");
862 if (aul_svc_create_result_bundle(request->data, &reply_data) != 0)
863 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to create a result bundle");
865 app_control_foreach_extra_data(reply, app_control_copy_reply_data_cb, reply_data);
868 case APP_CONTROL_RESULT_SUCCEEDED:
869 appsvc_result = AUL_SVC_RES_OK;
871 case APP_CONTROL_RESULT_FAILED:
872 appsvc_result = AUL_SVC_RES_NOT_OK;
874 case APP_CONTROL_RESULT_CANCELED:
875 appsvc_result = AUL_SVC_RES_CANCEL;
878 appsvc_result = AUL_SVC_RES_CANCEL;
882 ret = aul_svc_send_result(reply_data, appsvc_result);
883 bundle_free(reply_data);
885 if (ret == AUL_SVC_RET_EINVAL)
886 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
888 return app_control_error(APP_CONTROL_ERROR_LAUNCH_REJECTED, __FUNCTION__, NULL);
891 return APP_CONTROL_ERROR_NONE;
895 int app_control_add_extra_data(app_control_h app_control, const char *key, const char *value)
897 if (app_control_validate(app_control) || app_control_validate_extra_data(key) || app_control_validate_extra_data(value))
898 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
900 if (app_control_validate_internal_key(key))
901 return app_control_error(APP_CONTROL_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use");
903 if (aul_svc_get_data(app_control->data, key) != NULL) {
904 /* overwrite any existing value */
905 bundle_del(app_control->data, key);
908 if (aul_svc_add_data(app_control->data, key, value) != 0)
909 return app_control_error(APP_CONTROL_ERROR_KEY_REJECTED, __FUNCTION__, "failed to add data to the appsvc handle");
911 return APP_CONTROL_ERROR_NONE;
915 int app_control_add_extra_data_array(app_control_h app_control, const char *key, const char* value[], int length)
917 if (app_control_validate(app_control) || app_control_validate_extra_data(key))
918 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
920 if (value == NULL || length <= 0)
921 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid array");
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 if (aul_svc_get_data_array(app_control->data, key, NULL) != NULL) {
927 /* overwrite any existing value */
928 bundle_del(app_control->data, key);
931 if (aul_svc_add_data_array(app_control->data, key, value, length) != 0)
932 return app_control_error(APP_CONTROL_ERROR_KEY_REJECTED, __FUNCTION__, "failed to add array data to the appsvc handle");
934 return APP_CONTROL_ERROR_NONE;
937 int app_control_remove_extra_data(app_control_h app_control, const char *key)
939 if (app_control_validate(app_control) || app_control_validate_extra_data(key))
940 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
942 if (app_control_validate_internal_key(key))
943 return app_control_error(APP_CONTROL_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use");
945 if (bundle_del(app_control->data, key))
946 return app_control_error(APP_CONTROL_ERROR_KEY_NOT_FOUND, __FUNCTION__, NULL);
948 return APP_CONTROL_ERROR_NONE;
951 int app_control_get_extra_data(app_control_h app_control, const char *key, char **value)
953 const char *data_value;
955 if (app_control_validate(app_control) || app_control_validate_extra_data(key) || value == NULL)
956 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
958 if (app_control_validate_internal_key(key))
959 return app_control_error(APP_CONTROL_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use");
961 data_value = aul_svc_get_data(app_control->data, key);
962 if (data_value == NULL) {
963 if (errno == ENOTSUP)
964 return app_control_error(APP_CONTROL_ERROR_INVALID_DATA_TYPE, __FUNCTION__, NULL);
966 return app_control_error(APP_CONTROL_ERROR_KEY_NOT_FOUND, __FUNCTION__, NULL);
969 *value = strdup(data_value);
971 return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
973 return APP_CONTROL_ERROR_NONE;
976 int app_control_get_extra_data_array(app_control_h app_control, const char *key, char ***value, int *length)
978 const char **array_data;
979 int array_data_length;
980 char **array_data_clone;
983 if (app_control_validate(app_control) || app_control_validate_extra_data(key))
984 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
986 if (value == NULL || length == 0)
987 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
989 if (app_control_validate_internal_key(key))
990 return app_control_error(APP_CONTROL_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use");
992 array_data = aul_svc_get_data_array(app_control->data, key, &array_data_length);
993 if (array_data == NULL) {
994 if (errno == ENOTSUP)
995 return app_control_error(APP_CONTROL_ERROR_INVALID_DATA_TYPE, __FUNCTION__, NULL);
997 return app_control_error(APP_CONTROL_ERROR_KEY_NOT_FOUND, __FUNCTION__, NULL);
1000 array_data_clone = calloc(array_data_length, sizeof(char *));
1001 if (array_data_clone == NULL)
1002 return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
1004 for (i = 0; i < array_data_length; i++) {
1005 if (array_data[i] != NULL) {
1006 array_data_clone[i] = strdup(array_data[i]);
1007 if (array_data_clone[i] == NULL)
1012 *value = array_data_clone;
1013 *length = array_data_length;
1015 return APP_CONTROL_ERROR_NONE;
1018 for (i = 0; i < array_data_length; i++) {
1019 if (array_data_clone[i])
1020 free(array_data_clone[i]);
1022 free(array_data_clone);
1024 return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
1027 int app_control_is_extra_data_array(app_control_h app_control, const char *key, bool *array)
1029 if (app_control_validate(app_control) || app_control_validate_extra_data(key) || array == NULL)
1030 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1032 if (app_control_validate_internal_key(key))
1033 return app_control_error(APP_CONTROL_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use");
1035 if (!aul_svc_data_is_array(app_control->data, key))
1040 return APP_CONTROL_ERROR_NONE;
1044 app_control_h app_control;
1045 app_control_extra_data_cb callback;
1048 } foreach_context_extra_data_t;
1050 static void app_control_cb_broker_bundle_iterator(const char *key, const int type, const bundle_keyval_t *kv, void *user_data)
1052 foreach_context_extra_data_t *foreach_context = NULL;
1053 app_control_extra_data_cb extra_data_cb;
1055 if (key == NULL || !(type == BUNDLE_TYPE_STR || type == BUNDLE_TYPE_STR_ARRAY))
1058 foreach_context = (foreach_context_extra_data_t *)user_data;
1059 if (foreach_context->foreach_break == true)
1062 if (app_control_validate_internal_key(key))
1065 extra_data_cb = foreach_context->callback;
1067 if (extra_data_cb != NULL) {
1068 bool stop_foreach = false;
1070 stop_foreach = !extra_data_cb(foreach_context->app_control, key, foreach_context->user_data);
1072 foreach_context->foreach_break = stop_foreach;
1076 int app_control_foreach_extra_data(app_control_h app_control, app_control_extra_data_cb callback, void *user_data)
1078 foreach_context_extra_data_t foreach_context = {
1079 .app_control = app_control,
1080 .callback = callback,
1081 .user_data = user_data,
1082 .foreach_break = false
1085 if (app_control_validate(app_control) || callback == NULL)
1086 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1088 bundle_foreach(app_control->data, app_control_cb_broker_bundle_iterator, &foreach_context);
1090 return APP_CONTROL_ERROR_NONE;
1094 app_control_h app_control;
1095 app_control_app_matched_cb callback;
1098 } foreach_context_launchable_app_t;
1100 /* LCOV_EXCL_START */
1101 int app_control_cb_broker_foreach_app_matched(const char *package, void *data)
1103 foreach_context_launchable_app_t *foreach_context;
1104 app_control_app_matched_cb app_matched_cb;
1106 if (package == NULL || data == NULL) {
1107 app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1111 foreach_context = (foreach_context_launchable_app_t *)data;
1112 if (foreach_context->foreach_break == true)
1115 app_matched_cb = foreach_context->callback;
1116 if (app_matched_cb != NULL) {
1117 bool stop_foreach = false;
1119 stop_foreach = !app_matched_cb(foreach_context->app_control, package, foreach_context->user_data);
1121 foreach_context->foreach_break = stop_foreach;
1126 /* LCOV_EXCL_STOP */
1128 int app_control_foreach_app_matched(app_control_h app_control, app_control_app_matched_cb callback, void *user_data)
1130 foreach_context_launchable_app_t foreach_context = {
1131 .app_control = app_control,
1132 .callback = callback,
1133 .user_data = user_data,
1134 .foreach_break = false
1137 if (app_control_validate(app_control) || callback == NULL)
1138 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1140 aul_svc_get_list_for_uid(app_control->data, app_control_cb_broker_foreach_app_matched, &foreach_context, getuid());
1142 return APP_CONTROL_ERROR_NONE;
1145 int app_control_get_caller(app_control_h app_control, char **package)
1147 const char *bundle_value;
1150 if (app_control_validate(app_control) || package == NULL)
1151 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1153 if (app_control->type != APP_CONTROL_TYPE_EVENT)
1154 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid app_control handle type");
1156 bundle_value = bundle_get_val(app_control->data, AUL_K_CALLER_APPID);
1157 if (bundle_value == NULL)
1158 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to retrieve the appid of the caller");
1160 package_dup = strdup(bundle_value);
1161 if (package_dup == NULL)
1162 return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
1164 *package = package_dup;
1166 return APP_CONTROL_ERROR_NONE;
1169 int app_control_is_reply_requested(app_control_h app_control, bool *requested)
1171 const char *bundle_value;
1173 if (app_control_validate(app_control) || requested == NULL)
1174 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1176 if (app_control->type != APP_CONTROL_TYPE_EVENT)
1177 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid app_control handle type");
1179 bundle_value = bundle_get_val(app_control->data, AUL_K_WAIT_RESULT);
1180 if (bundle_value != NULL)
1185 return APP_CONTROL_ERROR_NONE;
1188 int app_control_import_from_bundle(app_control_h app_control, bundle *data)
1190 bundle *data_dup = NULL;
1192 if (app_control_validate(app_control) || data == NULL)
1193 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1195 data_dup = bundle_dup(data);
1196 if (data_dup == NULL)
1197 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to duplicate the bundle");
1199 if (app_control->data != NULL)
1200 bundle_free(app_control->data);
1202 app_control->data = data_dup;
1204 return APP_CONTROL_ERROR_NONE;
1207 int app_control_export_as_bundle(app_control_h app_control, bundle **data)
1209 bundle *data_dup = NULL;
1211 if (app_control_validate(app_control) || data == NULL)
1212 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1214 data_dup = bundle_dup(app_control->data);
1215 if (data_dup == NULL)
1216 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to duplicate the bundle");
1220 return APP_CONTROL_ERROR_NONE;
1223 int app_control_request_transient_app(app_control_h app_control, unsigned int callee_id, app_control_host_res_fn cbfunc, void *data)
1227 if (app_control_validate(app_control))
1228 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1230 ret = aul_svc_request_transient_app(app_control->data, callee_id, (aul_svc_host_res_fn)cbfunc, data);
1232 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1234 return APP_CONTROL_ERROR_NONE;
1237 int app_control_enable_app_started_result_event(app_control_h app_control)
1241 if (app_control_validate(app_control))
1242 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1244 ret = aul_svc_subscribe_launch_result(app_control->data, AUL_SVC_K_LAUNCH_RESULT_APP_STARTED);
1246 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1248 return APP_CONTROL_ERROR_NONE;
1251 int app_control_set_instance_id(app_control_h app_control, const char *instance_id)
1255 if (app_control_validate(app_control) || instance_id == NULL)
1256 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1258 ret = aul_svc_set_instance_id(app_control->data, instance_id);
1260 return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, "Out of memory");
1262 return APP_CONTROL_ERROR_NONE;
1265 int app_control_get_instance_id(app_control_h app_control, char **instance_id)
1269 if (app_control_validate(app_control) || instance_id == NULL)
1270 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1272 id = aul_svc_get_instance_id(app_control->data);
1274 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "Failed to get the instance id");
1276 *instance_id = strdup(id);
1277 if (*instance_id == NULL)
1278 return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, "Failed to duplicate the instance id");
1280 return APP_CONTROL_ERROR_NONE;