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