2 * Copyright (c) 2011 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.
29 #include <app_service.h>
30 #include <app_service_private.h>
36 #define LOG_TAG "CAPI_APPFW_APPLICATION_SERVICE"
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__"
66 typedef struct service_request_context_s {
68 service_reply_cb reply_cb;
70 } *service_request_context_h;
72 extern int appsvc_allow_transient_app(bundle *b, unsigned int id);
74 static int service_create_reply(bundle *data, struct service_s **service);
76 static const char* service_error_to_string(service_error_e error)
79 case SERVICE_ERROR_NONE:
82 case SERVICE_ERROR_INVALID_PARAMETER:
83 return "INVALID_PARAMETER";
85 case SERVICE_ERROR_OUT_OF_MEMORY:
86 return "OUT_OF_MEMORY";
88 case SERVICE_ERROR_APP_NOT_FOUND:
89 return "APP_NOT_FOUND";
91 case SERVICE_ERROR_KEY_NOT_FOUND:
92 return "KEY_NOT_FOUND";
94 case SERVICE_ERROR_KEY_REJECTED:
95 return "KEY_REJECTED";
97 case SERVICE_ERROR_INVALID_DATA_TYPE:
98 return "INVALID_DATA_TYPE";
100 case SERVICE_ERROR_LAUNCH_REJECTED:
101 return "LAUNCH_REJECTED";
108 int service_error(service_error_e error, const char* function, const char *description)
111 LOGE("[%s] %s(0x%08x) : %s", function, service_error_to_string(error), error, description);
113 LOGE("[%s] %s(0x%08x)", function, service_error_to_string(error), error);
118 static int service_validate_extra_data(const char *data)
120 if (data == NULL || data[0] == '\0')
121 return SERVICE_ERROR_INVALID_PARAMETER;
123 return SERVICE_ERROR_NONE;
126 static int service_valiate_service(service_h service)
128 if (service == NULL || service->data == NULL)
129 return SERVICE_ERROR_INVALID_PARAMETER;
131 return SERVICE_ERROR_NONE;
134 static int service_new_id()
140 int service_validate_internal_key(const char *key)
142 if (strncmp(BUNDLE_KEY_PREFIX_AUL, key, strlen(BUNDLE_KEY_PREFIX_AUL)) == 0)
145 if (strncmp(BUNDLE_KEY_PREFIX_SERVICE, key, strlen(BUNDLE_KEY_PREFIX_SERVICE)) == 0)
151 static void service_request_result_broker(bundle *appsvc_bundle, int appsvc_request_code, appsvc_result_val appsvc_result, void *appsvc_data)
153 service_request_context_h request_context;
155 service_h reply = NULL;
156 service_result_e result;
158 service_reply_cb reply_cb;
160 if (appsvc_data == NULL) {
161 service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid service reply");
165 if (service_create_reply(appsvc_bundle, &reply) != 0) {
166 service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to create service reply");
170 request_context = appsvc_data;
171 request = request_context->service;
173 switch (appsvc_result) {
175 result = SERVICE_RESULT_SUCCEEDED;
178 case APPSVC_RES_NOT_OK:
179 result = SERVICE_RESULT_FAILED;
182 case APPSVC_RES_CANCEL:
183 result = SERVICE_RESULT_CANCELED;
187 result = SERVICE_RESULT_CANCELED;
191 user_data = request_context->user_data;
192 reply_cb = request_context->reply_cb;
194 if (reply_cb != NULL)
195 reply_cb(request, reply, result, user_data);
197 service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid callback ");
199 service_destroy(reply);
201 if (request_context->service != NULL)
202 service_destroy(request_context->service);
204 free(request_context);
208 int service_create(service_h *service)
210 return service_create_request(NULL, service);
213 int service_create_request(bundle *data, service_h *service)
215 struct service_s *service_request;
218 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
220 service_request = malloc(sizeof(struct service_s));
222 if (service_request == NULL)
223 return service_error(SERVICE_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create a service handle");
225 service_request->type = SERVICE_TYPE_REQUEST;
228 service_request->data = bundle_dup(data);
230 service_request->data = bundle_create();
232 if (service_request->data == NULL) {
233 free(service_request);
234 return service_error(SERVICE_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create a bundle");
237 service_request->id = service_new_id();
238 service_request->launch_pid = -1;
240 *service = service_request;
242 return SERVICE_ERROR_NONE;
245 int service_create_event(bundle *data, struct service_s **service)
247 struct service_s *service_event;
249 const char *operation;
251 if (data == NULL || service == NULL)
252 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
254 service_event = malloc(sizeof(struct service_s));
256 if (service_event == NULL)
257 return service_error(SERVICE_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create a service handle");
259 service_event->type = SERVICE_TYPE_EVENT;
260 service_event->data = bundle_dup(data);
261 service_event->id = service_new_id();
263 operation = appsvc_get_operation(service_event->data);
265 if (operation == NULL)
266 appsvc_set_operation(service_event->data, SERVICE_OPERATION_DEFAULT);
268 *service = service_event;
270 return SERVICE_ERROR_NONE;
273 static int service_create_reply(bundle *data, struct service_s **service)
275 struct service_s *service_reply;
277 if (data == NULL || service == NULL)
278 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
280 service_reply = malloc(sizeof(struct service_s));
282 if (service_reply == NULL)
283 return service_error(SERVICE_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create a service handle");
285 service_reply->type = SERVICE_TYPE_REPLY;
286 service_reply->data = bundle_dup(data);
287 service_reply->id = service_new_id();
289 *service = service_reply;
291 return SERVICE_ERROR_NONE;
294 int service_destroy(service_h service)
296 if (service_valiate_service(service))
297 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
299 bundle_free(service->data);
300 service->data = NULL;
303 return SERVICE_ERROR_NONE;
306 int service_to_bundle(service_h service, bundle **data)
308 if (service_valiate_service(service) || data == NULL)
309 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
311 *data = service->data;
313 return SERVICE_ERROR_NONE;
316 int service_set_operation(service_h service, const char *operation)
318 if (service_valiate_service(service))
319 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
321 if (operation != NULL) {
322 if (appsvc_set_operation(service->data, operation) != 0)
323 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid operation");
325 bundle_del(service->data, BUNDLE_KEY_OPERATION);
328 return SERVICE_ERROR_NONE;
331 int service_get_operation(service_h service, char **operation)
333 const char *operation_value;
335 if (service_valiate_service(service) || operation == NULL)
336 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
338 operation_value = appsvc_get_operation(service->data);
340 if (operation_value != NULL)
341 *operation = strdup(operation_value);
345 return SERVICE_ERROR_NONE;
349 int service_set_uri(service_h service, const char *uri)
351 if (service_valiate_service(service))
352 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
355 if (appsvc_set_uri(service->data, uri) != 0)
356 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid URI");
358 bundle_del(service->data, BUNDLE_KEY_URI);
361 return SERVICE_ERROR_NONE;
365 int service_get_uri(service_h service, char **uri)
367 const char *uri_value;
369 if (service_valiate_service(service) || uri == NULL)
370 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
372 uri_value = appsvc_get_uri(service->data);
374 if (uri_value != NULL)
375 *uri = strdup(uri_value);
379 return SERVICE_ERROR_NONE;
383 int service_set_mime(service_h service, const char *mime)
385 if (service_valiate_service(service))
386 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
389 if (appsvc_set_mime(service->data, mime) != 0)
390 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid MIME type");
392 bundle_del(service->data, BUNDLE_KEY_MIME);
395 return SERVICE_ERROR_NONE;
399 int service_get_mime(service_h service, char **mime)
401 const char *mime_value;
403 if (service_valiate_service(service) || mime == NULL)
404 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
406 mime_value = appsvc_get_mime(service->data);
408 if (mime_value != NULL)
409 *mime = strdup(mime_value);
413 return SERVICE_ERROR_NONE;
417 int service_set_category(service_h service, const char *category)
419 if (service_valiate_service(service))
420 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
422 if (category != NULL) {
423 if (appsvc_set_category(service->data, category) != 0)
424 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid MIME type");
426 bundle_del(service->data, BUNDLE_KEY_MIME);
429 return SERVICE_ERROR_NONE;
433 int service_get_category(service_h service, char **category)
435 const char *category_value;
437 if (service_valiate_service(service) || category == NULL)
438 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
440 category_value = appsvc_get_category(service->data);
442 if (category_value != NULL)
443 *category = strdup(category_value);
447 return SERVICE_ERROR_NONE;
451 int service_set_package(service_h service, const char *package)
454 * TODO: this function must be deprecated
456 return service_set_app_id(service, package);
459 int service_get_package(service_h service, char **package)
462 * TODO: this function must be deprecated
464 return service_get_app_id(service, package);
468 int service_set_app_id(service_h service, const char *app_id)
470 if (service_valiate_service(service))
471 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
473 if (app_id != NULL) {
474 if (appsvc_set_appid(service->data, app_id) != 0)
475 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid application ID");
477 bundle_del(service->data, BUNDLE_KEY_PACKAGE);
480 return SERVICE_ERROR_NONE;
484 int service_get_app_id(service_h service, char **app_id)
486 const char *app_id_value;
488 if (service_valiate_service(service) || app_id == NULL)
489 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
491 app_id_value = appsvc_get_appid(service->data);
493 if (app_id_value != NULL)
494 *app_id = strdup(app_id_value);
498 return SERVICE_ERROR_NONE;
501 int service_set_window(service_h service, unsigned int id)
503 if (service_valiate_service(service))
504 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
507 if (appsvc_allow_transient_app(service->data, id) != 0)
508 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid id");
510 bundle_del(service->data, BUNDLE_KEY_WINDOW);
513 return SERVICE_ERROR_NONE;
516 int service_get_window(service_h service, unsigned int *id)
518 const char *window_id;
520 if (service_valiate_service(service) || id == NULL)
521 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
523 window_id = bundle_get_val(service->data, BUNDLE_KEY_WINDOW);
525 if (window_id != NULL)
526 *id = atoi(window_id);
530 return SERVICE_ERROR_NONE;
533 int service_clone(service_h *clone, service_h service)
535 service_h service_clone;
537 if (service_valiate_service(service) || clone == NULL)
538 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
540 service_clone = malloc(sizeof(struct service_s));
542 if (service_clone == NULL)
543 return service_error(SERVICE_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create a service handle");
545 service_clone->id = service_new_id();
546 service_clone->type = service->type;
547 service_clone->data = bundle_dup(service->data);
549 *clone = service_clone;
551 return SERVICE_ERROR_NONE;
555 int service_send_launch_request(service_h service, service_reply_cb callback, void *user_data)
557 const char *operation;
560 bool implicit_default_operation = false;
563 service_request_context_h request_context = NULL;
565 if (service_valiate_service(service))
566 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
568 operation = appsvc_get_operation(service->data);
570 if (operation == NULL) {
571 implicit_default_operation = true;
572 operation = SERVICE_OPERATION_DEFAULT;
575 appid = appsvc_get_appid(service->data);
577 if (!strcmp(operation, SERVICE_OPERATION_DEFAULT)) {
579 return service_error(SERVICE_ERROR_APP_NOT_FOUND, __FUNCTION__, "package must be specified if the operation is default value");
582 if (callback != NULL) {
583 service_h request_clone = NULL;
585 request_context = calloc(1, sizeof(struct service_request_context_s));
587 if (request_context == NULL)
588 return service_error(SERVICE_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
590 request_context->reply_cb = callback;
592 if (service_clone(&request_clone, service) != SERVICE_ERROR_NONE) {
593 free(request_context);
594 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to clone the service request handle");
597 request_context->service = request_clone;
598 request_context->user_data = user_data;
601 if (implicit_default_operation == true)
602 appsvc_set_operation(service->data, SERVICE_OPERATION_DEFAULT);
604 launch_pid = appsvc_usr_run_service(service->data, service->id, callback ? service_request_result_broker : NULL, request_context, getuid());
606 if (implicit_default_operation == true)
607 bundle_del(service->data, BUNDLE_KEY_OPERATION);
609 if (launch_pid < 0) {
610 if (launch_pid == APPSVC_RET_ENOMATCH)
611 return service_error(SERVICE_ERROR_APP_NOT_FOUND, __FUNCTION__, NULL);
613 return service_error(SERVICE_ERROR_LAUNCH_REJECTED, __FUNCTION__, NULL);
616 service->launch_pid = launch_pid;
618 return SERVICE_ERROR_NONE;
622 int service_send_terminate_request(service_h service)
624 if (service_valiate_service(service))
625 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
627 if (service->type != SERVICE_TYPE_REQUEST || service->launch_pid < 0)
628 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
630 appsvc_subapp_terminate_request_pid(service->launch_pid);
632 return SERVICE_ERROR_NONE;
635 static bool service_copy_reply_data_cb(service_h service, const char *key, void *user_data)
637 bundle *reply_data = user_data;
639 char **value_array = NULL;
640 int value_array_length = 0;
641 int value_array_index = 0;
643 if (reply_data == NULL) {
644 service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
648 if (appsvc_data_is_array(service->data, key)) {
649 service_get_extra_data_array(service, key, &value_array, &value_array_length);
650 appsvc_add_data_array(reply_data, key, (const char**)value_array, value_array_length);
652 for (value_array_index = 0; value_array_index < value_array_length; value_array_index++)
653 free(value_array[value_array_index]);
656 service_get_extra_data(service, key, &value);
657 appsvc_add_data(reply_data, key, value);
664 int service_reply_to_launch_request(service_h reply, service_h request, service_result_e result)
669 if (service_valiate_service(reply) || service_valiate_service(request))
670 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
672 if (appsvc_create_result_bundle(request->data, &reply_data) != 0)
673 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to create a result bundle");
675 service_foreach_extra_data(reply, service_copy_reply_data_cb, reply_data);
678 case SERVICE_RESULT_SUCCEEDED:
679 appsvc_result = APPSVC_RES_OK;
682 case SERVICE_RESULT_FAILED:
683 appsvc_result = APPSVC_RES_NOT_OK;
686 case SERVICE_RESULT_CANCELED:
687 appsvc_result = APPSVC_RES_CANCEL;
691 appsvc_result = APPSVC_RES_CANCEL;
695 appsvc_send_result(reply_data, appsvc_result);
697 return SERVICE_ERROR_NONE;
701 int service_add_extra_data(service_h service, const char *key, const char *value)
703 if (service_valiate_service(service) || service_validate_extra_data(key) || service_validate_extra_data(value))
704 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
706 if (service_validate_internal_key(key))
707 return service_error(SERVICE_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use");
709 if (appsvc_get_data(service->data, key) != NULL)
710 bundle_del(service->data, key);
712 if (appsvc_add_data(service->data, key, value) != 0)
713 return service_error(SERVICE_ERROR_KEY_REJECTED, __FUNCTION__, "failed to add data to the appsvc handle");
715 return SERVICE_ERROR_NONE;
719 int service_add_extra_data_array(service_h service, const char *key, const char* value[], int length)
721 if (service_valiate_service(service) || service_validate_extra_data(key))
722 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
724 if (value == NULL || length <= 0)
725 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid array");
727 if (service_validate_internal_key(key))
728 return service_error(SERVICE_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use");
730 if (appsvc_get_data_array(service->data, key, NULL) != NULL)
731 bundle_del(service->data, key);
733 if (appsvc_add_data_array(service->data, key, value, length) != 0)
734 return service_error(SERVICE_ERROR_KEY_REJECTED, __FUNCTION__, "failed to add array data to the appsvc handle");
736 return SERVICE_ERROR_NONE;
740 int service_remove_extra_data(service_h service, const char *key)
742 if (service_valiate_service(service) || service_validate_extra_data(key))
743 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
745 if (service_validate_internal_key(key))
746 return service_error(SERVICE_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use");
748 if (bundle_del(service->data, key))
749 return service_error(SERVICE_ERROR_KEY_NOT_FOUND, __FUNCTION__, NULL);
751 return SERVICE_ERROR_NONE;
755 int service_get_extra_data(service_h service, const char *key, char **value)
757 const char *data_value;
759 if (service_valiate_service(service) || service_validate_extra_data(key) || value == NULL)
760 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
763 if (service_validate_internal_key(key))
764 return service_error(SERVICE_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use");
766 data_value = appsvc_get_data(service->data, key);
768 if (data_value == NULL) {
769 if (errno == ENOTSUP)
770 return service_error(SERVICE_ERROR_INVALID_DATA_TYPE, __FUNCTION__, NULL);
772 return service_error(SERVICE_ERROR_KEY_NOT_FOUND, __FUNCTION__, NULL);
775 *value = strdup(data_value);
777 return SERVICE_ERROR_NONE;
781 int service_get_extra_data_array(service_h service, const char *key, char ***value, int *length)
783 const char **array_data;
784 int array_data_length;
785 char **array_data_clone;
788 if (service_valiate_service(service) || service_validate_extra_data(key))
789 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
791 if (value == NULL || length == 0)
792 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
794 if (service_validate_internal_key(key))
795 return service_error(SERVICE_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use");
797 array_data = appsvc_get_data_array(service->data, key, &array_data_length);
799 if (array_data == NULL) {
800 if (errno == ENOTSUP)
801 return service_error(SERVICE_ERROR_INVALID_DATA_TYPE, __FUNCTION__, NULL);
803 return service_error(SERVICE_ERROR_KEY_NOT_FOUND, __FUNCTION__, NULL);
806 array_data_clone = calloc(array_data_length, sizeof(char*));
808 if (array_data_clone == NULL)
809 return service_error(SERVICE_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
811 for (i = 0; i < array_data_length; i++) {
812 if (array_data[i] != NULL)
813 array_data_clone[i] = strdup(array_data[i]);
816 *value = array_data_clone;
817 *length = array_data_length;
819 return SERVICE_ERROR_NONE;
823 int service_is_extra_data_array(service_h service, const char *key, bool *array)
825 if (service_valiate_service(service) || service_validate_extra_data(key) || array == NULL)
826 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
828 if (service_validate_internal_key(key))
829 return service_error(SERVICE_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use");
831 if (!appsvc_data_is_array(service->data, key))
836 return SERVICE_ERROR_NONE;
842 service_extra_data_cb callback;
845 } foreach_context_extra_data_t;
847 static void service_cb_broker_bundle_iterator(const char *key, const int type, const bundle_keyval_t *kv, void *user_data)
849 foreach_context_extra_data_t* foreach_context = NULL;
850 service_extra_data_cb extra_data_cb;
852 if (key == NULL || !(type == BUNDLE_TYPE_STR || type == BUNDLE_TYPE_STR_ARRAY))
855 foreach_context = (foreach_context_extra_data_t*)user_data;
857 if (foreach_context->foreach_break == true)
860 if (service_validate_internal_key(key))
863 extra_data_cb = foreach_context->callback;
865 if (extra_data_cb != NULL) {
866 bool stop_foreach = false;
867 stop_foreach = !extra_data_cb(foreach_context->service, key, foreach_context->user_data);
868 foreach_context->foreach_break = stop_foreach;
874 int service_foreach_extra_data(service_h service, service_extra_data_cb callback, void *user_data)
876 foreach_context_extra_data_t foreach_context = {
878 .callback = callback,
879 .user_data = user_data,
880 .foreach_break = false
883 if (service_valiate_service(service) || callback == NULL)
884 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
886 bundle_foreach(service->data, service_cb_broker_bundle_iterator, &foreach_context);
888 return SERVICE_ERROR_NONE;
893 service_app_matched_cb callback;
896 } foreach_context_launchable_app_t;
898 int service_cb_broker_foreach_app_matched(const char *package, void *data)
900 foreach_context_launchable_app_t *foreach_context;
901 service_app_matched_cb app_matched_cb;
903 if (package == NULL || data == NULL) {
904 service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
908 foreach_context = (foreach_context_launchable_app_t*)data;
910 if (foreach_context->foreach_break == true)
913 app_matched_cb = foreach_context->callback;
915 if (app_matched_cb != NULL) {
916 bool stop_foreach = false;
917 stop_foreach = !app_matched_cb(foreach_context->service, package, foreach_context->user_data);
918 foreach_context->foreach_break = stop_foreach;
924 int service_foreach_app_matched(service_h service, service_app_matched_cb callback, void *user_data)
926 foreach_context_launchable_app_t foreach_context = {
928 .callback = callback,
929 .user_data = user_data,
930 .foreach_break = false
933 if (service_valiate_service(service) || callback == NULL)
934 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
936 appsvc_usr_get_list(service->data, service_cb_broker_foreach_app_matched, &foreach_context, getuid());
938 return SERVICE_ERROR_NONE;
942 int service_get_caller(service_h service, char **package)
944 const char *bundle_value;
947 if (service_valiate_service(service) || package == NULL)
948 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
950 if (service->type != SERVICE_TYPE_EVENT)
951 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid service handle type");
953 bundle_value = bundle_get_val(service->data, AUL_K_CALLER_APPID);
954 if (bundle_value == NULL)
955 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to retrieve the appid of the caller");
957 package_dup = strdup(bundle_value);
959 if (package_dup == NULL)
960 return service_error(SERVICE_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
962 *package = package_dup;
964 return SERVICE_ERROR_NONE;
968 int service_is_reply_requested(service_h service, bool *requested)
970 const char *bundle_value;
972 if (service_valiate_service(service) || requested == NULL)
973 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
975 if (service->type != SERVICE_TYPE_EVENT)
976 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid service handle type");
978 bundle_value = bundle_get_val(service->data, AUL_K_WAIT_RESULT);
980 if (bundle_value != NULL)
985 return SERVICE_ERROR_NONE;
988 int service_import_from_bundle(service_h service, bundle *data)
990 bundle *data_dup = NULL;
992 if (service_valiate_service(service) || data == NULL)
993 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
995 data_dup = bundle_dup(data);
997 if (data_dup == NULL)
998 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to duplicate the bundle");
1000 if (service->data != NULL)
1001 bundle_free(service->data);
1003 service->data = data_dup;
1005 return SERVICE_ERROR_NONE;
1008 int service_export_as_bundle(service_h service, bundle **data)
1010 bundle *data_dup = NULL;
1012 if (service_valiate_service(service) || data == NULL)
1013 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1015 data_dup = bundle_dup(service->data);
1017 if (data_dup == NULL)
1018 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to duplicate the bundle");
1022 return SERVICE_ERROR_NONE;