Apply tizen coding rules
[platform/core/api/application.git] / src / service.c
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <unistd.h>
21 #include <string.h>
22 #include <errno.h>
23
24 #include <bundle.h>
25 #include <aul.h>
26 #include <appsvc.h>
27 #include <dlog.h>
28
29 #include <app_service.h>
30 #include <app_service_private.h>
31
32 #ifdef LOG_TAG
33 #undef LOG_TAG
34 #endif
35
36 #define LOG_TAG "CAPI_APPFW_APPLICATION_SERVICE"
37
38 #ifndef TIZEN_PATH_MAX
39 #define TIZEN_PATH_MAX 1024
40 #endif
41
42 #define BUNDLE_KEY_PREFIX_AUL "__AUL_"
43 #define BUNDLE_KEY_PREFIX_SERVICE "__APP_SVC_"
44
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
52
53 typedef enum {
54         SERVICE_TYPE_REQUEST,
55         SERVICE_TYPE_EVENT,
56         SERVICE_TYPE_REPLY,
57 } service_type_e;
58
59 struct service_s {
60         int id;
61         service_type_e type;
62         bundle *data;
63         int launch_pid;
64 };
65
66 typedef struct service_request_context_s {
67         service_h service;
68         service_reply_cb reply_cb;
69         void *user_data;
70 } *service_request_context_h;
71
72 extern int appsvc_allow_transient_app(bundle *b, unsigned int id);
73
74 static int service_create_reply(bundle *data, struct service_s **service);
75
76 static const char* service_error_to_string(service_error_e error)
77 {
78         switch (error) {
79         case SERVICE_ERROR_NONE:
80                 return "NONE";
81
82         case SERVICE_ERROR_INVALID_PARAMETER:
83                 return "INVALID_PARAMETER";
84
85         case SERVICE_ERROR_OUT_OF_MEMORY:
86                 return "OUT_OF_MEMORY";
87
88         case SERVICE_ERROR_APP_NOT_FOUND:
89                 return "APP_NOT_FOUND";
90
91         case SERVICE_ERROR_KEY_NOT_FOUND:
92                 return "KEY_NOT_FOUND";
93
94         case SERVICE_ERROR_KEY_REJECTED:
95                 return "KEY_REJECTED";
96
97         case SERVICE_ERROR_INVALID_DATA_TYPE:
98                 return "INVALID_DATA_TYPE";
99
100         case SERVICE_ERROR_LAUNCH_REJECTED:
101                 return "LAUNCH_REJECTED";
102
103         default:
104                 return "UNKNOWN";
105         }
106 }
107
108 int service_error(service_error_e error, const char* function, const char *description)
109 {
110         if (description)
111                 LOGE("[%s] %s(0x%08x) : %s", function, service_error_to_string(error), error, description);
112         else
113                 LOGE("[%s] %s(0x%08x)", function, service_error_to_string(error), error);
114
115         return error;
116 }
117
118 static int service_validate_extra_data(const char *data)
119 {
120         if (data == NULL || data[0] == '\0')
121                 return SERVICE_ERROR_INVALID_PARAMETER;
122
123         return SERVICE_ERROR_NONE;
124 }
125
126 static int service_valiate_service(service_h service)
127 {
128         if (service == NULL || service->data == NULL)
129                 return SERVICE_ERROR_INVALID_PARAMETER;
130
131         return SERVICE_ERROR_NONE;
132 }
133
134 static int service_new_id()
135 {
136         static int sid = 0;
137         return sid++;
138 }
139
140 int service_validate_internal_key(const char *key)
141 {
142         if (strncmp(BUNDLE_KEY_PREFIX_AUL, key, strlen(BUNDLE_KEY_PREFIX_AUL)) == 0)
143                 return -1;
144
145         if (strncmp(BUNDLE_KEY_PREFIX_SERVICE, key, strlen(BUNDLE_KEY_PREFIX_SERVICE)) == 0)
146                 return -1;
147
148         return 0;
149 }
150
151 static void service_request_result_broker(bundle *appsvc_bundle, int appsvc_request_code, appsvc_result_val appsvc_result, void *appsvc_data)
152 {
153         service_request_context_h request_context;
154         service_h request;
155         service_h reply = NULL;
156         service_result_e result;
157         void *user_data;
158         service_reply_cb reply_cb;
159
160         if (appsvc_data == NULL) {
161                 service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid service reply");
162                 return;
163         }
164
165         if (service_create_reply(appsvc_bundle, &reply) != 0) {
166                 service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to create service reply");
167                 return;
168         }
169
170         request_context = appsvc_data;
171         request = request_context->service;
172
173         switch (appsvc_result) {
174         case APPSVC_RES_OK:
175                 result = SERVICE_RESULT_SUCCEEDED;
176                 break;
177
178         case APPSVC_RES_NOT_OK:
179                 result = SERVICE_RESULT_FAILED;
180                 break;
181
182         case APPSVC_RES_CANCEL:
183                 result = SERVICE_RESULT_CANCELED;
184                 break;
185
186         default:
187                 result = SERVICE_RESULT_CANCELED;
188                 break;
189         }
190
191         user_data = request_context->user_data;
192         reply_cb = request_context->reply_cb;
193
194         if (reply_cb != NULL)
195                 reply_cb(request, reply, result, user_data);
196         else
197                 service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid callback ");
198
199         service_destroy(reply);
200
201         if (request_context->service != NULL)
202                 service_destroy(request_context->service);
203
204         free(request_context);
205 }
206
207
208 int service_create(service_h *service)
209 {
210         return service_create_request(NULL, service);
211 }
212
213 int service_create_request(bundle *data, service_h *service)
214 {
215         struct service_s *service_request;
216
217         if (service == NULL)
218                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
219
220         service_request = malloc(sizeof(struct service_s));
221
222         if (service_request == NULL)
223                 return service_error(SERVICE_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create a service handle");
224
225         service_request->type = SERVICE_TYPE_REQUEST;
226
227         if (data != NULL)
228                 service_request->data = bundle_dup(data);
229         else
230                 service_request->data = bundle_create();
231
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");
235         }
236
237         service_request->id = service_new_id();
238         service_request->launch_pid = -1;
239
240         *service = service_request;
241
242         return SERVICE_ERROR_NONE;
243 }
244
245 int service_create_event(bundle *data, struct service_s **service)
246 {
247         struct service_s *service_event;
248
249         const char *operation;
250
251         if (data == NULL || service == NULL)
252                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
253
254         service_event = malloc(sizeof(struct service_s));
255
256         if (service_event == NULL)
257                 return service_error(SERVICE_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create a service handle");
258
259         service_event->type = SERVICE_TYPE_EVENT;
260         service_event->data = bundle_dup(data);
261         service_event->id = service_new_id();
262
263         operation = appsvc_get_operation(service_event->data);
264
265         if (operation == NULL)
266                 appsvc_set_operation(service_event->data, SERVICE_OPERATION_DEFAULT);
267
268         *service = service_event;
269
270         return SERVICE_ERROR_NONE;
271 }
272
273 static int service_create_reply(bundle *data, struct service_s **service)
274 {
275         struct service_s *service_reply;
276
277         if (data == NULL || service == NULL)
278                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
279
280         service_reply = malloc(sizeof(struct service_s));
281
282         if (service_reply == NULL)
283                 return service_error(SERVICE_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create a service handle");
284
285         service_reply->type = SERVICE_TYPE_REPLY;
286         service_reply->data = bundle_dup(data);
287         service_reply->id = service_new_id();
288
289         *service = service_reply;
290
291         return SERVICE_ERROR_NONE;
292 }
293
294 int service_destroy(service_h service)
295 {
296         if (service_valiate_service(service))
297                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
298
299         bundle_free(service->data);
300         service->data = NULL;
301         free(service);
302
303         return SERVICE_ERROR_NONE;
304 }
305
306 int service_to_bundle(service_h service, bundle **data)
307 {
308         if (service_valiate_service(service) || data == NULL)
309                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
310
311         *data = service->data;
312
313         return SERVICE_ERROR_NONE;
314 }
315
316 int service_set_operation(service_h service, const char *operation)
317 {
318         if (service_valiate_service(service))
319                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
320
321         if (operation != NULL) {
322                 if (appsvc_set_operation(service->data, operation) != 0)
323                         return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid operation");
324         } else {
325                 bundle_del(service->data, BUNDLE_KEY_OPERATION);
326         }
327
328         return SERVICE_ERROR_NONE;
329 }
330
331 int service_get_operation(service_h service, char **operation)
332 {
333         const char *operation_value;
334
335         if (service_valiate_service(service) || operation == NULL)
336                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
337
338         operation_value = appsvc_get_operation(service->data);
339
340         if (operation_value != NULL)
341                 *operation = strdup(operation_value);
342         else
343                 *operation = NULL;
344
345         return SERVICE_ERROR_NONE;
346 }
347
348
349 int service_set_uri(service_h service, const char *uri)
350 {
351         if (service_valiate_service(service))
352                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
353
354         if (uri != NULL) {
355                 if (appsvc_set_uri(service->data, uri) != 0)
356                         return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid URI");
357         } else {
358                 bundle_del(service->data, BUNDLE_KEY_URI);
359         }
360
361         return SERVICE_ERROR_NONE;
362 }
363
364
365 int service_get_uri(service_h service, char **uri)
366 {
367         const char *uri_value;
368
369         if (service_valiate_service(service) || uri == NULL)
370                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
371
372         uri_value = appsvc_get_uri(service->data);
373
374         if (uri_value != NULL)
375                 *uri = strdup(uri_value);
376         else
377                 *uri = NULL;
378
379         return SERVICE_ERROR_NONE;
380 }
381
382
383 int service_set_mime(service_h service, const char *mime)
384 {
385         if (service_valiate_service(service))
386                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
387
388         if (mime != NULL) {
389                 if (appsvc_set_mime(service->data, mime) != 0)
390                         return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid MIME type");
391         } else {
392                 bundle_del(service->data, BUNDLE_KEY_MIME);
393         }
394
395         return SERVICE_ERROR_NONE;
396 }
397
398
399 int service_get_mime(service_h service, char **mime)
400 {
401         const char *mime_value;
402
403         if (service_valiate_service(service) || mime == NULL)
404                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
405
406         mime_value = appsvc_get_mime(service->data);
407
408         if (mime_value != NULL)
409                 *mime = strdup(mime_value);
410         else
411                 *mime = NULL;
412
413         return SERVICE_ERROR_NONE;
414 }
415
416
417 int service_set_category(service_h service, const char *category)
418 {
419         if (service_valiate_service(service))
420                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
421
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");
425         } else {
426                 bundle_del(service->data, BUNDLE_KEY_MIME);
427         }
428
429         return SERVICE_ERROR_NONE;
430 }
431
432
433 int service_get_category(service_h service, char **category)
434 {
435         const char *category_value;
436
437         if (service_valiate_service(service) || category == NULL)
438                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
439
440         category_value = appsvc_get_category(service->data);
441
442         if (category_value != NULL)
443                 *category = strdup(category_value);
444         else
445                 *category = NULL;
446
447         return SERVICE_ERROR_NONE;
448 }
449
450
451 int service_set_package(service_h service, const char *package)
452 {
453         /*
454          * TODO: this function must be deprecated
455          */
456         return service_set_app_id(service, package);
457 }
458
459 int service_get_package(service_h service, char **package)
460 {
461         /*
462          * TODO: this function must be deprecated
463          */
464         return service_get_app_id(service, package);
465 }
466
467
468 int service_set_app_id(service_h service, const char *app_id)
469 {
470         if (service_valiate_service(service))
471                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
472
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");
476         } else {
477                 bundle_del(service->data, BUNDLE_KEY_PACKAGE);
478         }
479
480         return SERVICE_ERROR_NONE;
481 }
482
483
484 int service_get_app_id(service_h service, char **app_id)
485 {
486         const char *app_id_value;
487
488         if (service_valiate_service(service) || app_id == NULL)
489                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
490
491         app_id_value = appsvc_get_appid(service->data);
492
493         if (app_id_value != NULL)
494                 *app_id = strdup(app_id_value);
495         else
496                 *app_id = NULL;
497
498         return SERVICE_ERROR_NONE;
499 }
500
501 int service_set_window(service_h service, unsigned int id)
502 {
503         if (service_valiate_service(service))
504                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
505
506         if (id > 0) {
507                 if (appsvc_allow_transient_app(service->data, id) != 0)
508                         return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid id");
509         } else {
510                 bundle_del(service->data, BUNDLE_KEY_WINDOW);
511         }
512
513         return SERVICE_ERROR_NONE;
514 }
515
516 int service_get_window(service_h service, unsigned int *id)
517 {
518         const char *window_id;
519
520         if (service_valiate_service(service) || id == NULL)
521                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
522
523         window_id = bundle_get_val(service->data, BUNDLE_KEY_WINDOW);
524
525         if (window_id != NULL)
526                 *id = atoi(window_id);
527         else
528                 *id = 0;
529
530         return SERVICE_ERROR_NONE;
531 }
532
533 int service_clone(service_h *clone, service_h service)
534 {
535         service_h service_clone;
536
537         if (service_valiate_service(service) || clone == NULL)
538                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
539
540         service_clone = malloc(sizeof(struct service_s));
541
542         if (service_clone == NULL)
543                 return service_error(SERVICE_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create a service handle");
544
545         service_clone->id = service_new_id();
546         service_clone->type = service->type;
547         service_clone->data = bundle_dup(service->data);
548
549         *clone = service_clone;
550
551         return SERVICE_ERROR_NONE;
552 }
553
554
555 int service_send_launch_request(service_h service, service_reply_cb callback, void *user_data)
556 {
557         const char *operation;
558         const char *appid;
559
560         bool implicit_default_operation = false;
561         int launch_pid;
562
563         service_request_context_h request_context = NULL;
564
565         if (service_valiate_service(service))
566                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
567
568         operation = appsvc_get_operation(service->data);
569
570         if (operation == NULL) {
571                 implicit_default_operation = true;
572                 operation = SERVICE_OPERATION_DEFAULT;
573         }
574
575         appid = appsvc_get_appid(service->data);
576
577         if (!strcmp(operation, SERVICE_OPERATION_DEFAULT)) {
578                 if (appid == NULL)
579                         return service_error(SERVICE_ERROR_APP_NOT_FOUND, __FUNCTION__, "package must be specified if the operation is default value");
580         }
581
582         if (callback != NULL) {
583                 service_h request_clone = NULL;
584
585                 request_context = calloc(1, sizeof(struct service_request_context_s));
586
587                 if (request_context == NULL)
588                         return service_error(SERVICE_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
589
590                 request_context->reply_cb = callback;
591
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");
595                 }
596
597                 request_context->service = request_clone;
598                 request_context->user_data = user_data;
599         }
600
601         if (implicit_default_operation == true)
602                 appsvc_set_operation(service->data, SERVICE_OPERATION_DEFAULT);
603
604         launch_pid = appsvc_usr_run_service(service->data, service->id, callback ? service_request_result_broker : NULL, request_context, getuid());
605
606         if (implicit_default_operation == true)
607                 bundle_del(service->data, BUNDLE_KEY_OPERATION);
608
609         if (launch_pid < 0) {
610                 if (launch_pid == APPSVC_RET_ENOMATCH)
611                         return service_error(SERVICE_ERROR_APP_NOT_FOUND, __FUNCTION__, NULL);
612                 else
613                         return service_error(SERVICE_ERROR_LAUNCH_REJECTED, __FUNCTION__, NULL);
614         }
615
616         service->launch_pid = launch_pid;
617
618         return SERVICE_ERROR_NONE;
619 }
620
621
622 int service_send_terminate_request(service_h service)
623 {
624         if (service_valiate_service(service))
625                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
626
627         if (service->type != SERVICE_TYPE_REQUEST || service->launch_pid < 0)
628                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
629
630         appsvc_subapp_terminate_request_pid(service->launch_pid);
631
632         return SERVICE_ERROR_NONE;
633 }
634
635 static bool service_copy_reply_data_cb(service_h service, const char *key, void *user_data)
636 {
637         bundle *reply_data = user_data;
638         char *value = NULL;
639         char **value_array = NULL;
640         int value_array_length = 0;
641         int value_array_index = 0;
642
643         if (reply_data == NULL) {
644                 service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
645                 return false;
646         }
647
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);
651
652                 for (value_array_index = 0; value_array_index < value_array_length; value_array_index++)
653                         free(value_array[value_array_index]);
654                 free(value_array);
655         } else {
656                 service_get_extra_data(service, key, &value);
657                 appsvc_add_data(reply_data, key, value);
658                 free(value);
659         }
660
661         return true;
662 }
663
664 int service_reply_to_launch_request(service_h reply, service_h request, service_result_e result)
665 {
666         bundle *reply_data;
667         int appsvc_result;
668
669         if (service_valiate_service(reply) || service_valiate_service(request))
670                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
671
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");
674
675         service_foreach_extra_data(reply, service_copy_reply_data_cb, reply_data);
676
677         switch (result) {
678         case SERVICE_RESULT_SUCCEEDED:
679                 appsvc_result = APPSVC_RES_OK;
680                 break;
681
682         case SERVICE_RESULT_FAILED:
683                 appsvc_result = APPSVC_RES_NOT_OK;
684                 break;
685
686         case SERVICE_RESULT_CANCELED:
687                 appsvc_result = APPSVC_RES_CANCEL;
688                 break;
689
690         default:
691                 appsvc_result = APPSVC_RES_CANCEL;
692                 break;
693         }
694
695         appsvc_send_result(reply_data, appsvc_result);
696
697         return SERVICE_ERROR_NONE;
698 }
699
700
701 int service_add_extra_data(service_h service, const char *key, const char *value)
702 {
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);
705
706         if (service_validate_internal_key(key))
707                 return service_error(SERVICE_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use");
708
709         if (appsvc_get_data(service->data, key) != NULL)
710                 bundle_del(service->data, key);
711
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");
714
715         return SERVICE_ERROR_NONE;
716 }
717
718
719 int service_add_extra_data_array(service_h service, const char *key, const char* value[], int length)
720 {
721         if (service_valiate_service(service) || service_validate_extra_data(key))
722                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
723
724         if (value == NULL || length <= 0)
725                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid array");
726
727         if (service_validate_internal_key(key))
728                 return service_error(SERVICE_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use");
729
730         if (appsvc_get_data_array(service->data, key, NULL) != NULL)
731                 bundle_del(service->data, key);
732
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");
735
736         return SERVICE_ERROR_NONE;
737 }
738
739
740 int service_remove_extra_data(service_h service, const char *key)
741 {
742         if (service_valiate_service(service) || service_validate_extra_data(key))
743                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
744
745         if (service_validate_internal_key(key))
746                 return service_error(SERVICE_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use");
747
748         if (bundle_del(service->data, key))
749                 return service_error(SERVICE_ERROR_KEY_NOT_FOUND, __FUNCTION__, NULL);
750
751         return SERVICE_ERROR_NONE;
752 }
753
754
755 int service_get_extra_data(service_h service, const char *key, char **value)
756 {
757         const char *data_value;
758
759         if (service_valiate_service(service) || service_validate_extra_data(key) || value == NULL)
760                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
761
762
763         if (service_validate_internal_key(key))
764                 return service_error(SERVICE_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use");
765
766         data_value = appsvc_get_data(service->data, key);
767
768         if (data_value == NULL) {
769                 if (errno == ENOTSUP)
770                         return service_error(SERVICE_ERROR_INVALID_DATA_TYPE, __FUNCTION__, NULL);
771                 else
772                         return service_error(SERVICE_ERROR_KEY_NOT_FOUND, __FUNCTION__, NULL);
773         }
774
775         *value = strdup(data_value);
776
777         return SERVICE_ERROR_NONE;
778 }
779
780
781 int service_get_extra_data_array(service_h service, const char *key, char ***value, int *length)
782 {
783         const char **array_data;
784         int array_data_length;
785         char **array_data_clone;
786         int i;
787
788         if (service_valiate_service(service) || service_validate_extra_data(key))
789                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
790
791         if (value == NULL || length == 0)
792                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
793
794         if (service_validate_internal_key(key))
795                 return service_error(SERVICE_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use");
796
797         array_data = appsvc_get_data_array(service->data, key, &array_data_length);
798
799         if (array_data == NULL) {
800                 if (errno == ENOTSUP)
801                         return service_error(SERVICE_ERROR_INVALID_DATA_TYPE, __FUNCTION__, NULL);
802                 else
803                         return service_error(SERVICE_ERROR_KEY_NOT_FOUND, __FUNCTION__, NULL);
804         }
805
806         array_data_clone = calloc(array_data_length, sizeof(char*));
807
808         if (array_data_clone == NULL)
809                 return service_error(SERVICE_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
810
811         for (i = 0; i < array_data_length; i++) {
812                 if (array_data[i] != NULL)
813                         array_data_clone[i] = strdup(array_data[i]);
814         }
815
816         *value = array_data_clone;
817         *length = array_data_length;
818
819         return SERVICE_ERROR_NONE;
820 }
821
822
823 int service_is_extra_data_array(service_h service, const char *key, bool *array)
824 {
825         if (service_valiate_service(service) || service_validate_extra_data(key) || array == NULL)
826                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
827
828         if (service_validate_internal_key(key))
829                 return service_error(SERVICE_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use");
830
831         if (!appsvc_data_is_array(service->data, key))
832                 *array = false;
833         else
834                 *array = true;
835
836         return SERVICE_ERROR_NONE;
837 }
838
839
840 typedef struct {
841         service_h service;
842         service_extra_data_cb callback;
843         void* user_data;
844         bool foreach_break;
845 } foreach_context_extra_data_t;
846
847 static void service_cb_broker_bundle_iterator(const char *key, const int type, const bundle_keyval_t *kv, void *user_data)
848 {
849         foreach_context_extra_data_t* foreach_context = NULL;
850         service_extra_data_cb extra_data_cb;
851
852         if (key == NULL || !(type == BUNDLE_TYPE_STR || type == BUNDLE_TYPE_STR_ARRAY))
853                 return;
854
855         foreach_context = (foreach_context_extra_data_t*)user_data;
856
857         if (foreach_context->foreach_break == true)
858                 return;
859
860         if (service_validate_internal_key(key))
861                 return;
862
863         extra_data_cb = foreach_context->callback;
864
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;
869         }
870
871 }
872
873
874 int service_foreach_extra_data(service_h service, service_extra_data_cb callback, void *user_data)
875 {
876         foreach_context_extra_data_t foreach_context = {
877                 .service = service,
878                 .callback = callback,
879                 .user_data = user_data,
880                 .foreach_break = false
881         };
882
883         if (service_valiate_service(service) || callback == NULL)
884                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
885
886         bundle_foreach(service->data, service_cb_broker_bundle_iterator, &foreach_context);
887
888         return SERVICE_ERROR_NONE;
889 }
890
891 typedef struct {
892         service_h service;
893         service_app_matched_cb callback;
894         void* user_data;
895         bool foreach_break;
896 } foreach_context_launchable_app_t;
897
898 int service_cb_broker_foreach_app_matched(const char *package, void *data)
899 {
900         foreach_context_launchable_app_t *foreach_context;
901         service_app_matched_cb app_matched_cb;
902
903         if (package == NULL || data == NULL) {
904                 service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
905                 return -1;
906         }
907
908         foreach_context = (foreach_context_launchable_app_t*)data;
909
910         if (foreach_context->foreach_break == true)
911                 return -1;
912
913         app_matched_cb = foreach_context->callback;
914
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;
919         }
920
921         return 0;
922 }
923
924 int service_foreach_app_matched(service_h service, service_app_matched_cb callback, void *user_data)
925 {
926         foreach_context_launchable_app_t foreach_context = {
927                 .service = service,
928                 .callback = callback,
929                 .user_data = user_data,
930                 .foreach_break = false
931         };
932
933         if (service_valiate_service(service) || callback == NULL)
934                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
935
936         appsvc_usr_get_list(service->data, service_cb_broker_foreach_app_matched, &foreach_context, getuid());
937
938         return SERVICE_ERROR_NONE;
939 }
940
941
942 int service_get_caller(service_h service, char **package)
943 {
944         const char *bundle_value;
945         char *package_dup;
946
947         if (service_valiate_service(service) || package == NULL)
948                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
949
950         if (service->type != SERVICE_TYPE_EVENT)
951                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid service handle type");
952
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");
956
957         package_dup = strdup(bundle_value);
958
959         if (package_dup == NULL)
960                 return service_error(SERVICE_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
961
962         *package = package_dup;
963
964         return SERVICE_ERROR_NONE;
965 }
966
967
968 int service_is_reply_requested(service_h service, bool *requested)
969 {
970         const char *bundle_value;
971
972         if (service_valiate_service(service) || requested == NULL)
973                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
974
975         if (service->type != SERVICE_TYPE_EVENT)
976                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid service handle type");
977
978         bundle_value = bundle_get_val(service->data, AUL_K_WAIT_RESULT);
979
980         if (bundle_value != NULL)
981                 *requested = true;
982         else
983                 *requested = false;
984
985         return SERVICE_ERROR_NONE;
986 }
987
988 int service_import_from_bundle(service_h service, bundle *data)
989 {
990         bundle *data_dup = NULL;
991
992         if (service_valiate_service(service) || data == NULL)
993                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
994
995         data_dup = bundle_dup(data);
996
997         if (data_dup == NULL)
998                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to duplicate the bundle");
999
1000         if (service->data != NULL)
1001                 bundle_free(service->data);
1002
1003         service->data = data_dup;
1004
1005         return SERVICE_ERROR_NONE;
1006 }
1007
1008 int service_export_as_bundle(service_h service, bundle **data)
1009 {
1010         bundle *data_dup = NULL;
1011
1012         if (service_valiate_service(service) || data == NULL)
1013                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1014
1015         data_dup = bundle_dup(service->data);
1016
1017         if (data_dup == NULL)
1018                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to duplicate the bundle");
1019
1020         *data = data_dup;
1021
1022         return SERVICE_ERROR_NONE;
1023 }
1024