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