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