9edd4e1037592a89bc16d5d6c0061a9817027e83
[framework/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 extern int appsvc_request_transient_app(bundle *b, unsigned int callee_id, appsvc_host_res_fn cbfunc, void *data);
74
75 static int service_create_reply(bundle *data, struct service_s **service);
76
77 static const char* service_error_to_string(service_error_e error)
78 {
79         switch (error)
80         {
81         case SERVICE_ERROR_NONE:
82                 return "NONE";
83
84         case SERVICE_ERROR_INVALID_PARAMETER:
85                 return "INVALID_PARAMETER";
86
87         case SERVICE_ERROR_OUT_OF_MEMORY:
88                 return "OUT_OF_MEMORY";
89
90         case SERVICE_ERROR_APP_NOT_FOUND:
91                 return "APP_NOT_FOUND";
92
93         case SERVICE_ERROR_KEY_NOT_FOUND:
94                 return "KEY_NOT_FOUND";
95
96         case SERVICE_ERROR_KEY_REJECTED:
97                 return "KEY_REJECTED";
98
99         case SERVICE_ERROR_INVALID_DATA_TYPE:
100                 return "INVALID_DATA_TYPE";
101
102         case SERVICE_ERROR_LAUNCH_REJECTED:
103                 return "LAUNCH_REJECTED";
104
105         default :
106                 return "UNKNOWN";
107         }
108 }
109
110 int service_error(service_error_e error, const char* function, const char *description)
111 {
112         if (description)
113         {
114                 LOGE("[%s] %s(0x%08x) : %s", function, service_error_to_string(error), error, description);     
115         }
116         else
117         {
118                 if(error == SERVICE_ERROR_KEY_NOT_FOUND)
119                         LOGW("[%s] %s(0x%08x)", function, service_error_to_string(error), error);
120                 else
121                         LOGE("[%s] %s(0x%08x)", function, service_error_to_string(error), error);
122         }
123
124         return error;
125 }
126
127 static int service_validate_extra_data(const char *data)
128 {
129         if (data == NULL || data[0] == '\0')
130         {
131                 return SERVICE_ERROR_INVALID_PARAMETER;
132         }
133
134         return SERVICE_ERROR_NONE;
135 }
136
137 static int service_valiate_service(service_h service)
138 {
139         if (service == NULL || service->data == NULL)
140         {
141                 return SERVICE_ERROR_INVALID_PARAMETER;
142         }
143
144         return SERVICE_ERROR_NONE;
145 }
146
147 static int service_new_id()
148 {
149         static int sid = 0;
150         return sid++;
151 }
152
153 int service_validate_internal_key(const char *key)
154 {
155         if (strncmp(BUNDLE_KEY_PREFIX_AUL, key, strlen(BUNDLE_KEY_PREFIX_AUL)) == 0)
156         {
157                 return -1;
158         }
159
160         if (strncmp(BUNDLE_KEY_PREFIX_SERVICE, key, strlen(BUNDLE_KEY_PREFIX_SERVICE)) == 0)
161         {
162                 return -1;
163         }
164
165         return 0;
166 }
167
168 static void service_request_result_broker(bundle *appsvc_bundle, int appsvc_request_code, appsvc_result_val appsvc_result, void *appsvc_data)
169 {
170         service_request_context_h request_context;
171         service_h request;
172         service_h reply = NULL;
173         service_result_e result;
174         void *user_data;
175         service_reply_cb reply_cb;      
176
177         if (appsvc_data == NULL)
178         {
179                 service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid service reply");
180                 return;
181         }
182
183         if (service_create_reply(appsvc_bundle, &reply) != 0)
184         {
185                 service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to create service reply");
186                 return;         
187         }
188
189         request_context = appsvc_data;
190         request = request_context->service;
191
192         switch (appsvc_result)
193         {
194         case APPSVC_RES_OK:
195                 result = SERVICE_RESULT_SUCCEEDED;
196                 break;
197
198         case APPSVC_RES_NOT_OK:
199                 result = SERVICE_RESULT_FAILED;
200                 break;
201
202         case APPSVC_RES_CANCEL:
203                 result = SERVICE_RESULT_CANCELED;
204                 break;
205
206         default:
207                 result = SERVICE_RESULT_CANCELED;
208                 break;
209         }
210
211         user_data = request_context->user_data;
212         reply_cb = request_context->reply_cb;
213
214         if (reply_cb != NULL)
215         {
216                 reply_cb(request, reply, result, user_data);
217         }
218         else
219         {
220                 service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid callback ");
221         }
222
223         service_destroy(reply);
224
225         if (request_context->service != NULL)
226         {
227                 service_destroy(request_context->service);
228         }
229
230         free(request_context);
231 }
232
233
234 int service_create(service_h *service)
235 {
236         return service_create_request(NULL, service);
237 }
238
239 int service_create_request(bundle *data, service_h *service)
240 {
241         struct service_s *service_request;
242
243         if (service == NULL)
244         {
245                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
246         }
247
248         service_request = malloc(sizeof(struct service_s));
249
250         if (service_request == NULL)
251         {
252                 return service_error(SERVICE_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create a service handle");
253         }
254
255         service_request->type = SERVICE_TYPE_REQUEST;
256
257         if (data != NULL)
258         {
259                 service_request->data = bundle_dup(data);
260         }
261         else
262         {
263                 service_request->data = bundle_create();
264         }
265
266         if (service_request->data == NULL)
267         {
268                 free(service_request);
269                 return service_error(SERVICE_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create a bundle");
270         }
271
272         service_request->id = service_new_id();
273         service_request->launch_pid = -1;
274
275         *service = service_request;
276
277         return SERVICE_ERROR_NONE;
278 }
279
280 int service_create_event(bundle *data, struct service_s **service)
281 {
282         struct service_s *service_event;
283
284         const char *operation;
285
286         if (data == NULL || service == NULL)
287         {
288                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
289         }
290
291         service_event = malloc(sizeof(struct service_s));
292
293         if (service_event == NULL)
294         {
295                 return service_error(SERVICE_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create a service handle");
296         }       
297
298         service_event->type = SERVICE_TYPE_EVENT;
299         service_event->data = bundle_dup(data);
300         service_event->id = service_new_id();
301
302         operation = appsvc_get_operation(service_event->data);
303
304         if (operation == NULL)
305         {
306                 appsvc_set_operation(service_event->data, SERVICE_OPERATION_DEFAULT);
307         }
308
309         *service = service_event;
310
311         return SERVICE_ERROR_NONE;
312 }
313
314 static int service_create_reply(bundle *data, struct service_s **service)
315 {
316         struct service_s *service_reply;
317
318         if (data == NULL || service == NULL)
319         {
320                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
321         }
322
323         service_reply = malloc(sizeof(struct service_s));
324
325         if (service_reply == NULL)
326         {
327                 return service_error(SERVICE_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create a service handle");
328         }       
329
330         service_reply->type = SERVICE_TYPE_REPLY;
331         service_reply->data = bundle_dup(data);
332         service_reply->id = service_new_id();
333
334         *service = service_reply;
335
336         return SERVICE_ERROR_NONE;
337 }
338
339 int service_destroy(service_h service)
340 {
341         if (service_valiate_service(service))
342         {
343                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
344         }
345
346         bundle_free(service->data);
347         service->data = NULL;
348         free(service);
349
350         return SERVICE_ERROR_NONE;
351 }
352
353 int service_to_bundle(service_h service, bundle **data)
354 {
355         if (service_valiate_service(service) || data == NULL)
356         {
357                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
358         }
359
360         *data = service->data;
361
362         return SERVICE_ERROR_NONE;
363 }
364
365 int service_set_operation(service_h service, const char *operation)
366 {
367         if (service_valiate_service(service))
368         {
369                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
370         }
371
372         if (operation != NULL)
373         {
374                 if (appsvc_set_operation(service->data, operation) != 0)
375                 {
376                         return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid operation");
377                 }
378         }
379         else
380         {
381                 bundle_del(service->data, BUNDLE_KEY_OPERATION);
382         }
383
384         return SERVICE_ERROR_NONE;
385 }
386
387 int service_get_operation(service_h service, char **operation)
388 {
389         const char *operation_value;
390
391         if (service_valiate_service(service) || operation == NULL)
392         {
393                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
394         }
395
396         operation_value = appsvc_get_operation(service->data);
397
398         if (operation_value != NULL)
399         {
400                 *operation = strdup(operation_value);
401         }
402         else
403         {
404                 *operation = NULL;
405         }
406
407         return SERVICE_ERROR_NONE;
408 }
409
410
411 int service_set_uri(service_h service, const char *uri)
412 {
413         if (service_valiate_service(service))
414         {
415                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
416         }
417
418         if (uri != NULL)
419         {
420                 if (appsvc_set_uri(service->data, uri) != 0)
421                 {
422                         return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid URI");
423                 }
424         }
425         else
426         {
427                 bundle_del(service->data, BUNDLE_KEY_URI);
428         }
429         
430         return SERVICE_ERROR_NONE;
431 }
432
433
434 int service_get_uri(service_h service, char **uri)
435 {
436         const char *uri_value;
437
438         if (service_valiate_service(service) || uri == NULL)
439         {
440                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
441         }
442
443         uri_value = appsvc_get_uri(service->data);
444
445         if (uri_value != NULL)
446         {
447                 *uri = strdup(uri_value);
448         }
449         else
450         {
451                 *uri = NULL;
452         }
453
454         return SERVICE_ERROR_NONE;
455 }
456
457
458 int service_set_mime(service_h service, const char *mime)
459 {
460         if (service_valiate_service(service))
461         {
462                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
463         }
464
465         if (mime != NULL)
466         {
467                 if (appsvc_set_mime(service->data, mime) != 0)
468                 {
469                         return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid MIME type");
470                 }
471         }
472         else
473         {
474                 bundle_del(service->data, BUNDLE_KEY_MIME);
475         }
476
477         return SERVICE_ERROR_NONE;
478 }
479
480
481 int service_get_mime(service_h service, char **mime)
482 {
483         const char *mime_value;
484
485         if (service_valiate_service(service) || mime == NULL)
486         {
487                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
488         }
489
490         mime_value = appsvc_get_mime(service->data);
491
492         if (mime_value != NULL)
493         {
494                 *mime = strdup(mime_value);
495         }
496         else
497         {
498                 *mime = NULL;
499         }
500
501         return SERVICE_ERROR_NONE;
502 }
503
504
505 int service_set_category(service_h service, const char *category)
506 {
507         if (service_valiate_service(service))
508         {
509                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
510         }
511
512         if (category != NULL)
513         {
514                 if (appsvc_set_category(service->data, category) != 0)
515                 {
516                         return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid MIME type");
517                 }
518         }
519         else
520         {
521                 bundle_del(service->data, BUNDLE_KEY_MIME);
522         }
523
524         return SERVICE_ERROR_NONE;
525 }
526
527
528 int service_get_category(service_h service, char **category)
529 {
530         const char *category_value;
531
532         if (service_valiate_service(service) || category == NULL)
533         {
534                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
535         }
536
537         category_value = appsvc_get_category(service->data);
538
539         if (category_value != NULL)
540         {
541                 *category = strdup(category_value);
542         }
543         else
544         {
545                 *category = NULL;
546         }
547
548         return SERVICE_ERROR_NONE;
549 }
550
551
552 int service_set_package(service_h service, const char *package)
553 {
554         // TODO: this function must be deprecated
555         return service_set_app_id(service, package);
556 }
557
558 int service_get_package(service_h service, char **package)
559 {
560         // TODO: this function must be deprecated
561         return service_get_app_id(service, package);
562 }
563
564
565 int service_set_app_id(service_h service, const char *app_id)
566 {
567         if (service_valiate_service(service))
568         {
569                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
570         }
571
572         if (app_id != NULL)
573         {
574                 if (appsvc_set_appid(service->data, app_id) != 0)
575                 {
576                         return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid application ID");
577                 }
578         }
579         else
580         {
581                 bundle_del(service->data, BUNDLE_KEY_PACKAGE);
582         }
583
584         return SERVICE_ERROR_NONE;
585 }
586
587
588 int service_get_app_id(service_h service, char **app_id)
589 {
590         const char *app_id_value;
591
592         if (service_valiate_service(service) || app_id == NULL)
593         {
594                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
595         }
596
597         app_id_value = appsvc_get_appid(service->data);
598
599         if (app_id_value != NULL)
600         {
601                 *app_id = strdup(app_id_value);
602         }
603         else
604         {
605                 *app_id = NULL;
606         }
607
608         return SERVICE_ERROR_NONE;
609 }
610
611 int service_set_window(service_h service, unsigned int id)
612 {
613         if (service_valiate_service(service))
614         {
615                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
616         }
617
618         if (id > 0)
619         {
620                 if (appsvc_allow_transient_app(service->data, id) != 0)
621                 {
622                         return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid id");
623                 }
624         }
625         else
626         {
627                 bundle_del(service->data, BUNDLE_KEY_WINDOW);
628         }
629
630         return SERVICE_ERROR_NONE;
631 }
632
633 int service_get_window(service_h service, unsigned int *id)
634 {
635         const char *window_id;
636
637         if (service_valiate_service(service) || id == NULL)
638         {
639                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
640         }
641
642         window_id = bundle_get_val(service->data, BUNDLE_KEY_WINDOW);
643
644         if (window_id != NULL)
645         {
646                 *id = atoi(window_id);
647         }
648         else
649         {
650                 *id = 0;
651         }
652
653         return SERVICE_ERROR_NONE;
654 }
655
656 int service_clone(service_h *clone, service_h service)
657 {
658         service_h service_clone;
659
660         if (service_valiate_service(service) || clone == NULL)
661         {
662                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
663         }
664
665         service_clone = malloc(sizeof(struct service_s));
666
667         if (service_clone == NULL)
668         {
669                 return service_error(SERVICE_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create a service handle");
670         }
671
672         service_clone->id = service_new_id();
673         service_clone->type = service->type;
674         service_clone->data = bundle_dup(service->data);
675
676         *clone = service_clone;
677
678         return SERVICE_ERROR_NONE;
679 }
680
681
682 int service_send_launch_request(service_h service, service_reply_cb callback, void *user_data)
683 {
684         const char *operation;
685         const char *appid;
686
687         bool implicit_default_operation = false;
688         int launch_pid;
689
690         service_request_context_h request_context = NULL;
691
692         if (service_valiate_service(service))
693         {
694                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
695         }
696
697         operation = appsvc_get_operation(service->data);
698
699         if (operation == NULL)
700         {
701                 implicit_default_operation = true;
702                 operation = SERVICE_OPERATION_DEFAULT;
703         }
704
705         appid = appsvc_get_appid(service->data);
706
707         // operation : default
708         if (!strcmp(operation, SERVICE_OPERATION_DEFAULT))
709         {
710                 if (appid == NULL)
711                 {
712                         return service_error(SERVICE_ERROR_APP_NOT_FOUND, __FUNCTION__, "package must be specified if the operation is default value");
713                 }
714         }
715
716         if (callback != NULL)
717         {
718                 service_h request_clone = NULL;
719
720                 request_context = calloc(1, sizeof(struct service_request_context_s));
721
722                 if (request_context == NULL)
723                 {
724                         return service_error(SERVICE_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
725                 }
726
727                 request_context->reply_cb = callback;
728
729                 if (service_clone(&request_clone, service) != SERVICE_ERROR_NONE)
730                 {
731                         free(request_context);
732                         return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to clone the service request handle");
733                 }
734
735                 request_context->service = request_clone;
736                 request_context->user_data = user_data;
737         }
738
739         if (implicit_default_operation == true)
740         {
741                 appsvc_set_operation(service->data, SERVICE_OPERATION_DEFAULT);
742         }
743
744         launch_pid = appsvc_run_service(service->data, service->id, callback ? service_request_result_broker : NULL, request_context);
745
746         if (implicit_default_operation == true)
747         {
748                 bundle_del(service->data, BUNDLE_KEY_OPERATION);
749         }
750
751         if (launch_pid < 0)
752         {
753                 if (launch_pid == APPSVC_RET_ENOMATCH)
754                 {
755                         return service_error(SERVICE_ERROR_APP_NOT_FOUND, __FUNCTION__, NULL);
756                 }
757                 else if (launch_pid == APPSVC_RET_EILLACC)
758                 {
759                         return service_error(SERVICE_ERROR_PERMISSION_DENIED, __FUNCTION__, NULL);
760                 }
761                 else
762                 {
763                         return service_error(SERVICE_ERROR_LAUNCH_REJECTED, __FUNCTION__, NULL);
764                 }
765         }
766
767         service->launch_pid = launch_pid;
768
769         return SERVICE_ERROR_NONE;
770 }
771
772
773 int service_send_terminate_request(service_h service)
774 {
775         if (service_valiate_service(service))
776         {
777                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
778         }
779
780         if(service->type != SERVICE_TYPE_REQUEST || service->launch_pid < 0)
781         {
782                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
783         }
784
785         appsvc_subapp_terminate_request_pid(service->launch_pid);
786
787         return SERVICE_ERROR_NONE;
788 }
789
790 static bool service_copy_reply_data_cb(service_h service, const char *key, void *user_data)
791 {
792         bundle *reply_data = user_data;
793         char *value = NULL;
794         char **value_array = NULL;
795         int value_array_length = 0;
796         int value_array_index = 0;
797
798         if (reply_data == NULL)
799         {
800                 service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
801                 return false;
802         }
803
804         if (appsvc_data_is_array(service->data, key))
805         {
806                 service_get_extra_data_array(service, key, &value_array, &value_array_length);
807                 appsvc_add_data_array(reply_data, key, (const char**)value_array, value_array_length);
808
809                 for (value_array_index=0; value_array_index < value_array_length; value_array_index++)
810                 {
811                         free(value_array[value_array_index]);
812                 }
813
814                 free(value_array);
815         }
816         else
817         {
818                 service_get_extra_data(service, key, &value);
819                 appsvc_add_data(reply_data, key, value);
820                 free(value);
821         }
822
823         return true;
824 }
825
826 int service_reply_to_launch_request(service_h reply, service_h request, service_result_e result)
827 {
828         bundle *reply_data;
829         int appsvc_result;
830
831         if (service_valiate_service(reply) || service_valiate_service(request))
832         {
833                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
834         }
835
836         if (appsvc_create_result_bundle(request->data, &reply_data) != 0)
837         {
838                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to create a result bundle");
839         }
840
841         service_foreach_extra_data(reply, service_copy_reply_data_cb, reply_data);
842
843         switch (result)
844         {
845         case SERVICE_RESULT_SUCCEEDED:
846                 appsvc_result = APPSVC_RES_OK;
847                 break;
848
849         case SERVICE_RESULT_FAILED:
850                 appsvc_result = APPSVC_RES_NOT_OK;
851                 break;
852
853         case SERVICE_RESULT_CANCELED:
854                 appsvc_result = APPSVC_RES_CANCEL;
855                 break;
856
857         default:
858                 appsvc_result = APPSVC_RES_CANCEL;
859                 break;
860         }
861
862         appsvc_send_result(reply_data, appsvc_result);
863         
864         return SERVICE_ERROR_NONE;
865 }
866
867
868 int service_add_extra_data(service_h service, const char *key, const char *value)
869 {
870         if (service_valiate_service(service) || service_validate_extra_data(key) || service_validate_extra_data(value))
871         {
872                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
873         }
874
875         if (service_validate_internal_key(key))
876         {
877                 return service_error(SERVICE_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use");
878         }
879
880         if (appsvc_get_data(service->data, key) != NULL)
881         {
882                 // overwrite any existing value
883                 bundle_del(service->data, key);
884         }
885
886         if (appsvc_add_data(service->data, key, value) != 0)
887         {
888                 return service_error(SERVICE_ERROR_KEY_REJECTED, __FUNCTION__, "failed to add data to the appsvc handle");
889         }
890
891         return SERVICE_ERROR_NONE;
892 }
893
894
895 int service_add_extra_data_array(service_h service, const char *key, const char* value[], int length)
896 {
897         if (service_valiate_service(service) || service_validate_extra_data(key))
898         {
899                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
900         }
901
902         if (value == NULL || length <= 0)
903         {
904                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid array");
905         }       
906
907         if (service_validate_internal_key(key))
908         {
909                 return service_error(SERVICE_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use");
910         }
911
912         if (appsvc_get_data_array(service->data, key, NULL) != NULL)
913         {
914                 // overwrite any existing value
915                 bundle_del(service->data,key);
916         }
917
918         if (appsvc_add_data_array(service->data, key, value, length) != 0)
919         {
920                 return service_error(SERVICE_ERROR_KEY_REJECTED, __FUNCTION__, "failed to add array data to the appsvc handle");                
921         }
922
923         return SERVICE_ERROR_NONE;
924 }
925
926
927 int service_remove_extra_data(service_h service, const char *key)
928 {
929         if (service_valiate_service(service) || service_validate_extra_data(key))
930         {
931                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
932         }
933
934         if (service_validate_internal_key(key))
935         {
936                 return service_error(SERVICE_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use");
937         }
938
939         if (bundle_del(service->data, key))
940         {
941                 return service_error(SERVICE_ERROR_KEY_NOT_FOUND, __FUNCTION__, NULL);
942         }
943
944         return SERVICE_ERROR_NONE;
945 }
946
947
948 int service_get_extra_data(service_h service, const char *key, char **value)
949 {
950         const char *data_value;
951
952         if (service_valiate_service(service) || service_validate_extra_data(key) || value == NULL)
953         {
954                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
955         }
956
957
958         if (service_validate_internal_key(key))
959         {
960                 return service_error(SERVICE_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use");
961         }
962
963         data_value = appsvc_get_data(service->data, key);
964
965         if (data_value == NULL) 
966         {
967                 if (errno == ENOTSUP)
968                 {
969                         return service_error(SERVICE_ERROR_INVALID_DATA_TYPE, __FUNCTION__, NULL);
970                 }
971                 else
972                 {
973                         return service_error(SERVICE_ERROR_KEY_NOT_FOUND, __FUNCTION__, NULL);
974                 }
975         }
976
977         *value = strdup(data_value);
978
979         return SERVICE_ERROR_NONE;
980 }
981
982
983 int service_get_extra_data_array(service_h service, const char *key, char ***value, int *length)
984 {
985         const char **array_data;
986         int array_data_length;
987         char **array_data_clone;
988         int i;
989
990         if (service_valiate_service(service) || service_validate_extra_data(key))
991         {
992                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
993         }
994
995         if (value == NULL || length == 0)
996         {
997                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
998         }
999
1000         if (service_validate_internal_key(key))
1001         {
1002                 return service_error(SERVICE_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use");
1003         }
1004
1005         array_data = appsvc_get_data_array(service->data, key, &array_data_length);
1006
1007         if (array_data == NULL)
1008         {
1009                 if (errno == ENOTSUP)
1010                 {
1011                         return service_error(SERVICE_ERROR_INVALID_DATA_TYPE, __FUNCTION__, NULL);
1012                 }
1013                 else
1014                 {
1015                         return service_error(SERVICE_ERROR_KEY_NOT_FOUND, __FUNCTION__, NULL);
1016                 }
1017         }
1018
1019         array_data_clone = calloc(array_data_length, sizeof(char*));
1020
1021         if (array_data_clone == NULL)
1022         {
1023                 return service_error(SERVICE_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
1024         }
1025
1026         for (i=0; i<array_data_length; i++)
1027         {
1028                 if (array_data[i] != NULL)
1029                 {
1030                         array_data_clone[i] = strdup(array_data[i]);
1031                 }
1032         }
1033
1034         *value = array_data_clone;
1035         *length = array_data_length;
1036
1037         return SERVICE_ERROR_NONE;
1038 }
1039
1040
1041 int service_is_extra_data_array(service_h service, const char *key, bool *array)
1042 {
1043         if (service_valiate_service(service) || service_validate_extra_data(key) || array == NULL)
1044         {
1045                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1046         }
1047
1048         if (service_validate_internal_key(key))
1049         {
1050                 return service_error(SERVICE_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use");
1051 \r       }
1052
1053         if (!appsvc_data_is_array(service->data, key))
1054         {
1055                 *array = false;
1056         }
1057         else
1058         {
1059                 *array = true;
1060         }
1061
1062         return SERVICE_ERROR_NONE;
1063 }
1064
1065
1066 typedef struct {
1067         service_h service;
1068         service_extra_data_cb callback;
1069         void* user_data;
1070         bool foreach_break;
1071 } foreach_context_extra_data_t;
1072
1073 static void service_cb_broker_bundle_iterator(const char *key, const int type, const bundle_keyval_t *kv, void *user_data)
1074 {
1075         foreach_context_extra_data_t* foreach_context = NULL;
1076         service_extra_data_cb extra_data_cb;
1077
1078         if (key == NULL || !(type == BUNDLE_TYPE_STR || type == BUNDLE_TYPE_STR_ARRAY))
1079         {
1080                 return;
1081         }
1082
1083         foreach_context = (foreach_context_extra_data_t*)user_data;
1084
1085         if (foreach_context->foreach_break == true)
1086         {
1087                 return;
1088         }
1089
1090         if (service_validate_internal_key(key))
1091         {
1092                 return;
1093         }
1094         
1095         extra_data_cb = foreach_context->callback;
1096
1097         if (extra_data_cb != NULL)
1098         {
1099                 bool stop_foreach = false;
1100                 
1101                 stop_foreach = !extra_data_cb(foreach_context->service, key, foreach_context->user_data);
1102         
1103                 foreach_context->foreach_break = stop_foreach;
1104         }
1105
1106 }
1107
1108
1109 int service_foreach_extra_data(service_h service, service_extra_data_cb callback, void *user_data)
1110 {
1111         foreach_context_extra_data_t foreach_context = {
1112                 .service = service,
1113                 .callback = callback,
1114                 .user_data = user_data,
1115                 .foreach_break = false
1116         };
1117         
1118         if (service_valiate_service(service) || callback == NULL)
1119         {
1120                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1121         }
1122
1123         bundle_foreach(service->data, service_cb_broker_bundle_iterator, &foreach_context);
1124
1125         return SERVICE_ERROR_NONE;
1126 }
1127
1128 typedef struct {
1129         service_h service;
1130         service_app_matched_cb callback;
1131         void* user_data;
1132         bool foreach_break;
1133 } foreach_context_launchable_app_t;
1134
1135 int service_cb_broker_foreach_app_matched(const char *package, void *data)
1136 {
1137         foreach_context_launchable_app_t *foreach_context;
1138         service_app_matched_cb app_matched_cb;
1139
1140         if (package == NULL || data == NULL)
1141         {
1142                 service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1143                 return -1;
1144         }
1145
1146         foreach_context = (foreach_context_launchable_app_t*)data;
1147
1148         if (foreach_context->foreach_break == true)
1149         {
1150                 return -1;
1151         }
1152
1153         app_matched_cb = foreach_context->callback;
1154
1155         if (app_matched_cb != NULL)
1156         {
1157                 bool stop_foreach = false;
1158                 
1159                 stop_foreach = !app_matched_cb(foreach_context->service, package, foreach_context->user_data);
1160         
1161                 foreach_context->foreach_break = stop_foreach;
1162         }
1163
1164         return 0;
1165 }
1166
1167 int service_foreach_app_matched(service_h service, service_app_matched_cb callback, void *user_data)
1168 {
1169         foreach_context_launchable_app_t foreach_context = {
1170                 .service = service,
1171                 .callback = callback,
1172                 .user_data = user_data,
1173                 .foreach_break = false
1174         };
1175
1176         if (service_valiate_service(service) || callback == NULL)
1177         {
1178                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1179         }
1180
1181         appsvc_get_list(service->data, service_cb_broker_foreach_app_matched, &foreach_context);
1182
1183         return SERVICE_ERROR_NONE;
1184 }
1185
1186
1187 int service_get_caller(service_h service, char **package)
1188 {
1189         const char *bundle_value;
1190         char *package_dup;
1191
1192         if (service_valiate_service(service) || package == NULL)
1193         {
1194                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1195         }
1196
1197         if (service->type != SERVICE_TYPE_EVENT)
1198         {
1199                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid service handle type");
1200         }
1201
1202         bundle_value = bundle_get_val(service->data, AUL_K_CALLER_APPID);
1203         if (bundle_value == NULL)
1204         {
1205                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to retrieve the appid of the caller");
1206         }
1207
1208         package_dup = strdup(bundle_value);
1209
1210         if (package_dup == NULL)
1211         {
1212                 return service_error(SERVICE_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
1213         }
1214
1215         *package = package_dup;
1216
1217         return SERVICE_ERROR_NONE;
1218 }
1219
1220
1221 int service_is_reply_requested(service_h service, bool *requested)
1222 {
1223         const char *bundle_value;
1224         
1225         if (service_valiate_service(service) || requested == NULL)
1226         {
1227                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1228         }
1229
1230         if (service->type != SERVICE_TYPE_EVENT)
1231         {
1232                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid service handle type");
1233         }
1234
1235         bundle_value = bundle_get_val(service->data, AUL_K_WAIT_RESULT);
1236
1237         if (bundle_value != NULL)
1238         {
1239                 *requested = true;
1240         }
1241         else
1242         {
1243                 *requested = false;
1244         }
1245
1246         return SERVICE_ERROR_NONE;
1247 }
1248
1249 int service_import_from_bundle(service_h service, bundle *data)
1250 {
1251         bundle *data_dup = NULL;
1252
1253         if (service_valiate_service(service) || data == NULL)
1254         {
1255                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1256         }
1257
1258         data_dup = bundle_dup(data);
1259
1260         if (data_dup == NULL)
1261         {
1262                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to duplicate the bundle");
1263         }
1264
1265         if (service->data != NULL)
1266         {
1267                 bundle_free(service->data);
1268         }
1269
1270         service->data = data_dup;
1271
1272         return SERVICE_ERROR_NONE;
1273 }
1274
1275 int service_export_as_bundle(service_h service, bundle **data)
1276 {
1277         bundle *data_dup = NULL;
1278
1279         if (service_valiate_service(service) || data == NULL)
1280         {
1281                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1282         }
1283
1284         data_dup = bundle_dup(service->data);
1285
1286         if (data_dup == NULL)
1287         {
1288                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to duplicate the bundle");
1289         }
1290
1291         *data = data_dup;
1292
1293         return SERVICE_ERROR_NONE;
1294 }
1295
1296
1297 int service_request_transient_app(service_h service, unsigned int callee_id, service_host_res_fn cbfunc, void *data)
1298 {
1299         int ret;
1300
1301         if (service_valiate_service(service))
1302         {
1303                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1304         }
1305
1306         ret = appsvc_request_transient_app(service->data, callee_id, (appsvc_host_res_fn)cbfunc, data);
1307
1308         if (ret < 0)
1309         {
1310                 return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1311         }
1312
1313         return SERVICE_ERROR_NONE;
1314 }
1315